blob: 4f05416f553a90c4f8787010cc400b70b87ab45d [file] [log] [blame]
/**
* *****************************************************************************
* Copyright (C) 2012 Spanish National Bioinformatics Institute (INB),
* Barcelona Supercomputing Center and The University of Manchester
*
* Modifications to the initial code base are copyright of their respective
* authors, or their employers as appropriate.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307
*****************************************************************************
*/
package net.sf.taverna.wsdl.parser;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URI;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.xml.namespace.QName;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.woden.WSDLFactory;
import org.apache.woden.WSDLReader;
import org.apache.woden.XMLElement;
import org.apache.woden.types.NCName;
import org.apache.woden.wsdl20.Binding;
import org.apache.woden.wsdl20.BindingOperation;
import org.apache.woden.wsdl20.Description;
import org.apache.woden.wsdl20.ElementDeclaration;
import org.apache.woden.wsdl20.Endpoint;
import org.apache.woden.wsdl20.Interface;
import org.apache.woden.wsdl20.InterfaceMessageReference;
import org.apache.woden.wsdl20.InterfaceOperation;
import org.apache.woden.wsdl20.Service;
import org.apache.woden.wsdl20.enumeration.Direction;
import org.apache.woden.wsdl20.extensions.ExtensionProperty;
import org.apache.woden.wsdl20.extensions.soap.SOAPConstants;
import org.apache.woden.wsdl20.xml.DescriptionElement;
import org.apache.woden.wsdl20.xml.DocumentationElement;
import org.apache.ws.commons.schema.XmlSchemaCollection;
import org.apache.ws.commons.schema.XmlSchemaObject;
import org.w3c.dom.Element;
/**
* @author Dmitry Repchevsky
*/
public class WSDL20Parser implements GenericWSDLParser {
private static Map<String, WSDL20Parser> parsers;
private final Description description;
private final XmlSchemaCollection schemas;
private WSDL20Parser(Description description) throws IOException {
this.description = description;
schemas = new XmlSchemaCollection();
}
@Override
public String getDocumentBaseURI() {
DescriptionElement element = description.toElement();
URI documentBaseURI = element.getDocumentBaseURI();
return documentBaseURI == null ? null : documentBaseURI.toString();
}
@Override
public List<QName> getServices() {
List<QName> services = new ArrayList<QName>();
for (Service service : description.getServices()) {
services.add(service.getName());
}
return services;
}
@Override
public List<String> getPorts(QName serviceName) {
List<String> ports = new ArrayList<String>();
Service service = description.getService(serviceName);
if (service != null) {
for (Endpoint endpoint : service.getEndpoints()) {
final NCName endpointName = endpoint.getName();
if (endpointName != null) {
ports.add(endpointName.toString());
}
}
}
return ports;
}
@Override
public List<String> getOperations(String portName) {
List<String> operations = new ArrayList<String>();
for (Service service : description.getServices()) {
for (Endpoint endpoint : service.getEndpoints()) {
final NCName endpointName = endpoint.getName();
if (endpointName != null && endpointName.toString().equals(portName)) {
Binding binding = endpoint.getBinding();
if (binding != null) {
for (BindingOperation bindingOperation : binding.getBindingOperations()) {
InterfaceOperation interfaceOperation = bindingOperation.getInterfaceOperation();
if (interfaceOperation != null) {
operations.add(interfaceOperation.getName().getLocalPart());
}
}
}
}
}
}
return operations;
}
@Override
public WSRF_Version isWSRFPort(String portName) {
return null;
}
@Override
public String getOperationStyle(String portName, String operationName) throws UnknownOperationException {
return "document";
}
@Override
public String getSOAPActionURI(String portName, String operationName) throws UnknownOperationException {
BindingOperation bindingOperation = getBindingOperation(portName, operationName);
InterfaceOperation interfaceOperation = bindingOperation.getInterfaceOperation();
ExtensionProperty property = interfaceOperation.getExtensionProperty(SOAPConstants.NS_URI_SOAP, SOAPConstants.ATTR_ACTION);
return property == null ? null : property.getContent().toString();
}
@Override
public QName getRPCRequestMethodName(String portName, String operationName) throws UnknownOperationException {
// NO RPC SUPPORT YET
return new QName(operationName);
}
@Override
public QName getRPCResponseMethodName(String portName, String operationName) throws UnknownOperationException {
// NO RPC SUPPORT YET
return new QName(operationName);
}
@Override
public String getSoapInputUse(String portName, String operationName) throws UnknownOperationException {
return "literal";
}
@Override
public String getSoapOutputUse(String portName, String operationName) throws UnknownOperationException {
return "literal";
}
@Override
public String getSoapAddress(String portName) {
for (Service service : description.getServices()) {
for (Endpoint endpoint : service.getEndpoints()) {
final NCName endpointName = endpoint.getName();
if (endpointName != null && endpointName.toString().equals(portName)) {
URI address = endpoint.getAddress();
return address == null ? null : address.toString();
}
}
}
return null;
}
@Override
public String getOperationEndpointLocation(String operationName) throws UnknownOperationException {
for (Service service : description.getServices()) {
for (Endpoint endpoint : service.getEndpoints()) {
Binding binding = endpoint.getBinding();
if (binding != null) {
for (BindingOperation o : binding.getBindingOperations()) {
InterfaceOperation operation = o.getInterfaceOperation();
if (operation != null && operationName.equals(operation.getName().getLocalPart())) {
URI address = endpoint.getAddress();
return address == null ? null : address.toString();
}
}
}
}
}
return null;
}
@Override
public String getOperationDocumentation(String portName, String operationName) throws UnknownOperationException {
Writer writer = new StringWriter();
BindingOperation bindingOperation = getBindingOperation(portName, operationName);
InterfaceOperation interfaceOperation = bindingOperation.getInterfaceOperation();
try {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
for (DocumentationElement documentation : interfaceOperation.toElement().getDocumentationElements()) {
XMLElement xml = documentation.getContent();
Object source = xml.getSource();
if (source instanceof Element) {
Element element = (Element)source;
try {
transformer.transform(new DOMSource(element), new StreamResult(writer));
} catch (TransformerException ex) {}
}
}
} catch (TransformerFactoryConfigurationError ex) {}
catch (TransformerConfigurationException ex) {}
return writer.toString();
}
@Override
public LinkedHashMap<String, XmlSchemaObject> getInputParameters(String portName, String operationName) throws UnknownOperationException {
LinkedHashMap<String, XmlSchemaObject> parameters = new LinkedHashMap<String, XmlSchemaObject>();
BindingOperation bindingOperation = getBindingOperation(portName, operationName);
InterfaceOperation interfaceOperation = bindingOperation.getInterfaceOperation();
// NOTE THAT THIS CODE IS NOT VALID FOR "RPC" STYLE
for (InterfaceMessageReference input : interfaceOperation.getInterfaceMessageReferences()) {
if (Direction.IN == input.getDirection()) {
ElementDeclaration element = input.getElementDeclaration();
parameters.put(element.getName().getLocalPart(), (XmlSchemaObject)element.getContent());
}
}
return parameters;
}
@Override
public LinkedHashMap<String, XmlSchemaObject> getOutputParameters(String portName, String operationName) throws UnknownOperationException {
LinkedHashMap<String, XmlSchemaObject> parameters = new LinkedHashMap<String, XmlSchemaObject>();
BindingOperation bindingOperation = getBindingOperation(portName, operationName);
InterfaceOperation interfaceOperation = bindingOperation.getInterfaceOperation();
// NOTE THAT THIS CODE IS NOT VALID FOR "RPC" STYLE
for (InterfaceMessageReference output : interfaceOperation.getInterfaceMessageReferences()) {
if (Direction.OUT == output.getDirection()) {
ElementDeclaration element = output.getElementDeclaration();
parameters.put(element.getName().getLocalPart(), (XmlSchemaObject)element.getContent());
}
}
return parameters;
}
private BindingOperation getBindingOperation(String portName, String operationName) throws UnknownOperationException {
Binding[] bindings = null;
if (portName == null) {
bindings = description.getBindings();
} else {
loop:
for (Service service : description.getServices()) {
for (Endpoint endpoint : service.getEndpoints()) {
final NCName endpointName = endpoint.getName();
if (endpointName != null && endpointName.toString().equals(portName)) {
Binding binding = endpoint.getBinding();
if (binding != null) {
bindings = new Binding[] {binding};
break loop;
}
}
}
}
if (bindings == null) {
bindings = description.getBindings();
}
}
if (bindings != null) {
for (Binding binding : bindings) {
for (BindingOperation bindingOperation : binding.getBindingOperations()) {
InterfaceOperation interfaceOperation = bindingOperation.getInterfaceOperation();
if (interfaceOperation != null && operationName.equals(interfaceOperation.getName().getLocalPart())) {
return bindingOperation;
}
}
}
}
throw new UnknownOperationException("Unknown operation: " + operationName);
}
public static synchronized WSDL20Parser getWSDL20Parser(String wsdlLocation) throws Exception {
WSDL20Parser parser = null;
if (parsers == null) {
parsers = new TreeMap<String, WSDL20Parser>();
} else {
parser = parsers.get(wsdlLocation);
}
if (parser == null) {
WSDLFactory factory = WSDLFactory.newInstance();
WSDLReader reader = factory.newWSDLReader();
reader.setFeature(WSDLReader.FEATURE_VALIDATION, true);
Description description = reader.readWSDL(wsdlLocation);
parser = new WSDL20Parser(description);
parsers.put(wsdlLocation, parser);
}
return parser;
}
}