Return-Path: Delivered-To: apmail-ws-axis-dev-archive@www.apache.org Received: (qmail 70445 invoked from network); 16 Jul 2004 14:04:34 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 16 Jul 2004 14:04:34 -0000 Received: (qmail 31368 invoked by uid 500); 16 Jul 2004 14:04:26 -0000 Delivered-To: apmail-ws-axis-dev-archive@ws.apache.org Received: (qmail 31309 invoked by uid 500); 16 Jul 2004 14:04:25 -0000 Mailing-List: contact axis-dev-help@ws.apache.org; run by ezmlm Precedence: bulk Reply-To: axis-dev@ws.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list axis-dev@ws.apache.org Received: (qmail 31296 invoked by uid 99); 16 Jul 2004 14:04:24 -0000 X-ASF-Spam-Status: No, hits=0.0 required=10.0 tests= X-Spam-Check-By: apache.org Received: from [12.130.29.202] (HELO eero.baz.org) (12.130.29.202) by apache.org (qpsmtpd/0.27.1) with ESMTP; Fri, 16 Jul 2004 07:04:21 -0700 Received: by eero.baz.org (Postfix, from userid 1017) id D4D7636C31; Fri, 16 Jul 2004 10:04:12 -0400 (EDT) Received: from AURORA (h00a0cc40bbaf.ne.client2.attbi.com [66.30.193.156]) by eero (tmda-ofmipd) with ESMTP; Fri, 16 Jul 2004 10:04:08 -0400 (EDT) Message-ID: <005701c46b3d$c133c8b0$7b00a8c0@AURORA> To: Cc: , References: Subject: Re: When is Axis 1.2 expected to be "final"? Date: Fri, 16 Jul 2004 10:04:04 -0400 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0054_01C46B1C.399BBAA0" X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2800.1409 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1409 From: Glen Daniels X-Delivery-Agent: TMDA/1.0.2 (Bold Forbes) X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N This is a multi-part message in MIME format. ------=_NextPart_000_0054_01C46B1C.399BBAA0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 8bit Hi Thomas: The problem here seems to be that although the WSDL says that there's going to be an array of "xsd:string", the actual wire message has an arrayType of "soapenc:string[]". This is because of the way Axis currently handles type mappings, which will be getting a full revamp for Axis 2.0. In particular: a type mapping for Axis consists of a pair [qname, javaType], which maps an xml type like "xsd:string" to a java type like "java.lang.String". The problem is that arrays are mapped like this: ["myNS:ArrayOfStrings", "java.lang.String[]"] - in other words, we can map the array type QName to a Java array class, but then when we want to know what the actual component type QName is, we do a lookup on the Java class (i.e. java.lang.String). Since this is an RPC/enc service, String maps to soapenc:string, not xsd:string, and hence the engine outputs what turns out to be the wrong arrayType. The way it SHOULD be working is that XML array types remember the type QName of their component, and always use that in order to be schema-valid. Then we get the Java type from the XML type rather than the other way around. Unfortunately, I can't fix this now, since it's a major change. I'm considering giving you a workaround by letting you specify a "NO_SOAPENC_TYPES" option, which won't map the soapenc types for a given service (or globally). But also.... dims, I just noticed the change you made on December 9th to org.apache.axis.wsdl.fromJava.Types. With this change, we ALWAYS emit the type mapping from the default type mapping registry if it exists, and NEVER the one from the service-specific type mapping - this seems very very bad. That means if a given service has remapped any of the default types, there will be an inconsistency between the generated WSDL and the actual runtime behavior.... This is part of the problem with Thomas' bug, since if the code were the old way you would see "soapenc:string" in the WSDL instead of "xsd:string". I'm putting this back the way it was, which may actually fix the .NET issue! If .NET was having a problem because the types didn't agree, and not because it doesn't support the soapenc types (this actually seems pretty likely to me, esp if it used to work), this should fix it. I'm attaching the updated Types.java file - Thomas, if you could try your test again with this one (making sure to use the newly generated WSDL), that would be great. Thanks, --Glen ----- Original Message ----- From: "Thomas B�rkel" To: ; Sent: Friday, July 16, 2004 9:12 AM Subject: RE: When is Axis 1.2 expected to be "final"? HI! I have tested again with .NET 1.1 plus WSE 2.0 and Axis 1.2 beta 2. Still the same. I have added a comment to the issue. My knowledge of Axis is too limited to provide a patch for that kind of problem. If you have Visual Studio.NET 2003, you can easily reproduce the problem. I cannot provide a ready-to-run complete test case, because I do not use Tomcat or any deployment at all. Thanks, Thomas > -----Original Message----- > From: Davanum Srinivas [mailto:davanum@gmail.com] > Sent: Donnerstag, 15. Juli 2004 15:13 > To: axis-dev@ws.apache.org > Subject: Re: When is Axis 1.2 expected to be "final"? > > > Thomas, > > If you can provide a patch that would be the BEST solution as i cannot > recreate the > problem....(http://nagoya.apache.org/wiki/apachewiki.cgi?AxisP > rojectPages/SubmitPatches) > > Thanks, > dims > > On Thu, 15 Jul 2004 07:47:05 +0200, Thomas B�rkel > wrote: > > HI! > > > > First, since Axis 1.1 RC2 works OK with .NET 1.1, Axis 1.2 > should also. > > > > Second, .NET 2.0 is far from release. You mean WSE 2.0. > I'll test Axis 1.2 Beta against that. > > > > And I did not say to hold up the beta, the question was > about the final. > > > > Thomas > > > > > > > > > > > -----Original Message----- > > > From: Davanum Srinivas [mailto:davanum@gmail.com] > > > Sent: Mittwoch, 14. Juli 2004 13:22 > > > To: axis-dev@ws.apache.org > > > Subject: Re: When is Axis 1.2 expected to be "final"? > > > > > > > > > Thomas, > > > > > > IF someone submits a test case that displays this problem > with latest > > > .NET 2.0 FINAL and Axis LATEST CVS, then am willing to hold up the > > > beta. Not otherwise. > > > > > > -- dims > > > > > > On Wed, 14 Jul 2004 10:07:48 +0200, Thomas B�rkel > > > wrote: > > > > HI! > > > > > > > > Sorry, but how can Axis 1.2 going to be released, if there > > > are severe interop problems with .NET? > > > > > > > > http://nagoya.apache.org/jira/browse/AXIS-1308 > > > > > > > > Thomas > > > > > > > > > > > > > -----Original Message----- > > > > > From: Tom Jordahl [mailto:tomj@macromedia.com] > > > > > Sent: Freitag, 9. Juli 2004 17:03 > > > > > To: 'axis-dev@ws.apache.org' > > > > > Subject: RE: When is Axis 1.2 expected to be "final"? > > > > > > > > > > > > > > > > > > > > Real soon now.... > > > > > > > > > > -- > > > > > Tom Jordahl > > > > > Macromedia Server Development > > > > > > > > > > -----Original Message----- > > > > > From: ricky_frost@peoplesoft.com > > > [mailto:ricky_frost@peoplesoft.com] > > > > > Sent: Thursday, July > > > 08, 2004 1:18 PM > > > > > To: axis-dev@ws.apache.org > > > > > Subject: When is Axis 1.2 expected to be "final"? > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > A project I'm looking at (ws-wsrp4j) just incorporated the > > > > > 1.2 beta and so > > > > > I would like to know. I asked on that list but they referred > > > > > me here... > > > > > > > > > > > > > > > > > > > > > > > -- > > > Davanum Srinivas - http://webservices.apache.org/~dims/ > > > > > > > > -- > Davanum Srinivas - http://webservices.apache.org/~dims/ > ------=_NextPart_000_0054_01C46B1C.399BBAA0 Content-Type: application/octet-stream; name="Types.java" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="Types.java" /* * Copyright 2001-2002,2004 The Apache Software Foundation. *=20 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *=20 * http://www.apache.org/licenses/LICENSE-2.0 *=20 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or = implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.axis.wsdl.fromJava; import org.apache.axis.AxisFault; import org.apache.axis.Constants; import org.apache.axis.InternalException; import org.apache.axis.MessageContext; import org.apache.axis.soap.SOAPConstants; import org.apache.axis.components.logger.LogFactory; import org.apache.axis.description.ServiceDesc; import org.apache.axis.encoding.Serializer; import org.apache.axis.encoding.SerializerFactory; import org.apache.axis.encoding.SimpleType; import org.apache.axis.encoding.TypeMapping; import org.apache.axis.encoding.ser.BeanSerializerFactory; import org.apache.axis.encoding.ser.EnumSerializerFactory; import org.apache.axis.enum.Style; import org.apache.axis.utils.JavaUtils; import org.apache.axis.utils.Messages; import org.apache.axis.utils.XMLUtils; import org.apache.axis.wsdl.symbolTable.BaseTypeMapping; import org.apache.axis.wsdl.symbolTable.SymbolTable; import org.apache.axis.wsdl.symbolTable.TypeEntry; import org.apache.commons.logging.Log; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import javax.wsdl.Definition; import javax.wsdl.WSDLException; import javax.xml.namespace.QName; import javax.xml.parsers.ParserConfigurationException; import javax.xml.rpc.holders.Holder; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; /** *

Description:

This class is used to recursively serializes a = Java Class into * an XML Schema representation. *

* It has utility methods to create a schema node, assosiate namespaces = to the various types * * @author unascribed */ public class Types { /** Field log */ protected static Log log =3D = LogFactory.getLog(Types.class.getName()); /** Field def */ Definition def; /** Field namespaces */ Namespaces namespaces =3D null; /** Field tm */ TypeMapping tm; /** Field defaultTM */ TypeMapping defaultTM; /** Field targetNamespace */ String targetNamespace; /** Field wsdlTypesElem */ Element wsdlTypesElem =3D null; /** Field schemaTypes */ HashMap schemaTypes =3D null; /** Field schemaElementNames */ HashMap schemaElementNames =3D null; /** Field schemaUniqueElementNames */ HashMap schemaUniqueElementNames =3D null; /** Field wrapperMap */ HashMap wrapperMap =3D new HashMap(); /** Field stopClasses */ List stopClasses =3D null; /** Field beanCompatErrs */ List beanCompatErrs =3D new ArrayList(); /** Field serviceDesc */ private ServiceDesc serviceDesc =3D null; /** Keep track of the element QNames we've written to avoid dups */ private Set writtenElementQNames =3D new HashSet(); =20 /** Which types have we already written? */ Class [] mappedTypes =3D null; public static boolean isArray(Class clazz) { return clazz.isArray() || = java.util.Collection.class.isAssignableFrom(clazz); } private static Class getComponentType(Class clazz) { if (clazz.isArray()) { return clazz.getComponentType(); } else if (java.util.Collection.class.isAssignableFrom(clazz)) { return Object.class; } else { return null; } } /** * This class serailizes a Class to XML Schema. The = constructor * provides the context for the streamed node within the WSDL = document * * @param def WSDL Definition Element to declare = namespaces * @param tm TypeMappingRegistry to handle known types * @param defaultTM default TM * @param namespaces user defined or autogenerated namespace = and prefix maps * @param targetNamespace targetNamespace of the document * @param stopClasses * @param serviceDesc */ public Types(Definition def, TypeMapping tm, TypeMapping defaultTM, Namespaces namespaces, String targetNamespace, List stopClasses, ServiceDesc serviceDesc) { this.def =3D def; this.serviceDesc =3D serviceDesc; createDocumentFragment(); this.tm =3D tm; this.defaultTM =3D defaultTM; =20 mappedTypes =3D tm.getAllClasses(); =20 this.namespaces =3D namespaces; this.targetNamespace =3D targetNamespace; this.stopClasses =3D stopClasses; schemaElementNames =3D new HashMap(); schemaUniqueElementNames =3D new HashMap(); schemaTypes =3D new HashMap(); } /** * Return the namespaces object for the current context * * @return */ public Namespaces getNamespaces() { return namespaces; } /** * Loads the types from the input schema file. * * @param inputSchema file or URL * @throws IOException * @throws WSDLException * @throws SAXException * @throws ParserConfigurationException */ public void loadInputSchema(String inputSchema) throws IOException, WSDLException, SAXException, ParserConfigurationException { // Read the input wsdl file into a Document Document doc =3D XMLUtils.newDocument(inputSchema); // Ensure that the root element is xsd:schema Element root =3D doc.getDocumentElement(); if (root.getLocalName().equals("schema") && Constants.isSchemaXSD(root.getNamespaceURI())) { Node schema =3D docHolder.importNode(root, true); if (null =3D=3D wsdlTypesElem) { writeWsdlTypesElement(); } wsdlTypesElem.appendChild(schema); // Create a symbol table and populate it with the input = types BaseTypeMapping btm =3D new BaseTypeMapping() { public String getBaseName(QName qNameIn) { QName qName =3D new QName(qNameIn.getNamespaceURI(), qNameIn.getLocalPart()); Class cls =3D defaultTM.getClassForQName(qName); if (cls =3D=3D null) { return null; } else { return = JavaUtils.getTextClassName(cls.getName()); } } }; SymbolTable symbolTable =3D new SymbolTable(btm, true, = false, false); symbolTable.populateTypes(new URL(inputSchema), doc); processSymTabEntries(symbolTable); } else { // If not, we'll just bail out... perhaps we should log a = warning // or throw an exception? ; } } /** * Walk the type/element entries in the symbol table and * add each one to the list of processed types. This prevents * the types from being duplicated. * * @param symbolTable */ private void processSymTabEntries(SymbolTable symbolTable) { Iterator iterator =3D = symbolTable.getElementIndex().entrySet().iterator(); while (iterator.hasNext()) { Map.Entry me =3D (Map.Entry) iterator.next(); QName name =3D (QName) me.getKey(); TypeEntry te =3D (TypeEntry) me.getValue(); String prefix =3D XMLUtils.getPrefix(name.getNamespaceURI(), te.getNode()); if (!((null =3D=3D prefix) || "".equals(prefix))) { namespaces.putPrefix(name.getNamespaceURI(), prefix); def.addNamespace(prefix, name.getNamespaceURI()); } addToElementsList(name); } iterator =3D symbolTable.getTypeIndex().entrySet().iterator(); while (iterator.hasNext()) { Map.Entry me =3D (Map.Entry) iterator.next(); QName name =3D (QName) me.getKey(); TypeEntry te =3D (TypeEntry) me.getValue(); String prefix =3D XMLUtils.getPrefix(name.getNamespaceURI(), te.getNode()); if (!((null =3D=3D prefix) || "".equals(prefix))) { namespaces.putPrefix(name.getNamespaceURI(), prefix); def.addNamespace(prefix, name.getNamespaceURI()); } addToTypesList(name); } } /** * Load the types from the input wsdl file. * * @param inputWSDL file or URL * @throws IOException * @throws WSDLException * @throws SAXException * @throws ParserConfigurationException */ public void loadInputTypes(String inputWSDL) throws IOException, WSDLException, SAXException, ParserConfigurationException { // Read the input wsdl file into a Document Document doc =3D XMLUtils.newDocument(inputWSDL); // Search for the 'types' element NodeList elements =3D doc.getChildNodes(); if ((elements.getLength() > 0) && = elements.item(0).getLocalName().equals("definitions")) { elements =3D elements.item(0).getChildNodes(); for (int i =3D 0; (i < elements.getLength()) && (wsdlTypesElem =3D=3D = null); i++) { Node node =3D elements.item(i); if ((node.getLocalName() !=3D null) && node.getLocalName().equals("types")) { wsdlTypesElem =3D (Element) node; } } } // If types element not found, there is no need to continue. if (wsdlTypesElem =3D=3D null) { return; } // Import the types element into the Types docHolder document wsdlTypesElem =3D (Element) docHolder.importNode(wsdlTypesElem, = true); docHolder.appendChild(wsdlTypesElem); // Create a symbol table and populate it with the input wsdl = document BaseTypeMapping btm =3D new BaseTypeMapping() { public String getBaseName(QName qNameIn) { QName qName =3D new QName(qNameIn.getNamespaceURI(), qNameIn.getLocalPart()); Class cls =3D defaultTM.getClassForQName(qName); if (cls =3D=3D null) { return null; } else { return JavaUtils.getTextClassName(cls.getName()); } } }; SymbolTable symbolTable =3D new SymbolTable(btm, true, false, = false); symbolTable.populate(null, doc); processSymTabEntries(symbolTable); } /** * Write out a type referenced by a part type attribute. * * @param type Class to generate the XML Schema info = for * @param qname QName of the type. If null, qname is * defaulted from the class. * @return the QName of the generated Schema type, null if void, * if the Class type cannot be converted to a schema type * then xsd:anytype is returned. * @throws AxisFault */ public QName writeTypeForPart(Class type, QName qname) throws = AxisFault { // patch by costin to fix an NPE; commented out till we find out = what the problem is // if you get NullPointerExceptions in this class, turn it on = and submit some // replicable test data to the Axis team via bugzilla /* * if( type=3D=3Dnull ) { * return null; * } */ if (type.getName().equals("void")) { return null; } =20 if (Holder.class.isAssignableFrom(type)) { type =3D JavaUtils.getHolderValueType(type); } // Get the qname if ((qname =3D=3D null) || (Constants.isSOAP_ENC(qname.getNamespaceURI()) && "Array".equals(qname.getLocalPart()))) { qname =3D getTypeQName(type); if (qname =3D=3D null) { throw new AxisFault("Class:" + type.getName()); } } if (!makeTypeElement(type, qname, null)) { qname =3D Constants.XSD_ANYTYPE; } return qname; } =20 /** * Write out a type (and its subtypes) referenced by a part type = attribute. * * @param type Class to generate the XML Schema info = for * @param qname QName of the type. If null, qname is * defaulted from the class. * @return the QName of the generated Schema type, null if void, * if the Class type cannot be converted to a schema type * then xsd:anytype is returned. */ public QName writeTypeAndSubTypeForPart(Class type, QName qname) throws AxisFault { =20 // Write out type in parameter QName qNameRet =3D writeTypeForPart(type, qname); =20 // If mappedTypesexists=20 // Will write subTypes of the type in parameters if (mappedTypes !=3D null) { for (int i =3D 0; i < mappedTypes.length; i++) { Class tempMappedType =3D mappedTypes[i]; QName name; =20 // If tempMappedType is subtype of the "type" parameter // and type is not Object (Object superclass of all Java = class...) =20 // write the subtype if (tempMappedType !=3D null && type !=3D Object.class &&=20 tempMappedType !=3D type && type.isAssignableFrom(tempMappedType)) { name =3D tm.getTypeQName(tempMappedType); if (!isAnonymousType(name)) { writeTypeForPart(tempMappedType, name); } =20 // Only do each one once. This is OK to do because = each // Types instance is for generating a single WSDL. mappedTypes[i] =3D null; } } } //if (mappedTyped !=3D null) { =20 return qNameRet; =20 } =20 /** * Write out an element referenced by a part element attribute. * * @param type Class to generate the XML Schema info = for * @param qname QName of the element. If null, qname = is * defaulted from the class. * @return the QName of the generated Schema type, null if no = element * @throws AxisFault */ public QName writeElementForPart(Class type, QName qname) throws = AxisFault { // patch by costin to fix an NPE; commented out till we find out = what the problem is // if you get NullPointerExceptions in this class, turn it on = and submit some // replicable test data to the Axis team via bugzilla /* * if( type=3D=3Dnull ) { * return null; * } */ if (type.getName().equals("void")) { return null; } if (Holder.class.isAssignableFrom(type)) { type =3D JavaUtils.getHolderValueType(type); } // Get the qname if ((qname =3D=3D null) || (Constants.isSOAP_ENC(qname.getNamespaceURI()) && "Array".equals(qname.getLocalPart()))) { qname =3D getTypeQName(type); if (qname =3D=3D null) { throw new AxisFault("Class:" + type.getName()); } } // Return null it a simple type (not an element) String nsURI =3D qname.getNamespaceURI(); if (Constants.isSchemaXSD(nsURI) || (Constants.isSOAP_ENC(nsURI) && !"Array".equals(qname.getLocalPart()))) { return null; } // Make sure a types section is present if (wsdlTypesElem =3D=3D null) { writeWsdlTypesElement(); } // Write Element, if problems occur return null. if (writeTypeAsElement(type, qname) =3D=3D null) { qname =3D null; } return qname; } /** * Write the element definition for a WRAPPED operation. This will * write out any necessary namespace/schema declarations, an an = element * definition with an internal (anonymous) complexType. The name of = the * element will be *foo*Request or *foo*Response depending on = whether the * request boolean is true. If the operation contains parameters, = then * we also generate a >sequence< node underneath the = complexType, * and return it for later use by writeWrappedParameter() below. * * @param qname the desired element QName * @param request true if we're writing the request wrapper, false = if * writing the response. * @param hasParams true if there are parameters, and thus a = sequence * node is needed * @return a DOM Element for the sequence, inside which we'll write = the * parameters as elements, or null if there are no = parameters * @throws AxisFault */ public Element writeWrapperElement( QName qname, boolean request, boolean hasParams) throws = AxisFault { // Make sure a types section is present if (wsdlTypesElem =3D=3D null) { writeWsdlTypesElement(); } // Write the namespace definition for the wrapper writeTypeNamespace(qname.getNamespaceURI()); // Create an for the wrapper Element wrapperElement =3D docHolder.createElement("element"); writeSchemaElementDecl(qname, wrapperElement); wrapperElement.setAttribute("name", qname.getLocalPart()); // Create an anonymous for the wrapper Element complexType =3D docHolder.createElement("complexType"); wrapperElement.appendChild(complexType); // If we have parameters in the operation, create a // under the complexType and return it. if (hasParams) { Element sequence =3D docHolder.createElement("sequence"); complexType.appendChild(sequence); return sequence; } return null; } /** * Write a parameter (a sub-element) into a sequence generated by * writeWrapperElement() above. * * @param sequence the <sequence> in which we're writing * @param name is the name of an element to add to the wrapper = element. * @param type is the QName of the type of the element. * @param javaType * @throws AxisFault */ public void writeWrappedParameter( Element sequence, String name, QName type, Class javaType) throws AxisFault { if (javaType =3D=3D void.class) { return; } if (javaType.isArray()) { type =3D writeTypeForPart(javaType.getComponentType(), = null); } else { type =3D writeTypeForPart(javaType, type); } if (type =3D=3D null) { // throw an Exception!! } Element childElem; if (isAnonymousType(type)) { childElem =3D createElementWithAnonymousType(name, javaType, = false, docHolder); } else { // Create the child and add it to the wrapper = childElem =3D docHolder.createElement("element"); childElem.setAttribute("name", name); String prefix =3D namespaces.getCreatePrefix(type.getNamespaceURI()); String prefixedName =3D prefix + ":" + type.getLocalPart(); childElem.setAttribute("type", prefixedName); if (javaType.isArray()) { childElem.setAttribute("maxOccurs", "unbounded"); } } sequence.appendChild(childElem); } /** * Method isAnonymousType * * @param type * @return */ private boolean isAnonymousType(QName type) { return type.getLocalPart().indexOf(SymbolTable.ANON_TOKEN) !=3D = -1; } /** * Create a schema element for the given type * * @param type the class type * @param qName * @return the QName of the generated Element or problems occur * @throws AxisFault */ private QName writeTypeAsElement(Class type, QName qName) throws = AxisFault { if ((qName =3D=3D null) || = Constants.equals(Constants.SOAP_ARRAY, qName)) { qName =3D getTypeQName(type); } writeTypeNamespace(type, qName); String elementType =3D writeType(type, qName); if (elementType !=3D null) { // Element element =3D = createElementDecl(qName.getLocalPart(), type, qName, isNullable(type), = false); // if (element !=3D null) // writeSchemaElement(typeQName,element); return qName; } return null; } /** * write out the namespace declaration and return the type QName for = the * given Class * * @param type input Class * @param qName qname of the Class * @return QName for the schema type representing the class */ private QName writeTypeNamespace(Class type, QName qName) { if (qName =3D=3D null) { qName =3D getTypeQName(type); } writeTypeNamespace(qName.getNamespaceURI()); return qName; } /** * write out the namespace declaration. * * @param namespaceURI qname of the type */ private void writeTypeNamespace(String namespaceURI) { if ((namespaceURI !=3D null) && !namespaceURI.equals("")) { String pref =3D def.getPrefix(namespaceURI); if (pref =3D=3D null) { = def.addNamespace(namespaces.getCreatePrefix(namespaceURI), namespaceURI); } } } /** * Return the QName of the specified javaType * * @param javaType input javaType Class * @return QName */ public QName getTypeQName(Class javaType) { QName qName =3D null; // Use the typeMapping information to lookup the qName. QName dQName =3D null; if (defaultTM !=3D null) { dQName =3D defaultTM.getTypeQName(javaType); } if (tm !=3D null) { qName =3D tm.getTypeQName(javaType); } if (qName =3D=3D null) { qName =3D dQName; } else if ((qName !=3D null) && (qName !=3D dQName)) { // If the TM and default TM resulted in different // names, choose qName unless it is a schema namespace. // (i.e. prefer soapenc primitives over schema primitives) if (Constants.isSchemaXSD(qName.getNamespaceURI())) { qName =3D dQName; } } // If the javaType is an array and the qName is // SOAP_ARRAY, construct the QName using the // QName of the component type if (isArray(javaType) &&=20 Constants.equals(Constants.SOAP_ARRAY, qName)) { Class componentType =3D getComponentType(javaType); // If component namespace uri =3D=3D targetNamespace // Construct ArrayOf // Else // Construct ArrayOf__ QName cqName =3D getTypeQName(componentType); if (targetNamespace.equals(cqName.getNamespaceURI())) { qName =3D new QName(targetNamespace, "ArrayOf" + cqName.getLocalPart()); } else { String pre =3D = namespaces.getCreatePrefix(cqName.getNamespaceURI()); qName =3D new QName(targetNamespace, "ArrayOf_" + pre + "_" + cqName.getLocalPart()); } return qName; } // If a qName was not found construct one using the // class name information. if (qName =3D=3D null) { String pkg =3D = getPackageNameFromFullName(javaType.getName()); String lcl =3D getLocalNameFromFullName(javaType.getName()); String ns =3D namespaces.getCreate(pkg); namespaces.getCreatePrefix(ns); String localPart =3D lcl.replace('$', '_'); qName =3D new QName(ns, localPart); } return qName; } /** * Return a string suitable for representing a given QName in the = context * of this WSDL document. If the namespace of the QName is not yet * registered, we will register it up in the Definitions. * * @param qname a QName (typically a type) * @return a String containing a standard "ns:localPart" rep of the = QName */ public String getQNameString(QName qname) { String prefix =3D = namespaces.getCreatePrefix(qname.getNamespaceURI()); return prefix + ":" + qname.getLocalPart(); } /** * Utility method to get the package name from a fully qualified = java class name * * @param full input class name * @return package name */ public static String getPackageNameFromFullName(String full) { if (full.lastIndexOf('.') < 0) { return ""; } else { return full.substring(0, full.lastIndexOf('.')); } } /** * Utility method to get the local class name from a fully qualified = java class name * * @param full input class name * @return package name */ public static String getLocalNameFromFullName(String full) { String end =3D ""; if (full.startsWith("[L")) { end =3D "[]"; full =3D full.substring(3, full.length() - 1); } if (full.lastIndexOf('.') < 0) { return full + end; } else { return full.substring(full.lastIndexOf('.') + 1) + end; } } /** * Method writeSchemaTypeDecl * * @param qname * @param element * @throws AxisFault */ public void writeSchemaTypeDecl(QName qname, Element element) throws AxisFault { writeSchemaElement(qname.getNamespaceURI(), element); } /** * Method writeSchemaElementDecl * * @param qname * @param element * @throws AxisFault */ public void writeSchemaElementDecl(QName qname, Element element) throws AxisFault { if (writtenElementQNames.contains(qname)) { throw new AxisFault( Constants.FAULT_SERVER_GENERAL, Messages.getMessage( "duplicateSchemaElement", qname.toString()), = null, null); } writeSchemaElement(qname.getNamespaceURI(), element); writtenElementQNames.add(qname); } /** * @deprecated * Please use writeSchemaElement(String namespaceURI, Element = element)=20 * * @param qName qName to get the namespace of the schema node * @param element the Element to append to the Schema node * @throws AxisFault */ public void writeSchemaElement(QName qName, Element element) throws AxisFault { writeSchemaElement(qName.getNamespaceURI(), element); } /** * Write out the given Element into the appropriate schema node. * If need be create the schema node as well * * @param namespaceURI namespace this node should get dropped into * @param element the Element to append to the Schema node * @throws AxisFault */ public void writeSchemaElement(String namespaceURI, Element element) throws AxisFault { if (wsdlTypesElem =3D=3D null) { try { writeWsdlTypesElement(); } catch (Exception e) { log.error(e); return; } } if ((namespaceURI =3D=3D null) || namespaceURI.equals("")) { throw new AxisFault( Constants.FAULT_SERVER_GENERAL, Messages.getMessage("noNamespace00", namespaceURI), = null, null); } Element schemaElem =3D null; NodeList nl =3D wsdlTypesElem.getChildNodes(); for (int i =3D 0; i < nl.getLength(); i++) { NamedNodeMap attrs =3D nl.item(i).getAttributes(); if (attrs !=3D null) { for (int n =3D 0; n < attrs.getLength(); n++) { Attr a =3D (Attr) attrs.item(n); if (a.getName().equals("targetNamespace") && a.getValue().equals(namespaceURI)) { schemaElem =3D (Element) nl.item(i); } } } } if (schemaElem =3D=3D null) { schemaElem =3D docHolder.createElement("schema"); wsdlTypesElem.appendChild(schemaElem); schemaElem.setAttribute("xmlns", = Constants.URI_DEFAULT_SCHEMA_XSD); schemaElem.setAttribute("targetNamespace", namespaceURI); // Add SOAP-ENC namespace import if necessary if (serviceDesc.getStyle() =3D=3D Style.RPC) { Element importElem =3D = docHolder.createElement("import"); schemaElem.appendChild(importElem); importElem.setAttribute("namespace", Constants.URI_DEFAULT_SOAP_ENC); } if ((serviceDesc.getStyle() =3D=3D Style.DOCUMENT) || (serviceDesc.getStyle() =3D=3D Style.WRAPPED)) { schemaElem.setAttribute("elementFormDefault", = "qualified"); } writeTypeNamespace(namespaceURI); } schemaElem.appendChild(element); } /** * Get the Types element for the WSDL document. If not present, = create one */ private void writeWsdlTypesElement() { if (wsdlTypesElem =3D=3D null) { // Create a element corresponding to the wsdl = namespaces. wsdlTypesElem =3D = docHolder.createElementNS(Constants.NS_URI_WSDL11, "types"); wsdlTypesElem.setPrefix(Constants.NS_PREFIX_WSDL); } } /** * Write a schema representation for the given Class. = Recurse * through all the public fields as well as fields represented by = java * bean compliant accessor methods. *

* Then return the qualified string representation of the generated = type * * @param type Class for which to generate schema * @return a prefixed string for the schema type * @throws AxisFault */ public String writeType(Class type) throws AxisFault { return writeType(type, null); } /** * Write a schema representation for the given Class. = Recurse * through all the public fields as well as fields represented by = java * bean compliant accessor methods. *

* Then return the qualified string representation of the generated = type * * @param type Class for which to generate schema * @param qName of the type to write * @return a prefixed string for the schema type or null if problems = occur * @throws AxisFault */ public String writeType(Class type, QName qName) throws AxisFault { // Get a corresponding QName if one is not provided if ((qName =3D=3D null) || = Constants.equals(Constants.SOAP_ARRAY, qName)) { qName =3D getTypeQName(type); } if (!makeTypeElement(type, qName, null)) { return null; } return getQNameString(qName); } /** * Method createArrayElement * * @param componentTypeName * @return */ public Element createArrayElement(String componentTypeName) { SOAPConstants constants =3D null; MessageContext mc =3D MessageContext.getCurrentContext(); if(mc=3D=3Dnull||mc.getSOAPConstants()=3D=3Dnull){ constants =3D SOAPConstants.SOAP11_CONSTANTS; =20 } else { constants =3D mc.getSOAPConstants(); } String prefix =3D = namespaces.getCreatePrefix(constants.getEncodingURI()); // ComplexType representation of array Element complexType =3D docHolder.createElement("complexType"); Element complexContent =3D = docHolder.createElement("complexContent"); complexType.appendChild(complexContent); Element restriction =3D docHolder.createElement("restriction"); complexContent.appendChild(restriction); restriction.setAttribute("base", prefix + ":Array"); Element attribute =3D docHolder.createElement("attribute"); restriction.appendChild(attribute); =20 attribute.setAttribute("ref", prefix + ":arrayType"); prefix =3D namespaces.getCreatePrefix(Constants.NS_URI_WSDL11); attribute.setAttribute(prefix + ":arrayType", componentTypeName); return complexType; } /** * Create an array which is a wrapper type for "item" elements * of a component type. This is basically the unencoded parallel to * a SOAP-encoded array. * * @param componentType * @param itemName * @return */ public Element createLiteralArrayElement(String componentType, QName itemName) { Element complexType =3D docHolder.createElement("complexType"); Element sequence =3D docHolder.createElement("sequence"); complexType.appendChild(sequence); Element elem =3D docHolder.createElement("element"); elem.setAttribute("name", "item"); elem.setAttribute("type", componentType); elem.setAttribute("minOccurs", "0"); elem.setAttribute("maxOccurs", "unbounded"); sequence.appendChild(elem); return complexType; } /** * Returns true if indicated type matches the JAX-RPC enumeration = class. * Note: supports JSR 101 version 0.6 Public Draft * * @param cls * @return */ public static boolean isEnumClass(Class cls) { try { java.lang.reflect.Method m =3D cls.getMethod("getValue", = null); java.lang.reflect.Method m2 =3D cls.getMethod("toString", = null); if ((m !=3D null) && (m2 !=3D null)) { java.lang.reflect.Method m3 =3D cls.getDeclaredMethod("fromString", new Class[]{ java.lang.String.class}); java.lang.reflect.Method m4 =3D = cls.getDeclaredMethod("fromValue", new Class[]{ m.getReturnType()}); if ((m3 !=3D null) && = Modifier.isStatic(m3.getModifiers()) && Modifier.isPublic(m3.getModifiers()) && (m4 = !=3D null) && Modifier.isStatic(m4.getModifiers()) && Modifier.isPublic(m4.getModifiers())) { // Return false if there is a setValue member method try { if (cls.getMethod("setValue", new Class[]{ m.getReturnType()}) =3D=3D null) { return true; } return false; } catch (java.lang.NoSuchMethodException e) { return true; } } } } catch (java.lang.NoSuchMethodException e) { } return false; } /** * Write Enumeration Complex Type * (Only supports enumeration classes of string types) * * @param qName QName of type. * @param cls class of type * @return * @throws NoSuchMethodException * @throws IllegalAccessException * @throws AxisFault */ public Element writeEnumType(QName qName, Class cls) throws NoSuchMethodException, IllegalAccessException, = AxisFault { if (!isEnumClass(cls)) { return null; } // Get the base type of the enum class java.lang.reflect.Method m =3D cls.getMethod("getValue", null); Class base =3D m.getReturnType(); // Create simpleType, restriction elements Element simpleType =3D docHolder.createElement("simpleType"); simpleType.setAttribute("name", qName.getLocalPart()); Element restriction =3D docHolder.createElement("restriction"); simpleType.appendChild(restriction); String baseType =3D writeType(base, null); restriction.setAttribute("base", baseType); // Create an enumeration using the field values Field[] fields =3D cls.getDeclaredFields(); for (int i =3D 0; i < fields.length; i++) { Field field =3D fields[i]; int mod =3D field.getModifiers(); // Inspect each public static final field of the same type // as the base if (Modifier.isPublic(mod) && Modifier.isStatic(mod) && Modifier.isFinal(mod) && (field.getType() =3D=3D = base)) { // Create an enumeration using the value specified Element enumeration =3D = docHolder.createElement("enumeration"); enumeration.setAttribute("value", = field.get(null).toString()); restriction.appendChild(enumeration); } } return simpleType; } /** * Create Element * * @param qname * @param javaType * @param typeQName * @param nillable nillable attribute of the element * @param omittable * @throws AxisFault */ public void writeElementDecl(QName qname, Class javaType, QName typeQName, boolean nillable, boolean omittable) throws AxisFault { if (writtenElementQNames.contains(qname)) { return; } String name =3D qname.getLocalPart(); Element element =3D docHolder.createElement("element"); // Generate an element name that matches the type. element.setAttribute("name", name); if (nillable) { element.setAttribute("nillable", "true"); } if (omittable) { element.setAttribute("minOccurs", "0"); element.setAttribute("maxOccurs", "1"); } // Write the type for this element, handling anonymous or named // types appropriately. makeTypeElement(javaType, typeQName, element); writeSchemaElementDecl(qname, element); } /** * Create Element with a given name and type * * @param elementName the name of the created element * @param elementType schema type representation of the element * @param nullable nullable attribute of the element * @param omittable * @param docHolder * @return the created Element */ public Element createElement(String elementName, String elementType, boolean nullable, boolean omittable, Document docHolder) { Element element =3D docHolder.createElement("element"); element.setAttribute("name", elementName); if (nullable) { element.setAttribute("nillable", "true"); } if (omittable) { element.setAttribute("minOccurs", "0"); element.setAttribute("maxOccurs", "1"); } if (elementType !=3D null) { element.setAttribute("type", elementType); } return element; } /** * Create Attribute Element with a given name and type * * @param elementName the name of the created element * @param javaType * @param xmlType * @param nullable nullable attribute of the element * @param docHolder * @return the created Element * @throws AxisFault */ public Element createAttributeElement( String elementName, Class javaType, QName xmlType, boolean = nullable, Document docHolder) throws AxisFault { Element element =3D docHolder.createElement("attribute"); element.setAttribute("name", elementName); if (nullable) { element.setAttribute("nillable", "true"); } makeTypeElement(javaType, xmlType, element); return element; } /** * Is the given class one of the simple types? In other words, * do we have a mapping for this type which is in the xsd or * soap-enc namespaces? * * @param type input Class * @return true if the type is a simple type */ boolean isSimpleType(Class type) { QName qname =3D tm.getTypeQName(type); if (qname =3D=3D null) { return false; // No mapping } String nsURI =3D qname.getNamespaceURI(); return (Constants.isSchemaXSD(nsURI) || = Constants.isSOAP_ENC(nsURI)); } /** * Is the given class acceptable as an attribute * * @param type input Class * @return true if the type is a simple, enum type or extends = SimpleType */ public boolean isAcceptableAsAttribute(Class type) { return isSimpleType(type) || isEnumClass(type) || implementsSimpleType(type); } /** * Does the class implement SimpleType * * @param type input Class * @return true if the type implements SimpleType */ boolean implementsSimpleType(Class type) { Class[] impls =3D type.getInterfaces(); for (int i =3D 0; i < impls.length; i++) { if (impls[i] =3D=3D SimpleType.class) { return true; } } return false; } /** * Generates a unique element name for a given namespace of the form * el0, el1 .... * * @param qName the namespace for the generated element * @return elementname */ // *** NOT USED? *** // // private String generateUniqueElementName(QName qName) { // Integer count =3D = (Integer)schemaUniqueElementNames.get(qName.getNamespaceURI()); // if (count =3D=3D null) // count =3D new Integer(0); // else // count =3D new Integer(count.intValue() + 1); // schemaUniqueElementNames.put(qName.getNamespaceURI(), count); // return "el" + count.intValue(); // } /** * Add the type to an ArrayList and return true if the Schema node * needs to be generated * If the type already exists, just return false to indicate that = the type is already * generated in a previous iteration * * @param qName of the type. * @return if the type is added returns true, * else if the type is already present returns false */ private boolean addToTypesList(QName qName) { boolean added =3D false; String namespaceURI =3D qName.getNamespaceURI(); ArrayList types =3D (ArrayList) schemaTypes.get(namespaceURI); // Quick return if schema type (will never add these ourselves) if (Constants.isSchemaXSD(namespaceURI) || (Constants.isSOAP_ENC(namespaceURI) && !"Array".equals(qName.getLocalPart()))) { // Make sure we do have the namespace declared, though... writeTypeNamespace(namespaceURI); return false; } if (types =3D=3D null) { types =3D new ArrayList(); types.add(qName.getLocalPart()); writeTypeNamespace(namespaceURI); schemaTypes.put(namespaceURI, types); added =3D true; } else { if (!types.contains(qName.getLocalPart())) { types.add(qName.getLocalPart()); added =3D true; } } // If addded, look at the namespace uri to see if the schema = element should be // generated. if (added) { String prefix =3D namespaces.getCreatePrefix(namespaceURI); if (prefix.equals(Constants.NS_PREFIX_SOAP_ENV) || prefix.equals(Constants.NS_PREFIX_SOAP_ENC) || prefix.equals(Constants.NS_PREFIX_SCHEMA_XSD) || prefix.equals(Constants.NS_PREFIX_WSDL) || prefix.equals(Constants.NS_PREFIX_WSDL_SOAP)) { return false; } else { return true; } } return false; } /** * Add the element to an ArrayList and return true if the Schema = element * needs to be generated * If the element already exists, just return false to indicate that = the type is already * generated in a previous iteration * * @param qName the name space of the element * @return if the type is added returns true, else if the type is = already present returns false */ private boolean addToElementsList(QName qName) { if (qName =3D=3D null) { return false; } boolean added =3D false; ArrayList elements =3D (ArrayList) = schemaElementNames.get(qName.getNamespaceURI()); if (elements =3D=3D null) { elements =3D new ArrayList(); elements.add(qName.getLocalPart()); schemaElementNames.put(qName.getNamespaceURI(), elements); added =3D true; } else { if (!elements.contains(qName.getLocalPart())) { elements.add(qName.getLocalPart()); added =3D true; } } return added; } /** * Determines if the field is nullable. All non-primitives except * for byte[] are nillable. * * @param type input Class * @return true if nullable */ public boolean isNullable(Class type) { if (type.isPrimitive() || (type.isArray() && (type.getComponentType() =3D=3D byte.class))) { return false; } else { return true; } } /** * todo ravi: Get rid of Doccument fragment and import node stuuf, * once I have a handle on the wsdl4j mechanism to get at types. *

* Switch over notes: remove docHolder, docFragment in favor of = wsdl4j Types *

* DocumentFragment docFragment; *

* DocumentFragment docFragment; *

* DocumentFragment docFragment; *

* DocumentFragment docFragment; */ // DocumentFragment docFragment; Document docHolder; /** * Method createDocumentFragment */ private void createDocumentFragment() { try { this.docHolder =3D XMLUtils.newDocument(); } catch (ParserConfigurationException e) { // This should not occur throw new InternalException(e); } } /** * Method updateNamespaces */ public void updateNamespaces() { Namespaces namespaces =3D getNamespaces(); Iterator nspIterator =3D namespaces.getNamespaces(); while (nspIterator.hasNext()) { String nsp =3D (String) nspIterator.next(); String pref =3D def.getPrefix(nsp); if (pref =3D=3D null) { def.addNamespace(namespaces.getCreatePrefix(nsp), nsp); } } } /** * Inserts the type fragment into the given wsdl document and = ensures * that definitions from each embedded schema are allowed to = reference * schema components from the other sibling schemas. * @param doc */ public void insertTypesFragment(Document doc) { updateNamespaces(); if (wsdlTypesElem =3D=3D null)=20 return; // Make sure that definitions from each embedded schema are = allowed // to reference schema components from the other sibling = schemas. Element schemaElem =3D null; String tns =3D null; NodeList nl =3D wsdlTypesElem.getChildNodes(); for (int i =3D 0; i < nl.getLength(); i++) { NamedNodeMap attrs =3D nl.item(i).getAttributes(); if (attrs =3D=3D null) continue; // Should never happen. for (int n =3D 0; n < attrs.getLength(); n++) { Attr a =3D (Attr) attrs.item(n); if (a.getName().equals("targetNamespace")) { tns =3D a.getValue(); schemaElem =3D (Element) nl.item(i); break; } } // Ignore what appears to be a not namespace-qualified // schema definition. if (tns !=3D null && !"".equals(tns.trim())) { // By now we know that an import element might be = necessary // for some sibling schemas. However, in the absence of // a symbol table proper, the best we can do is add one // for each sibling schema. Iterator it =3D schemaTypes.keySet().iterator(); String otherTns; Element importElem; while (it.hasNext()) { if (!tns.equals(otherTns =3D (String) it.next())) { importElem =3D = docHolder.createElement("import"); importElem.setAttribute("namespace", otherTns); schemaElem.insertBefore(importElem, schemaElem.getFirstChild()); } } } schemaElem =3D null; tns =3D null; } =20 // Import the wsdlTypesElement into the doc. org.w3c.dom.Node node =3D doc.importNode(wsdlTypesElem, true); // Insert the imported element at the beginning of the document doc.getDocumentElement(). insertBefore(node, doc.getDocumentElement().getFirstChild()); } =20 /** * Return the list of classes that we should not emit WSDL for. * * @return */ public List getStopClasses() { return stopClasses; } /** * Create a DOM Element in this context * * @param elementName * @return */ public Element createElement(String elementName) { return docHolder.createElement(elementName); } /** * isBeanCompatible * * @param javaType Class * @param issueErrors if true, issue messages if not compatible * Returns true if it appears that this class is = a bean and * can be mapped to a complexType * @return */ protected boolean isBeanCompatible(Class javaType, boolean = issueErrors) { // Must be a non-primitive and non array if (javaType.isArray() || javaType.isPrimitive()) { if (issueErrors && !beanCompatErrs.contains(javaType)) { log.warn(Messages.getMessage("beanCompatType00", javaType.getName())); beanCompatErrs.add(javaType); } return false; } // Anything in the java or javax package that // does not have a defined mapping is excluded. if (javaType.getName().startsWith("java.") || javaType.getName().startsWith("javax.")) { if (issueErrors && !beanCompatErrs.contains(javaType)) { log.warn(Messages.getMessage("beanCompatPkg00", javaType.getName())); beanCompatErrs.add(javaType); } return false; } // Return true if appears to be an enum class if (JavaUtils.isEnumClass(javaType)) { return true; } // Must have a default public constructor if not // Throwable if (!java.lang.Throwable.class.isAssignableFrom(javaType)) { try { javaType.getConstructor(new Class[]{ }); } catch (java.lang.NoSuchMethodException e) { if (issueErrors && !beanCompatErrs.contains(javaType)) { = log.warn(Messages.getMessage("beanCompatConstructor00", javaType.getName())); beanCompatErrs.add(javaType); } return false; } } // Make sure superclass is compatible Class superClass =3D javaType.getSuperclass(); if ((superClass !=3D null) && (superClass !=3D = java.lang.Object.class) && (superClass !=3D java.lang.Exception.class) && (superClass !=3D java.lang.Throwable.class) && (superClass !=3D java.rmi.RemoteException.class) && (superClass !=3D org.apache.axis.AxisFault.class) && ((stopClasses =3D=3D null) || !(stopClasses.contains(superClass.getName())))) { if (!isBeanCompatible(superClass, false)) { if (issueErrors && !beanCompatErrs.contains(javaType)) { log.warn(Messages.getMessage("beanCompatExtends00", javaType.getName(), superClass.getName(), javaType.getName())); beanCompatErrs.add(javaType); } return false; } } return true; } /** * Write an <element> with an anonymous internal ComplexType * * @param elementName * @param fieldType * @param omittable * @param ownerDocument * @return * @throws AxisFault */ public Element createElementWithAnonymousType( String elementName, Class fieldType, boolean omittable, = Document ownerDocument) throws AxisFault { Element element =3D docHolder.createElement("element"); element.setAttribute("name", elementName); if (isNullable(fieldType)) { element.setAttribute("nillable", "true"); } if (omittable) { element.setAttribute("minOccurs", "0"); element.setAttribute("maxOccurs", "1"); } makeTypeElement(fieldType, null, element); return element; } /** * Create a schema type element (either simpleType or complexType) = for * the particular type/qName combination. If the type is named, we * handle inserting the new type into the appropriate <schema> * in the WSDL types section. If the type is anonymous, we append = the * definition underneath the Element which was passed as the = container * (typically a field of a higher-level type or a parameter in a = wrapped * operation). * * @param type Java type to write * @param qName the desired type QName * @param containingElement a schema element ("element" or = "attribute") * which should either receive a type=3D"" = attribute decoration * (for named types) or a child element = defining an anonymous * type * @return true if the type was already present or was added, false = if there was a problem * @throws AxisFault */ private boolean makeTypeElement( Class type, QName qName, Element containingElement) throws AxisFault { // Get a corresponding QName if one is not provided if ((qName =3D=3D null) || = Constants.equals(Constants.SOAP_ARRAY, qName)) { qName =3D getTypeQName(type); } boolean anonymous =3D isAnonymousType(qName); // Can't have an anonymous type outside of a containing element if (anonymous && (containingElement =3D=3D null)) { throw new AxisFault( Messages.getMessage( "noContainerForAnonymousType", = qName.toString())); } // If we've already got this type (because it's a native type or // because we've already written it), just add the type=3D"" = attribute // (if appropriate) and return. if (!addToTypesList(qName) && !anonymous) { if (containingElement !=3D null) { containingElement.setAttribute("type", = getQNameString(qName)); } return true; } // look up the serializer in the TypeMappingRegistry Serializer ser =3D null; SerializerFactory factory =3D null; if (tm !=3D null) { factory =3D (SerializerFactory) tm.getSerializer(type, = qName); } else { factory =3D (SerializerFactory) = defaultTM.getSerializer(type, qName); } // If no factory is found, use the BeanSerializerFactory // if applicable, otherwise issue errors and treat as an anyType if (factory =3D=3D null) { if (isEnumClass(type)) { factory =3D new EnumSerializerFactory(type, qName); } else if (isBeanCompatible(type, true)) { factory =3D new BeanSerializerFactory(type, qName); } else { return false; } } if (factory !=3D null) { ser =3D (Serializer) = factory.getSerializerAs(Constants.AXIS_SAX); } // if we can't get a serializer, that is bad. if (ser =3D=3D null) { throw new AxisFault(Messages.getMessage("NoSerializer00", type.getName())); } Element typeEl; try { typeEl =3D ser.writeSchema(type, this); } catch (Exception e) { throw AxisFault.makeFault(e); } // If this is an anonymous type, just make the type element a = child // of containingElement. If not, set the "type" attribute of // containingElement to the right QName, and make sure the type = is // correctly written into the appropriate element. if (anonymous) { if (typeEl =3D=3D null) { containingElement.setAttribute("type", = getQNameString(getTypeQName(type))); } else { containingElement.appendChild(typeEl); } } else { if (typeEl !=3D null) { typeEl.setAttribute("name", qName.getLocalPart()); // Write the type in the appropriate writeSchemaTypeDecl(qName, typeEl); } if (containingElement !=3D null) { containingElement.setAttribute("type", = getQNameString(qName)); } } return true; } /** * return the service description * @return */=20 public ServiceDesc getServiceDesc() { return serviceDesc; } } ------=_NextPart_000_0054_01C46B1C.399BBAA0--