KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > encoding > TypeMappingImpl


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;
18
19 import org.apache.axis.Constants;
20 import org.apache.axis.AxisProperties;
21 import org.apache.axis.MessageContext;
22 import org.apache.axis.AxisEngine;
23 import org.apache.axis.handlers.soap.SOAPService;
24 import org.apache.axis.components.logger.LogFactory;
25 import org.apache.axis.encoding.ser.ArrayDeserializerFactory;
26 import org.apache.axis.encoding.ser.ArraySerializerFactory;
27 import org.apache.axis.encoding.ser.BeanDeserializerFactory;
28 import org.apache.axis.encoding.ser.BeanSerializerFactory;
29 import org.apache.axis.utils.ArrayUtil;
30 import org.apache.axis.utils.Messages;
31 import org.apache.axis.utils.ClassUtils;
32 import org.apache.axis.utils.JavaUtils;
33 import org.apache.axis.wsdl.fromJava.Namespaces;
34 import org.apache.axis.wsdl.fromJava.Types;
35 import org.apache.commons.logging.Log;
36
37 import javax.xml.namespace.QName JavaDoc;
38 import javax.xml.rpc.JAXRPCException JavaDoc;
39
40 import java.lang.reflect.Array JavaDoc;
41 import java.util.ArrayList JavaDoc;
42 import java.util.HashMap JavaDoc;
43 import java.util.List JavaDoc;
44 import java.io.Serializable JavaDoc;
45
46 /**
47  * <p>
48  * This is the implementation of the axis TypeMapping interface (which extends
49  * the JAX-RPC TypeMapping interface).
50  * </p>
51  * <p>
52  * A TypeMapping is obtained from the singleton TypeMappingRegistry using
53  * the namespace of the webservice. The TypeMapping contains the tuples
54  * {Java type, SerializerFactory, DeserializerFactory, Type QName)
55  * </p>
56  * <p>
57  * So if you have a Web Service with the namespace "XYZ", you call
58  * the TypeMappingRegistry.getTypeMapping("XYZ").
59  * </p>
60  * <p>
61  * The wsdl in your web service will use a number of types. The tuple
62  * information for each of these will be accessed via the TypeMapping.
63  * </p>
64  * <p>
65  * Because every web service uses the soap, schema, wsdl primitives, we could
66  * pre-populate the TypeMapping with these standard tuples. Instead,
67  * if the namespace/class matches is not found in the TypeMapping
68  * the request is delegated to the
69  * Default TypeMapping or another TypeMapping
70  * </p>
71  *
72  * @author Rich Scheuerle (scheu@us.ibm.com)
73  */

74 public class TypeMappingImpl implements Serializable JavaDoc
75 {
76     protected static Log log =
77         LogFactory.getLog(TypeMappingImpl.class.getName());
78
79     /**
80      * Work around a .NET bug with soap encoded types.
81      * This is a static property of the type mapping that will
82      * cause the class to ignore SOAPENC types when looking up
83      * QNames of java types. See getTypeQNameExact().
84      */

85     public static boolean dotnet_soapenc_bugfix = false;
86
87     public static class Pair implements Serializable JavaDoc {
88         public Class JavaDoc javaType;
89         public QName JavaDoc xmlType;
90         public Pair(Class JavaDoc javaType, QName JavaDoc xmlType) {
91             this.javaType = javaType;
92             this.xmlType = xmlType;
93         }
94         public boolean equals(Object JavaDoc o) {
95             if (o == null) return false;
96             Pair p = (Pair) o;
97             // Test straight equality
98
if (p.xmlType == this.xmlType &&
99                 p.javaType == this.javaType) {
100                 return true;
101             }
102             return (p.xmlType.equals(this.xmlType) &&
103                     p.javaType.equals(this.javaType));
104         }
105         public int hashCode() {
106             int hashcode = 0;
107             if (javaType != null) {
108                 hashcode ^= javaType.hashCode();
109             }
110             if (xmlType != null) {
111                 hashcode ^= xmlType.hashCode();
112             }
113             return hashcode;
114         }
115     }
116
117     private HashMap JavaDoc qName2Pair; // QName to Pair Mapping
118
private HashMap JavaDoc class2Pair; // Class Name to Pair Mapping
119
private HashMap JavaDoc pair2SF; // Pair to Serialization Factory
120
private HashMap JavaDoc pair2DF; // Pair to Deserialization Factory
121
private ArrayList JavaDoc namespaces; // Supported namespaces
122

123     protected Boolean JavaDoc doAutoTypes = null;
124
125     /**
126      * Construct TypeMapping
127      */

128     public TypeMappingImpl() {
129         qName2Pair = new HashMap JavaDoc();
130         class2Pair = new HashMap JavaDoc();
131         pair2SF = new HashMap JavaDoc();
132         pair2DF = new HashMap JavaDoc();
133         namespaces = new ArrayList JavaDoc();
134     }
135
136     private static boolean isArray(Class JavaDoc clazz)
137     {
138         return clazz.isArray() || java.util.Collection JavaDoc.class.isAssignableFrom(clazz);
139     }
140
141
142     /********* JAX-RPC Compliant Method Definitions *****************/
143
144     /**
145      * Gets the list of encoding styles supported by this TypeMapping object.
146      *
147      * @return String[] of namespace URIs for the supported encoding
148      * styles and XML schema namespaces.
149      */

150     public String JavaDoc[] getSupportedEncodings() {
151         String JavaDoc[] stringArray = new String JavaDoc[namespaces.size()];
152         return (String JavaDoc[]) namespaces.toArray(stringArray);
153     }
154
155     /**
156      * Sets the list of encoding styles supported by this TypeMapping object.
157      * (Not sure why this is useful...this information is automatically updated
158      * during registration.
159      *
160      * @param namespaceURIs String[] of namespace URI's
161      */

162     public void setSupportedEncodings(String JavaDoc[] namespaceURIs) {
163         namespaces.clear();
164         for (int i =0; i< namespaceURIs.length; i++) {
165             if (!namespaces.contains(namespaceURIs[i])) {
166                 namespaces.add(namespaceURIs[i]);
167             }
168         }
169     }
170
171     /**
172      * isRegistered returns true if the [javaType, xmlType]
173      * pair is registered.
174      * @param javaType - Class of the Java type
175      * @param xmlType - Qualified name of the XML data type
176      * @return true if there is a mapping for the given pair, or
177      * false if the pair is not specifically registered.
178      *
179      * For example if called with (java.lang.String[], soapenc:Array)
180      * this routine will return false because this pair is
181      * probably not specifically registered.
182      * However if getSerializer is called with the same pair,
183      * the default TypeMapping will use extra logic to find
184      * a serializer (i.e. array serializer)
185      */

186     public boolean isRegistered(Class JavaDoc javaType, QName JavaDoc xmlType) {
187         if (javaType == null || xmlType == null) {
188             // REMOVED_FOR_TCK
189
// return false;
190
throw new JAXRPCException JavaDoc(
191                     Messages.getMessage(javaType == null ?
192                                          "badJavaType" : "badXmlType"));
193         }
194         if (pair2SF.keySet().contains(new Pair(javaType, xmlType))) {
195             return true;
196         }
197         return false;
198     }
199
200     /**
201      * Registers SerializerFactory and DeserializerFactory for a
202      * specific type mapping between an XML type and Java type.
203      *
204      * @param javaType - Class of the Java type
205      * @param xmlType - Qualified name of the XML data type
206      * @param sf - SerializerFactory
207      * @param dsf - DeserializerFactory
208      *
209      * @throws JAXRPCException - If any error during the registration
210      */

211     public void register(Class JavaDoc javaType, QName JavaDoc xmlType,
212                          javax.xml.rpc.encoding.SerializerFactory JavaDoc sf,
213                          javax.xml.rpc.encoding.DeserializerFactory JavaDoc dsf)
214         throws JAXRPCException JavaDoc {
215         // At least a serializer or deserializer factory must be specified.
216
if (sf == null && dsf == null) {
217             throw new JAXRPCException JavaDoc(Messages.getMessage("badSerFac"));
218         }
219
220         internalRegister(javaType, xmlType, sf, dsf);
221     }
222
223     /**
224      * Internal version of register(), which allows null factories.
225      *
226      * @param javaType
227      * @param xmlType
228      * @param sf
229      * @param dsf
230      * @throws JAXRPCException
231      */

232     protected void internalRegister(Class JavaDoc javaType, QName JavaDoc xmlType,
233                          javax.xml.rpc.encoding.SerializerFactory JavaDoc sf,
234                          javax.xml.rpc.encoding.DeserializerFactory JavaDoc dsf)
235             throws JAXRPCException JavaDoc {
236         // Both javaType and xmlType must be specified.
237
if (javaType == null || xmlType == null) {
238             throw new JAXRPCException JavaDoc(
239                     Messages.getMessage(javaType == null ?
240                                          "badJavaType" : "badXmlType"));
241         }
242
243         //REMOVED_FOR_TCK
244
//if (sf != null &&
245
// !(sf instanceof javax.xml.rpc.encoding.SerializerFactory)) {
246
// throw new JAXRPCException(message text);
247
//}
248
//if (dsf != null &&
249
// !(dsf instanceof javax.xml.rpc.encoding.DeserializerFactory)) {
250
// throw new JAXRPCException(message text);
251
//}
252

253         Pair pair = new Pair(javaType, xmlType);
254
255         // This code used to not put the xmlType and the JavaType
256
// in the maps if it already existed:
257
// if ((dsf != null) || (qName2Pair.get(xmlType) == null))
258
// This goes against the philosphy that "last one registered wins".
259
// In particular, the mapping for java.lang.Object --> anyType
260
// was coming out in WSDL generation under the 1999 XML Schema
261
// namespace, which .NET doesn't understand (and is not great anyway).
262
qName2Pair.put(xmlType, pair);
263         class2Pair.put(javaType, pair);
264
265         if (sf != null)
266             pair2SF.put(pair, sf);
267         if (dsf != null)
268             pair2DF.put(pair, dsf);
269     }
270
271     /**
272      * Gets the SerializerFactory registered for the specified pair
273      * of Java type and XML data type.
274      *
275      * @param javaType - Class of the Java type
276      * @param xmlType - Qualified name of the XML data type
277      *
278      * @return Registered SerializerFactory
279      *
280      * @throws JAXRPCException - If there is no registered SerializerFactory
281      * for this pair of Java type and XML data type
282      * java.lang.IllegalArgumentException -
283      * If invalid or unsupported XML/Java type is specified
284      */

285     public javax.xml.rpc.encoding.SerializerFactory JavaDoc
286         getSerializer(Class JavaDoc javaType, QName JavaDoc xmlType)
287         throws JAXRPCException JavaDoc {
288
289         javax.xml.rpc.encoding.SerializerFactory JavaDoc sf = null;
290
291         // If the xmlType was not provided, get one
292
if (xmlType == null) {
293             xmlType = getTypeQName(javaType, null);
294             // If we couldn't find one, we're hosed, since getTypeQName()
295
// already asked all of our delegates.
296
if (xmlType == null) {
297                 return null;
298             }
299         }
300
301         // Try to get the serializer associated with this pair
302
Pair pair = new Pair(javaType, xmlType);
303
304         // Now get the serializer with the pair
305
sf = (javax.xml.rpc.encoding.SerializerFactory JavaDoc) pair2SF.get(pair);
306
307         // Need to look into hierarchy of component type.
308
// ex) java.util.GregorianCalendar[]
309
// -> java.util.Calendar[]
310
if (sf == null && javaType.isArray()) {
311             int dimension = 1;
312             Class JavaDoc componentType = javaType.getComponentType();
313             while (componentType.isArray()) {
314                 dimension += 1;
315                 componentType = componentType.getComponentType();
316             }
317             int[] dimensions = new int[dimension];
318             componentType = componentType.getSuperclass();
319             Class JavaDoc superJavaType = null;
320             while (componentType != null) {
321                 superJavaType = Array.newInstance(componentType, dimensions).getClass();
322                 pair = new Pair(superJavaType, xmlType);
323                 sf = (javax.xml.rpc.encoding.SerializerFactory JavaDoc) pair2SF.get(pair);
324                 if (sf != null) {
325                     break;
326                 }
327                 componentType = componentType.getSuperclass();
328             }
329         }
330         
331         // check if ArrayOfT(xml)->T[](java) conversion is possible
332
if (sf == null && javaType.isArray() && xmlType != null) {
333             Pair pair2 = (Pair) qName2Pair.get(xmlType);
334             if (pair2 != null
335                     && pair2.javaType != null
336                     && !pair2.javaType.isPrimitive()
337                     && ArrayUtil.isConvertable(pair2.javaType, javaType)) {
338                 sf = (javax.xml.rpc.encoding.SerializerFactory JavaDoc) pair2SF.get(pair2);
339             }
340         }
341         
342         return sf;
343     }
344     
345     public SerializerFactory finalGetSerializer(Class JavaDoc javaType) {
346         Pair pair;
347         if (isArray(javaType)) {
348             pair = (Pair) qName2Pair.get(Constants.SOAP_ARRAY);
349         } else {
350             pair = (Pair) class2Pair.get(javaType);
351         }
352         if (pair != null) {
353             return (SerializerFactory)pair2SF.get(pair);
354         }
355
356         return null;
357     }
358
359     /**
360      * Get the exact XML type QName which will be used when serializing a
361      * given Class to a given type QName. In other words, if we have:
362      *
363      * Class TypeQName
364      * ----------------------
365      * Base myNS:Base
366      * Child myNS:Child
367      *
368      * and call getXMLType(Child.class, BASE_QNAME), we should get
369      * CHILD_QNAME.
370      *
371      * @param javaType
372      * @param xmlType
373      * @return the type's QName
374      * @throws JAXRPCException
375      */

376     public QName JavaDoc getXMLType(Class JavaDoc javaType, QName JavaDoc xmlType, boolean encoded)
377         throws JAXRPCException JavaDoc
378     {
379         javax.xml.rpc.encoding.SerializerFactory JavaDoc sf = null;
380
381         // If the xmlType was not provided, get one
382
if (xmlType == null) {
383             xmlType = getTypeQNameRecursive(javaType);
384
385             // If we couldn't find one, we're hosed, since getTypeQName()
386
// already asked all of our delegates.
387
if (xmlType == null) {
388                 return null;
389             }
390         }
391
392         // Try to get the serializer associated with this pair
393
Pair pair = new Pair(javaType, xmlType);
394
395         // Now get the serializer with the pair
396
sf = (javax.xml.rpc.encoding.SerializerFactory JavaDoc) pair2SF.get(pair);
397         if (sf != null)
398             return xmlType;
399
400         // If not successful, use the xmlType to get
401
// another pair. For some xmlTypes (like SOAP_ARRAY)
402
// all of the possible javaTypes are not registered.
403
if (isArray(javaType)) {
404             if (encoded) {
405                 return Constants.SOAP_ARRAY;
406             } else {
407                 pair = (Pair) qName2Pair.get(xmlType);
408             }
409         }
410
411         if (pair == null) {
412             pair = (Pair) class2Pair.get(javaType);
413         }
414
415         if (pair != null) {
416             xmlType = pair.xmlType;
417         }
418         return xmlType;
419     }
420
421     /**
422      * Gets the DeserializerFactory registered for the specified pair
423      * of Java type and XML data type.
424      *
425      * @param javaType - Class of the Java type
426      * @param xmlType - Qualified name of the XML data type
427      *
428      * @return Registered DeserializerFactory
429      *
430      * @throws JAXRPCException - If there is no registered DeserializerFactory
431      * for this pair of Java type and XML data type
432      * java.lang.IllegalArgumentException -
433      * If invalid or unsupported XML/Java type is specified
434      */

435     public javax.xml.rpc.encoding.DeserializerFactory JavaDoc
436         getDeserializer(Class JavaDoc javaType, QName JavaDoc xmlType, TypeMappingDelegate start)
437         throws JAXRPCException JavaDoc {
438         if (javaType == null) {
439             javaType = start.getClassForQName(xmlType);
440             // If we don't have a mapping, we're hosed since getClassForQName()
441
// has already asked all our delegates.
442
if (javaType == null) {
443                 return null;
444             }
445         }
446
447         Pair pair = new Pair(javaType, xmlType);
448
449         return (javax.xml.rpc.encoding.DeserializerFactory JavaDoc) pair2DF.get(pair);
450     }
451     
452     public DeserializerFactory finalGetDeserializer(Class JavaDoc javaType,
453                                                     QName JavaDoc xmlType,
454                                                     TypeMappingDelegate start) {
455         DeserializerFactory df = null;
456         if (javaType != null && javaType.isArray()) {
457             Class JavaDoc componentType = javaType.getComponentType();
458
459             // HACK ALERT - Don't return the ArrayDeserializer IF
460
// the xmlType matches the component type of the array,
461
// because that means we're using maxOccurs and we'll
462
// want the higher layers to get the component type
463
// deserializer... (sigh)
464
if (xmlType != null) {
465                 Class JavaDoc actualClass = start.getClassForQName(xmlType);
466                 if (actualClass == componentType ||
467                     (actualClass != null && componentType.isAssignableFrom(actualClass))) {
468                     return null;
469                 }
470             }
471             Pair pair = (Pair) qName2Pair.get(Constants.SOAP_ARRAY);
472             df = (DeserializerFactory) pair2DF.get(pair);
473             if (df instanceof ArrayDeserializerFactory && javaType.isArray()) {
474                 QName JavaDoc componentXmlType = start.getTypeQName(componentType);
475                 if (componentXmlType != null) {
476                     df = new ArrayDeserializerFactory(componentXmlType);
477                 }
478             }
479         }
480         return df;
481     }
482
483     /**
484      * Removes the SerializerFactory registered for the specified
485      * pair of Java type and XML data type.
486      *
487      * @param javaType - Class of the Java type
488      * @param xmlType - Qualified name of the XML data type
489      *
490      * @throws JAXRPCException - If there is error in
491      * removing the registered SerializerFactory
492      */

493     public void removeSerializer(Class JavaDoc javaType, QName JavaDoc xmlType)
494         throws JAXRPCException JavaDoc {
495         if (javaType == null || xmlType == null) {
496             throw new JAXRPCException JavaDoc(
497                     Messages.getMessage(javaType == null ?
498                                          "badJavaType" : "badXmlType"));
499         }
500
501         Pair pair = new Pair(javaType, xmlType);
502         pair2SF.remove(pair);
503     }
504
505     /**
506      * Removes the DeserializerFactory registered for the specified
507      * pair of Java type and XML data type.
508      *
509      * @param javaType - Class of the Java type
510      * @param xmlType - Qualified name of the XML data type
511      *
512      * @throws JAXRPCException - If there is error in
513      * removing the registered DeserializerFactory
514      */

515     public void removeDeserializer(Class JavaDoc javaType, QName JavaDoc xmlType)
516         throws JAXRPCException JavaDoc {
517         if (javaType == null || xmlType == null) {
518             throw new JAXRPCException JavaDoc(
519                     Messages.getMessage(javaType == null ?
520                                          "badJavaType" : "badXmlType"));
521         }
522         Pair pair = new Pair(javaType, xmlType);
523         pair2DF.remove(pair);
524     }
525
526
527      /********* End JAX-RPC Compliant Method Definitions *****************/
528
529     /**
530      * Gets the QName for the type mapped to Class.
531      * @param javaType class or type
532      * @return xmlType qname or null
533      */

534     public QName JavaDoc getTypeQNameRecursive(Class JavaDoc javaType) {
535         QName JavaDoc ret = null;
536         while (javaType != null) {
537             ret = getTypeQName(javaType, null);
538             if (ret != null)
539                 return ret;
540
541             // Walk my interfaces...
542
Class JavaDoc [] interfaces = javaType.getInterfaces();
543             if (interfaces != null) {
544                 for (int i = 0; i < interfaces.length; i++) {
545                     Class JavaDoc iface = interfaces[i];
546                     ret = getTypeQName(iface, null);
547                     if (ret != null)
548                         return ret;
549                 }
550             }
551
552             javaType = javaType.getSuperclass();
553         }
554         return null;
555     }
556
557     /**
558      * Get the QName for this Java class, but only return a specific
559      * mapping if there is one. In other words, don't do special array
560      * processing, etc.
561      *
562      * @param javaType
563      * @return
564      */

565     public QName JavaDoc getTypeQNameExact(Class JavaDoc javaType, TypeMappingDelegate next) {
566         if (javaType == null)
567             return null;
568        
569         QName JavaDoc xmlType = null;
570         Pair pair = (Pair) class2Pair.get(javaType);
571
572         if (isDotNetSoapEncFixNeeded() && pair != null ) {
573             // Hack alert!
574
// If we are in .NET bug compensation mode, skip over any
575
// SOAP Encoded types we my find and prefer XML Schema types
576
xmlType = pair.xmlType;
577             if (Constants.isSOAP_ENC(xmlType.getNamespaceURI()) &&
578                     !xmlType.getLocalPart().equals("Array")) {
579                 pair = null;
580             }
581         }
582
583         if (pair == null && next != null) {
584             // Keep checking up the stack...
585
xmlType = next.delegate.getTypeQNameExact(javaType,
586                                                       next.next);
587         }
588
589         if (pair != null) {
590             xmlType = pair.xmlType;
591         }
592
593         return xmlType;
594     }
595
596     /**
597      * isDotNetSoapEncFixNeeded - Do we need to compensate for the dotnet bug.
598      * check the service specific flag before using the global flag
599      * @return
600      */

601     private boolean isDotNetSoapEncFixNeeded() {
602         MessageContext msgContext = MessageContext.getCurrentContext();
603         if (msgContext != null) {
604             SOAPService service = msgContext.getService();
605             if (service != null) {
606                 String JavaDoc dotNetSoapEncFix = (String JavaDoc) service.getOption(AxisEngine.PROP_DOTNET_SOAPENC_FIX);
607                 if (dotNetSoapEncFix != null) {
608                     return JavaUtils.isTrue(dotNetSoapEncFix);
609                 }
610             }
611         }
612         return TypeMappingImpl.dotnet_soapenc_bugfix;
613     }
614
615     public QName JavaDoc getTypeQName(Class JavaDoc javaType, TypeMappingDelegate next) {
616         QName JavaDoc xmlType = getTypeQNameExact(javaType, next);
617
618         /* If auto-typing is on and the array has the default SOAP_ARRAY QName,
619          * then generate a namespace for this array intelligently. Also
620          * register it's javaType and xmlType. List classes and derivitives
621          * can't be used because they should be serialized as an anyType array.
622          */

623         if ( shouldDoAutoTypes() &&
624              javaType != List JavaDoc.class &&
625              !List JavaDoc.class.isAssignableFrom(javaType) &&
626              xmlType != null &&
627              xmlType.equals(Constants.SOAP_ARRAY) )
628         {
629             xmlType = new QName JavaDoc(
630                 Namespaces.makeNamespace( javaType.getName() ),
631                 Types.getLocalNameFromFullName( javaType.getName() ) );
632
633             internalRegister( javaType,
634                               xmlType,
635                               new ArraySerializerFactory(),
636                               new ArrayDeserializerFactory() );
637         }
638
639         // Can only detect arrays via code
640
if (xmlType == null && isArray(javaType)) {
641
642             // get the registered array if any
643
Pair pair = (Pair) class2Pair.get(Object JavaDoc[].class);
644             // TODO: it always returns the last registered one,
645
// so that's why the soap 1.2 typemappings have to
646
// move to an other registry to differentiate them
647
if (pair != null) {
648                 xmlType = pair.xmlType;
649             } else {
650                 xmlType = Constants.SOAP_ARRAY;
651             }
652         }
653
654         /* If the class isn't an array or List and auto-typing is turned on,
655         * register the class and it's type as beans.
656         */

657         if (xmlType == null && shouldDoAutoTypes())
658         {
659             xmlType = new QName JavaDoc(
660                 Namespaces.makeNamespace( javaType.getName() ),
661                 Types.getLocalNameFromFullName( javaType.getName() ) );
662
663             /* If doAutoTypes is set, register a new type mapping for the
664             * java class with the above QName. This way, when getSerializer()
665             * and getDeserializer() are called, this QName is returned and
666             * these methods do not need to worry about creating a serializer.
667             */

668             internalRegister( javaType,
669                               xmlType,
670                               new BeanSerializerFactory(javaType, xmlType),
671                               new BeanDeserializerFactory(javaType, xmlType) );
672         }
673
674         //log.debug("getTypeQName xmlType =" + xmlType);
675
return xmlType;
676     }
677
678     public Class JavaDoc getClassForQName(QName JavaDoc xmlType, Class JavaDoc javaType,
679                                   TypeMappingDelegate next) {
680         if (xmlType == null) {
681             return null;
682         }
683
684         //log.debug("getClassForQName xmlType =" + xmlType);
685

686         if (javaType != null) {
687             // Looking for an exact match first
688
Pair pair = new Pair(javaType, xmlType);
689             if (pair2DF.get(pair) == null) {
690                 if (next != null) {
691                     javaType = next.getClassForQName(xmlType, javaType);
692                 }
693             }
694         }
695
696         if (javaType == null) {
697             //look for it in our map
698
Pair pair = (Pair) qName2Pair.get(xmlType);
699             if (pair == null && next != null) {
700                 //on no match, delegate
701
javaType = next.getClassForQName(xmlType);
702             } else if (pair != null) {
703                 javaType = pair.javaType;
704             }
705         }
706         
707         //log.debug("getClassForQName javaType =" + javaType);
708
if(javaType == null && shouldDoAutoTypes()) {
709             String JavaDoc pkg = Namespaces.getPackage(xmlType.getNamespaceURI());
710             if (pkg != null) {
711                 String JavaDoc className = xmlType.getLocalPart();
712                 if (pkg.length() > 0) {
713                     className = pkg + "." + className;
714                 }
715                 try {
716                     javaType = ClassUtils.forName(className);
717                     internalRegister(javaType,
718                                      xmlType,
719                                      new BeanSerializerFactory(javaType, xmlType),
720                                      new BeanDeserializerFactory(javaType, xmlType));
721                 } catch (ClassNotFoundException JavaDoc e) {
722                 }
723             }
724         }
725         return javaType;
726     }
727
728     public void setDoAutoTypes(boolean doAutoTypes) {
729         this.doAutoTypes = doAutoTypes ? Boolean.TRUE : Boolean.FALSE;
730     }
731     
732     public boolean shouldDoAutoTypes() {
733         if(doAutoTypes != null) {
734             return doAutoTypes.booleanValue();
735         }
736         MessageContext msgContext = MessageContext.getCurrentContext();
737         if(msgContext != null) {
738             if (msgContext.isPropertyTrue("axis.doAutoTypes") ||
739                     (msgContext.getAxisEngine() != null && JavaUtils.isTrue(msgContext.getAxisEngine().getOption("axis.doAutoTypes")))) {
740                 doAutoTypes = Boolean.TRUE;
741             }
742         }
743         if(doAutoTypes == null){
744             doAutoTypes = AxisProperties.getProperty("axis.doAutoTypes",
745                     "false")
746                     .equals("true") ?
747                     Boolean.TRUE : Boolean.FALSE;
748         }
749         return doAutoTypes.booleanValue();
750     }
751
752     /**
753      * Returns an array of all the classes contained within this mapping
754      */

755     public Class JavaDoc [] getAllClasses(TypeMappingDelegate next)
756     {
757         java.util.HashSet JavaDoc temp = new java.util.HashSet JavaDoc();
758         if (next != null)
759         {
760             temp.addAll(java.util.Arrays.asList(next.getAllClasses()));
761         }
762         temp.addAll(class2Pair.keySet());
763         return (Class JavaDoc[])temp.toArray(new Class JavaDoc[temp.size()]);
764     }
765 }
Popular Tags