Search in sources :

Example 1 with ElementDesc

use of org.apache.axis.description.ElementDesc in project Lucee by lucee.

the class BeanDeserializer method onStartChild.

/**
 * Deserializer interface called on each child element encountered in
 * the XML stream.
 * @param namespace is the namespace of the child element
 * @param localName is the local name of the child element
 * @param prefix is the prefix used on the name of the child element
 * @param attributes are the attributes of the child element
 * @param context is the deserialization context.
 * @return is a Deserializer to use to deserialize a child (must be
 * a derived class of SOAPHandler) or null if no deserialization should
 * be performed.
 */
@Override
public SOAPHandler onStartChild(String namespace, String localName, String prefix, Attributes attributes, DeserializationContext context) throws SAXException {
    handleMixedContent();
    BeanPropertyDescriptor propDesc = null;
    FieldDesc fieldDesc = null;
    SOAPConstants soapConstants = context.getSOAPConstants();
    String encodingStyle = context.getEncodingStyle();
    boolean isEncoded = Constants.isSOAP_ENC(encodingStyle);
    QName elemQName = new QName(namespace, localName);
    // The collectionIndex needs to be reset for Beans with multiple arrays
    if ((prevQName == null) || (!prevQName.equals(elemQName))) {
        collectionIndex = -1;
    }
    boolean isArray = false;
    QName itemQName = null;
    if (typeDesc != null) {
        // Lookup the name appropriately (assuming an unqualified
        // name for SOAP encoding, using the namespace otherwise)
        String fieldName = typeDesc.getFieldNameForElement(elemQName, isEncoded);
        propDesc = (BeanPropertyDescriptor) propertyMap.get(fieldName);
        fieldDesc = typeDesc.getFieldByName(fieldName);
        if (fieldDesc != null) {
            ElementDesc element = (ElementDesc) fieldDesc;
            isArray = element.isMaxOccursUnbounded();
            itemQName = element.getItemQName();
        }
    }
    if (propDesc == null) {
        // look for a field by this name.
        propDesc = (BeanPropertyDescriptor) propertyMap.get(localName);
    }
    // Workaround
    if (propDesc == null) {
        StringBuilder sb = new StringBuilder();
        sb.append(Character.toLowerCase(localName.charAt(0)));
        if (localName.length() > 1)
            sb.append(localName.substring(1));
        // look for a field by this name.
        propDesc = (BeanPropertyDescriptor) propertyMap.get(sb.toString());
    }
    // reporting a problem
    if (propDesc == null || (((prevQName != null) && prevQName.equals(elemQName) && !(propDesc.isIndexed() || isArray) && getAnyPropertyDesc() != null))) {
        // try to put unknown elements into a SOAPElement property, if
        // appropriate
        prevQName = elemQName;
        propDesc = getAnyPropertyDesc();
        if (propDesc != null) {
            try {
                MessageElement[] curElements = (MessageElement[]) propDesc.get(value);
                int length = 0;
                if (curElements != null) {
                    length = curElements.length;
                }
                MessageElement[] newElements = new MessageElement[length + 1];
                if (curElements != null) {
                    System.arraycopy(curElements, 0, newElements, 0, length);
                }
                MessageElement thisEl = context.getCurElement();
                newElements[length] = thisEl;
                propDesc.set(value, newElements);
                // defer it to the child SOAPHandler
                if (!localName.equals(thisEl.getName())) {
                    return new SOAPHandler(newElements, length);
                }
                return new SOAPHandler();
            } catch (Exception e) {
                throw new SAXException(e);
            }
        }
    }
    if (propDesc == null) {
        // No such field
        throw new SAXException(Messages.getMessage("badElem00", javaType.getName(), localName));
    }
    prevQName = elemQName;
    // Get the child's xsi:type if available
    QName childXMLType = context.getTypeFromAttributes(namespace, localName, attributes);
    String href = attributes.getValue(soapConstants.getAttrHref());
    Class fieldType = propDesc.getType();
    // If no xsi:type or href, check the meta-data for the field
    if (childXMLType == null && fieldDesc != null && href == null) {
        childXMLType = fieldDesc.getXmlType();
        if (itemQName != null) {
            // This is actually a wrapped literal array and should be
            // deserialized with the ArrayDeserializer
            childXMLType = Constants.SOAP_ARRAY;
            fieldType = propDesc.getActualType();
        } else {
            childXMLType = fieldDesc.getXmlType();
        }
    }
    // Get Deserializer for child, default to using DeserializerImpl
    Deserializer dSer = getDeserializer(childXMLType, fieldType, href, context);
    // no good metadata).
    if (dSer == null) {
        dSer = context.getDeserializerForClass(propDesc.getType());
    }
    // Fastpath nil checks...
    if (context.isNil(attributes)) {
        if ((propDesc.isIndexed() || isArray)) {
            if (!((dSer != null) && (dSer instanceof ArrayDeserializer))) {
                collectionIndex++;
                dSer.registerValueTarget(new BeanPropertyTarget(value, propDesc, collectionIndex));
                addChildDeserializer(dSer);
                return (SOAPHandler) dSer;
            }
        }
        return null;
    }
    if (dSer == null) {
        throw new SAXException(Messages.getMessage("noDeser00", childXMLType.toString()));
    }
    if (constructorToUse != null) {
        if (constructorTarget == null) {
            constructorTarget = new ConstructorTarget(constructorToUse, this);
        }
        dSer.registerValueTarget(constructorTarget);
    } else if (propDesc.isWriteable()) {
        // Register value target
        if ((itemQName != null || propDesc.isIndexed() || isArray) && !(dSer instanceof ArrayDeserializer)) {
            collectionIndex++;
            dSer.registerValueTarget(new BeanPropertyTarget(value, propDesc, collectionIndex));
        } else {
            // If we're here, the element maps to a single field value,
            // whether that be a "basic" type or an array, so use the
            // normal (non-indexed) BeanPropertyTarget form.
            collectionIndex = -1;
            dSer.registerValueTarget(new BeanPropertyTarget(value, propDesc));
        }
    }
    // Let the framework know that we need this deserializer to complete
    // for the bean to complete.
    addChildDeserializer(dSer);
    return (SOAPHandler) dSer;
}
Also used : ElementDesc(org.apache.axis.description.ElementDesc) QName(javax.xml.namespace.QName) MessageElement(org.apache.axis.message.MessageElement) SOAPHandler(org.apache.axis.message.SOAPHandler) SAXException(org.xml.sax.SAXException) BeanPropertyDescriptor(org.apache.axis.utils.BeanPropertyDescriptor) SAXException(org.xml.sax.SAXException) Deserializer(org.apache.axis.encoding.Deserializer) ConstructorTarget(org.apache.axis.encoding.ConstructorTarget) SOAPConstants(org.apache.axis.soap.SOAPConstants) FieldDesc(org.apache.axis.description.FieldDesc)

Aggregations

QName (javax.xml.namespace.QName)1 ElementDesc (org.apache.axis.description.ElementDesc)1 FieldDesc (org.apache.axis.description.FieldDesc)1 ConstructorTarget (org.apache.axis.encoding.ConstructorTarget)1 Deserializer (org.apache.axis.encoding.Deserializer)1 MessageElement (org.apache.axis.message.MessageElement)1 SOAPHandler (org.apache.axis.message.SOAPHandler)1 SOAPConstants (org.apache.axis.soap.SOAPConstants)1 BeanPropertyDescriptor (org.apache.axis.utils.BeanPropertyDescriptor)1 SAXException (org.xml.sax.SAXException)1