📄 beanserializer.java
字号:
/* * Copyright 2001-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.AxisFault;import org.apache.axis.Constants;import org.apache.axis.components.logger.LogFactory;import org.apache.axis.description.FieldDesc;import org.apache.axis.description.TypeDesc;import org.apache.axis.description.ElementDesc;import org.apache.axis.encoding.SerializationContext;import org.apache.axis.encoding.Serializer;import org.apache.axis.message.MessageElement;import org.apache.axis.utils.BeanPropertyDescriptor;import org.apache.axis.utils.BeanUtils;import org.apache.axis.utils.JavaUtils;import org.apache.axis.utils.Messages;import org.apache.axis.utils.FieldPropertyDescriptor;import org.apache.axis.wsdl.fromJava.Types;import org.apache.axis.wsdl.symbolTable.SchemaUtils;import org.apache.commons.logging.Log;import org.w3c.dom.Element;import org.xml.sax.Attributes;import org.xml.sax.helpers.AttributesImpl;import javax.xml.namespace.QName;import java.io.IOException;import java.io.Serializable;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Modifier;import java.lang.reflect.Constructor;import java.util.List;/** * General purpose serializer/deserializerFactory 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 BeanSerializer implements Serializer, Serializable { protected static Log log = LogFactory.getLog(BeanSerializer.class.getName()); private static final QName MUST_UNDERSTAND_QNAME = new QName(Constants.URI_SOAP11_ENV, Constants.ATTR_MUST_UNDERSTAND); private static final Object[] ZERO_ARGS = new Object [] { "0" }; QName xmlType; Class javaType; protected BeanPropertyDescriptor[] propertyDescriptor = null; protected TypeDesc typeDesc = null; // Construct BeanSerializer for the indicated class/qname public BeanSerializer(Class javaType, QName xmlType) { this(javaType, xmlType, TypeDesc.getTypeDescForClass(javaType)); } // Construct BeanSerializer for the indicated class/qname public BeanSerializer(Class javaType, QName xmlType, TypeDesc typeDesc) { this(javaType, xmlType, typeDesc, null); if (typeDesc != null) { propertyDescriptor = typeDesc.getPropertyDescriptors(); } else { propertyDescriptor = BeanUtils.getPd(javaType, null); } } // Construct BeanSerializer for the indicated class/qname/propertyDesc public BeanSerializer(Class javaType, QName xmlType, TypeDesc typeDesc, BeanPropertyDescriptor[] propertyDescriptor) { this.xmlType = xmlType; this.javaType = javaType; this.typeDesc = typeDesc; this.propertyDescriptor = propertyDescriptor; } /** * Serialize a bean. Done simply by serializing each bean property. * @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 { // Check for meta-data in the bean that will tell us if any of the // properties are actually attributes, add those to the element // attribute list Attributes beanAttrs = getObjectAttributes(value, attributes, context); // Get the encoding style boolean isEncoded = context.isEncoded(); // check whether we have and xsd:any namespace="##any" type boolean suppressElement = !isEncoded && name.getNamespaceURI().equals("") && name.getLocalPart().equals("any"); if (!suppressElement) context.startElement(name, beanAttrs); // check whether the array is converted to ArrayOfT shema type if (value != null && value.getClass().isArray()) { Object newVal = JavaUtils.convert(value, javaType); if (newVal != null && javaType.isAssignableFrom(newVal.getClass())) { value = newVal; } } try { // Serialize each property for (int i=0; i<propertyDescriptor.length; i++) { String propName = propertyDescriptor[i].getName(); if (propName.equals("class")) continue; QName qname = null; QName xmlType = null; Class javaType = propertyDescriptor[i].getType(); boolean isOmittable = false; // isNillable default value depends on the field type boolean isNillable = Types.isNullable(javaType); // isArray boolean isArray = false; QName itemQName = null; // If we have type metadata, check to see what we're doing // with this field. If it's an attribute, skip it. If it's // an element, use whatever qname is in there. If we can't // find any of this info, use the default. if (typeDesc != null) { FieldDesc field = typeDesc.getFieldByName(propName); if (field != null) { if (!field.isElement()) { continue; } ElementDesc element = (ElementDesc)field; // If we're SOAP encoded, just use the local part, // not the namespace. Otherwise use the whole // QName. if (isEncoded) { qname = new QName(element.getXmlName().getLocalPart()); } else { qname = element.getXmlName(); } isOmittable = element.isMinOccursZero(); isNillable = element.isNillable(); isArray = element.isMaxOccursUnbounded(); xmlType = element.getXmlType(); itemQName = element.getItemQName(); context.setItemQName(itemQName); } } if (qname == null) { qname = new QName(isEncoded ? "" : name.getNamespaceURI(), propName); } if (xmlType == null) { // look up the type QName using the class xmlType = context.getQNameForClass(javaType); } // Read the value from the property if (propertyDescriptor[i].isReadable()) { if (itemQName != null || (!propertyDescriptor[i].isIndexed() && !isArray)) { // Normal case: serialize the value Object propValue = propertyDescriptor[i].get(value); if (propValue == null) { // an element cannot be null if nillable property is set to // "false" and the element cannot be omitted if (!isNillable && !isOmittable) { if (Number.class.isAssignableFrom(javaType)) { // If we have a null and it's a number, though, // we might turn it into the appropriate kind of 0. // TODO : Should be caching these constructors? try { Constructor constructor = javaType.getConstructor( SimpleDeserializer.STRING_CLASS); propValue = constructor.newInstance(ZERO_ARGS); } catch (Exception e) { // If anything goes wrong here, oh well we tried. } } if (propValue == null) { throw new IOException( Messages.getMessage( "nullNonNillableElement", propName)); } } // if meta data says minOccurs=0, then we can skip // it if its value is null and we aren't doing SOAP // encoding. if (isOmittable && !isEncoded) { continue; } } context.serialize(qname, null, propValue, xmlType, javaType); } else { // Collection of properties: serialize each one int j=0; while(j >= 0) { Object propValue = null; try { propValue = propertyDescriptor[i].get(value, j); j++; } catch (Exception e) { j = -1; } if (j >= 0) { context.serialize(qname, null, propValue, xmlType, propertyDescriptor[i].getType()); } } } } } BeanPropertyDescriptor anyDesc = typeDesc == null ? null : typeDesc.getAnyDesc(); if (anyDesc != null) { // If we have "extra" content here, it'll be an array // of MessageElements. Serialize each one. Object anyVal = anyDesc.get(value); if (anyVal != null && anyVal instanceof MessageElement[]) { MessageElement [] anyContent = (MessageElement[])anyVal; for (int i = 0; i < anyContent.length; i++) { MessageElement element = anyContent[i]; element.output(context); } } } } catch (InvocationTargetException ite) { Throwable target = ite.getTargetException(); log.error(Messages.getMessage("exception00"), target); throw new IOException(target.toString()); } catch (Exception e) { log.error(Messages.getMessage("exception00"), e); throw new IOException(e.toString()); } if (!suppressElement) context.endElement(); } public String getMechanismType() { return Constants.AXIS_SAX; } /** * Return XML schema for the specified type, suitable for insertion into * the <types> element of a WSDL document, or underneath an * <element> or <attribute> declaration. * * @param javaType the Java Class we're writing out schema for * @param types the Java2WSDL Types object which holds the context * for the WSDL being generated. * @return a type element containing a schema simpleType/complexType * @see org.apache.axis.wsdl.fromJava.Types */ public Element writeSchema(Class javaType, Types types) throws Exception { // ComplexType representation of bean class Element complexType = types.createElement("complexType"); // See if there is a super class, stop if we hit a stop class Element e = null; Class superClass = javaType.getSuperclass(); BeanPropertyDescriptor[] superPd = null; List stopClasses = types.getStopClasses(); if (superClass != null && superClass != java.lang.Object.class && superClass != java.lang.Exception.class && superClass != java.lang.Throwable.class && superClass != java.lang.RuntimeException.class && superClass != java.rmi.RemoteException.class && superClass != org.apache.axis.AxisFault.class && (stopClasses == null || !(stopClasses.contains(superClass.getName()))) ) { // Write out the super class String base = types.writeType(superClass); Element complexContent = types.createElement("complexContent"); complexType.appendChild(complexContent); Element extension = types.createElement("extension"); complexContent.appendChild(extension); extension.setAttribute("base", base); e = extension; // Get the property descriptors for the super class TypeDesc superTypeDesc = TypeDesc.getTypeDescForClass(superClass); if (superTypeDesc != null) { superPd = superTypeDesc.getPropertyDescriptors();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -