package org.jboss.axis.wsdl.symbolTable;
import org.jboss.axis.Constants;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
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;
public class SchemaUtils
{
static final QName VALUE_QNAME = Utils.findQName("", "value");
public static Vector getContainedElementDeclarations(Node node, SymbolTable symbolTable)
{
if (node == null)
{
return null;
}
if (isXSDNode(node, "element"))
{
NodeList children = node.getChildNodes();
for (int j = 0; j < children.getLength(); j++)
{
Node kid = children.item(j);
if (isXSDNode(kid, "complexType"))
{
node = kid;
break;
}
}
}
if (isXSDNode(node, "complexType"))
{
NodeList children = node.getChildNodes();
Node complexContent = null;
Node simpleContent = null;
Node extension = null;
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)
{
children = complexContent.getChildNodes();
for (int j = 0; j < children.getLength() && extension == null; j++)
{
Node kid = children.item(j);
if (isXSDNode(kid, "extension"))
{
extension = kid;
}
}
}
if (simpleContent != null)
{
children = simpleContent.getChildNodes();
for (int j = 0; j < children.getLength() && extension == null; j++)
{
QName extensionOrRestrictionKind = Utils.getNodeQName(children.item(j));
if (extensionOrRestrictionKind != null &&
(extensionOrRestrictionKind.getLocalPart().equals("extension") ||
extensionOrRestrictionKind.getLocalPart().equals("restriction")) &&
Constants.isSchemaXSD(extensionOrRestrictionKind.getNamespaceURI()))
{
QName extendsOrRestrictsType =
Utils.getTypeQName(children.item(j), new BooleanHolder(), false);
Vector v = new Vector();
ElementDecl elem = new ElementDecl();
elem.setType(symbolTable.getTypeEntry(extendsOrRestrictsType, false));
elem.setName(VALUE_QNAME);
v.add(elem);
return v;
}
}
}
if (extension != null)
{
node = extension; }
children = node.getChildNodes();
Vector v = new Vector();
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("sequence"))
{
v.addAll(processSequenceNode(children.item(j), symbolTable));
}
else if (subNodeKind.getLocalPart().equals("all"))
{
v.addAll(processAllNode(children.item(j), symbolTable));
}
else if (subNodeKind.getLocalPart().equals("choice"))
{
v.addAll(processChoiceNode(children.item(j), symbolTable));
}
else if (subNodeKind.getLocalPart().equals("group"))
{
v.addAll(processGroupNode(children.item(j), symbolTable));
}
}
}
return v;
}
else
{
QName simpleQName = getSimpleTypeBase(node);
if (simpleQName != null)
{
TypeEntry simpleType = symbolTable.getType(simpleQName);
if (simpleType != null)
{
Vector v = new Vector();
ElementDecl elem = new ElementDecl();
elem.setType(simpleType);
elem.setName(new javax.xml.namespace.QName("", "value"));
v.add(elem);
return v;
}
}
}
return null;
}
private static Vector processChoiceNode(Node choiceNode,
SymbolTable symbolTable)
{
Vector v = new Vector();
NodeList children = choiceNode.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("choice"))
{
v.addAll(processChoiceNode(children.item(j), symbolTable));
}
else if (subNodeKind.getLocalPart().equals("sequence"))
{
v.addAll(processSequenceNode(children.item(j), symbolTable));
}
else if (subNodeKind.getLocalPart().equals("group"))
{
v.addAll(processGroupNode(children.item(j), symbolTable));
}
else if (subNodeKind.getLocalPart().equals("element"))
{
ElementDecl elem =
processChildElementNode(children.item(j),
symbolTable);
if (elem != null)
v.add(elem);
}
}
}
return v;
}
private static Vector processSequenceNode(Node sequenceNode,
SymbolTable symbolTable)
{
Vector v = new Vector();
NodeList children = sequenceNode.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("choice"))
{
v.addAll(processChoiceNode(children.item(j), symbolTable));
}
else if (subNodeKind.getLocalPart().equals("sequence"))
{
v.addAll(processSequenceNode(children.item(j), symbolTable));
}
else if (subNodeKind.getLocalPart().equals("group"))
{
v.addAll(processGroupNode(children.item(j), symbolTable));
}
else if (subNodeKind.getLocalPart().equals("any"))
{
TypeEntry type = symbolTable.getType(Constants.XSD_ANY);
ElementDecl elem =
new ElementDecl(type, Utils.findQName("", "any"));
elem.setAnyElement(true);
v.add(elem);
}
else if (subNodeKind.getLocalPart().equals("element"))
{
ElementDecl elem =
processChildElementNode(children.item(j),
symbolTable);
if (elem != null)
v.add(elem);
}
}
}
return v;
}
private static Vector processGroupNode(Node groupNode, SymbolTable symbolTable)
{
Vector v = new Vector();
NodeList children = groupNode.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("choice"))
{
v.addAll(processChoiceNode(children.item(j), symbolTable));
}
else if (subNodeKind.getLocalPart().equals("sequence"))
{
v.addAll(processSequenceNode(children.item(j), symbolTable));
}
else if (subNodeKind.getLocalPart().equals("all"))
{
v.addAll(processAllNode(children.item(j), symbolTable));
}
}
}
return v;
}
private static Vector processAllNode(Node allNode, SymbolTable symbolTable)
{
Vector v = new Vector();
NodeList children = allNode.getChildNodes();
for (int j = 0; j < children.getLength(); j++)
{
Node kid = children.item(j);
if (isXSDNode(kid, "element"))
{
ElementDecl elem = processChildElementNode(kid, symbolTable);
if (elem != null)
{
v.add(elem);
}
}
}
return v;
}
private static ElementDecl processChildElementNode(Node elementNode,
SymbolTable symbolTable)
{
QName nodeName = Utils.getNodeNameQName(elementNode);
BooleanHolder forElement = new BooleanHolder();
QName nodeType = Utils.getTypeQName(elementNode, forElement, false);
TypeEntry type = symbolTable.getTypeEntry(nodeType, forElement.value);
if (!forElement.value)
{
String form = Utils.getAttribute(elementNode, "form");
if (form != null && form.equals("unqualified"))
{
nodeName = Utils.findQName("", nodeName.getLocalPart());
}
else if (form == null)
{
String def = Utils.getScopedAttribute(elementNode,
"elementFormDefault");
if (def == null || def.equals("unqualified"))
{
nodeName = Utils.findQName("", nodeName.getLocalPart());
}
}
}
if (type != null)
{
ElementDecl elem = new ElementDecl(type, nodeName);
String minOccurs = Utils.getAttribute(elementNode, "minOccurs");
if (minOccurs != null && minOccurs.equals("0"))
{
elem.setMinOccursIs0(true);
}
return elem;
}
return null;
}
public static QName getElementAnonQName(Node node)
{
if (isXSDNode(node, "element"))
{
NodeList children = node.getChildNodes();
for (int j = 0; j < children.getLength(); j++)
{
Node kid = children.item(j);
if (isXSDNode(kid, "complexType") || isXSDNode(kid, "simpleType"))
{
return Utils.getNodeNameQName(kid);
}
}
}
return null;
}
public static QName getAttributeAnonQName(Node node)
{
if (isXSDNode(node, "attribute"))
{
NodeList children = node.getChildNodes();
for (int j = 0; j < children.getLength(); j++)
{
Node kid = children.item(j);
if (isXSDNode(kid, "complexType") || isXSDNode(kid, "simpleType"))
{
return Utils.getNodeNameQName(kid);
}
}
}
return null;
}
public static boolean isSimpleTypeOrSimpleContent(Node node)
{
if (node == null)
{
return false;
}
if (isXSDNode(node, "element"))
{
NodeList children = node.getChildNodes();
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;
}
}
}
if (isXSDNode(node, "simpleType"))
{
return true;
}
if (isXSDNode(node, "complexType"))
{
NodeList children = node.getChildNodes();
Node complexContent = null;
Node simpleContent = null;
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)
{
return false;
}
if (simpleContent != null)
{
return true;
}
}
return false;
}
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;
}
public static TypeEntry getComplexElementExtensionBase(Node node, SymbolTable symbolTable)
{
if (node == null)
{
return null;
}
TypeEntry cached = (TypeEntry)symbolTable.node2ExtensionBase.get(node);
if (cached != null)
{
return cached; }
if (isXSDNode(node, "element"))
{
NodeList children = node.getChildNodes();
Node complexNode = null;
for (int j = 0; j < children.getLength() && complexNode == null; j++)
{
if (isXSDNode(children.item(j), "complexType"))
{
complexNode = children.item(j);
node = complexNode;
}
}
}
if (isXSDNode(node, "complexType"))
{
NodeList children = node.getChildNodes();
Node content = null;
Node extension = null;
for (int j = 0; j < children.getLength() && content == null; 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++)
{
Node kid = children.item(j);
if (isXSDNode(kid, "extension"))
{
extension = kid;
}
}
}
if (extension == null)
{
cached = null;
}
else
{
QName extendsType = Utils.getTypeQName(extension, new BooleanHolder(), false);
if (extendsType == null)
{
cached = null;
}
else
{
cached = symbolTable.getType(extendsType);
}
}
}
symbolTable.node2ExtensionBase.put(node, cached);
return cached;
}
public static QName getSimpleTypeBase(Node node)
{
QName baseQName = null;
if (node == null)
{
return null;
}
QName nodeKind = Utils.getNodeQName(node);
if (isXSDNode(node, "element"))
{
NodeList children = node.getChildNodes();
for (int j = 0; j < children.getLength(); j++)
{
if (isXSDNode(children.item(j), "simpleType"))
{
node = children.item(j);
break;
}
}
}
if (isXSDNode(node, "simpleType"))
{
NodeList children = node.getChildNodes();
Node restrictionNode = null;
for (int j = 0; j < children.getLength() && restrictionNode == null; j++)
{
if (isXSDNode(children.item(j), "restriction"))
{
restrictionNode = children.item(j);
}
}
if (restrictionNode != null)
{
baseQName = Utils.getTypeQName(restrictionNode, new BooleanHolder(), false);
}
if (baseQName != null && restrictionNode != null)
{
NodeList enums = restrictionNode.getChildNodes();
for (int i = 0; i < enums.getLength(); i++)
{
if (isXSDNode(enums.item(i), "enumeration"))
{
return null;
}
}
}
}
return baseQName;
}
public static Node getRestrictionOrExtensionNode(Node node)
{
Node re = null;
if (node == null)
{
return re;
}
if (isXSDNode(node, "element"))
{
NodeList children = node.getChildNodes();
Node node2 = null;
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;
}
}
}
if (isXSDNode(node, "simpleType") || isXSDNode(node, "complexType"))
{
NodeList children = node.getChildNodes();
Node complexContent = null;
if (node.getLocalName().equals("complexType"))
{
for (int j = 0; j < children.getLength() && complexContent == null; j++)
{
Node kid = children.item(j);
if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent"))
{
complexContent = kid;
}
}
node = complexContent;
}
if (node != null)
{
children = node.getChildNodes();
for (int j = 0; j < children.getLength() && re == null; j++)
{
Node kid = children.item(j);
if (isXSDNode(kid, "extension") || isXSDNode(kid, "restriction"))
{
re = kid;
}
}
}
}
return re;
}
public static QName getArrayComponentQName(Node node, IntHolder dims)
{
dims.value = 1; QName qName = getCollectionComponentQName(node);
if (qName == null)
{
qName = getArrayComponentQName_JAXRPC(node, dims);
}
return qName;
}
public static QName getCollectionComponentQName(Node node)
{
if (node == null)
{
return null;
}
if (isXSDNode(node, "element"))
{
BooleanHolder forElement = new BooleanHolder();
QName componentQName = Utils.getTypeQName(node, forElement, true);
if (componentQName != null)
{
QName fullQName = Utils.getTypeQName(node, forElement, false);
if (!componentQName.equals(fullQName))
{
return componentQName;
}
}
}
return null;
}
private static QName getArrayComponentQName_JAXRPC(Node node, IntHolder dims)
{
dims.value = 0; if (node == null)
{
return null;
}
if (isXSDNode(node, "element"))
{
NodeList children = node.getChildNodes();
for (int j = 0; j < children.getLength(); j++)
{
Node kid = children.item(j);
if (isXSDNode(kid, "complexType"))
{
node = kid;
break;
}
}
}
if (isXSDNode(node, "complexType"))
{
NodeList children = node.getChildNodes();
Node complexContentNode = null;
for (int j = 0; j < children.getLength(); j++)
{
Node kid = children.item(j);
if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent"))
{
complexContentNode = kid;
break;
}
}
Node restrictionNode = null;
if (complexContentNode != null)
{
children = complexContentNode.getChildNodes();
for (int j = 0; j < children.getLength(); j++)
{
Node kid = children.item(j);
if (isXSDNode(kid, "restriction"))
{
restrictionNode = kid;
break;
}
}
}
QName baseType = null;
if (restrictionNode != null)
{
baseType = Utils.getTypeQName(restrictionNode, new BooleanHolder(), false);
if (baseType != null &&
baseType.getLocalPart().equals("Array") &&
Constants.isSOAP_ENC(baseType.getNamespaceURI()))
; else
baseType = null; }
Node groupNode = null;
Node attributeNode = null;
if (baseType != null)
{
children = restrictionNode.getChildNodes();
for (int j = 0;
j < children.getLength() && groupNode == null && attributeNode == null;
j++)
{
Node kid = children.item(j);
if (isXSDNode(kid, "sequence") || isXSDNode(kid, "all"))
{
groupNode = kid;
if (groupNode.getChildNodes().getLength() == 0)
{
groupNode = null;
}
}
if (isXSDNode(kid, "attribute"))
{
BooleanHolder isRef = new BooleanHolder();
QName refQName = Utils.getTypeQName(kid, isRef, false);
if (refQName != null &&
isRef.value &&
refQName.getLocalPart().equals("arrayType") &&
Constants.isSOAP_ENC(refQName.getNamespaceURI()))
{
attributeNode = kid;
}
}
}
}
if (attributeNode != null)
{
String wsdlArrayTypeValue = null;
Vector attrs = Utils.getAttributesWithLocalName(attributeNode, "arrayType");
for (int i = 0; i < attrs.size() && wsdlArrayTypeValue == null; i++)
{
Node attrNode = (Node)attrs.elementAt(i);
String attrName = attrNode.getNodeName();
QName attrQName = Utils.getQNameFromPrefixedName(attributeNode, attrName);
if (Constants.isWSDL(attrQName.getNamespaceURI()))
{
wsdlArrayTypeValue = attrNode.getNodeValue();
}
}
if (wsdlArrayTypeValue != null)
{
int i = wsdlArrayTypeValue.indexOf('[');
if (i > 0)
{
String prefixedName = wsdlArrayTypeValue.substring(0, i);
String mangledString = wsdlArrayTypeValue.replace(',', '[');
dims.value = 0;
int index = mangledString.indexOf('[');
while (index > 0)
{
dims.value++;
index = mangledString.indexOf('[', index + 1);
}
return Utils.getQNameFromPrefixedName(restrictionNode, prefixedName);
}
}
}
else if (groupNode != null)
{
NodeList elements = groupNode.getChildNodes();
Node elementNode = null;
for (int i = 0; i < elements.getLength() && elementNode == null; i++)
{
Node kid = elements.item(i);
if (isXSDNode(kid, "element"))
{
elementNode = elements.item(i);
break;
}
}
if (elementNode != null)
{
String maxOccursValue = Utils.getAttribute(elementNode, "maxOccurs");
if (maxOccursValue != null &&
maxOccursValue.equalsIgnoreCase("unbounded"))
{
dims.value = 1;
return Utils.getTypeQName(elementNode, new BooleanHolder(), true);
}
}
}
}
return null;
}
public static Vector getContainedAttributeTypes(Node node,
SymbolTable symbolTable)
{
Vector v = null;
if (node == null)
{
return null;
}
if (isXSDNode(node, "element"))
{
NodeList children = node.getChildNodes();
for (int j = 0; j < children.getLength(); j++)
{
Node kid = children.item(j);
if (isXSDNode(kid, "complexType"))
{
node = kid;
break;
}
}
}
if (isXSDNode(node, "complexType"))
{
NodeList children = node.getChildNodes();
Node content = null;
for (int j = 0; j < children.getLength(); j++)
{
Node kid = children.item(j);
if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent"))
{
content = kid;
break;
}
}
if (content != null)
{
children = content.getChildNodes();
for (int j = 0; j < children.getLength(); j++)
{
Node kid = children.item(j);
if (isXSDNode(kid, "extension"))
{
node = kid;
break;
}
}
}
children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++)
{
Node child = children.item(i);
if (!isXSDNode(child, "attribute"))
{
continue;
}
if (v == null)
v = new Vector();
QName attributeName = Utils.getNodeNameQName(child);
BooleanHolder forElement = new BooleanHolder();
QName attributeType = Utils.getTypeQName(child, forElement, false);
if (!forElement.value)
{
String form = Utils.getAttribute(child, "form");
if (form != null && form.equals("unqualified"))
{
attributeName = Utils.findQName("", attributeName.getLocalPart());
}
else if (form == null)
{
String def = Utils.getScopedAttribute(child,
"attributeFormDefault");
if (def == null || def.equals("unqualified"))
{
attributeName = Utils.findQName("", attributeName.getLocalPart());
}
}
}
else
{
attributeName = attributeType;
}
TypeEntry type = symbolTable.getTypeEntry(attributeType,
forElement.value);
if (type != null && attributeName != null)
{
v.add(type);
v.add(attributeName);
}
}
}
return v;
}
private static String schemaTypes[] = {
"string",
"normalizedString",
"token",
"byte",
"unsignedByte",
"base64Binary",
"hexBinary",
"integer",
"positiveInteger",
"negativeInteger",
"nonNegativeInteger",
"nonPositiveInteger",
"int",
"unsignedInt",
"long",
"unsignedLong",
"short",
"unsignedShort",
"decimal",
"float",
"double",
"boolean",
"time",
"dateTime",
"duration",
"date",
"gMonth",
"gYear",
"gYearMonth",
"gDay",
"gMonthDay",
"Name",
"QName",
"NCName",
"anyURI",
"language",
"ID",
"IDREF",
"IDREFS",
"ENTITY",
"ENTITIES",
"NOTATION",
"NMTOKEN",
"NMTOKENS"
};
private static final Set schemaTypeSet = new HashSet(Arrays.asList(schemaTypes));
private static boolean isSimpleSchemaType(String s)
{
if (s == null)
return false;
return schemaTypeSet.contains(s);
}
public static boolean isSimpleSchemaType(QName qname)
{
if (qname == null ||
!Constants.isSchemaXSD(qname.getNamespaceURI()))
{
return false;
}
return isSimpleSchemaType(qname.getLocalPart());
}
}