📄 deserializerimpl.java
字号:
* DeserializerImpl provides default behavior, which involves the following: * - directly handling the deserialization of a nill value * - handling the registration of the id value. * - handling the registration of a fixup if this element is an href. * - calling onStartElement to do the actual deserialization if not nill or href cases. * @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 * * Normally a specific Deserializer (FooDeserializer) should extend DeserializerImpl. * Here is the flow that will occur in such cases: * 1) DeserializerImpl.startElement(...) will be called and do the id/href/nill stuff. * 2) If real deserialization needs to take place DeserializerImpl.onStartElement will be * invoked, which will attempt to install the specific Deserializer (FooDeserializer) * 3) The FooDeserializer.startElement(...) will be called to do the Foo specific stuff. * This results in a call to FooDeserializer.onStartElement(...) if startElement was * not overridden. * 4) The onChildElement(...) method is called for each child element. Nothing occurs * if not overridden. The FooDeserializer.onStartChild(...) method should return * the deserializer for the child element. * 5) When the end tag is reached, the endElement(..) method is invoked. The default * behavior is to handle hrefs/ids, call onEndElement and then call the Deserializer * valueComplete method. * * So the methods that you potentially want to override are: * onStartElement, onStartChild, componentsReady, setValue(object, hint) * You probably should not override startElement or endElement. * If you need specific behaviour at the end of the element consider overriding * onEndElement. * * See the pre-existing Deserializers for more information. */ public void startElement(String namespace, String localName, String prefix, Attributes attributes, DeserializationContext context) throws SAXException { super.startElement(namespace, localName, prefix, attributes, context); // If the nil attribute is present and true, set the value to null // and return since there is nothing to deserialize. if (context.isNil(attributes)) { value = null; isNil = true; return; } SOAPConstants soapConstants = context.getSOAPConstants(); // If this element has an id, then associate the value with the id. // (Prior to this association, the MessageElement of the element is // associated with the id. Failure to replace the MessageElement at this // point will cause an infinite loop during deserialization if the // current element contains child elements that cause an href back to this id.) // Also note that that endElement() method is responsible for the final // association of this id with the completed value. id = attributes.getValue("id"); if (id != null) { context.addObjectById(id, value); if (debugEnabled) { log.debug(Messages.getMessage("deserInitPutValueDebug00", "" + value, id)); } context.registerFixup("#" + id, this); } String href = attributes.getValue(soapConstants.getAttrHref()); if (href != null) { isHref = true; Object ref = context.getObjectByRef(href); if (debugEnabled) { log.debug(Messages.getMessage( "gotForID00", new String[] {"" + ref, href, (ref == null ? "*null*" : ref.getClass().toString())})); } if (ref == null) { // Nothing yet... register for later interest. context.registerFixup(href, this); return; } if (ref instanceof MessageElement) { context.replaceElementHandler(new EnvelopeHandler(this)); SAX2EventRecorder r = context.getRecorder(); context.setRecorder(null); ((MessageElement)ref).publishToHandler((DefaultHandler) context); context.setRecorder(r); } else { if( !href.startsWith("#") && defaultType != null && ref instanceof Part ){ //For attachments this is the end of the road-- invoke deserializer Deserializer dser = context.getDeserializerForType(defaultType ); if(null != dser){ dser.startElement(namespace, localName, prefix, attributes, context); ref = dser.getValue(); } } // If the ref is not a MessageElement, then it must be an // element that has already been deserialized. Use it directly. value = ref; componentsReadyFlag = true; valueComplete(); } } else { isHref = false; onStartElement(namespace, localName, prefix, attributes, context); } } /** * This method is invoked after startElement when the element requires * deserialization (i.e. the element is not an href and the value is not nil.) * DeserializerImpl provides default behavior, which simply * involves obtaining a correct Deserializer and plugging its handler. * @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 onStartElement(String namespace, String localName, String prefix, Attributes attributes, DeserializationContext context) throws SAXException { // If I'm the base class, try replacing myself with an // appropriate deserializer gleaned from type info. if (this.getClass().equals(DeserializerImpl.class)) { QName type = context.getTypeFromAttributes(namespace, localName, attributes); // If no type is specified, use the defaultType if available. // xsd:string is used if no type is provided. if (type == null) { type = defaultType; if (type == null) { type = Constants.XSD_STRING; } } if (debugEnabled) { log.debug(Messages.getMessage("gotType00", "Deser", "" + type)); } // We know we're deserializing, but we don't have // a specific deserializer. So create one using the // attribute type qname. if (type != null) { Deserializer dser = context.getDeserializerForType(type); if (dser == null) { dser = context.getDeserializerForClass(null); } if (dser != null) { // Move the value targets to the new deserializer dser.moveValueTargets(this); context.replaceElementHandler((SOAPHandler) dser); // And don't forget to give it the start event... boolean isRef = context.isProcessingRef(); context.setProcessingRef(true); dser.startElement(namespace, localName, prefix, attributes, context); context.setProcessingRef(isRef); } else { throw new SAXException( Messages.getMessage("noDeser00", "" + type)); } } } } /** * onStartChild is called on each child element. * The default behavior supplied by DeserializationImpl is to do nothing. * A specific deserializer may perform other tasks. For example a * BeanDeserializer will construct a deserializer for the indicated * property and return it. * @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 { return null; } /** * endElement is called when the end element tag is reached. * It handles href/id information for multi-ref processing * and invokes the valueComplete() method of the deserializer * which sets the targets with the deserialized value. * @param namespace is the namespace of the child element * @param localName is the local name of the child element * @param context is the deserialization context */ public final void endElement(String namespace, String localName, DeserializationContext context) throws SAXException { super.endElement(namespace, localName, context); isEnded = true; if (!isHref) { onEndElement(namespace, localName, context); } // Time to call valueComplete to copy the value to // the targets. First a call is made to componentsReady // to ensure that all components are ready. if (componentsReady()) { valueComplete(); } // If this element has an id, then associate the value with the id. // Subsequent hrefs to the id will obtain the value directly. // This is necessary for proper multi-reference deserialization. if (id != null) { context.addObjectById(id, value); if (debugEnabled) { log.debug(Messages.getMessage("deserPutValueDebug00", "" + value, id)); } } } /** * onEndElement is called by endElement. It is not called * if the element has an href. * @param namespace is the namespace of the child element * @param localName is the local name of the child element * @param context is the deserialization context */ public void onEndElement(String namespace, String localName, DeserializationContext context) throws SAXException { // If we only have SAX events, but someone really wanted a // value, try sending them the contents of this element // as a String... // ??? Is this the right thing to do here? if (this.getClass().equals(DeserializerImpl.class) && targets != null && !targets.isEmpty()) { StringWriter writer = new StringWriter(); SerializationContext serContext = new SerializationContext(writer, context.getMessageContext()); serContext.setSendDecl(false); SAXOutputter so = null; so = new SAXOutputter(serContext); context.getCurElement().publishContents(so); if (!isNil) { value = writer.getBuffer().toString(); } } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -