FileDocCategorySizeDatePackage
SymbolTable.javaAPI DocApache Axis 1.4140742Sat Apr 22 18:57:26 BST 2006org.apache.axis.wsdl.symbolTable

SymbolTable

public class SymbolTable extends Object
This class represents a table of all of the top-level symbols from a set of WSDL Definitions and DOM Documents: XML types; WSDL messages, portTypes, bindings, and services.

This symbolTable contains entries of the form where key is of type QName and value is of type Vector. The Vector's elements are all of the objects that have the given QName. This is necessary since names aren't unique among the WSDL types. message, portType, binding, service, could all have the same QName and are differentiated merely by type. SymbolTable contains type-specific getters to bypass the Vector layer: public PortTypeEntry getPortTypeEntry(QName name), etc.

Fields Summary
protected HashMap
derivedTypes
private boolean
addImports
Field addImports
private HashMap
symbolTable
Field symbolTable
private final Map
elementTypeEntries
Field elementTypeEntries
private final Map
elementIndex
Field elementIndex
private final Map
typeTypeEntries
Field typeTypeEntries
private final Map
typeIndex
Field typeIndex
protected final Map
node2ExtensionBase
cache of nodes -> base types for complexTypes. The cache is built on nodes because multiple TypeEntry objects may use the same node.
private boolean
verbose
Field verbose
protected boolean
quiet
Field quiet
private BaseTypeMapping
btm
Field btm
private boolean
nowrap
Field nowrap
private boolean
wrapped
Field wrapped
public static final String
ANON_TOKEN
Field ANON_TOKEN
private javax.wsdl.Definition
def
Field def
private String
wsdlURI
Field wsdlURI
private boolean
wrapArrays
If this is false, we will "unwrap" literal arrays, generating a plan "String[]" instead of "ArrayOfString" when encountering an element containing a single maxOccurs="unbounded" inner element.
Set
arrayTypeQNames
private final Map
elementFormDefaults
Field elementFormDefaults
private org.apache.axis.utils.URLHashSet
importedFiles
Add the given Definition and Document information to the symbol table (including imported symbols), populating it with SymTabEntries for each of the top-level symbols. NOTE: filename is used only by checkForUndefined so that it can report which WSDL file has the problem. If we're on the primary WSDL file, then we don't know the name and filename will be null. But we know the names of all imported files.
private static final int
ABOVE_SCHEMA_LEVEL
Utility method which walks the Document and creates Type objects for each complexType, simpleType, attributeGroup or element referenced or defined.

What goes into the symbol table? In general, only the top-level types (ie., those just below the schema tag). But base types and references can appear below the top level. So anything at the top level is added to the symbol table, plus non-Element types (ie, base and refd) that appear deep within other types.

private static final int
SCHEMA_LEVEL
Field SCHEMA_LEVEL
Constructors Summary
public SymbolTable(BaseTypeMapping btm, boolean addImports, boolean verbose, boolean nowrap)
Construct a symbol table with the given Namespaces.

param
btm
param
addImports
param
verbose
param
nowrap

                                            
        
                           

        this.btm = btm;
        this.addImports = addImports;
        this.verbose = verbose;
        this.nowrap = nowrap;
    
Methods Summary
protected voidadd(java.lang.String context, javax.wsdl.Definition def, org.w3c.dom.Document doc)
Add the given Definition and Document information to the symbol table (including imported symbols), populating it with SymTabEntries for each of the top-level symbols. When the symbol table has been populated, iterate through it, setting the isReferenced flag appropriately for each entry.

param
context
param
def
param
doc
throws
IOException
throws
SAXException
throws
WSDLException
throws
ParserConfigurationException


        URL contextURL = (context == null)
                ? null
                : getURL(null, context);

        populate(contextURL, def, doc, null);
        processTypes();
        checkForUndefined();
        populateParameters();
        setReferences(def, doc);    // uses wrapped flag set in populateParameters
    
private voidaddInishParm(java.util.Vector inputs, java.util.Vector outputs, int index, int outdex, Parameters parameters, boolean trimInput)
Add an in or inout parameter to the parameters object.

param
inputs
param
outputs
param
index
param
outdex
param
parameters
param
trimInput


        Parameter p = (Parameter) inputs.get(index);

        // If this is an element, we want the XML to reflect the element name
        // not the part name.  Same check is made in addOutParam below.
        if (p.getType() instanceof DefinedElement) {
            DefinedElement de = (DefinedElement) p.getType();

            p.setQName(de.getQName());
        }

        // If this is a collection we want the XML to reflect the type in
        // the collection, not foo[unbounded].
        // Same check is made in addOutParam below.
        if (p.getType() instanceof CollectionElement) {
            p.setQName(p.getType().getRefType().getQName());
        }

        // Should we remove the given parameter type/name entries from the Vector?
        if (trimInput) {
            inputs.remove(index);
        }

        // At this point we know the name and type of the parameter, and that it's at least an
        // in parameter.  Now check to see whether it's also in the outputs Vector.  If it is,
        // then it's an inout parameter.
        if (outdex >= 0) {
            Parameter outParam = (Parameter) outputs.get(outdex);

            TypeEntry paramEntry = p.getType();
            TypeEntry outParamEntry = outParam.getType();
//            String paramLastLocalPart = Utils.getLastLocalPart(paramEntry.getQName().getLocalPart());
//            String outParamLastLocalPart = Utils.getLastLocalPart(outParamEntry.getQName().getLocalPart());
            if (paramEntry.equals(outParamEntry)) {
                outputs.remove(outdex);
                p.setMode(Parameter.INOUT);

                ++parameters.inouts;
            }
            /*
            else if (paramLastLocalPart.equals(outParamLastLocalPart)) {
                outputs.remove(outdex);
                p.setMode(Parameter.INOUT);

                ++parameters.inouts;
                if (paramEntry.isBaseType()) {
                    if (paramEntry.getBaseType().equals(outParamEntry.getBaseType())) {
                        outputs.remove(outdex);
                        p.setMode(Parameter.INOUT);

                        ++parameters.inouts;
                    }
                }
                else if (paramEntry.getRefType() != null) {
                    if (paramEntry.getRefType().equals(outParamEntry.getRefType())) {
                        outputs.remove(outdex);
                        p.setMode(Parameter.INOUT);

                        ++parameters.inouts;
                    }
                }
                else {
                    ++parameters.inputs;
                }
            }
        */
            else {

                // If we're here, we have both an input and an output
                // part with the same name but different types.... guess
                // it's not really an inout....
                //
                // throw new IOException(Messages.getMessage("differentTypes00",
                // new String[] { p.getName(),
                // p.getType().getQName().toString(),
                // outParam.getType().getQName().toString()
                // }
                // ));
                // There is some controversy about this, and the specs are
                // a bit vague about what should happen if the types don't
                // agree.  Throwing an error is not correct with document/lit
                // operations, as part names get resused (i.e. "body").
                // See WSDL 1.1 section 2.4.6,
                // WSDL 1.2 working draft 9 July 2002 section 2.3.1
                ++parameters.inputs;
            }
        } else {
            ++parameters.inputs;
        }

        parameters.list.add(p);
    
private org.apache.axis.constants.UseaddMIMETypes(BindingEntry bEntry, javax.wsdl.extensions.mime.MIMEMultipartRelated mpr, javax.wsdl.Operation op)
Add the parts that are really MIME types as MIME types. A side effect is to return the body Type of the given MIMEMultipartRelated object.

param
bEntry
param
mpr
param
op
return
throws
IOException


        Use bodyType = Use.ENCODED;
        List parts = mpr.getMIMEParts();
        Iterator i = parts.iterator();

        while (i.hasNext()) {
            MIMEPart part = (MIMEPart) i.next();
            List elems = part.getExtensibilityElements();
            Iterator j = elems.iterator();

            while (j.hasNext()) {
                Object obj = j.next();

                if (obj instanceof MIMEContent) {
                    MIMEContent content = (MIMEContent) obj;
                    TypeEntry typeEntry = findPart(op, content.getPart());
                    if (typeEntry == null) {
                        throw new RuntimeException(Messages.getMessage("cannotFindPartForOperation00", content.getPart(),
                                op.getName(), content.getType()));
                    }
                    String dims = typeEntry.getDimensions();

                    if ((dims.length() <= 0)
                            && (typeEntry.getRefType() != null)) {
                        Node node = typeEntry.getRefType().getNode();

                        if (getInnerCollectionComponentQName(node) != null) {
                            dims += "[]";
                        }
                    }

                    String type = content.getType();

                    if ((type == null) || (type.length() == 0)) {
                        type = "text/plain";
                    }

                    bEntry.setMIMEInfo(op.getName(), content.getPart(), type,
                            dims);
                } else if (obj instanceof SOAPBody) {
                    String use = ((SOAPBody) obj).getUse();

                    if (use == null) {
                        throw new IOException(
                                Messages.getMessage("noUse", op.getName()));
                    }

                    if (use.equalsIgnoreCase("literal")) {
                        bodyType = Use.LITERAL;
                    }
                } else if (obj instanceof UnknownExtensibilityElement) {

                    // TODO: After WSDL4J supports soap12, change this code
                    UnknownExtensibilityElement unkElement =
                            (UnknownExtensibilityElement) obj;
                    QName name =
                            unkElement.getElementType();

                    if (name.getNamespaceURI().equals(Constants.URI_WSDL12_SOAP)
                            && name.getLocalPart().equals("body")) {
                        String use =
                                unkElement.getElement().getAttribute("use");

                        if (use == null) {
                            throw new IOException(
                                    Messages.getMessage("noUse", op.getName()));
                        }

                        if (use.equalsIgnoreCase("literal")) {
                            bodyType = Use.LITERAL;
                        }
                    }
                }
            }
        }

        return bodyType;
    
private voidaddOutParm(java.util.Vector outputs, int outdex, Parameters parameters, boolean trim)
Add an output parameter to the parameters object.

param
outputs
param
outdex
param
parameters
param
trim


        Parameter p = (Parameter) outputs.get(outdex);

        // If this is an element, we want the XML to reflect the element name
        // not the part name.  Same check is made in addInishParam above.
        if (p.getType() instanceof DefinedElement) {
            DefinedElement de = (DefinedElement) p.getType();

            p.setQName(de.getQName());
        }

        // If this is a collection we want the XML to reflect the type in
        // the collection, not foo[unbounded].
        // Same check is made in addInishParam above.
        if (p.getType() instanceof CollectionElement) {
            p.setQName(p.getType().getRefType().getQName());
        }

        if (trim) {
            outputs.remove(outdex);
        }

        p.setMode(Parameter.OUT);

        ++parameters.outputs;

        parameters.list.add(p);
    
private voidaddTypes(java.net.URL context, org.w3c.dom.Node node, int level)
Method addTypes

param
context
param
node
param
level
throws
IOException
throws
ParserConfigurationException
throws
WSDLException
throws
SAXException


                                                                                      
           
               
             

        if (node == null) {
            return;
        }

        // Get the kind of node (complexType, wsdl:part, etc.)
        String localPart = node.getLocalName();

        if (localPart != null) {
            boolean isXSD =
                    Constants.isSchemaXSD(node.getNamespaceURI());

            if (((isXSD && localPart.equals("complexType"))
                    || localPart.equals("simpleType"))) {

                // If an extension or restriction is present,
                // create a type for the reference
                Node re = SchemaUtils.getRestrictionOrExtensionNode(node);

                if ((re != null) && (Utils.getAttribute(re, "base") != null)) {
                    createTypeFromRef(re);
                }

                Node list = SchemaUtils.getListNode(node);
                if (list != null && Utils.getAttribute(list,"itemType") != null) {
                    createTypeFromRef(list);
                }

                Node union = SchemaUtils.getUnionNode(node);
                if (union != null) {
                    QName [] memberTypes = Utils.getMemberTypeQNames(union);
                    if (memberTypes != null) {
                        for (int i=0;i<memberTypes.length;i++) {
                            if (SchemaUtils.isSimpleSchemaType(memberTypes[i]) &&
                                getType(memberTypes[i]) == null) {
                                symbolTablePut(new BaseType(memberTypes[i]));
                            }
                        }
                    }
                }

                // This is a definition of a complex type.
                // Create a Type.
                createTypeFromDef(node, false, false);
            } else if (isXSD && localPart.equals("element")) {

                // Create a type entry for the referenced type
                createTypeFromRef(node);

                // If an extension or restriction is present,
                // create a type for the reference
                Node re = SchemaUtils.getRestrictionOrExtensionNode(node);

                if ((re != null) && (Utils.getAttribute(re, "base") != null)) {
                    createTypeFromRef(re);
                }

                // Create a type representing an element.  (This may
                // seem like overkill, but is necessary to support ref=
                // and element=.
                createTypeFromDef(node, true, level > SCHEMA_LEVEL);
            } else if (isXSD && localPart.equals("attributeGroup")) {

                // bug 23145: support attributeGroup (Brook Richan)
                // Create a type entry for the referenced type
                createTypeFromRef(node);

                // Create a type representing an attributeGroup.
                createTypeFromDef(node, false, level > SCHEMA_LEVEL);
            }  else if (isXSD && localPart.equals("group")) {
                // Create a type entry for the referenced type
                createTypeFromRef(node);
                // Create a type representing an group
                createTypeFromDef(node, false, level > SCHEMA_LEVEL);
            } else if (isXSD && localPart.equals("attribute")) {

                // Create a type entry for the referenced type
                BooleanHolder forElement = new BooleanHolder();
                QName refQName = Utils.getTypeQName(node, forElement,
                        false);

                if ((refQName != null) && !forElement.value) {
                    createTypeFromRef(node);

                    // Get the symbol table entry and make sure it is a simple
                    // type
                    if (refQName != null) {
                        TypeEntry refType = getTypeEntry(refQName, false);

                        if ((refType != null)
                                && (refType instanceof Undefined)) {

                            // Don't know what the type is.
                            // It better be simple so set it as simple
                            refType.setSimpleType(true);
                        } else if ((refType == null)
                                || (!(refType instanceof BaseType)
                                && !refType.isSimpleType())) {

                            // Problem if not simple
                            throw new IOException(
                                    Messages.getMessage(
                                            "AttrNotSimpleType01",
                                            refQName.toString()));
                        }
                    }
                }
                createTypeFromDef(node, true, level > SCHEMA_LEVEL);
            } else if (isXSD && localPart.equals("any")) {

                // Map xsd:any element to special xsd:any "type"
                if (getType(Constants.XSD_ANY) == null) {
                    Type type = new BaseType(Constants.XSD_ANY);

                    symbolTablePut(type);
                }
            } else if (localPart.equals("part")
                    && Constants.isWSDL(node.getNamespaceURI())) {

                // This is a wsdl part.  Create an TypeEntry representing the reference
                createTypeFromRef(node);
            } else if (isXSD && localPart.equals("include")) {
                String includeName = Utils.getAttribute(node, "schemaLocation");

                if (includeName != null) {
                    URL url = getURL(context, includeName);
                    Document includeDoc = XMLUtils.newDocument(url.toString());

                    // Vidyanand : Fix for Bug #15124
                    org.w3c.dom.Element schemaEl =
                            includeDoc.getDocumentElement();

                    if (!schemaEl.hasAttribute("targetNamespace")) {
                        org.w3c.dom.Element parentSchemaEl =
                                (org.w3c.dom.Element) node.getParentNode();

                        if (parentSchemaEl.hasAttribute("targetNamespace")) {

                            // we need to set two things in here
                            // 1. targetNamespace
                            // 2. setup the xmlns=<targetNamespace> attribute
                            String tns =
                                    parentSchemaEl.getAttribute("targetNamespace");

                            schemaEl.setAttribute("targetNamespace", tns);
                            schemaEl.setAttribute("xmlns", tns);
                        }
                    }

                    populate(url, null, includeDoc, url.toString());
                }
            }
        }

        if (level == ABOVE_SCHEMA_LEVEL) {
            if ((localPart != null)
                && localPart.equals("schema")) {
                level = SCHEMA_LEVEL;
                String targetNamespace = ((org.w3c.dom.Element) node).getAttribute("targetNamespace");
                String elementFormDefault = ((org.w3c.dom.Element) node).getAttribute("elementFormDefault");
                if (targetNamespace != null && targetNamespace.length() > 0) {
                    elementFormDefault = (elementFormDefault == null || elementFormDefault.length() == 0) ?
                            "unqualified" : elementFormDefault;
                    if(elementFormDefaults.get(targetNamespace)==null) {
                        elementFormDefaults.put(targetNamespace, elementFormDefault);
                    }
                }
            }
        } else {
            ++level;
        }

        // Recurse through children nodes
        NodeList children = node.getChildNodes();

        for (int i = 0; i < children.getLength(); i++) {
            addTypes(context, children.item(i), level);
        }
    
private voidcheckForUndefined(javax.wsdl.Definition def, java.lang.String filename)
Scan the Definition for undefined objects and throw an error.

param
def
param
filename
throws
IOException


        if (def != null) {

            // Bindings
            Iterator ib = def.getBindings().values().iterator();

            while (ib.hasNext()) {
                Binding binding = (Binding) ib.next();

                if (binding.isUndefined()) {
                    if (filename == null) {
                        throw new IOException(
                                Messages.getMessage(
                                        "emitFailtUndefinedBinding01",
                                        binding.getQName().getLocalPart()));
                    } else {
                        throw new IOException(
                                Messages.getMessage(
                                        "emitFailtUndefinedBinding02",
                                        binding.getQName().getLocalPart(), filename));
                    }
                }
            }

            // portTypes
            Iterator ip = def.getPortTypes().values().iterator();

            while (ip.hasNext()) {
                PortType portType = (PortType) ip.next();

                if (portType.isUndefined()) {
                    if (filename == null) {
                        throw new IOException(
                                Messages.getMessage(
                                        "emitFailtUndefinedPort01",
                                        portType.getQName().getLocalPart()));
                    } else {
                        throw new IOException(
                                Messages.getMessage(
                                        "emitFailtUndefinedPort02",
                                        portType.getQName().getLocalPart(), filename));
                    }
                }
            }

            /*
             * tomj: This is a bad idea, faults seem to be undefined
             * / RJB reply:  this MUST be done for those systems that do something with
             * / messages.  Perhaps we have to do an extra step for faults?  I'll leave
             * / this commented for now, until someone uses this generator for something
             * / other than WSDL2Java.
             *           // Messages
             *           Iterator i = def.getMessages().values().iterator();
             *           while (i.hasNext()) {
             *               Message message = (Message) i.next();
             *               if (message.isUndefined()) {
             *                   throw new IOException(
             *                           Messages.getMessage("emitFailtUndefinedMessage01",
             *                                   message.getQName().getLocalPart()));
             *               }
             *           }
             */
        }
    
private voidcheckForUndefined()
Scan the symbol table for undefined types and throw an exception.

throws
IOException


        Iterator it = symbolTable.values().iterator();

        while (it.hasNext()) {
            Vector v = (Vector) it.next();

            for (int i = 0; i < v.size(); ++i) {
                SymTabEntry entry = (SymTabEntry) v.get(i);

                // Report undefined types
                if (entry instanceof UndefinedType) {
                    QName qn = entry.getQName();

                    // Special case dateTime/timeInstant that changed
                    // from version to version.
                    if ((qn.getLocalPart().equals(
                            "dateTime") && !qn.getNamespaceURI().equals(
                                    Constants.URI_2001_SCHEMA_XSD)) || (qn.getLocalPart().equals(
                                            "timeInstant") && qn.getNamespaceURI().equals(
                                                    Constants.URI_2001_SCHEMA_XSD))) {
                        throw new IOException(
                                Messages.getMessage(
                                        "wrongNamespace00", qn.getLocalPart(),
                                        qn.getNamespaceURI()));
                    }

                    // Check for a undefined XSD Schema Type and throw
                    // an unsupported message instead of undefined
                    if (SchemaUtils.isSimpleSchemaType(qn)) {
                        throw new IOException(
                                Messages.getMessage(
                                        "unsupportedSchemaType00", qn.getLocalPart()));
                    }

                    // last case, its some other undefined thing
                    throw new IOException(
                            Messages.getMessage(
                                    "undefined00", qn.toString()));
                }    // if undefined
                else if (entry instanceof UndefinedElement) {
                    throw new IOException(
                            Messages.getMessage(
                                    "undefinedElem00", entry.getQName().toString()));
                }
            }
        }
    
private voidcreateTypeFromDef(org.w3c.dom.Node node, boolean isElement, boolean belowSchemaLevel)
Create a TypeEntry from the indicated node, which defines a type that represents a complexType, simpleType or element (for ref=).

param
node
param
isElement
param
belowSchemaLevel
throws
IOException


        // Get the QName of the node's name attribute value
        QName qName = Utils.getNodeNameQName(node);

        if (qName != null) {

            // If the qname is already registered as a base type,
            // don't create a defining type/element.
            if (!isElement && (btm.getBaseName(qName) != null)) {
                return;
            }

            // If the node has a type or ref attribute, get the
            // qname representing the type
            BooleanHolder forElement = new BooleanHolder();
            QName refQName = Utils.getTypeQName(node, forElement,
                    false);

            if (refQName != null) {

                // Error check - bug 12362
                if (qName.getLocalPart().length() == 0) {
                    String name = Utils.getAttribute(node, "name");

                    if (name == null) {
                        name = "unknown";
                    }

                    throw new IOException(Messages.getMessage("emptyref00",
                            name));
                }

                // Now get the TypeEntry
                TypeEntry refType = getTypeEntry(refQName, forElement.value);

                if (!belowSchemaLevel) {
                    if (refType == null) {
                        throw new IOException(
                                Messages.getMessage(
                                        "absentRef00", refQName.toString(),
                                        qName.toString()));
                    }

                    symbolTablePut(new DefinedElement(qName, refType, node,
                            ""));
                }
            } else {

                // Flow to here indicates no type= or ref= attribute.
                // See if this is an array or simple type definition.
                IntHolder numDims = new IntHolder();
                BooleanHolder underlTypeNillable = new BooleanHolder();

                // If we're supposed to unwrap arrays, supply someplace to put the "inner" QName
                // so we can propagate it into the appropriate metadata container.
                QNameHolder itemQName = wrapArrays ? null : new QNameHolder();
                BooleanHolder forElement2 = new BooleanHolder();

                numDims.value = 0;

                QName arrayEQName = 
                        SchemaUtils.getArrayComponentQName(node,
                                                           numDims,
                                                           underlTypeNillable,
                                                           itemQName,
                                                           forElement2,
                                                           this);

                if (arrayEQName != null) {

                    // Get the TypeEntry for the array element type
                    refQName = arrayEQName;

                    TypeEntry refType = getTypeEntry(refQName, forElement2.value);

                    if (refType == null) {
//                        arrayTypeQNames.add(refQName);

                        // Not defined yet, add one
                        String baseName = btm.getBaseName(refQName);

                        if (baseName != null) {
                            refType = new BaseType(refQName);
                        } else if(forElement2.value) {
                            refType = new UndefinedElement(refQName);
                        } else {
                            refType = new UndefinedType(refQName);
                        }

                        symbolTablePut(refType);
                    }

                    // Create a defined type or element that references refType
                    String dims = "";

                    while (numDims.value > 0) {
                        dims += "[]";

                        numDims.value--;
                    }

                    TypeEntry defType = null;

                    if (isElement) {
                        if (!belowSchemaLevel) {
                            defType =
                               new DefinedElement(qName, refType, node, dims);
                            // Save component type for ArraySerializer
                            defType.setComponentType(arrayEQName);
                            if (itemQName != null)
                                defType.setItemQName(itemQName.value);
                        }
                    } else {
                        defType = new DefinedType(qName, refType, node, dims);
                        // Save component type for ArraySerializer
                        defType.setComponentType(arrayEQName);
                        defType.setUnderlTypeNillable(underlTypeNillable.value);
                        if (itemQName != null)
                            defType.setItemQName(itemQName.value);
                    }

                    if (defType != null) {
                        symbolTablePut(defType);
                    }
                } else {

                    // Create a TypeEntry representing this  type/element
                    String baseName = btm.getBaseName(qName);

                    if (baseName != null) {
                        symbolTablePut(new BaseType(qName));
                    } else {

                        // Create a type entry, set whether it should
                        // be mapped as a simple type, and put it in the
                        // symbol table.
                        TypeEntry te = null;
                        TypeEntry parentType = null;

                        if (!isElement) {
                            te = new DefinedType(qName, node);

                            // check if we are an anonymous type underneath
                            // an element.  If so, we point the refType of the
                            // element to us (the real type).
                            if (qName.getLocalPart().indexOf(ANON_TOKEN) >= 0) {
                                Node parent = node.getParentNode();
                                QName parentQName =
                                        Utils.getNodeNameQName(parent);
                                parentType = getElement(parentQName);
                            }
                        } else {
                            if (!belowSchemaLevel) {
                                te = new DefinedElement(qName, node);
                            }
                        }

                        if (te != null) {
                            if (SchemaUtils.isSimpleTypeOrSimpleContent(node)) {
                                te.setSimpleType(true);
                            }
                            te = (TypeEntry)symbolTablePut(te);

                            if (parentType != null) {
                                parentType.setRefType(te);
                            }
                        }
                    }
                }
            }
        }
    
protected voidcreateTypeFromRef(org.w3c.dom.Node node)
Node may contain a reference (via type=, ref=, or element= attributes) to another type. Create a Type object representing this referenced type.

param
node
throws
IOException


        // Get the QName of the node's type attribute value
        BooleanHolder forElement = new BooleanHolder();
        QName qName = Utils.getTypeQName(node, forElement, false);

        if (qName == null || (Constants.isSchemaXSD(qName.getNamespaceURI()) &&
                qName.getLocalPart().equals("simpleRestrictionModel"))) {
            return;
        }

        // Error check - bug 12362
        if (qName.getLocalPart().length() == 0) {
            String name = Utils.getAttribute(node, "name");

            if (name == null) {
                name = "unknown";
            }

            throw new IOException(Messages.getMessage("emptyref00", name));
        }

        // Get Type or Element depending on whether type attr was used.
        TypeEntry type = getTypeEntry(qName, forElement.value);

        // A symbol table entry is created if the TypeEntry is not found
        if (type == null) {

            // See if this is a special QName for collections
            if (qName.getLocalPart().indexOf("[") > 0) {
                QName containedQName = Utils.getTypeQName(node,
                        forElement, true);
                TypeEntry containedTE = getTypeEntry(containedQName,
                        forElement.value);

                if (!forElement.value) {

                    // Case of type and maxOccurs
                    if (containedTE == null) {

                        // Collection Element Type not defined yet, add one.
                        String baseName = btm.getBaseName(containedQName);

                        if (baseName != null) {
                            containedTE = new BaseType(containedQName);
                        } else {
                            containedTE = new UndefinedType(containedQName);
                        }

                        symbolTablePut(containedTE);
                    }
                    boolean wrapped = qName.getLocalPart().endsWith("wrapped");
                    symbolTablePut(new CollectionType(qName, containedTE,
                            node, "[]", wrapped));
                } else {

                    // Case of ref and maxOccurs
                    if (containedTE == null) {
                        containedTE = new UndefinedElement(containedQName);

                        symbolTablePut(containedTE);
                    }

                    symbolTablePut(new CollectionElement(qName,
                            containedTE, node,
                            "[]"));
                }
            } else {

                // Add a BaseType or Undefined Type/Element
                String baseName = btm.getBaseName(qName);

                if (baseName != null) {
                    symbolTablePut(new BaseType(qName));

                    // bugzilla 23145: handle attribute groups
                    // soap/encoding is treated as a "known" schema
                    // so now let's act like we know it
                } else if (qName.equals(Constants.SOAP_COMMON_ATTRS11)) {
                    symbolTablePut(new BaseType(qName));

                    // the 1.1 commonAttributes type contains two attributes
                    // make sure those attributes' types are in the symbol table
                    // attribute name = "id" type = "xsd:ID"
                    if (getTypeEntry(Constants.XSD_ID, false) == null) {
                        symbolTablePut(new BaseType(Constants.XSD_ID));
                    }

                    // attribute name = "href" type = "xsd:anyURI"
                    if (getTypeEntry(Constants.XSD_ANYURI, false) == null) {
                        symbolTablePut(new BaseType(Constants.XSD_ANYURI));
                    }
                } else if (qName.equals(Constants.SOAP_COMMON_ATTRS12)) {
                    symbolTablePut(new BaseType(qName));

                    // the 1.2 commonAttributes type contains one attribute
                    // make sure the attribute's type is in the symbol table
                    // attribute name = "id" type = "xsd:ID"
                    if (getTypeEntry(Constants.XSD_ID, false) == null) {
                        symbolTablePut(new BaseType(Constants.XSD_ID));
                    }
                } else if (qName.equals(Constants.SOAP_ARRAY_ATTRS11)) {
                    symbolTablePut(new BaseType(qName));

                    // the 1.1 arrayAttributes type contains two attributes
                    // make sure the attributes' types are in the symbol table
                    // attribute name = "arrayType" type = "xsd:string"
                    if (getTypeEntry(Constants.XSD_STRING, false) == null) {
                        symbolTablePut(new BaseType(Constants.XSD_STRING));
                    }

                    // attribute name = "offset" type = "soapenc:arrayCoordinate"
                    // which is really an xsd:string
                } else if (qName.equals(Constants.SOAP_ARRAY_ATTRS12)) {
                    symbolTablePut(new BaseType(qName));

                    // the 1.2 arrayAttributes type contains two attributes
                    // make sure the attributes' types are in the symbol table
                    // attribute name = "arraySize" type = "2003soapenc:arraySize"
                    // which is really a hairy beast that is not
                    // supported, yet; so let's just use string
                    if (getTypeEntry(Constants.XSD_STRING, false) == null) {
                        symbolTablePut(new BaseType(Constants.XSD_STRING));
                    }

                    // attribute name = "itemType" type = "xsd:QName"
                    if (getTypeEntry(Constants.XSD_QNAME, false) == null) {
                        symbolTablePut(new BaseType(Constants.XSD_QNAME));
                    }
                } else if (forElement.value == false) {
                    symbolTablePut(new UndefinedType(qName));
                } else {
                    symbolTablePut(new UndefinedElement(qName));
                }
            }
        }
    
public voiddump(java.io.PrintStream out)
Dump the contents of the symbol table. For debugging purposes only.

param
out


        out.println();
        out.println(Messages.getMessage("symbolTable00"));
        out.println("-----------------------");

        Iterator it = symbolTable.values().iterator();

        while (it.hasNext()) {
            Vector v = (Vector) it.next();

            for (int i = 0; i < v.size(); ++i) {
                out.println(v.elementAt(i).getClass().getName());
                out.println(v.elementAt(i));
            }
        }

        out.println("-----------------------");
    
protected voidensureOperationMessageValid(javax.wsdl.Message message)
ensures that a message in a <input>, <output>, or <fault> element in an <operation> element is valid. In particular, ensures that
  1. an attribute message is present (according to the XML Schema for WSDL 1.1 message is required

  2. the value of attribute message (a QName) refers to an already defined message

Note: this method should throw a javax.wsdl.WSDLException rather than a java.io.IOException

param
message the message object
throws
IOException thrown, if the message is not valid


        // make sure the message is not null (i.e. there is an
        // attribute 'message ')
        //
        if (message == null) {
            throw new IOException(
                    "<input>,<output>, or <fault> in <operation ..> without attribute 'message' found. Attribute 'message' is required.");
        }

        // make sure the value of the attribute refers to an
        // already defined message
        //
        if (message.isUndefined()) {
            throw new IOException(
                    "<input ..>, <output ..> or <fault ..> in <portType> with undefined message found. message name is '"
                    + message.getQName().toString() + "'");
        }
    
protected voidensureOperationValid(javax.wsdl.Operation operation)
ensures that an an element <operation> within an element <portType> is valid. Throws an exception if the operation is not valid.

Note: this method should throw a javax.wsdl.WSDLException rather than a java.io.IOException

param
operation the operation element
throws
IOException thrown, if the element is not valid.
throws
IllegalArgumentException thrown, if operation is null


        if (operation == null) {
            throw new IllegalArgumentException(
                    "parameter 'operation' must not be null");
        }

        Input input = operation.getInput();
        Message message;

        if (input != null) {
            message = input.getMessage();
            if (message == null) {
                throw new IOException(
                        "No 'message' attribute in <input> for operation '" +
                        operation.getName() + "'");
            }
            ensureOperationMessageValid(message);
        }

        Output output = operation.getOutput();

        if (output != null) {
            message = output.getMessage();
            if (message == null) {
                throw new IOException(
                        "No 'message' attribute in <output> for operation '" +
                        operation.getName() + "'");
            }
            ensureOperationMessageValid(output.getMessage());
        }

        Map faults = operation.getFaults();

        if (faults != null) {
            Iterator it = faults.values().iterator();

            while (it.hasNext()) {
                Fault fault = (Fault)it.next();
                message = fault.getMessage();
                if (message == null) {
                    throw new IOException(
                            "No 'message' attribute in <fault> named '" +
                            fault.getName() + "' for operation '" +
                            operation.getName() + "'");
                }
                ensureOperationMessageValid(message);
            }
        }
    
protected voidensureOperationsOfPortTypeValid(javax.wsdl.PortType portType)
ensures that an an element <portType> is valid. Throws an exception if the portType is not valid.

Note: this method should throw a javax.wsdl.WSDLException rather than a java.io.IOException

param
portType the portType element
throws
IOException thrown, if the element is not valid.
throws
IllegalArgumentException thrown, if operation is null


        if (portType == null) {
            throw new IllegalArgumentException(
                    "parameter 'portType' must not be null");
        }

        List operations = portType.getOperations();

        // no operations defined ? -> valid according to the WSDL 1.1 schema
        //
        if ((operations == null) || (operations.size() == 0)) {
            return;
        }

        // check operations defined in this portType
        //
        Iterator it = operations.iterator();

        while (it.hasNext()) {
            Operation operation = (Operation) it.next();

            ensureOperationValid(operation);
        }
    
protected booleanexistsPortWithName(javax.xml.namespace.QName name)
checks whether there exists a WSDL port with a given name in the current symbol table

param
name the QName of the port. Note: only the local part of the qname is relevant, since port names are not qualified with a namespace. They are of type nmtoken in WSDL 1.1 and of type ncname in WSDL 1.2
return
true, if there is a port element with the specified name; false, otherwise


        Vector v = (Vector) symbolTable.get(name);

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

        Iterator it = v.iterator();

        while (it.hasNext()) {
            Object o = it.next();

            if (o instanceof PortEntry) {
                return true;
            }
        }

        return false;
    
private voidfaultsFromSOAPFault(javax.wsdl.Binding binding, javax.wsdl.BindingOperation bindOp, javax.wsdl.Operation operation, java.util.ArrayList faults)
Get the faults from the soap:fault clause.

param
binding
param
bindOp
param
operation
param
faults
throws
IOException


        Iterator faultMapIter = bindOp.getBindingFaults().values().iterator();

        for (; faultMapIter.hasNext();) {
            BindingFault bFault = (BindingFault) faultMapIter.next();

            // Set default entry for this fault
            String faultName = bFault.getName();

            // Check to make sure this fault is named
            if ((faultName == null) || (faultName.length() == 0)) {
                throw new IOException(
                        Messages.getMessage(
                                "unNamedFault00", bindOp.getName(),
                                binding.getQName().toString()));
            }

            boolean foundSOAPFault = false;
            String soapFaultUse = "";
            String soapFaultNamespace = "";
            Iterator faultIter =
                    bFault.getExtensibilityElements().iterator();

            for (; faultIter.hasNext();) {
                Object obj = faultIter.next();

                if (obj instanceof SOAPFault) {
                    foundSOAPFault = true;
                    soapFaultUse = ((SOAPFault) obj).getUse();
                    soapFaultNamespace = ((SOAPFault) obj).getNamespaceURI();

                    break;
                } else if (obj instanceof UnknownExtensibilityElement) {

                    // TODO: After WSDL4J supports soap12, change this code
                    UnknownExtensibilityElement unkElement =
                            (UnknownExtensibilityElement) obj;
                    QName name =
                            unkElement.getElementType();

                    if (name.getNamespaceURI().equals(Constants.URI_WSDL12_SOAP)
                            && name.getLocalPart().equals("fault")) {
                        if (unkElement.getElement().getAttribute("use")
                                != null) {
                            soapFaultUse =
                                    unkElement.getElement().getAttribute("use");
                        }

                        if (unkElement.getElement().getAttribute("namespace")
                                != null) {
                            soapFaultNamespace =
                                    unkElement.getElement().getAttribute(
                                            "namespace");
                        }
                    }
                }
            }

            // Check to make sure we have a soap:fault element
            if (!foundSOAPFault) {
                throw new IOException(
                        Messages.getMessage(
                                "missingSoapFault00", faultName, bindOp.getName(),
                                binding.getQName().toString()));
            }

            // TODO error checking:
            // if use=literal, no use of namespace on the soap:fault
            // if use=encoded, no use of element on the part
            // Check this fault to make sure it matches the one
            // in the matching portType Operation
            Fault opFault = operation.getFault(bFault.getName());

            if (opFault == null) {
                throw new IOException(Messages.getMessage("noPortTypeFault",
                        new String[]{
                            bFault.getName(),
                            bindOp.getName(),
                            binding.getQName().toString()}));
            }

            // put the updated entry back in the map
            faults.add(new FaultInfo(opFault, Use.getUse(soapFaultUse),
                    soapFaultNamespace, this));
        }
    
private voidfillInBindingInfo(BindingEntry bEntry, javax.wsdl.Operation operation, java.util.Iterator it, java.util.ArrayList faults, boolean input)
Fill in some binding information: bodyType, mimeType, header info.

param
bEntry
param
operation
param
it
param
faults
param
input
throws
IOException


        for (; it.hasNext();) {
            Object obj = it.next();

            if (obj instanceof SOAPBody) {
                setBodyType(((SOAPBody) obj).getUse(), bEntry, operation,
                        input);
            } else if (obj instanceof SOAPHeader) {
                SOAPHeader header = (SOAPHeader) obj;

                setBodyType(header.getUse(), bEntry, operation, input);

                // Note, this only works for explicit headers - those whose
                // parts come from messages used in the portType's operation
                // input/output clauses - it does not work for implicit
                // headers - those whose parts come from messages not used in
                // the portType's operation's input/output clauses.  I don't
                // know what we're supposed to emit for implicit headers.
                bEntry.setHeaderPart(operation.getName(), header.getPart(),
                        input
                        ? BindingEntry.IN_HEADER
                        : BindingEntry.OUT_HEADER);

                // Add any soap:headerFault info to the faults array
                Iterator headerFaults = header.getSOAPHeaderFaults().iterator();

                while (headerFaults.hasNext()) {
                    SOAPHeaderFault headerFault =
                            (SOAPHeaderFault) headerFaults.next();

                    faults.add(new FaultInfo(headerFault, this));
                }
            } else if (obj instanceof MIMEMultipartRelated) {
                bEntry.setBodyType(
                        operation,
                        addMIMETypes(
                                bEntry, (MIMEMultipartRelated) obj, operation), input);
            } else if (obj instanceof UnknownExtensibilityElement) {
                UnknownExtensibilityElement unkElement =
                        (UnknownExtensibilityElement) obj;
                QName name =
                        unkElement.getElementType();

                if (name.getNamespaceURI().equals(Constants.URI_DIME_WSDL)
                        && name.getLocalPart().equals("message")) {
                    fillInDIMEInformation(unkElement, input, operation, bEntry);
                }

                // TODO: After WSDL4J supports soap12, change this code
                if (name.getNamespaceURI().equals(Constants.URI_WSDL12_SOAP)
                        && name.getLocalPart().equals("body")) {
                    setBodyType(unkElement.getElement().getAttribute("use"),
                            bEntry, operation, input);
                }

                // TODO: After WSDL4J supports soap12, change this code
                if (name.getNamespaceURI().equals(Constants.URI_WSDL12_SOAP)
                        && name.getLocalPart().equals("header")) {
                    setBodyType(unkElement.getElement().getAttribute("use"),
                            bEntry, operation, input);

                    // Note, this only works for explicit headers - those whose
                    // parts come from messages used in the portType's operation
                    // input/output clauses - it does not work for implicit
                    // headers - those whose parts come from messages not used in
                    // the portType's operation's input/output clauses.  I don't
                    // know what we're supposed to emit for implicit headers.
                    bEntry.setHeaderPart(
                            operation.getName(),
                            unkElement.getElement().getAttribute("part"), input
                            ? BindingEntry.IN_HEADER
                            : BindingEntry.OUT_HEADER);

                    // Add any soap12:headerFault info to the faults array
                    NodeList headerFaults =
                            unkElement.getElement().getChildNodes();

                    for (int i = 0; i < headerFaults.getLength(); i++) {
                        String faultMessage =
                                unkElement.getElement().getAttribute("message");
                        String faultPart =
                                unkElement.getElement().getAttribute("part");
                        String faultUse =
                                unkElement.getElement().getAttribute("use");
                        String faultNamespaceURI =
                                unkElement.getElement().getAttribute("namespace");
                        QName faultMessageQName = null;
                        int sep = faultMessage.indexOf(':");

                        if (sep == -1) {
                            faultMessageQName = new QName(faultMessage);
                        } else {
                            faultMessageQName =
                                    new QName(faultMessage.substring(0, sep),
                                            faultMessage.substring(sep + 1));
                        }

                        faults.add(new FaultInfo(faultMessageQName, faultPart,
                                faultUse, faultNamespaceURI,
                                this));
                    }
                }
            }
        }
    
private voidfillInDIMEInformation(javax.wsdl.extensions.UnknownExtensibilityElement unkElement, boolean input, javax.wsdl.Operation operation, BindingEntry bEntry)
Fill in DIME information

param
unkElement
param
input
param
operation
param
bEntry


        String layout = unkElement.getElement().getAttribute("layout");

        // TODO: what to do with layout info?
        if (layout.equals(Constants.URI_DIME_CLOSED_LAYOUT)) {
        } else if (layout.equals(Constants.URI_DIME_OPEN_LAYOUT)) {
        }

        Map parts = null;

        if (input) {
            parts = operation.getInput().getMessage().getParts();
        } else {
            parts = operation.getOutput().getMessage().getParts();
        }

        if (parts != null) {
            Iterator iterator = parts.values().iterator();

            while (iterator.hasNext()) {
                Part part = (Part) iterator.next();

                if (part != null) {
                    String dims = "";
                    org.w3c.dom.Element element = null;

                    if (part.getTypeName() != null) {
                        TypeEntry partType = getType(part.getTypeName());

                        if (partType.getDimensions().length() > 0) {
                            dims = partType.getDimensions();
                            partType = partType.getRefType();
                        }

                        element = (org.w3c.dom.Element) partType.getNode();
                    } else if (part.getElementName() != null) {
                        TypeEntry partElement =
                                getElement(part.getElementName()).getRefType();

                        element = (org.w3c.dom.Element) partElement.getNode();

                        QName name = getInnerCollectionComponentQName(element);

                        if (name != null) {
                            dims += "[]";
                            partElement = getType(name);
                            element =
                                    (org.w3c.dom.Element) partElement.getNode();
                        } else {
                            name = getInnerTypeQName(element);

                            if (name != null) {
                                partElement = getType(name);
                                element =
                                        (org.w3c.dom.Element) partElement.getNode();
                            }
                        }
                    }

                    if (element != null) {
                        org.w3c.dom.Element e =
                                (org.w3c.dom.Element) XMLUtils.findNode(
                                        element,
                                        new QName(
                                                Constants.URI_DIME_CONTENT, "mediaType"));

                        if (e != null) {
                            String value = e.getAttribute("value");

                            bEntry.setOperationDIME(operation.getName());
                            bEntry.setMIMEInfo(operation.getName(),
                                    part.getName(), value, dims);
                        }
                    }
                }
            }
        }
    
private voidfillParamInfo(Parameter param, BindingEntry bindingEntry, java.lang.String opName, java.lang.String partName)
Set the header information for this paramter

param
param Parameter to modify
param
bindingEntry Binding info for this operation/parameter
param
opName the operation we are processing
param
partName the part we are processing


        // If we don't have a binding, can't do anything
        if (bindingEntry == null)
            return;

        setMIMEInfo(param, bindingEntry.getMIMEInfo(opName, partName));

        boolean isHeader = false;

        // Is this parameter in an Input header?
        if (bindingEntry.isInHeaderPart(opName, partName)) {
            isHeader = true;
            param.setInHeader(true);
        }

        // Is this parameter in an Output header?
        if (bindingEntry.isOutHeaderPart(opName, partName)) {
            isHeader = true;
            param.setOutHeader(true);
        }

        // If this parameter is part of a header, find the binding operation
        // that we are processing and get the QName of the parameter.
        if (isHeader && (bindingEntry.getBinding() != null)) {
            List list = bindingEntry.getBinding().getBindingOperations();

            for (int i = 0; (list != null) && (i < list.size()); i++) {
                BindingOperation operation = (BindingOperation) list.get(i);

                if (operation.getName().equals(opName)) {
                    if (param.isInHeader()) {
                        QName qName = getBindedParameterName(
                                operation.getBindingInput().getExtensibilityElements(),
                                param);

                        if(qName!= null) {
                            param.setQName(qName);
                        }
                    } else if (param.isOutHeader()) {
                        QName qName = getBindedParameterName(
                                operation.getBindingOutput().getExtensibilityElements(),
                                param);

                        if(qName!= null) {
                            param.setQName(qName);
                        }
                    }
                }
            }
        }
    
private TypeEntryfindPart(javax.wsdl.Operation operation, java.lang.String partName)
Method findPart

param
operation
param
partName
return


        Map parts = operation.getInput().getMessage().getParts();
        Iterator iterator = parts.values().iterator();
        TypeEntry part = findPart(iterator, partName);

        if (part == null) {
            parts = operation.getOutput().getMessage().getParts();
            iterator = parts.values().iterator();
            part = findPart(iterator, partName);
        }

        return part;
    
private TypeEntryfindPart(java.util.Iterator iterator, java.lang.String partName)
Method findPart

param
iterator
param
partName
return


        while (iterator.hasNext()) {
            Part part = (Part) iterator.next();

            if (part != null) {
                String typeName = part.getName();

                if (partName.equals(typeName)) {
                    if (part.getTypeName() != null) {
                        return getType(part.getTypeName());
                    } else if (part.getElementName() != null) {
                        return getElement(part.getElementName());
                    }
                }
            }
        }

        return null;
    
public SymTabEntryget(javax.xml.namespace.QName qname, java.lang.Class cls)
Get the entry with the given QName of the given class. If it does not exist, return null.

param
qname
param
cls
return


        Vector v = (Vector) symbolTable.get(qname);

        if (v == null) {
            return null;
        } else {
            for (int i = 0; i < v.size(); ++i) {
                SymTabEntry entry = (SymTabEntry) v.elementAt(i);

                if (cls.isInstance(entry)) {
                    return entry;
                }
            }

            return null;
        }
    
private javax.xml.namespace.QNamegetBindedParameterName(java.util.List elements, Parameter p)
Method getBindedParameterName

param
elements
param
p
return


        // If the parameter can either be in the message header or in the
        // message body.
        // When it is in the header, there may be a SOAPHeader (soap:header)
        // with its part name. The namespace used is the one of the soap:header.
        // When it is in the body, if there is a SOAPBody with its part name,
        // the namespace used is the one of this soap:body.
        //
        // If the parameter is in the body and there is a soap:body with no parts,
        // its namespace is used for the parameter.
        QName paramName = null;
        String defaultNamespace = null;
        String parameterPartName = p.getName();

        for (Iterator k = elements.iterator(); k.hasNext();) {
            ExtensibilityElement element = (ExtensibilityElement) k.next();

            if (element instanceof SOAPBody) {
                SOAPBody bodyElement = (SOAPBody) element;
                List parts = bodyElement.getParts();

                if ((parts == null) || (parts.size() == 0)) {
                    defaultNamespace = bodyElement.getNamespaceURI();
                } else {
                    boolean found = false;

                    for (Iterator l = parts.iterator(); l.hasNext();) {
                        Object o = l.next();

                        if(o instanceof String) {
                            if (parameterPartName.equals((String)o)) {
                                paramName =
                                        new QName(bodyElement.getNamespaceURI(),
                                                parameterPartName);
                                found = true;
                                break;
                            }
                        }
                    }

                    if (found) {
                        break;
                    }
                }
            } else if (element instanceof SOAPHeader) {
                SOAPHeader headerElement = (SOAPHeader) element;
                String part = headerElement.getPart();

                if (parameterPartName.equals(part)) {
                    paramName = new QName(headerElement.getNamespaceURI(),
                            parameterPartName);
                    break;
                }
            }
        }

        if ((paramName == null) && (!p.isInHeader()) && (!p.isOutHeader())) {
            if (defaultNamespace != null) {
                paramName = new QName(defaultNamespace, parameterPartName);
            } else {
                paramName = p.getQName();
            }
        }

        return paramName;
    
public BindingEntrygetBindingEntry(javax.xml.namespace.QName qname)
Get the BindingEntry with the given QName. If it doesn't exist, return null.

param
qname
return

        return (BindingEntry) get(qname, BindingEntry.class);
    
public javax.wsdl.DefinitiongetDefinition()
Get the Definition. The definition is null until populate is called.

return

        return def;
    
public ElementgetElement(javax.xml.namespace.QName qname)
Get the Element TypeEntry with the given QName. If it doesn't exist, return null.

param
qname
return

        return (Element) elementTypeEntries.get(qname);
    
public java.util.MapgetElementFormDefaults()

        return elementFormDefaults;
    
public java.util.MapgetElementIndex()
Return an unmodifiable map of qnames -> Elements in the symbol table.

return
an unmodifiable Map value

        return elementIndex;
    
private static java.net.URLgetFileURL(java.net.URL contextURL, java.lang.String path)
Method getFileURL

param
contextURL
param
path
return
throws
IOException


        if (contextURL != null) {

            // get the parent directory of the contextURL, and append
            // the spec string to the end.
            String contextFileName = contextURL.getFile();
            URL parent = null;
            File parentFile = new File(contextFileName).getParentFile(); 
            if ( parentFile != null ) {
                parent = parentFile.toURL(); 
            }
            if (parent != null) {
                return new URL(parent, path);
            }
        }

        return new URL("file", "", path);
    
public java.util.HashMapgetHashMap()
Get the raw symbol table HashMap.

return

        return symbolTable;
    
private javax.xml.namespace.QNamegetInnerCollectionComponentQName(org.w3c.dom.Node node)
Method getInnerCollectionComponentQName

param
node
return


        if (node == null) {
            return null;
        }

        QName name = SchemaUtils.getCollectionComponentQName(node, new QNameHolder(), new BooleanHolder(), this);

        if (name != null) {
            return name;
        }

        // Dive into the node if necessary
        NodeList children = node.getChildNodes();

        for (int i = 0; i < children.getLength(); i++) {
            name = getInnerCollectionComponentQName(children.item(i));

            if (name != null) {
                return name;
            }
        }

        return null;
    
private static javax.xml.namespace.QNamegetInnerTypeQName(org.w3c.dom.Node node)
Method getInnerTypeQName

param
node
return


        if (node == null) {
            return null;
        }

        BooleanHolder forElement = new BooleanHolder();
        QName name = Utils.getTypeQName(node, forElement, true);

        if (name != null) {
            return name;
        }

        // Dive into the node if necessary
        NodeList children = node.getChildNodes();

        for (int i = 0; i < children.getLength(); i++) {
            name = getInnerTypeQName(children.item(i));

            if (name != null) {
                return name;
            }
        }

        return null;
    
public java.util.ListgetMessageEntries()

        List messageEntries = new ArrayList();
        Iterator iter = symbolTable.values().iterator();
        while (iter.hasNext()) {
            Vector v = (Vector)iter.next();
            for (int i = 0; i < v.size(); ++i) {
                SymTabEntry entry = (SymTabEntry)v.elementAt(i);
                if (entry instanceof MessageEntry) {
                    messageEntries.add(entry);
                }
            }
        }

        return messageEntries;
    
public MessageEntrygetMessageEntry(javax.xml.namespace.QName qname)
Get the MessageEntry with the given QName. If it doesn't exist, return null.

param
qname
return

        return (MessageEntry) get(qname, MessageEntry.class);
    
public ParametersgetOperationParameters(javax.wsdl.Operation operation, java.lang.String namespace, BindingEntry bindingEntry)
For the given operation, this method returns the parameter info conveniently collated. There is a bit of processing that is needed to write the interface, stub, and skeleton. Rather than do that processing 3 times, it is done once, here, and stored in the Parameters object.

param
operation
param
namespace
param
bindingEntry
return
throws
IOException


        Parameters parameters = new Parameters();

        // The input and output Vectors of Parameters
        Vector inputs = new Vector();
        Vector outputs = new Vector();
        List parameterOrder = operation.getParameterOrdering();

        // Handle parameterOrder="", which is techinically illegal
        if ((parameterOrder != null) && parameterOrder.isEmpty()) {
            parameterOrder = null;
        }

        Input input = operation.getInput();
        Output output = operation.getOutput();

        parameters.mep = operation.getStyle();

        // All input parts MUST be in the parameterOrder list.  It is an error otherwise.
        if (parameterOrder != null && !wrapped) {
            if (input != null) {
                Message inputMsg = input.getMessage();
                Map allInputs = inputMsg.getParts();
                Collection orderedInputs =
                        inputMsg.getOrderedParts(parameterOrder);

                if (allInputs.size() != orderedInputs.size()) {
                    throw new IOException(
                            Messages.getMessage("emitFail00", operation.getName()));
                }
            }
        }

        boolean literalInput = false;
        boolean literalOutput = false;

        if (bindingEntry != null) {
            literalInput = (bindingEntry.getInputBodyType(operation)
                    == Use.LITERAL);
            literalOutput = (bindingEntry.getOutputBodyType(operation)
                    == Use.LITERAL);
        }

        // Collect all the input parameters
        if ((input != null) && (input.getMessage() != null)) {
            getParametersFromParts(inputs,
                    input.getMessage().getOrderedParts(null),
                    literalInput, operation.getName(),
                    bindingEntry);
        }

        // Collect all the output parameters
        if ((output != null) && (output.getMessage() != null)) {
            getParametersFromParts(outputs,
                    output.getMessage().getOrderedParts(null),
                    literalOutput, operation.getName(),
                    bindingEntry);
        }

        if (parameterOrder != null && !wrapped) {

            // Construct a list of the parameters in the parameterOrder list, determining the
            // mode of each parameter and preserving the parameterOrder list.
            for (int i = 0; i < parameterOrder.size(); ++i) {
                String name = (String) parameterOrder.get(i);

                // index in the inputs Vector of the given name, -1 if it doesn't exist.
                int index = getPartIndex(name, inputs);

                // index in the outputs Vector of the given name, -1 if it doesn't exist.
                int outdex = getPartIndex(name, outputs);

                if (index >= 0) {

                    // The mode of this parameter is either in or inout
                    addInishParm(inputs, outputs, index, outdex, parameters,
                            true);
                } else if (outdex >= 0) {
                    addOutParm(outputs, outdex, parameters, true);
                } else {
                    System.err.println(Messages.getMessage("noPart00", name));
                }
            }
        }

        // Some special case logic for JAX-RPC, but also to make things
        // nicer for the user.
        // If we have a single input and output with the same name
        // instead of: void echo(StringHolder inout)
        // Do this:  string echo(string in)
        if (wrapped && (inputs.size() == 1) && (outputs.size() == 1)
                &&
                Utils.getLastLocalPart(((Parameter) inputs.get(0)).getName()).equals(
                Utils.getLastLocalPart(((Parameter) outputs.get(0)).getName()))
                ) {

            // add the input and make sure its a IN not an INOUT
            addInishParm(inputs, null, 0, -1, parameters, false);
        } else {

            // Get the mode info about those parts that aren't in the
            // parameterOrder list. Since they're not in the parameterOrder list,
            // the order is, first all in (and inout) parameters, then all out
            // parameters, in the order they appear in the messages.
            for (int i = 0; i < inputs.size(); i++) {
                Parameter p = (Parameter) inputs.get(i);
                int outdex = getPartIndex(p.getName(), outputs);

                addInishParm(inputs, outputs, i, outdex, parameters, false);
            }
        }

        // Now that the remaining in and inout parameters are collected,
        // determine the status of outputs.  If there is only 1, then it
        // is the return value.  If there are more than 1, then they are
        // out parameters.
        if (outputs.size() == 1) {
            parameters.returnParam = (Parameter) outputs.get(0);

            parameters.returnParam.setMode(Parameter.OUT);

            if (parameters.returnParam.getType() instanceof DefinedElement) {
                parameters.returnParam.setQName(
                        parameters.returnParam.getType().getQName());
            }

            ++parameters.outputs;
        } else {
            for (int i = 0; i < outputs.size(); i++) {
                addOutParm(outputs, i, parameters, false);
            }
        }

        parameters.faults = operation.getFaults();

        // before we return the paramters,
        // make sure we dont have a duplicate name
        Vector used = new Vector(parameters.list.size());
        Iterator i = parameters.list.iterator();

        while (i.hasNext()) {
            Parameter parameter = (Parameter) i.next();
            int count = 2;

            while (used.contains(parameter.getName())) {

                // duplicate, add a suffix and try again
                parameter.setName(parameter.getName()
                        + Integer.toString(count++));
            }

            used.add(parameter.getName());
        }

        return parameters;
    
public voidgetParametersFromParts(java.util.Vector v, java.util.Collection parts, boolean literal, java.lang.String opName, BindingEntry bindingEntry)
This method returns a vector containing Parameters which represent each Part (shouldn't we call these "Parts" or something?) This routine does the wrapped doc/lit processing. It is also used for generating Faults, and this really confuses things but we need to do the same processing for the fault messages. This whole method is waaaay too complex. It needs rewriting (for instance, we sometimes new up a Parameter, then ignore it in favor of another we new up.)

param
v The output vector of parameters
param
parts The parts of the message
param
literal Are we in a literal operation (or fault)?
param
opName The operation (or fault) name
param
bindingEntry The binding for this operation - can be NULL if we are looking at a fault
throws
IOException when encountering an error in the WSDL


        // Determine if there's only one element.  For wrapped
        // style, we normally only have 1 part which is an
        // element.  But with MIME we could have any number of
        // types along with that single element.  As long as
        // there's only ONE element, and it's the same name as
        // the operation, we can unwrap it.
        int numberOfElements = 0;
        boolean possiblyWrapped = false;
        Iterator i = parts.iterator();

        while (i.hasNext()) {
            Part part = (Part) i.next();

            if (part.getElementName() != null) {
                ++numberOfElements;

                if (part.getElementName().getLocalPart().equals(opName)) {
                    possiblyWrapped = true;
                }
            }
        }

        // Try to sense "wrapped" document literal mode
        // if we haven't been told not to.
        // Criteria:
        // - If there is a single element part,
        // - That part is an element
        // - That element has the same name as the operation
        // - That element has no attributes (check done below)

        if (!nowrap && literal && (numberOfElements == 1) && possiblyWrapped) {
            wrapped = true;
        }

        i = parts.iterator();

        while (i.hasNext()) {
            Parameter param = new Parameter();
            Part part = (Part) i.next();
            QName elementName = part.getElementName();
            QName typeName = part.getTypeName();
            String partName = part.getName();

            // if we are either:
            //   1. encoded
            //   2. literal & not wrapped.
            if (!literal || !wrapped || (elementName == null)) {
                param.setName(partName);

                // Add this type or element name
                if (typeName != null) {
                    param.setType(getType(typeName));
                } else if (elementName != null) {

                    // Just an FYI: The WSDL spec says that for use=encoded
                    // that parts reference an abstract type using the type attr
                    // but we kinda do the right thing here, so let it go.
                    // if (!literal)
                    // error...
                    param.setType(getElement(elementName));
                } else {

                    // no type or element
                    throw new IOException(
                            Messages.getMessage(
                                    "noTypeOrElement00", new String[]{partName,
                                                                      opName}));
                }

                fillParamInfo(param, bindingEntry, opName, partName);
                v.add(param);

                continue;    // next part
            }

            // flow to here means wrapped literal !
            // See if we can map all the XML types to java(?) types
            // if we can, we use these as the types
            Node node = null;
            TypeEntry typeEntry = null;

            if ((typeName != null)
                    && (bindingEntry == null || bindingEntry.getMIMETypes().size() == 0)) {

                // Since we can't (yet?) make the Axis engine generate the right
                // XML for literal parts that specify the type attribute,
                // (unless they're MIME types) abort processing with an
                // error if we encounter this case
                //
                // node = getTypeEntry(typeName, false).getNode();
                String bindingName = (bindingEntry == null)
                        ? "unknown"
                        : bindingEntry.getBinding().getQName().toString();

                throw new IOException(Messages.getMessage("literalTypePart00",
                        new String[]{
                            partName,
                            opName,
                            bindingName}));
            }

            // Get the node which corresponds to the type entry for this
            // element.  i.e.:
            // <part name="part" element="foo:bar"/>
            // ...
            // <schema targetNamespace="foo">
            // <element name="bar"...>  <--- This one
            typeEntry = getTypeEntry(elementName, true);
            node = typeEntry.getNode();

            // Check if this element is of the form:
            // <element name="foo" type="tns:foo_type"/>
            BooleanHolder forElement = new BooleanHolder();
            QName type = Utils.getTypeQName(node, forElement,
                    false);
            if ((type != null) && !forElement.value) {

                // If in fact we have such a type, go get the node that
                // corresponds to THAT definition.
                typeEntry = getTypeEntry(type, false);
                node = typeEntry.getNode();
            }

            Vector vTypes = null;

            // If we have nothing at this point, we're in trouble.
            if (node == null) {
              // If node is null, that means the element in question has no type declaration,
              // therefore is not a wrapper element.
              wrapped = false;
                if (verbose) {
                    System.out.println(Messages.getMessage("cannotDoWrappedMode00", elementName.toString()));
                }
            } else {

                // check for attributes
                if (typeEntry.getContainedAttributes() != null) {
                    // can't do wrapped mode
                    wrapped = false;
                }

                if (!SchemaUtils.isWrappedType(node)) {
                    // mark the type entry as not just literal referenced
                    // This doesn't work, but it may help in the future.
                    // The problem is "wrapped" is a symbol table wide flag,
                    // which means if one operation breaks the rules
                    // implemented in isWrappedType(), then everything goes bad
                    // For example, see bug Axis-1900.
                    typeEntry.setOnlyLiteralReference(false);
                    wrapped = false;
                }

                // Get the nested type entries.
                // TODO - If we are unable to represent any of the types in the
                // element, we need to use SOAPElement/SOAPBodyElement.
                // I don't believe getContainedElementDecl does the right thing yet.
                vTypes = typeEntry.getContainedElements();
            }

            // IF we got the type entries and we didn't find attributes
            // THEN use the things in this element as the parameters
            if ((vTypes != null) && wrapped) {

                // add the elements in this list
                for (int j = 0; j < vTypes.size(); j++) {
                    ElementDecl elem = (ElementDecl) vTypes.elementAt(j);
                    Parameter p = new Parameter();

                    p.setQName(elem.getQName());
                    // If the parameter is a anonymous complex type, the parameter
                    // name should just be the name of the element, not >foo>element
                    String paramName = p.getName();
                    final int gt = paramName.lastIndexOf(ANON_TOKEN);
                    if (gt != 1) {
                        paramName = paramName.substring(gt+1);
                    }
                    p.setName(paramName);
                    p.setType(elem.getType());
                    p.setOmittable(elem.getMinOccursIs0());
                    p.setNillable(elem.getNillable());
                    fillParamInfo(p, bindingEntry, opName, partName);
                    v.add(p);
                }
            } else {

                // - we were unable to get the types OR
                // - we found attributes
                // so we can't use wrapped mode.
                param.setName(partName);

                if (typeName != null) {
                    param.setType(getType(typeName));
                } else if (elementName != null) {
                    param.setType(getElement(elementName));
                }

                fillParamInfo(param, bindingEntry, opName, partName);
                v.add(param);
            }
        }                    // while
    
private intgetPartIndex(java.lang.String name, java.util.Vector v)
Return the index of the given name in the given Vector, -1 if it doesn't exist.

param
name
param
v
return

        name = Utils.getLastLocalPart(name);
        for (int i = 0; i < v.size(); i++) {
            String paramName = ((Parameter) v.get(i)).getName();
            paramName = Utils.getLastLocalPart(paramName);
            if (name.equals(paramName)) {
                return i;
            }
        }

        return -1;
    
public PortTypeEntrygetPortTypeEntry(javax.xml.namespace.QName qname)
Get the PortTypeEntry with the given QName. If it doesn't exist, return null.

param
qname
return

        return (PortTypeEntry) get(qname, PortTypeEntry.class);
    
public ServiceEntrygetServiceEntry(javax.xml.namespace.QName qname)
Get the ServiceEntry with the given QName. If it doesn't exist, return null.

param
qname
return

        return (ServiceEntry) get(qname, ServiceEntry.class);
    
public java.util.VectorgetSymbols(javax.xml.namespace.QName qname)
Get the list of entries with the given QName. Since symbols can share QNames, this list is necessary. This list will not contain any more than one element of any given SymTabEntry.

param
qname
return

        return (Vector) symbolTable.get(qname);
    
public TypegetType(javax.xml.namespace.QName qname)
Get the Type TypeEntry with the given QName. If it doesn't exist, return null.

param
qname
return

        return (Type) typeTypeEntries.get(qname);
    
public TypeEntrygetTypeEntry(javax.xml.namespace.QName qname, boolean wantElementType)
Get the type entry for the given qname.

param
qname
param
wantElementType boolean that indicates type or element (for type= or ref=)
return


        if (wantElementType) {
            return getElement(qname);
        } else {
            return getType(qname);
        }
    
public intgetTypeEntryCount()
Return the count of TypeEntries in the symbol table.

return
an int value

        return elementTypeEntries.size() + typeTypeEntries.size();
    
public java.util.MapgetTypeIndex()
Return an unmodifiable map of qnames -> Elements in the symbol table.

return
an unmodifiable Map value

        return typeIndex;
    
public java.util.VectorgetTypes()
Get the list of all the XML schema types in the symbol table. In other words, all entries that are instances of TypeEntry.

return
deprecated
use specialized get{Element,Type}Index() methods instead


        Vector v = new Vector();

        v.addAll(elementTypeEntries.values());
        v.addAll(typeTypeEntries.values());

        return v;
    
private static java.net.URLgetURL(java.net.URL contextURL, java.lang.String spec)
This is essentially a call to "new URL(contextURL, spec)" with extra handling in case spec is a file.

param
contextURL
param
spec
return
throws
IOException


        // First, fix the slashes as windows filenames may have backslashes
        // in them, but the URL class wont do the right thing when we later
        // process this URL as the contextURL.
        String path = spec.replace('\\", '/");

        // See if we have a good URL.
        URL url = null;

        try {

            // first, try to treat spec as a full URL
            url = new URL(contextURL, path);

            // if we are deail with files in both cases, create a url
            // by using the directory of the context URL.
            if ((contextURL != null) && url.getProtocol().equals("file")
                    && contextURL.getProtocol().equals("file")) {
                url = getFileURL(contextURL, path);
            }
        } catch (MalformedURLException me) {

            // try treating is as a file pathname
            url = getFileURL(contextURL, path);
        }

        // Everything is OK with this URL, although a file url constructed
        // above may not exist.  This will be caught later when the URL is
        // accessed.
        return url;
    
public java.lang.StringgetWSDLURI()
Get the WSDL URI. The WSDL URI is null until populate is called, and ONLY if a WSDL URI is provided.

return

        return wsdlURI;
    
public booleanisKnownNamespace(java.lang.String namespace)
Check if this is a known namespace (soap-enc or schema xsd or schema xsi or xml)

param
namespace
return
true if this is a know namespace.


        if (Constants.isSOAP_ENC(namespace)) {
            return true;
        }

        if (Constants.isSchemaXSD(namespace)) {
            return true;
        }

        if (Constants.isSchemaXSI(namespace)) {
            return true;
        }

        if (namespace.equals(Constants.NS_URI_XML)) {
            return true;
        }

        return false;
    
public booleanisQuiet()
Method isQuiet

return

        return quiet;
    
public booleanisWrapped()
Are we wrapping literal soap body elements.

return

        return wrapped;
    
private voidlookForImports(java.net.URL context, org.w3c.dom.Node node)
Recursively find all xsd:import'ed objects and call populate for each one.

param
context
param
node
throws
IOException
throws
ParserConfigurationException
throws
SAXException
throws
WSDLException


        NodeList children = node.getChildNodes();

        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);

            if ("import".equals(child.getLocalName())) {
                NamedNodeMap attributes = child.getAttributes();
                Node namespace = attributes.getNamedItem("namespace");

                // skip XSD import of soap encoding
                if ((namespace != null)
                        && isKnownNamespace(namespace.getNodeValue())) {
                    continue;
                }

                Node importFile = attributes.getNamedItem("schemaLocation");

                if (importFile != null) {
                    URL url = getURL(context, importFile.getNodeValue());

                    if (!importedFiles.contains(url)) {
                        importedFiles.add(url);

                        String filename = url.toString();

                        populate(url, null, XMLUtils.newDocument(filename),
                                filename);
                    }
                }
            }

            lookForImports(context, child);
        }
    
public voidpopulate(java.lang.String uri)
Call this method if you have a uri for the WSDL document

param
uri wsdlURI the location of the WSDL file.
throws
IOException
throws
WSDLException
throws
SAXException
throws
ParserConfigurationException

        populate(uri, null, null);
    
public voidpopulate(java.lang.String uri, java.lang.String username, java.lang.String password)
Method populate

param
uri
param
username
param
password
throws
IOException
throws
WSDLException
throws
SAXException
throws
ParserConfigurationException


        if (verbose) {
            System.out.println(Messages.getMessage("parsing00", uri));
        }

        Document doc = XMLUtils.newDocument(uri, username, password);

        this.wsdlURI = uri;

        try {
            File f = new File(uri);

            if (f.exists()) {
                uri = f.toURL().toString();
            }
        } catch (Exception e) {
        }

        populate(uri, doc);
    
public voidpopulate(java.lang.String context, org.w3c.dom.Document doc)
Call this method if your WSDL document has already been parsed as an XML DOM document.

param
context context This is directory context for the Document. If the Document were from file "/x/y/z.wsdl" then the context could be "/x/y" (even "/x/y/z.wsdl" would work). If context is null, then the context becomes the current directory.
param
doc doc This is the XML Document containing the WSDL.
throws
IOException
throws
SAXException
throws
WSDLException
throws
ParserConfigurationException


        WSDLReader reader = WSDLFactory.newInstance().newWSDLReader();

        reader.setFeature("javax.wsdl.verbose", verbose);

        this.def = reader.readWSDL(context, doc);

        add(context, def, doc);
    
private voidpopulate(java.net.URL context, javax.wsdl.Definition def, org.w3c.dom.Document doc, java.lang.String filename)
Method populate

param
context
param
def
param
doc
param
filename
throws
IOException
throws
ParserConfigurationException
throws
SAXException
throws
WSDLException


                                                                                               
      
                   
               
             

        if (doc != null) {
            populateTypes(context, doc);

            if (addImports) {

                // Add the symbols from any xsd:import'ed documents.
                lookForImports(context, doc);
            }
        }

        if (def != null) {
            checkForUndefined(def, filename);

            if (addImports) {

                // Add the symbols from the wsdl:import'ed WSDL documents
                Map imports = def.getImports();
                Object[] importKeys = imports.keySet().toArray();

                for (int i = 0; i < importKeys.length; ++i) {
                    Vector v = (Vector) imports.get(importKeys[i]);

                    for (int j = 0; j < v.size(); ++j) {
                        Import imp = (Import) v.get(j);

                        if (!importedFiles.contains(imp.getLocationURI())) {
                            importedFiles.add(imp.getLocationURI());

                            URL url = getURL(context, imp.getLocationURI());

                            populate(url, imp.getDefinition(),
                                    XMLUtils.newDocument(url.toString()),
                                    url.toString());
                        }
                    }
                }
            }

            populateMessages(def);
            populatePortTypes(def);
            populateBindings(def);
            populateServices(def);
        }
    
private voidpopulateBindings(javax.wsdl.Definition def)
Populate the symbol table with all of the BindingEntry's from the Definition.

param
def
throws
IOException


        Iterator i = def.getBindings().values().iterator();

        while (i.hasNext()) {
            Binding binding = (Binding) i.next();
            BindingEntry bEntry = new BindingEntry(binding);

            symbolTablePut(bEntry);

            Iterator extensibilityElementsIterator =
                    binding.getExtensibilityElements().iterator();

            while (extensibilityElementsIterator.hasNext()) {
                Object obj = extensibilityElementsIterator.next();

                if (obj instanceof SOAPBinding) {
                    bEntry.setBindingType(BindingEntry.TYPE_SOAP);

                    SOAPBinding sb = (SOAPBinding) obj;
                    String style = sb.getStyle();

                    if ("rpc".equalsIgnoreCase(style)) {
                        bEntry.setBindingStyle(Style.RPC);
                    }
                } else if (obj instanceof HTTPBinding) {
                    HTTPBinding hb = (HTTPBinding) obj;

                    if (hb.getVerb().equalsIgnoreCase("post")) {
                        bEntry.setBindingType(BindingEntry.TYPE_HTTP_POST);
                    } else {
                        bEntry.setBindingType(BindingEntry.TYPE_HTTP_GET);
                    }
                } else if (obj instanceof UnknownExtensibilityElement) {

                    // TODO: After WSDL4J supports soap12, change this code
                    UnknownExtensibilityElement unkElement =
                            (UnknownExtensibilityElement) obj;
                    QName name =
                            unkElement.getElementType();

                    if (name.getNamespaceURI().equals(Constants.URI_WSDL12_SOAP)
                            && name.getLocalPart().equals("binding")) {
                        bEntry.setBindingType(BindingEntry.TYPE_SOAP);

                        String style =
                                unkElement.getElement().getAttribute("style");

                        if ("rpc".equalsIgnoreCase(style)) {
                            bEntry.setBindingStyle(Style.RPC);
                        }
                    }
                }
            }

            // Step through the binding operations, setting the following as appropriate:
            // - hasLiteral
            // - body types
            // - mimeTypes
            // - headers
            HashMap attributes = new HashMap();
            List bindList = binding.getBindingOperations();
            HashMap faultMap = new HashMap();    // name to SOAPFault from WSDL4J

            for (Iterator opIterator = bindList.iterator();
                 opIterator.hasNext();) {
                BindingOperation bindOp =
                        (BindingOperation) opIterator.next();
                Operation operation = bindOp.getOperation();
                BindingInput bindingInput = bindOp.getBindingInput();
                BindingOutput bindingOutput = bindOp.getBindingOutput();
                String opName = bindOp.getName();

                // First, make sure the binding operation matches a portType operation
                String inputName = (bindingInput == null)
                        ? null
                        : bindingInput.getName();
                String outputName = (bindingOutput == null)
                        ? null
                        : bindingOutput.getName();

                if (binding.getPortType().getOperation(
                        opName, inputName, outputName) == null) {
                    throw new IOException(Messages.getMessage("unmatchedOp",
                            new String[]{
                                opName,
                                inputName,
                                outputName}));
                }

                ArrayList faults = new ArrayList();

                // input
                if (bindingInput != null) {
                    if (bindingInput.getExtensibilityElements() != null) {
                        Iterator inIter =
                                bindingInput.getExtensibilityElements().iterator();

                        fillInBindingInfo(bEntry, operation, inIter, faults,
                                true);
                    }
                }

                // output
                if (bindingOutput != null) {
                    if (bindingOutput.getExtensibilityElements() != null) {
                        Iterator outIter =
                                bindingOutput.getExtensibilityElements().iterator();

                        fillInBindingInfo(bEntry, operation, outIter, faults,
                                false);
                    }
                }

                // faults
                faultsFromSOAPFault(binding, bindOp, operation, faults);

                // Add this fault name and info to the map
                faultMap.put(bindOp, faults);

                Use inputBodyType = bEntry.getInputBodyType(operation);
                Use outputBodyType = bEntry.getOutputBodyType(operation);

                // Associate the portType operation that goes with this binding
                // with the body types.
                attributes.put(bindOp.getOperation(),
                        new BindingEntry.OperationAttr(inputBodyType,
                                outputBodyType, faultMap));

                // If the input or output body uses literal, flag the binding as using literal.
                // NOTE:  should I include faultBodyType in this check?
                if ((inputBodyType == Use.LITERAL)
                        || (outputBodyType == Use.LITERAL)) {
                    bEntry.setHasLiteral(true);
                }

                bEntry.setFaultBodyTypeMap(operation, faultMap);
            }    // binding operations

            bEntry.setFaults(faultMap);
        }
    
private voidpopulateMessages(javax.wsdl.Definition def)
Populate the symbol table with all of the MessageEntry's from the Definition.

param
def
throws
IOException


        Iterator i = def.getMessages().values().iterator();

        while (i.hasNext()) {
            Message message = (Message) i.next();
            MessageEntry mEntry = new MessageEntry(message);

            symbolTablePut(mEntry);
        }
    
private voidpopulateParameters()
Create the parameters and store them in the bindingEntry.

throws
IOException


        Iterator it = symbolTable.values().iterator();

        while (it.hasNext()) {
            Vector v = (Vector) it.next();

            for (int i = 0; i < v.size(); ++i) {
                if (v.get(i) instanceof BindingEntry) {
                    BindingEntry bEntry = (BindingEntry) v.get(i);

                    // Skip non-soap bindings
                    if (bEntry.getBindingType() != BindingEntry.TYPE_SOAP) {
                        continue;
                    }

                    Binding binding = bEntry.getBinding();
                    Collection bindOperations = bEntry.getOperations();
                    PortType portType = binding.getPortType();
                    HashMap parameters = new HashMap();
                    Iterator operations =
                            portType.getOperations().iterator();

                    // get parameters
                    while (operations.hasNext()) {
                        Operation operation = (Operation) operations.next();

                        // See if the PortType operation has a corresponding
                        // Binding operation and report an error if it doesn't.
                        if (!bindOperations.contains(operation)) {
                            throw new IOException(
                                    Messages.getMessage(
                                            "emitFailNoMatchingBindOperation01",
                                            operation.getName(),
                                            portType.getQName().getLocalPart()));
                        }

                        String namespace =
                                portType.getQName().getNamespaceURI();
                        Parameters parms = getOperationParameters(operation,
                                namespace, bEntry);
                        parameters.put(operation, parms);
                    }

                    bEntry.setParameters(parameters);
                }
            }
        }
    
private voidpopulatePortTypes(javax.wsdl.Definition def)
Populate the symbol table with all of the PortTypeEntry's from the Definition.

param
def
throws
IOException


        Iterator i = def.getPortTypes().values().iterator();

        while (i.hasNext()) {
            PortType portType = (PortType) i.next();

            // If the portType is undefined, then we're parsing a Definition
            // that didn't contain a portType, merely a binding that referred
            // to a non-existent port type.  Don't bother with it.
            if (!portType.isUndefined()) {
                ensureOperationsOfPortTypeValid(portType);

                PortTypeEntry ptEntry = new PortTypeEntry(portType);

                symbolTablePut(ptEntry);
            }
        }
    
private voidpopulatePorts(java.util.Map ports)
populates the symbol table with port elements defined within a <service> element.

param
ports a map of name->port pairs (i.e. what is returned by service.getPorts()
throws
IOException thrown, if an IO or WSDL error is detected
see
javax.wsdl.Service#getPorts()
see
javax.wsdl.Port


        if (ports == null) {
            return;
        }

        Iterator it = ports.values().iterator();

        while (it.hasNext()) {
            Port port = (Port) it.next();
            String portName = port.getName();
            Binding portBinding = port.getBinding();

            // make sure there is a port name. The 'name' attribute for WSDL ports is
            // mandatory
            //
            if (portName == null) {

                // REMIND: should rather be a javax.wsdl.WSDLException ?
                throw new IOException(
                        Messages.getMessage("missingPortNameException"));
            }

            // make sure there is a binding for the port. The 'binding' attribute for
            // WSDL ports is mandatory
            //
            if (portBinding == null) {

                // REMIND: should rather be a javax.wsdl.WSDLException ?
                throw new IOException(
                        Messages.getMessage("missingBindingException"));
            }

            // make sure the port name is unique among all port names defined in this
            // WSDL document.
            //
            // NOTE: there's a flaw in com.ibm.wsdl.xml.WSDLReaderImpl#parsePort() and
            // com.ibm.wsdl.xml.WSDLReaderImpl#addPort(). These methods do not enforce
            // the port name exists and is unique. Actually, if two port definitions with
            // the same name exist within the same service element, only *one* port
            // element is present after parsing and the following exception is not thrown.
            //
            // If two ports with the same name exist in different service elements,
            // the exception below is thrown. This is conformant to the WSDL 1.1 spec (sec 2.6)
            // , which states: "The name attribute provides a unique name among all ports
            // defined within in the enclosing WSDL document."
            //
            //
            if (existsPortWithName(new QName(portName))) {

                // REMIND: should rather be a javax.wsdl.WSDLException ?
                throw new IOException(
                        Messages.getMessage("twoPortsWithSameName", portName));
            }

            PortEntry portEntry = new PortEntry(port);

            symbolTablePut(portEntry);
        }
    
private voidpopulateServices(javax.wsdl.Definition def)
Populate the symbol table with all of the ServiceEntry's from the Definition.

param
def
throws
IOException

    	String originalName = null;
        Iterator i = def.getServices().values().iterator();

        while (i.hasNext()) {
            Service service = (Service) i.next();
            originalName = service.getQName().getLocalPart();
            // do a bit of name validation
            if ((service.getQName() == null)
                    || (service.getQName().getLocalPart() == null)
                    || service.getQName().getLocalPart().equals("")) {
                throw new IOException(Messages.getMessage("BadServiceName00"));
            }

            // behave as though backslashes were never there
            service.setQName(BackslashUtil.getQNameWithBackslashlessLocal(service.getQName()));
            ServiceEntry sEntry = new ServiceEntry(service);
            // we'll need this later when it is time print a backslash escaped service name
            sEntry.setOriginalServiceName(originalName);
            symbolTablePut(sEntry);
            populatePorts(service.getPorts());
        }
    
public voidpopulateTypes(java.net.URL context, org.w3c.dom.Document doc)
Populate the symbol table with all of the Types from the Document.

param
context
param
doc
throws
IOException
throws
SAXException
throws
WSDLException
throws
ParserConfigurationException

        addTypes(context, doc, ABOVE_SCHEMA_LEVEL);
    
protected voidprocessTypes()

        for (Iterator i = typeTypeEntries.values().iterator(); i.hasNext(); ) {
            Type type = (Type) i.next();
            Node node = type.getNode();            
            
            // Process the attributes
            Vector attributes = 
                    SchemaUtils.getContainedAttributeTypes(node, this);

            if (attributes != null) {
                type.setContainedAttributes(attributes);
            }

            // Process the elements
            Vector elements =
                    SchemaUtils.getContainedElementDeclarations(node, this);

            if (elements != null) {
                type.setContainedElements(elements);
            }
        }
    
private voidsetBindingReferences(BindingEntry entry, javax.wsdl.Definition def, org.w3c.dom.Document doc)
Set the isReferenced flag to true on the given BindingEntry and all SymTabEntries that it refers to ONLY if this binding is a SOAP binding.

param
entry
param
def
param
doc


        if (entry.getBindingType() == BindingEntry.TYPE_SOAP) {

            // If we don't want to emit stuff from imported files, only set the
            // isReferenced flag if this entry exists in the immediate WSDL file.
            Binding binding = entry.getBinding();

            if (addImports) {
                entry.setIsReferenced(true);
            } else {

                // NOTE:  I thought I could have simply done:
                // if (def.getBindng(binding.getQName()) != null)
                // but that method traces through all imported bindings.
                Map bindings = def.getBindings();

                if (bindings.containsValue(binding)) {
                    entry.setIsReferenced(true);
                }
            }

            // Set all the binding's portTypes
            PortType portType = binding.getPortType();
            PortTypeEntry ptEntry = getPortTypeEntry(portType.getQName());

            if (ptEntry != null) {
                setPortTypeReferences(ptEntry, entry, def, doc);
            }
        }
    
private voidsetBodyType(java.lang.String use, BindingEntry bEntry, javax.wsdl.Operation operation, boolean input)
Set the body type.

param
use
param
bEntry
param
operation
param
input


        if (use == null) {
            // Deprecated
            // throw new IOException(Messages.getMessage("noUse",
            //        operation.getName()));
            // for WS-I BP 1.0 R2707.
            // Set default of use to literal.
            use = "literal";
        }

        if (use.equalsIgnoreCase("literal")) {
            bEntry.setBodyType(operation, Use.LITERAL, input);
        }
    
private voidsetMIMEInfo(Parameter p, MimeInfo mimeInfo)
Set the MIME type. This can be determine in one of two ways: 1. From WSDL 1.1 MIME constructs on the binding (passed in); 2. From AXIS-specific xml MIME types.

param
p
param
mimeInfo


        // If there is no binding MIME construct (ie., the mimeType parameter is
        // null), then get the MIME type from the AXIS-specific xml MIME type.
        if (mimeInfo == null && p.getType() != null) {
            QName mimeQName = p.getType().getQName();

            if (mimeQName.getNamespaceURI().equals(Constants.NS_URI_XMLSOAP)) {
                if (Constants.MIME_IMAGE.equals(mimeQName)) {
                    mimeInfo = new MimeInfo("image/jpeg", "");
                } else if (Constants.MIME_PLAINTEXT.equals(mimeQName)) {
                    mimeInfo = new MimeInfo("text/plain", "");
                } else if (Constants.MIME_MULTIPART.equals(mimeQName)) {
                    mimeInfo = new MimeInfo("multipart/related", "");
                } else if (Constants.MIME_SOURCE.equals(mimeQName)) {
                    mimeInfo = new MimeInfo("text/xml", "");
                } else if (Constants.MIME_OCTETSTREAM.equals(mimeQName)) {
                    mimeInfo = new MimeInfo("application/octet-stream", "");
                }
            }
        }

        p.setMIMEInfo(mimeInfo);
    
private voidsetMessageReferences(MessageEntry entry, javax.wsdl.Definition def, org.w3c.dom.Document doc, boolean literal)
Set the isReferenced flag to true on the given MessageEntry and all SymTabEntries that it refers to.

param
entry
param
def
param
doc
param
literal


        // If we don't want to emit stuff from imported files, only set the
        // isReferenced flag if this entry exists in the immediate WSDL file.
        Message message = entry.getMessage();

        if (addImports) {
            entry.setIsReferenced(true);
        } else {

            // NOTE:  I thought I could have simply done:
            // if (def.getMessage(message.getQName()) != null)
            // but that method traces through all imported messages.
            Map messages = def.getMessages();

            if (messages.containsValue(message)) {
                entry.setIsReferenced(true);
            }
        }

        // Set all the message's types
        Iterator parts = message.getParts().values().iterator();

        while (parts.hasNext()) {
            Part part = (Part) parts.next();
            TypeEntry type = getType(part.getTypeName());

            if (type != null) {
                setTypeReferences(type, doc, literal);
            }

            type = getElement(part.getElementName());

            if (type != null) {
                setTypeReferences(type, doc, literal);

                TypeEntry refType = type.getRefType();

                if (refType != null) {
                    setTypeReferences(refType, doc, literal);
                }
            }
        }
    
private voidsetPortTypeReferences(PortTypeEntry entry, BindingEntry bEntry, javax.wsdl.Definition def, org.w3c.dom.Document doc)
Set the isReferenced flag to true on the given PortTypeEntry and all SymTabEntries that it refers to.

param
entry
param
bEntry
param
def
param
doc


        // If we don't want to emit stuff from imported files, only set the
        // isReferenced flag if this entry exists in the immediate WSDL file.
        PortType portType = entry.getPortType();

        if (addImports) {
            entry.setIsReferenced(true);
        } else {

            // NOTE:  I thought I could have simply done:
            // if (def.getPortType(portType.getQName()) != null)
            // but that method traces through all imported portTypes.
            Map portTypes = def.getPortTypes();

            if (portTypes.containsValue(portType)) {
                entry.setIsReferenced(true);
            }
        }

        // Set all the portType's messages
        Iterator operations = portType.getOperations().iterator();

        // For each operation, query its input, output, and fault messages
        while (operations.hasNext()) {
            Operation operation = (Operation) operations.next();
            Input input = operation.getInput();
            Output output = operation.getOutput();

            // Find out if this reference is a literal reference or not.
            boolean literalInput = false;
            boolean literalOutput = false;

            if (bEntry != null) {
                literalInput = bEntry.getInputBodyType(operation)
                        == Use.LITERAL;
                literalOutput = bEntry.getOutputBodyType(operation)
                        == Use.LITERAL;
            }

            // Query the input message
            if (input != null) {
                Message message = input.getMessage();

                if (message != null) {
                    MessageEntry mEntry = getMessageEntry(message.getQName());

                    if (mEntry != null) {
                        setMessageReferences(mEntry, def, doc, literalInput);
                    }
                }
            }

            // Query the output message
            if (output != null) {
                Message message = output.getMessage();

                if (message != null) {
                    MessageEntry mEntry = getMessageEntry(message.getQName());

                    if (mEntry != null) {
                        setMessageReferences(mEntry, def, doc, literalOutput);
                    }
                }
            }

            // Query the fault messages
            Iterator faults = operation.getFaults().values().iterator();

            while (faults.hasNext()) {
                Message message = ((Fault) faults.next()).getMessage();

                if (message != null) {
                    MessageEntry mEntry = getMessageEntry(message.getQName());

                    if (mEntry != null) {
                        setMessageReferences(mEntry, def, doc, false);
                    }
                }
            }
        }
    
public voidsetQuiet(boolean quiet)
Method setQuiet

param
quiet

        this.quiet = quiet;
    
private voidsetReferences(javax.wsdl.Definition def, org.w3c.dom.Document doc)
Set each SymTabEntry's isReferenced flag. The default is false. If no other symbol references this symbol, then leave it false, otherwise set it to true. (An exception to the rule is that derived types are set as referenced if their base type is referenced. This is necessary to support generation and registration of derived types.)

param
def
param
doc


        Map stuff = def.getServices();

        if (stuff.isEmpty()) {
            stuff = def.getBindings();

            if (stuff.isEmpty()) {
                stuff = def.getPortTypes();

                if (stuff.isEmpty()) {
                    stuff = def.getMessages();

                    if (stuff.isEmpty()) {
                        for (Iterator i = elementTypeEntries.values().iterator();
                             i.hasNext();) {
                            setTypeReferences((TypeEntry) i.next(), doc, false);
                        }

                        for (Iterator i = typeTypeEntries.values().iterator();
                             i.hasNext();) {
                            setTypeReferences((TypeEntry) i.next(), doc, false);
                        }
                    } else {
                        Iterator i = stuff.values().iterator();

                        while (i.hasNext()) {
                            Message message = (Message) i.next();
                            MessageEntry mEntry =
                                    getMessageEntry(message.getQName());

                            setMessageReferences(mEntry, def, doc, false);
                        }
                    }
                } else {
                    Iterator i = stuff.values().iterator();

                    while (i.hasNext()) {
                        PortType portType = (PortType) i.next();
                        PortTypeEntry ptEntry =
                                getPortTypeEntry(portType.getQName());

                        setPortTypeReferences(ptEntry, null, def, doc);
                    }
                }
            } else {
                Iterator i = stuff.values().iterator();

                while (i.hasNext()) {
                    Binding binding = (Binding) i.next();
                    BindingEntry bEntry = getBindingEntry(binding.getQName());

                    setBindingReferences(bEntry, def, doc);
                }
            }
        } else {
            Iterator i = stuff.values().iterator();

            while (i.hasNext()) {
                Service service = (Service) i.next();
                ServiceEntry sEntry = getServiceEntry(service.getQName());

                setServiceReferences(sEntry, def, doc);
            }
        }
    
private voidsetServiceReferences(ServiceEntry entry, javax.wsdl.Definition def, org.w3c.dom.Document doc)
Set the isReferenced flag to true on the given ServiceEntry and all SymTabEntries that it refers to.

param
entry
param
def
param
doc


        // If we don't want to emit stuff from imported files, only set the
        // isReferenced flag if this entry exists in the immediate WSDL file.
        Service service = entry.getService();

        if (addImports) {
            entry.setIsReferenced(true);
        } else {

            // NOTE:  I thought I could have simply done:
            // if (def.getService(service.getQName()) != null)
            // but that method traces through all imported services.
            Map services = def.getServices();

            if (services.containsValue(service)) {
                entry.setIsReferenced(true);
            }
        }

        // Set all the service's bindings
        Iterator ports = service.getPorts().values().iterator();

        while (ports.hasNext()) {
            Port port = (Port) ports.next();
            Binding binding = port.getBinding();

            if (binding != null) {
                BindingEntry bEntry = getBindingEntry(binding.getQName());

                if (bEntry != null) {
                    setBindingReferences(bEntry, def, doc);
                }
            }
        }
    
private voidsetTypeReferences(TypeEntry entry, org.w3c.dom.Document doc, boolean literal)
Set the isReferenced flag to true on the given TypeEntry and all SymTabEntries that it refers to.

param
entry
param
doc
param
literal


        // Check to see if already processed.
        if ((entry.isReferenced() && !literal)
                || (entry.isOnlyLiteralReferenced() && literal)) {
            return;
        }

        if (wrapped) {

            // If this type is ONLY referenced from a literal usage in a binding,
            // then isOnlyLiteralReferenced should return true.
            if (!entry.isReferenced() && literal) {
                entry.setOnlyLiteralReference(true);
            }

            // If this type was previously only referenced as a literal type,
            // but now it is referenced in a non-literal manner, turn off the
            // onlyLiteralReference flag.
            else if (entry.isOnlyLiteralReferenced() && !literal) {
                entry.setOnlyLiteralReference(false);
            }
        }

        // If we don't want to emit stuff from imported files, only set the
        // isReferenced flag if this entry exists in the immediate WSDL file.
        Node node = entry.getNode();

        if (addImports || (node == null) || (node.getOwnerDocument() == doc)) {
            entry.setIsReferenced(true);

            if (entry instanceof DefinedElement) {
                BooleanHolder forElement = new BooleanHolder();
                QName referentName = Utils.getTypeQName(node,
                        forElement, false);

                if (referentName != null) {
                    TypeEntry referent = getTypeEntry(referentName,
                            forElement.value);

                    if (referent != null) {
                        setTypeReferences(referent, doc, literal);
                    }
                }

                // If the Defined Element has an anonymous type,
                // process it with the current literal flag setting.
                QName anonQName =
                        SchemaUtils.getElementAnonQName(entry.getNode());

                if (anonQName != null) {
                    TypeEntry anonType = getType(anonQName);

                    if (anonType != null) {
                        setTypeReferences(anonType, doc, literal);

                        return;
                    }
                }
            }
        }

        HashSet nestedTypes = entry.getNestedTypes(this, true);
        Iterator it = nestedTypes.iterator();

        while (it.hasNext()) {
            TypeEntry nestedType = (TypeEntry) it.next();
            TypeEntry refType = entry.getRefType();

            if (nestedType == null) {
            	continue;
            }

            // If this entry has a referenced type that isn't
            // the same as the nested type
            // AND the OnlyLiteral reference switch is on
            // THEN turn the OnlyLiteral reference switch off.
            // If only someone had put a comment here saying why we do this...
            if ((refType != null)
                    && !refType.equals(nestedType)
                    && nestedType.isOnlyLiteralReferenced()) {
                nestedType.setOnlyLiteralReference(false);
            }

            if (!nestedType.isReferenced()) {

                // setTypeReferences(nestedType, doc, literal);
                if (nestedType != entry) {
                    setTypeReferences(nestedType, doc, false);
                }
            }
        }
    
public voidsetWrapArrays(boolean wrapArrays)

        this.wrapArrays = wrapArrays;
    
public voidsetWrapped(boolean wrapped)
Turn on/off element wrapping for literal soap body's.

param
wrapped

        this.wrapped = wrapped;
    
private SymTabEntrysymbolTablePut(SymTabEntry entry)
Put the given SymTabEntry into the symbol table, if appropriate.

param
entry
throws
IOException


        QName name = entry.getQName();

        SymTabEntry e = get(name, entry.getClass());

        if (e == null) {
            e = entry;

            // An entry of the given qname of the given type doesn't exist yet.
            if ((entry instanceof Type)
                    && (get(name, UndefinedType.class) != null)) {

                // A undefined type exists in the symbol table, which means
                // that the type is used, but we don't yet have a definition for
                // the type.  Now we DO have a definition for the type, so
                // replace the existing undefined type with the real type.
                if (((TypeEntry) get(name, UndefinedType.class)).isSimpleType()
                        && !((TypeEntry) entry).isSimpleType()) {

                    // Problem if the undefined type was used in a
                    // simple type context.
                    throw new IOException(
                            Messages.getMessage(
                                    "AttrNotSimpleType01", name.toString()));
                }

                Vector v = (Vector) symbolTable.get(name);

                for (int i = 0; i < v.size(); ++i) {
                    Object oldEntry = v.elementAt(i);

                    if (oldEntry instanceof UndefinedType) {

                        // Replace it in the symbol table
                        v.setElementAt(entry, i);

                        // Replace it in the types index
                        typeTypeEntries.put(name, entry);

                        // Update all of the entries that refer to the unknown type
                        ((UndefinedType) oldEntry).update((Type) entry);
                    }
                }
            } else if ((entry instanceof Element)
                    && (get(name, UndefinedElement.class) != null)) {

                // A undefined element exists in the symbol table, which means
                // that the element is used, but we don't yet have a definition for
                // the element.  Now we DO have a definition for the element, so
                // replace the existing undefined element with the real element.
                Vector v = (Vector) symbolTable.get(name);

                for (int i = 0; i < v.size(); ++i) {
                    Object oldEntry = v.elementAt(i);

                    if (oldEntry instanceof UndefinedElement) {

                        // Replace it in the symbol table
                        v.setElementAt(entry, i);

                        // Replace it in the elements index
                        elementTypeEntries.put(name, entry);

                        // Update all of the entries that refer to the unknown type
                        ((Undefined) oldEntry).update((Element) entry);
                    }
                }
            } else {

                // Add this entry to the symbol table
                Vector v = (Vector) symbolTable.get(name);

                if (v == null) {
                    v = new Vector();

                    symbolTable.put(name, v);
                }

                v.add(entry);

                // add TypeEntries to specialized indices for
                // fast lookups during reference resolution.
                if (entry instanceof Element) {
                    elementTypeEntries.put(name, entry);
                } else if (entry instanceof Type) {
                    typeTypeEntries.put(name, entry);
                }
            }
        } else {
            if (!quiet) {
                System.out.println(Messages.getMessage("alreadyExists00",
                                                       "" + name));
            }
        }

        return e;