Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/axis/encoding/TypeMappingImpl.java


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;
38  import javax.xml.rpc.JAXRPCException;
39  
40  import java.lang.reflect.Array;
41  import java.util.ArrayList;
42  import java.util.HashMap;
43  import java.util.List;
44  import java.io.Serializable;
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
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 {
88          public Class javaType;
89          public QName xmlType;
90          public Pair(Class javaType, QName xmlType) {
91              this.javaType = javaType;
92              this.xmlType = xmlType;
93          }
94          public boolean equals(Object 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 qName2Pair;     // QName to Pair Mapping
118     private HashMap class2Pair;     // Class Name to Pair Mapping
119     private HashMap pair2SF;        // Pair to Serialization Factory
120     private HashMap pair2DF;        // Pair to Deserialization Factory
121     private ArrayList namespaces;   // Supported namespaces
122 
123     protected Boolean doAutoTypes = null;
124 
125     /**
126      * Construct TypeMapping
127      */
128     public TypeMappingImpl() {
129         qName2Pair  = new HashMap();
130         class2Pair  = new HashMap();
131         pair2SF     = new HashMap();
132         pair2DF     = new HashMap();
133         namespaces  = new ArrayList();
134     }
135 
136     private static boolean isArray(Class clazz)
137     {
138         return clazz.isArray() || java.util.Collection.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[] getSupportedEncodings() {
151         String[] stringArray = new String[namespaces.size()];
152         return (String[]) 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[] 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 javaType, QName xmlType) {
187         if (javaType == null || xmlType == null) {
188             // REMOVED_FOR_TCK
189             // return false;
190             throw new JAXRPCException(
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 javaType, QName xmlType,
212                          javax.xml.rpc.encoding.SerializerFactory sf,
213                          javax.xml.rpc.encoding.DeserializerFactory dsf)
214         throws JAXRPCException {
215         // At least a serializer or deserializer factory must be specified.
216         if (sf == null && dsf == null) {
217             throw new JAXRPCException(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 javaType, QName xmlType,
233                          javax.xml.rpc.encoding.SerializerFactory sf,
234                          javax.xml.rpc.encoding.DeserializerFactory dsf)
235             throws JAXRPCException {
236         // Both javaType and xmlType must be specified.
237         if (javaType == null || xmlType == null) {
238             throw new JAXRPCException(
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
286         getSerializer(Class javaType, QName xmlType)
287         throws JAXRPCException {
288 
289         javax.xml.rpc.encoding.SerializerFactory 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) 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 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 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) 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) pair2SF.get(pair2);
339             }
340         }
341         
342         return sf;
343     }
344     
345     public SerializerFactory finalGetSerializer(Class 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 getXMLType(Class javaType, QName xmlType, boolean encoded)
377         throws JAXRPCException
378     {
379         javax.xml.rpc.encoding.SerializerFactory 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) 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
436         getDeserializer(Class javaType, QName xmlType, TypeMappingDelegate start)
437         throws JAXRPCException {
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) pair2DF.get(pair);
450     }
451     
452     public DeserializerFactory finalGetDeserializer(Class javaType,
453                                                     QName xmlType,
454                                                     TypeMappingDelegate start) {
455         DeserializerFactory df = null;
456         if (javaType != null && javaType.isArray()) {
457             Class 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 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 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 javaType, QName xmlType)
494         throws JAXRPCException {
495         if (javaType == null || xmlType == null) {
496             throw new JAXRPCException(
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 javaType, QName xmlType)
516         throws JAXRPCException {
517         if (javaType == null || xmlType == null) {
518             throw new JAXRPCException(
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 getTypeQNameRecursive(Class javaType) {
535         QName 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 [] interfaces = javaType.getInterfaces();
543             if (interfaces != null) {
544                 for (int i = 0; i < interfaces.length; i++) {
545                     Class 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 getTypeQNameExact(Class javaType, TypeMappingDelegate next) {
566         if (javaType == null)
567             return null;
568        
569         QName 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 dotNetSoapEncFix = (String) 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 getTypeQName(Class javaType, TypeMappingDelegate next) {
616         QName 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.class &&
625              !List.class.isAssignableFrom(javaType) &&
626              xmlType != null &&
627              xmlType.equals(Constants.SOAP_ARRAY) )
628         {
629             xmlType = new QName(
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[].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(
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 getClassForQName(QName xmlType, Class 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 pkg = Namespaces.getPackage(xmlType.getNamespaceURI());
710             if (pkg != null) {
711                 String 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 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 [] getAllClasses(TypeMappingDelegate next)
756     {
757         java.util.HashSet temp = new java.util.HashSet();
758         if (next != null)
759         {
760             temp.addAll(java.util.Arrays.asList(next.getAllClasses()));
761         }
762         temp.addAll(class2Pair.keySet());
763         return (Class[])temp.toArray(new Class[temp.size()]);
764     }
765 }