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;
+	}	
+	
+}