alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Apache CXF example source code file (ObjectType.java)

This example Apache CXF source code file (ObjectType.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Apache CXF tags/keywords

aegistype, aegistype, bytearrayinputstream, class, context, databindingexception, databindingexception, dom, io, object, objecttype, objecttype, override, override, qname, typemapping, util

The Apache CXF ObjectType.java source code

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.cxf.aegis.type.basic;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.util.Collections;
import java.util.Set;

import javax.xml.namespace.QName;

import org.w3c.dom.Document;

import org.apache.cxf.aegis.Context;
import org.apache.cxf.aegis.DatabindingException;
import org.apache.cxf.aegis.type.AegisType;
import org.apache.cxf.aegis.type.TypeMapping;
import org.apache.cxf.aegis.xml.MessageReader;
import org.apache.cxf.aegis.xml.MessageWriter;
import org.apache.cxf.common.util.Base64Utility;
import org.apache.cxf.common.util.SOAPConstants;
import org.apache.cxf.common.xmlschema.XmlSchemaConstants;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaSimpleType;
import org.apache.ws.commons.schema.XmlSchemaSimpleTypeRestriction;

/**
 * AegisType for runtime inspection of types. Looks as the class to be written, and
 * looks to see if there is a type for that class. If there is, it writes out
 * the value and inserts a <em>xsi:type attribute to signal what the type
 * of the value is. Can specify an optional set of dependent <code>AegisType's
 * in the constructor, in the case that the type is a custom type that may not
 * have its schema in the WSDL. Can specify whether or not unknown objects
 * should be serialized as a byte stream.
 * 
 */
public class ObjectType extends AegisType {
    private static final QName XSI_TYPE = new QName(SOAPConstants.XSI_NS, "type");
    private static final QName XSI_NIL = new QName(SOAPConstants.XSI_NS, "nil");

    private Set<AegisType> dependencies;
    private boolean serializedWhenUnknown;
    private boolean readToDocument;

    @SuppressWarnings("unchecked")
    public ObjectType() {
        this(Collections.EMPTY_SET);
        readToDocument = true;
    }

    public ObjectType(Set<AegisType> dependencies) {
        this(dependencies, false);
    }

    @SuppressWarnings("unchecked")
    public ObjectType(boolean serializeWhenUnknown) {
        this(Collections.EMPTY_SET, serializeWhenUnknown);
    }

    public ObjectType(Set<AegisType> dependencies, boolean serializeWhenUnknown) {
        this.dependencies = dependencies;
        this.serializedWhenUnknown = serializeWhenUnknown;
    }

    @Override
    public Object readObject(MessageReader reader, Context context) throws DatabindingException {
        if (isNil(reader.getAttributeReader(XSI_NIL))) {
            while (reader.hasMoreElementReaders()) {
                reader.getNextElementReader();
            }

            return null;
        }

        MessageReader typeReader = reader.getAttributeReader(XSI_TYPE);

        if (null == typeReader && !readToDocument) {
            throw new DatabindingException("Missing 'xsi:type' attribute");
        }

        String typeName = typeReader.getValue();

        if (null == typeName && !readToDocument) {
            throw new DatabindingException("Missing 'xsi:type' attribute value");
        }

        AegisType type = null;
        QName typeQName = null;
        
        if (typeName != null) {
            typeName = typeName.trim();
            typeQName = extractQName(reader, typeName);
        } else {
            typeQName = reader.getName();
        }

        TypeMapping tm = context.getTypeMapping();
        if (tm == null) {
            tm = getTypeMapping();
        }

        type = tm.getType(typeQName);

        if (type == null) {
            type = tm.getType(getSchemaType());
        }

        if (type == this) {
            throw new DatabindingException("Could not determine how to read type: " + typeQName);
        }
        
        if (type == null && readToDocument) {
            type = getTypeMapping().getType(Document.class);
        }

        if (null == type) {
            // TODO should check namespace as well..
            if (serializedWhenUnknown && "serializedJavaObject".equals(typeName)) {
                return reconstituteJavaObject(reader);
            }

            throw new DatabindingException("No mapped type for '" + typeName + "' (" + typeQName + ")");
        }

        return type.readObject(reader, context);
    }

    private QName extractQName(MessageReader reader, String typeName) {
        int colon = typeName.indexOf(':');

        if (-1 == colon) {
            return new QName(reader.getNamespace(), typeName);
        } else {
            return new QName(reader.getNamespaceForPrefix(typeName.substring(0, colon)), typeName
                .substring(colon + 1));
        }
    }

    private Object reconstituteJavaObject(MessageReader reader) throws DatabindingException {

        try {
            ByteArrayInputStream in = new ByteArrayInputStream(Base64Utility
                                                                   .decode(reader.getValue().trim()));
            return new ObjectInputStream(in).readObject();
        } catch (Exception e) {
            throw new DatabindingException("Unable to reconstitute serialized object", e);
        }
    }

    private boolean isNil(MessageReader reader) {
        return null != reader && "true".equals(reader.getValue() == null ? "" : reader.getValue());
    }

    @Override
    public void writeObject(Object object, MessageWriter writer, Context context) 
        throws DatabindingException {
        if (null == object) {
            MessageWriter nilWriter = writer.getAttributeWriter(XSI_NIL);

            nilWriter.writeValue("true");

            nilWriter.close();
        } else {
            AegisType type = determineType(context, object.getClass());

            if (null == type) {
                TypeMapping tm = context.getTypeMapping();
                if (tm == null) {
                    tm = getTypeMapping();
                }

                type = tm.getTypeCreator().createType(object.getClass());
                tm.register(type);
            }
            
            writer.writeXsiType(type.getSchemaType());
            boolean nextIsBeanType = type instanceof BeanType;
            if (nextIsBeanType) {
                ((BeanType)type).writeObjectFromObjectType(object, writer, context, true);
            } else {
                type.writeObject(object, writer, context);
            }
        }
    }

    public AegisType determineType(Context context, Class clazz) {
        TypeMapping tm = context.getTypeMapping();
        if (tm == null) {
            tm = getTypeMapping();
        }
        AegisType type = tm.getType(clazz);

        if (null != type) {
            return type;
        }

        Class[] interfaces = clazz.getInterfaces();

        for (int i = 0; i < interfaces.length; i++) {
            Class anInterface = interfaces[i];

            type = tm.getType(anInterface);

            if (null != type) {
                return type;
            }
        }

        Class superclass = clazz.getSuperclass();

        if (null == superclass || Object.class.equals(superclass)) {
            return null;
        }

        return determineType(context, superclass);
    }

    public boolean isReadToDocument() {
        return readToDocument;
    }

    public void setReadToDocument(boolean readToDocument) {
        this.readToDocument = readToDocument;
    }

    public boolean isSerializedWhenUnknown() {
        return serializedWhenUnknown;
    }

    public void setSerializedWhenUnknown(boolean serializedWhenUnknown) {
        this.serializedWhenUnknown = serializedWhenUnknown;
    }

    public void setDependencies(Set<AegisType> dependencies) {
        this.dependencies = dependencies;
    }

    @Override
    public Set<AegisType> getDependencies() {
        return dependencies;
    }

    @Override
    public boolean isComplex() {
        return true;
    }

    @Override
    public void writeSchema(XmlSchema root) {
        if (serializedWhenUnknown) {
            XmlSchemaSimpleType simple = new XmlSchemaSimpleType(root);
            simple.setName("serializedJavaObject");
            root.addType(simple);
            root.getItems().add(simple);
            XmlSchemaSimpleTypeRestriction restriction = new XmlSchemaSimpleTypeRestriction();    
            simple.setContent(restriction);
            restriction.setBaseTypeName(XmlSchemaConstants.BASE64BINARY_QNAME);
        }
    }
}

Other Apache CXF examples (source code examples)

Here is a short list of links related to this Apache CXF ObjectType.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.