📄 beandeserializer.java
字号:
/* * Copyright 2001-2002,2004 The Apache Software Foundation. * * Licensed 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.axis.encoding.ser;import org.apache.axis.Constants;import org.apache.axis.components.logger.LogFactory;import org.apache.axis.description.ElementDesc;import org.apache.axis.description.FieldDesc;import org.apache.axis.description.TypeDesc;import org.apache.axis.encoding.ConstructorTarget;import org.apache.axis.encoding.DeserializationContext;import org.apache.axis.encoding.Deserializer;import org.apache.axis.encoding.DeserializerImpl;import org.apache.axis.encoding.Target;import org.apache.axis.encoding.TypeMapping;import org.apache.axis.message.MessageElement;import org.apache.axis.message.SOAPHandler;import org.apache.axis.soap.SOAPConstants;import org.apache.axis.utils.BeanPropertyDescriptor;import org.apache.axis.utils.Messages;import org.apache.commons.logging.Log;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import javax.xml.namespace.QName;import java.io.CharArrayWriter;import java.io.Serializable;import java.lang.reflect.Constructor;import java.util.Map;/** * General purpose deserializer for an arbitrary java bean. * * @author Sam Ruby <rubys@us.ibm.com> * @author Rich Scheuerle <scheu@us.ibm.com> * @author Tom Jordahl <tomj@macromedia.com> */public class BeanDeserializer extends DeserializerImpl implements Serializable{ protected static Log log = LogFactory.getLog(BeanDeserializer.class.getName()); private final CharArrayWriter val = new CharArrayWriter(); QName xmlType; Class javaType; protected Map propertyMap = null; protected QName prevQName; /** * Constructor if no default constructor */ protected Constructor constructorToUse = null; /** * Constructor Target object to use (if constructorToUse != null) */ protected Target constructorTarget = null; /** Type metadata about this class for XML deserialization */ protected TypeDesc typeDesc = null; // This counter is updated to deal with deserialize collection properties protected int collectionIndex = -1; protected SimpleDeserializer cacheStringDSer = null; protected QName cacheXMLType = null; // Construct BeanSerializer for the indicated class/qname public BeanDeserializer(Class javaType, QName xmlType) { this(javaType, xmlType, TypeDesc.getTypeDescForClass(javaType)); } // Construct BeanDeserializer for the indicated class/qname and meta Data public BeanDeserializer(Class javaType, QName xmlType, TypeDesc typeDesc ) { this(javaType, xmlType, typeDesc, BeanDeserializerFactory.getProperties(javaType, typeDesc)); } // Construct BeanDeserializer for the indicated class/qname and meta Data public BeanDeserializer(Class javaType, QName xmlType, TypeDesc typeDesc, Map propertyMap ) { this.xmlType = xmlType; this.javaType = javaType; this.typeDesc = typeDesc; this.propertyMap = propertyMap; // create a value try { value=javaType.newInstance(); } catch (Exception e) { // Don't process the exception at this point. // This is defered until the call to startElement // which will throw the exception. } } /** * startElement * * The ONLY reason that this method is overridden is so that * the object value can be set or a reasonable exception is thrown * indicating that the object cannot be created. This is done * at this point so that it occurs BEFORE href/id processing. * @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 */ public void startElement(String namespace, String localName, String prefix, Attributes attributes, DeserializationContext context) throws SAXException { // Create the bean object if it was not already // created in the constructor. if (value == null) { try { value=javaType.newInstance(); } catch (Exception e) { // Use first found constructor. // Note : the right way is to use XML mapping information // for example JSR 109's constructor-parameter-order Constructor[] constructors = javaType.getConstructors(); if (constructors.length > 0) { constructorToUse = constructors[0]; } // Failed to create an object if no constructor if (constructorToUse == null) { throw new SAXException(Messages.getMessage("cantCreateBean00", javaType.getName(), e.toString())); } } } // Invoke super.startElement to do the href/id processing. super.startElement(namespace, localName, prefix, attributes, context); } /** * 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. */ 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); } // try and see if this is an xsd:any namespace="##any" element before // 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); // if this is the first pass through the MessageContexts // make sure that the correct any element is set, // that is the child of the current MessageElement, however // on the first pass this child has not been set yet, so // 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -