KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > webservice > deployment > TypeMappingDescription


1 /**
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7 package org.jboss.webservice.deployment;
8
9 // $Id: TypeMappingDescription.java,v 1.8.2.12 2005/03/15 23:29:30 tdiesler Exp $
10

11 import org.jboss.axis.Constants;
12 import org.jboss.axis.encoding.ser.ArrayDeserializerFactory;
13 import org.jboss.axis.encoding.ser.ArraySerializerFactory;
14 import org.jboss.axis.encoding.ser.BeanDeserializerFactory;
15 import org.jboss.axis.encoding.ser.BeanSerializerFactory;
16 import org.jboss.axis.encoding.ser.CalendarDeserializerFactory;
17 import org.jboss.axis.encoding.ser.CalendarSerializerFactory;
18 import org.jboss.axis.encoding.ser.EnumDeserializerFactory;
19 import org.jboss.axis.encoding.ser.EnumSerializerFactory;
20 import org.jboss.axis.encoding.ser.QNameDeserializerFactory;
21 import org.jboss.axis.encoding.ser.QNameSerializerFactory;
22 import org.jboss.axis.encoding.ser.SimpleDeserializerFactory;
23 import org.jboss.axis.encoding.ser.SimpleSerializerFactory;
24 import org.jboss.axis.enums.Use;
25 import org.jboss.axis.utils.DOM2Utils;
26 import org.jboss.axis.utils.JavaUtils;
27 import org.jboss.logging.Logger;
28 import org.jboss.util.Classes;
29 import org.jboss.webservice.encoding.ser.MetaDataBeanDeserializerFactory;
30 import org.jboss.webservice.encoding.ser.MetaDataBeanSerializerFactory;
31 import org.jboss.webservice.metadata.jaxrpcmapping.JavaXmlTypeMapping;
32 import org.jboss.webservice.metadata.jaxrpcmapping.VariableMapping;
33 import org.jboss.webservice.util.DOMUtils;
34 import org.w3c.dom.Element JavaDoc;
35 import org.xml.sax.InputSource JavaDoc;
36
37 import javax.xml.namespace.QName JavaDoc;
38 import javax.xml.parsers.DocumentBuilder JavaDoc;
39 import java.io.PrintWriter JavaDoc;
40 import java.io.StringReader JavaDoc;
41 import java.util.Calendar JavaDoc;
42
43 /**
44  * Abstracts an Axis service description
45  *
46  * @author thomas.diesler@jboss.org
47  * @since 08-June-2004
48  */

49 public class TypeMappingDescription
50 {
51    // provide logging
52
private final Logger log = Logger.getLogger(TypeMappingDescription.class);
53
54    private QName JavaDoc typeQName;
55    private QName JavaDoc anonymousQName;
56    private String JavaDoc javaType;
57    private String JavaDoc serFactoryName;
58    private String JavaDoc desFactoryName;
59    private String JavaDoc encodingURI;
60    private BeanXMLMetaData metaData;
61
62    /**
63     * By default, type mappings are generated from the information in the WSDL and the JAXRPC.
64     * <p/>
65     * 1. All types from jaxrpc-mapping should be registered with Axis even when they do not appear in any of the operation
66     * parameter of return types. They might be subtypes contained in top level types.
67     * <p/>
68     * 2. Do not register a type twice when we have more than on service per deployment.
69     * <p/>
70     * This flag indicates, wheter a type has user defined information comming from ws4ee-deployment.xml
71     * A user defined type can alway override an automatically generated type.
72     */

73    private boolean userDefined;
74
75    public TypeMappingDescription(QName JavaDoc qname, QName JavaDoc anonymousQName, String JavaDoc javaType, Use use, JavaXmlTypeMapping jaxrpcTypeMapping)
76    {
77       if (qname == null)
78          throw new IllegalArgumentException JavaDoc("TypeMapping qname cannot be null");
79       if (javaType == null)
80          throw new IllegalArgumentException JavaDoc("TypeMapping javaType cannot be null");
81       if (use == null)
82          throw new IllegalArgumentException JavaDoc("TypeMapping use cannot be null");
83
84       this.javaType = javaType;
85       this.typeQName = qname;
86       this.anonymousQName = anonymousQName;
87
88       if (jaxrpcTypeMapping != null)
89          initMetaDataFromJavaXMLTypeMapping(qname, jaxrpcTypeMapping);
90
91       if (Use.LITERAL.equals(use))
92          encodingURI = Constants.URI_LITERAL_ENC;
93       else if (Use.ENCODED.equals(use))
94          encodingURI = Constants.URI_SOAP11_ENC;
95       else
96          throw new IllegalArgumentException JavaDoc("Unsupported use: " + use);
97
98    }
99
100    // Add type mapping meta data if we have a jaxrpc mapping
101
private void initMetaDataFromJavaXMLTypeMapping(QName JavaDoc qname, JavaXmlTypeMapping jaxrpcTypeMapping)
102    {
103       if (jaxrpcTypeMapping.getVariableMappings().length > 0)
104       {
105          String JavaDoc xmlns = "xmlns:" + qname.getPrefix() + "='" + qname.getNamespaceURI() + "'";
106          StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("<typeMapping " + xmlns + "><typeDesc>");
107          VariableMapping[] varMappings = jaxrpcTypeMapping.getVariableMappings();
108          for (int i = 0; i < varMappings.length; i++)
109          {
110             VariableMapping varMapping = varMappings[i];
111             String JavaDoc fieldName = varMapping.getJavaVariableName();
112
113             String JavaDoc xmlName = varMapping.getXmlElementName();
114             if (xmlName == null)
115                xmlName = varMapping.getXmlAttributeName();
116             if (xmlName == null)
117                xmlName = varMapping.getXmlWildcard();
118
119             boolean isAttribute = varMapping.getXmlAttributeName() != null;
120             String JavaDoc asAttr = (isAttribute ? "asAttr='true' " : " ");
121
122             buffer.append("<elementDesc fieldName='" + fieldName + "' xmlName='" + xmlName + "' " + asAttr + "/>");
123          }
124
125          buffer.append("<elementOrder>");
126          for (int i = 0; i < varMappings.length; i++)
127          {
128             VariableMapping varMapping = varMappings[i];
129             if (varMapping.getXmlElementName() != null)
130                buffer.append("<element name='" + varMapping.getJavaVariableName() + "'/>");
131          }
132          buffer.append("</elementOrder></typeDesc></typeMapping>");
133
134          try
135          {
136             DocumentBuilder JavaDoc builder = DOM2Utils.getDocumentBuilder();
137             Element JavaDoc root = builder.parse(new InputSource JavaDoc(new StringReader JavaDoc(buffer.toString()))).getDocumentElement();
138             metaData = BeanXMLMetaData.parse(DOMUtils.getFirstChildElement(root));
139          }
140          catch (Exception JavaDoc e)
141          {
142             throw new IllegalArgumentException JavaDoc("Cannot construct meta data from: " + buffer);
143          }
144       }
145    }
146
147    /**
148     * Load the javaType with the given class loader.
149     */

150    public Class JavaDoc loadJavaType(ClassLoader JavaDoc cl)
151    {
152       Class JavaDoc typeClass = null;
153       String JavaDoc componentType = null;
154       try
155       {
156          boolean isArrayType = javaType.endsWith("[]");
157
158          if (isArrayType)
159             componentType = javaType.substring(0, javaType.indexOf("["));
160          else
161             componentType = javaType;
162
163
164          // Array classes do not exist in the wild. They only exist after loading the component
165
// class type, and in 1.4.2 they are not created via the ClassLoader.loadClass call
166
// http://developer.java.sun.com/developer/bugParade/bugs/4976356.html
167
if (isArrayType)
168          {
169             if (JavaUtils.isJavaKeyword(componentType))
170             {
171                String JavaDoc className = JavaUtils.getLoadableClassName(javaType);
172                typeClass = ClassLoader.getSystemClassLoader().loadClass(className);
173             }
174             else
175             {
176                // load the component first
177
Class.forName(componentType, true, cl);
178
179                String JavaDoc className = JavaUtils.getLoadableClassName(javaType);
180                typeClass = Class.forName(className, true, cl);
181             }
182          }
183
184          if (isArrayType == false)
185          {
186             if (JavaUtils.isJavaKeyword(javaType))
187             {
188                typeClass = getPrimitiveClass(javaType);
189             }
190             else
191             {
192                typeClass = cl.loadClass(javaType);
193             }
194          }
195
196          // Now we got the class we can assign the serializer/deserializer
197
initSerializerForClass(typeClass);
198
199       }
200       catch (ClassNotFoundException JavaDoc ignore)
201       {
202          log.warn("Class not found: " + javaType);
203       }
204       catch (NoClassDefFoundError JavaDoc ignore)
205       {
206          log.warn("No class definition for " + javaType);
207       }
208
209       return typeClass;
210    }
211
212    private Class JavaDoc getPrimitiveClass(String JavaDoc javaType)
213    {
214       if ("int".equals(javaType))
215          return int.class;
216       else if ("short".equals(javaType))
217          return short.class;
218       else if ("boolean".equals(javaType))
219          return boolean.class;
220       else if ("byte".equals(javaType))
221          return byte.class;
222       else if ("long".equals(javaType))
223          return long.class;
224       else if ("double".equals(javaType))
225          return double.class;
226       else if ("float".equals(javaType))
227          return float.class;
228       else if ("char".equals(javaType))
229          return char.class;
230
231       return null;
232    }
233
234    /**
235     * Initialize the serializer/deserializer factory pair.
236     */

237    private void initSerializerForClass(Class JavaDoc typeClass)
238    {
239       boolean isEncoded = Constants.URI_SOAP11_ENC.equals(encodingURI);
240
241       boolean isSimpleType = (typeClass == null
242               || Classes.isPrimitive(typeClass)
243               || typeClass.getName().startsWith("java.lang")
244               || typeClass.getName().startsWith("java.math"));
245
246       if (getSerializerFactoryName() == null)
247       {
248          String JavaDoc serFactory = null;
249          if (isSimpleType)
250          {
251             serFactory = SimpleSerializerFactory.class.getName();
252          }
253          else if (JavaUtils.isArrayClass(typeClass))
254          {
255             if (isEncoded)
256             {
257                serFactory = ArraySerializerFactory.class.getName();
258             }
259          }
260          else if (JavaUtils.isEnumClass(typeClass))
261          {
262             serFactory = EnumSerializerFactory.class.getName();
263          }
264          else if (QName JavaDoc.class.isAssignableFrom(typeClass))
265          {
266             serFactory = QNameSerializerFactory.class.getName();
267          }
268          else if (Calendar JavaDoc.class.isAssignableFrom(typeClass))
269          {
270             serFactory = CalendarSerializerFactory.class.getName();
271          }
272          else
273          {
274             if (metaData != null)
275             {
276                serFactory = MetaDataBeanSerializerFactory.class.getName();
277             }
278             else
279             {
280                serFactory = BeanSerializerFactory.class.getName();
281             }
282          }
283
284          setSerializerFactoryName(serFactory);
285       }
286
287       if (getDeserializerFactoryName() == null)
288       {
289          String JavaDoc desFactory = null;
290          if (isSimpleType)
291          {
292             desFactory = SimpleDeserializerFactory.class.getName();
293          }
294          else if (JavaUtils.isEnumClass(typeClass))
295          {
296             desFactory = EnumDeserializerFactory.class.getName();
297          }
298          else if (JavaUtils.isArrayClass(typeClass))
299          {
300             if (isEncoded)
301             {
302                desFactory = ArrayDeserializerFactory.class.getName();
303             }
304          }
305          else if (QName JavaDoc.class.isAssignableFrom(typeClass))
306          {
307             desFactory = QNameDeserializerFactory.class.getName();
308          }
309          else if (Calendar JavaDoc.class.isAssignableFrom(typeClass))
310          {
311             desFactory = CalendarDeserializerFactory.class.getName();
312          }
313          else
314          {
315             if (metaData != null)
316             {
317                desFactory = MetaDataBeanDeserializerFactory.class.getName();
318             }
319             else
320             {
321                desFactory = BeanDeserializerFactory.class.getName();
322             }
323          }
324
325          setDeserializerFactoryName(desFactory);
326       }
327    }
328
329    public String JavaDoc getJavaType()
330    {
331       return javaType;
332    }
333
334    public QName JavaDoc getTypeQName()
335    {
336       return typeQName;
337    }
338
339    public QName JavaDoc getAnonymousQName()
340    {
341       return anonymousQName;
342    }
343
344    public String JavaDoc getDeserializerFactoryName()
345    {
346       return desFactoryName;
347    }
348
349    public String JavaDoc getSerializerFactoryName()
350    {
351       return serFactoryName;
352    }
353
354    public String JavaDoc getEncodingURI()
355    {
356       return encodingURI;
357    }
358
359    public void setEncodingURI(String JavaDoc encodingURI)
360    {
361       this.encodingURI = encodingURI;
362    }
363
364    public void setTypeQName(QName JavaDoc typeQName)
365    {
366       this.typeQName = typeQName;
367    }
368
369    public void setSerializerFactoryName(String JavaDoc serFactoryName)
370    {
371       this.serFactoryName = serFactoryName;
372    }
373
374    public void setDeserializerFactoryName(String JavaDoc desFactoryName)
375    {
376       this.desFactoryName = desFactoryName;
377    }
378
379    public BeanXMLMetaData getMetaData()
380    {
381       return metaData;
382    }
383
384    public void setMetaData(BeanXMLMetaData metaData)
385    {
386       this.metaData = metaData;
387    }
388
389    public boolean isUserDefined()
390    {
391       return userDefined;
392    }
393
394    public void setUserDefined(boolean userDefined)
395    {
396       this.userDefined = userDefined;
397    }
398
399    public void writeWSDD(PrintWriter JavaDoc out)
400    {
401       String JavaDoc javaType = getJavaType();
402       QName JavaDoc typeQName = getTypeQName();
403       String JavaDoc encodingURI = getEncodingURI();
404
405       log.trace("TypeMapping: " + this);
406
407       String JavaDoc typeAttr = WSDDGenerator.getQNameAttrValue(typeQName);
408
409       String JavaDoc typePrefix = typeQName.getPrefix();
410       String JavaDoc xmlns = "xmlns:" + typePrefix + "='" + typeQName.getNamespaceURI() + "'";
411
412       ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
413       Class JavaDoc typeClass = loadJavaType(cl);
414
415       // The serializer/derserializer factory might not be known until we load the class
416
String JavaDoc serializer = getSerializerFactoryName();
417       String JavaDoc deserializer = getDeserializerFactoryName();
418
419       if (isUserDefined())
420          out.println(" <!-- User defined type mapping -->");
421
422       if (typeClass == null)
423          out.println(" <!-- Class not found, ignore type mapping");
424       else if (serializer == null || deserializer == null)
425          out.println(" <!-- Serializer/Deserializer not found, ignore type mapping");
426
427       out.println(" <typeMapping");
428       out.println(" qname='" + typeAttr + "' " + xmlns);
429       out.println(" type='java:" + javaType + "'");
430       out.println(" serializer='" + serializer + "'");
431       out.println(" deserializer='" + deserializer + "'");
432       out.println(" encodingStyle='" + encodingURI + "'>");
433       if (metaData != null)
434       {
435          metaData.serializeAsXML(out);
436       }
437       out.println(" </typeMapping>");
438
439       if (typeClass == null || serializer == null || deserializer == null)
440          out.println(" -->");
441    }
442
443    public boolean equals(Object JavaDoc obj)
444    {
445       if (obj == null) return false;
446       return toString().equals(obj.toString());
447    }
448
449    public int hashCode()
450    {
451       return toString().hashCode();
452    }
453
454    public String JavaDoc toString()
455    {
456       return "[type=" + typeQName + ",anonymous=" + anonymousQName + ",java=" + javaType + ",serf=" + serFactoryName + ",desf=" + desFactoryName + ",encoding=" + encodingURI + "]";
457    }
458 }
Popular Tags