FileDocCategorySizeDatePackage
SimpleDeserializer.javaAPI DocApache Axis 1.415356Sat Apr 22 18:57:26 BST 2006org.apache.axis.encoding.ser

SimpleDeserializer

public class SimpleDeserializer extends org.apache.axis.encoding.DeserializerImpl
A deserializer for any simple type with a (String) constructor. Note: this class is designed so that subclasses need only override the makeValue method in order to construct objects of their own type.
author
Glen Daniels (gdaniels@apache.org)
author
Sam Ruby (rubys@us.ibm.com) Modified for JAX-RPC @author Rich Scheuerle (scheu@us.ibm.com)

Fields Summary
private static final Class[]
STRING_STRING_CLASS
public static final Class[]
STRING_CLASS
private final CharArrayWriter
val
private Constructor
constructor
private Map
propertyMap
private HashMap
attributeMap
public QName
xmlType
public Class
javaType
private org.apache.axis.description.TypeDesc
typeDesc
protected org.apache.axis.encoding.DeserializationContext
context
protected SimpleDeserializer
cacheStringDSer
protected QName
cacheXMLType
Constructors Summary
public SimpleDeserializer(Class javaType, QName xmlType)
The Deserializer is constructed with the xmlType and javaType (which could be a java primitive like int.class)

                           
         
         this.xmlType = xmlType;
        this.javaType = javaType;
        
        init();
    
public SimpleDeserializer(Class javaType, QName xmlType, org.apache.axis.description.TypeDesc typeDesc)

        this.xmlType = xmlType;
        this.javaType = javaType;
        this.typeDesc = typeDesc;
        
        init();
    
Methods Summary
public voidcharacters(char[] chars, int start, int end)
Append any characters received to the value. This method is defined by Deserializer.

        val.write(chars,start,end);
    
private voidinit()
Initialize the typeDesc, property descriptors and propertyMap.

        // The typeDesc and map array are only necessary
        // if this class extends SimpleType.
        if (SimpleType.class.isAssignableFrom(javaType)) {
            // Set the typeDesc if not already set
            if (typeDesc == null) {
                typeDesc = TypeDesc.getTypeDescForClass(javaType);
            }
        }

        // Get the cached propertyDescriptor from the type or
        // generate a fresh one.
        if (typeDesc != null) {
            propertyMap = typeDesc.getPropertyDescriptorMap();
        } else {
            BeanPropertyDescriptor[] pd = BeanUtils.getPd(javaType, null);
            propertyMap = new HashMap();
            for (int i = 0; i < pd.length; i++) {
                BeanPropertyDescriptor descriptor = pd[i];
                propertyMap.put(descriptor.getName(), descriptor);
            }
        }
    
private java.lang.ObjectmakeBasicValue(java.lang.String source)

        // If the javaType is a boolean, except a number of different sources
        if (javaType == boolean.class || 
            javaType == Boolean.class) {
            // This is a pretty lame test, but it is what the previous code did.
            switch (source.charAt(0)) {
                case '0": case 'f": case 'F":
                    return Boolean.FALSE;
                    
                case '1": case 't": case 'T": 
                    return Boolean.TRUE; 
                    
                default:
                    throw new NumberFormatException(
                            Messages.getMessage("badBool00"));
                }
            
        }
        
        // If expecting a Float or a Double, need to accept some special cases.
        if (javaType == float.class ||
            javaType == java.lang.Float.class) {
            if (source.equals("NaN")) {
                return new Float(Float.NaN);
            } else if (source.equals("INF")) {
                return new Float(Float.POSITIVE_INFINITY);
            } else if (source.equals("-INF")) {
                return new Float(Float.NEGATIVE_INFINITY);
            } else {
                return new Float(source);
            }
        }
        
        if (javaType == double.class ||
            javaType == java.lang.Double.class) {
            if (source.equals("NaN")) {
                return new Double(Double.NaN);
            } else if (source.equals("INF")) {
                return new Double(Double.POSITIVE_INFINITY);
            } else if (source.equals("-INF")) {
                return new Double(Double.NEGATIVE_INFINITY);
            } else {
                return new Double(source);
            }
        }    
        
        if (javaType == int.class ||
            javaType == java.lang.Integer.class) {
            return new Integer(source);
        }
        
        if (javaType == short.class ||
            javaType == java.lang.Short.class) {
            return new Short(source);
        }
        
        if (javaType == long.class ||
            javaType == java.lang.Long.class) {
            return new Long(source);
        }
        
        if (javaType == byte.class ||
            javaType == java.lang.Byte.class) {
            return new Byte(source);
        }
        
        if (javaType == org.apache.axis.types.URI.class) {
            return new org.apache.axis.types.URI(source);
        }

        return null;
    
public java.lang.ObjectmakeValue(java.lang.String source)
Convert the string that has been accumulated into an Object. Subclasses may override this. Note that if the javaType is a primitive, the returned object is a wrapper class.

param
source the serialized value to be deserialized
throws
Exception any exception thrown by this method will be wrapped

        if (javaType == java.lang.String.class) {
            return source;
        }

        // Trim whitespace if non-String
        source = source.trim();

        if (source.length() == 0 && typeDesc == null) {
            return null;
        }
        
        // if constructor is set skip all basic java type checks
        if (this.constructor == null) {
            Object value = makeBasicValue(source);
            if (value != null) {
                return value;
            }
        }
            
        Object [] args = null;
        
        boolean isQNameSubclass = QName.class.isAssignableFrom(javaType);

        if (isQNameSubclass) {
            int colon = source.lastIndexOf(":");
            String namespace = colon < 0 ? "" :
                context.getNamespaceURI(source.substring(0, colon));
            String localPart = colon < 0 ? source : source.substring(colon + 1);
            args = new Object [] {namespace, localPart};
        } 

        if (constructor == null) {
            try {
                if (isQNameSubclass) {
                    constructor = 
                        javaType.getDeclaredConstructor(STRING_STRING_CLASS);
                } else {
                    constructor = 
                        javaType.getDeclaredConstructor(STRING_CLASS);
                }
            } catch (Exception e) {
                return null;
            }
        }
        
        if(constructor.getParameterTypes().length==0){
            try {
                Object obj = constructor.newInstance(new Object[]{});
                obj.getClass().getMethod("set_value", new Class[]{String.class})
                        .invoke(obj, new Object[]{source});
                return obj;
            } catch (Exception e){
                //Ignore exception
            }
        }
        if (args == null) {
            args = new Object[]{source};
        }
        return constructor.newInstance(args);
    
public voidonEndElement(java.lang.String namespace, java.lang.String localName, org.apache.axis.encoding.DeserializationContext context)
Append any characters to the value. This method is defined by Deserializer.

        if (isNil) {
            value = null;
            return;
        }
        try {
            value = makeValue(val.toString());
        } catch (InvocationTargetException ite) {
            Throwable realException = ite.getTargetException();
            if (realException instanceof Exception)
                throw new SAXException((Exception)realException);
            else
                throw new SAXException(ite.getMessage());
        } catch (Exception e) {
            throw new SAXException(e);
        }
        
        // If this is a SimpleType, set attributes we have stashed away
        setSimpleTypeAttributes();
    
public org.apache.axis.message.SOAPHandleronStartChild(java.lang.String namespace, java.lang.String localName, java.lang.String prefix, org.xml.sax.Attributes attributes, org.apache.axis.encoding.DeserializationContext context)
There should not be nested elements, so thow and exception if this occurs.

        throw new SAXException(
                Messages.getMessage("cantHandle00", "SimpleDeserializer"));
    
public voidonStartElement(java.lang.String namespace, java.lang.String localName, java.lang.String prefix, org.xml.sax.Attributes attributes, org.apache.axis.encoding.DeserializationContext context)
Set the bean properties that correspond to element attributes. This method is invoked after startElement when the element requires deserialization (i.e. the element is not an href and the value is not nil.)

param
namespace is the namespace of the element
param
localName is the name of the element
param
prefix is the prefix of the element
param
attributes are the attributes on the element...used to get the type
param
context is the DeserializationContext

        
        this.context = context;

        // loop through the attributes and set bean properties that
        // correspond to attributes
        for (int i=0; i < attributes.getLength(); i++) {
            QName attrQName = new QName(attributes.getURI(i),
                                        attributes.getLocalName(i));
            
            String fieldName = attributes.getLocalName(i);
            
            if(typeDesc != null) {
                fieldName = typeDesc.getFieldNameForAttribute(attrQName);
                if (fieldName == null)
                    continue;
            }

            if (propertyMap == null)
                continue;
            
            // look for the attribute property
            BeanPropertyDescriptor bpd =
                    (BeanPropertyDescriptor) propertyMap.get(fieldName);
            if (bpd != null) {
                if (!bpd.isWriteable() || bpd.isIndexed() ) continue ;
                
                // determine the QName for this child element
                TypeMapping tm = context.getTypeMapping();
                Class type = bpd.getType();
                QName qn = tm.getTypeQName(type);
                if (qn == null)
                    throw new SAXException(
                            Messages.getMessage("unregistered00", type.toString()));
                
                // get the deserializer
                Deserializer dSer = context.getDeserializerForType(qn);
                if (dSer == null)
                    throw new SAXException(
                            Messages.getMessage("noDeser00", type.toString()));
                if (! (dSer instanceof SimpleDeserializer))
                    throw new SAXException(
                            Messages.getMessage("AttrNotSimpleType00",
                                                bpd.getName(),
                                                type.toString()));
                
                // Success!  Create an object from the string and save
                // it in our attribute map for later.
                if (attributeMap == null) {
                    attributeMap = new HashMap();
                }
                try {
                    Object val = ((SimpleDeserializer)dSer).
                            makeValue(attributes.getValue(i));
                    attributeMap.put(fieldName, val);
                } catch (Exception e) {
                    throw new SAXException(e);
                }
            } // if
        } // attribute loop
    
public voidreset()
Reset deserializer for re-use

        val.reset();
        attributeMap = null; // Remove attribute map
        isNil = false; // Don't know if nil
        isEnded = false; // Indicate the end of element not yet called
    
public voidsetConstructor(java.lang.reflect.Constructor c)
The Factory calls setConstructor.

        constructor = c;
    
private voidsetSimpleTypeAttributes()
Process any attributes we may have encountered (in onStartElement)

        if (attributeMap == null)
            return;
        
        // loop through map
        Set entries = attributeMap.entrySet();
        for (Iterator iterator = entries.iterator(); iterator.hasNext();) {
            Map.Entry entry = (Map.Entry) iterator.next();
            String name = (String) entry.getKey();
            Object val = entry.getValue();
            
            BeanPropertyDescriptor bpd =
                    (BeanPropertyDescriptor) propertyMap.get(name);
            if (!bpd.isWriteable() || bpd.isIndexed()) continue;
            try {
                bpd.set(value, val );
            } catch (Exception e) {
                throw new SAXException(e);
            }
        }