KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > encoding > ser > SimpleListDeserializer


1 /*
2  * Copyright 2001,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.axis.encoding.ser;
18
19 import java.lang.reflect.Array JavaDoc;
20 import java.lang.reflect.Constructor JavaDoc;
21 import java.lang.reflect.InvocationTargetException JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.Map JavaDoc;
25 import java.util.Set JavaDoc;
26 import java.util.StringTokenizer JavaDoc;
27
28 import javax.xml.namespace.QName JavaDoc;
29
30 import org.apache.axis.description.TypeDesc;
31 import org.apache.axis.encoding.DeserializationContext;
32 import org.apache.axis.encoding.Deserializer;
33 import org.apache.axis.encoding.SimpleType;
34 import org.apache.axis.encoding.TypeMapping;
35 import org.apache.axis.message.SOAPHandler;
36 import org.apache.axis.utils.BeanPropertyDescriptor;
37 import org.apache.axis.utils.Messages;
38 import org.xml.sax.Attributes JavaDoc;
39 import org.xml.sax.SAXException JavaDoc;
40
41 /**
42  * Deserializer for
43  * <xsd:simpleType ...>
44  * <xsd:list itemType="...">
45  * </xsd:simpleType>
46  * based on SimpleDeserializer
47  *
48  * @author Ias (iasandcb@tmax.co.kr)
49  */

50 public class SimpleListDeserializer extends SimpleDeserializer {
51
52     StringBuffer JavaDoc val = new StringBuffer JavaDoc();
53     private Constructor JavaDoc constructor = null;
54     private Map JavaDoc propertyMap = null;
55     private HashMap JavaDoc attributeMap = null;
56     private DeserializationContext context = null;
57
58     public QName JavaDoc xmlType;
59     public Class JavaDoc javaType;
60
61     private TypeDesc typeDesc = null;
62
63     protected SimpleListDeserializer cacheStringDSer = null;
64     protected QName JavaDoc cacheXMLType = null;
65     /**
66      * The Deserializer is constructed with the xmlType and
67      * javaType (which could be a java primitive like int.class)
68      */

69     public SimpleListDeserializer(Class JavaDoc javaType, QName JavaDoc xmlType) {
70         super (javaType, xmlType);
71
72         this.xmlType = xmlType;
73         this.javaType = javaType;
74     }
75     public SimpleListDeserializer(Class JavaDoc javaType, QName JavaDoc xmlType, TypeDesc typeDesc) {
76         super (javaType, xmlType, typeDesc);
77
78         this.xmlType = xmlType;
79         this.javaType = javaType;
80         this.typeDesc = typeDesc;
81     }
82    
83     
84     /**
85      * Reset deserializer for re-use
86      */

87     public void reset() {
88         val.setLength(0); // Reset string buffer back to zero
89
attributeMap = null; // Remove attribute map
90
isNil = false; // Don't know if nil
91
isEnded = false; // Indicate the end of element not yet called
92
}
93
94     /**
95      * The Factory calls setConstructor.
96      */

97     public void setConstructor(Constructor JavaDoc c)
98     {
99         constructor = c;
100     }
101
102     /**
103      * There should not be nested elements, so thow and exception if this occurs.
104      */

105     public SOAPHandler onStartChild(String JavaDoc namespace,
106                                     String JavaDoc localName,
107                                     String JavaDoc prefix,
108                                     Attributes JavaDoc attributes,
109                                     DeserializationContext context)
110         throws SAXException JavaDoc
111     {
112         throw new SAXException JavaDoc(
113                 Messages.getMessage("cantHandle00", "SimpleDeserializer"));
114     }
115
116     /**
117      * Append any characters received to the value. This method is defined
118      * by Deserializer.
119      */

120     public void characters(char [] chars, int start, int end)
121         throws SAXException JavaDoc
122     {
123         val.append(chars, start, end);
124     }
125
126     /**
127      * Append any characters to the value. This method is defined by
128      * Deserializer.
129      */

130     public void onEndElement(String JavaDoc namespace, String JavaDoc localName,
131                            DeserializationContext context)
132         throws SAXException JavaDoc
133     {
134         if (isNil || val == null) {
135             value = null;
136             return;
137         }
138         try {
139             value = makeValue(val.toString());
140         } catch (InvocationTargetException JavaDoc ite) {
141             Throwable JavaDoc realException = ite.getTargetException();
142             if (realException instanceof Exception JavaDoc)
143                throw new SAXException JavaDoc((Exception JavaDoc)realException);
144             else
145                throw new SAXException JavaDoc(ite.getMessage());
146         } catch (Exception JavaDoc e) {
147             throw new SAXException JavaDoc(e);
148         }
149
150         // If this is a SimpleType, set attributes we have stashed away
151
setSimpleTypeAttributes();
152     }
153
154     /**
155      * Convert the string that has been accumulated into an Object. Subclasses
156      * may override this.
157      * @param source the serialized value to be deserialized
158      * @throws Exception any exception thrown by this method will be wrapped
159      */

160     public Object JavaDoc makeValue(String JavaDoc source) throws Exception JavaDoc
161     {
162         // According to XML Schema Spec Part 0: Primer 2.3.1 - white space delimitor
163
StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(source.trim());
164         int length = tokenizer.countTokens();
165         Object JavaDoc list = Array.newInstance(javaType, length);
166         for (int i = 0; i < length; i++) {
167             String JavaDoc token = tokenizer.nextToken();
168             Array.set(list, i, makeUnitValue(token));
169         }
170         return list;
171     }
172
173     private Object JavaDoc makeUnitValue(String JavaDoc source) throws Exception JavaDoc
174     {
175         // If the javaType is a boolean, except a number of different sources
176
if (javaType == boolean.class || javaType == Boolean JavaDoc.class) {
177             // This is a pretty lame test, but it is what the previous code did.
178
switch (source.charAt(0)) {
179                 case '0': case 'f': case 'F':
180                     return Boolean.FALSE;
181                     
182                    case '1': case 't': case 'T':
183                        return Boolean.TRUE;
184                        
185                       default:
186                           throw new NumberFormatException JavaDoc(
187                                   Messages.getMessage("badBool00"));
188             }
189             
190         }
191         
192         // If expecting a Float or a Double, need to accept some special cases.
193
if (javaType == float.class ||
194                 javaType == java.lang.Float JavaDoc.class) {
195             if (source.equals("NaN")) {
196                 return new Float JavaDoc(Float.NaN);
197             } else if (source.equals("INF")) {
198                 return new Float JavaDoc(Float.POSITIVE_INFINITY);
199             } else if (source.equals("-INF")) {
200                 return new Float JavaDoc(Float.NEGATIVE_INFINITY);
201             }
202         }
203         if (javaType == double.class ||
204                 javaType == java.lang.Double JavaDoc.class) {
205             if (source.equals("NaN")) {
206                 return new Double JavaDoc(Double.NaN);
207             } else if (source.equals("INF")) {
208                 return new Double JavaDoc(Double.POSITIVE_INFINITY);
209             } else if (source.equals("-INF")) {
210                 return new Double JavaDoc(Double.NEGATIVE_INFINITY);
211             }
212         }
213         if (javaType == QName JavaDoc.class) {
214             int colon = source.lastIndexOf(":");
215             String JavaDoc namespace = colon < 0 ? "" :
216                 context.getNamespaceURI(source.substring(0, colon));
217             String JavaDoc localPart = colon < 0 ? source :
218                 source.substring(colon + 1);
219             return new QName JavaDoc(namespace, localPart);
220         }
221
222         return constructor.newInstance(new Object JavaDoc [] { source });
223     }
224     /**
225      * Set the bean properties that correspond to element attributes.
226      *
227      * This method is invoked after startElement when the element requires
228      * deserialization (i.e. the element is not an href and the value is not nil.)
229      * @param namespace is the namespace of the element
230      * @param localName is the name of the element
231      * @param prefix is the prefix of the element
232      * @param attributes are the attributes on the element...used to get the type
233      * @param context is the DeserializationContext
234      */

235     public void onStartElement(String JavaDoc namespace, String JavaDoc localName,
236                                String JavaDoc prefix, Attributes JavaDoc attributes,
237                                DeserializationContext context)
238             throws SAXException JavaDoc
239     {
240
241         this.context = context;
242
243         // If we have no metadata, we have no attributes. Q.E.D.
244
if (typeDesc == null)
245             return;
246
247         // loop through the attributes and set bean properties that
248
// correspond to attributes
249
for (int i=0; i < attributes.getLength(); i++) {
250             QName JavaDoc attrQName = new QName JavaDoc(attributes.getURI(i),
251                                         attributes.getLocalName(i));
252             String JavaDoc fieldName = typeDesc.getFieldNameForAttribute(attrQName);
253             if (fieldName == null)
254                 continue;
255
256             // look for the attribute property
257
BeanPropertyDescriptor bpd =
258                     (BeanPropertyDescriptor) propertyMap.get(fieldName);
259             if (bpd != null) {
260                 if (!bpd.isWriteable() || bpd.isIndexed() ) continue ;
261
262                 // determine the QName for this child element
263
TypeMapping tm = context.getTypeMapping();
264                 Class JavaDoc type = bpd.getType();
265                 QName JavaDoc qn = tm.getTypeQName(type);
266                 if (qn == null)
267                     throw new SAXException JavaDoc(
268                             Messages.getMessage("unregistered00", type.toString()));
269
270                 // get the deserializer
271
Deserializer dSer = context.getDeserializerForType(qn);
272                 if (dSer == null)
273                     throw new SAXException JavaDoc(
274                             Messages.getMessage("noDeser00", type.toString()));
275                 if (! (dSer instanceof SimpleListDeserializer))
276                     throw new SAXException JavaDoc(
277                             Messages.getMessage("AttrNotSimpleType00",
278                                                  bpd.getName(),
279                                                  type.toString()));
280
281                 // Success! Create an object from the string and save
282
// it in our attribute map for later.
283
if (attributeMap == null) {
284                     attributeMap = new HashMap JavaDoc();
285                 }
286                 try {
287                     Object JavaDoc val = ((SimpleListDeserializer)dSer).
288                         makeValue(attributes.getValue(i));
289                     attributeMap.put(fieldName, val);
290                 } catch (Exception JavaDoc e) {
291                     throw new SAXException JavaDoc(e);
292                 }
293             } // if
294
} // attribute loop
295
} // onStartElement
296

297     /**
298      * Process any attributes we may have encountered (in onStartElement)
299      */

300     private void setSimpleTypeAttributes() throws SAXException JavaDoc {
301         // if this isn't a simpleType bean, wont have attributes
302
if (! SimpleType.class.isAssignableFrom(javaType) ||
303             attributeMap == null)
304             return;
305
306         // loop through map
307
Set JavaDoc entries = attributeMap.entrySet();
308         for (Iterator JavaDoc iterator = entries.iterator(); iterator.hasNext();) {
309             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
310             String JavaDoc name = (String JavaDoc) entry.getKey();
311             Object JavaDoc val = entry.getValue();
312
313             BeanPropertyDescriptor bpd =
314                     (BeanPropertyDescriptor) propertyMap.get(name);
315             if (!bpd.isWriteable() || bpd.isIndexed()) continue;
316             try {
317                 bpd.set(value, val );
318             } catch (Exception JavaDoc e) {
319                 throw new SAXException JavaDoc(e);
320             }
321         }
322     }
323
324 }
325
Popular Tags