KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > axis > wsdl > fromJava > Types


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2001-2002 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Axis" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation. For more
52  * information on the Apache Software Foundation, please see
53  * <http://www.apache.org/>.
54  */

55
56 package org.jboss.axis.wsdl.fromJava;
57
58 import org.jboss.axis.AxisFault;
59 import org.jboss.axis.Constants;
60 import org.jboss.axis.InternalException;
61 import org.jboss.axis.description.ServiceDesc;
62 import org.jboss.axis.encoding.Serializer;
63 import org.jboss.axis.encoding.SerializerFactory;
64 import org.jboss.axis.encoding.SimpleType;
65 import org.jboss.axis.encoding.TypeMapping;
66 import org.jboss.axis.encoding.ser.BeanSerializerFactory;
67 import org.jboss.axis.encoding.ser.EnumSerializerFactory;
68 import org.jboss.axis.enums.Style;
69 import org.jboss.axis.utils.JavaUtils;
70 import org.jboss.axis.utils.Messages;
71 import org.jboss.axis.utils.XMLUtils;
72 import org.jboss.axis.wsdl.symbolTable.BaseTypeMapping;
73 import org.jboss.axis.wsdl.symbolTable.SymbolTable;
74 import org.jboss.logging.Logger;
75 import org.w3c.dom.Attr JavaDoc;
76 import org.w3c.dom.Document JavaDoc;
77 import org.w3c.dom.Element JavaDoc;
78 import org.w3c.dom.NamedNodeMap JavaDoc;
79 import org.w3c.dom.Node JavaDoc;
80 import org.w3c.dom.NodeList JavaDoc;
81 import org.xml.sax.SAXException JavaDoc;
82
83 import javax.wsdl.Definition;
84 import javax.wsdl.WSDLException;
85 import javax.xml.namespace.QName JavaDoc;
86 import javax.xml.parsers.ParserConfigurationException JavaDoc;
87 import javax.xml.rpc.holders.Holder JavaDoc;
88 import java.io.IOException JavaDoc;
89 import java.lang.reflect.Field JavaDoc;
90 import java.lang.reflect.Modifier JavaDoc;
91 import java.net.URL JavaDoc;
92 import java.util.ArrayList JavaDoc;
93 import java.util.HashMap JavaDoc;
94 import java.util.Iterator JavaDoc;
95 import java.util.List JavaDoc;
96
97 /**
98  * <p>Description: </p> This class is used to recursively serializes a Java Class into
99  * an XML Schema representation.
100  * <p/>
101  * It has utility methods to create a schema node, assosiate namespaces to the various types
102  *
103  * @author unascribed
104  */

105 public class Types
106 {
107    private static Logger log = Logger.getLogger(Types.class.getName());
108
109    Definition def;
110    Namespaces namespaces = null;
111    TypeMapping tm;
112    TypeMapping defaultTM;
113    String JavaDoc targetNamespace;
114    Element JavaDoc wsdlTypesElem = null;
115    HashMap JavaDoc schemaTypes = null;
116    HashMap JavaDoc schemaElementNames = null;
117    HashMap JavaDoc schemaUniqueElementNames = null;
118    HashMap JavaDoc wrapperMap = new HashMap JavaDoc();
119    List JavaDoc stopClasses = null;
120    List JavaDoc beanCompatErrs = new ArrayList JavaDoc();
121    ServiceDesc serviceDesc = null;
122
123    /**
124     * This class serailizes a <code>Class</code> to XML Schema. The constructor
125     * provides the context for the streamed node within the WSDL document
126     *
127     * @param def WSDL Definition Element to declare namespaces
128     * @param tm TypeMappingRegistry to handle known types
129     * @param defaultTM default TM
130     * @param namespaces user defined or autogenerated namespace and prefix maps
131     * @param targetNamespace targetNamespace of the document
132     */

133    public Types(Definition def,
134                 TypeMapping tm,
135                 TypeMapping defaultTM,
136                 Namespaces namespaces,
137                 String JavaDoc targetNamespace,
138                 List JavaDoc stopClasses,
139                 ServiceDesc serviceDesc)
140    {
141       this.def = def;
142       this.serviceDesc = serviceDesc;
143       createDocumentFragment();
144       this.tm = tm;
145       this.defaultTM = defaultTM;
146       this.namespaces = namespaces;
147       this.targetNamespace = targetNamespace;
148       this.stopClasses = stopClasses;
149       schemaElementNames = new HashMap JavaDoc();
150       schemaUniqueElementNames = new HashMap JavaDoc();
151       schemaTypes = new HashMap JavaDoc();
152    }
153
154    /**
155     * Return the namespaces object for the current context
156     */

157    public Namespaces getNamespaces()
158    {
159       return namespaces;
160    }
161
162    /**
163     * Loads the types from the input schema file.
164     *
165     * @param inputSchema file or URL
166     */

167    public void loadInputSchema(String JavaDoc inputSchema)
168            throws IOException JavaDoc, WSDLException, SAXException JavaDoc,
169            ParserConfigurationException JavaDoc
170    {
171       // Read the input wsdl file into a Document
172
Document JavaDoc doc = XMLUtils.newDocument(inputSchema);
173
174       // Ensure that the root element is xsd:schema
175
Element JavaDoc root = doc.getDocumentElement();
176       if (root.getLocalName().equals("schema") &&
177               Constants.isSchemaXSD(root.getNamespaceURI()))
178       {
179          Node JavaDoc schema = docHolder.importNode(root, true);
180          if (null == wsdlTypesElem)
181          {
182             writeWsdlTypesElement();
183          }
184          wsdlTypesElem.appendChild(schema);
185
186          // Create a symbol table and populate it with the input types
187
BaseTypeMapping btm =
188                  new BaseTypeMapping()
189                  {
190                     public String JavaDoc getBaseName(QName JavaDoc qNameIn)
191                     {
192                        QName JavaDoc qName = new QName JavaDoc(qNameIn.getNamespaceURI(),
193                                qNameIn.getLocalPart());
194                        Class JavaDoc cls = defaultTM.getClassForQName(qName);
195                        if (cls == null)
196                           return null;
197                        else
198                           return JavaUtils.getTextClassName(cls.getName());
199                     }
200                  };
201          SymbolTable symbolTable = new SymbolTable(btm,
202                  true, false, false);
203          symbolTable.populateTypes(new URL JavaDoc(inputSchema), doc);
204
205          processSymTabEntries(symbolTable);
206       }
207       else
208       {
209          // If not, we'll just bail out... perhaps we should log a warning
210
// or throw an exception?
211
;
212       }
213    }
214
215    /**
216     * Walk the type/element entries in the symbol table and
217     * add each one to the list of processed types. This prevents
218     * the types from being duplicated.
219     *
220     * @param symbolTable
221     */

222    private void processSymTabEntries(SymbolTable symbolTable)
223    {
224       Iterator JavaDoc iterator = symbolTable.getElementIndex().keySet().iterator();
225       while (iterator.hasNext())
226       {
227          QName JavaDoc name = (QName JavaDoc)iterator.next();
228          addToElementsList(name);
229       }
230       iterator = symbolTable.getTypeIndex().keySet().iterator();
231       while (iterator.hasNext())
232       {
233          QName JavaDoc name = (QName JavaDoc)iterator.next();
234          addToTypesList(name);
235       }
236    }
237
238    /**
239     * Load the types from the input wsdl file.
240     *
241     * @param inputWSDL file or URL
242     */

243    public void loadInputTypes(String JavaDoc inputWSDL)
244            throws IOException JavaDoc, WSDLException,
245            SAXException JavaDoc, ParserConfigurationException JavaDoc
246    {
247
248       // Read the input wsdl file into a Document
249
Document JavaDoc doc = XMLUtils.newDocument(inputWSDL);
250
251       // Search for the 'types' element
252
NodeList JavaDoc elements = doc.getChildNodes();
253       if (elements.getLength() > 0 &&
254               elements.item(0).getLocalName().equals("definitions"))
255       {
256          elements = elements.item(0).getChildNodes();
257          for (int i = 0;
258               i < elements.getLength() && wsdlTypesElem == null;
259               i++)
260          {
261             Node JavaDoc node = elements.item(i);
262             if (node.getLocalName() != null &&
263                     node.getLocalName().equals("types"))
264             {
265                wsdlTypesElem = (Element JavaDoc)node;
266             }
267          }
268       }
269
270       // If types element not found, there is no need to continue.
271
if (wsdlTypesElem == null)
272       {
273          return;
274       }
275
276       // Import the types element into the Types docHolder document
277
wsdlTypesElem =
278               (Element JavaDoc)docHolder.importNode(wsdlTypesElem, true);
279       docHolder.appendChild(wsdlTypesElem);
280
281       // Create a symbol table and populate it with the input wsdl document
282
BaseTypeMapping btm =
283               new BaseTypeMapping()
284               {
285                  public String JavaDoc getBaseName(QName JavaDoc qNameIn)
286                  {
287                     QName JavaDoc qName = new QName JavaDoc(qNameIn.getNamespaceURI(),
288                             qNameIn.getLocalPart());
289                     Class JavaDoc cls = defaultTM.getClassForQName(qName);
290                     if (cls == null)
291                        return null;
292                     else
293                        return JavaUtils.getTextClassName(cls.getName());
294                  }
295               };
296       SymbolTable symbolTable = new SymbolTable(btm,
297               true, false, false);
298       symbolTable.populate(null, doc);
299
300       processSymTabEntries(symbolTable);
301    }
302
303    /**
304     * Write out a type referenced by a part type attribute.
305     *
306     * @param type <code>Class</code> to generate the XML Schema info for
307     * @param qname <code>QName</code> of the type. If null, qname is
308     * defaulted from the class.
309     * @return the QName of the generated Schema type, null if void,
310     * if the Class type cannot be converted to a schema type
311     * then xsd:anytype is returned.
312     */

313    public QName JavaDoc writeTypeForPart(Class JavaDoc type, QName JavaDoc qname) throws AxisFault
314    {
315       //patch by costin to fix an NPE; commented out till we find out what the problem is
316
//if you get NullPointerExceptions in this class, turn it on and submit some
317
//replicable test data to the Axis team via bugzilla
318
/*
319       if( type==null ) {
320           return null;
321       }
322       */

323       if (type.getName().equals("void"))
324       {
325          return null;
326       }
327
328       if (Holder JavaDoc.class.isAssignableFrom(type))
329       {
330          type = JavaUtils.getHolderValueType(type);
331       }
332
333       // Get the qname
334
if (qname == null ||
335               (Constants.isSOAP_ENC(qname.getNamespaceURI()) &&
336               "Array".equals(qname.getLocalPart())))
337       {
338          qname = getTypeQName(type);
339          if (qname == null)
340          {
341             throw new AxisFault("Class:" + type.getName());
342          }
343       }
344
345       if (!makeTypeElement(type, qname, null))
346       {
347          qname = Constants.XSD_ANYTYPE;
348       }
349
350       return qname;
351    }
352
353    /**
354     * Write out an element referenced by a part element attribute.
355     *
356     * @param type <code>Class</code> to generate the XML Schema info for
357     * @param qname <code>QName</code> of the element. If null, qname is
358     * defaulted from the class.
359     * @return the QName of the generated Schema type, null if no element
360     */

361    public QName JavaDoc writeElementForPart(Class JavaDoc type, QName JavaDoc qname) throws AxisFault
362    {
363       //patch by costin to fix an NPE; commented out till we find out what the problem is
364
//if you get NullPointerExceptions in this class, turn it on and submit some
365
//replicable test data to the Axis team via bugzilla
366
/*
367       if( type==null ) {
368           return null;
369       }
370       */

371       if (type.getName().equals("void"))
372       {
373          return null;
374       }
375
376       if (Holder JavaDoc.class.isAssignableFrom(type))
377       {
378          type = JavaUtils.getHolderValueType(type);
379       }
380
381       // Get the qname
382
if (qname == null ||
383               (Constants.isSOAP_ENC(qname.getNamespaceURI()) &&
384               "Array".equals(qname.getLocalPart())))
385       {
386          qname = getTypeQName(type);
387          if (qname == null)
388          {
389             throw new AxisFault("Class:" + type.getName());
390          }
391       }
392
393       // Return null it a simple type (not an element)
394
String JavaDoc nsURI = qname.getNamespaceURI();
395       if (Constants.isSchemaXSD(nsURI) ||
396               (Constants.isSOAP_ENC(nsURI) &&
397               !"Array".equals(qname.getLocalPart())))
398       {
399          return null;
400       }
401
402       // Make sure a types section is present
403
if (wsdlTypesElem == null)
404       {
405          writeWsdlTypesElement();
406       }
407
408       // Write Element, if problems occur return null.
409
if (writeTypeAsElement(type, qname) == null)
410       {
411          qname = null;
412       }
413       return qname;
414    }
415
416    /**
417     * Write the element definition for a WRAPPED operation. This will
418     * write out any necessary namespace/schema declarations, an an element
419     * definition with an internal (anonymous) complexType. The name of the
420     * element will be *foo*Request or *foo*Response depending on whether the
421     * request boolean is true. If the operation contains parameters, then
422     * we also generate a &gt;sequence&lt; node underneath the complexType,
423     * and return it for later use by writeWrappedParameter() below.
424     *
425     * @param qname the desired element QName
426     * @param request true if we're writing the request wrapper, false if
427     * writing the response.
428     * @param hasParams true if there are parameters, and thus a sequence
429     * node is needed
430     * @return a DOM Element for the sequence, inside which we'll write the
431     * parameters as elements, or null if there are no parameters
432     */

433    public Element JavaDoc writeWrapperElement(QName JavaDoc qname,
434                                       boolean request,
435                                       boolean hasParams) throws AxisFault
436    {
437       // Make sure a types section is present
438
if (wsdlTypesElem == null)
439       {
440          writeWsdlTypesElement();
441       }
442
443       // Write the namespace definition for the wrapper
444
writeTypeNamespace(qname);
445
446       // Create an <element> for the wrapper
447
Element JavaDoc wrapperElement = docHolder.createElement("element");
448       writeSchemaElement(qname, wrapperElement);
449       wrapperElement.setAttribute("name", qname.getLocalPart());
450
451       // Create an anonymous <complexType> for the wrapper
452
Element JavaDoc complexType = docHolder.createElement("complexType");
453       wrapperElement.appendChild(complexType);
454
455       // If we have parameters in the operation, create a <sequence>
456
// under the complexType and return it.
457
if (hasParams)
458       {
459          Element JavaDoc sequence = docHolder.createElement("sequence");
460          complexType.appendChild(sequence);
461          return sequence;
462       }
463
464       return null;
465    }
466
467    /**
468     * Write a parameter (a sub-element) into a sequence generated by
469     * writeWrapperElement() above.
470     *
471     * @param sequence the &lt;sequence&gt; in which we're writing
472     * @param name is the name of an element to add to the wrapper element.
473     * @param type is the QName of the type of the element.
474     */

475    public void writeWrappedParameter(Element JavaDoc sequence, String JavaDoc name,
476                                      QName JavaDoc type, Class JavaDoc javaType)
477            throws AxisFault
478    {
479
480       if (javaType == void.class)
481       {
482          return;
483       }
484
485       if (type == null)
486       {
487          type = writeTypeForPart(javaType, type);
488       }
489
490       if (type == null)
491       {
492          // throw an Exception!!
493
}
494
495       Element JavaDoc childElem;
496       if (isAnonymousType(type))
497       {
498          childElem = createElementWithAnonymousType(name, javaType,
499                  false, docHolder);
500       }
501       else
502       {
503          // Create the child <element> and add it to the wrapper <sequence>
504
childElem = docHolder.createElement("element");
505          childElem.setAttribute("name", name);
506
507          String JavaDoc prefix = namespaces.getCreatePrefix(type.getNamespaceURI());
508          String JavaDoc prefixedName = prefix + ":" + type.getLocalPart();
509          childElem.setAttribute("type", prefixedName);
510       }
511       sequence.appendChild(childElem);
512    }
513
514    private boolean isAnonymousType(QName JavaDoc type)
515    {
516       return type.getLocalPart().indexOf(SymbolTable.ANON_TOKEN) != -1;
517    }
518
519    /**
520     * Create a schema element for the given type
521     *
522     * @param type the class type
523     * @return the QName of the generated Element or problems occur
524     */

525    private QName JavaDoc writeTypeAsElement(Class JavaDoc type, QName JavaDoc qName) throws AxisFault
526    {
527       if (qName == null ||
528               Constants.equals(Constants.SOAP_ARRAY, qName))
529       {
530          qName = getTypeQName(type);
531       }
532       QName JavaDoc typeQName = writeTypeNamespace(type, qName);
533
534       String JavaDoc elementType = writeType(type, qName);
535       if (elementType != null)
536       {
537          Element JavaDoc element = createElementDecl(qName.getLocalPart(), type, qName, isNullable(type), false);
538          if (element != null)
539             writeSchemaElement(typeQName, element);
540          return qName;
541       }
542       return null;
543    }
544
545    /**
546     * write out the namespace declaration and return the type QName for the
547     * given <code>Class</code>
548     *
549     * @param type input Class
550     * @param qName qname of the Class
551     * @return QName for the schema type representing the class
552     */

553    private QName JavaDoc writeTypeNamespace(Class JavaDoc type, QName JavaDoc qName)
554    {
555       if (qName == null)
556       {
557          qName = getTypeQName(type);
558       }
559       writeTypeNamespace(qName);
560       return qName;
561    }
562
563    /**
564     * write out the namespace declaration.
565     *
566     * @param qName qname of the type
567     */

568    private void writeTypeNamespace(QName JavaDoc qName)
569    {
570       if (qName != null && !qName.getNamespaceURI().equals(""))
571       {
572          String JavaDoc pref = def.getPrefix(qName.getNamespaceURI());
573          if (pref == null)
574             def.addNamespace(namespaces.getCreatePrefix(qName.getNamespaceURI()),
575                     qName.getNamespaceURI());
576
577       }
578    }
579
580    /**
581     * Return the QName of the specified javaType
582     *
583     * @param javaType input javaType Class
584     * @return QName
585     */

586    public QName JavaDoc getTypeQName(Class JavaDoc javaType)
587    {
588       QName JavaDoc qName = null;
589
590       // Use the typeMapping information to lookup the qName.
591
QName JavaDoc dQName = null;
592       if (defaultTM != null)
593       {
594          dQName = defaultTM.getTypeQName(javaType);
595       }
596       if (tm != null)
597       {
598          qName = tm.getTypeQName(javaType);
599       }
600       if (qName == null)
601       {
602          qName = dQName;
603       }
604       else if (qName != null && qName != dQName)
605       {
606          // If the TM and default TM resulted in different
607
// names, choose qName unless it is a schema namespace.
608
// (i.e. prefer soapenc primitives over schema primitives)
609
if (Constants.isSchemaXSD(qName.getNamespaceURI()))
610          {
611             qName = dQName;
612          }
613       }
614
615       // If the javaType is an array and the qName is
616
// SOAP_ARRAY, construct the QName using the
617
// QName of the component type
618
if (javaType.isArray() &&
619               qName != null &&
620               Constants.equals(Constants.SOAP_ARRAY, qName))
621       {
622          Class JavaDoc componentType = javaType.getComponentType();
623          // If component namespace uri == targetNamespace
624
// Construct ArrayOf<componentLocalPart>
625
// Else
626
// Construct ArrayOf_<componentPrefix>_<componentLocalPart>
627
QName JavaDoc cqName = getTypeQName(componentType);
628          if (targetNamespace.equals(cqName.getNamespaceURI()))
629          {
630             qName = new QName JavaDoc(targetNamespace,
631                     "ArrayOf" + cqName.getLocalPart());
632          }
633          else
634          {
635             String JavaDoc pre = namespaces.getCreatePrefix(cqName.getNamespaceURI());
636             qName = new QName JavaDoc(targetNamespace,
637                     "ArrayOf_" + pre + "_" + cqName.getLocalPart());
638          }
639          return qName;
640       }
641
642       // If a qName was not found construct one using the
643
// class name information.
644
if (qName == null)
645       {
646          String JavaDoc pkg = getPackageNameFromFullName(javaType.getName());
647          String JavaDoc lcl = getLocalNameFromFullName(javaType.getName());
648
649          String JavaDoc ns = namespaces.getCreate(pkg);
650          namespaces.getCreatePrefix(ns);
651          String JavaDoc localPart = lcl.replace('$', '_');
652          qName = new QName JavaDoc(ns, localPart);
653       }
654
655       return qName;
656    }
657
658    /**
659     * Return a string suitable for representing a given QName in the context
660     * of this WSDL document. If the namespace of the QName is not yet
661     * registered, we will register it up in the Definitions.
662     *
663     * @param qname a QName (typically a type)
664     * @return a String containing a standard "ns:localPart" rep of the QName
665     */

666    public String JavaDoc getQNameString(QName JavaDoc qname)
667    {
668       String JavaDoc prefix = namespaces.getCreatePrefix(qname.getNamespaceURI());
669       return prefix + ":" + qname.getLocalPart();
670    }
671
672    /**
673     * Utility method to get the package name from a fully qualified java class name
674     *
675     * @param full input class name
676     * @return package name
677     */

678    public static String JavaDoc getPackageNameFromFullName(String JavaDoc full)
679    {
680       if (full.lastIndexOf('.') < 0)
681          return "";
682       else
683          return full.substring(0, full.lastIndexOf('.'));
684    }
685
686    /**
687     * Utility method to get the local class name from a fully qualified java class name
688     *
689     * @param full input class name
690     * @return package name
691     */

692    public static String JavaDoc getLocalNameFromFullName(String JavaDoc full)
693    {
694       if (full.lastIndexOf('.') < 0)
695          return full;
696       else
697          return full.substring(full.lastIndexOf('.') + 1);
698    }
699
700    /**
701     * Write out the given Element into the appropriate schema node.
702     * If need be create the schema node as well
703     *
704     * @param qName qName to get the namespace of the schema node
705     * @param element the Element to append to the Schema node
706     */

707    public void writeSchemaElement(QName JavaDoc qName, Element JavaDoc element)
708            throws AxisFault
709    {
710       if (wsdlTypesElem == null)
711       {
712          try
713          {
714             writeWsdlTypesElement();
715          }
716          catch (Exception JavaDoc e)
717          {
718             log.error(e);
719             return;
720          }
721       }
722       String JavaDoc namespaceURI = qName.getNamespaceURI();
723       if (namespaceURI == null || namespaceURI.equals(""))
724       {
725          throw new AxisFault(Constants.FAULT_SERVER_GENERAL,
726                  Messages.getMessage("noNamespace00",
727                          qName.toString()),
728                  null, null);
729       }
730
731       Element JavaDoc schemaElem = null;
732       NodeList JavaDoc nl = wsdlTypesElem.getChildNodes();
733       for (int i = 0; i < nl.getLength(); i++)
734       {
735          NamedNodeMap JavaDoc attrs = nl.item(i).getAttributes();
736          if (attrs != null)
737          {
738             for (int n = 0; n < attrs.getLength(); n++)
739             {
740                Attr JavaDoc a = (Attr JavaDoc)attrs.item(n);
741                if (a.getName().equals("targetNamespace") &&
742                        a.getValue().equals(namespaceURI))
743                   schemaElem = (Element JavaDoc)nl.item(i);
744             }
745          }
746       }
747       if (schemaElem == null)
748       {
749          schemaElem = docHolder.createElement("schema");
750          wsdlTypesElem.appendChild(schemaElem);
751          schemaElem.setAttribute("xmlns", Constants.URI_DEFAULT_SCHEMA_XSD);
752          schemaElem.setAttribute("targetNamespace", namespaceURI);
753
754          // Add SOAP-ENC namespace import if necessary
755
if (serviceDesc.getStyle() == Style.RPC)
756          {
757             Element JavaDoc importElem = docHolder.createElement("import");
758             schemaElem.appendChild(importElem);
759             importElem.setAttribute("namespace", Constants.URI_DEFAULT_SOAP_ENC);
760          }
761
762          writeTypeNamespace(qName);
763       }
764       schemaElem.appendChild(element);
765    }
766
767    /**
768     * Get the Types element for the WSDL document. If not present, create one
769     */

770    private void writeWsdlTypesElement()
771    {
772       if (wsdlTypesElem == null)
773       {
774          // Create a <wsdl:types> element corresponding to the wsdl namespaces.
775
wsdlTypesElem =
776                  docHolder.createElementNS(Constants.NS_URI_WSDL11, "types");
777          wsdlTypesElem.setPrefix(Constants.NS_PREFIX_WSDL);
778       }
779    }
780
781    /**
782     * Write a schema representation for the given <code>Class</code>. Recurse
783     * through all the public fields as well as fields represented by java
784     * bean compliant accessor methods.
785     * <p/>
786     * Then return the qualified string representation of the generated type
787     *
788     * @param type Class for which to generate schema
789     * @return a prefixed string for the schema type
790     */

791    public String JavaDoc writeType(Class JavaDoc type) throws AxisFault
792    {
793       return writeType(type, null);
794    }
795
796    /**
797     * Write a schema representation for the given <code>Class</code>. Recurse
798     * through all the public fields as well as fields represented by java
799     * bean compliant accessor methods.
800     * <p/>
801     * Then return the qualified string representation of the generated type
802     *
803     * @param type Class for which to generate schema
804     * @param qName of the type to write
805     * @return a prefixed string for the schema type or null if problems occur
806     */

807    public String JavaDoc writeType(Class JavaDoc type, QName JavaDoc qName) throws AxisFault
808    {
809       // Get a corresponding QName if one is not provided
810
if (qName == null ||
811               Constants.equals(Constants.SOAP_ARRAY, qName))
812       {
813          qName = getTypeQName(type);
814       }
815
816       if (!makeTypeElement(type, qName, null))
817       {
818          return null;
819       }
820       return getQNameString(qName);
821    }
822
823    public Element JavaDoc createArrayElement(String JavaDoc componentTypeName)
824    {
825       // ComplexType representation of array
826
Element JavaDoc complexType = docHolder.createElement("complexType");
827
828       Element JavaDoc complexContent = docHolder.createElement("complexContent");
829       complexType.appendChild(complexContent);
830
831       Element JavaDoc restriction = docHolder.createElement("restriction");
832       complexContent.appendChild(restriction);
833       restriction.setAttribute("base",
834               Constants.NS_PREFIX_SOAP_ENC + ":Array");
835
836       Element JavaDoc attribute = docHolder.createElement("attribute");
837       restriction.appendChild(attribute);
838       attribute.setAttribute("ref",
839               Constants.NS_PREFIX_SOAP_ENC + ":arrayType");
840       attribute.setAttribute(Constants.NS_PREFIX_WSDL + ":arrayType",
841               componentTypeName);
842
843