dims 2003/01/03 05:56:09 Modified: java/src/org/apache/axis/wsdl/symbolTable SchemaUtils.java DefinedType.java SymbolTable.java Utils.java java/test/wsdl/qualify2 attribute-qualify.wsdl Log: Fixes for Bug 15724 - WSDL2Java takes hours on large files from [EMAIL PROTECTED] (Eric Friedman) Notes: - attribute-qualify.wsdl had a small bug it was not using xsd:attribute for phone complextype Revision Changes Path 1.22 +182 -287 xml-axis/java/src/org/apache/axis/wsdl/symbolTable/SchemaUtils.java Index: SchemaUtils.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/symbolTable/SchemaUtils.java,v retrieving revision 1.21 retrieving revision 1.22 diff -u -r1.21 -r1.22 --- SchemaUtils.java 31 Dec 2002 22:46:51 -0000 1.21 +++ SchemaUtils.java 3 Jan 2003 13:56:08 -0000 1.22 @@ -61,6 +61,9 @@ import javax.xml.namespace.QName; import javax.xml.rpc.holders.BooleanHolder; import javax.xml.rpc.holders.IntHolder; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; import java.util.Vector; /** @@ -70,6 +73,8 @@ */ public class SchemaUtils { + static final QName VALUE_QNAME = Utils.findQName("", "value"); + /** * If the specified node represents a supported JAX-RPC complexType or * simpleType, a Vector is returned which contains ElementDecls for the @@ -89,53 +94,41 @@ } // If the node kind is an element, dive into it. - QName nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("element") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { + if (isXSDNode(node, "element")) { NodeList children = node.getChildNodes(); - Node complexNode = null; - for (int j = 0; j < children.getLength() && complexNode == null; j++) { - QName complexKind = Utils.getNodeQName(children.item(j)); - if (complexKind != null && - complexKind.getLocalPart().equals("complexType") && - Constants.isSchemaXSD(complexKind.getNamespaceURI())) { - complexNode = children.item(j); - node = complexNode; + for (int j = 0; j < children.getLength(); j++) { + Node kid = children.item(j); + if (isXSDNode(kid, "complexType")) { + node = kid; + break; } } } // Expecting a schema complexType or simpleType - nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("complexType") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { - + if (isXSDNode(node, "complexType")) { // Under the complexType there could be complexContent/simpleContent // and extension elements if this is a derived type. Skip over these. NodeList children = node.getChildNodes(); Node complexContent = null; Node simpleContent = null; Node extension = null; - for (int j = 0; j < children.getLength() && complexContent == null; j++) { - QName complexContentKind = Utils.getNodeQName(children.item(j)); - if (complexContentKind != null && - Constants.isSchemaXSD(complexContentKind.getNamespaceURI())) { - if (complexContentKind.getLocalPart().equals("complexContent") ) - complexContent = children.item(j); - else if (complexContentKind.getLocalPart().equals("simpleContent")) - simpleContent = children.item(j); + for (int j = 0; j < children.getLength(); j++) { + Node kid = children.item(j); + if (isXSDNode(kid, "complexContent")) { + complexContent = kid; + break; // REMIND: should this be here or on either branch? + } else if (isXSDNode(kid, "simpleContent")) { + simpleContent = kid; } } if (complexContent != null) { children = complexContent.getChildNodes(); for (int j = 0; j < children.getLength() && extension == null; j++) { - QName extensionKind = Utils.getNodeQName(children.item(j)); - if (extensionKind != null && - extensionKind.getLocalPart().equals("extension") && - Constants.isSchemaXSD(extensionKind.getNamespaceURI())) - extension = children.item(j); + Node kid = children.item(j); + if (isXSDNode(kid, "extension")) { + extension = kid; + } } } if (simpleContent != null) { @@ -156,11 +149,10 @@ Vector v = new Vector(); ElementDecl elem = new ElementDecl(); elem.setType(symbolTable.getTypeEntry(extendsOrRestrictsType, false)); - elem.setName(new javax.xml.namespace.QName("", "value")); + elem.setName(VALUE_QNAME); v.add(elem); return v; } - } } @@ -260,7 +252,7 @@ // serializer. TypeEntry type = symbolTable.getType(Constants.XSD_ANY); ElementDecl elem = - new ElementDecl(type, new QName("","any")); + new ElementDecl(type, Utils.findQName("","any")); elem.setAnyElement(true); v.add(elem); } else if (subNodeKind.getLocalPart().equals("element")) { @@ -308,15 +300,11 @@ Vector v = new Vector(); NodeList children = allNode.getChildNodes(); for (int j = 0; j < children.getLength(); j++) { - QName subNodeKind = Utils.getNodeQName(children.item(j)); - if (subNodeKind != null && - Constants.isSchemaXSD(subNodeKind.getNamespaceURI())) { - if (subNodeKind.getLocalPart().equals("element")) { - ElementDecl elem = - processChildElementNode(children.item(j), - symbolTable); - if (elem != null) - v.add(elem); + Node kid = children.item(j); + if (isXSDNode(kid, "element")) { + ElementDecl elem = processChildElementNode(kid,symbolTable); + if (elem != null) { + v.add(elem); } } } @@ -354,14 +342,14 @@ String form = Utils.getAttribute(elementNode, "form"); if (form != null && form.equals("unqualified")) { // Unqualified nodeName - nodeName = new QName("", nodeName.getLocalPart()); + nodeName = Utils.findQName("", nodeName.getLocalPart()); } else if (form == null) { // check elementForDefault on schema element String def = Utils.getScopedAttribute(elementNode, "elementFormDefault"); if (def == null || def.equals("unqualified")) { // Unqualified nodeName - nodeName = new QName("", nodeName.getLocalPart()); + nodeName = Utils.findQName("", nodeName.getLocalPart()); } } } @@ -383,18 +371,12 @@ * or null. */ public static QName getElementAnonQName(Node node) { - QName nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("element") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { + if (isXSDNode(node, "element")) { NodeList children = node.getChildNodes(); for (int j = 0; j < children.getLength(); j++) { - QName kind = Utils.getNodeQName(children.item(j)); - if (kind != null && - (kind.getLocalPart().equals("complexType") || - kind.getLocalPart().equals("simpleType")) && - Constants.isSchemaXSD(kind.getNamespaceURI())) { - return Utils.getNodeNameQName(children.item(j)); + Node kid = children.item(j); + if (isXSDNode(kid, "complexType") || isXSDNode(kid, "simpleType")) { + return Utils.getNodeNameQName(kid); } } } @@ -406,18 +388,12 @@ * or null. */ public static QName getAttributeAnonQName(Node node) { - QName nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("attribute") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { + if (isXSDNode(node, "attribute")) { NodeList children = node.getChildNodes(); for (int j = 0; j < children.getLength(); j++) { - QName kind = Utils.getNodeQName(children.item(j)); - if (kind != null && - (kind.getLocalPart().equals("complexType") || - kind.getLocalPart().equals("simpleType")) && - Constants.isSchemaXSD(kind.getNamespaceURI())) { - return Utils.getNodeNameQName(children.item(j)); + Node kid = children.item(j); + if (isXSDNode(kid, "complexType") || isXSDNode(kid, "simpleType")) { + return Utils.getNodeNameQName(kid); } } } @@ -433,53 +409,37 @@ } // If the node kind is an element, dive into it. - QName nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("element") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { + if (isXSDNode(node, "element")) { NodeList children = node.getChildNodes(); - Node complexNode = null; - for (int j = 0; j < children.getLength() && complexNode == null; j++) { - QName kind = Utils.getNodeQName(children.item(j)); - if (kind != null && - kind.getLocalPart().equals("complexType") && - Constants.isSchemaXSD(kind.getNamespaceURI())) { - complexNode = children.item(j); - node = complexNode; - } - if (kind != null && - kind.getLocalPart().equals("simpleType") && - Constants.isSchemaXSD(kind.getNamespaceURI())) { + for (int j = 0; j < children.getLength(); j++) { + Node kid = children.item(j); + if (isXSDNode(kid, "complexType")) { + node = kid; + break; + } else if (isXSDNode(kid, "simpleType")) { return true; } } } // Expecting a schema complexType or simpleType - nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("simpleType") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { + if (isXSDNode(node, "simpleType")) { return true; } - if (nodeKind != null && - nodeKind.getLocalPart().equals("complexType") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { - + if (isXSDNode(node, "complexType")) { // Under the complexType there could be complexContent/simpleContent // and extension elements if this is a derived type. Skip over these. NodeList children = node.getChildNodes(); Node complexContent = null; Node simpleContent = null; - for (int j = 0; j < children.getLength() && complexContent == null; j++) { - QName complexContentKind = Utils.getNodeQName(children.item(j)); - if (complexContentKind != null && - Constants.isSchemaXSD(complexContentKind.getNamespaceURI())) { - if (complexContentKind.getLocalPart().equals("complexContent") ) - complexContent = children.item(j); - else if (complexContentKind.getLocalPart().equals("simpleContent")) - simpleContent = children.item(j); + for (int j = 0; j < children.getLength(); j++) { + Node kid = children.item(j); + if (isXSDNode(kid, "complexContent")) { + complexContent = kid; + break; + } else if (isXSDNode(kid, "simpleContent")) { + simpleContent = kid; } } if (complexContent != null) { @@ -493,6 +453,26 @@ } /** + * Test whether <tt>node</tt> is not null, belongs to the XML + * Schema namespace, and has a localName that matches + * <tt>schemaLocalName</tt> + * + * This can be used to determine that a given Node defines a + * schema "complexType" "element" and so forth. + * + * @param node a <code>Node</code> value + * @param schemaLocalName a <code>String</code> value + * @return true if the node is matches the name in the schema namespace. + */ + private static boolean isXSDNode(Node node, String schemaLocalName) { + if ((node != null) && Constants.isSchemaXSD(node.getNamespaceURI())) { + String localName = node.getLocalName(); + return ((localName != null) && localName.equals(schemaLocalName)); + } + return false; + } + + /** * If the specified node represents a supported JAX-RPC complexType/element * which extends another complexType. The Type of the base is returned. */ @@ -501,18 +481,17 @@ return null; } + TypeEntry cached = (TypeEntry)symbolTable.node2ExtensionBase.get(node); + if (cached != null) { + return cached; // cache hit + } + // If the node kind is an element, dive into it. - QName nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("element") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { + if (isXSDNode(node, "element")) { NodeList children = node.getChildNodes(); Node complexNode = null; for (int j = 0; j < children.getLength() && complexNode == null; j++) { - QName complexKind = Utils.getNodeQName(children.item(j)); - if (complexKind != null && - complexKind.getLocalPart().equals("complexType") && - Constants.isSchemaXSD(complexKind.getNamespaceURI())) { + if (isXSDNode(children.item(j), "complexType")) { complexNode = children.item(j); node = complexNode; } @@ -520,10 +499,7 @@ } // Expecting a schema complexType - nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("complexType") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { + if (isXSDNode(node, "complexType")) { // Under the complexType there could be should be a complexContent & // extension elements if this is a derived type. @@ -531,39 +507,35 @@ Node content = null; Node extension = null; for (int j = 0; j < children.getLength() && content == null; j++) { - QName contentKind = Utils.getNodeQName(children.item(j)); - if (contentKind != null && - contentKind.getLocalPart().equals("complexContent") && - Constants.isSchemaXSD(contentKind.getNamespaceURI())) - content = children.item(j); - if (contentKind != null && - contentKind.getLocalPart().equals("simpleContent") && - Constants.isSchemaXSD(contentKind.getNamespaceURI())) - content = children.item(j); + Node kid = children.item(j); + if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent")) { + content = kid; + } } if (content != null) { children = content.getChildNodes(); for (int j = 0; j < children.getLength() && extension == null; j++) { - QName extensionKind = Utils.getNodeQName(children.item(j)); - if (extensionKind != null && - extensionKind.getLocalPart().equals("extension") && - Constants.isSchemaXSD(extensionKind.getNamespaceURI())) - extension = children.item(j); + Node kid = children.item(j); + if (isXSDNode(kid, "extension")) { + extension = kid; + } } } if (extension == null) { - return null; // No extension - } - - // Get the QName of the extension base - QName extendsType = Utils.getTypeQName(extension, new BooleanHolder(), false); - if (extendsType == null) { - return null; // No extension base + cached = null; + } else { + // Get the QName of the extension base + QName extendsType = Utils.getTypeQName(extension, new BooleanHolder(), false); + if (extendsType == null) { + cached = null; + } else { + // Return associated Type + cached = symbolTable.getType(extendsType); + } } - // Return associated Type - return symbolTable.getType(extendsType); } - return null; + symbolTable.node2ExtensionBase.put(node, cached); + return cached; } /** @@ -579,37 +551,25 @@ // If the node kind is an element, dive into it. QName nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("element") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { + if (isXSDNode(node, "element")) { NodeList children = node.getChildNodes(); - Node simpleNode = null; - for (int j = 0; j < children.getLength() && simpleNode == null; j++) { - QName simpleKind = Utils.getNodeQName(children.item(j)); - if (simpleKind != null && - simpleKind.getLocalPart().equals("simpleType") && - Constants.isSchemaXSD(simpleKind.getNamespaceURI())) { - simpleNode = children.item(j); - node = simpleNode; + for (int j = 0; j < children.getLength(); j++) { + if (isXSDNode(children.item(j), "simpleType")) { + node = children.item(j); + break; } } } // Get the node kind, expecting a schema simpleType - nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("simpleType") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { - + if (isXSDNode(node, "simpleType")) { // Under the simpleType there should be a restriction. // (There may be other #text nodes, which we will ignore). NodeList children = node.getChildNodes(); Node restrictionNode = null; for (int j = 0; j < children.getLength() && restrictionNode == null; j++) { - QName restrictionKind = Utils.getNodeQName(children.item(j)); - if (restrictionKind != null && - restrictionKind.getLocalPart().equals("restriction") && - Constants.isSchemaXSD(restrictionKind.getNamespaceURI())) + if (isXSDNode(children.item(j), "restriction")) { restrictionNode = children.item(j); + } } // The restriction node indicates the type being restricted @@ -623,11 +583,7 @@ if (baseQName != null && restrictionNode != null) { NodeList enums = restrictionNode.getChildNodes(); for (int i=0; i < enums.getLength(); i++) { - QName enumKind = Utils.getNodeQName(enums.item(i)); - if (enumKind != null && - enumKind.getLocalPart().equals("enumeration") && - Constants.isSchemaXSD(enumKind.getNamespaceURI())) { - + if (isXSDNode(enums.item(i), "enumeration")) { // Found an enumeration, this isn't a // 'normal' simple type. return null; @@ -649,42 +605,28 @@ } // If the node kind is an element, dive into it. - QName nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("element") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { + if (isXSDNode(node, "element")) { NodeList children = node.getChildNodes(); Node node2 = null; - for (int j = 0; j < children.getLength() && node2 == null; j++) { - QName kind2 = Utils.getNodeQName(children.item(j)); - if (kind2 != null && - (kind2.getLocalPart().equals("simpleType") || - kind2.getLocalPart().equals("complexType") || - kind2.getLocalPart().equals("simpleContent")) && - Constants.isSchemaXSD(kind2.getNamespaceURI())) { - node2 = children.item(j); - node = node2; + for (int j = 0; j < children.getLength(); j++) { + Node n = children.item(j); + if (isXSDNode(n, "simpleType") || isXSDNode(n, "complexType") || isXSDNode(n, "simpleContent")) { + node = n; + break; } } } // Get the node kind, expecting a schema simpleType - nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - (nodeKind.getLocalPart().equals("simpleType") || - nodeKind.getLocalPart().equals("complexType")) && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { - + if (isXSDNode(node, "simpleType") || isXSDNode(node, "complexType")) { // Under the complexType there could be a complexContent. NodeList children = node.getChildNodes(); Node complexContent = null; - if (nodeKind.getLocalPart().equals("complexType")) { + if (node.getLocalName().equals("complexType")) { for (int j = 0; j < children.getLength() && complexContent == null; j++) { - QName complexContentKind = Utils.getNodeQName(children.item(j)); - if (complexContentKind != null && - (complexContentKind.getLocalPart().equals("complexContent") || - complexContentKind.getLocalPart().equals("simpleContent"))&& - Constants.isSchemaXSD(complexContentKind.getNamespaceURI())) - complexContent = children.item(j); + Node kid = children.item(j); + if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent")) { + complexContent = kid; + } } node = complexContent; } @@ -692,12 +634,10 @@ if (node != null) { children = node.getChildNodes(); for (int j = 0; j < children.getLength() && re == null; j++) { - QName reKind = Utils.getNodeQName(children.item(j)); - if (reKind != null && - (reKind.getLocalPart().equals("extension") || - reKind.getLocalPart().equals("restriction")) && - Constants.isSchemaXSD(reKind.getNamespaceURI())) - re = children.item(j); + Node kid = children.item(j); + if (isXSDNode(kid, "extension") || isXSDNode(kid, "restriction")) { + re = kid; + } } } } @@ -738,11 +678,7 @@ } // If the node kind is an element, dive get its type. - QName nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("element") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { - + if (isXSDNode(node, "element")) { // Compare the componentQName with the name of the // full name. If different, return componentQName BooleanHolder forElement = new BooleanHolder(); @@ -793,39 +729,29 @@ } // If the node kind is an element, dive into it. - QName nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("element") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { + if (isXSDNode(node, "element")) { NodeList children = node.getChildNodes(); - Node complexNode = null; - for (int j = 0; j < children.getLength() && complexNode == null; j++) { - QName complexKind = Utils.getNodeQName(children.item(j)); - if (complexKind != null && - complexKind.getLocalPart().equals("complexType") && - Constants.isSchemaXSD(complexKind.getNamespaceURI())) { - complexNode = children.item(j); - node = complexNode; + for (int j = 0; j < children.getLength(); j++) { + Node kid = children.item(j); + if (isXSDNode(kid, "complexType")) { + node = kid; + break; } } } - // Get the node kind, expecting a schema complexType - nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("complexType") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { + // Get the node kind, expecting a schema complexType + if (isXSDNode(node, "complexType")) { // Under the complexType there should be a complexContent. // (There may be other #text nodes, which we will ignore). NodeList children = node.getChildNodes(); Node complexContentNode = null; - for (int j = 0; j < children.getLength() && complexContentNode == null; j++) { - QName complexContentKind = Utils.getNodeQName(children.item(j)); - if (complexContentKind != null && - (complexContentKind.getLocalPart().equals("complexContent") || - complexContentKind.getLocalPart().equals("simpleContent")) && - Constants.isSchemaXSD(complexContentKind.getNamespaceURI())) - complexContentNode = children.item(j); + for (int j = 0; j < children.getLength(); j++) { + Node kid = children.item(j); + if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent")) { + complexContentNode = kid; + break; + } } // Under the complexContent there should be a restriction. @@ -833,12 +759,12 @@ Node restrictionNode = null; if (complexContentNode != null) { children = complexContentNode.getChildNodes(); - for (int j = 0; j < children.getLength() && restrictionNode == null; j++) { - QName restrictionKind = Utils.getNodeQName(children.item(j)); - if (restrictionKind != null && - restrictionKind.getLocalPart().equals("restriction") && - Constants.isSchemaXSD(restrictionKind.getNamespaceURI())) - restrictionNode = children.item(j); + for (int j = 0; j < children.getLength(); j++) { + Node kid = children.item(j); + if (isXSDNode(kid, "restriction")) { + restrictionNode = kid; + break; + } } } @@ -864,12 +790,9 @@ for (int j = 0; j < children.getLength() && groupNode == null && attributeNode == null; j++) { - QName kind = Utils.getNodeQName(children.item(j)); - if (kind != null && - (kind.getLocalPart().equals("sequence") || - kind.getLocalPart().equals("all")) && - Constants.isSchemaXSD(kind.getNamespaceURI())) { - groupNode = children.item(j); + Node kid = children.item(j); + if (isXSDNode(kid, "sequence") || isXSDNode(kid, "all")) { + groupNode = kid; if (groupNode.getChildNodes().getLength() == 0) { // This covers the rather odd but legal empty sequence. // <complexType name="ArrayOfString"> @@ -883,18 +806,16 @@ groupNode = null; } } - if (kind != null && - kind.getLocalPart().equals("attribute") && - Constants.isSchemaXSD(kind.getNamespaceURI())) { + if (isXSDNode(kid, "attribute")) { // If the attribute node does not have ref="soapenc:arrayType" // then keep looking. BooleanHolder isRef = new BooleanHolder(); - QName refQName = Utils.getTypeQName(children.item(j), isRef, false); + QName refQName = Utils.getTypeQName(kid, isRef, false); if (refQName != null && isRef.value && refQName.getLocalPart().equals("arrayType") && Constants.isSOAP_ENC(refQName.getNamespaceURI())) { - attributeNode = children.item(j); + attributeNode = kid; } } } @@ -938,11 +859,10 @@ NodeList elements = groupNode.getChildNodes(); Node elementNode = null; for (int i=0; i < elements.getLength() && elementNode == null; i++) { - QName elementKind = Utils.getNodeQName(elements.item(i)); - if (elementKind != null && - elementKind.getLocalPart().equals("element") && - Constants.isSchemaXSD(elementKind.getNamespaceURI())) { + Node kid = elements.item(i); + if (isXSDNode(kid, "element")) { elementNode = elements.item(i); + break; } } @@ -989,70 +909,49 @@ } // Check for SimpleContent // If the node kind is an element, dive into it. - QName nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("element") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { + if (isXSDNode(node, "element")) { NodeList children = node.getChildNodes(); - Node complexNode = null; - for (int j = 0; j < children.getLength() && complexNode == null; j++) { - QName complexKind = Utils.getNodeQName(children.item(j)); - if (complexKind != null && - complexKind.getLocalPart().equals("complexType") && - Constants.isSchemaXSD(complexKind.getNamespaceURI())) { - complexNode = children.item(j); - node = complexNode; + for (int j = 0; j < children.getLength(); j++) { + Node kid = children.item(j); + if (isXSDNode(kid, "complexType")) { + node = kid; + break; } } } // Expecting a schema complexType - nodeKind = Utils.getNodeQName(node); - if (nodeKind != null && - nodeKind.getLocalPart().equals("complexType") && - Constants.isSchemaXSD(nodeKind.getNamespaceURI())) { - + if (isXSDNode(node, "complexType")) { // Under the complexType there could be complexContent/simpleContent // and extension elements if this is a derived type. Skip over these. NodeList children = node.getChildNodes(); Node content = null; - Node extension = null; - for (int j = 0; j < children.getLength() && content == null; j++) { - QName complexContentKind = Utils.getNodeQName(children.item(j)); - if (complexContentKind != null && - Constants.isSchemaXSD(complexContentKind.getNamespaceURI())) { - if (complexContentKind.getLocalPart().equals("complexContent") || - complexContentKind.getLocalPart().equals("simpleContent")) { - content = children.item(j); - } + for (int j = 0; j < children.getLength(); j++) { + Node kid = children.item(j); + if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent")) { + content = kid; + break; } } // Check for extensions if (content != null) { children = content.getChildNodes(); for (int j = 0; j < children.getLength(); j++) { - QName extensionKind = Utils.getNodeQName(children.item(j)); - if (extensionKind != null && - extensionKind.getLocalPart().equals("extension") && - Constants.isSchemaXSD(extensionKind.getNamespaceURI())) { - extension = children.item(j); + Node kid = children.item(j); + if (isXSDNode(kid, "extension")) { + node = kid; break; } } } - if (extension != null) { - node = extension; - } - // examine children of the node for <attribute> elements children = node.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); - nodeKind = Utils.getNodeQName(child); - if (nodeKind == null || - ! nodeKind.getLocalPart().equals("attribute")) + if (! isXSDNode(child, "attribute")) { continue; + } // we have an attribute node if (v == null) @@ -1076,14 +975,14 @@ String form = Utils.getAttribute(child, "form"); if (form != null && form.equals("unqualified")) { // Unqualified nodeName - attributeName = new QName("", attributeName.getLocalPart()); + attributeName = Utils.findQName("", attributeName.getLocalPart()); } else if (form == null) { // check attributeFormDefault on schema element String def = Utils.getScopedAttribute(child, "attributeFormDefault"); if (def == null || def.equals("unqualified")) { // Unqualified nodeName - attributeName = new QName("", attributeName.getLocalPart()); + attributeName = Utils.findQName("", attributeName.getLocalPart()); } } } else { @@ -1152,6 +1051,8 @@ "NMTOKEN", "NMTOKENS" }; + + private static final Set schemaTypeSet = new HashSet(Arrays.asList(schemaTypes)); /** * Determine if a string is a simple XML Schema type @@ -1159,14 +1060,8 @@ private static boolean isSimpleSchemaType(String s) { if (s == null) return false; - - // This is rather expensive. Probably should be - // a hash lookup. - for (int i = 0; i < schemaTypes.length; i++) { - if (schemaTypes[i].equals(s)) - return true; - } - return false; + + return schemaTypeSet.contains(s); } /** * Determine if a QName is a simple XML Schema type 1.3 +16 -0 xml-axis/java/src/org/apache/axis/wsdl/symbolTable/DefinedType.java Index: DefinedType.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/symbolTable/DefinedType.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- DefinedType.java 20 Jun 2002 20:35:47 -0000 1.2 +++ DefinedType.java 3 Jan 2003 13:56:08 -0000 1.3 @@ -62,11 +62,27 @@ * always emitted. */ public class DefinedType extends Type { + // cache lookups for our base type + protected TypeEntry extensionBase; + public DefinedType(QName pqName, Node pNode) { super(pqName, pNode); } public DefinedType(QName pqName, TypeEntry refType, Node pNode, String dims) { super(pqName, refType, pNode, dims); + } + + /** + * Get a TypeEntry for the base type of this type, if one exists. + * + * @param symbolTable a <code>SymbolTable</code> value + * @return a <code>TypeEntry</code> value + */ + public TypeEntry getComplexTypeExtensionBase(SymbolTable symbolTable) { + if (null == extensionBase) { + extensionBase = SchemaUtils.getComplexElementExtensionBase(getNode(), symbolTable); + } + return extensionBase; } }; 1.67 +73 -37 xml-axis/java/src/org/apache/axis/wsdl/symbolTable/SymbolTable.java Index: SymbolTable.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/symbolTable/SymbolTable.java,v retrieving revision 1.66 retrieving revision 1.67 diff -u -r1.66 -r1.67 --- SymbolTable.java 2 Jan 2003 00:02:42 -0000 1.66 +++ SymbolTable.java 3 Jan 2003 13:56:08 -0000 1.67 @@ -106,6 +106,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -139,8 +140,20 @@ private HashMap symbolTable = new HashMap(); - // A list of the TypeEntry elements in the symbol table - private Vector types = new Vector(); + // a map of qnames -> Elements in the symbol table + private final Map elementTypeEntries = new HashMap(); + // an unmodifiable wrapper so that we can share the index with others, safely + private final Map elementIndex = Collections.unmodifiableMap(elementTypeEntries); + // a map of qnames -> Types in the symbol table + private final Map typeTypeEntries = new HashMap(); + // an unmodifiable wrapper so that we can share the index with others, safely + private final Map typeIndex = Collections.unmodifiableMap(typeTypeEntries); + + /** cache of nodes -> base types for complexTypes. The cache is + * built on nodes because multiple TypeEntry objects may use the + * same node. + */ + protected final Map node2ExtensionBase = new HashMap(); // allow friendly access private boolean verbose; @@ -215,30 +228,19 @@ } // getTypeEntry /** - * Get the Type TypeEntry with the given QName. If it doesn't exist, return null. + * Get the Type TypeEntry with the given QName. If it doesn't + * exist, return null. */ public Type getType(QName qname) { - for (int i = 0; i < types.size(); ++i) { - TypeEntry type = (TypeEntry) types.get(i); - if (type.getQName().equals(qname) - && (type instanceof Type)) { - return (Type) type; - } - } - return null; + return (Type)typeTypeEntries.get(qname); } // getType /** - * Get the Element TypeEntry with the given QName. If it doesn't exist, return null. + * Get the Element TypeEntry with the given QName. If it doesn't + * exist, return null. */ public Element getElement(QName qname) { - for (int i = 0; i < types.size(); ++i) { - TypeEntry type = (TypeEntry) types.get(i); - if (type.getQName().equals(qname) && type instanceof Element) { - return (Element) type; - } - } - return null; + return (Element)elementTypeEntries.get(qname); } // getElement /** @@ -272,12 +274,46 @@ /** * Get the list of all the XML schema types in the symbol table. In other words, all entries * that are instances of TypeEntry. + * + * @deprecated use specialized get{Element,Type}Index() methods instead */ public Vector getTypes() { - return types; + Vector v = new Vector(); + v.addAll(elementTypeEntries.values()); + v.addAll(typeTypeEntries.values()); + return v; } // getTypes /** + * Return an unmodifiable map of qnames -> Elements in the symbol + * table. + * + * @return an unmodifiable <code>Map</code> value + */ + public Map getElementIndex() { + return elementIndex; + } + + /** + * Return an unmodifiable map of qnames -> Elements in the symbol + * table. + * + * @return an unmodifiable <code>Map</code> value + */ + public Map getTypeIndex() { + return typeIndex; + } + + /** + * Return the count of TypeEntries in the symbol table. + * + * @return an <code>int</code> value + */ + public int getTypeEntryCount() { + return elementTypeEntries.size() + typeTypeEntries.size(); + } + + /** * Get the Definition. The definition is null until * populate is called. */ @@ -1931,9 +1967,13 @@ if (stuff.isEmpty()) { stuff = def.getMessages(); if (stuff.isEmpty()) { - for (int i = 0; i < types.size(); ++i) { - TypeEntry type = (TypeEntry) types.get(i); - setTypeReferences(type, doc, false); + 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 { @@ -2264,12 +2304,8 @@ // Replace it in the symbol table v.setElementAt(entry, i); - // Replace it in the types Vector - for (int j = 0; j < types.size(); ++j) { - if (types.elementAt(j) == oldEntry) { - types.setElementAt(entry, j); - } - } + // 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); @@ -2289,12 +2325,8 @@ // Replace it in the symbol table v.setElementAt(entry, i); - // Replace it in the types Vector - for (int j = 0; j < types.size(); ++j) { - if (types.elementAt(j) == oldEntry) { - types.setElementAt(entry, j); - } - } + // 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); @@ -2309,8 +2341,12 @@ symbolTable.put(name, v); } v.add(entry); - if (entry instanceof TypeEntry) { - types.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); } } } 1.24 +52 -24 xml-axis/java/src/org/apache/axis/wsdl/symbolTable/Utils.java Index: Utils.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/symbolTable/Utils.java,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- Utils.java 2 Jan 2003 15:37:47 -0000 1.23 +++ Utils.java 3 Jan 2003 13:56:08 -0000 1.24 @@ -61,8 +61,10 @@ import javax.xml.namespace.QName; import javax.xml.rpc.holders.BooleanHolder; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.Map; import java.util.Vector; /** @@ -72,8 +74,39 @@ * @author Tom Jordahl ([EMAIL PROTECTED]) */ public class Utils { + /** cache of namespaces -> maps of localNames -> QNames */ + static final Map nsmap = new HashMap(); /** + * Find or create a QName with the specified namespace/localName. + * + * @param namespace + * @param localName + */ + static QName findQName(String namespace, String localName) { + QName qname = null; + + // get the inner map, using the namespace as a key + Map ln2qn = (Map)nsmap.get(namespace); + if (null == ln2qn) { // cache miss + ln2qn = new HashMap(); + nsmap.put(namespace, ln2qn); + + qname = new QName(namespace, localName); + ln2qn.put(localName, qname); + } else { // cache hit + qname = (QName)ln2qn.get(localName); + if (null == qname) { // cache miss + qname = new QName(namespace, localName); + ln2qn.put(localName, qname); + } else { + // cache hit + } + } + return qname; + } + + /** * getNillableQName returns the QName to use if the nillable=true * attribute is used. * For example, in JAX-RPC: @@ -95,13 +128,13 @@ localName.equals("double") || localName.equals("boolean") || localName.equals("byte")) { - rc = new QName(Constants.URI_DEFAULT_SOAP_ENC, + rc = findQName(Constants.URI_DEFAULT_SOAP_ENC, qName.getLocalPart()); } else if (localName.equals("base64Binary")) { - rc = new QName(Constants.URI_DEFAULT_SOAP_ENC, "base64"); + rc = findQName(Constants.URI_DEFAULT_SOAP_ENC, "base64"); } else if (localName.equals("hexBinary")) { - rc = new QName(Constants.URI_DEFAULT_SCHEMA_XSD, "hexBinary"); + rc = findQName(Constants.URI_DEFAULT_SCHEMA_XSD, "hexBinary"); } } return rc; @@ -186,7 +219,7 @@ } String namespace = node.getNamespaceURI(); - return (new QName(namespace, localName)); + return (findQName(namespace, localName)); } /** @@ -244,7 +277,7 @@ if (namespace == null) { namespace = getScopedAttribute(node, "targetNamespace"); } - return (new QName(namespace, localName)); + return (findQName(namespace, localName)); } /** @@ -308,7 +341,7 @@ } else if (!maxOccursValue.equals("1") || !minOccursValue.equals("1")) { String localPart = qName.getLocalPart(); localPart += "[" + maxOccursValue + "]"; - qName = new QName(qName.getNamespaceURI(), localPart); + qName = findQName(qName.getNamespaceURI(), localPart); } } } @@ -412,7 +445,7 @@ else { namespace = getScopedAttribute(node, "xmlns:" + prefixedName.substring(0, prefixedName.lastIndexOf(":"))); } - return (new QName(namespace, localName)); + return (findQName(namespace, localName)); } /** @@ -427,32 +460,27 @@ (type.getQName().getLocalPart().equals("anyType")|| type.getQName().getLocalPart().equals("any"))) { // All types are derived from anyType - types.addAll(symbolTable.getTypes()); + types.addAll(symbolTable.getTypeIndex().values()); } return types; } // getNestedTypes - private static void getDerivedTypes( - TypeEntry type, HashSet types, SymbolTable symbolTable) { + private static void getDerivedTypes(TypeEntry type, HashSet types, SymbolTable symbolTable) { // If all types are in the set, return - if (types.size() == symbolTable.getTypes().size()) { + if (types.size() == symbolTable.getTypeEntryCount()) { return; } // Search the dictionary for derived types of type - Vector allTypes = symbolTable.getTypes(); - Iterator it = allTypes.iterator(); - while(it.hasNext()) { - TypeEntry derivedType = (TypeEntry) it.next(); - if (derivedType instanceof DefinedType && - derivedType.getNode() != null && - !types.contains(derivedType) && - SchemaUtils.getComplexElementExtensionBase( - derivedType.getNode(), - symbolTable) == type) { - types.add(derivedType); - getDerivedTypes(derivedType, types, symbolTable); + for (Iterator it = symbolTable.getTypeIndex().values().iterator(); it.hasNext();) { + Type t = (Type)it.next(); + if (t instanceof DefinedType && + t.getNode() != null && + !types.contains(t) && + (((DefinedType)t).getComplexTypeExtensionBase(symbolTable) == type)) { + types.add(t); + getDerivedTypes(t, types, symbolTable); } } } // getDerivedTypes @@ -483,7 +511,7 @@ } // If all types are in the set, return - if (types.size() == symbolTable.getTypes().size()) { + if (types.size() == symbolTable.getTypeEntryCount()) { return; } 1.2 +3 -3 xml-axis/java/test/wsdl/qualify2/attribute-qualify.wsdl Index: attribute-qualify.wsdl =================================================================== RCS file: /home/cvs/xml-axis/java/test/wsdl/qualify2/attribute-qualify.wsdl,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- attribute-qualify.wsdl 1 Jul 2002 16:09:39 -0000 1.1 +++ attribute-qualify.wsdl 3 Jan 2003 13:56:09 -0000 1.2 @@ -19,10 +19,10 @@ <xsd:element name="number" type="xsd:string"/> </xsd:all> <!-- These attributes should be qualified --> - <attribute name="color" type="xsd:string"/> - <attribute name="hair" type="xsd:string" form="qualified"/> + <xsd:attribute name="color" type="xsd:string"/> + <xsd:attribute name="hair" type="xsd:string" form="qualified"/> <!-- This attribute should not --> - <attribute name="age" type="xsd:int" form="unqualified"/> + <xsd:attribute name="age" type="xsd:int" form="unqualified"/> </xsd:complexType> <xsd:element name="phone" type="s0:phone"/>