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/23 11:16:54 UTC

[13/28] incubator-taverna-common-activities git commit: Revert "temporarily empty repository"

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/390c286b/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/390c286b/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/390c286b/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/390c286b/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/390c286b/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/390c286b/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/390c286b/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/390c286b/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/390c286b/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/390c286b/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/390c286b/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

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/390c286b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/xmlsplitter/XMLInputSplitter.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/xmlsplitter/XMLInputSplitter.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/xmlsplitter/XMLInputSplitter.java
new file mode 100644
index 0000000..031de03
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/xmlsplitter/XMLInputSplitter.java
@@ -0,0 +1,290 @@
+/*******************************************************************************
+ * 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.xmlsplitter;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+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 org.apache.axis.encoding.Base64;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.Namespace;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.XMLOutputter;
+
+public class XMLInputSplitter {
+
+	private TypeDescriptor typeDescriptor;
+	private String[] outputNames;
+	private String[] inputNames;
+	private String[] inputTypes;
+
+	public XMLInputSplitter(TypeDescriptor typeDescriptor, String inputNames[],
+			String inputTypes[], String[] outputNames) {
+		this.typeDescriptor = typeDescriptor;
+		this.outputNames = outputNames;
+		this.inputTypes = inputTypes;
+		this.inputNames = inputNames;
+	}
+
+	public Map<String, String> execute(Map<String, Object> inputMap)
+			throws JDOMException, IOException {
+		Map<String, String> result = new HashMap<String, String>();
+		Element outputElement = (this.typeDescriptor.getName().length() > 0 ? new Element(
+				this.typeDescriptor.getName())
+				: new Element(this.typeDescriptor.getType()));
+
+		if (typeDescriptor instanceof ComplexTypeDescriptor) {
+			executeForComplexType(inputMap, result, outputElement);
+
+		} else {
+			for (String key : inputMap.keySet()) {
+				Object dataObject = inputMap.get(key);
+
+				if (dataObject instanceof List) {
+					Element dataElement = buildElementFromObject(key, "");
+					for (Object dataItem : ((List<?>) dataObject)) {
+						Element itemElement = buildElementFromObject(key,
+								dataItem);
+						dataElement.addContent(itemElement);
+					}
+
+					XMLOutputter outputter = new XMLOutputter();
+					String xmlText = outputter.outputString(dataElement);
+
+					result.put(outputNames[0], xmlText);
+				} else {
+					Element dataElement = buildElementFromObject(key,
+							dataObject);
+					outputElement.addContent(dataElement);
+					XMLOutputter outputter = new XMLOutputter();
+					String xmlText = outputter.outputString(outputElement);
+					result.put(outputNames[0], xmlText);
+				}
+
+			}
+		}
+
+		return result;
+
+	}
+
+	private void executeForComplexType(Map<String, Object> inputMap,
+			Map<String, String> result, Element outputElement)
+			throws JDOMException, IOException {
+		ComplexTypeDescriptor complexDescriptor = (ComplexTypeDescriptor) typeDescriptor;
+		for (TypeDescriptor elementType : complexDescriptor.getElements()) {
+			String key = elementType.getName();
+			Object dataObject = inputMap.get(key);			
+			if (dataObject==null) {
+				if (elementType.isOptional()) {
+					continue;
+				} if (elementType.isNillable()) {
+					dataObject = "xsi:nil";
+				} else {
+					dataObject="";
+				}
+			}
+
+			if (dataObject instanceof List) {
+				Element arrayElement = buildElementFromObject(key, "");
+
+				String itemkey = "item";
+				boolean wrapped = false;
+				if (elementType instanceof ArrayTypeDescriptor) {
+					wrapped = ((ArrayTypeDescriptor) elementType).isWrapped();
+					TypeDescriptor arrayElementType = ((ArrayTypeDescriptor) elementType)
+							.getElementType();
+					if (!wrapped) {
+						itemkey = elementType.getName();
+					} else {
+						if (arrayElementType.getName() != null
+								&& arrayElementType.getName().length() > 0) {
+							itemkey = arrayElementType.getName();
+						} else {
+							itemkey = arrayElementType.getType();
+						}
+					}
+
+				}
+
+				for (Object itemObject : ((List<?>)dataObject)) {
+
+					Element dataElement = buildElementFromObject(itemkey,
+							itemObject);
+					dataElement.setNamespace(Namespace.getNamespace(elementType
+							.getNamespaceURI()));
+					if (!wrapped) {
+						dataElement.setName(itemkey);
+						outputElement.addContent(dataElement);
+					} else {
+						arrayElement.addContent(dataElement);
+					}
+				}
+				if (wrapped)
+					outputElement.addContent(arrayElement);
+			} else {
+				Element dataElement = buildElementFromObject(key, dataObject);
+				outputElement.addContent(dataElement);
+			}
+		}
+		for (TypeDescriptor attribute : complexDescriptor.getAttributes()) {
+			String key = attribute.getName();
+			Object dataObject = inputMap.get("1" + key);
+			if (dataObject == null) {
+				dataObject = inputMap.get(key);
+			}
+			if (dataObject != null) {
+				outputElement.setAttribute(key, dataObject.toString(), Namespace
+						.getNamespace(attribute.getNamespaceURI()));
+			}
+		}
+		
+		outputElement.setNamespace(Namespace.getNamespace(typeDescriptor
+				.getNamespaceURI()));
+		XMLOutputter outputter = new XMLOutputter();
+		String xmlText = outputter.outputString(outputElement);
+		result.put(outputNames[0], xmlText);
+	}
+
+	private Element buildElementFromObject(String key, Object dataObject)
+			throws JDOMException, IOException {
+
+		Element dataElement = null;
+
+		if (isXMLInput(key)) {
+			dataElement = createDataElementForXMLInput(dataObject, key);
+		} else {
+			dataElement = new Element(key);
+			setDataElementNamespace(key, dataElement);
+			Namespace xsiNs = org.jdom.Namespace
+				.getNamespace("xsi",
+						"http://www.w3.org/2001/XMLSchema-instance");
+			if (dataObject.toString().equals("xsi:nil")) {
+				dataElement.setAttribute("nil", "true", xsiNs); // changes nil value
+			} else {
+				if (dataObject instanceof byte[]) {
+				
+					dataElement
+							.setAttribute(
+									"type",
+									"xsd:base64Binary",
+									xsiNs);
+					dataObject = Base64
+							.encode(((byte[]) dataObject));
+				}
+				dataElement.setText(dataObject.toString());
+			}
+
+		}
+		return dataElement;
+	}
+
+	private Element createDataElementForXMLInput(Object dataObject, String key)
+			throws JDOMException, IOException {
+		Element dataElement = null;
+		String xml = dataObject.toString();
+		if (xml.length() > 0) {
+			Document doc = new SAXBuilder().build(new StringReader(xml));
+			dataElement = doc.getRootElement();
+			dataElement.detach();
+		} else {
+			dataElement = new Element(key);
+		}
+
+		setDataElementNamespace(key, dataElement);
+		return dataElement;
+	}
+
+	// set the namespace if it can be determined from the element TypeDescriptor
+	// by the key
+	private void setDataElementNamespace(String key, Element dataElement) {
+		if (typeDescriptor instanceof ComplexTypeDescriptor) {
+			TypeDescriptor elementTypeDescriptor = ((ComplexTypeDescriptor) typeDescriptor)
+					.elementForName(key);
+			if (elementTypeDescriptor != null) {
+				String nsURI = null;
+				if (elementTypeDescriptor instanceof BaseTypeDescriptor) {
+					nsURI = elementTypeDescriptor.getNamespaceURI();
+					// this is some protective code against old workflows that
+					// had the base element namespace incorrectly
+					// declared (it was using the type NS, rather than the
+					// element NS.
+					if (nsURI.contains("XMLSchema")
+							&& nsURI.contains("http://www.w3.org")) {
+						nsURI = typeDescriptor.getNamespaceURI();
+					}
+				} else {
+					nsURI = elementTypeDescriptor.getNamespaceURI();
+				}
+				if (nsURI != null && nsURI.length() > 0) {
+					updateElementNamespace(dataElement, nsURI);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Updates the element namespace, and also iterates all descendant elements.
+	 * If these elements have no default namespace, or is blank then it is also
+	 * set to namespaceURI (JDOM by default will not set the child elements to
+	 * the same namespace as the element modified but will override them with
+	 * blank namespaces).
+	 * 
+	 * @param dataElement
+	 * @param namespaceURI
+	 */
+	private void updateElementNamespace(Element dataElement, String namespaceURI) {
+		dataElement.setNamespace(Namespace.getNamespace(namespaceURI));
+		Iterator<?> iterator = dataElement.getDescendants();
+		while (iterator.hasNext()) {
+			Object descendantObject = iterator.next();
+			if (descendantObject instanceof Element) {
+				Element childElement = (Element) descendantObject;
+				if (childElement.getNamespaceURI() == null) {
+					childElement.setNamespace(Namespace
+							.getNamespace(namespaceURI));
+				}
+			}
+		}
+	}
+
+	private boolean isXMLInput(String key) {
+		boolean result = false;
+		for (int i = 0; i < inputNames.length; i++) {
+			if (inputNames[i].equals(key)) {
+				result = inputTypes[i].indexOf("'text/xml'") != -1;
+			}
+		}
+		return result;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/390c286b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/xmlsplitter/XMLOutputSplitter.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/xmlsplitter/XMLOutputSplitter.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/xmlsplitter/XMLOutputSplitter.java
new file mode 100644
index 0000000..4ad5061
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/xmlsplitter/XMLOutputSplitter.java
@@ -0,0 +1,212 @@
+/*
+ * 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: XMLOutputSplitter.java,v $
+ * Revision           $Revision: 1.2 $
+ * Release status     $State: Exp $
+ * Last modified on   $Date: 2008/08/08 10:28:07 $
+ *               by   $Author: stain $
+ * Created on 16-May-2006
+ *****************************************************************/
+package net.sf.taverna.wsdl.xmlsplitter;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+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 org.apache.axis.encoding.Base64;
+import org.jdom.Attribute;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.XMLOutputter;
+
+public class XMLOutputSplitter {
+
+	private TypeDescriptor typeDescriptor;
+	private String[] outputNames;
+	private String[] inputNames;
+	private String[] outputTypes;
+
+	public XMLOutputSplitter(TypeDescriptor typeDescriptor,
+			String[] outputNames, String[] outputTypes,String[] inputNames) {
+		this.typeDescriptor = typeDescriptor;
+		this.outputNames = outputNames;
+		this.inputNames = inputNames;
+		this.outputTypes = outputTypes;
+	}
+
+	@SuppressWarnings("unchecked")
+	public Map<String, Object> execute(Map<String, String> inputMap)
+			throws XMLSplitterExecutionException {
+
+		Map<String, Object> result = new HashMap<String, Object>();
+		List<String> outputNameList = Arrays.asList(outputNames);
+
+		String xml = inputMap.get(inputNames[0]);
+		try {
+			Document doc = new SAXBuilder().build(new StringReader(xml));
+			List<Element> children = doc.getRootElement().getChildren();
+			if (typeDescriptor instanceof ArrayTypeDescriptor) {
+				if (outputNames.length > 1)
+					throw new XMLSplitterExecutionException(
+							"Unexpected, multiple output names for ArrayType");
+				executeForArrayType(result, children);
+			} else {
+				executeForComplexType(result, outputNameList, children, doc.getRootElement().getAttributes());
+			}
+
+			// populate missing outputs with empty strings for basic types,
+			// empty elements for complex/array types.
+			for (int i = 0; i < outputNames.length; i++) {
+				if (result.get(outputNames[i]) == null) {
+					if (outputTypes[i].equals("'text/xml'")) {
+						result
+								.put(outputNames[i], "<" + outputNames[i]
+										+ " />");
+					} else if (outputTypes[i].startsWith("l('")) {
+						result.put(outputNames[i], new ArrayList<Object>());
+					} else {
+						result.put(outputNames[i], "");
+					}
+
+				}
+			}
+		} catch (JDOMException e) {
+			throw new XMLSplitterExecutionException("Unable to parse XML: " + xml, e);
+		} catch (IOException e) {
+			throw new XMLSplitterExecutionException("IOException parsing XML: " + xml,
+					e);
+		}
+
+		return result;
+	}
+
+	private void executeForArrayType(Map<String, Object> result,
+			List<Element> children) {
+		ArrayTypeDescriptor arrayDescriptor = (ArrayTypeDescriptor) typeDescriptor;
+		List<String> values = new ArrayList<String>();
+		XMLOutputter outputter = new XMLOutputter();
+
+		boolean isInnerBaseType = arrayDescriptor.getElementType() instanceof BaseTypeDescriptor;
+		if (isInnerBaseType) {
+			values = extractBaseTypeArrayFromChildren(children);
+		} else {
+			for (Element child : children) {
+				values.add(outputter.outputString(child));
+			}
+		}
+		result.put(outputNames[0], values);
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	private void executeForComplexType(Map<String, Object> result,
+			List<String> outputNameList, List<Element> children, List<Attribute> list)
+			throws IOException {               
+
+		XMLOutputter outputter = new XMLOutputter();
+		for (Element child : children) {
+			
+			if (outputNameList.contains(child.getName())) {
+				int i = outputNameList.indexOf(child.getName());
+				TypeDescriptor descriptorForChild = ((ComplexTypeDescriptor) typeDescriptor)
+						.elementForName(outputNames[i]);
+				if (outputTypes[i].startsWith("l(")
+						&& descriptorForChild instanceof ArrayTypeDescriptor
+						&& !((ArrayTypeDescriptor) descriptorForChild)
+								.isWrapped()) {
+					boolean isXMLContent = outputTypes[i].contains("text/xml");
+					result.put(child.getName(), extractDataListFromChildList(
+							children, isXMLContent));
+                    break;
+				} else {
+					if (outputTypes[i].equals("'text/xml'")
+							|| outputTypes[i].equals("l('text/xml')")) {
+						String xmlText = outputter.outputString(child);
+						result.put(child.getName(), xmlText);
+					} else if (outputTypes[i]
+							.equals("'application/octet-stream'")) { // base64Binary
+						
+						byte[] data = Base64.decode(child
+								.getText());
+						result.put(child.getName(), data);
+					} else if (outputTypes[i].equals("l('text/plain')")) { // an
+																			// inner
+																			// element
+																			// containing
+																			// a
+																			// list
+						result.put(child.getName(),
+								extractBaseTypeArrayFromChildren(child
+										.getChildren()));
+					} else {
+						result.put(child.getName(), child.getText());
+					}
+				}
+			}
+		}
+		for (Attribute attribute : list) {
+			if (outputNameList.contains("1" + attribute.getName())) {
+				result.put("1" + attribute.getName(), attribute.getValue());
+			} else if (outputNameList.contains(attribute.getName())) {
+				result.put(attribute.getName(), attribute.getValue());
+			}
+		}
+	}
+
+	private List<String> extractDataListFromChildList(List<Element> children,
+			boolean isXMLContent) {
+		List<String> result = new ArrayList<String>();
+		XMLOutputter outputter = new XMLOutputter();
+		for (Element child : children) {
+			if (!isXMLContent) {
+				result.add(child.getTextTrim());
+			} else {
+				result.add(outputter.outputString(child));
+			}
+		}
+		return result;
+	}
+
+	private List<String> extractBaseTypeArrayFromChildren(List<Element> children) {
+		List<String> result = new ArrayList<String>();
+		for (Element child : children) {
+			result.add(child.getTextTrim());
+		}
+		return result;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/390c286b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/xmlsplitter/XMLSplitterExecutionException.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/xmlsplitter/XMLSplitterExecutionException.java b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/xmlsplitter/XMLSplitterExecutionException.java
new file mode 100644
index 0000000..6ec1720
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/net/sf/taverna/wsdl/xmlsplitter/XMLSplitterExecutionException.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * 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.xmlsplitter;
+
+public class XMLSplitterExecutionException extends Exception {
+
+	private static final long serialVersionUID = 5623707293500493612L;
+
+	public XMLSplitterExecutionException(String msg, Throwable cause) {
+		super(msg, cause);
+	}
+
+	public XMLSplitterExecutionException(String msg) {
+		super(msg);
+	}
+}