📄 serializationcontext.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;import java.io.IOException;import java.io.Writer;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Calendar;import java.util.Date;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.Stack;import javax.xml.namespace.QName;import javax.xml.rpc.JAXRPCException;import javax.xml.rpc.holders.QNameHolder;import org.apache.axis.AxisEngine;import org.apache.axis.AxisProperties;import org.apache.axis.Constants;import org.apache.axis.Message;import org.apache.axis.MessageContext;import org.apache.axis.attachments.Attachments;import org.apache.axis.client.Call;import org.apache.axis.components.encoding.XMLEncoder;import org.apache.axis.components.encoding.XMLEncoderFactory;import org.apache.axis.components.logger.LogFactory;import org.apache.axis.constants.Use;import org.apache.axis.description.OperationDesc;import org.apache.axis.description.TypeDesc;import org.apache.axis.encoding.ser.ArraySerializer;import org.apache.axis.encoding.ser.BaseSerializerFactory;import org.apache.axis.encoding.ser.SimpleListSerializerFactory;import org.apache.axis.handlers.soap.SOAPService;import org.apache.axis.schema.SchemaVersion;import org.apache.axis.soap.SOAPConstants;import org.apache.axis.types.HexBinary;import org.apache.axis.utils.IDKey;import org.apache.axis.utils.JavaUtils;import org.apache.axis.utils.Mapping;import org.apache.axis.utils.Messages;import org.apache.axis.utils.NSStack;import org.apache.axis.utils.XMLUtils;import org.apache.axis.utils.cache.MethodCache;import org.apache.axis.wsdl.symbolTable.SchemaUtils;import org.apache.axis.wsdl.symbolTable.SymbolTable;import org.apache.axis.wsdl.symbolTable.Utils;import org.apache.commons.logging.Log;import org.w3c.dom.Attr;import org.w3c.dom.CDATASection;import org.w3c.dom.CharacterData;import org.w3c.dom.Comment;import org.w3c.dom.Element;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.w3c.dom.Text;import org.xml.sax.Attributes;import org.xml.sax.helpers.AttributesImpl;/** Manage a serialization, including keeping track of namespace mappings * and element stacks. * * @author Glen Daniels (gdaniels@apache.org) * @author Rich Scheuerle <scheu@us.ibm.com> */public class SerializationContext implements javax.xml.rpc.encoding.SerializationContext{ protected static Log log = LogFactory.getLog(SerializationContext.class.getName()); // invariant member variable to track low-level logging requirements // we cache this once per instance lifecycle to avoid repeated lookups // in heavily used code. private final boolean debugEnabled = log.isDebugEnabled(); private NSStack nsStack = null; private boolean writingStartTag = false; private boolean onlyXML = true; private int indent=0; private Stack elementStack = new Stack(); private Writer writer; private int lastPrefixIndex = 1; private MessageContext msgContext; private QName currentXMLType; /** The item QName if we're serializing a literal array... */ private QName itemQName; /** The item type if we're serializing a literal array... */ private QName itemType; /** The SOAP context we're using */ private SOAPConstants soapConstants = SOAPConstants.SOAP11_CONSTANTS; private static QName multirefQName = new QName("","multiRef"); private static Class[] SERIALIZER_CLASSES = new Class[] {String.class, Class.class, QName.class}; private static final String SERIALIZER_METHOD = "getSerializer"; /** * Should I write out objects as multi-refs? * * !!! For now, this is an all-or-nothing flag. Either ALL objects will * be written in-place as hrefs with the full serialization at the end * of the body, or we'll write everything inline (potentially repeating * serializations of identical objects). */ private boolean doMultiRefs = false; /** * Should I disable the pretty xml completely. */ private boolean disablePrettyXML = false; /** * Should I disable the namespace prefix optimization. */ private boolean enableNamespacePrefixOptimization = false; /** * current setting for pretty */ private boolean pretty = false; /** * Should I send an XML declaration? */ private boolean sendXMLDecl = true; /** * Should I send xsi:type attributes? By default, yes. */ private boolean sendXSIType = true; /** * Send an element with an xsi:nil="true" attribute for null * variables (if Boolean.TRUE), or nothing (if Boolean.FALSE). */ private Boolean sendNull = Boolean.TRUE; /** * A place to hold objects we cache for multi-ref serialization, and * remember the IDs we assigned them. */ private HashMap multiRefValues = null; private int multiRefIndex = -1; private boolean noNamespaceMappings = true; private QName writeXMLType; private XMLEncoder encoder = null; /** The flag whether the XML decl should be written */ protected boolean startOfDocument = true; /** The encoding to serialize */ private String encoding = XMLEncoderFactory.DEFAULT_ENCODING; class MultiRefItem { String id; QName xmlType; Boolean sendType; Object value; MultiRefItem(String id, QName xmlType, Boolean sendType, Object value) { this.id = id; this.xmlType = xmlType; this.sendType = sendType; this.value = value; } } /** * These three variables are necessary to process * multi-level object graphs for multi-ref serialization. * While writing out nested multi-ref objects (via outputMultiRef), we * will fill the secondLevelObjects vector * with any new objects encountered. * The outputMultiRefsFlag indicates whether we are currently within the * outputMultiRef() method (so that serialization() knows to update the * secondLevelObjects vector). * The forceSer variable is the trigger to force actual serialization of the indicated object. */ private HashSet secondLevelObjects = null; private Object forceSer = null; private boolean outputMultiRefsFlag = false; /** * Which schema version are we using? */ SchemaVersion schemaVersion = SchemaVersion.SCHEMA_2001; /** * A list of particular namespace -> prefix mappings we should prefer. * See getPrefixForURI() below. */ HashMap preferredPrefixes = new HashMap(); /** * Construct SerializationContext with associated writer * @param writer java.io.Writer */ public SerializationContext(Writer writer) { this.writer = writer; initialize(); } private void initialize() { // These are the preferred prefixes we'll use instead of the "ns1" // style defaults. MAKE SURE soapConstants IS SET CORRECTLY FIRST! preferredPrefixes.put(soapConstants.getEncodingURI(), Constants.NS_PREFIX_SOAP_ENC); preferredPrefixes.put(Constants.NS_URI_XML, Constants.NS_PREFIX_XML); preferredPrefixes.put(schemaVersion.getXsdURI(), Constants.NS_PREFIX_SCHEMA_XSD); preferredPrefixes.put(schemaVersion.getXsiURI(), Constants.NS_PREFIX_SCHEMA_XSI); preferredPrefixes.put(soapConstants.getEnvelopeURI(), Constants.NS_PREFIX_SOAP_ENV); nsStack = new NSStack(enableNamespacePrefixOptimization); } /** * Construct SerializationContext with associated writer and MessageContext * @param writer java.io.Writer * @param msgContext is the MessageContext */ public SerializationContext(Writer writer, MessageContext msgContext) { this.writer = writer; this.msgContext = msgContext; if ( msgContext != null ) { soapConstants = msgContext.getSOAPConstants(); // Use whatever schema is associated with this MC schemaVersion = msgContext.getSchemaVersion(); Boolean shouldSendDecl = (Boolean)msgContext.getProperty( AxisEngine.PROP_XML_DECL); if (shouldSendDecl != null) sendXMLDecl = shouldSendDecl.booleanValue(); Boolean shouldSendMultiRefs = (Boolean)msgContext.getProperty(AxisEngine.PROP_DOMULTIREFS); if (shouldSendMultiRefs != null) doMultiRefs = shouldSendMultiRefs.booleanValue(); Boolean shouldDisablePrettyXML = (Boolean)msgContext.getProperty(AxisEngine.PROP_DISABLE_PRETTY_XML); if (shouldDisablePrettyXML != null) disablePrettyXML = shouldDisablePrettyXML.booleanValue(); Boolean shouldDisableNamespacePrefixOptimization = (Boolean)msgContext.getProperty(AxisEngine.PROP_ENABLE_NAMESPACE_PREFIX_OPTIMIZATION); if (shouldDisableNamespacePrefixOptimization != null) { enableNamespacePrefixOptimization = shouldDisableNamespacePrefixOptimization.booleanValue(); } else { enableNamespacePrefixOptimization = JavaUtils.isTrue(AxisProperties.getProperty(AxisEngine.PROP_ENABLE_NAMESPACE_PREFIX_OPTIMIZATION, "true")); } boolean sendTypesDefault = sendXSIType; // A Literal use operation overrides the above settings. Don't // send xsi:type, and don't do multiref in that case. OperationDesc operation = msgContext.getOperation(); if (operation != null) { if (operation.getUse() != Use.ENCODED) { doMultiRefs = false; sendTypesDefault = false; } } else { // A Literal use service also overrides the above settings. SOAPService service = msgContext.getService(); if (service != null) { if (service.getUse() != Use.ENCODED) { doMultiRefs = false; sendTypesDefault = false; } } } // The SEND_TYPE_ATTR and PROP_SEND_XSI options indicate // whether the elements should have xsi:type attributes. // Only turn this off is the user tells us to if ( !msgContext.isPropertyTrue(Call.SEND_TYPE_ATTR, sendTypesDefault )) sendXSIType = false ;// Don't need this since the above isPropertyTrue should walk up to the engine's// properties...?// // Boolean opt = (Boolean)optionSource.getOption(AxisEngine.PROP_SEND_XSI);// if (opt != null) {// sendXSIType = opt.booleanValue();// } } else { enableNamespacePrefixOptimization = JavaUtils.isTrue(AxisProperties.getProperty(AxisEngine.PROP_ENABLE_NAMESPACE_PREFIX_OPTIMIZATION, "true")); disablePrettyXML = JavaUtils.isTrue(AxisProperties.getProperty(AxisEngine.PROP_DISABLE_PRETTY_XML, "true")); } // Set up preferred prefixes based on current schema, soap ver, etc. initialize(); } /** * Get whether the serialization should be pretty printed. * @return true/false */ public boolean getPretty() { return pretty; } /** * Indicate whether the serialization should be pretty printed. * @param pretty true/false */ public void setPretty(boolean pretty) { if(!disablePrettyXML) { this.pretty = pretty;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -