FileDocCategorySizeDatePackage
Types.javaAPI DocApache Axis 1.462762Sat Apr 22 18:57:28 BST 2006org.apache.axis.wsdl.fromJava

Types

public class Types extends Object

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

Fields Summary
protected static Log
log
Field log
javax.wsdl.Definition
def
Field def
Namespaces
namespaces
Field namespaces
org.apache.axis.encoding.TypeMapping
tm
Field tm
org.apache.axis.encoding.TypeMapping
defaultTM
Field defaultTM
String
targetNamespace
Field targetNamespace
Element
wsdlTypesElem
Field wsdlTypesElem
HashMap
schemaTypes
Field schemaTypes
HashMap
schemaElementNames
Field schemaElementNames
HashMap
schemaUniqueElementNames
Field schemaUniqueElementNames
HashMap
wrapperMap
Field wrapperMap
List
stopClasses
Field stopClasses
List
beanCompatErrs
Field beanCompatErrs
private org.apache.axis.description.ServiceDesc
serviceDesc
Field serviceDesc
private Set
writtenElementQNames
Keep track of the element QNames we've written to avoid dups
Class[]
mappedTypes
Which types have we already written?
Emitter
emitter
The java to wsdl emitter
Document
docHolder
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;

Constructors Summary
public Types(javax.wsdl.Definition def, org.apache.axis.encoding.TypeMapping tm, org.apache.axis.encoding.TypeMapping defaultTM, Namespaces namespaces, String targetNamespace, List stopClasses, org.apache.axis.description.ServiceDesc serviceDesc)
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


        this.def = def;
        this.serviceDesc = serviceDesc;

        createDocumentFragment();

        this.tm = tm;
        this.defaultTM = defaultTM;

        mappedTypes = tm.getAllClasses();

        this.namespaces = namespaces;
        this.targetNamespace = targetNamespace;
        this.stopClasses = stopClasses;
        schemaElementNames = new HashMap();
        schemaUniqueElementNames = new HashMap();
        schemaTypes = new HashMap();
    
public Types(javax.wsdl.Definition def, org.apache.axis.encoding.TypeMapping tm, org.apache.axis.encoding.TypeMapping defaultTM, Namespaces namespaces, String targetNamespace, List stopClasses, org.apache.axis.description.ServiceDesc serviceDesc, Emitter emitter)
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
param
emitter Java2Wsdl emitter

        this(def, tm, defaultTM, namespaces, targetNamespace, stopClasses, serviceDesc);
        this.emitter = emitter;
    
Methods Summary
private booleanaddToElementsList(javax.xml.namespace.QName qName)
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


        if (qName == null) {
            return false;
        }

        boolean added = false;
        ArrayList elements =
                (ArrayList) schemaElementNames.get(qName.getNamespaceURI());

        if (elements == null) {
            elements = new ArrayList();

            elements.add(qName.getLocalPart());
            schemaElementNames.put(qName.getNamespaceURI(), elements);

            added = true;
        } else {
            if (!elements.contains(qName.getLocalPart())) {
                elements.add(qName.getLocalPart());

                added = true;
            }
        }

        return added;
    
private booleanaddToTypesList(javax.xml.namespace.QName qName)
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


        boolean added = false;
        String namespaceURI = qName.getNamespaceURI();
        ArrayList types = (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 == null) {
            types = new ArrayList();

            types.add(qName.getLocalPart());

            writeTypeNamespace(namespaceURI);
            schemaTypes.put(namespaceURI, types);

            added = true;
        } else {
            if (!types.contains(qName.getLocalPart())) {
                types.add(qName.getLocalPart());

                added = true;
            }
        }

        // If addded, look at the namespace uri to see if the schema element should be
        // generated.
        if (added) {
            String prefix = 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;
    
public org.w3c.dom.ElementcreateArrayElement(java.lang.String componentTypeName)
Method createArrayElement

param
componentTypeName
return


        SOAPConstants constants;
        MessageContext mc = MessageContext.getCurrentContext();
        if(mc==null||mc.getSOAPConstants()==null){
            constants = SOAPConstants.SOAP11_CONSTANTS;
        } else {
            constants = mc.getSOAPConstants();
        }
        String prefix = namespaces.getCreatePrefix(constants.getEncodingURI());
        // ComplexType representation of array
        Element complexType = docHolder.createElement("complexType");
        Element complexContent = docHolder.createElement("complexContent");

        complexType.appendChild(complexContent);

        Element restriction = docHolder.createElement("restriction");

        complexContent.appendChild(restriction);
        restriction.setAttribute("base",
                prefix + ":Array");

        Element attribute = docHolder.createElement("attribute");

        restriction.appendChild(attribute);

        attribute.setAttribute("ref",
                prefix + ":arrayType");

        prefix = namespaces.getCreatePrefix(Constants.NS_URI_WSDL11);
        attribute.setAttribute(prefix + ":arrayType",
                componentTypeName);

        return complexType;
    
public org.w3c.dom.ElementcreateAttributeElement(java.lang.String elementName, java.lang.Class javaType, javax.xml.namespace.QName xmlType, boolean nullable, org.w3c.dom.Document docHolder)
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


        Element element = docHolder.createElement("attribute");

        element.setAttribute("name", elementName);

        if (nullable) {
            element.setAttribute("nillable", "true");
        }

        makeTypeElement(javaType, xmlType, element);

        return element;
    
private voidcreateDocumentFragment()
Method createDocumentFragment


        try {
            this.docHolder = XMLUtils.newDocument();
        } catch (ParserConfigurationException e) {

            // This should not occur
            throw new InternalException(e);
        }
    
public org.w3c.dom.ElementcreateElement(java.lang.String elementName, java.lang.String elementType, boolean nullable, boolean omittable, org.w3c.dom.Document docHolder)
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


        Element element = 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 != null) {
            element.setAttribute("type", elementType);
        }

        return element;
    
public org.w3c.dom.ElementcreateElement(java.lang.String elementName)
Create a DOM Element in this context

param
elementName
return

        return docHolder.createElement(elementName);
    
public org.w3c.dom.ElementcreateElementWithAnonymousType(java.lang.String elementName, java.lang.Class fieldType, boolean omittable, org.w3c.dom.Document ownerDocument)
Write an <element> with an anonymous internal ComplexType

param
elementName
param
fieldType
param
omittable
param
ownerDocument
return
throws
AxisFault


        Element element = 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;
    
public org.w3c.dom.ElementcreateLiteralArrayElement(java.lang.String componentType, javax.xml.namespace.QName itemName)
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 the QName of the inner element (right now we only use the localPart)
return

        String itemLocalName = "item";
        if (itemName != null) {
            itemLocalName = itemName.getLocalPart();
        }

        Element complexType = docHolder.createElement("complexType");
        Element sequence = docHolder.createElement("sequence");

        complexType.appendChild(sequence);

        Element elem = docHolder.createElement("element");
        elem.setAttribute("name", itemLocalName);
        elem.setAttribute("type", componentType);
        elem.setAttribute("minOccurs", "0");
        elem.setAttribute("maxOccurs", "unbounded");

        sequence.appendChild(elem);

        return complexType;
    
private static java.lang.ClassgetComponentType(java.lang.Class clazz)

        if (clazz.isArray())
        {
            return clazz.getComponentType();
        }
        else if (java.util.Collection.class.isAssignableFrom(clazz))
        {
            return Object.class;
        }
        else
        {
            return null;
        }
    
public static java.lang.StringgetLocalNameFromFullName(java.lang.String full)
Utility method to get the local class name from a fully qualified java class name

param
full input class name
return
package name


        String end = "";

        if (full.startsWith("[L")) {
            end = "[]";
            full = full.substring(3, full.length() - 1);
        }

        if (full.lastIndexOf('.") < 0) {
            return full + end;
        } else {
            return full.substring(full.lastIndexOf('.") + 1) + end;
        }
    
public NamespacesgetNamespaces()
Return the namespaces object for the current context

return

        return namespaces;
    
public static java.lang.StringgetPackageNameFromFullName(java.lang.String full)
Utility method to get the package name from a fully qualified java class name

param
full input class name
return
package name


        if (full.lastIndexOf('.") < 0) {
            return "";
        } else {
            return full.substring(0, full.lastIndexOf('."));
        }
    
public java.lang.StringgetQNameString(javax.xml.namespace.QName 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


        String prefix = namespaces.getCreatePrefix(qname.getNamespaceURI());

        return prefix + ":" + qname.getLocalPart();
    
public org.apache.axis.description.ServiceDescgetServiceDesc()
return the service description

return

        return serviceDesc;
    
public java.util.ListgetStopClasses()
Return the list of classes that we should not emit WSDL for.

return

        return stopClasses;
    
public javax.xml.namespace.QNamegetTypeQName(java.lang.Class javaType)
Return the QName of the specified javaType

param
javaType input javaType Class
return
QName

        QName qName = null;

        // Use the typeMapping information to lookup the qName.
        qName = tm.getTypeQName(javaType);

        // 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) &&
                Constants.equals(Constants.SOAP_ARRAY, qName)) {
            Class componentType = getComponentType(javaType);

            // For WS-I BP compliance, we can't use "ArrayOf" as a type prefix 
            // instead use "MyArrayOf" (gag) 
            String arrayTypePrefix = "ArrayOf";

            boolean isWSICompliant = JavaUtils.isTrue(
                    AxisProperties.getProperty(Constants.WSIBP11_COMPAT_PROPERTY));
            if (isWSICompliant) {
                arrayTypePrefix = "MyArrayOf";
            }

            // If component namespace uri == targetNamespace
            // Construct ArrayOf<componentLocalPart>
            // Else
            // Construct ArrayOf_<componentPrefix>_<componentLocalPart>
            QName cqName = getTypeQName(componentType);

            if (targetNamespace.equals(cqName.getNamespaceURI())) {
                qName = new QName(targetNamespace,
                        arrayTypePrefix + cqName.getLocalPart());
            } else {
                String pre =
                        namespaces.getCreatePrefix(cqName.getNamespaceURI());

                qName = new QName(targetNamespace,
                        arrayTypePrefix + "_" + pre + "_"
                        + cqName.getLocalPart());
            }

            return qName;
        }

        // If a qName was not found construct one using the
        // class name information.
        if (qName == null) {
            String pkg = getPackageNameFromFullName(javaType.getName());
            String lcl = getLocalNameFromFullName(javaType.getName());
            String ns = namespaces.getCreate(pkg);

            namespaces.getCreatePrefix(ns);

            String localPart = lcl.replace('$", '_");

            qName = new QName(ns, localPart);
        }

        return qName;
    
booleanimplementsSimpleType(java.lang.Class type)
Does the class implement SimpleType

param
type input Class
return
true if the type implements SimpleType


        Class[] impls = type.getInterfaces();

        for (int i = 0; i < impls.length; i++) {
            if (impls[i] == SimpleType.class) {
                return true;
            }
        }

        return false;
    
public voidinsertTypesFragment(org.w3c.dom.Document doc)
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


        updateNamespaces();

        if (wsdlTypesElem == null)
            return;

        // Make sure that definitions from each embedded schema are allowed
        // to reference schema components from the other sibling schemas.
        Element schemaElem = null;
        String tns = null;
        NodeList nl = wsdlTypesElem.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            NamedNodeMap attrs = nl.item(i).getAttributes();
            if (attrs == null) continue; // Should never happen.
            for (int n = 0; n < attrs.getLength(); n++) {
                Attr a = (Attr) attrs.item(n);
                if (a.getName().equals("targetNamespace")) {
                    tns = a.getValue();
                    schemaElem = (Element) nl.item(i);
                    break;
                }
            }

            // Ignore what appears to be a not namespace-qualified
            // schema definition.
            if (tns != 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 = schemaTypes.keySet().iterator();
                String otherTns;
                Element importElem;
                while (it.hasNext()) {
                    if (!tns.equals(otherTns = (String) it.next())) {
                        importElem = docHolder.createElement("import");
                        importElem.setAttribute("namespace", otherTns);
                        schemaElem.insertBefore(importElem,
                                schemaElem.getFirstChild());
                    }
                }
            }
            schemaElem = null;
            tns = null;
        }

        // Import the wsdlTypesElement into the doc.
        org.w3c.dom.Node node = doc.importNode(wsdlTypesElem, true);
        // Insert the imported element at the beginning of the document
        doc.getDocumentElement().
                insertBefore(node,
                        doc.getDocumentElement().getFirstChild());
    
public booleanisAcceptableAsAttribute(java.lang.Class type)
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

        return isSimpleType(type) || isEnumClass(type)
                || implementsSimpleType(type);
    
private booleanisAnonymousType(javax.xml.namespace.QName type)
Method isAnonymousType

param
type
return

        return type.getLocalPart().indexOf(SymbolTable.ANON_TOKEN) != -1;
    
public static booleanisArray(java.lang.Class clazz)


        
    
        return clazz.isArray() || java.util.Collection.class.isAssignableFrom(clazz);
    
protected booleanisBeanCompatible(java.lang.Class javaType, boolean issueErrors)
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


        // 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 = javaType.getSuperclass();

        if ((superClass != null) && (superClass != java.lang.Object.class)
                && (superClass != java.lang.Exception.class)
                && (superClass != java.lang.Throwable.class)
                && (superClass != java.rmi.RemoteException.class)
                && (superClass != org.apache.axis.AxisFault.class)
                && ((stopClasses == 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;
    
public static booleanisEnumClass(java.lang.Class cls)
Returns true if indicated type matches the JAX-RPC enumeration class. Note: supports JSR 101 version 0.6 Public Draft

param
cls
return


        try {
            java.lang.reflect.Method m = cls.getMethod("getValue", null);
            java.lang.reflect.Method m2 = cls.getMethod("toString", null);

            if ((m != null) && (m2 != null)) {
                java.lang.reflect.Method m3 =
                        cls.getDeclaredMethod("fromString",
                                new Class[]{
                                    java.lang.String.class});
                java.lang.reflect.Method m4 = cls.getDeclaredMethod("fromValue",
                        new Class[]{
                            m.getReturnType()});

                if ((m3 != null) && Modifier.isStatic(m3.getModifiers())
                        && Modifier.isPublic(m3.getModifiers()) && (m4 != 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()}) == null) {
                            return true;
                        }

                        return false;
                    } catch (java.lang.NoSuchMethodException e) {
                        return true;
                    }
                }
            }
        } catch (java.lang.NoSuchMethodException e) {
        }

        return false;
    
public static booleanisNullable(java.lang.Class type)
Determines if the field is nullable. All non-primitives are nillable.

param
type input Class
return
true if nullable

        if (type.isPrimitive()) {
            return false;
        } else {
            return true;
        }
    
private booleanisPresent(java.lang.String list, java.lang.String namespace)
check if the namespace is present in the list.

param
list
param
namespace
return

        if(list == null || list.length()==0)
                return false;
        String[] array = StringUtils.split(list,',");
        for(int i=0;i<array.length;i++){
            if(array[i].equals(namespace))
                return true;
        }
        return false;
    
booleanisSimpleType(java.lang.Class type)
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


        QName qname = tm.getTypeQName(type);

        if (qname == null) {
            return false;    // No mapping
        }

        String nsURI = qname.getNamespaceURI();

        return (Constants.isSchemaXSD(nsURI) || Constants.isSOAP_ENC(nsURI));
    
public voidloadInputSchema(java.lang.String inputSchema)
Loads the types from the input schema file.

param
inputSchema file or URL
throws
IOException
throws
WSDLException
throws
SAXException
throws
ParserConfigurationException


        // Read the input wsdl file into a Document
        Document doc = XMLUtils.newDocument(inputSchema);

        // Ensure that the root element is xsd:schema
        Element root = doc.getDocumentElement();

        if (root.getLocalName().equals("schema")
                && Constants.isSchemaXSD(root.getNamespaceURI())) {
            Node schema = docHolder.importNode(root, true);

            if (null == wsdlTypesElem) {
                writeWsdlTypesElement();
            }

            wsdlTypesElem.appendChild(schema);

            // Create a symbol table and populate it with the input types
            BaseTypeMapping btm = new BaseTypeMapping() {

                public String getBaseName(QName qNameIn) {

                    QName qName = new QName(qNameIn.getNamespaceURI(),
                            qNameIn.getLocalPart());
                    Class cls = defaultTM.getClassForQName(qName);

                    if (cls == null) {
                        return null;
                    } else {
                        return JavaUtils.getTextClassName(cls.getName());
                    }
                }
            };
            SymbolTable symbolTable = 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?
            ;
        }
    
public voidloadInputTypes(java.lang.String inputWSDL)
Load the types from the input wsdl file.

param
inputWSDL file or URL
throws
IOException
throws
WSDLException
throws
SAXException
throws
ParserConfigurationException


        // Read the input wsdl file into a Document
        Document doc = XMLUtils.newDocument(inputWSDL);

        // Search for the 'types' element
        NodeList elements = doc.getChildNodes();

        if ((elements.getLength() > 0)
                && elements.item(0).getLocalName().equals("definitions")) {
            elements = elements.item(0).getChildNodes();

            for (int i = 0;
                 (i < elements.getLength()) && (wsdlTypesElem == null);
                 i++) {
                Node node = elements.item(i);

                if ((node.getLocalName() != null)
                        && node.getLocalName().equals("types")) {
                    wsdlTypesElem = (Element) node;
                }
            }
        }

        // If types element not found, there is no need to continue.
        if (wsdlTypesElem == null) {
            return;
        }

        // Import the types element into the Types docHolder document
        wsdlTypesElem = (Element) docHolder.importNode(wsdlTypesElem, true);

        docHolder.appendChild(wsdlTypesElem);

        // Create a symbol table and populate it with the input wsdl document
        BaseTypeMapping btm = new BaseTypeMapping() {

            public String getBaseName(QName qNameIn) {

                QName qName = new QName(qNameIn.getNamespaceURI(),
                        qNameIn.getLocalPart());
                Class cls = tm.getClassForQName(qName);

                if (cls == null) {
                    return null;
                } else {
                    return JavaUtils.getTextClassName(cls.getName());
                }
            }
        };
        SymbolTable symbolTable = new SymbolTable(btm, true, false, false);

        symbolTable.populate(null, doc);
        processSymTabEntries(symbolTable);
    
private booleanmakeTypeElement(java.lang.Class type, javax.xml.namespace.QName qName, org.w3c.dom.Element containingElement)
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="" 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


        // Get a corresponding QName if one is not provided
        if ((qName == null) || Constants.equals(Constants.SOAP_ARRAY, qName)) {
            qName = getTypeQName(type);
        }

        boolean anonymous = isAnonymousType(qName);

        // Can't have an anonymous type outside of a containing element
        if (anonymous && (containingElement == 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="" attribute
        // (if appropriate) and return.
        if (!addToTypesList(qName) && !anonymous) {
            if (containingElement != null) {
                containingElement.setAttribute("type", getQNameString(qName));
            }

            return true;
        }

        // look up the serializer in the TypeMappingRegistry
        SerializerFactory factory;
        factory = (SerializerFactory) tm.getSerializer(type, qName);

        // If no factory is found, use the BeanSerializerFactory
        // if applicable, otherwise issue errors and treat as an anyType
        if (factory == null) {
            if (isEnumClass(type)) {
                factory = new EnumSerializerFactory(type, qName);
            } else if (isBeanCompatible(type, true)) {
                factory = new BeanSerializerFactory(type, qName);
            } else {
                return false;
            }
        }

        // factory is not null
        Serializer ser = (Serializer) factory.getSerializerAs(Constants.AXIS_SAX);

        // if we can't get a serializer, that is bad.
        if (ser == null) {
            throw new AxisFault(Messages.getMessage("NoSerializer00",
                    type.getName()));
        }

        Element typeEl;

        try {
            typeEl = 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 <schema> element.
        if (anonymous) {
            if (typeEl == null) {
                containingElement.setAttribute("type", getQNameString(getTypeQName(type)));
            } else {
                containingElement.appendChild(typeEl);
            }
        } else {
            if (typeEl != null) {
                typeEl.setAttribute("name", qName.getLocalPart());

                // Write the type in the appropriate <schema>
                writeSchemaTypeDecl(qName, typeEl);
            }

            if (containingElement != null) {
                containingElement.setAttribute("type", getQNameString(qName));
            }
        }

        // store the mapping of type qname and its correspoding java type	
        if (emitter != null) {
            emitter.getQName2ClassMap().put(qName, type);
        }

        return true;
    
private voidprocessSymTabEntries(org.apache.axis.wsdl.symbolTable.SymbolTable symbolTable)
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


        Iterator iterator = symbolTable.getElementIndex().entrySet().iterator();

        while (iterator.hasNext()) {
            Map.Entry me = (Map.Entry) iterator.next();
            QName name = (QName) me.getKey();
            TypeEntry te = (TypeEntry) me.getValue();
            String prefix = XMLUtils.getPrefix(name.getNamespaceURI(),
                    te.getNode());

            if (!((null == prefix) || "".equals(prefix))) {
                namespaces.putPrefix(name.getNamespaceURI(), prefix);
                def.addNamespace(prefix, name.getNamespaceURI());
            }

            addToElementsList(name);
        }

        iterator = symbolTable.getTypeIndex().entrySet().iterator();

        while (iterator.hasNext()) {
            Map.Entry me = (Map.Entry) iterator.next();
            QName name = (QName) me.getKey();
            TypeEntry te = (TypeEntry) me.getValue();
            String prefix = XMLUtils.getPrefix(name.getNamespaceURI(),
                    te.getNode());

            if (!((null == prefix) || "".equals(prefix))) {
                namespaces.putPrefix(name.getNamespaceURI(), prefix);
                def.addNamespace(prefix, name.getNamespaceURI());
            }

            addToTypesList(name);
        }
    
public voidupdateNamespaces()
Method updateNamespaces


        Namespaces namespaces = getNamespaces();
        Iterator nspIterator = namespaces.getNamespaces();

        while (nspIterator.hasNext()) {
            String nsp = (String) nspIterator.next();
            String pref = def.getPrefix(nsp);

            if (pref == null) {
                def.addNamespace(namespaces.getCreatePrefix(nsp), nsp);
            }
        }
    
public voidwriteElementDecl(javax.xml.namespace.QName qname, java.lang.Class javaType, javax.xml.namespace.QName typeQName, boolean nillable, javax.xml.namespace.QName itemQName)
Create a top-level element declaration in our generated schema

param
qname
param
javaType
param
typeQName
param
nillable nillable attribute of the element
param
itemQName
throws
AxisFault


        if (writtenElementQNames.contains(qname)) {
            return;
        }

        String name = qname.getLocalPart();

        Element element = docHolder.createElement("element");

        // Generate an element name that matches the type.
        element.setAttribute("name", name);

        if (nillable) {
            element.setAttribute("nillable", "true");
        }

        /*
         * These are not legal on top-level elements!
         * (feel free to delete this block after say Oct 2005)
        if (omittable) {
            element.setAttribute("minOccurs", "0");
            element.setAttribute("maxOccurs", "1");
        }

        if (javaType.isArray()) {
            element.setAttribute("maxOccurs", "unbounded");
        }
        */

        if (javaType.isArray()) {
            // TODO : Should check to see if this array type is specifically mapped
            String componentType = writeType(javaType.getComponentType());
            Element complexType = createLiteralArrayElement(componentType,
                                                            itemQName);
            element.appendChild(complexType);
        } else {
            // Write the type for this element, handling anonymous or named
            // types appropriately.
            makeTypeElement(javaType, typeQName, element);
        }

        writeSchemaElementDecl(qname, element);
    
public javax.xml.namespace.QNamewriteElementForPart(java.lang.Class type, javax.xml.namespace.QName qname)
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


        // 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==null ) {
        *   return null;
        * }
        */
        if (type.getName().equals("void")) {
            return null;
        }

        if (Holder.class.isAssignableFrom(type)) {
            type = JavaUtils.getHolderValueType(type);
        }

        // Get the qname
        if ((qname == null)
                || (Constants.isSOAP_ENC(qname.getNamespaceURI())
                && "Array".equals(qname.getLocalPart()))) {
            qname = getTypeQName(type);

            if (qname == null) {
                throw new AxisFault("Class:" + type.getName());
            }
        }

        // Return null it a simple type (not an element)
        String nsURI = 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 == null) {
            writeWsdlTypesElement();
        }

        // Write Element, if problems occur return null.
        if (writeTypeAsElement(type, qname) == null) {
            qname = null;
        }

        return qname;
    
public org.w3c.dom.ElementwriteEnumType(javax.xml.namespace.QName qName, java.lang.Class cls)
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


        if (!isEnumClass(cls)) {
            return null;
        }

        // Get the base type of the enum class
        java.lang.reflect.Method m = cls.getMethod("getValue", null);
        Class base = m.getReturnType();

        // Create simpleType, restriction elements
        Element simpleType = docHolder.createElement("simpleType");

        simpleType.setAttribute("name", qName.getLocalPart());

        Element restriction = docHolder.createElement("restriction");

        simpleType.appendChild(restriction);

        String baseType = writeType(base, null);

        restriction.setAttribute("base", baseType);

        // Create an enumeration using the field values
        Field[] fields = cls.getDeclaredFields();

        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            int mod = 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() == base)) {

                // Create an enumeration using the value specified
                Element enumeration = docHolder.createElement("enumeration");

                enumeration.setAttribute("value", field.get(null).toString());
                restriction.appendChild(enumeration);
            }
        }

        return simpleType;
    
public voidwriteSchemaElement(javax.xml.namespace.QName qName, org.w3c.dom.Element element)

deprecated
Please use writeSchemaElement(String namespaceURI, Element element)
param
qName qName to get the namespace of the schema node
param
element the Element to append to the Schema node
throws
AxisFault

        writeSchemaElement(qName.getNamespaceURI(), element);
    
public voidwriteSchemaElement(java.lang.String namespaceURI, org.w3c.dom.Element 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


        if (wsdlTypesElem == null) {
            try {
                writeWsdlTypesElement();
            } catch (Exception e) {
                log.error(e);

                return;
            }
        }

        if ((namespaceURI == null) || namespaceURI.equals("")) {
            throw new AxisFault(
                    Constants.FAULT_SERVER_GENERAL,
                    Messages.getMessage("noNamespace00", namespaceURI), null, null);
        }

        Element schemaElem = null;
        NodeList nl = wsdlTypesElem.getChildNodes();

        for (int i = 0; i < nl.getLength(); i++) {
            NamedNodeMap attrs = nl.item(i).getAttributes();

            if (attrs != null) {
                for (int n = 0; n < attrs.getLength(); n++) {
                    Attr a = (Attr) attrs.item(n);

                    if (a.getName().equals("targetNamespace")
                            && a.getValue().equals(namespaceURI)) {
                        schemaElem = (Element) nl.item(i);
                    }
                }
            }
        }

        if (schemaElem == null) {
            schemaElem = 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() == Style.RPC) {
                Element importElem = docHolder.createElement("import");

                schemaElem.appendChild(importElem);
                importElem.setAttribute("namespace",
                        Constants.URI_DEFAULT_SOAP_ENC);
            }

            SOAPService service = null;
            if(MessageContext.getCurrentContext() != null) {
                service = MessageContext.getCurrentContext().getService();
            }
            if(service != null && isPresent((String) service.getOption("schemaQualified"), namespaceURI)){
                schemaElem.setAttribute("elementFormDefault", "qualified");
            } else if(service != null && isPresent((String) service.getOption("schemaUnqualified"), namespaceURI)){
                // DO nothing..default is unqualified.
            } else if ((serviceDesc.getStyle() == Style.DOCUMENT)
                    || (serviceDesc.getStyle() == Style.WRAPPED)) {
                schemaElem.setAttribute("elementFormDefault", "qualified");
            }

            writeTypeNamespace(namespaceURI);
        }

        schemaElem.appendChild(element);
    
public voidwriteSchemaElementDecl(javax.xml.namespace.QName qname, org.w3c.dom.Element element)
Method writeSchemaElementDecl

param
qname
param
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);
    
public voidwriteSchemaTypeDecl(javax.xml.namespace.QName qname, org.w3c.dom.Element element)
Method writeSchemaTypeDecl

param
qname
param
element
throws
AxisFault

        writeSchemaElement(qname.getNamespaceURI(), element);
    
public java.lang.StringwriteType(java.lang.Class type)
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

        return writeType(type, null);
    
public java.lang.StringwriteType(java.lang.Class type, javax.xml.namespace.QName qName)
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


        // Get a corresponding QName if one is not provided
        if ((qName == null) || Constants.equals(Constants.SOAP_ARRAY, qName)) {
            qName = getTypeQName(type);
        }

        if (!makeTypeElement(type, qName, null)) {
            return null;
        }

        return getQNameString(qName);
    
public javax.xml.namespace.QNamewriteTypeAndSubTypeForPart(java.lang.Class type, javax.xml.namespace.QName qname)
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.


        // Write out type in parameter
        QName qNameRet = writeTypeForPart(type, qname);

        // If mappedTypesexists 
        // Will write subTypes of the type in parameters
        if (mappedTypes != null) {
            for (int i = 0; i < mappedTypes.length; i++) {
                Class tempMappedType = mappedTypes[i];
                QName name;

                // If tempMappedType is subtype of the "type" parameter
                // and type is not Object (Object superclass of all Java class...)  
                // write the subtype
                if (tempMappedType != null &&
                        type != Object.class &&
                        tempMappedType != type &&
                        type.isAssignableFrom(tempMappedType)) {
                    name = tm.getTypeQName(tempMappedType);
                    if (!isAnonymousType(name)) {
                        writeTypeForPart(tempMappedType, name);
                    }

                    // Only do each one once.  This is OK to do because each
                    // Types instance is for generating a single WSDL.
                    mappedTypes[i] = null;
                }
            }
        } //if (mappedTyped != null) {

        return qNameRet;
    
private javax.xml.namespace.QNamewriteTypeAsElement(java.lang.Class type, javax.xml.namespace.QName qName)
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


        if ((qName == null) || Constants.equals(Constants.SOAP_ARRAY, qName)) {
            qName = getTypeQName(type);
        }

        writeTypeNamespace(type, qName);
        String elementType = writeType(type, qName);

        if (elementType != null) {

            // Element element = createElementDecl(qName.getLocalPart(), type, qName, isNullable(type), false);
            // if (element != null)
            // writeSchemaElement(typeQName,element);
            return qName;
        }

        return null;
    
public javax.xml.namespace.QNamewriteTypeForPart(java.lang.Class type, javax.xml.namespace.QName qname)
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


        // 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==null ) {
        *   return null;
        * }
        */
        if (type.getName().equals("void")) {
            return null;
        }

        if (Holder.class.isAssignableFrom(type)) {
            type = JavaUtils.getHolderValueType(type);
        }

        // Get the qname
        if ((qname == null)
                || (Constants.isSOAP_ENC(qname.getNamespaceURI())
                && "Array".equals(qname.getLocalPart()))) {
            qname = getTypeQName(type);

            if (qname == null) {
                throw new AxisFault("Class:" + type.getName());
            }
        }

        if (!makeTypeElement(type, qname, null)) {
            qname = Constants.XSD_ANYTYPE;
        }

        return qname;
    
private javax.xml.namespace.QNamewriteTypeNamespace(java.lang.Class type, javax.xml.namespace.QName qName)
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


        if (qName == null) {
            qName = getTypeQName(type);
        }

        writeTypeNamespace(qName.getNamespaceURI());

        return qName;
    
private voidwriteTypeNamespace(java.lang.String namespaceURI)
write out the namespace declaration.

param
namespaceURI qname of the type


        if ((namespaceURI != null) && !namespaceURI.equals("")) {
            String pref = def.getPrefix(namespaceURI);

            if (pref == null) {
                def.addNamespace(namespaces.getCreatePrefix(namespaceURI),
                        namespaceURI);
            }
        }
    
public voidwriteWrappedParameter(org.w3c.dom.Element sequence, java.lang.String name, javax.xml.namespace.QName type, java.lang.Class javaType)
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


        if (javaType == void.class) {
            return;
        }

        // JAX-RPC 1.1 says that byte[] should always be a Base64Binary
        // This (rather strange) hack will ensure that we don't map it
        // in to an maxoccurs=unbounded array.
        if (javaType.isArray() && !javaType.equals(byte[].class)) {
            type = writeTypeForPart(javaType.getComponentType(), null);
        } else {
            type = writeTypeForPart(javaType, type);
        }

        if (type == null) {
            // TODO: throw an Exception!!
            return;
        }

        Element childElem;

        if (isAnonymousType(type)) {
            childElem = createElementWithAnonymousType(name, javaType, false,
                    docHolder);
        } else {

            // Create the child <element> and add it to the wrapper <sequence>
            childElem = docHolder.createElement("element");

            childElem.setAttribute("name", name);

            String prefix =
                    namespaces.getCreatePrefix(type.getNamespaceURI());
            String prefixedName = prefix + ":" + type.getLocalPart();

            childElem.setAttribute("type", prefixedName);

            // JAX-RPC 1.1 says that byte[] should always be a Base64Binary
            // This (rather strange) hack will ensure that we don't map it
            // in to an maxoccurs=unbounded array.
            if (javaType.isArray() && !javaType.equals(byte[].class)) {
                childElem.setAttribute("maxOccurs", "unbounded");
            }
        }

        sequence.appendChild(childElem);
    
public org.w3c.dom.ElementwriteWrapperElement(javax.xml.namespace.QName qname, boolean request, boolean hasParams)
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


        // Make sure a types section is present
        if (wsdlTypesElem == null) {
            writeWsdlTypesElement();
        }

        // Write the namespace definition for the wrapper
        writeTypeNamespace(qname.getNamespaceURI());

        // Create an <element> for the wrapper
        Element wrapperElement = docHolder.createElement("element");

        writeSchemaElementDecl(qname, wrapperElement);
        wrapperElement.setAttribute("name", qname.getLocalPart());

        // Create an anonymous <complexType> for the wrapper
        Element complexType = docHolder.createElement("complexType");

        wrapperElement.appendChild(complexType);

        // If we have parameters in the operation, create a <sequence>
        // under the complexType and return it.
        if (hasParams) {
            Element sequence = docHolder.createElement("sequence");

            complexType.appendChild(sequence);

            return sequence;
        }

        return null;
    
private voidwriteWsdlTypesElement()
Get the Types element for the WSDL document. If not present, create one


        if (wsdlTypesElem == null) {

            // Create a <wsdl:types> element corresponding to the wsdl namespaces.
            wsdlTypesElem = docHolder.createElementNS(Constants.NS_URI_WSDL11,
                    "types");

            wsdlTypesElem.setPrefix(Constants.NS_PREFIX_WSDL);
        }