You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by re...@apache.org on 2015/03/19 14:43:38 UTC
[10/35] incubator-taverna-common-activities git commit: package names
changed to org.apache.taverna.*
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/WSRF_RLOperation.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/WSRF_RLOperation.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/WSRF_RLOperation.java
new file mode 100644
index 0000000..5cd94de
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/WSRF_RLOperation.java
@@ -0,0 +1,36 @@
+/*
+* 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.taverna.wsdl.parser;
+
+/**
+ * @author Dmitry Repchevsky
+ */
+
+public enum WSRF_RLOperation {
+
+ Destroy("http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination/DestroyRequest"),
+ SetTerminationTime("http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination/SetTerminationTimeRequest");
+
+ public final String SOAP_ACTION;
+
+ private WSRF_RLOperation(String req_action) {
+ SOAP_ACTION = req_action;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/WSRF_RPOperation.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/WSRF_RPOperation.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/WSRF_RPOperation.java
new file mode 100644
index 0000000..0f0f3e6
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/WSRF_RPOperation.java
@@ -0,0 +1,44 @@
+/*
+* 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.taverna.wsdl.parser;
+
+/**
+ * @author Dmitry Repchevsky
+ */
+
+public enum WSRF_RPOperation {
+
+ GetResourcePropertyDocument("http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest"),
+ GetResourceProperty("http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest"),
+ GetMultipleResourceProperties("http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest"),
+ QueryResourceProperties("http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesRequest"),
+ QueryExpressionDialect("http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesRequest"),
+ PutResourcePropertyDocument("http://docs.oasis-open.org/wsrf/rpw-2/PutResourcePropertyDocument/PutResourcePropertyDocumentRequest"),
+ SetResourceProperties("http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesRequest"),
+ InsertResourceProperties("http://docs.oasis-open.org/wsrf/rpw-2/InsertResourceProperties/InsertResourcePropertiesRequest"),
+ UpdateResourceProperties("http://docs.oasis-open.org/wsrf/rpw-2/UpdateResourceProperties/UpdateResourcePropertiesRequest"),
+ DeleteResourceProperties("http://docs.oasis-open.org/wsrf/rpw-2/DeleteResourceProperties/DeleteResourcePropertiesRequest");
+
+ public final String SOAP_ACTION;
+
+ private WSRF_RPOperation(String req_action) {
+ SOAP_ACTION = req_action;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/WSRF_Version.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/WSRF_Version.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/WSRF_Version.java
new file mode 100644
index 0000000..5b9e74e
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/WSRF_Version.java
@@ -0,0 +1,64 @@
+/*
+* 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.taverna.wsdl.parser;
+
+/**
+ * @author Dmitry Repchevsky
+ */
+
+public enum WSRF_Version {
+
+ Draft01("http://schemas.xmlsoap.org/ws/2004/08/addressing",
+ "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd",
+ "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceLifetime-1.2-draft-01.xsd"), // 2004_10_01
+
+ Draft02("http://schemas.xmlsoap.org/ws/2004/08/addressing",
+ "http://docs.oasis-open.org/wsrf/2004/11/wsrf-WS-ResourceProperties-1.2-draft-05.xsd",
+ "http://docs.oasis-open.org/wsrf/2004/11/wsrf-WS-ResourceLifetime-1.2-draft-04.xsd"), // 2004_12_09
+
+ Draft03("http://schemas.xmlsoap.org/ws/2004/08/addressing",
+ "http://docs.oasis-open.org/wsrf/2005/03/wsrf-WS-ResourceProperties-1.2-draft-06.xsd",
+ "http://docs.oasis-open.org/wsrf/2005/03/wsrf-WS-ResourceLifetime-1.2-draft-05.xsd"), // 2005_03_08
+
+ PR01("http://www.w3.org/2005/03/addressing",
+ "http://docs.oasis-open.org/wsrf/rp-1",
+ "http://docs.oasis-open.org/wsrf/rl-1"), // 2005_06_10
+
+// PR02("http://www.w3.org/2005/08/addressing",
+// "http://docs.oasis-open.org/wsrf/rp-2",
+// "http://docs.oasis-open.org/wsrf/rl-2"), // 2005_10_06
+
+ Standard("http://www.w3.org/2005/08/addressing",
+ "http://docs.oasis-open.org/wsrf/rp-2",
+ "http://docs.oasis-open.org/wsrf/rl-2"); // 2006_04_01
+
+ public final String WSA;
+
+ public final String WSRF_RP;
+ public final String WSRF_RL;
+
+ WSRF_Version(String wsa, String wsrf_rp, String wsrf_rl) {
+ WSA = wsa;
+
+ WSRF_RP = wsrf_rp;
+ WSRF_RL = wsrf_rl;
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/package.html
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/package.html b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/package.html
new file mode 100644
index 0000000..8fc2638
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/parser/package.html
@@ -0,0 +1,5 @@
+<body>
+Contains classes required to parse a WSDL to discover and describe the operations and their input and output data structures.<br>
+These classes are derived heavily from the original parsing classes from the Taverna 1 WSDLBasedProcessor and have been refactored<br>
+to remove references to to Taverna 1
+</body>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/AbstractBodyBuilder.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/AbstractBodyBuilder.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/AbstractBodyBuilder.java
new file mode 100644
index 0000000..2cd6f3e
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/AbstractBodyBuilder.java
@@ -0,0 +1,373 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.wsdl.WSDLException;
+import javax.xml.bind.DatatypeConverter;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPFactory;
+import org.apache.taverna.wsdl.parser.ArrayTypeDescriptor;
+import org.apache.taverna.wsdl.parser.BaseTypeDescriptor;
+import org.apache.taverna.wsdl.parser.ComplexTypeDescriptor;
+import org.apache.taverna.wsdl.parser.TypeDescriptor;
+import org.apache.taverna.wsdl.parser.UnknownOperationException;
+import org.apache.taverna.wsdl.parser.WSDLParser;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+@SuppressWarnings("unchecked")
+public abstract class AbstractBodyBuilder implements BodyBuilder {
+
+ private static Logger logger = Logger.getLogger(AbstractBodyBuilder.class);
+
+ private String style;
+ private WSDLParser parser;
+ private String operationName;
+
+ protected enum Style {
+ DOCUMENT, RPC
+ };
+
+ protected enum Use {
+ LITERAL, ENCODED
+ };
+
+ protected Map<String, String> namespaceMappings;
+ protected List<TypeDescriptor> inputDescriptors;
+
+ public AbstractBodyBuilder(String style, WSDLParser parser,
+ String operationName, List<TypeDescriptor> inputDescriptors) {
+ this.style = style;
+ this.parser = parser;
+ this.operationName = operationName;
+ this.inputDescriptors = inputDescriptors;
+ }
+
+ protected Style getStyle() {
+ Style result = Style.DOCUMENT;
+ if (style.equalsIgnoreCase("rpc")) {
+ result = Style.RPC;
+ } else if (style.equalsIgnoreCase("document")) {
+ result = Style.DOCUMENT;
+ }
+ return result;
+ }
+
+ protected abstract Use getUse();
+
+ /**
+ *
+ * @return the namespace for the operation
+ */
+ private String getOperationNamespace() throws UnknownOperationException {
+ return parser.getOperationNamespaceURI(operationName);
+ }
+
+ private QName getOperationQname() throws UnknownOperationException {
+ return parser.getOperationQname(operationName);
+ }
+
+ @Override
+ public SOAPElement build(Map inputMap) throws WSDLException,
+ ParserConfigurationException, SOAPException, IOException,
+ SAXException, UnknownOperationException {
+
+ List<TypeDescriptor> inputs = parser.getOperationInputParameters(operationName);
+
+ namespaceMappings = generateNamespaceMappings(inputs);
+
+ QName operationQname = getOperationQname();
+
+ String ns = namespaceMappings.get(operationQname.getNamespaceURI());
+
+ SOAPElement body = ns == null ? SOAPFactory.newInstance().createElement(operationQname) :
+ SOAPFactory.newInstance().createElement(operationQname.getLocalPart(), ns, operationQname.getNamespaceURI());
+
+ // its important to preserve the order of the inputs!
+ for (Iterator<TypeDescriptor> iterator = inputs.iterator(); iterator.hasNext();) {
+ TypeDescriptor descriptor = iterator.next();
+ String inputName = descriptor.getName();
+ Object dataValue = inputMap.get(inputName);
+
+ body = createBodyElementForData(operationName, namespaceMappings,
+ operationQname.getNamespaceURI(), body, descriptor, inputName, dataValue);
+ }
+
+ return body;
+ }
+
+
+
+ protected SOAPElement createBodyElementForData(String operationName,
+ Map<String, String> namespaceMappings, String operationNamespace,
+ SOAPElement body, TypeDescriptor descriptor, String inputName,
+ Object dataValue) throws ParserConfigurationException,
+ SAXException, IOException, UnknownOperationException, SOAPException {
+ if (dataValue != null) {
+ String mimeType = getMimeTypeForInputName(inputName);
+ String typeName = descriptor.getType();
+
+ Element el;
+ if (descriptor instanceof ArrayTypeDescriptor) {
+ el = createElementForArrayType(namespaceMappings, inputName,
+ dataValue, descriptor, mimeType, typeName);
+
+ } else {
+ el = createSkeletonElementForSingleItem(namespaceMappings,
+ descriptor, inputName, typeName);
+ populateElementWithObjectData(mimeType, el, dataValue, descriptor);
+ }
+
+ body = addElementToBody(operationNamespace, body, el);
+ }
+ return body;
+ }
+
+ protected abstract SOAPElement addElementToBody(
+ String operationNamespace, SOAPElement body, Element el)
+ throws SOAPException;
+
+ protected abstract Element createSkeletonElementForSingleItem(
+ Map<String, String> namespaceMappings, TypeDescriptor descriptor,
+ String inputName, String typeName);
+
+ /**
+ * generates an XML DOM Element for an array
+ *
+ * @param namespaceMappings
+ * @param inputName
+ * @param dataValue
+ * @param descriptor
+ * @param mimeType
+ * @param typeName
+ * @return
+ * @throws ParserConfigurationException
+ * @throws SAXException
+ * @throws IOException
+ */
+ protected abstract Element createElementForArrayType(
+ Map<String, String> namespaceMappings, String inputName,
+ Object dataValue, TypeDescriptor descriptor, String mimeType,
+ String typeName) throws ParserConfigurationException, SAXException,
+ IOException, UnknownOperationException;
+
+ /**
+ * Populates a DOM XML Element with the contents of a List of dataValues
+ *
+ * @param mimeType -
+ * the mime type of the data
+ * @param element -
+ * the Element to be populated
+ * @param dataValues -
+ * the List of Objects containing the data
+ * @param elementType -
+ * the TypeDescriptor for the element being populated
+ * @throws ParserConfigurationException
+ * @throws SAXException
+ * @throws IOException
+ */
+ protected void populateElementWithList(String mimeType, Element element,
+ List dataValues, TypeDescriptor elementType)
+ throws ParserConfigurationException, SAXException, IOException {
+ for (Iterator dataIterator = dataValues.iterator(); dataIterator
+ .hasNext();) {
+ Object dataItem = dataIterator.next();
+ String tag;
+ if (elementType instanceof BaseTypeDescriptor) {
+ tag = elementType.getType();
+ } else {
+ tag = elementType.getName();
+ }
+
+ Element item = element.getOwnerDocument().createElement(tag);
+ populateElementWithObjectData(mimeType, item, dataItem, elementType);
+ element.appendChild(item);
+ }
+ }
+
+ /**
+ * Populates a DOM XML Element with dataValue according to its mimetype
+ *
+ * @param mimeType
+ * @param element
+ * @param dataValue
+ * @param descriptor
+ * @throws ParserConfigurationException
+ * @throws SAXException
+ * @throws IOException
+ */
+ protected void populateElementWithObjectData(String mimeType,
+ Element element, Object dataValue, TypeDescriptor descriptor)
+ throws ParserConfigurationException, SAXException, IOException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ DocumentBuilder builder = factory.newDocumentBuilder();
+
+ if (mimeType.equals("'text/xml'")) {
+ Document doc = builder.parse(new ByteArrayInputStream(dataValue
+ .toString().getBytes()));
+ Element documentElement = doc.getDocumentElement();
+
+ if (descriptor instanceof ComplexTypeDescriptor) {
+ ComplexTypeDescriptor complexType = (ComplexTypeDescriptor) descriptor;
+ NamedNodeMap attributes = documentElement.getAttributes();
+ if (attributes != null) {
+ for (int i = 0; i < attributes.getLength(); i++) {
+ Node attributeNode = attributes.item(i);
+ if (attributeNode instanceof Attr) {
+ Attr attribute = (Attr) attributeNode;
+ TypeDescriptor typeDescriptor = complexType.attributeForName(attribute.getName());
+ if (typeDescriptor != null) {
+ element.setAttributeNS(typeDescriptor.getNamespaceURI(), typeDescriptor.getName(), attribute.getValue());
+ }
+ }
+ }
+ }
+ }
+
+ Node child = documentElement.getFirstChild();
+
+ while (child != null) {
+ element.appendChild(element.getOwnerDocument().importNode(
+ child, true));
+ child = child.getNextSibling();
+ }
+ } else if (mimeType.equals("'application/octet-stream'")
+ && dataValue instanceof byte[]) {
+ String encoded = DatatypeConverter.printBase64Binary((byte[]) dataValue);
+ element.appendChild(element.getOwnerDocument().createTextNode(
+ encoded));
+ } else {
+ element.appendChild(element.getOwnerDocument().createTextNode(
+ dataValue.toString()));
+ }
+ }
+
+ /**
+ * Provides the mime type for a given input
+ *
+ * @param inputName
+ * @return
+ */
+ protected String getMimeTypeForInputName(String inputName) {
+ for (TypeDescriptor desc : inputDescriptors) {
+ if (desc.getName().equals(inputName))
+ return desc.getMimeType();
+ }
+ return "";
+ }
+
+ /**
+ * Generates a map of all the namespaces for the operation and all of the
+ * types required to call the operation. Namesspace prefixes (the key) start
+ * with ns1 representing the operation, and continue incrementally for all
+ * additional namespaces (ns2, ns3 ... etc).
+ *
+ * @return
+ * @param inputs -
+ * List of input TypeDescriptor's
+ * @throws UnknownOperationException
+ * @throws IOException
+ */
+ protected Map<String, String> generateNamespaceMappings(List inputs)
+ throws UnknownOperationException, IOException {
+ Map<String, String> result = new HashMap<String, String>();
+ int nsCount = 2;
+
+ result.put(getOperationNamespace(), "ns1");
+ result.put("http://www.w3.org/2001/XMLSchema", "xsd");
+ result.put("http://www.w3.org/2001/XMLSchema-instance", "xsi");
+
+ for (Iterator iterator = inputs.iterator(); iterator.hasNext();) {
+ TypeDescriptor descriptor = (TypeDescriptor) iterator.next();
+ nsCount = mapNamespace(descriptor, new ArrayList<TypeDescriptor>(),result, nsCount);
+
+ }
+
+ return result;
+ }
+
+ /**
+ * creates a namespace prefix and adds the namespace to the namespaceMap for
+ * a TypeDescriptor. Further recursive calls are made if this type contains
+ * addition inner elements that are not already mapped.
+ *
+ * @param descriptor
+ * @param namespaceMap
+ * @param nsCount
+ * @return
+ */
+ protected int mapNamespace(TypeDescriptor descriptor, List<TypeDescriptor> visitedDescriptors,
+ Map<String, String> namespaceMap, int nsCount) {
+ if (!visitedDescriptors.contains(descriptor)) {
+ visitedDescriptors.add(descriptor);
+ String namespace = descriptor.getNamespaceURI();
+ if (namespace != null && namespace.length() > 0
+ && !namespaceMap.containsKey(namespace)) {
+ namespaceMap.put(namespace, "ns" + nsCount);
+ nsCount++;
+ }
+
+ if (descriptor instanceof ArrayTypeDescriptor) {
+ nsCount = mapNamespace(((ArrayTypeDescriptor) descriptor)
+ .getElementType(),visitedDescriptors, namespaceMap, nsCount);
+ } else if (descriptor instanceof ComplexTypeDescriptor) {
+ List elements = ((ComplexTypeDescriptor) descriptor).getElements();
+ for (Iterator iterator = elements.iterator(); iterator.hasNext();) {
+ nsCount = mapNamespace((TypeDescriptor) iterator.next(),visitedDescriptors,
+ namespaceMap, nsCount);
+ }
+ }
+ }
+ else {
+ logger.error("The descriptor: "+descriptor+" is appears to be part of a cyclic schema. Bailing out of mapping namespace.");
+ }
+
+ return nsCount;
+ }
+
+ protected Element createElementNS(String namespace, String name) {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ try {
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ return builder.newDocument().createElementNS(namespace, name);
+ } catch (ParserConfigurationException e) {
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/AbstractSOAPResponseParser.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/AbstractSOAPResponseParser.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/AbstractSOAPResponseParser.java
new file mode 100644
index 0000000..638c410
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/AbstractSOAPResponseParser.java
@@ -0,0 +1,46 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.io.StringWriter;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.w3c.dom.Node;
+
+/**
+ * @author Dmitry Repchevsky
+ */
+
+public abstract class AbstractSOAPResponseParser implements SOAPResponseParser{
+
+ public String toString(Node node) throws TransformerException {
+ TransformerFactory factory = TransformerFactory.newInstance();
+ Transformer transformer = factory.newTransformer();
+ StringWriter writer = new StringWriter();
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ transformer.transform(new DOMSource(node), new StreamResult(writer));
+
+ return writer.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/BodyBuilder.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/BodyBuilder.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/BodyBuilder.java
new file mode 100644
index 0000000..89a2297
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/BodyBuilder.java
@@ -0,0 +1,45 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.io.IOException;
+import java.util.Map;
+import javax.wsdl.WSDLException;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPException;
+import org.apache.taverna.wsdl.parser.UnknownOperationException;
+import org.xml.sax.SAXException;
+
+/**
+ * Interface to a class that is responsible for creating the SOAP body elements from the provided inputs
+ * for invoking a SOAP based Web-service.
+ *
+ * @author Stuart Owen
+ */
+@SuppressWarnings("unchecked")
+public interface BodyBuilder {
+
+ public SOAPElement build(Map inputMap)
+ throws WSDLException, ParserConfigurationException, SOAPException,
+ IOException, SAXException, UnknownOperationException;
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/BodyBuilderFactory.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/BodyBuilderFactory.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/BodyBuilderFactory.java
new file mode 100644
index 0000000..64842ae
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/BodyBuilderFactory.java
@@ -0,0 +1,52 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.util.List;
+
+import org.apache.taverna.wsdl.parser.TypeDescriptor;
+import org.apache.taverna.wsdl.parser.UnknownOperationException;
+import org.apache.taverna.wsdl.parser.WSDLParser;
+
+/**
+ * Factory that creates an appropriate BodyBuilder according to the provided WSDLProcessors style and use.
+ * @author Stuart Owen
+ *
+ */
+public class BodyBuilderFactory {
+
+ private static BodyBuilderFactory instance = new BodyBuilderFactory();
+
+ public static BodyBuilderFactory instance() {
+ return instance;
+ }
+
+ public BodyBuilder create(WSDLParser parser, String operationName, List<TypeDescriptor> inputDescriptors) throws UnknownOperationException {
+ String use = parser.getUse(operationName);
+ String style = parser.getStyle(operationName);
+ if (use.equals("encoded")) {
+ return new EncodedBodyBuilder(style, parser,operationName, inputDescriptors);
+ }
+ else if (use.equals("literal")) {
+ return new LiteralBodyBuilder(style,parser,operationName, inputDescriptors);
+ }
+ return new LiteralBodyBuilder(style,parser,operationName, inputDescriptors);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/CyclicReferenceException.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/CyclicReferenceException.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/CyclicReferenceException.java
new file mode 100644
index 0000000..7f2804e
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/CyclicReferenceException.java
@@ -0,0 +1,35 @@
+/*
+* 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.taverna.wsdl.soap;
+
+/**
+ * Exception thrown when a MultiRef based xml document is found to have cyclic
+ * references when transforming into a flat XML document, therefore meaning the
+ * xml cannot be transformed.
+ *
+ * @author sowen
+ *
+ */
+
+public class CyclicReferenceException extends Exception {
+
+ private static final long serialVersionUID = -4051406646273085676L;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/EncodedBodyBuilder.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/EncodedBodyBuilder.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/EncodedBodyBuilder.java
new file mode 100644
index 0000000..a88ca88
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/EncodedBodyBuilder.java
@@ -0,0 +1,158 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.wsdl.WSDLException;
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.soap.SOAPConstants;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPFactory;
+import org.apache.taverna.wsdl.parser.ArrayTypeDescriptor;
+import org.apache.taverna.wsdl.parser.BaseTypeDescriptor;
+import org.apache.taverna.wsdl.parser.TypeDescriptor;
+import org.apache.taverna.wsdl.parser.UnknownOperationException;
+import org.apache.taverna.wsdl.parser.WSDLParser;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+@SuppressWarnings("unchecked")
+public class EncodedBodyBuilder extends AbstractBodyBuilder {
+ public EncodedBodyBuilder(String style, WSDLParser parser, String operationName, List<TypeDescriptor> inputDescriptors) {
+ super(style, parser,operationName,inputDescriptors);
+ }
+
+ @Override
+ protected Use getUse() {
+ return Use.ENCODED;
+ }
+
+ @Override
+ public SOAPElement build(Map inputMap) throws WSDLException,
+ ParserConfigurationException, SOAPException, IOException,
+ SAXException, UnknownOperationException {
+
+ SOAPElement result = super.build(inputMap);
+
+ for (Iterator iterator = namespaceMappings.keySet().iterator(); iterator.hasNext();) {
+ String namespaceURI = (String) iterator.next();
+ String ns = namespaceMappings.get(namespaceURI);
+ result.addNamespaceDeclaration(ns, namespaceURI);
+ }
+
+ result.setAttributeNS(SOAPConstants.URI_NS_SOAP_1_1_ENVELOPE, "soapenv:encodingStyle", SOAPConstants.URI_NS_SOAP_ENCODING);
+
+ return result;
+ }
+
+ @Override
+ protected Element createSkeletonElementForSingleItem(
+ Map<String, String> namespaceMappings, TypeDescriptor descriptor,
+ String inputName, String typeName) {
+
+ Element el = createElementNS(null, inputName);
+
+ String ns = namespaceMappings.get(descriptor.getNamespaceURI());
+ if (ns != null) {
+ el.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi:type", ns + ":" + descriptor.getType());
+ }
+ return el;
+ }
+
+ @Override
+ protected Element createElementForArrayType(
+ Map<String, String> namespaceMappings, String inputName,
+ Object dataValue, TypeDescriptor descriptor, String mimeType,
+ String typeName) throws ParserConfigurationException, SAXException,
+ IOException, UnknownOperationException {
+ DocumentBuilderFactory builderFactory = DocumentBuilderFactory
+ .newInstance();
+ builderFactory.setNamespaceAware(true);
+ DocumentBuilder docBuilder = builderFactory.newDocumentBuilder();
+
+ ArrayTypeDescriptor arrayDescriptor = (ArrayTypeDescriptor) descriptor;
+ TypeDescriptor elementType = arrayDescriptor.getElementType();
+ int size = 0;
+
+ Element el = createElementNS(null, inputName);
+
+ if (dataValue instanceof List) {
+ List dataValues = (List) dataValue;
+ size = dataValues.size();
+ populateElementWithList(mimeType, el, dataValues, elementType);
+ } else {
+ // if mime type is text/xml then the data is an array in xml form,
+ // else its just a single primitive element
+ if (mimeType.equals("'text/xml'")) {
+
+ Document doc = docBuilder.parse(new ByteArrayInputStream(
+ dataValue.toString().getBytes()));
+ Node child = doc.getDocumentElement().getFirstChild();
+
+ while (child != null) {
+ size++;
+ el.appendChild(el.getOwnerDocument()
+ .importNode(child, true));
+ child = child.getNextSibling();
+ }
+ } else {
+ String tag = "item";
+ if (elementType instanceof BaseTypeDescriptor) {
+ tag = elementType.getType();
+ } else {
+ tag = elementType.getName();
+ }
+ Element item = el.getOwnerDocument().createElement(tag);
+ populateElementWithObjectData(mimeType, item, dataValue, descriptor);
+ el.appendChild(item);
+ }
+
+ }
+
+ String ns = namespaceMappings.get(elementType.getNamespaceURI());
+ if (ns != null) {
+ String elementNS = ns + ":" + elementType.getType() + "[" + size + "]";
+ el.setAttributeNS(SOAPConstants.URI_NS_SOAP_ENCODING, "soapenc:arrayType", elementNS);
+ }
+
+ el.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi:type", "soapenc:Array");
+
+ return el;
+ }
+
+ @Override
+ protected SOAPElement addElementToBody(String operationNamespace, SOAPElement body, Element el) throws SOAPException {
+ SOAPElement child = SOAPFactory.newInstance().createElement(el);
+ body.addChildElement(child);
+ return body;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/JaxWSInvoker.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/JaxWSInvoker.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/JaxWSInvoker.java
new file mode 100644
index 0000000..9f0ae88
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/JaxWSInvoker.java
@@ -0,0 +1,235 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.xml.bind.DatatypeConverter;
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.soap.SOAPPart;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.ws.BindingProvider;
+import javax.xml.ws.Dispatch;
+import javax.xml.ws.Service;
+import javax.xml.ws.handler.Handler;
+import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.handler.soap.SOAPHandler;
+import javax.xml.ws.handler.soap.SOAPMessageContext;
+import javax.xml.ws.soap.SOAPBinding;
+import org.apache.taverna.wsdl.parser.WSDLParser;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.message.WSSecUsernameToken;
+import org.w3c.dom.Document;
+
+/**
+ * JAX-WS based invoker. The invoker uses Apache WSS4j security library.
+ *
+ * @author Dmitry Repchevsky
+ */
+
+public class JaxWSInvoker {
+
+ private Dispatch<SOAPMessage> dispatch;
+
+ private String username;
+ private String password;
+ private WSSTokenProfile token;
+
+ public JaxWSInvoker(WSDLParser parser, String portName, String operationName) {
+
+ QName port_qname = null;
+ for (QName service_name : parser.getServices()) {
+ loop:
+ for (String port_name : parser.getPorts(service_name)) {
+ if (portName == null) {
+ for (String operation_name : parser.getOperations(port_name)) {
+ if (operation_name.equals(operationName)) {
+ port_qname = new QName(port_name);
+ break loop;
+ }
+ }
+ } else if (portName.equals(port_name)) {
+ port_qname = new QName(portName);
+ break;
+ }
+ }
+
+ if (port_qname != null) {
+ // found the port in this service
+ Service service = Service.create(service_name);
+ String endpoint = parser.getOperationEndpointLocation(port_qname.getLocalPart());
+ service.addPort(port_qname, SOAPBinding.SOAP11HTTP_BINDING, endpoint); // TODO: SOAP version
+ dispatch = service.createDispatch(port_qname, SOAPMessage.class, javax.xml.ws.Service.Mode.MESSAGE);
+
+ List<Handler> chain = new ArrayList<Handler>();//Arrays.asList(new InvokerHandler());
+ chain.add(new WSSHandler());
+
+ dispatch.getBinding().setHandlerChain(chain);
+
+ break;
+ }
+ }
+
+ // assert(dispatch != null)
+
+ if (operationName != null) {
+ try {
+ String soapAction = parser.getSOAPActionURI(operationName);
+ if (soapAction != null) {
+ Map<String, Object> rc = dispatch.getRequestContext();
+ rc.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
+ rc.put(BindingProvider.SOAPACTION_URI_PROPERTY, soapAction);
+ }
+ }
+ catch(Exception ex) {}
+ }
+ }
+
+ /**
+ * Sets user credentials. If there is no WSS token profile is defined HTTP security is used
+ *
+ * @param username
+ * @param password
+ */
+ public void setCredentials(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ /**
+ * Specifies a token profile for WSS security
+ *
+ * @param token WSS security token to be used
+ */
+ public void setWSSSecurity(WSSTokenProfile token) {
+ this.token = token;
+ }
+
+ /**
+ * Sets up an http timeout.
+ *
+ * @param timeout
+ */
+ public void setTimeout(int timeout) {
+ Map<String, Object> rc = dispatch.getRequestContext();
+
+ // these parameters are SUN METRO JAX-WS implementation specific
+ rc.put("com.sun.xml.internal.ws.request.timeout", timeout);
+ rc.put("com.sun.xml.internal.ws.connect.timeout", timeout);
+
+// rc.put(BindingProviderProperties.REQUEST_TIMEOUT, timeout);
+// rc.put(BindingProviderProperties.CONNECT_TIMEOUT, timeout);
+ }
+
+ public SOAPMessage call(SOAPMessage message) throws Exception {
+
+ Map<String, Object> rc = dispatch.getRequestContext();
+
+ // if credentials are set, but no WS-Security token is defined
+ // use Basic HTTP Authentication
+ if (username != null && username.length() > 0 &&
+ password != null && password.length() > 0 &&
+ token == null) {
+ rc.put(BindingProvider.USERNAME_PROPERTY, username);
+ rc.put(BindingProvider.PASSWORD_PROPERTY, password);
+ } else {
+ if (rc.containsKey(BindingProvider.USERNAME_PROPERTY)) {
+ rc.remove(BindingProvider.USERNAME_PROPERTY);
+ }
+ if (rc.containsKey(BindingProvider.PASSWORD_PROPERTY)) {
+ rc.remove(BindingProvider.PASSWORD_PROPERTY);
+ }
+ }
+
+ return dispatch.invoke(message);
+ }
+
+ class WSSHandler implements SOAPHandler<SOAPMessageContext> {
+
+ @Override
+ public Set getHeaders() {
+ return Collections.EMPTY_SET;
+ }
+
+ @Override
+ public void close(MessageContext context) {
+
+ }
+
+ @Override
+ public boolean handleMessage(SOAPMessageContext context) {
+
+ if (Boolean.TRUE == context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)) {
+ if (username != null && username.length() > 0 &&
+ password != null && password.length() > 0 &&
+ token != null) {
+
+ SOAPMessage message = context.getMessage();
+ SOAPPart part = message.getSOAPPart();
+
+ try {
+ switch(token) {
+ case UsernameToken: {
+ WSSecUsernameToken builder = new WSSecUsernameToken();
+ builder.setPasswordType(WSConstants.PASSWORD_TEXT);
+ builder.setUserInfo(username, password);
+
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(part);
+ Document signed = builder.build(part, secHeader);
+ part.setContent(new DOMSource(signed));
+ }
+ case PasswordDigest: {
+ WSSecUsernameToken builder = new WSSecUsernameToken();
+ builder.setPasswordType(WSConstants.PASSWORD_TEXT);
+ MessageDigest sha = MessageDigest.getInstance("MD5");
+ sha.reset();
+ sha.update(password.getBytes());
+ String passwdDigest = DatatypeConverter.printBase64Binary(sha.digest());
+ builder.setUserInfo(username, passwdDigest);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(part);
+ Document signed = builder.build(part, secHeader);
+ part.setContent(new DOMSource(signed));
+ }
+ }
+ }
+ catch (WSSecurityException | SOAPException | NoSuchAlgorithmException ex) {}
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean handleFault(SOAPMessageContext context) {
+ return true;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/LiteralBodyBuilder.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/LiteralBodyBuilder.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/LiteralBodyBuilder.java
new file mode 100644
index 0000000..816837d
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/LiteralBodyBuilder.java
@@ -0,0 +1,226 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.wsdl.WSDLException;
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPFactory;
+
+import org.apache.taverna.wsdl.parser.ArrayTypeDescriptor;
+import org.apache.taverna.wsdl.parser.BaseTypeDescriptor;
+import org.apache.taverna.wsdl.parser.TypeDescriptor;
+import org.apache.taverna.wsdl.parser.UnknownOperationException;
+import org.apache.taverna.wsdl.parser.WSDLParser;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+/**
+ * An implementation of BodyBuilder that supports creating the SOAP body for
+ * Webservices based upon a WSDL with Literal style.
+ *
+ * @author Stuart Owen
+ * @author Stian Soiland-Reyes
+ *
+ */
+@SuppressWarnings("unchecked")
+public class LiteralBodyBuilder extends AbstractBodyBuilder {
+
+ private static Logger logger = Logger.getLogger(LiteralBodyBuilder.class);
+
+ private static final String TYPE = "type";
+
+ public LiteralBodyBuilder(String style, WSDLParser parser, String operationName, List<TypeDescriptor> inputDescriptors) {
+ super(style, parser, operationName,inputDescriptors);
+ }
+
+ @Override
+ protected Use getUse() {
+ return Use.LITERAL;
+ }
+
+ @Override
+ public SOAPElement build(Map inputMap) throws WSDLException,
+ ParserConfigurationException, SOAPException, IOException,
+ SAXException, UnknownOperationException {
+
+ SOAPElement body = super.build(inputMap);
+
+ if (getStyle() == Style.DOCUMENT) {
+ fixTypeAttributes(body);
+ }
+
+ return body;
+ }
+
+ @Override
+ protected Element createSkeletonElementForSingleItem(
+ Map<String, String> namespaceMappings, TypeDescriptor descriptor,
+ String inputName, String typeName) {
+ if (getStyle()==Style.DOCUMENT) {
+ return createElementNS("", descriptor.getQname().getLocalPart());
+
+ } else {
+ return createElementNS("", inputName);
+ }
+ }
+
+ private void fixTypeAttributes(Node parent) {
+ if (parent.getNodeType() == Node.ELEMENT_NODE) {
+ Element el = (Element) parent;
+ if (parent.hasAttributes()) {
+ NamedNodeMap attributes = parent.getAttributes();
+ List<Node> attributeNodesForRemoval = new ArrayList<Node>();
+ for (int i = 0; i < attributes.getLength(); i++) {
+ Node node = attributes.item(i);
+
+ if (XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI.equals(node.getNamespaceURI()) && TYPE.equals(node.getLocalName())) {
+ // TAV-712 - don't just strip out xsi:type - let's fix the
+ // name prefixes instead
+
+ String xsiType = node.getTextContent();
+ // Resolve prefix of xsi type
+ String[] xsiTypeSplitted = xsiType.split(":", 2);
+ String xsiTypePrefix = "";
+ String xsiTypeName;
+ if (xsiTypeSplitted.length == 1) {
+ // No prefix
+ xsiTypeName = xsiTypeSplitted[0];
+ } else {
+ xsiTypePrefix = xsiTypeSplitted[0];
+ xsiTypeName = xsiTypeSplitted[1];
+ }
+
+ String xsiTypeNS;
+ if (parent instanceof SOAPElement) {
+ xsiTypeNS = ((SOAPElement)parent).getNamespaceURI(xsiTypePrefix);
+ } else {
+ xsiTypeNS = node
+ .lookupNamespaceURI(xsiTypePrefix);
+ }
+ // Use global namespace prefixes
+ String newPrefix = namespaceMappings.get(xsiTypeNS);
+ if (newPrefix == null) {
+ logger.warn("Can't find prefix for xsi:type namespace " + xsiTypeNS + " - keeping old " + xsiType);
+ } else {
+ String newXsiType = newPrefix + ":" + xsiTypeName;
+ node.setTextContent(newXsiType);
+ logger.info("Replacing " + xsiType + " with " + newXsiType);
+ }
+ }
+ }
+ for (Node node : attributeNodesForRemoval) {
+ el.removeAttributeNS(node.getNamespaceURI(), node
+ .getLocalName());
+ }
+ }
+ }
+ for (int i = 0; i < parent.getChildNodes().getLength(); i++) {
+ fixTypeAttributes(parent.getChildNodes().item(i));
+ }
+ }
+
+ @Override
+ protected Element createElementForArrayType(
+ Map<String, String> namespaceMappings, String inputName,
+ Object dataValue, TypeDescriptor descriptor, String mimeType,
+ String typeName) throws ParserConfigurationException, SAXException,
+ IOException, UnknownOperationException {
+
+ ArrayTypeDescriptor arrayDescriptor = (ArrayTypeDescriptor) descriptor;
+ TypeDescriptor elementType = arrayDescriptor.getElementType();
+ int size = 0;
+
+ Element el = createElementNS("", inputName);
+
+ if (dataValue instanceof List) {
+ List dataValues = (List) dataValue;
+ size = dataValues.size();
+ populateElementWithList(mimeType, el, dataValues, elementType);
+ } else {
+
+ // if mime type is text/xml then the data is an array in xml form,
+ // else its just a single primitive element
+ if (mimeType.equals("'text/xml'")) {
+ DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
+ builderFactory.setNamespaceAware(true);
+ DocumentBuilder docBuilder = builderFactory.newDocumentBuilder();
+ Document doc = docBuilder.parse(new ByteArrayInputStream(
+ dataValue.toString().getBytes()));
+ Node child = doc.getDocumentElement().getFirstChild();
+
+ while (child != null) {
+ size++;
+ el.appendChild(el.getOwnerDocument()
+ .importNode(child, true));
+ child = child.getNextSibling();
+ }
+ } else {
+ String tag = "item";
+ if (elementType instanceof BaseTypeDescriptor) {
+ tag = elementType.getType();
+ } else {
+ tag = elementType.getName();
+ }
+ Element item = el.getOwnerDocument().createElement(tag);
+ populateElementWithObjectData(mimeType, item, dataValue, descriptor);
+ el.appendChild(item);
+ }
+
+ }
+
+ return el;
+ }
+
+ @Override
+ protected SOAPElement addElementToBody(String operationNamespace, SOAPElement body, Element el) throws SOAPException {
+ SOAPElement element = SOAPFactory.newInstance().createElement(el);
+
+ if (getStyle()==Style.DOCUMENT) {
+ // el itself is a body
+ Node node = el.getOwnerDocument().renameNode(el, operationNamespace, el.getLocalName());
+ node.setPrefix(body.getPrefix()); // unnecessary, but to keep junits happy
+
+ body = SOAPFactory.newInstance().createElement((Element)node);
+
+ } else {
+ body.addChildElement(element);
+ }
+ return body;
+ }
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/ObjectConverter.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/ObjectConverter.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/ObjectConverter.java
new file mode 100644
index 0000000..3eadc9e
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/ObjectConverter.java
@@ -0,0 +1,158 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * <p>
+ * This class replicates the behaviour of data conversion when using DataThingFactory.bake in Taverna 1.
+ * </p>
+ * <p>
+ * In particular it deals with the conversion of arrays to ArrayList
+ * </p>
+ * @author Stuart Owen
+ *
+ *
+ */
+public class ObjectConverter {
+
+ /**
+ * Converts an Object into an appropriate type, in particular recursively converting [] arrays to List<?>'s.<br>
+ *
+ * This method is a copy of convertObject in DataThingFactory from Taverna 1
+ * @param theObject
+ * @return
+ */
+ public static Object convertObject(Object theObject) {
+
+ if (theObject == null) {
+ return null;
+ }
+ // If an array type...
+ Class<?> theClass = theObject.getClass();
+ if (theClass.isArray()) {
+ // Special case for byte[]
+ if (theObject instanceof byte[]) {
+ // System.out.println("Found a byte[], returning it.");
+ return theObject;
+ } //extra primitive object checks for those fun edge cases!
+ else if (theObject instanceof int[]){
+ List<Object> l = new ArrayList<Object>();
+ for (int i = 0; i<((int[])theObject).length;i++) {
+ Object a = ((int[])theObject)[i];
+ l.add(convertObject(a));
+ }
+ return l;
+ } else if (theObject instanceof short[]){
+ List<Object> l = new ArrayList<Object>();
+ for (int i = 0; i<((short[])theObject).length;i++) {
+ Object a = ((short[])theObject)[i];
+ l.add(convertObject(a));
+ }
+ return l;
+ } else if (theObject instanceof long[]){
+ List<Object> l = new ArrayList<Object>();
+ for (int i = 0; i<((long[])theObject).length;i++) {
+ Object a = ((long[])theObject)[i];
+ l.add(convertObject(a));
+ }
+ return l;
+ } else if (theObject instanceof float[]){
+ List<Object> l = new ArrayList<Object>();
+ for (int i = 0; i<((float[])theObject).length;i++) {
+ Object a = ((float[])theObject)[i];
+ l.add(convertObject(a));
+ }
+ return l;
+ } else if (theObject instanceof double[]){
+ List<Object> l = new ArrayList<Object>();
+ for (int i = 0; i<((double[])theObject).length;i++) {
+ Object a = ((double[])theObject)[i];
+ l.add(convertObject(a));
+ }
+ return l;
+ } else if (theObject instanceof boolean[]){
+ List<Object> l = new ArrayList<Object>();
+ for (int i = 0; i<((boolean[])theObject).length;i++) {
+ Object a = ((boolean[])theObject)[i];
+ l.add(convertObject(a));
+ }
+ return l;
+ } else if (theObject instanceof char[]){
+ List<Object> l = new ArrayList<Object>();
+ for (int i = 0; i<((char[])theObject).length;i++) {
+ Object a = ((char[])theObject)[i];
+ l.add(convertObject(a));
+ }
+ return l;
+ } else {
+ // For all other arrays, create a new
+ // List and iterate over the array,
+ // unpackaging the item and recursively
+ // putting it into the new List after
+ // conversion
+
+ // System.out.println("Found an array length
+ // "+theArray.length+", repacking as List...");
+
+ List<Object> l = new ArrayList<Object>();
+ Object[] theArray = (Object[]) theObject;
+ for (int i = 0; i < theArray.length; i++) {
+ l.add(convertObject(theArray[i]));
+ }
+ return l;
+ }
+ }
+ // If a collection, iterate over it and copy
+ if (theObject instanceof Collection) {
+ if (theObject instanceof List) {
+ // System.out.println("Re-packing a list...");
+ List<Object> l = new ArrayList<Object>();
+ for (Iterator<?> i = ((List<?>) theObject).iterator(); i.hasNext();) {
+ l.add(convertObject(i.next()));
+ }
+ return l;
+ } else if (theObject instanceof Set) {
+ // System.out.println("Re-packing a set...");
+ Set<Object> s = new HashSet<Object>();
+ for (Iterator<?> i = ((Set<?>) theObject).iterator(); i.hasNext();) {
+ s.add(convertObject(i.next()));
+ }
+ return s;
+ }
+ }
+ // If a number then return the string representation for it
+ if (theObject instanceof Number) {
+ // System.out.println("Found a number, converting it to a
+ // string...");
+ return theObject.toString();
+ }
+ // Otherwise just return the object
+ // System.out.println("Found a "+theObject.getClass().getName()+",
+ // returning it");
+ return theObject;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseEncodedMultiRefParser.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseEncodedMultiRefParser.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseEncodedMultiRefParser.java
new file mode 100644
index 0000000..ed15b10
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseEncodedMultiRefParser.java
@@ -0,0 +1,181 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.xml.soap.SOAPElement;
+
+import org.apache.taverna.wsdl.parser.TypeDescriptor;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+/**
+ * A SOAPResponseParser responsible for responses that are fragmented into
+ * seperate referenced blocks of XML - Multiref format. It trys to resolve each
+ * reference to the corresponding multiref element, eventually generating a
+ * single XML document. Cyclic references are not allows, and lead to a
+ * CyclicReferenceException
+ *
+ * @author sowen
+ *
+ */
+@SuppressWarnings("unchecked")
+public class SOAPResponseEncodedMultiRefParser extends
+ SOAPResponseEncodedParser {
+
+ private List resolvedReferences = new ArrayList();
+
+ private Map referenceMap;
+
+ public SOAPResponseEncodedMultiRefParser(List<TypeDescriptor> outputDescriptors) {
+ super(outputDescriptors);
+ }
+
+ /**
+ * Expects a list of XML SOAPBodyElement fragements, with the first being
+ * the root, and transforms this into a single XML document. Cyclic
+ * references lead to a CyclicReferenceException being thrown. XML
+ * namespaces are removed, leading to easier to read XML.
+ *
+ * @param response -
+ * List of XML SOAPBodyElement fragments.
+ */
+ @Override
+ public Map parse(List<SOAPElement> response) throws Exception, CyclicReferenceException {
+ Map result = new HashMap();
+ generateRefMap(response);
+ expandRefMap();
+ SOAPElement mainBody = response.get(0);
+
+ for (TypeDescriptor descriptor : outputDescriptors) {
+ String outputName = descriptor.getName();
+
+ Node outputNode = getOutputNode(mainBody, outputName);
+ if (outputNode != null) {
+ expandNode(outputNode, new ArrayList());
+ String xml;
+ if (getStripAttributes()) {
+ stripAttributes(outputNode);
+ outputNode = removeNamespace(outputName, (Element) outputNode);
+ }
+ xml = toString(outputNode);
+
+ result.put(outputName, xml);
+ }
+
+ }
+
+ return result;
+ }
+
+ /**
+ * Generates a map of each multiref element, mapped to its ID.
+ *
+ * @param response
+ * @throws Exception
+ */
+ private void generateRefMap(List response) throws Exception {
+ Map result = new HashMap();
+
+ for (Iterator iterator = response.iterator(); iterator.hasNext();) {
+ SOAPElement bodyElement = (SOAPElement) iterator.next();
+ String id = bodyElement.getAttribute("id");
+ if (id.length() > 0) {
+ result.put("#" + id, bodyElement);
+ }
+ }
+
+ referenceMap = result;
+ }
+
+ /**
+ * Expands any references to other fragments within each multiref fragment,
+ * resulting in all multiref fragments being fully expanded.
+ *
+ * @throws CyclicReferenceException
+ */
+ private void expandRefMap() throws CyclicReferenceException {
+ for (Iterator iterator = referenceMap.keySet().iterator(); iterator
+ .hasNext();) {
+ String key = (String) iterator.next();
+ if (!resolvedReferences.contains(key)) {
+ expandMultirefElement(key, new ArrayList());
+ }
+ }
+ }
+
+ private void expandMultirefElement(String key, List parentKeys)
+ throws CyclicReferenceException {
+ if (parentKeys.contains(key))
+ throw new CyclicReferenceException();
+ parentKeys.add(key);
+ Node node = (Node) referenceMap.get(key);
+ expandNode(node, parentKeys);
+ resolvedReferences.add(key);
+ parentKeys.remove(key);
+ }
+
+ private void expandNode(Node node, List parentKeys)
+ throws CyclicReferenceException {
+ String href = getHrefForNode(node);
+ if (href != null) {
+ if (!resolvedReferences.contains(href)) {
+ expandMultirefElement(href, parentKeys);
+ }
+ copyMultirefContentsToParent(node, href);
+ }
+ if (node.hasChildNodes()) {
+ Node child = node.getFirstChild();
+ while (child != null) {
+ expandNode(child, parentKeys);
+ child = child.getNextSibling();
+ }
+ }
+ }
+
+ private void copyMultirefContentsToParent(Node parent, String multirefKey) {
+ Element multiRef = (Element) referenceMap.get(multirefKey);
+ Node child = multiRef.getFirstChild();
+ while (child != null) {
+ parent.appendChild(parent.getOwnerDocument()
+ .importNode(child, true));
+ child = child.getNextSibling();
+ }
+ parent.getAttributes().removeNamedItem("href");
+ }
+
+ private String getHrefForNode(Node node) {
+ String result = null;
+ NamedNodeMap nodemap = node.getAttributes();
+ if (nodemap != null) {
+ Node attrNode = nodemap.getNamedItem("href");
+ if (attrNode != null) {
+ result = attrNode.getNodeValue();
+ }
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseEncodedParser.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseEncodedParser.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseEncodedParser.java
new file mode 100644
index 0000000..9b9b3c9
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseEncodedParser.java
@@ -0,0 +1,174 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.soap.SOAPElement;
+
+import org.apache.taverna.wsdl.parser.TypeDescriptor;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+/**
+ * SOAPResponseParser responsible for parsing SOAP responses from RPC/encoded
+ * based service, but that are not fragmented to multiref documents.
+ *
+ * @author sowen
+ *
+ */
+@SuppressWarnings("unchecked")
+public class SOAPResponseEncodedParser extends AbstractSOAPResponseParser {
+
+ protected List<TypeDescriptor> outputDescriptors;
+
+ private boolean stripAttributes = false;
+
+ public SOAPResponseEncodedParser(List<TypeDescriptor> outputDescriptors) {
+ this.outputDescriptors = outputDescriptors;
+ }
+
+ /**
+ * Parses the response into a single XML document, which is placed in the
+ * outputMap together with the given output name. Namespaces and other
+ * attributes are stripped out according to stripAttributes.
+ *
+ * @param List
+ * @return Map
+ */
+ @Override
+ public Map parse(List<SOAPElement> response) throws Exception {
+
+ Map result = new HashMap();
+ SOAPElement mainBody = response.get(0);
+
+ for (TypeDescriptor descriptor : outputDescriptors) {
+ String outputName = descriptor.getName();
+
+ Node outputNode = getOutputNode(mainBody, outputName);
+ if (outputNode != null) {
+ if (stripAttributes) {
+ stripAttributes(outputNode);
+ outputNode = removeNamespace(outputName, (Element) outputNode);
+ }
+
+ String xml = toString(outputNode);
+ result.put(outputName, xml);
+ }
+ }
+
+ return result;
+ }
+
+ protected Node getOutputNode(Element mainBody, String outputName) {
+ // first try using body namespace ...
+ Node outputNode = mainBody.getElementsByTagNameNS(
+ mainBody.getNamespaceURI(), outputName).item(0);
+ // ... and if that doesn't work, try without namespace
+ if (outputNode == null) {
+ outputNode = mainBody.getElementsByTagName(outputName).item(
+ 0);
+ }
+ if (outputNode == null) { // if still null, and there is only 1
+ // output, take the first child
+ if (outputDescriptors.size() == 1
+ && mainBody.getChildNodes().getLength() == 1) {
+ outputNode = mainBody.getFirstChild();
+ }
+ }
+ return outputNode;
+ }
+
+ /**
+ * Removes the namespace from the surrounding element that represents the
+ * outputName. E.g. converts <ns1:element xmlns:ns1="http://someurl">...</ns1:element>
+ * to <element>...</element>
+ *
+ * @param outputName
+ * @param element
+ * @return
+ * @throws ParserConfigurationException
+ * @throws IOException
+ * @throws SAXException
+ */
+ protected Element removeNamespace(String outputName, Element element)
+ throws ParserConfigurationException, SAXException, IOException {
+
+ return (Element)element.getOwnerDocument().renameNode(element, null, element.getLocalName());
+
+ // :-O
+// String xml;
+// String innerXML = XMLUtils.getInnerXMLString(element);
+// if (innerXML != null) {
+// xml = "<" + outputName + ">" + innerXML + "</" + outputName + ">";
+// } else {
+// xml = "<" + outputName + " />";
+// }
+// DocumentBuilder builder = DocumentBuilderFactory.newInstance()
+// .newDocumentBuilder();
+// Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes()));
+// return doc.getDocumentElement();
+ }
+
+ protected void stripAttributes(Node node) {
+ List names = new ArrayList();
+ if (node.getAttributes() != null) {
+ for (int i = 0; i < node.getAttributes().getLength(); i++) {
+ names.add(node.getAttributes().item(i).getNodeName());
+ }
+ }
+
+ for (Iterator iterator = names.iterator(); iterator.hasNext();) {
+ node.getAttributes().removeNamedItem((String) iterator.next());
+ }
+
+ if (node.hasChildNodes()) {
+ Node child = node.getFirstChild();
+ while (child != null) {
+ stripAttributes(child);
+ child = child.getNextSibling();
+ }
+ }
+
+ }
+
+ /**
+ * determines whether attributes in the resulting XML should be stripped
+ * out, including namespace definitions, leading to XML that is much easier
+ * to read.
+ *
+ * @param stripAttributes
+ */
+ public void setStripAttributes(boolean stripAttributes) {
+ this.stripAttributes = stripAttributes;
+ }
+
+ public boolean getStripAttributes() {
+ return this.stripAttributes;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseLiteralParser.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseLiteralParser.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseLiteralParser.java
new file mode 100644
index 0000000..7f7c2c8
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseLiteralParser.java
@@ -0,0 +1,79 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.soap.SOAPElement;
+
+import org.apache.taverna.wsdl.parser.TypeDescriptor;
+
+/**
+ * Responsible for parsing the SOAP response from calling a Literal based
+ * service.
+ *
+ * @author sowen
+ *
+ */
+@SuppressWarnings("unchecked")
+public class SOAPResponseLiteralParser extends AbstractSOAPResponseParser {
+
+ List<TypeDescriptor>outputDescriptors;
+
+ public SOAPResponseLiteralParser(List<TypeDescriptor> outputDescriptors) {
+ this.outputDescriptors = outputDescriptors;
+ }
+
+ /**
+ * Expects a list containing a single SOAPBodyElement, the contents of which
+ * are transferred directly to the output, converted to a String, and placed
+ * into the outputMaP which is returned
+ *
+ * @return Map of the outputs
+ */
+ @Override
+ public Map parse(List response) throws Exception {
+ Map result = new HashMap();
+
+ if (response.size() > 0) {
+ SOAPElement rpcElement = (SOAPElement) response.get(0);
+
+ String outputName = getOutputName();
+ String xml = toString(rpcElement);
+
+ result.put(outputName, xml);
+ }
+
+ return result;
+ }
+
+ protected String getOutputName() {
+ String result = "";
+ for (TypeDescriptor descriptor : outputDescriptors) {
+ String name=descriptor.getName();
+ if (!name.equals("attachmentList")) {
+ result = name;
+ break;
+ }
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseParser.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseParser.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseParser.java
new file mode 100644
index 0000000..f919b87
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseParser.java
@@ -0,0 +1,48 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.util.List;
+import java.util.Map;
+import javax.xml.soap.SOAPElement;
+
+/**
+ * Inteface that defines all parsers responsible for parsing SOAP responses from
+ * calling SOAP based webservices.
+ *
+ * @author sowen
+ *
+ */
+@SuppressWarnings("unchecked")
+public interface SOAPResponseParser {
+
+ /**
+ * All SOAPResponseParsers take a list of SOAPBodyElement's, resulting from
+ * invoking the service, and convert these into a suitable map of output
+ * DataThings.
+ *
+ * @param response -
+ * List of SOAPBodyElements
+ * @return Map of output DataThing's mapped to their output name
+ * @throws Exception
+ */
+ public Map parse(List<SOAPElement> response) throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseParserFactory.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseParserFactory.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseParserFactory.java
new file mode 100644
index 0000000..a092076
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponseParserFactory.java
@@ -0,0 +1,94 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.util.List;
+
+import org.apache.taverna.wsdl.parser.TypeDescriptor;
+
+/**
+ * A factory class that selects the correct type of SOAPResponseParser according
+ * to the service type , the types output of that service, and the response from
+ * invoking that service.
+ *
+ * @author sowen
+ *
+ */
+@SuppressWarnings("unchecked")
+public class SOAPResponseParserFactory {
+
+ private static SOAPResponseParserFactory instance = new SOAPResponseParserFactory();
+
+ public static SOAPResponseParserFactory instance() {
+ return instance;
+ }
+
+ /**
+ * returns an instance of the appropriate type of SOAPResponseParser
+ *
+ * @param response -
+ * List of SOAPBodyElement's resulting from the service
+ * invokation.
+ * @param use -
+ * the type of the service - 'literal' or 'encoded'
+ * @param style -
+ * the style of the service - 'document' or 'rpc'
+ * @param outputDescriptors -
+ * the List of {@link TypeDescriptor}'s describing the service outputs
+ * @return
+ * @see SOAPResponseParser
+ */
+ public SOAPResponseParser create(List response, String use, String style,
+ List<TypeDescriptor> outputDescriptors) {
+
+ SOAPResponseParser result = null;
+
+ if (outputIsPrimitive(outputDescriptors)) {
+ if (use.equalsIgnoreCase("literal")) {
+ result = new SOAPResponsePrimitiveLiteralParser(outputDescriptors);
+ }
+ else {
+ result = new SOAPResponsePrimitiveParser(outputDescriptors);
+ }
+ } else if (use.equals("literal")) {
+ result = new SOAPResponseLiteralParser(outputDescriptors);
+ } else {
+ if (response.size() > 1) {
+ result = new SOAPResponseEncodedMultiRefParser(outputDescriptors);
+ } else {
+ result = new SOAPResponseEncodedParser(outputDescriptors);
+ }
+ }
+
+ return result;
+ }
+
+ private boolean outputIsPrimitive(List<TypeDescriptor> outputDescriptors) {
+ boolean result = true;
+ for (TypeDescriptor d : outputDescriptors) {
+ if (d.getMimeType().equals("'text/xml'")) {
+ result = false;
+ break;
+ }
+ }
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponsePrimitiveLiteralParser.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponsePrimitiveLiteralParser.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponsePrimitiveLiteralParser.java
new file mode 100644
index 0000000..f65c46d
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponsePrimitiveLiteralParser.java
@@ -0,0 +1,71 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.io.ByteArrayInputStream;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.taverna.wsdl.parser.TypeDescriptor;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * A response parser specifically for literal use services that return primative types.
+ * It extends the SOAPReponseLiteralParser, but unwraps the result from the enclosing XML
+ * to expose the primitive result.
+ *
+ * This is specially designed for unwrapped/literal type services, and RPC/literal services (untested).
+ * @author Stuart
+ *
+ */
+@SuppressWarnings("unchecked")
+public class SOAPResponsePrimitiveLiteralParser extends
+ SOAPResponseLiteralParser {
+
+ public SOAPResponsePrimitiveLiteralParser(List<TypeDescriptor> outputDescriptors) {
+ super(outputDescriptors);
+ }
+
+ @Override
+ public Map parse(List response) throws Exception {
+ Map result = super.parse(response);
+ Object dataValue = result.get(getOutputName());
+ if (dataValue!=null) {
+ String xml = dataValue.toString();
+
+ DocumentBuilder builder = DocumentBuilderFactory.newInstance()
+ .newDocumentBuilder();
+ Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes()));
+
+ Node node = doc.getFirstChild();
+ result.put(getOutputName(), node.getFirstChild().getNodeValue());
+ }
+ return result;
+ }
+
+
+}
+
+