| /* |
| * 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.components.logger.LogFactory; |
| import org.apache.axis.encoding.DeserializationContext; |
| import org.apache.axis.encoding.Deserializer; |
| import org.apache.axis.encoding.DeserializerImpl; |
| import org.apache.axis.encoding.DeserializerTarget; |
| import org.apache.axis.message.SOAPHandler; |
| import org.apache.axis.utils.Messages; |
| import org.apache.commons.logging.Log; |
| import org.xml.sax.Attributes; |
| import org.xml.sax.SAXException; |
| |
| import javax.xml.namespace.QName; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| /* |
| * A <code>MapSerializer</code> is be used to deserialize |
| * deserialize Maps using the <code>SOAP-ENC</code> |
| * encoding style.<p> |
| * |
| * @author Glen Daniels (gdaniels@apache.org) |
| * Modified by @author Rich scheuerle <scheu@us.ibm.com> |
| */ |
| public class MapDeserializer extends DeserializerImpl { |
| |
| protected static Log log = |
| LogFactory.getLog(MapDeserializer.class.getName()); |
| |
| // Fixed objects to act as hints to the set() callback |
| public static final Object KEYHINT = new Object(); |
| public static final Object VALHINT = new Object(); |
| public static final Object NILHINT = new Object(); |
| |
| |
| /** |
| * 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.) |
| * |
| * Simply creates map. |
| * @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 (log.isDebugEnabled()) { |
| log.debug("Enter MapDeserializer::startElement()"); |
| } |
| |
| if (context.isNil(attributes)) { |
| return; |
| } |
| |
| // Create a hashmap to hold the deserialized values. |
| setValue(new HashMap()); |
| |
| if (log.isDebugEnabled()) { |
| log.debug("Exit: MapDeserializer::startElement()"); |
| } |
| } |
| |
| /** |
| * onStartChild is called on each child element. |
| * |
| * @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 { |
| |
| if (log.isDebugEnabled()) { |
| log.debug("Enter: MapDeserializer::onStartChild()"); |
| } |
| |
| if(localName.equals("item")) { |
| ItemHandler handler = new ItemHandler(this); |
| |
| // This item must be complete before we're complete... |
| addChildDeserializer(handler); |
| |
| if (log.isDebugEnabled()) { |
| log.debug("Exit: MapDeserializer::onStartChild()"); |
| } |
| |
| return handler; |
| } |
| |
| return this; |
| } |
| |
| /** |
| * The registerValueTarget code above causes this set function to be invoked when |
| * each value is known. |
| * @param value is the value of an element |
| * @param hint is the key |
| */ |
| public void setChildValue(Object value, Object hint) throws SAXException |
| { |
| if (log.isDebugEnabled()) { |
| log.debug(Messages.getMessage("gotValue00", "MapDeserializer", "" + value)); |
| } |
| ((Map)this.value).put(hint, value); |
| } |
| |
| /** |
| * A deserializer for an <item>. Handles getting the key and |
| * value objects from their own deserializers, and then putting |
| * the values into the HashMap we're building. |
| * |
| */ |
| class ItemHandler extends DeserializerImpl { |
| Object key; |
| Object myValue; |
| int numSet = 0; |
| MapDeserializer md = null; |
| |
| ItemHandler(MapDeserializer md) { |
| this.md = md; |
| } |
| /** |
| * Callback from our deserializers. The hint indicates |
| * whether the passed "val" argument is the key or the value |
| * for this mapping. |
| */ |
| public void setChildValue(Object val, Object hint) throws SAXException |
| { |
| if (hint == KEYHINT) { |
| key = val; |
| } else if (hint == VALHINT) { |
| myValue = val; |
| } else if (hint != NILHINT) { |
| return; |
| } |
| numSet++; |
| if (numSet == 2) |
| md.setChildValue(myValue, key); |
| } |
| |
| public SOAPHandler onStartChild(String namespace, |
| String localName, |
| String prefix, |
| Attributes attributes, |
| DeserializationContext context) |
| throws SAXException |
| { |
| QName typeQName = context.getTypeFromAttributes(namespace, |
| localName, |
| attributes); |
| Deserializer dser = context.getDeserializerForType(typeQName); |
| |
| // If no deserializer, use the base DeserializerImpl. |
| if (dser == null) |
| dser = new DeserializerImpl(); |
| |
| // When the child value is ready, we |
| // want our set method to be invoked. |
| // To do this register a DeserializeTarget on the |
| // new Deserializer. |
| DeserializerTarget dt = null; |
| if (context.isNil(attributes)) { |
| dt = new DeserializerTarget(this, NILHINT); |
| } else if (localName.equals("key")) { |
| dt = new DeserializerTarget(this, KEYHINT); |
| } else if (localName.equals("value")) { |
| dt = new DeserializerTarget(this, VALHINT); |
| } else { |
| // Do nothing |
| } |
| if (dt != null) { |
| dser.registerValueTarget(dt); |
| } |
| |
| // We need this guy to complete for us to complete. |
| addChildDeserializer(dser); |
| |
| return (SOAPHandler)dser; |
| } |
| } |
| } |