| /* |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| |
| package org.apache.airavata.common.utils; |
| |
| import java.io.IOException; |
| import java.io.StringReader; |
| import java.net.MalformedURLException; |
| import java.net.URI; |
| import java.net.URL; |
| import java.net.URLConnection; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| import javax.xml.namespace.QName; |
| |
| import org.apache.airavata.common.exception.UtilsException; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import org.xmlpull.infoset.XmlAttribute; |
| import org.xmlpull.infoset.XmlBuilderException; |
| import org.xmlpull.infoset.XmlElement; |
| import org.xmlpull.infoset.XmlNamespace; |
| |
| import xsul.XmlConstants; |
| import xsul5.wsdl.WsdlBinding; |
| import xsul5.wsdl.WsdlDefinitions; |
| import xsul5.wsdl.WsdlPortType; |
| import xsul5.wsdl.WsdlPortTypeOperation; |
| import xsul5.wsdl.WsdlUtil; |
| |
| public class WSDLUtil { |
| |
| private static final Logger logger = LoggerFactory.getLogger(WSDLUtil.class); |
| |
| /** |
| * @param wsdlString |
| * @return The WSDL |
| * @throws UtilsException |
| */ |
| public static WsdlDefinitions stringToWSDL(String wsdlString) throws UtilsException { |
| try { |
| XmlElement wsdlElement = XMLUtil.stringToXmlElement(wsdlString); |
| WsdlDefinitions definitions = new WsdlDefinitions(wsdlElement); |
| return definitions; |
| } catch (RuntimeException e) { |
| throw new UtilsException(e); |
| } |
| } |
| |
| /** |
| * @param definitions3 |
| * @return The WsdlDefinitions (XSUL5) |
| */ |
| public static xsul5.wsdl.WsdlDefinitions wsdlDefinitions3ToWsdlDefintions5(xsul.wsdl.WsdlDefinitions definitions3) { |
| |
| return new xsul5.wsdl.WsdlDefinitions(XMLUtil.xmlElement3ToXmlElement5(definitions3)); |
| } |
| |
| /** |
| * @param definitions5 |
| * @return The WsdlDefinitions (XSUL3) |
| */ |
| public static xsul.wsdl.WsdlDefinitions wsdlDefinitions5ToWsdlDefintions3(xsul5.wsdl.WsdlDefinitions definitions5) { |
| |
| return new xsul.wsdl.WsdlDefinitions(XMLUtil.xmlElement5ToXmlElement3(definitions5.xml())); |
| } |
| |
| /** |
| * @param definitions |
| * @return The name of the WSDL. |
| */ |
| public static String getWSDLName(WsdlDefinitions definitions) { |
| String wsdlName = definitions.xml().attributeValue(WSConstants.NAME_ATTRIBUTE); |
| if (wsdlName == null) { |
| // name is optional. |
| wsdlName = ""; |
| } |
| return wsdlName; |
| } |
| |
| /** |
| * @param definitions |
| * @return The QName of the WSDL. |
| */ |
| public static QName getWSDLQName(WsdlDefinitions definitions) { |
| String targetNamespace = definitions.getTargetNamespace(); |
| String wsdlName = getWSDLName(definitions); |
| return new QName(targetNamespace, wsdlName); |
| } |
| |
| /** |
| * @param definitions |
| * @return The first portType |
| * @throws UtilsException |
| */ |
| public static WsdlPortType getFirstPortType(WsdlDefinitions definitions) throws UtilsException { |
| for (WsdlPortType portType : definitions.portTypes()) { |
| return portType; |
| } |
| throw new UtilsException("No portType is defined in WSDL"); |
| } |
| |
| public static WsdlPortTypeOperation getFirstOperation(WsdlDefinitions definitions) throws UtilsException { |
| for (WsdlPortTypeOperation operation : getFirstPortType(definitions).operations()) { |
| return operation; |
| } |
| throw new UtilsException("No portType is defined in WSDL"); |
| } |
| |
| /** |
| * @param definitions |
| * @return The QName of the first portType. |
| * @throws UtilsException |
| */ |
| public static QName getFirstPortTypeQName(WsdlDefinitions definitions) throws UtilsException { |
| String targetNamespace = definitions.getTargetNamespace(); |
| for (WsdlPortType portType : definitions.portTypes()) { |
| String portTypeName = portType.getName(); |
| QName portTypeQName = new QName(targetNamespace, portTypeName); |
| return portTypeQName; |
| } |
| throw new UtilsException("No portType is defined."); |
| } |
| |
| /** |
| * @param definitions |
| * @param portTypeQName |
| * @return The name of the first operation in a given portType. |
| * @throws UtilsException |
| */ |
| public static String getFirstOperationName(WsdlDefinitions definitions, QName portTypeQName) throws UtilsException { |
| WsdlPortType portType = definitions.getPortType(portTypeQName.getLocalPart()); |
| for (WsdlPortTypeOperation operation : portType.operations()) { |
| String operationName = operation.getOperationName(); |
| |
| // XXX Temporary solution to skip some GFac specific operations. |
| if ("Shutdown".equals(operationName)) { |
| continue; |
| } else if ("Kill".equals(operationName)) { |
| continue; |
| } else if ("Ping".equals(operationName)) { |
| continue; |
| } |
| |
| return operationName; |
| } |
| throw new UtilsException("No operation is defined"); |
| } |
| |
| /** |
| * @param definitions |
| * @return The cloned WsdlDefinitions |
| */ |
| public static WsdlDefinitions deepClone(WsdlDefinitions definitions) throws UtilsException { |
| return new WsdlDefinitions(XMLUtil.deepClone(definitions.xml())); |
| } |
| |
| /** |
| * @param definitions |
| * @param paramType |
| * @return The schema that includes the type definition |
| */ |
| public static XmlElement getSchema(WsdlDefinitions definitions, QName paramType) throws UtilsException { |
| XmlElement types = definitions.getTypes(); |
| |
| Iterable<XmlElement> schemas = types.elements(WSConstants.XSD_NS, WSConstants.SCHEMA_TAG); |
| for (XmlElement schema : schemas) { |
| if (isTypeDefinedInSchema(paramType, schema)) { |
| return schema; |
| } |
| } |
| |
| // ok we didnt find the type in the schema in first level |
| // now we try try to see if it exist in schema imports. |
| // we loop in two step because its better to avoid the network |
| // connection if possible |
| for (XmlElement schema : schemas) { |
| Iterable<XmlElement> imports = schema.elements(WSConstants.XSD_NS, WSConstants.IMPORT_TAG); |
| for (XmlElement importEle : imports) { |
| String schemaLocation = importEle.attributeValue(WSConstants.SCHEMA_LOCATION_ATTRIBUTE); |
| if (null != schemaLocation && !"".equals(schemaLocation)) { |
| try { |
| // connect using a url connection |
| URL url = new URL(schemaLocation); |
| URLConnection connection = url.openConnection(); |
| connection.connect(); |
| XmlElement importedSchema = xsul5.XmlConstants.BUILDER.parseFragmentFromInputStream(connection |
| .getInputStream()); |
| if (isTypeDefinedInSchema(paramType, importedSchema)) { |
| // still return the parent schema |
| return schema; |
| } |
| } catch (MalformedURLException e) { |
| throw new UtilsException(e); |
| } catch (XmlBuilderException e) { |
| throw new UtilsException(e); |
| } catch (IOException e) { |
| throw new UtilsException(e); |
| } |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| private static boolean isTypeDefinedInSchema(QName paramType, XmlElement schema) { |
| String schemaTargetNamespace = schema.attributeValue(WSConstants.TARGET_NAMESPACE_ATTRIBUTE); |
| if (schemaTargetNamespace.equals(paramType.getNamespaceURI())) { |
| for (XmlElement complexType : schema.elements(WSConstants.XSD_NS, WSConstants.COMPLEX_TYPE_TAG)) { |
| String complexTypeName = complexType.attributeValue(WSConstants.NAME_ATTRIBUTE); |
| if (complexTypeName.equals(paramType.getLocalPart())) { |
| return true; |
| } |
| } |
| for (XmlElement simpleType : schema.elements(WSConstants.XSD_NS, WSConstants.SIMPLE_TYPE_TAG)) { |
| String simpleTypeName = simpleType.attributeValue(WSConstants.NAME_ATTRIBUTE); |
| if (simpleTypeName.equals(paramType.getLocalPart())) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * @param definitions |
| * @param paramType |
| * @return The type definition |
| */ |
| public static XmlElement getTypeDefinition(WsdlDefinitions definitions, QName paramType) throws UtilsException { |
| XmlElement types = definitions.getTypes(); |
| XmlElement returnType = null; |
| types.element(null, WSConstants.SCHEMA_TAG); |
| Iterable<XmlElement> schemas = types.elements(null, WSConstants.SCHEMA_TAG); |
| for (XmlElement schema : schemas) { |
| |
| returnType = findTypeInSchema(paramType, schema); |
| if (returnType != null) { |
| return returnType; |
| } |
| } |
| // ok we didnt find the type in the schemas |
| // try to find it in the schema imports. |
| |
| // if not found it will return null so we would return null |
| return findTypeDefinitionInImports(definitions, paramType); |
| |
| } |
| |
| /** |
| * |
| * @param definitions |
| * @param paramType |
| * @return |
| */ |
| |
| public static XmlElement getImportContainingTypeDefinition(WsdlDefinitions definitions, QName paramType) |
| throws UtilsException { |
| XmlElement types = definitions.getTypes(); |
| XmlElement returnType = null; |
| Iterable<XmlElement> schemas = types.elements(WSConstants.XSD_NS, WSConstants.SCHEMA_TAG); |
| for (XmlElement schema : schemas) { |
| Iterable<XmlElement> imports = schema.elements(WSConstants.XSD_NS, WSConstants.IMPORT_TAG); |
| for (XmlElement importEle : imports) { |
| String schemaLocation = importEle.attributeValue(WSConstants.SCHEMA_LOCATION_ATTRIBUTE); |
| if (null != schemaLocation && !"".equals(schemaLocation)) { |
| try { |
| // connect using a url connection |
| URL url = new URL(schemaLocation); |
| URLConnection connection = url.openConnection(); |
| connection.connect(); |
| XmlElement importedSchema = xsul5.XmlConstants.BUILDER.parseFragmentFromInputStream(connection |
| .getInputStream()); |
| returnType = findTypeInSchema(paramType, importedSchema); |
| if (returnType != null) { |
| return importEle; |
| } |
| |
| } catch (MalformedURLException e) { |
| throw new UtilsException(e); |
| } catch (XmlBuilderException e) { |
| throw new UtilsException(e); |
| } catch (IOException e) { |
| throw new UtilsException(e); |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * |
| * @param definitions |
| * @param paramType |
| * @return |
| */ |
| |
| public static XmlElement findTypeDefinitionInImports(WsdlDefinitions definitions, QName paramType) |
| throws UtilsException { |
| XmlElement types = definitions.getTypes(); |
| XmlElement returnType = null; |
| Iterable<XmlElement> schemas = types.elements(null, WSConstants.SCHEMA_TAG); |
| for (XmlElement schema : schemas) { |
| Iterable<XmlElement> imports = schema.elements(WSConstants.XSD_NS, WSConstants.IMPORT_TAG); |
| for (XmlElement importEle : imports) { |
| String schemaLocation = importEle.attributeValue(WSConstants.SCHEMA_LOCATION_ATTRIBUTE); |
| if (null != schemaLocation && !"".equals(schemaLocation)) { |
| try { |
| // connect using a url connection |
| URL url = new URL(schemaLocation); |
| URLConnection connection = url.openConnection(); |
| connection.connect(); |
| XmlElement importedSchema = xsul5.XmlConstants.BUILDER.parseFragmentFromInputStream(connection |
| .getInputStream()); |
| returnType = findTypeInSchema(paramType, importedSchema); |
| if (returnType != null) { |
| return returnType; |
| } |
| |
| } catch (MalformedURLException e) { |
| throw new UtilsException(e); |
| } catch (XmlBuilderException e) { |
| throw new UtilsException(e); |
| } catch (IOException e) { |
| throw new UtilsException(e); |
| } |
| } |
| } |
| } |
| return null; |
| |
| } |
| |
| private static XmlElement findTypeInSchema(QName paramType, XmlElement schema) { |
| String schemaTargetNamespace = schema.attributeValue(WSConstants.TARGET_NAMESPACE_ATTRIBUTE); |
| if (null != schemaTargetNamespace && schemaTargetNamespace.equals(paramType.getNamespaceURI())) { |
| for (XmlElement complexType : schema.elements(WSConstants.XSD_NS, WSConstants.COMPLEX_TYPE_TAG)) { |
| String complexTypeName = complexType.attributeValue(WSConstants.NAME_ATTRIBUTE); |
| if (complexTypeName.equals(paramType.getLocalPart())) { |
| return complexType; |
| |
| } |
| } |
| for (XmlElement simpleType : schema.elements(WSConstants.XSD_NS, WSConstants.SIMPLE_TYPE_TAG)) { |
| String simpleTypeName = simpleType.attributeValue(WSConstants.NAME_ATTRIBUTE); |
| if (simpleTypeName.equals(paramType.getLocalPart())) { |
| return simpleType; |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * @param wsdl |
| * @return true if the WSDL is AWSDL; false otherwise. |
| */ |
| public static boolean isAWSDL(WsdlDefinitions wsdl) { |
| if (wsdl.services().iterator().hasNext()) { |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * @param definitions |
| * @return true if the service supports asynchronous invocation; false otherwise; |
| */ |
| public static boolean isAsynchronousSupported(WsdlDefinitions definitions) { |
| for (WsdlBinding binding : definitions.bindings()) { |
| XmlElement element = binding.xml().element(WSConstants.USING_ADDRESSING_TAG); |
| if (element != null) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Converts a specified AWSDL to CWSDL using DSC URI. |
| * |
| * @param definitions |
| * The specified AWSDL. This will be modified. |
| * @param url |
| * The URL of the service |
| * @return The CWSDL converted. |
| */ |
| public static WsdlDefinitions convertToCWSDL(WsdlDefinitions definitions, URI url) { |
| for (WsdlPortType portType : definitions.portTypes()) { |
| WsdlUtil.createCWSDL(definitions, portType, url); |
| } |
| return definitions; |
| } |
| |
| /** |
| * @param uri |
| * @return The URI with "?wsdl" at the end. |
| */ |
| public static String appendWSDLQuary(String uri) { |
| URI wsdlURI = appendWSDLQuary(URI.create(uri)); |
| return wsdlURI.toString(); |
| } |
| |
| public static List<XmlNamespace> getNamespaces(XmlElement element) { |
| LinkedList<XmlNamespace> namespaces = new LinkedList<XmlNamespace>(); |
| namespaces.add(element.getNamespace()); |
| Iterable<XmlAttribute> attributes = element.attributes(); |
| for (XmlAttribute xmlAttribute : attributes) { |
| if (xmlAttribute.getNamespace() != null && !namespaces.contains(xmlAttribute.getNamespace())) { |
| namespaces.add(xmlAttribute.getNamespace()); |
| } |
| int index = xmlAttribute.getValue().indexOf(':'); |
| if (-1 != index) { |
| String prefix = xmlAttribute.getValue().substring(0, index); |
| if (element.lookupNamespaceByPrefix(prefix) != null) { |
| namespaces.add(element.lookupNamespaceByPrefix(prefix)); |
| } |
| } |
| } |
| Iterable children = element.children(); |
| for (Object object : children) { |
| if (object instanceof XmlElement) { |
| List<XmlNamespace> newNSs = getNamespaces((XmlElement) object); |
| for (XmlNamespace xmlNamespace : newNSs) { |
| if (!namespaces.contains(xmlNamespace)) { |
| namespaces.add(xmlNamespace); |
| } |
| } |
| } |
| } |
| return namespaces; |
| } |
| |
| /** |
| * @param uri |
| * @return The URI with "?wsdl" at the end. |
| */ |
| public static URI appendWSDLQuary(URI uri) { |
| if (uri.toString().endsWith("?wsdl")) { |
| logger.warn("URL already has ?wsdl at the end: " + uri.toString()); |
| // Don't throw exception to be more error tolerant. |
| return uri; |
| } |
| String path = uri.getPath(); |
| if (path == null || path.length() == 0) { |
| uri = uri.resolve("/"); |
| } |
| uri = URI.create(uri.toString() + "?wsdl"); |
| return uri; |
| } |
| |
| /** |
| * @param valueElement |
| * @return |
| */ |
| public static org.xmlpull.v1.builder.XmlElement xmlElement5ToXmlElementv1(XmlElement valueElement) { |
| |
| return XmlConstants.BUILDER.parseFragmentFromReader(new StringReader(xsul5.XmlConstants.BUILDER |
| .serializeToStringPretty(valueElement))); |
| } |
| |
| /** |
| * |
| * @param vals |
| * @param <T> |
| * @return |
| */ |
| public static <T extends Object> T getfirst(Iterable<T> vals) { |
| for (T class1 : vals) { |
| return class1; |
| } |
| throw new RuntimeException("Iterator empty"); |
| |
| } |
| |
| /** |
| * @param serviceSchema |
| */ |
| public static void print(XmlElement serviceSchema) { |
| System.out.println(xsul5.XmlConstants.BUILDER.serializeToStringPretty(serviceSchema)); |
| } |
| |
| /** |
| * @param workflowID |
| * @return |
| */ |
| public static String findWorkflowName(URI workflowID) { |
| String[] splits = workflowID.toString().split("/"); |
| return splits[splits.length - 1]; |
| |
| } |
| |
| /** |
| * |
| * @param element |
| * @param name |
| * @param oldValue |
| * @param newValue |
| */ |
| public static void replaceAttributeValue(XmlElement element, String name, String oldValue, String newValue) { |
| XmlAttribute attribute = element.attribute(name); |
| if (null != attribute && oldValue.equals(attribute.getValue())) { |
| element.removeAttribute(attribute); |
| element.setAttributeValue(name, newValue); |
| } |
| Iterable iterator = element.children(); |
| for (Object object : iterator) { |
| if (object instanceof XmlElement) { |
| replaceAttributeValue((XmlElement) object, name, oldValue, newValue); |
| } |
| } |
| |
| } |
| |
| public static boolean attributeExist(XmlElement element, String name, String value) { |
| XmlAttribute attribute = element.attribute(name); |
| if (null != attribute && value.equals(attribute.getValue())) { |
| return true; |
| } |
| Iterable iterator = element.children(); |
| boolean ret = false; |
| for (Object object : iterator) { |
| if (object instanceof XmlElement) { |
| ret = ret || attributeExist((XmlElement) object, name, value); |
| } |
| } |
| return ret; |
| |
| } |
| |
| |
| } |