blob: 5eb34363259c85f7dd06bb80364d528c58725be8 [file] [log] [blame]
/*
*
* 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;
}
}