You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2015/02/17 12:36:34 UTC
[14/70] [abbrv] incubator-taverna-common-activities git commit:
taverna-wsdl-generic/
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/AbstractBodyBuilder.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/AbstractBodyBuilder.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/AbstractBodyBuilder.java
new file mode 100644
index 0000000..445e158
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/AbstractBodyBuilder.java
@@ -0,0 +1,362 @@
+/*******************************************************************************
+ * Copyright (C) 2007 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.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.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.soap.SOAPException;
+
+import net.sf.taverna.wsdl.parser.ArrayTypeDescriptor;
+import net.sf.taverna.wsdl.parser.BaseTypeDescriptor;
+import net.sf.taverna.wsdl.parser.ComplexTypeDescriptor;
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+import net.sf.taverna.wsdl.parser.UnknownOperationException;
+import net.sf.taverna.wsdl.parser.WSDLParser;
+
+import org.apache.axis.encoding.Base64;
+import org.apache.axis.message.SOAPBodyElement;
+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);
+ }
+
+ public SOAPBodyElement build(Map inputMap) throws WSDLException,
+ ParserConfigurationException, SOAPException, IOException,
+ SAXException, UnknownOperationException {
+
+ List inputs = parser.getOperationInputParameters(operationName);
+
+ namespaceMappings = generateNamespaceMappings(inputs);
+
+ QName operationQname = getOperationQname();
+
+ SOAPBodyElement body = new SOAPBodyElement(operationQname);
+
+ // its important to preserve the order of the inputs!
+ for (Iterator iterator = inputs.iterator(); iterator.hasNext();) {
+ TypeDescriptor descriptor = (TypeDescriptor) iterator.next();
+ String inputName = descriptor.getName();
+ Object dataValue = inputMap.get(inputName);
+
+ body = createBodyElementForData(operationName, namespaceMappings,
+ operationQname.getNamespaceURI(), body, descriptor, inputName, dataValue);
+ }
+
+ return body;
+ }
+
+
+
+ protected SOAPBodyElement createBodyElementForData(String operationName,
+ Map<String, String> namespaceMappings, String operationNamespace,
+ SOAPBodyElement 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 = null;
+
+ 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 SOAPBodyElement addElementToBody(
+ String operationNamespace, SOAPBodyElement 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 = Base64.encode((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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/BodyBuilder.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/BodyBuilder.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/BodyBuilder.java
new file mode 100644
index 0000000..7e6c8d0
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/BodyBuilder.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (C) 2007 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.soap;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.wsdl.WSDLException;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.soap.SOAPException;
+
+import net.sf.taverna.wsdl.parser.UnknownOperationException;
+
+import org.apache.axis.message.SOAPBodyElement;
+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 SOAPBodyElement build(Map inputMap)
+ throws WSDLException, ParserConfigurationException, SOAPException,
+ IOException, SAXException, UnknownOperationException;
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/BodyBuilderFactory.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/BodyBuilderFactory.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/BodyBuilderFactory.java
new file mode 100644
index 0000000..c827770
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/BodyBuilderFactory.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (C) 2007 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.soap;
+
+import java.util.List;
+
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+import net.sf.taverna.wsdl.parser.UnknownOperationException;
+import net.sf.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();
+ 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/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/CyclicReferenceException.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/CyclicReferenceException.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/CyclicReferenceException.java
new file mode 100644
index 0000000..027e49b
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/CyclicReferenceException.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2003 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate. Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * 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
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename $RCSfile: CyclicReferenceException.java,v $
+ * Revision $Revision: 1.1 $
+ * Release status $State: Exp $
+ * Last modified on $Date: 2007/11/28 16:05:45 $
+ * by $Author: sowen70 $
+ * Created on 05-May-2006
+ *****************************************************************/
+package net.sf.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/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/EncodedBodyBuilder.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/EncodedBodyBuilder.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/EncodedBodyBuilder.java
new file mode 100644
index 0000000..6f332ff
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/EncodedBodyBuilder.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (C) 2007 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.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.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.soap.SOAPException;
+
+import net.sf.taverna.wsdl.parser.ArrayTypeDescriptor;
+import net.sf.taverna.wsdl.parser.BaseTypeDescriptor;
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+import net.sf.taverna.wsdl.parser.UnknownOperationException;
+import net.sf.taverna.wsdl.parser.WSDLParser;
+
+import org.apache.axis.message.SOAPBodyElement;
+import org.apache.axis.utils.XMLUtils;
+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 SOAPBodyElement build(Map inputMap) throws WSDLException,
+ ParserConfigurationException, SOAPException, IOException,
+ SAXException, UnknownOperationException {
+
+ SOAPBodyElement 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.setAttribute("soapenv:encodingStyle",
+ "http://schemas.xmlsoap.org/soap/encoding/");
+ return result;
+ }
+
+ @Override
+ protected Element createSkeletonElementForSingleItem(
+ Map<String, String> namespaceMappings, TypeDescriptor descriptor,
+ String inputName, String typeName) {
+ Element el = XMLUtils.StringToElement("", inputName, "");
+
+ String ns = namespaceMappings.get(descriptor.getNamespaceURI());
+ if (ns != null) {
+ el.setAttribute("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();
+
+ Element el;
+ ArrayTypeDescriptor arrayDescriptor = (ArrayTypeDescriptor) descriptor;
+ TypeDescriptor elementType = arrayDescriptor.getElementType();
+ int size = 0;
+
+ el = XMLUtils.StringToElement("", 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.setAttribute("soapenc:arrayType", elementNS);
+ el.setAttribute("xmlns:soapenc",
+ "http://schemas.xmlsoap.org/soap/encoding/");
+ }
+
+ el.setAttribute("xsi:type", "soapenc:Array");
+
+ return el;
+ }
+
+ @Override
+ protected SOAPBodyElement addElementToBody(String operationNamespace, SOAPBodyElement body, Element el) throws SOAPException {
+ body.addChildElement(new SOAPBodyElement(el));
+ return body;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/LiteralBodyBuilder.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/LiteralBodyBuilder.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/LiteralBodyBuilder.java
new file mode 100644
index 0000000..274aa55
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/LiteralBodyBuilder.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (C) 2007 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.soap;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.wsdl.WSDLException;
+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 net.sf.taverna.wsdl.parser.ArrayTypeDescriptor;
+import net.sf.taverna.wsdl.parser.BaseTypeDescriptor;
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+import net.sf.taverna.wsdl.parser.UnknownOperationException;
+import net.sf.taverna.wsdl.parser.WSDLParser;
+
+import org.apache.axis.message.MessageElement;
+import org.apache.axis.message.SOAPBodyElement;
+import org.apache.axis.utils.XMLUtils;
+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.w3c.dom.NodeList;
+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";
+ private static final String NS_XSI = "http://www.w3.org/2001/XMLSchema-instance";
+
+ 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 SOAPBodyElement build(Map inputMap) throws WSDLException,
+ ParserConfigurationException, SOAPException, IOException,
+ SAXException, UnknownOperationException {
+
+ SOAPBodyElement 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 XMLUtils.StringToElement("", descriptor.getQname().getLocalPart(), "");
+ }
+ else {
+ return XMLUtils.StringToElement("", 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 (NS_XSI.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 MessageElement) {
+ xsiTypeNS = ((MessageElement)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());
+// }
+ }
+ }
+
+ if (parent instanceof SOAPElement) {
+ for (Iterator childIterator = ((SOAPElement) parent).getChildElements(); childIterator.hasNext();) {
+ Node childElement = (Node) childIterator.next();
+ fixTypeAttributes(childElement);
+ }
+ }
+// final NodeList childNodes = parent.getChildNodes();
+// for (int i = 0; i < childNodes.getLength(); i++) {
+// fixTypeAttributes(childNodes.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 {
+ DocumentBuilderFactory builderFactory = DocumentBuilderFactory
+ .newInstance();
+ builderFactory.setNamespaceAware(true);
+ DocumentBuilder docBuilder = builderFactory.newDocumentBuilder();
+
+ Element el;
+ ArrayTypeDescriptor arrayDescriptor = (ArrayTypeDescriptor) descriptor;
+ TypeDescriptor elementType = arrayDescriptor.getElementType();
+ int size = 0;
+
+ el = XMLUtils.StringToElement("", typeName, "");
+
+ 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);
+ }
+
+ }
+
+ return el;
+ }
+
+ @Override
+ protected SOAPBodyElement addElementToBody(String operationNamespace, SOAPBodyElement body, Element el) throws SOAPException {
+ if (getStyle()==Style.DOCUMENT) {
+ body = new SOAPBodyElement(el);
+ body.setNamespaceURI(operationNamespace);
+ }
+ else {
+ body.addChildElement(new SOAPBodyElement(el));
+ }
+ return body;
+ }
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/ObjectConverter.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/ObjectConverter.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/ObjectConverter.java
new file mode 100644
index 0000000..f973157
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/ObjectConverter.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (C) 2007 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.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/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseEncodedMultiRefParser.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseEncodedMultiRefParser.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseEncodedMultiRefParser.java
new file mode 100644
index 0000000..2266e0d
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseEncodedMultiRefParser.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2003 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate. Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * 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
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename $RCSfile: SOAPResponseEncodedMultiRefParser.java,v $
+ * Revision $Revision: 1.2 $
+ * Release status $State: Exp $
+ * Last modified on $Date: 2008/08/08 10:28:09 $
+ * by $Author: stain $
+ * Created on 05-May-2006
+ *****************************************************************/
+package net.sf.taverna.wsdl.soap;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+
+import org.apache.axis.message.SOAPBodyElement;
+import org.apache.axis.utils.XMLUtils;
+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 response) throws Exception, CyclicReferenceException {
+ Map result = new HashMap();
+ generateRefMap(response);
+ expandRefMap();
+ Element mainBody = ((SOAPBodyElement) response.get(0)).getAsDOM();
+
+ 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 = XMLUtils.ElementToString((Element) 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();) {
+ SOAPBodyElement bodyElement = (SOAPBodyElement) iterator.next();
+ String id = bodyElement.getAttribute("id");
+ if (id != null) {
+ result.put("#" + id, bodyElement.getAsDOM());
+ }
+ }
+
+ 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/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseEncodedParser.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseEncodedParser.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseEncodedParser.java
new file mode 100644
index 0000000..ab45289
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseEncodedParser.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2003 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate. Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * 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
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename $RCSfile: SOAPResponseEncodedParser.java,v $
+ * Revision $Revision: 1.2 $
+ * Release status $State: Exp $
+ * Last modified on $Date: 2008/08/08 10:28:09 $
+ * by $Author: stain $
+ * Created on 08-May-2006
+ *****************************************************************/
+package net.sf.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.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+
+import org.apache.axis.message.SOAPBodyElement;
+import org.apache.axis.utils.XMLUtils;
+import org.w3c.dom.Document;
+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 implements SOAPResponseParser {
+
+ 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
+ */
+ public Map parse(List response) throws Exception {
+
+ Map result = new HashMap();
+ Element mainBody = ((SOAPBodyElement) response.get(0)).getAsDOM();
+
+ for (TypeDescriptor descriptor : outputDescriptors) {
+ String outputName = descriptor.getName();
+
+ Node outputNode = getOutputNode(mainBody, outputName);
+ if (outputNode != null) {
+ String xml;
+
+ if (stripAttributes) {
+ stripAttributes(outputNode);
+ outputNode = removeNamespace(outputName,
+ (Element) outputNode);
+ }
+
+ xml = XMLUtils.ElementToString((Element) 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 {
+ 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/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseLiteralParser.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseLiteralParser.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseLiteralParser.java
new file mode 100644
index 0000000..c27af9d
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseLiteralParser.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2003 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate. Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * 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
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename $RCSfile: SOAPResponseLiteralParser.java,v $
+ * Revision $Revision: 1.1 $
+ * Release status $State: Exp $
+ * Last modified on $Date: 2007/11/28 16:05:45 $
+ * by $Author: sowen70 $
+ * Created on 05-May-2006
+ *****************************************************************/
+package net.sf.taverna.wsdl.soap;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+
+import org.apache.axis.message.SOAPBodyElement;
+import org.apache.axis.utils.XMLUtils;
+import org.w3c.dom.Element;
+
+/**
+ * Responsible for parsing the SOAP response from calling a Literal based
+ * service.
+ *
+ * @author sowen
+ *
+ */
+@SuppressWarnings("unchecked")
+public class SOAPResponseLiteralParser implements SOAPResponseParser {
+
+ 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
+ */
+ public Map parse(List response) throws Exception {
+ Map result = new HashMap();
+
+ if (response.size()>0) {
+ SOAPBodyElement rpcElement = (SOAPBodyElement) response.get(0);
+
+ Element dom = rpcElement.getAsDOM();
+
+ String outputName = getOutputName();
+ String xml = XMLUtils.ElementToString(dom);
+
+ 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/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseParser.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseParser.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseParser.java
new file mode 100644
index 0000000..a2da0f8
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseParser.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2003 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate. Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * 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
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename $RCSfile: SOAPResponseParser.java,v $
+ * Revision $Revision: 1.1 $
+ * Release status $State: Exp $
+ * Last modified on $Date: 2007/11/28 16:05:45 $
+ * by $Author: sowen70 $
+ * Created on 05-May-2006
+ *****************************************************************/
+package net.sf.taverna.wsdl.soap;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 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 response) throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseParserFactory.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseParserFactory.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseParserFactory.java
new file mode 100644
index 0000000..15df731
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponseParserFactory.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2003 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate. Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * 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
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename $RCSfile: SOAPResponseParserFactory.java,v $
+ * Revision $Revision: 1.1 $
+ * Release status $State: Exp $
+ * Last modified on $Date: 2007/11/28 16:05:45 $
+ * by $Author: sowen70 $
+ * Created on 05-May-2006
+ *****************************************************************/
+package net.sf.taverna.wsdl.soap;
+
+import java.util.List;
+
+import net.sf.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/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponsePrimitiveLiteralParser.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponsePrimitiveLiteralParser.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponsePrimitiveLiteralParser.java
new file mode 100644
index 0000000..e26f146
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponsePrimitiveLiteralParser.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (C) 2007 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.soap;
+
+import java.io.ByteArrayInputStream;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import net.sf.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;
+ }
+
+
+}
+
+
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponsePrimitiveParser.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponsePrimitiveParser.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponsePrimitiveParser.java
new file mode 100644
index 0000000..4bb0af4
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/SOAPResponsePrimitiveParser.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2003 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate. Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * 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
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename $RCSfile: SOAPResponsePrimitiveParser.java,v $
+ * Revision $Revision: 1.1 $
+ * Release status $State: Exp $
+ * Last modified on $Date: 2007/11/28 16:05:45 $
+ * by $Author: sowen70 $
+ * Created on 05-May-2006
+ *****************************************************************/
+package net.sf.taverna.wsdl.soap;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+
+import org.apache.axis.message.RPCElement;
+import org.apache.axis.message.RPCParam;
+
+/**
+ * SOAPResponseParser responsible for parsing soap responses that map to outputs
+ * that can be directly represented with Primitive types (i.e. int, String,
+ * String[]).
+ *
+ * @author sowen
+ *
+ */
+@SuppressWarnings("unchecked")
+public class SOAPResponsePrimitiveParser implements SOAPResponseParser {
+
+ private List<String> outputNames;
+
+ public SOAPResponsePrimitiveParser(List<TypeDescriptor> outputDescriptors) {
+ outputNames=new ArrayList<String>();
+ for (TypeDescriptor desc : outputDescriptors) {
+ outputNames.add(desc.getName());
+ }
+ }
+
+ /**
+ * Parses each SOAPBodyElement for the primitive type, and places it in the
+ * output Map
+ */
+ public Map parse(List response) throws Exception {
+ Map result = new HashMap();
+ int c = 0;
+
+
+ RPCElement responseElement = (RPCElement) response.get(0);
+ List params = responseElement.getParams();
+
+ for (Iterator paramIterator = params.iterator(); paramIterator
+ .hasNext();) {
+ RPCParam param = (RPCParam) paramIterator.next();
+ Object value = param.getObjectValue();
+ // use the param name if it matches the outputname list,
+ // otherwise use the defined output name.
+ // Outputs should come back in the order of the outputNames
+ // as this is specified in the WSDL (only an issue for multiple
+ // outputs which is very rare, and is going to be documented as
+ // unrecommended for Taverna).
+ if (outputNames.contains(param.getName())) {
+ result.put(param.getName(), ObjectConverter.convertObject(value));
+ } else {
+ result.put(outputNames.get(c), value);
+ }
+ c++;
+ }
+
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/WSDLSOAPInvoker.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/WSDLSOAPInvoker.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/WSDLSOAPInvoker.java
new file mode 100644
index 0000000..36c50da
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/WSDLSOAPInvoker.java
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2003 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate. Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * 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
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename $RCSfile: WSDLSOAPInvoker.java,v $
+ * Revision $Revision: 1.7 $
+ * Release status $State: Exp $
+ * Last modified on $Date: 2008/08/28 19:39:28 $
+ * by $Author: stain $
+ * Created on 07-Apr-2006
+ *****************************************************************/
+package net.sf.taverna.wsdl.soap;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.activation.DataHandler;
+import javax.wsdl.WSDLException;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.rpc.ServiceException;
+import javax.xml.soap.SOAPException;
+
+import net.sf.taverna.wsdl.parser.UnknownOperationException;
+import net.sf.taverna.wsdl.parser.WSDLParser;
+
+import org.apache.axis.AxisFault;
+import org.apache.axis.EngineConfiguration;
+import org.apache.axis.attachments.AttachmentPart;
+import org.apache.axis.client.Call;
+import org.apache.axis.message.SOAPBodyElement;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.axis.message.SOAPHeaderElement;
+import org.apache.axis.transport.http.HTTPTransport;
+import org.apache.log4j.Logger;
+import org.xml.sax.SAXException;
+
+/**
+ * Invoke SOAP based webservices
+ *
+ * @author Stuart Owen
+ *
+ */
+@SuppressWarnings("unchecked")
+public class WSDLSOAPInvoker {
+
+ private static final String ATTACHMENT_LIST = "attachmentList";
+ private BodyBuilderFactory bodyBuilderFactory = BodyBuilderFactory.instance();
+ private WSDLParser parser;
+ private String operationName;
+ private List<String> outputNames;
+
+ private static Logger logger = Logger.getLogger(WSDLSOAPInvoker.class);
+
+ public WSDLSOAPInvoker(WSDLParser parser, String operationName,
+ List<String> outputNames) {
+ this.parser = parser;
+ this.operationName = operationName;
+ this.outputNames = outputNames;
+ }
+
+ protected String getOperationName() {
+ return operationName;
+ }
+
+ protected WSDLParser getParser() {
+ return parser;
+ }
+
+ protected List<String> getOutputNames() {
+ return outputNames;
+ }
+
+
+ /**
+ * Invokes the webservice with the supplied input Map, and returns a Map
+ * containing the outputs, mapped against their output names.
+ *
+ * @param inputMap
+ * @return
+ * @throws Exception
+ */
+ public Map<String, Object> invoke(Map inputMap) throws Exception {
+ return invoke(inputMap, (EngineConfiguration)null);
+ }
+
+ /**
+ * Invokes the webservice with the supplied input Map and axis engine configuration,
+ * and returns a Map containing the outputs, mapped against their output names.
+ */
+ public Map<String, Object> invoke(Map inputMap, EngineConfiguration config)
+ throws Exception {
+
+ Call call = getCall(config);
+ return invoke(inputMap, call);
+ }
+
+ /**
+ * Invokes the webservice with the supplied input Map and preconfigured axis call,
+ * and returns a Map containing the outputs, mapped against their output names.
+ */
+ public Map<String, Object> invoke(Map inputMap, Call call)
+ throws Exception {
+
+ call.setTimeout(getTimeout());
+
+ SOAPEnvelope requestEnv = makeRequestEnvelope(inputMap);
+// logger.info("Invoking service with SOAP envelope:\n"+requestEnv);
+
+ SOAPEnvelope responseEnv = invokeCall(call, requestEnv);
+
+// logger.info("Received SOAP response:\n"+responseEnv);
+
+ Map<String, Object> result;
+ if (responseEnv == null) {
+ if (outputNames.size() == 1
+ && outputNames.get(0).equals(ATTACHMENT_LIST)) {
+ // Could be axis 2 service with no output (TAV-617)
+ result = new HashMap<String, Object>();
+ } else {
+ throw new IllegalStateException(
+ "Missing expected outputs from service");
+ }
+ } else {
+ List response = responseEnv.getBodyElements();
+// logger.info("SOAP response was:" + response);
+ SOAPResponseParser parser = SOAPResponseParserFactory
+ .instance()
+ .create(
+ response,
+ getUse(),
+ getStyle(),
+ this.parser
+ .getOperationOutputParameters(operationName));
+ result = parser.parse(response);
+ }
+
+ result.put(ATTACHMENT_LIST, extractAttachments(call));
+
+ return result;
+ }
+
+ protected SOAPEnvelope makeRequestEnvelope(Map inputMap)
+ throws UnknownOperationException, IOException, WSDLException,
+ ParserConfigurationException, SOAPException, SAXException {
+
+ SOAPEnvelope requestEnv = new SOAPEnvelope();
+ for (SOAPHeaderElement headerElement : makeSoapHeaders()) {
+ requestEnv.addHeader(headerElement);
+ }
+ requestEnv.addBodyElement(makeSoapBody(inputMap));
+ return requestEnv;
+ }
+
+ protected List<SOAPHeaderElement> makeSoapHeaders() {
+ return Collections.emptyList();
+ }
+
+ protected SOAPBodyElement makeSoapBody(Map inputMap)
+ throws UnknownOperationException, IOException, WSDLException,
+ ParserConfigurationException, SOAPException, SAXException {
+ BodyBuilder builder = bodyBuilderFactory.create(parser,
+ operationName,
+ parser.getOperationInputParameters(operationName));
+ return builder.build(inputMap);
+ }
+
+ protected SOAPEnvelope invokeCall(Call call, SOAPEnvelope requestEnv) throws AxisFault {
+ return call.invoke(requestEnv);
+ }
+
+ /**
+ * Reads the property taverna.wsdl.timeout, default to 5 minutes if missing.
+ *
+ * @return
+ */
+ protected Integer getTimeout() {
+ int result = 300000;
+ String minutesStr = System.getProperty("taverna.wsdl.timeout");
+
+ if (minutesStr == null) {
+ // using default of 5 minutes
+ return result;
+ }
+ try {
+ int minutes = Integer.parseInt(minutesStr.trim());
+ result = minutes * 1000 * 60;
+ } catch (NumberFormatException e) {
+ logger.error("Non-integer timeout", e);
+ return result;
+ }
+ return result;
+ }
+
+ protected String getStyle() {
+ return parser.getStyle();
+ }
+
+ protected String getUse() throws UnknownOperationException {
+ return parser.getUse(operationName);
+ }
+
+ /**
+ * Returns an axis based Call, initialised for the operation that needs to
+ * be invoked
+ *
+ * @return
+ * @throws ServiceException
+ * @throws UnknownOperationException
+ * @throws MalformedURLException
+ * @throws WSDLException
+ * @throws WSIFException
+ */
+ protected Call getCall(EngineConfiguration config) throws ServiceException, UnknownOperationException, MalformedURLException {
+
+ org.apache.axis.client.Service service;
+ if (config==null) {
+ service = new org.apache.axis.client.Service();
+ }
+ else {
+ service = new org.apache.axis.client.Service(config);
+ }
+
+ Call call = new Call(service);
+
+ call.setTransport(new HTTPTransport());
+ call.setTargetEndpointAddress(parser.getOperationEndpointLocations(operationName).get(0));
+ //result.setPortName(parser.getPortType(operationName).getQName());
+ //result.setOperation(operationName);
+
+ String use = parser.getUse(operationName);
+ call.setUseSOAPAction(true);
+ call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR,
+ Boolean.FALSE);
+ call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS,
+ Boolean.FALSE);
+ call
+ .setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
+
+ if (parser.getSOAPActionURI(operationName)!=null) {
+ call.setSOAPActionURI(parser.getSOAPActionURI(operationName));
+ }
+
+ if (use.equalsIgnoreCase("literal")) {
+ call.setEncodingStyle(null);
+ }
+ return call;
+ }
+
+
+ /**
+ * Exctracts any attachments that result from invoking the service, and
+ * returns them as a List wrapped within a DataThing
+ *
+ * @param axisCall
+ * @return
+ * @throws SOAPException
+ * @throws IOException
+ */
+ protected List extractAttachments(Call axisCall)
+ throws SOAPException, IOException {
+ List attachmentList = new ArrayList();
+ if (axisCall.getResponseMessage() != null
+ && axisCall.getResponseMessage().getAttachments() != null) {
+ for (Iterator i = axisCall.getResponseMessage().getAttachments(); i
+ .hasNext();) {
+ AttachmentPart ap = (AttachmentPart) i.next();
+ DataHandler dh = ap.getDataHandler();
+ BufferedInputStream bis = new BufferedInputStream(dh
+ .getInputStream());
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ int c;
+ while ((c = bis.read()) != -1) {
+ bos.write(c);
+ }
+ bis.close();
+ bos.close();
+ String mimeType = dh.getContentType();
+ if (mimeType.matches(".*image.*")
+ || mimeType.matches(".*octet.*")
+ || mimeType.matches(".*audio.*")
+ || mimeType.matches(".*application/zip.*")) {
+ attachmentList.add(bos.toByteArray());
+ } else {
+ attachmentList.add(new String(bos.toByteArray()));
+ }
+ }
+ }
+
+ return attachmentList;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/c8b66752/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/package.html
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/package.html b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/package.html
new file mode 100644
index 0000000..5fd36e5
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/soap/package.html
@@ -0,0 +1,5 @@
+<body>
+Contains classes required to invoke an endpoint for a SOAP based web-service described by a WSDL.<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