📄 deserializerimpl.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 org.apache.axis.Constants;import org.apache.axis.Part;import org.apache.axis.components.logger.LogFactory;import org.apache.axis.message.EnvelopeHandler;import org.apache.axis.message.MessageElement;import org.apache.axis.message.SAX2EventRecorder;import org.apache.axis.message.SAXOutputter;import org.apache.axis.message.SOAPHandler;import org.apache.axis.utils.Messages;import org.apache.axis.soap.SOAPConstants;import org.apache.commons.logging.Log;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;import javax.xml.namespace.QName;import java.io.StringWriter;import java.util.HashSet;import java.util.Vector;/** The Deserializer base class. * * @author Glen Daniels (gdaniels@allaire.com) * Re-architected for JAX-RPC Compliance by * @author Rich Scheuerle (sche@us.ibm.com) */public class DeserializerImpl extends SOAPHandler implements javax.xml.rpc.encoding.Deserializer, Deserializer, Callback{ protected static Log log = LogFactory.getLog(DeserializerImpl.class.getName()); protected Object value = null; // 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(); // isEnded is set when the endElement is called protected boolean isEnded = false; protected Vector targets = null; protected QName defaultType = null; protected boolean componentsReadyFlag = false; /** * A set of sub-deserializers whose values must complete before our * value is complete. */ private HashSet activeDeserializers = new HashSet(); protected boolean isHref = false; protected boolean isNil = false; // xsd:nil attribute is set to true protected String id = null; // Set to the id of the element public DeserializerImpl() { } /** * JAX-RPC compliant method which returns mechanism type. */ public String getMechanismType() { return Constants.AXIS_SAX; } /** * Get the deserialized value. * @return Object representing deserialized value or null */ public Object getValue() { return value; } /** * Set the deserialized value. * @param value Object representing deserialized value */ public void setValue(Object value) { this.value = value; } /** * If the deserializer has component values (like ArrayDeserializer) * this method gets the specific component via the hint. * The default implementation returns null. * @return Object representing deserialized value or null */ public Object getValue(Object hint) { return null; } /** * If the deserializer has component values (like ArrayDeserializer) * this method sets the specific component via the hint. * The default implementation does nothing. * @param hint Object representing deserialized value or null */ public void setChildValue(Object value, Object hint) throws SAXException { } public void setValue(Object value, Object hint) throws SAXException { if (hint instanceof Deserializer) { // This one's done activeDeserializers.remove(hint); // If we're past the end of our XML, and this is the last one, // our value has been assembled completely. if (componentsReady()) { // Got everything we need, call valueComplete() valueComplete(); } } } /** * In some circumstances an element may not have * a type attribute, but a default type qname is known from * information in the container. For example, * an element of an array may not have a type= attribute, * so the default qname is the component type of the array. * This method is used to communicate the default type information * to the deserializer. */ public void setDefaultType(QName qName) { defaultType = qName; } public QName getDefaultType() { return defaultType; } /** * For deserializers of non-primitives, the value may not be * known until later (due to multi-referencing). In such * cases the deserializer registers Target object(s). When * the value is known, the set(value) will be invoked for * each Target registered with the Deserializer. The Target * object abstracts the function of setting a target with a * value. See the Target interface for more info. * @param target */ public void registerValueTarget(Target target) { if (targets == null) { targets = new Vector(); } targets.addElement(target); } /** * Get the Value Targets of the Deserializer. * @return Vector of Target objects or null */ public Vector getValueTargets() { return targets; } /** * Remove the Value Targets of the Deserializer. */ public void removeValueTargets() { if (targets != null) { targets = null; } } /** * Move someone else's targets to our own (see DeserializationContext) * * The DeserializationContext only allows one Deserializer to * wait for a unknown multi-ref'ed value. So to ensure * that all of the targets are updated, this method is invoked * to copy the Target objects to the waiting Deserializer. * @param other is the Deserializer to copy targets from. */ public void moveValueTargets(Deserializer other) { if ((other == null) || (other.getValueTargets() == null)) { return; } if (targets == null) { targets = new Vector(); } targets.addAll(other.getValueTargets()); other.removeValueTargets(); } /** * Some deserializers (ArrayDeserializer) require * all of the component values to be known before the * value is complete. * (For the ArrayDeserializer this is important because * the elements are stored in an ArrayList, and all values * must be known before the ArrayList is converted into the * expected array. * * This routine is used to indicate when the components are ready. * The default (true) is useful for most Deserializers. */ public boolean componentsReady() { return (componentsReadyFlag || (!isHref && isEnded && activeDeserializers.isEmpty())); } /** * The valueComplete() method is invoked when the * end tag of the element is read. This results * in the setting of all registered Targets (see * registerValueTarget). * Note that the valueComplete() only processes * the Targets if componentReady() returns true. * So if you override componentReady(), then your * specific Deserializer will need to call valueComplete() * when your components are ready (See ArrayDeserializer) */ public void valueComplete() throws SAXException { if (componentsReady()) { if (targets != null) { for (int i = 0; i < targets.size(); i++) { Target target = (Target) targets.get(i); target.set(value); if (debugEnabled) { log.debug(Messages.getMessage("setValueInTarget00", "" + value, "" + target)); } } // Don't need targets any more, so clear them removeValueTargets(); } } } public void addChildDeserializer(Deserializer dSer) { // Keep track of our active deserializers. This enables us to figure // out whether or not we're really done in the case where we get to // our end tag, but still have open hrefs for members. if (activeDeserializers != null) { activeDeserializers.add(dSer); } // In concert with the above, we make sure each field deserializer // lets us know when it's done so we can take it off our list. dSer.registerValueTarget(new CallbackTarget(this, dSer)); } /** * Subclasses may override these */ /** * This method is invoked when an element start tag is encountered.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -