📄 arrayserializer.java
字号:
/* * Copyright 2001-2005 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 java.io.IOException;import java.lang.reflect.Array;import java.util.Collection;import java.util.Iterator;import javax.xml.namespace.QName;import org.w3c.dom.Element;import org.xml.sax.Attributes;import org.xml.sax.helpers.AttributesImpl;import org.apache.axis.AxisEngine;import org.apache.axis.Constants;import org.apache.axis.MessageContext;import org.apache.axis.components.logger.LogFactory;import org.apache.axis.constants.Use;import org.apache.axis.encoding.SerializationContext;import org.apache.axis.encoding.Serializer;import org.apache.axis.encoding.SerializerFactory;import org.apache.axis.encoding.TypeMapping;import org.apache.axis.schema.SchemaVersion;import org.apache.axis.soap.SOAPConstants;import org.apache.axis.utils.JavaUtils;import org.apache.axis.utils.Messages;import org.apache.axis.wsdl.fromJava.Types;import org.apache.commons.logging.Log;/** * An ArraySerializer handles serializing of arrays. * * Some code borrowed from ApacheSOAP - thanks to Matt Duftler! * * @author Glen Daniels (gdaniels@apache.org) * * Multi-reference stuff: * @author Rich Scheuerle (scheu@us.ibm.com) */public class ArraySerializer implements Serializer{ QName xmlType = null; Class javaType = null; QName componentType = null; QName componentQName = null; /** * Constructor * */ public ArraySerializer(Class javaType, QName xmlType) { this.javaType = javaType; this.xmlType = xmlType; } /** * Constructor * Special constructor that takes the component type of the array. */ public ArraySerializer(Class javaType, QName xmlType, QName componentType) { this(javaType, xmlType); this.componentType = componentType; } /** * Constructor * Special constructor that takes the component type and QName of the array. */ public ArraySerializer(Class javaType, QName xmlType, QName componentType, QName componentQName) { this(javaType, xmlType, componentType); this.componentQName = componentQName; } protected static Log log = LogFactory.getLog(ArraySerializer.class.getName()); /** * Serialize an element that is an array. * @param name is the element name * @param attributes are the attributes...serialize is free to add more. * @param value is the value * @param context is the SerializationContext */ public void serialize(QName name, Attributes attributes, Object value, SerializationContext context) throws IOException { if (value == null) throw new IOException(Messages.getMessage("cantDoNullArray00")); MessageContext msgContext = context.getMessageContext(); SchemaVersion schema = SchemaVersion.SCHEMA_2001; SOAPConstants soap = SOAPConstants.SOAP11_CONSTANTS; boolean encoded = context.isEncoded(); if (msgContext != null) { schema = msgContext.getSchemaVersion(); soap = msgContext.getSOAPConstants(); } Class cls = value.getClass(); Collection list = null; if (!cls.isArray()) { if (!(value instanceof Collection)) { throw new IOException( Messages.getMessage("cantSerialize00", cls.getName())); } list = (Collection)value; } // Get the componentType of the array/list Class componentClass; if (list == null) { componentClass = cls.getComponentType(); } else { componentClass = Object.class; } // Get the QName of the componentType // if it wasn't passed in from the constructor QName componentTypeQName = this.componentType; // Check to see if componentType is also an array. // If so, set the componentType to the most nested non-array // componentType. Increase the dims string by "[]" // each time through the loop. // Note from Rich Scheuerle: // This won't handle Lists of Lists or // arrays of Lists....only arrays of arrays. String dims = ""; if (componentTypeQName != null) { // if we have a Type QName at this point, // this is because ArraySerializer has been instanciated with it TypeMapping tm = context.getTypeMapping(); SerializerFactory factory = (SerializerFactory) tm.getSerializer( componentClass, componentTypeQName); while (componentClass.isArray() && factory instanceof ArraySerializerFactory) { ArraySerializerFactory asf = (ArraySerializerFactory) factory; componentClass = componentClass.getComponentType(); QName componentType = null; if (asf.getComponentType() != null) { componentType = asf.getComponentType(); if(encoded) { componentTypeQName = componentType; } } // update factory with the new values factory = (SerializerFactory) tm.getSerializer(componentClass, componentType); if (soap == SOAPConstants.SOAP12_CONSTANTS) dims += "* "; else dims += "[]"; } } else { // compatibility mode while (componentClass.isArray()) { componentClass = componentClass.getComponentType(); if (soap == SOAPConstants.SOAP12_CONSTANTS) dims += "* "; else dims += "[]"; } } // Try the current XML type from the context if (componentTypeQName == null) { componentTypeQName = context.getCurrentXMLType(); if (componentTypeQName != null) { if ((componentTypeQName.equals(xmlType) || componentTypeQName.equals(Constants.XSD_ANYTYPE) || componentTypeQName.equals(soap.getArrayType()))) { componentTypeQName = null; } } } if (componentTypeQName == null) { componentTypeQName = context.getItemType(); } // Then check the type mapping for the class if (componentTypeQName == null) { componentTypeQName = context.getQNameForClass(componentClass); } // If still not found, look at the super classes if (componentTypeQName == null) { Class searchCls = componentClass; while(searchCls != null && componentTypeQName == null) { searchCls = searchCls.getSuperclass(); componentTypeQName = context.getQNameForClass(searchCls); } if (componentTypeQName != null) { componentClass = searchCls; } } // Still can't find it? Throw an error. if (componentTypeQName == null) { throw new IOException( Messages.getMessage("noType00", componentClass.getName())); } int len = (list == null) ? Array.getLength(value) : list.size(); String arrayType = ""; int dim2Len = -1; if (encoded) { if (soap == SOAPConstants.SOAP12_CONSTANTS) { arrayType = dims + len; } else { arrayType = dims + "[" + len + "]"; } // Discover whether array can be serialized directly as a two-dimensional // array (i.e. arrayType=int[2,3]) versus an array of arrays. // Benefits: // - Less text passed on the wire. // - Easier to read wire format // - Tests the deserialization of multi-dimensional arrays. // Drawbacks: // - Is not safe! It is possible that the arrays are multiply // referenced. Transforming into a 2-dim array will cause the // multi-referenced information to be lost. Plus there is no // way to determine whether the arrays are multi-referenced. // - .NET currently (Dec 2002) does not support 2D SOAP-encoded arrays // // OLD Comment as to why this was ENABLED: // It is necessary for // interoperability (echo2DStringArray). It is 'safe' for now // because Axis treats arrays as non multi-ref (see the note // in SerializationContext.isPrimitive(...) ) // More complicated processing is necessary for 3-dim arrays, etc. // // Axis 1.1 - December 2002 // Turned this OFF because Microsoft .NET can not deserialize // multi-dimensional SOAP-encoded arrays, and this interopability // is pretty high visibility. Make it a global configuration parameter: // <parameter name="enable2DArrayEncoding" value="true"/> (tomj) // // Check the message context to see if we should turn 2D processing ON // Default is OFF boolean enable2Dim = false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -