Home | History | Annotate | Download | only in serialization
      1 /* Copyright (c) 2003,2004, Stefan Haustein, Oberhausen, Rhld., Germany
      2  *
      3  * Permission is hereby granted, free of charge, to any person obtaining a copy
      4  * of this software and associated documentation files (the "Software"), to deal
      5  * in the Software without restriction, including without limitation the rights
      6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or
      7  * sell copies of the Software, and to permit persons to whom the Software is
      8  * furnished to do so, subject to the following conditions:
      9  *
     10  * The  above copyright notice and this permission notice shall be included in
     11  * all copies or substantial portions of the Software.
     12  *
     13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     19  * IN THE SOFTWARE.
     20  *
     21  * Contributor(s): Sean McDaniel
     22  *
     23  * */
     24 
     25 package org.ksoap2.serialization;
     26 
     27 import java.io.*;
     28 import java.util.*;
     29 
     30 import org.xmlpull.v1.*;
     31 
     32 /**
     33  * Serializes instances of hashtable to and from xml. This implementation is
     34  * based on the xml schema from apache-soap, namely the type 'map' in the
     35  * namespace 'http://xml.apache.org/xml-soap'. Other soap implementations
     36  * including apache (obviously) and glue are also interoperable with the
     37  * schema.
     38  */
     39 public class MarshalHashtable implements Marshal {
     40 
     41     /** use then during registration */
     42     public static final String NAMESPACE = "http://xml.apache.org/xml-soap";
     43     /** use then during registration */
     44     public static final String NAME = "Map";
     45     /** CLDC does not support .class, so this helper is needed. */
     46     public static final Class HASHTABLE_CLASS = new Hashtable().getClass();
     47     SoapSerializationEnvelope envelope;
     48 
     49     public Object readInstance(XmlPullParser parser, String namespace, String name,
     50             PropertyInfo expected)
     51             throws IOException, XmlPullParserException {
     52         Hashtable instance = new Hashtable();
     53         String elementName = parser.getName();
     54         while (parser.nextTag() != XmlPullParser.END_TAG) {
     55             SoapObject item = new ItemSoapObject(instance);
     56             parser.require(XmlPullParser.START_TAG, null, "item");
     57             parser.nextTag();
     58             Object key = envelope.read(parser, item, 0, null, null, PropertyInfo.OBJECT_TYPE);
     59             parser.nextTag();
     60             if (key != null) {
     61                 item.setProperty(0, key);
     62             }
     63             Object value = envelope.read(parser, item, 1, null, null, PropertyInfo.OBJECT_TYPE);
     64             parser.nextTag();
     65             if (value != null) {
     66                 item.setProperty(1, value);
     67             }
     68             parser.require(XmlPullParser.END_TAG, null, "item");
     69         }
     70         parser.require(XmlPullParser.END_TAG, null, elementName);
     71         return instance;
     72     }
     73 
     74     public void writeInstance(XmlSerializer writer, Object instance) throws IOException {
     75         Hashtable h = (Hashtable) instance;
     76         SoapObject item = new SoapObject(null, null);
     77         item.addProperty("key", null);
     78         item.addProperty("value", null);
     79         for (Enumeration keys = h.keys(); keys.hasMoreElements(); ) {
     80             writer.startTag("", "item");
     81             Object key = keys.nextElement();
     82             item.setProperty(0, key);
     83             item.setProperty(1, h.get(key));
     84             envelope.writeObjectBodyWithAttributes(writer, item);
     85             writer.endTag("", "item");
     86         }
     87     }
     88 
     89     class ItemSoapObject extends SoapObject {
     90         Hashtable h;
     91         int resolvedIndex = -1;
     92 
     93         ItemSoapObject(Hashtable h) {
     94             super(null, null);
     95             this.h = h;
     96             addProperty("key", null);
     97             addProperty("value", null);
     98         }
     99 
    100         // 0 & 1 only valid
    101         public void setProperty(int index, Object value) {
    102             if (resolvedIndex == -1) {
    103                 super.setProperty(index, value);
    104                 resolvedIndex = index;
    105             } else {
    106                 // already have a key or value
    107                 Object resolved = resolvedIndex == 0 ? getProperty(0) : getProperty(1);
    108                 if (index == 0) {
    109                     h.put(value, resolved);
    110                 } else {
    111                     h.put(resolved, value);
    112                 }
    113             }
    114         }
    115     }
    116 
    117     public void register(SoapSerializationEnvelope cm) {
    118         envelope = cm;
    119         cm.addMapping(MarshalHashtable.NAMESPACE, MarshalHashtable.NAME, HASHTABLE_CLASS, this);
    120     }
    121 }
    122