Mercurial > repos > ganjoo > webservice_toolsuite
diff WebServiceToolWorkflow/lib/SAWADLParser/src/edu/uga/cs/lsdis/meteors/wadls/util/SchemaUtils.java @ 0:d5cd409b8a18 default tip
Migrated tool version 1.0.0 from old tool shed archive to new tool shed repository
author | ganjoo |
---|---|
date | Tue, 07 Jun 2011 18:00:50 -0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebServiceToolWorkflow/lib/SAWADLParser/src/edu/uga/cs/lsdis/meteors/wadls/util/SchemaUtils.java Tue Jun 07 18:00:50 2011 -0400 @@ -0,0 +1,543 @@ +/* + * Created on Apr 10, 2005 + * + */ +package edu.uga.cs.lsdis.meteors.wadls.util; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.wadls.Grammars; +import javax.wadls.Params; +import javax.wadls.WADLSException; +import javax.wadls.extensions.schema.Schema; +import javax.xml.namespace.QName; + +import org.w3c.dom.DOMException; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import edu.uga.cs.lsdis.meteors.wadls.Constants; +import edu.uga.cs.lsdis.meteors.wadls.extensions.schema.SchemaConstants; +import edu.uga.cs.lsdis.meteors.wadls.util.xml.QNameUtils; +import edu.uga.cs.lsdis.meteors.wadls.util.xml.XPathUtils; + +/** + * This file is a collection of utilities which find the location of a XML/XSD Element by using the given path. + * @author Zixin Wu + * + */ + +public class SchemaUtils { + + /** + * Search an XML element in the schemas contained in the given Types. + * @param types Search in the schemas contained in this WSDLS Types. + * @param tagName XML Element name of the desired element. + * @param elementName The value of the attribute "name" of the desired element. + * @return An XML element whose XML Element name is "tagName" and whose attribute "name" is "elementName". + * @throws WADLSException + */ + public static Element findXMLEleInSchemas(Grammars grammars, String tagName, QName elementName) throws WADLSException{ + Map schemas = grammars.getSchemas(); + Iterator it = schemas.values().iterator(); + while(it.hasNext()){ + Schema schema = (Schema)(it.next()); + Element schemaEle = schema.getElement(); + if (schemaEle.getAttribute(Constants.ATTR_TARGET_NAMESPACE).equals(elementName.getNamespaceURI())){ + Element foundEle = findXMLEleByName(schemaEle, tagName, elementName); + if (foundEle != null) + return foundEle; + } + } + return null; + } + + /** + * Search the element whose XML Element name is "tagName" and whose attribute "name" is "elementName", + * in the startElement, search in only one level depth. + * @param startElement Start searching from this XML Element. + * @param tagName XML Element name of the desired element. + * @param elementName The value of the attribute "name" of the desired element. + * @return An XML element whose XML Element name is "tagName" and whose attribute "name" is "elementName". + * @throws WADLSException + */ + public static Element findXMLEleByName(Element startElement, String tagName, QName elementName) throws WADLSException{ + NodeList nodeList = startElement.getChildNodes(); + //find the element with the required name as an attribute + int listLength = nodeList.getLength(); + for(int i=0;i<listLength;i++){ + Node currentNode = nodeList.item(i); + if (currentNode.getNodeType() != Node.ELEMENT_NODE) continue; + Element currentElement = (Element)nodeList.item(i); + //get the "name" attribute + String nameAttr = currentElement.getAttribute(SchemaConstants.ATTR_NAME); + QName qNameAttr = QNameUtils.getQName(nameAttr, currentElement); + //compare both namespaceURI and localname of the "name" attribute + if (elementName == null || qNameAttr.equals(elementName)){ + //compare localname of the tag, and check namespace of the tag is XSD + QName currentTagQName = QNameUtils.getQName(currentElement.getTagName(), currentElement); + if (SchemaConstants.XSD_STR_LIST.contains(currentTagQName.getNamespaceURI()) + && tagName.equals(currentTagQName.getLocalPart())){ + //this is the element we are looking for. + return currentElement; + } + } + } + return null; + } + + + /** + * Return a list of XSD elements contained in the startElement (XSD Element), search in only 1 level depth. + * @param startElement Start search from this XSD element. + * @param types WSDLS Types + * @return A list of XSD elements contained in the startElement. If no XSD element is contained, the list has 0 element. + * @throws WADLSException + */ + public static List listXSDElesInEle(Element startElement, Grammars grammars) throws WADLSException{ + String refAttr = startElement.getAttribute(SchemaConstants.ATTR_REF); + if (refAttr != ""){ + //look for the referenced element + QName elementQName = QNameUtils.getQName(refAttr, startElement); + Element refenecedElement = findXMLEleInSchemas(grammars, SchemaConstants.ELEM_ELEMENT, elementQName); + if (refenecedElement != null) + return listXSDElesInEle(refenecedElement, grammars); + else{ + throw new DOMException(DOMException.NOT_FOUND_ERR, "Cannot find referenced element"); + } + } + else{ + Element complexElement = null; + String typeAttr = startElement.getAttribute(SchemaConstants.ATTR_TYPE); + if (typeAttr != ""){ + //get the QName of typeAttr + QName typeQName = QNameUtils.getQName(typeAttr, startElement); + if (SchemaConstants.XSD_STR_LIST.contains(typeQName.getNamespaceURI())) + //primitive data type + return new ArrayList(); + else{ + //ComplexType or SimpleType + complexElement = findXMLEleInSchemas(grammars, SchemaConstants.ELEM_COMPLEXTYPE, typeQName); + if (complexElement == null) + //simpleType + return new ArrayList();; + } + } + else{ + //No type, look for complexType in the subNodes + complexElement = findXMLEleByName(startElement, SchemaConstants.ELEM_COMPLEXTYPE, null); + if (complexElement == null){ + WADLSException wsdlsExc = new WADLSException(WADLSException.NOT_FOUND_ELE_BY_PATH, + "cannot find complexType matching the path"); + wsdlsExc.setLocation(XPathUtils.getXPathExprFromNode(startElement)); + throw wsdlsExc; + } + } + + //we got the complexType element so far. + //we need to collect all the elements + return listXSDElesInComplexType(complexElement); + } + } + + public static List listXSDElesInEle(Element startElement, Params params) throws WADLSException{ + /*String refAttr = startElement.getAttribute(SchemaConstants.ATTR_REF); + if (refAttr != ""){ + //look for the referenced element + QName elementQName = QNameUtils.getQName(refAttr, startElement); + Element refenecedElement = findXMLEleInSchemas(grammars, SchemaConstants.ELEM_ELEMENT, elementQName); + if (refenecedElement != null) + return listXSDElesInEle(refenecedElement, grammars); + else{ + throw new DOMException(DOMException.NOT_FOUND_ERR, "Cannot find referenced element"); + } + } + else{ + Element complexElement = null; + String typeAttr = startElement.getAttribute(SchemaConstants.ATTR_TYPE); + if (typeAttr != ""){ + //get the QName of typeAttr + QName typeQName = QNameUtils.getQName(typeAttr, startElement); + if (SchemaConstants.XSD_STR_LIST.contains(typeQName.getNamespaceURI())) + //primitive data type + return new ArrayList(); + else{ + //ComplexType or SimpleType + complexElement = findXMLEleInSchemas(grammars, SchemaConstants.ELEM_COMPLEXTYPE, typeQName); + if (complexElement == null) + //simpleType + return new ArrayList();; + } + } + else{ + //No type, look for complexType in the subNodes + complexElement = findXMLEleByName(startElement, SchemaConstants.ELEM_COMPLEXTYPE, null); + if (complexElement == null){ + WADLSException wsdlsExc = new WADLSException(WADLSException.NOT_FOUND_ELE_BY_PATH, + "cannot find complexType matching the path"); + wsdlsExc.setLocation(XPathUtils.getXPathExprFromNode(startElement)); + throw wsdlsExc; + } + } + + //we got the complexType element so far. + //we need to collect all the elements + return listXSDElesInComplexType(complexElement); + }*/ + + List temp = null; + temp.set(1, startElement); + return temp; + + } + + /** + * Return a list of XSD elements contained in the complexElement (XSD complexType), search in only 1 level depth. + * @param complexElement Start search from this XSD complexType. + * @return A list of XSD elements contained in the startElement. If no XSD element is contained, the list has 0 element. + * @throws WADLSException + */ + public static List listXSDElesInComplexType(Element complexElement) throws WADLSException{ + List subElements = new ArrayList(); + + NodeList subNodes = complexElement.getChildNodes(); + int length = subNodes.getLength(); + for(int i=0;i<length;i++){ + Node currentNode = subNodes.item(i); + if (currentNode.getNodeType() != Node.ELEMENT_NODE) continue; + Element currentElement = (Element)currentNode; + String tagName = currentElement.getTagName(); + QName tagQName = QNameUtils.getQName(tagName, currentElement); + String localPart = tagQName.getLocalPart(); + if (!SchemaConstants.XSD_STR_LIST.contains(tagQName.getNamespaceURI())) + continue; + if (localPart.equals(SchemaConstants.ELEM_ELEMENT)) + subElements.add(currentElement); + else if + (localPart.equals(SchemaConstants.ELEM_ALL) + || localPart.equals(SchemaConstants.ELEM_SEQUENCE) + || localPart.equals(SchemaConstants.ELEM_CHOICE) + || localPart.equals(SchemaConstants.ELEM_COMPLEXCONTENT) + || localPart.equals(SchemaConstants.ELEM_RESTRICTION) + ) + //Just skip it, call this method recursively. + subElements.addAll(listXSDElesInComplexType(currentElement)); + } + return subElements; + } + + /** + * Search an XSD element located by the startElement and path. + * @param startElement Start search from this XSD element. + * @param path + * @param types WSDLS Types + * @return An XSD element + * @throws WADLSException + */ + public static Element findXSDEleOnEle(Element startElement, String path, Grammars grammars) throws WADLSException{ + String refAttr = startElement.getAttribute(SchemaConstants.ATTR_REF); + if (refAttr != ""){ + //look for the referenced element + QName elementQName = QNameUtils.getQName(refAttr, startElement); + Element refenecedElement = findXMLEleInSchemas(grammars, SchemaConstants.ELEM_ELEMENT, elementQName); + if (refenecedElement != null) + return findXSDEleOnEle(refenecedElement, path, grammars); + else{ + throw new DOMException(DOMException.NOT_FOUND_ERR, "Cannot find referenced element"); + } + } + else{ + if (path == "") + return startElement; + + String typeAttr = startElement.getAttribute(SchemaConstants.ATTR_TYPE); + if (typeAttr != ""){ //<... type="..."> + //get the QName of typeAttr + QName typeQName = QNameUtils.getQName(typeAttr, startElement); + if (SchemaConstants.XSD_STR_LIST.contains(typeQName.getNamespaceURI())){ + //primitive data type + WADLSException wsdlsExc = new WADLSException(WADLSException.PATH_ERROR, + "Primitive type cannot has path"); + wsdlsExc.setLocation(XPathUtils.getXPathExprFromNode(startElement)); + throw wsdlsExc; + } + else{ + //find the complexType with the given type QName + Element complexTypeElement = findXMLEleInSchemas(grammars, SchemaConstants.ELEM_COMPLEXTYPE, typeQName); + if (complexTypeElement != null) + return findXSDEleOnComplexType(complexTypeElement, path, grammars); + else + //cannot find in complexType + throw new DOMException(DOMException.NOT_FOUND_ERR, "cannot find complexType by the given path"); + } + } + else{ + //No type, look for complexType in the subNodes + Element complexElement = findXMLEleByName(startElement, SchemaConstants.ELEM_COMPLEXTYPE, null); + if (complexElement != null) + return findXSDEleOnComplexType(complexElement, path, grammars); + else{ + WADLSException wsdlsExc = new WADLSException(WADLSException.NOT_FOUND_ELE_BY_PATH, + "cannot find complexType matching the path"); + wsdlsExc.setLocation(XPathUtils.getXPathExprFromNode(startElement)); + throw wsdlsExc; + } + } + } + } + + public static Element findXSDEleOnEle(Element startElement, String path, Params params) throws WADLSException{ + /*String refAttr = startElement.getAttribute(SchemaConstants.ATTR_REF); + if (refAttr != ""){ + //look for the referenced element + QName elementQName = QNameUtils.getQName(refAttr, startElement); + Element refenecedElement = findXMLEleInSchemas(params, SchemaConstants.ELEM_ELEMENT, elementQName); + if (refenecedElement != null) + return findXSDEleOnEle(refenecedElement, path, grammars); + else{ + throw new DOMException(DOMException.NOT_FOUND_ERR, "Cannot find referenced element"); + } + } + else{ + if (path == "") + return startElement; + + String typeAttr = startElement.getAttribute(SchemaConstants.ATTR_TYPE); + if (typeAttr != ""){ //<... type="..."> + //get the QName of typeAttr + QName typeQName = QNameUtils.getQName(typeAttr, startElement); + if (SchemaConstants.XSD_STR_LIST.contains(typeQName.getNamespaceURI())){ + //primitive data type + WADLSException wsdlsExc = new WADLSException(WADLSException.PATH_ERROR, + "Primitive type cannot has path"); + wsdlsExc.setLocation(XPathUtils.getXPathExprFromNode(startElement)); + throw wsdlsExc; + } + else{ + //find the complexType with the given type QName + Element complexTypeElement = findXMLEleInSchemas(grammars, SchemaConstants.ELEM_COMPLEXTYPE, typeQName); + if (complexTypeElement != null) + return findXSDEleOnComplexType(complexTypeElement, path, grammars); + else + //cannot find in complexType + throw new DOMException(DOMException.NOT_FOUND_ERR, "cannot find complexType by the given path"); + } + } + else{ + //No type, look for complexType in the subNodes + Element complexElement = findXMLEleByName(startElement, SchemaConstants.ELEM_COMPLEXTYPE, null); + if (complexElement != null) + return findXSDEleOnComplexType(complexElement, path, grammars); + else{ + WADLSException wsdlsExc = new WADLSException(WADLSException.NOT_FOUND_ELE_BY_PATH, + "cannot find complexType matching the path"); + wsdlsExc.setLocation(XPathUtils.getXPathExprFromNode(startElement)); + throw wsdlsExc; + } + } + }*/ + return startElement; + } + + /** + * Search an XSD Element from the XSD complexType. + * @param complexTypeElement Start searching from this XSD ComplexType + * @param path + * @param types WSDLS Types + * @return An XSD Element + * @throws WADLSException + */ + public static Element findXSDEleOnComplexType(Element complexTypeElement, String path, Grammars grammars) throws WADLSException{ + if (path == null || path == "") + return null; + //look for the matching element. + String splitedPath[] = splitPath(path); + String elementName = splitedPath[0]; + path = splitedPath[1]; + Element targetElement = findXSDEleInComplexType(complexTypeElement, elementName, grammars); + if (targetElement != null) + return findXSDEleOnEle(targetElement, path, grammars); + else{ + WADLSException wsdlsExc = new WADLSException(WADLSException.NOT_FOUND_ELE_BY_PATH, + "Cannot find the element matching the path"); + wsdlsExc.setLocation(XPathUtils.getXPathExprFromNode(complexTypeElement)); + throw wsdlsExc; + } + } + + public static Element findXSDEleOnComplexType(Element complexTypeElement, String path, Params params) throws WADLSException{ + /*if (path == null || path == "") + return null; + //look for the matching element. + String splitedPath[] = splitPath(path); + String elementName = splitedPath[0]; + path = splitedPath[1]; + Element targetElement = findXSDEleInComplexType(complexTypeElement, elementName, grammars); + if (targetElement != null) + return findXSDEleOnEle(targetElement, path, grammars); + else{ + WADLSException wsdlsExc = new WADLSException(WADLSException.NOT_FOUND_ELE_BY_PATH, + "Cannot find the element matching the path"); + wsdlsExc.setLocation(XPathUtils.getXPathExprFromNode(complexTypeElement)); + throw wsdlsExc; + }*/ + return complexTypeElement; + } + + /** + * Search an XSD Element recursively inside of the complexType. + * @param startElement + * @param elementName The desired attribute "name" + * @param types WSDL Types + * @return A XSD Element + * @throws WADLSException + */ + public static Element findXSDEleInComplexType(Element startElement, String elementName, Grammars grammars) throws WADLSException{ + NodeList subNodes = startElement.getChildNodes(); + int length = subNodes.getLength(); + for(int i=0;i<length;i++){ + Node currentNode = subNodes.item(i); + if (currentNode.getNodeType() != Node.ELEMENT_NODE) continue; + Element currentElement = (Element)currentNode; + String tagName = currentElement.getTagName(); + QName tagQName = QNameUtils.getQName(tagName, currentElement); + String localPart = tagQName.getLocalPart(); + if (!SchemaConstants.XSD_STR_LIST.contains(tagQName.getNamespaceURI())) + continue; + if (localPart.equals(SchemaConstants.ELEM_ELEMENT)){ + String refAttr = currentElement.getAttribute(SchemaConstants.ATTR_REF); + if (refAttr != ""){ + if (refAttr.equals(elementName)){ //TODO need to compare the namespaces + //look for the referenced element + QName elementQName = QNameUtils.getQName(refAttr, currentElement); + Element refenecedElement = findXMLEleInSchemas(grammars, SchemaConstants.ELEM_ELEMENT, elementQName); + return refenecedElement; + } + } + else{ + String nameAttr = currentElement.getAttribute(SchemaConstants.ATTR_NAME); +// if (nameAttr == "") continue; + if (nameAttr.equals(elementName)) //TODO need to compare the namespaces + //this is the element we are looking for. + return currentElement; + } + } + else if + (localPart.equals(SchemaConstants.ELEM_ALL) + || localPart.equals(SchemaConstants.ELEM_SEQUENCE) + || localPart.equals(SchemaConstants.ELEM_CHOICE) + || localPart.equals(SchemaConstants.ELEM_COMPLEXCONTENT) + || localPart.equals(SchemaConstants.ELEM_RESTRICTION) + ){ + //Just skip it, call this method recursively. + return findXSDEleInComplexType(currentElement, elementName, grammars); + } + else if (localPart.equals(SchemaConstants.ELEM_EXTENSION)){ + //try to find it inside the <xsd:extension> + Element returnElement = findXSDEleInComplexType(currentElement, elementName, grammars); + if (returnElement != null) + return returnElement; + else{ + String baseAttr = currentElement.getAttribute(SchemaConstants.ATTR_BASE); + QName baseQName = QNameUtils.getQName(baseAttr, currentElement); + Element baseElement = findXMLEleInSchemas(grammars, SchemaConstants.ELEM_COMPLEXTYPE, baseQName); + return findXSDEleInComplexType(baseElement, elementName, grammars); + } + } + else if (localPart.equals(SchemaConstants.ELEM_GROUP)){ + //find <group>. + String refAttr = currentElement.getAttribute(SchemaConstants.ATTR_REF); + if (refAttr != ""){ + //look for the referenced <group> + QName groupQName = QNameUtils.getQName(refAttr, currentElement); + Element groupElement = findXMLEleInSchemas(grammars, SchemaConstants.ELEM_GROUP, groupQName); + if (groupElement != null){ + //try to find it in the referenced <group> + Element returnElement = findXSDEleInComplexType(groupElement, elementName, grammars); + if (returnElement != null) + return returnElement; + else + //Not in the referenced <group> + continue; + } + else + throw new DOMException(DOMException.NOT_FOUND_ERR, "Cannot find the referenced group"); + } + else + //Just skip it, call this method recursively. + return findXSDEleInComplexType(currentElement, elementName, grammars); + } + } + return null; + } + + /** + * return the first schema in the given extensible elements. + * @param extElements Search the first schema in this extensible elements. + * @return The first schema in the given extensible elements. + * @throws WADLSException + */ + public static Schema getFirstSchema(List extElements){ + if (extElements == null) + return null; + Object schemaObj = extElements.iterator().next(); + if (schemaObj == null) + return null; + /* ExtensibilityElement schemaEE = (ExtensibilityElement) schemaObj; + if (SchemaConstants.XSD_QNAME_LIST.contains(schemaEE.getElementType())) + return (Schema)schemaObj; + else*/ + return null; + } + + /** + * return all schemas in the given extensible elements. + * @param extElements Search the first schema in this extensible elements. + * @return All schemas in the given extensible elements. + * @throws WADLSException + */ + public static List getSchemas(List extElements){ + List schemas = new ArrayList(); + if (extElements != null){ + Iterator it = extElements.iterator(); + while(it.hasNext()){ + Object schemaObj = it.next(); + if (schemaObj == null) + continue; + /*ExtensibilityElement schemaEE = (ExtensibilityElement) schemaObj; + if (SchemaConstants.XSD_QNAME_LIST.contains(schemaEE.getElementType())) + schemas.add((Schema)schemaObj);*/ + } + } + return schemas; + } + + /** + * This method split the path string, return a string array, + * whose first dim is the string before the first '/' , + * and the second dim is the remaining string. + * @param path The path to be splitted. + * @return The splitted string. + */ + public static String[] splitPath(String path){ + String returnStr[] = new String[2]; //the string before '/' + int slashPosition = path.indexOf('/'); + if (slashPosition == -1){ + //no deeper path + returnStr[0] = path; + returnStr[1] = ""; + } + else{ + returnStr[0] = path.substring(0, slashPosition); + returnStr[1] = path.substring(slashPosition+1); + //if the remaining path is "/", empty it. + if (returnStr[1] == "/") returnStr[1] = ""; + } + return returnStr; + } + +}