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:52 UTC

[32/70] [abbrv] incubator-taverna-common-activities git commit: taverna-wsdl-activity/

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLInputSplitterActivity.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLInputSplitterActivity.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLInputSplitterActivity.java
new file mode 100644
index 0000000..3feb6f8
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLInputSplitterActivity.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * 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.t2.activities.wsdl.xmlsplitter;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.sf.taverna.t2.activities.wsdl.InputPortTypeDescriptorActivity;
+import net.sf.taverna.t2.reference.ReferenceService;
+import net.sf.taverna.t2.reference.ReferenceServiceException;
+import net.sf.taverna.t2.reference.T2Reference;
+import net.sf.taverna.t2.workflowmodel.OutputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.AbstractAsynchronousActivity;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityConfigurationException;
+import net.sf.taverna.t2.workflowmodel.processor.activity.AsynchronousActivityCallback;
+import net.sf.taverna.wsdl.parser.ArrayTypeDescriptor;
+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.xmlsplitter.XMLInputSplitter;
+import net.sf.taverna.wsdl.xmlsplitter.XMLSplitterSerialisationHelper;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * An activity that replicates the behaviour of the Taverna 1 XMLInputSplitters.
+ *
+ * @author Stuart Owen
+ *
+ */
+public class XMLInputSplitterActivity extends AbstractAsynchronousActivity<JsonNode> implements InputPortTypeDescriptorActivity {
+
+	public static final String URI = "http://ns.taverna.org.uk/2010/activity/xml-splitter/in";
+
+	JsonNode configBean;
+	TypeDescriptor typeDescriptor;
+
+	@Override
+	public void configure(JsonNode configBean) throws ActivityConfigurationException {
+		this.configBean = configBean;
+
+		try {
+			String wrappedType = configBean.get("wrappedType").textValue();
+			Element element = new SAXBuilder().build(new StringReader(wrappedType)).getRootElement();
+			typeDescriptor = XMLSplitterSerialisationHelper.extensionXMLToTypeDescriptor(element);
+		} catch (JDOMException | IOException e) {
+			throw new ActivityConfigurationException(e);
+		}
+	}
+
+	@Override
+	public void executeAsynch(final Map<String, T2Reference> data,
+			final AsynchronousActivityCallback callback) {
+		callback.requestRun(new Runnable() {
+
+			public void run() {
+				try {
+					ReferenceService referenceService = callback.getContext().getReferenceService();
+					XMLInputSplitter splitter = createSplitter();
+					Map<String,Object> inputMap = buildInputMap(data,referenceService);
+					Map<String,String> outputMap = splitter.execute(inputMap);
+					callback.receiveResult(createOutputData(outputMap,referenceService), new int[0]);
+				}
+				catch(Exception e) {
+					callback.fail("Error in XMLInputSplitterActivity",e);
+				}
+			}
+
+			private Map<String, T2Reference> createOutputData(
+					Map<String, String> outputMap,ReferenceService referenceService) throws ReferenceServiceException {
+				Map<String,T2Reference> result = new HashMap<String, T2Reference>();
+				for (String outputName : outputMap.keySet()) {
+					String xmlOut = outputMap.get(outputName);
+					result.put(outputName, referenceService.register(xmlOut, 0, true, callback.getContext()));
+				}
+				return result;
+			}
+
+			private XMLInputSplitter createSplitter() {
+				List<String> inputNames = new ArrayList<String>();
+				List<String> inputTypes = new ArrayList<String>();
+				List<String> outputNames = new ArrayList<String>();
+
+				//FIXME: need to use the definition beans for now to get the mimetype. Need to use the actual InputPort once the mimetype becomes available again.
+				if (configBean.has("inputPorts")) {
+					for (JsonNode inputPort : configBean.get("inputPorts")) {
+						inputNames.add(inputPort.get("name").textValue());
+						inputTypes.add(inputPort.get("mimeType").textValue());
+					}
+				}
+
+				for (OutputPort outputPorts : getOutputPorts()) {
+					outputNames.add(outputPorts.getName());
+				}
+
+				return new XMLInputSplitter(typeDescriptor,inputNames.toArray(new String[]{}),inputTypes.toArray(new String[]{}),outputNames.toArray(new String[]{}));
+			}
+
+			private Map<String,Object> buildInputMap(Map<String, T2Reference> data,ReferenceService referenceService) throws ReferenceServiceException {
+				Map<String,Object> result = new HashMap<String, Object>();
+				for (String inputName : data.keySet()) {
+					T2Reference id = data.get(inputName);
+					result.put(inputName, referenceService.renderIdentifier(id,String.class, callback.getContext()));
+
+				}
+				return result;
+			}
+		});
+
+	}
+
+	@Override
+	public JsonNode getConfiguration() {
+		return configBean;
+	}
+
+	/**
+	 * Returns a TypeDescriptor for the given port name. If the port cannot be found, or is not based upon a complex type, then null is returned.
+	 * @param portName
+	 * @return
+	 */
+	public TypeDescriptor getTypeDescriptorForInputPort(String portName) {
+		TypeDescriptor result = null;
+		if (typeDescriptor instanceof ComplexTypeDescriptor) {
+			for (TypeDescriptor desc : ((ComplexTypeDescriptor)typeDescriptor).getElements()) {
+				if (desc.getName().equals(portName)) {
+					result = desc;
+					break;
+				}
+			}
+		}
+		else if (typeDescriptor instanceof ArrayTypeDescriptor) {
+			TypeDescriptor desc = ((ArrayTypeDescriptor)typeDescriptor).getElementType();
+
+			if (typeDescriptor.getName().equals(portName)) {
+				result = desc;
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 *
+	 */
+	public Map<String, TypeDescriptor> getTypeDescriptorsForInputPorts()
+			throws UnknownOperationException, IOException {
+		Map<String, TypeDescriptor> descriptors = new HashMap<String, TypeDescriptor>();
+		if (typeDescriptor instanceof ComplexTypeDescriptor) {
+			for (TypeDescriptor desc : ((ComplexTypeDescriptor)typeDescriptor).getElements()) {
+				descriptors.put(desc.getName(), desc);
+			}
+		}
+		else if (typeDescriptor instanceof ArrayTypeDescriptor) {
+			TypeDescriptor desc = ((ArrayTypeDescriptor)typeDescriptor).getElementType();
+			descriptors.put(typeDescriptor.getName(), desc);
+		}
+		return descriptors;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLInputSplitterActivityFactory.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLInputSplitterActivityFactory.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLInputSplitterActivityFactory.java
new file mode 100644
index 0000000..2730637
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLInputSplitterActivityFactory.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (C) 2010 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.t2.activities.wsdl.xmlsplitter;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+
+import net.sf.taverna.t2.workflowmodel.Edits;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityConfigurationException;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityFactory;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityInputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityOutputPort;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * An {@link ActivityFactory} for creating <code>XMLInputSplitterActivity</code>.
+ *
+ * @author David Withers
+ */
+public class XMLInputSplitterActivityFactory implements ActivityFactory {
+
+	private Edits edits;
+
+	@Override
+	public XMLInputSplitterActivity createActivity() {
+		return new XMLInputSplitterActivity();
+	}
+
+	@Override
+	public URI getActivityType() {
+		return URI.create(XMLInputSplitterActivity.URI);
+	}
+
+	@Override
+	public JsonNode getActivityConfigurationSchema() {
+		ObjectMapper objectMapper = new ObjectMapper();
+		try {
+ 			return objectMapper.readTree(getClass().getResource("/xml-splitter.schema.json"));
+		} catch (IOException e) {
+			return objectMapper.createObjectNode();
+		}
+	}
+
+	public void setEdits(Edits edits) {
+		this.edits = edits;
+	}
+
+	@Override
+	public Set<ActivityInputPort> getInputPorts(JsonNode configuration)
+			throws ActivityConfigurationException {
+		Set<ActivityInputPort> inputPorts = new HashSet<>();
+		if (configuration.has("inputPorts")) {
+			for (JsonNode inputPort : configuration.get("inputPorts")) {
+				inputPorts.add(edits.createActivityInputPort(inputPort.get("name").textValue(),
+						inputPort.get("depth").intValue(), false, null, String.class));
+			}
+		}
+		return inputPorts;
+	}
+
+	@Override
+	public Set<ActivityOutputPort> getOutputPorts(JsonNode configuration)
+			throws ActivityConfigurationException {
+		Set<ActivityOutputPort> outputPorts = new HashSet<>();
+		if (configuration.has("outputPorts")) {
+			for (JsonNode outputPort : configuration.get("outputPorts")) {
+				outputPorts.add(edits.createActivityOutputPort(outputPort.get("name").textValue(),
+						outputPort.get("depth").intValue(), outputPort.get("granularDepth").intValue()));
+			}
+		}
+		return outputPorts;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLInputSplitterHealthChecker.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLInputSplitterHealthChecker.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLInputSplitterHealthChecker.java
new file mode 100644
index 0000000..57d47d4
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLInputSplitterHealthChecker.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * 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.t2.activities.wsdl.xmlsplitter;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+
+import net.sf.taverna.t2.visit.VisitReport;
+import net.sf.taverna.t2.visit.VisitReport.Status;
+import net.sf.taverna.t2.workflowmodel.health.HealthCheck;
+import net.sf.taverna.t2.workflowmodel.health.HealthChecker;
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+import net.sf.taverna.wsdl.xmlsplitter.XMLSplitterSerialisationHelper;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+
+public class XMLInputSplitterHealthChecker implements HealthChecker<XMLInputSplitterActivity> {
+
+	public boolean canVisit(Object subject) {
+		return subject!=null && subject instanceof XMLInputSplitterActivity;
+	}
+
+	public VisitReport visit(XMLInputSplitterActivity activity, List<Object> ancestors) {
+		Element element;
+		try {
+			String wrappedType = activity.getConfiguration().get("wrappedType").textValue();
+			element = new SAXBuilder().build(new StringReader(wrappedType)).getRootElement();
+		} catch (JDOMException | IOException e) {
+			return new VisitReport(HealthCheck.getInstance(), activity, "Error reading wrapped type", HealthCheck.INVALID_CONFIGURATION, Status.SEVERE);
+		}
+		TypeDescriptor typeDescriptor = XMLSplitterSerialisationHelper.extensionXMLToTypeDescriptor(element);
+		if (typeDescriptor==null) {
+			return new VisitReport(HealthCheck.getInstance(), activity, "Unknown datatype for port", HealthCheck.NULL_DATATYPE, Status.SEVERE);
+		}
+		else {
+			return new VisitReport(HealthCheck.getInstance(), activity, "Recognized datatype", HealthCheck.NO_PROBLEM, Status.OK);
+		}
+	}
+
+	public boolean isTimeConsuming() {
+		return false;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLOutputSplitterActivity.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLOutputSplitterActivity.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLOutputSplitterActivity.java
new file mode 100644
index 0000000..8a63681
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLOutputSplitterActivity.java
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * 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.t2.activities.wsdl.xmlsplitter;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.sf.taverna.t2.activities.wsdl.OutputPortTypeDescriptorActivity;
+import net.sf.taverna.t2.reference.ReferenceService;
+import net.sf.taverna.t2.reference.ReferenceServiceException;
+import net.sf.taverna.t2.reference.T2Reference;
+import net.sf.taverna.t2.workflowmodel.InputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.AbstractAsynchronousActivity;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityConfigurationException;
+import net.sf.taverna.t2.workflowmodel.processor.activity.AsynchronousActivityCallback;
+import net.sf.taverna.wsdl.parser.ArrayTypeDescriptor;
+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.xmlsplitter.XMLOutputSplitter;
+import net.sf.taverna.wsdl.xmlsplitter.XMLSplitterSerialisationHelper;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * An activity that replicates the behaviour of the Taverna 1 XMLOutputSplitter.
+ *
+ * @author Stuart Owen
+ *
+ */
+public class XMLOutputSplitterActivity extends
+		AbstractAsynchronousActivity<JsonNode> implements
+		OutputPortTypeDescriptorActivity {
+
+	public static final String URI = "http://ns.taverna.org.uk/2010/activity/xml-splitter/out";
+
+	JsonNode configBean;
+	TypeDescriptor typeDescriptor;
+
+	@Override
+	public void configure(JsonNode configBean)
+			throws ActivityConfigurationException {
+		this.configBean = configBean;
+
+		try {
+			String wrappedType = configBean.get("wrappedType").textValue();
+			Element element = new SAXBuilder().build(new StringReader(wrappedType)).getRootElement();
+			typeDescriptor = XMLSplitterSerialisationHelper.extensionXMLToTypeDescriptor(element);
+		} catch (JDOMException | IOException e) {
+			throw new ActivityConfigurationException(e);
+		}
+	}
+
+	@Override
+	public void executeAsynch(final Map<String, T2Reference> data,
+			final AsynchronousActivityCallback callback) {
+		callback.requestRun(new Runnable() {
+
+			public void run() {
+				try {
+					ReferenceService referenceService = callback.getContext()
+							.getReferenceService();
+					XMLOutputSplitter splitter = createSplitter();
+					Map<String, String> inputMap = buildInputMap(data,
+							referenceService);
+					Map<String, Object> outputMap = splitter.execute(inputMap);
+					callback.receiveResult(createOutputData(outputMap,
+							referenceService), new int[0]);
+				} catch (Exception e) {
+					callback.fail("Error in XMLInputSplitterActivity", e);
+				}
+			}
+
+			private Map<String, T2Reference> createOutputData(
+					Map<String, Object> outputMap,
+					ReferenceService referenceService)
+					throws ReferenceServiceException {
+				Map<String, T2Reference> result = new HashMap<String, T2Reference>();
+				for (String outputName : outputMap.keySet()) {
+					Object output = outputMap.get(outputName);
+					// TODO check if the output can be anything other than
+					// String or List
+					if (output instanceof List) {
+						result.put(outputName, referenceService.register(
+								output, 1, true, callback.getContext()));
+					} else {
+						result.put(outputName, referenceService.register(
+								output, 0, true, callback.getContext()));
+					}
+				}
+				return result;
+			}
+
+			private XMLOutputSplitter createSplitter() {
+				List<String> inputNames = new ArrayList<String>();
+				List<String> outputTypes = new ArrayList<String>();
+				List<String> outputNames = new ArrayList<String>();
+
+				// FIXME: need to use the definition beans for now to get the
+				// mimetype. Need to use the actual InputPort once the mimetype
+				// becomes available again.
+				if (configBean.has("outputPorts")) {
+					for (JsonNode outputPort : configBean.get("outputPorts")) {
+						outputNames.add(outputPort.get("name").textValue());
+						outputTypes.add(outputPort.get("mimeType").textValue());
+					}
+				}
+
+				for (InputPort outputPorts : getInputPorts()) {
+					inputNames.add(outputPorts.getName());
+				}
+
+				return new XMLOutputSplitter(typeDescriptor, outputNames
+						.toArray(new String[] {}), outputTypes
+						.toArray(new String[] {}), inputNames
+						.toArray(new String[] {}));
+			}
+
+			private Map<String, String> buildInputMap(
+					Map<String, T2Reference> data,
+					ReferenceService referenceService)
+					throws ReferenceServiceException {
+				Map<String, String> result = new HashMap<String, String>();
+				for (String inputName : data.keySet()) {
+					T2Reference id = data.get(inputName);
+					result.put(inputName, (String) referenceService
+							.renderIdentifier(id, String.class, callback
+									.getContext()));
+
+				}
+				return result;
+			}
+		});
+	}
+
+	@Override
+	public JsonNode getConfiguration() {
+		return configBean;
+	}
+
+	public TypeDescriptor getTypeDescriptorForOutputPort(String portName) {
+		TypeDescriptor result = null;
+		if (typeDescriptor instanceof ComplexTypeDescriptor) {
+			for (TypeDescriptor desc : ((ComplexTypeDescriptor) typeDescriptor)
+					.getElements()) {
+				if (desc.getName().equals(portName)) {
+					result = desc;
+					break;
+				}
+			}
+		}
+		else if (typeDescriptor instanceof ArrayTypeDescriptor) {
+			TypeDescriptor desc = ((ArrayTypeDescriptor)typeDescriptor).getElementType();
+
+			if (typeDescriptor.getName().equals(portName)) {
+				result = desc;
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 *
+	 */
+	public Map<String, TypeDescriptor> getTypeDescriptorsForOutputPorts()
+			throws UnknownOperationException, IOException {
+		Map<String, TypeDescriptor> descriptors = new HashMap<String, TypeDescriptor>();
+		if (typeDescriptor instanceof ComplexTypeDescriptor) {
+			for (TypeDescriptor desc : ((ComplexTypeDescriptor) typeDescriptor)
+					.getElements()) {
+				descriptors.put(desc.getName(), desc);
+			}
+		}
+		else if (typeDescriptor instanceof ArrayTypeDescriptor) {
+			TypeDescriptor desc = ((ArrayTypeDescriptor)typeDescriptor).getElementType();
+			descriptors.put(typeDescriptor.getName(), desc);
+		}
+		return descriptors;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLOutputSplitterActivityFactory.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLOutputSplitterActivityFactory.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLOutputSplitterActivityFactory.java
new file mode 100644
index 0000000..a4272e1
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLOutputSplitterActivityFactory.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (C) 2010 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.t2.activities.wsdl.xmlsplitter;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import net.sf.taverna.t2.workflowmodel.Edits;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityConfigurationException;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityFactory;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityInputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityOutputPort;
+
+/**
+ * An {@link ActivityFactory} for creating <code>XMLOutputSplitterActivity</code>.
+ *
+ * @author David Withers
+ */
+public class XMLOutputSplitterActivityFactory implements ActivityFactory {
+
+	private Edits edits;
+
+	@Override
+	public XMLOutputSplitterActivity createActivity() {
+		return new XMLOutputSplitterActivity();
+	}
+
+	@Override
+	public URI getActivityType() {
+		return URI.create(XMLOutputSplitterActivity.URI);
+	}
+
+	@Override
+	public JsonNode getActivityConfigurationSchema() {
+		ObjectMapper objectMapper = new ObjectMapper();
+		try {
+ 			return objectMapper.readTree(getClass().getResource("/xml-splitter.schema.json"));
+		} catch (IOException e) {
+			return objectMapper.createObjectNode();
+		}
+	}
+
+	@Override
+	public Set<ActivityInputPort> getInputPorts(JsonNode configuration)
+			throws ActivityConfigurationException {
+		Set<ActivityInputPort> inputPorts = new HashSet<>();
+		if (configuration.has("inputPorts")) {
+			for (JsonNode inputPort : configuration.get("inputPorts")) {
+				inputPorts.add(edits.createActivityInputPort(inputPort.get("name").textValue(),
+						inputPort.get("depth").intValue(), false, null, String.class));
+			}
+		}
+		return inputPorts;
+	}
+
+	@Override
+	public Set<ActivityOutputPort> getOutputPorts(JsonNode configuration)
+			throws ActivityConfigurationException {
+		Set<ActivityOutputPort> outputPorts = new HashSet<>();
+		if (configuration.has("outputPorts")) {
+			for (JsonNode outputPort : configuration.get("outputPorts")) {
+				outputPorts.add(edits.createActivityOutputPort(outputPort.get("name").textValue(),
+						outputPort.get("depth").intValue(), outputPort.get("granularDepth").intValue()));
+			}
+		}
+		return outputPorts;
+	}
+
+	public void setEdits(Edits edits) {
+		this.edits = edits;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLOutputSplitterHealthChecker.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLOutputSplitterHealthChecker.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLOutputSplitterHealthChecker.java
new file mode 100644
index 0000000..7634b6d
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLOutputSplitterHealthChecker.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * 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.t2.activities.wsdl.xmlsplitter;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+
+import net.sf.taverna.t2.visit.VisitReport;
+import net.sf.taverna.t2.visit.VisitReport.Status;
+import net.sf.taverna.t2.workflowmodel.health.HealthCheck;
+import net.sf.taverna.t2.workflowmodel.health.HealthChecker;
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+import net.sf.taverna.wsdl.xmlsplitter.XMLSplitterSerialisationHelper;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+
+public class XMLOutputSplitterHealthChecker implements HealthChecker<XMLOutputSplitterActivity> {
+
+	public boolean canVisit(Object subject) {
+		return subject!=null && subject instanceof XMLOutputSplitterActivity;
+	}
+
+	public VisitReport visit(XMLOutputSplitterActivity activity, List<Object> ancestors) {
+		Element element;
+		try {
+			String wrappedType = activity.getConfiguration().get("wrappedType").textValue();
+			element = new SAXBuilder().build(new StringReader(wrappedType)).getRootElement();
+		} catch (JDOMException | IOException e) {
+			return new VisitReport(HealthCheck.getInstance(), activity, "Error reading wrapped type", HealthCheck.INVALID_CONFIGURATION, Status.SEVERE);
+		}
+		TypeDescriptor typeDescriptor = XMLSplitterSerialisationHelper.extensionXMLToTypeDescriptor(element);
+		if (typeDescriptor==null) {
+			return new VisitReport(HealthCheck.getInstance(), activity, "Unknown datatype for port", HealthCheck.NULL_DATATYPE, Status.SEVERE);
+		}
+		else {
+			return new VisitReport(HealthCheck.getInstance(), activity, "Recognized datatype", HealthCheck.NO_PROBLEM, Status.OK);
+		}
+	}
+
+	public boolean isTimeConsuming() {
+		return false;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLSplitterConfigurationBean.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLSplitterConfigurationBean.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLSplitterConfigurationBean.java
new file mode 100644
index 0000000..2045260
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLSplitterConfigurationBean.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * 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.t2.activities.wsdl.xmlsplitter;
+
+import org.jdom.Element;
+
+import net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityPortsDefinitionBean;
+import net.sf.taverna.t2.workflowmodel.processor.config.ConfigurationBean;
+import net.sf.taverna.t2.workflowmodel.processor.config.ConfigurationProperty;
+
+@ConfigurationBean(uri = "http://ns.taverna.org.uk/2010/activity/xml-splitter#Config")
+public class XMLSplitterConfigurationBean extends ActivityPortsDefinitionBean {
+	Element wrappedTypeXML;
+
+	public Element getWrappedTypeXML() {
+		return wrappedTypeXML;
+	}
+
+	@ConfigurationProperty(name = "wrappedType", label = "Wrapped Type XML")
+	public void setWrappedTypeXML(Element wrappedTypeXML) {
+		this.wrappedTypeXML = wrappedTypeXML;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLSplitterConfigurationBeanBuilder.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLSplitterConfigurationBeanBuilder.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLSplitterConfigurationBeanBuilder.java
new file mode 100644
index 0000000..e8d7fa8
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/XMLSplitterConfigurationBeanBuilder.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * 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.t2.activities.wsdl.xmlsplitter;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+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.xmlsplitter.XMLSplitterSerialisationHelper;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.output.XMLOutputter;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * A helper class to facilitate in building an XMLSplitter configuration bean
+ * from the type descriptor XML, including setting up the ports.
+ *
+ * @author Stuart Owen
+ *
+ */
+public class XMLSplitterConfigurationBeanBuilder {
+
+	private static final JsonNodeFactory JSON_NODE_FACTORY = JsonNodeFactory.instance;
+
+	public static JsonNode buildBeanForInput(TypeDescriptor descriptor) throws JDOMException, IOException {
+		Element element = XMLSplitterSerialisationHelper.typeDescriptorToExtensionXML(descriptor);
+		return buildBeanForInput(element);
+	}
+
+	public static JsonNode buildBeanForOutput(TypeDescriptor descriptor) throws JDOMException, IOException {
+		Element element = XMLSplitterSerialisationHelper.typeDescriptorToExtensionXML(descriptor);
+		return buildBeanForOutput(element);
+	}
+
+	public static JsonNode buildBeanForInput(Element element) throws JDOMException, IOException {
+		ObjectNode bean = JSON_NODE_FACTORY.objectNode();
+		ArrayNode inputDefinitions = bean.arrayNode();
+		bean.put("inputPorts", inputDefinitions);
+		ArrayNode outputDefinitions = bean.arrayNode();
+		bean.put("outputPorts", outputDefinitions);
+
+		TypeDescriptor descriptor = XMLSplitterSerialisationHelper
+				.extensionXMLToTypeDescriptor(element);
+		ObjectNode outBean = outputDefinitions.addObject();
+		outBean.put("name", "output");
+		outBean.put("mimeType", "'text/xml'");
+		outBean.put("depth", 0);
+		outBean.put("granularDepth", 0);
+
+		if (descriptor instanceof ComplexTypeDescriptor) {
+			List<TypeDescriptor> elements = ((ComplexTypeDescriptor) descriptor).getElements();
+			String[] names = new String[elements.size()];
+			Class<?>[] types = new Class<?>[elements.size()];
+			TypeDescriptor.retrieveSignature(elements, names, types);
+			for (int i = 0; i < names.length; i++) {
+				ObjectNode portBean = inputDefinitions.addObject();
+				portBean.put("name", names[i]);
+				portBean.put("mimeType", TypeDescriptor.translateJavaType(types[i]));
+				portBean.put("depth", depthForDescriptor(elements.get(i)));
+			}
+
+			List<TypeDescriptor> attributes = ((ComplexTypeDescriptor) descriptor).getAttributes();
+			String[] elementNames = Arrays.copyOf(names, names.length);
+			Arrays.sort(elementNames);
+			String[] attributeNames = new String[attributes.size()];
+			Class<?>[] attributeTypes = new Class<?>[attributes.size()];
+			TypeDescriptor.retrieveSignature(attributes, attributeNames, attributeTypes);
+			for (int i = 0; i < attributeNames.length; i++) {
+				ObjectNode portBean = inputDefinitions.addObject();
+				if (Arrays.binarySearch(elementNames, attributeNames[i]) < 0) {
+					portBean.put("name", attributeNames[i]);
+				} else {
+					portBean.put("name", "1" + attributeNames[i]);
+				}
+				portBean.put("mimeType", TypeDescriptor.translateJavaType(attributeTypes[i]));
+				portBean.put("depth", depthForDescriptor(attributes.get(i)));
+			}
+			
+		} else if (descriptor instanceof ArrayTypeDescriptor) {
+			ObjectNode portBean = inputDefinitions.addObject();
+			portBean.put("name", descriptor.getName());
+
+			if (((ArrayTypeDescriptor) descriptor).getElementType() instanceof BaseTypeDescriptor) {
+				portBean.put("mimeType", "l('text/plain')");
+			} else {
+				portBean.put("mimeType", "l('text/xml')");
+			}
+			portBean.put("depth", 1);
+		}
+
+		String wrappedType = new XMLOutputter().outputString(element);
+		bean.put("wrappedType", wrappedType);
+
+		return bean;
+	}
+
+
+	private static int depthForDescriptor(TypeDescriptor desc) {
+		if (desc instanceof ArrayTypeDescriptor && (!((ArrayTypeDescriptor)desc).isWrapped() || ((ArrayTypeDescriptor)desc).getElementType() instanceof BaseTypeDescriptor)) {
+			return 1;
+		}
+		else {
+			return 0;
+		}
+	}
+
+	public static JsonNode buildBeanForOutput(Element element)
+			throws JDOMException, IOException {
+		ObjectNode bean = JSON_NODE_FACTORY.objectNode();
+		ArrayNode inputDefinitions = bean.arrayNode();
+		bean.put("inputPorts", inputDefinitions);
+		ArrayNode outputDefinitions = bean.arrayNode();
+		bean.put("outputPorts", outputDefinitions);
+
+		TypeDescriptor descriptor = XMLSplitterSerialisationHelper
+				.extensionXMLToTypeDescriptor(element);
+
+		ObjectNode inBean = inputDefinitions.addObject();
+		inBean.put("name", "input");
+		inBean.put("mimeType", "'text/xml'");
+		inBean.put("depth", 0);
+
+		if (descriptor instanceof ComplexTypeDescriptor) {
+			List<TypeDescriptor> elements = ((ComplexTypeDescriptor) descriptor).getElements();
+			String[] names = new String[elements.size()];
+			Class<?>[] types = new Class<?>[elements.size()];
+			TypeDescriptor.retrieveSignature(elements, names, types);
+			for (int i = 0; i < names.length; i++) {
+				ObjectNode portBean = outputDefinitions.addObject();
+				portBean.put("name", names[i]);
+				portBean.put("mimeType", TypeDescriptor.translateJavaType(types[i]));
+				int depth = depthForDescriptor(elements.get(i));
+				portBean.put("depth", depth);
+				portBean.put("granularDepth", depth);
+			}
+
+			List<TypeDescriptor> attributes = ((ComplexTypeDescriptor) descriptor).getAttributes();
+			String[] elementNames = Arrays.copyOf(names, names.length);
+			Arrays.sort(elementNames);
+			String[] attributeNames = new String[attributes.size()];
+			Class<?>[] attributeTypes = new Class<?>[attributes.size()];
+			TypeDescriptor.retrieveSignature(attributes, attributeNames, attributeTypes);
+			for (int i = 0; i < attributeNames.length; i++) {
+				ObjectNode portBean = outputDefinitions.addObject();
+				if (Arrays.binarySearch(elementNames, attributeNames[i]) < 0) {
+					portBean.put("name", attributeNames[i]);
+				} else {
+					portBean.put("name", "1" + attributeNames[i]);
+				}
+				portBean.put("mimeType", TypeDescriptor
+						.translateJavaType(attributeTypes[i]));
+				int depth = depthForDescriptor(attributes.get(i));
+				portBean.put("depth", depth);
+				portBean.put("granularDepth", depth);
+			}
+			
+		} else if (descriptor instanceof ArrayTypeDescriptor) {
+			ObjectNode portBean = outputDefinitions.addObject();
+			String name=descriptor.getName();
+			portBean.put("name", name);
+			portBean.put("depth", 1);
+			portBean.put("granularDepth", 1);
+			if (((ArrayTypeDescriptor) descriptor).getElementType() instanceof BaseTypeDescriptor) {
+				portBean.put("mimeType", "l('text/plain')");
+			} else {
+				portBean.put("mimeType", "l('text/xml')");
+			}
+		}
+
+
+		String wrappedType = new XMLOutputter().outputString(element);
+		bean.put("wrappedType", wrappedType);
+
+		return bean;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/resources/META-INF/services/net.sf.taverna.t2.workflowmodel.health.HealthChecker
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/resources/META-INF/services/net.sf.taverna.t2.workflowmodel.health.HealthChecker b/taverna-wsdl-activity/src/main/resources/META-INF/services/net.sf.taverna.t2.workflowmodel.health.HealthChecker
new file mode 100644
index 0000000..fb1c735
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/resources/META-INF/services/net.sf.taverna.t2.workflowmodel.health.HealthChecker
@@ -0,0 +1,4 @@
+net.sf.taverna.t2.activities.wsdl.WSDLActivityHealthChecker
+net.sf.taverna.t2.activities.wsdl.xmlsplitter.XMLOutputSplitterHealthChecker
+net.sf.taverna.t2.activities.wsdl.xmlsplitter.XMLInputSplitterHealthChecker
+net.sf.taverna.t2.activities.wsdl.WSDLActivityDescriptorChecker
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/resources/META-INF/spring/wsdl-activity-context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/resources/META-INF/spring/wsdl-activity-context-osgi.xml b/taverna-wsdl-activity/src/main/resources/META-INF/spring/wsdl-activity-context-osgi.xml
new file mode 100644
index 0000000..b8976d5
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/resources/META-INF/spring/wsdl-activity-context-osgi.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans:beans xmlns="http://www.springframework.org/schema/osgi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:beans="http://www.springframework.org/schema/beans"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans
+                                 http://www.springframework.org/schema/beans/spring-beans.xsd
+                                 http://www.springframework.org/schema/osgi
+                                 http://www.springframework.org/schema/osgi/spring-osgi.xsd">
+
+	<service ref="wsdlActivityHealthChecker" interface="net.sf.taverna.t2.workflowmodel.health.HealthChecker" />
+	<service ref="xmlInputSplitterHealthChecker" interface="net.sf.taverna.t2.workflowmodel.health.HealthChecker" />
+	<service ref="xmlOutputSplitterHealthChecker" interface="net.sf.taverna.t2.workflowmodel.health.HealthChecker" />
+
+	<service ref="wsdlActivityFactory" interface="net.sf.taverna.t2.workflowmodel.processor.activity.ActivityFactory" />
+	<service ref="xmlInputSplitterActivityFactory" interface="net.sf.taverna.t2.workflowmodel.processor.activity.ActivityFactory" />
+	<service ref="xmlOutputSplitterActivityFactory" interface="net.sf.taverna.t2.workflowmodel.processor.activity.ActivityFactory" />
+
+	<reference id="credentialManager" interface="net.sf.taverna.t2.security.credentialmanager.CredentialManager" />
+	<reference id="edits" interface="net.sf.taverna.t2.workflowmodel.Edits" />
+
+</beans:beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/resources/META-INF/spring/wsdl-activity-context.xml
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/resources/META-INF/spring/wsdl-activity-context.xml b/taverna-wsdl-activity/src/main/resources/META-INF/spring/wsdl-activity-context.xml
new file mode 100644
index 0000000..fbbdf55
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/resources/META-INF/spring/wsdl-activity-context.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans
+                           http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<bean id="wsdlActivityHealthChecker" class="net.sf.taverna.t2.activities.wsdl.WSDLActivityHealthChecker" />
+	<bean id="xmlInputSplitterHealthChecker" class="net.sf.taverna.t2.activities.wsdl.xmlsplitter.XMLInputSplitterHealthChecker" />
+	<bean id="xmlOutputSplitterHealthChecker" class="net.sf.taverna.t2.activities.wsdl.xmlsplitter.XMLOutputSplitterHealthChecker" />
+
+	<bean id="wsdlActivityFactory" class="net.sf.taverna.t2.activities.wsdl.WSDLActivityFactory">
+		<property name="credentialManager" ref="credentialManager" />
+		<property name="edits" ref="edits" />
+	</bean>
+	<bean id="xmlInputSplitterActivityFactory" class="net.sf.taverna.t2.activities.wsdl.xmlsplitter.XMLInputSplitterActivityFactory">
+		<property name="edits" ref="edits" />
+	</bean>
+	<bean id="xmlOutputSplitterActivityFactory" class="net.sf.taverna.t2.activities.wsdl.xmlsplitter.XMLOutputSplitterActivityFactory">
+		<property name="edits" ref="edits" />
+	</bean>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/resources/schema.json
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/resources/schema.json b/taverna-wsdl-activity/src/main/resources/schema.json
new file mode 100644
index 0000000..bcafb67
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/resources/schema.json
@@ -0,0 +1,39 @@
+{
+    "$schema": "http://json-schema.org/draft-03/schema#",
+    "id": "http://ns.taverna.org.uk/2010/activity/wsdl.schema.json",
+    "title": "WSDL activity configuration",
+    "type": "object",
+    "properties": {
+        "@context": {
+            "description": "JSON-LD context for interpreting the configuration as RDF",
+            "required": true,
+            "enum": ["http://ns.taverna.org.uk/2010/activity/wsdl.context.json"]
+        },
+        "operation": {
+            "title": "WSDL Operation",
+            "description": "The WSDL operation",
+            "type": "object",
+            "properties": {
+           		"wsdl": {
+            		"title": "WSDL URL",
+            		"description": "The location of the WSDL definition for the web service",
+            		"type": "string",
+		          	"required": true
+           		},
+           		"name": {
+            		"title": "Operation Name",
+            		"description": "The name of the WSDL operation",
+            		"type": "sting",
+ 		         	"required": true
+            	}
+            },
+            "required": true
+        },
+        "securityProfile": {
+            "title": "Security Profile",
+            "description": "WS-Security settings required by the web service",
+            "type": "string",
+            "required": false
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/main/resources/xml-splitter.schema.json
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/resources/xml-splitter.schema.json b/taverna-wsdl-activity/src/main/resources/xml-splitter.schema.json
new file mode 100644
index 0000000..3dbae7c
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/resources/xml-splitter.schema.json
@@ -0,0 +1,80 @@
+{
+    "$schema": "http://json-schema.org/draft-03/schema#",
+    "id": "http://ns.taverna.org.uk/2010/activity/xml-splitter.schema.json",
+    "title": "XML splitter activity configuration",
+    "type": "object",
+    "properties": {
+        "@context": {
+            "description": "JSON-LD context for interpreting the configuration as RDF",
+            "required": true,
+            "enum": ["http://ns.taverna.org.uk/2010/activity/xml-splitter.context.json"]
+        },
+        "wrappedType": {
+            "title": "Wrapped Type XML",
+            "type": "string",
+            "required": true
+        },
+        "inputPorts": {
+            "title": "Input Ports",
+            "type": "array",
+            "required": false,
+            "items": {
+                "type": "object",
+                "properties": {
+           		    "name": {
+                		"title": "Port Name",
+            			"description": "The name of the port",
+            			"type": "string",
+		          		"required": true
+           			},
+                    "depth": {
+                 		"title": "Port Depth",
+             			"description": "The depth of the port",
+                        "type": "integer",
+                        "required": true
+           			},
+                    "mimeType": {
+                 		"title": "Mime Type",
+             			"description": "The mime type of the port",
+                        "type": "string",
+                        "required": true
+                    }
+                }
+             }
+        },
+        "outputPorts": {
+            "title": "Output Ports",
+            "type": "array",
+            "required": false,
+            "items": {
+                "type": "object",
+                "properties": {
+           		    "name": {
+                		"title": "Port Name",
+            			"description": "The name of the port",
+            			"type": "string",
+		          		"required": true
+           			},
+                    "depth": {
+                 		"title": "Port Depth",
+             			"description": "The depth of the port",
+                        "type": "integer",
+                        "required": true
+                    }
+                    "granularDepth": {
+                 		"title": "Port Granular Depth",
+             			"description": "The granular depth of the port",
+                        "type": "integer",
+                        "required": true
+           			},
+                    "mimeType": {
+                 		"title": "Mime Type",
+             			"description": "The mime type of the port",
+                        "type": "string",
+                        "required": true
+                    }
+                }
+             }
+         }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityFactoryTest.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityFactoryTest.java b/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityFactoryTest.java
new file mode 100644
index 0000000..9b147cf
--- /dev/null
+++ b/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityFactoryTest.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (C) 2010 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.t2.activities.wsdl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.net.URI;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * 
+ * @author David Withers
+ */
+public class WSDLActivityFactoryTest {
+
+	private WSDLActivityFactory factory;
+	
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@Before
+	public void setUp() throws Exception {
+		factory = new WSDLActivityFactory();
+	}
+
+	/**
+	 * Test method for {@link net.sf.taverna.t2.activities.beanshell.BeanshellActivityFactory#createActivity()}.
+	 */
+	@Test
+	public void testCreateActivity() {
+		WSDLActivity createActivity = factory.createActivity();
+		assertNotNull(createActivity);
+	}
+
+	/**
+	 * Test method for {@link net.sf.taverna.t2.activities.beanshell.BeanshellActivityFactory#getActivityType()}.
+	 */
+	@Test
+	public void testGetActivityURI() {
+		assertEquals(URI.create(WSDLActivity.URI), factory.getActivityType());
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityTest.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityTest.java b/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityTest.java
new file mode 100644
index 0000000..b1868ac
--- /dev/null
+++ b/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityTest.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * 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.t2.activities.wsdl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.sf.taverna.t2.activities.testutils.ActivityInvoker;
+import net.sf.taverna.t2.activities.testutils.LocationConstants;
+import net.sf.taverna.t2.workflowmodel.OutputPort;
+import net.sf.taverna.wsdl.parser.ComplexTypeDescriptor;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class WSDLActivityTest implements LocationConstants {
+
+	private static final JsonNodeFactory JSON_NODE_FACTORY = JsonNodeFactory.instance;
+
+	private static WSDLActivity activity;
+	private static ObjectNode configBean;
+	private static ObjectNode operationConfigBean;
+	private static String wsdlLocation = WSDL_TEST_BASE
+			+ "eutils/eutils_lite.wsdl";
+
+	//@BeforeClass
+    @Ignore("Integration test")
+	public static void setUp() throws Exception {
+		activity = new WSDLActivity(null);
+		configBean = JSON_NODE_FACTORY.objectNode();
+		operationConfigBean = configBean.objectNode();
+		configBean.put("operation", operationConfigBean);
+		operationConfigBean.put("name", "run_eInfo");
+		operationConfigBean.put("wsdl", wsdlLocation);
+		activity.configure(configBean);
+	}
+
+	@Test
+    @Ignore("Integration test")
+	public void testConfigureWSDLActivityConfigurationBean() throws Exception {
+		assertEquals("There should be 1 input ports", 1, activity
+				.getInputPorts().size());
+		assertEquals("There should be 2 output ports", 2, activity
+				.getOutputPorts().size());
+
+		assertEquals("parameters", activity.getInputPorts().iterator().next()
+				.getName());
+
+		List<String> expectedOutputNames = new ArrayList<String>();
+		expectedOutputNames.add("parameters");
+		expectedOutputNames.add("attachmentList");
+		for (OutputPort port : activity.getOutputPorts()) {
+			assertTrue("Unexpected output name:" + port.getName(),
+					expectedOutputNames.contains(port.getName()));
+			expectedOutputNames.remove(port.getName());
+		}
+		assertEquals(
+				"Not all of the expected outputs were found, those remainng are:"
+						+ expectedOutputNames.toArray(), 0, expectedOutputNames
+						.size());
+	}
+
+	@Test
+    @Ignore("Integration test")
+	public void testGetConfiguration() throws Exception {
+		assertSame(configBean, activity.getConfiguration());
+	}
+
+	@Test
+	@Ignore("Service is broken")
+	public void testExecuteAsynchMapOfStringEntityIdentifierAsynchronousActivityCallback()
+			throws Exception {
+		Map<String, Object> inputMap = new HashMap<String, Object>();
+		inputMap.put("parameters", "<parameters><db>pubmed</db></parameters>");
+
+		Map<String, Class<?>> expectedOutputs = new HashMap<String, Class<?>>();
+		expectedOutputs.put("parameters", String.class);
+
+		Map<String, Object> outputMap = ActivityInvoker.invokeAsyncActivity(
+				activity, inputMap, expectedOutputs);
+		assertNotNull("there should be an output named parameters", outputMap
+				.get("parameters"));
+		String xml;
+		if (outputMap.get("parameters") instanceof String) {
+			xml = (String) outputMap.get("parameters");
+		} else {
+			byte[] bytes = (byte[]) outputMap.get("parameters");
+			xml = new String(bytes);
+		}
+
+		assertTrue("the xml is not what was expected", xml
+				.contains("<DbName>pubmed</DbName>"));
+	}
+
+    @Ignore("Integration test")
+	@Test
+	public void testGetTypeDescriptorForOutputPort() throws Exception {
+		assertNotNull("The type for the port 'paremeters' could not be found",
+				activity.getTypeDescriptorForOutputPort("parameters"));
+		assertTrue(
+				"The type for the port 'paremeters' shoule be complex",
+				activity.getTypeDescriptorForOutputPort("parameters") instanceof ComplexTypeDescriptor);
+		assertNull("There should be no type descriptor for 'fred' port",
+				activity.getTypeDescriptorForOutputPort("fred"));
+	}
+
+    @Ignore("Integration test")
+	@Test
+	public void testGetTypeDescriptorForInputPort() throws Exception {
+		assertNotNull("The type for the port 'parameters' could not be found",
+				activity.getTypeDescriptorForInputPort("parameters"));
+		assertTrue(
+				"The type for the port 'parameters' shoule be complex",
+				activity.getTypeDescriptorForInputPort("parameters") instanceof ComplexTypeDescriptor);
+		assertNull("There should be no type descriptor for 'fred' port",
+				activity.getTypeDescriptorForInputPort("fred"));
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/WSRFActivityTest.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/WSRFActivityTest.java b/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/WSRFActivityTest.java
new file mode 100644
index 0000000..dd144cf
--- /dev/null
+++ b/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/WSRFActivityTest.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * 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.t2.activities.wsdl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.StringReader;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+
+import net.sf.taverna.wsdl.parser.WSDLParser;
+
+import org.apache.axis.client.Call;
+import org.apache.axis.message.SOAPEnvelope;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.Namespace;
+import org.jdom.input.SAXBuilder;
+import org.junit.Before;
+import org.junit.Test;
+
+public class WSRFActivityTest {
+
+	public class DummyInvoker extends T2WSDLSOAPInvoker {
+
+		public DummyInvoker(String wsrfEndpoint) {
+			super(wsdlParser, "add", Arrays.asList("attachmentList"),
+					wsrfEndpoint, null);
+		}
+
+		@Override
+		protected SOAPEnvelope invokeCall(Call call, SOAPEnvelope requestEnv) {
+			requestXML = requestEnv;
+			return null;
+		}
+	}
+
+	private static final Namespace SoapEnvelopeNS = Namespace
+			.getNamespace("http://schemas.xmlsoap.org/soap/envelope/");
+	private static final Namespace CounterNS = Namespace
+			.getNamespace("http://counter.com");
+	private static final Namespace DifficultNS = Namespace
+			.getNamespace("http://difficult.com/");
+
+	private static final Namespace DefaultNS = Namespace
+			.getNamespace("http://default/");
+
+	private URL counterServiceWSDL;
+	private WSDLParser wsdlParser;
+	protected SOAPEnvelope requestXML;
+
+	@Before
+	public void makeWSDLParser() throws Exception {
+		String path = "wsrf/counterService/CounterService_.wsdl";
+		counterServiceWSDL = getClass().getResource(path);
+		assertNotNull("Coult not find test WSDL " + path, counterServiceWSDL);
+		wsdlParser = new WSDLParser(counterServiceWSDL.toExternalForm());
+	}
+
+	public void noHeaders() throws Exception {
+
+	}
+
+	@Test
+	public void insertedEndpoint() throws Exception {
+		// From T2-677 - support wsa:EndpointReference directly as well
+		String wsrfEndpoint = "" +
+				"<wsa:EndpointReference "
+				+ "xmlns:wsa='http://schemas.xmlsoap.org/ws/2004/03/addressing' "
+				+ "xmlns:counter='http://counter.com'>"
+				+ "  <wsa:Address>http://130.88.195.110:8080/wsrf/services/CounterService</wsa:Address>"
+				+ "   <wsa:ReferenceProperties>"
+				+ "     <counter:CounterKey>15063581</counter:CounterKey>"
+				+ "      <difficult:one xmlns:difficult='http://difficult.com/' "
+				+ "             difficult:attrib='something' attrib='else' >"
+				+ "         <difficult:fish><counter:fish /></difficult:fish> "
+				+ "      </difficult:one>" + "      <emptyNamespace>"
+				+ "          <defaultNamespace xmlns='http://default/'>"
+				+ "\n  default  \n " + "</defaultNamespace>"
+				+ "          <stillEmpty />" + "      </emptyNamespace>"
+				+ "  </wsa:ReferenceProperties>"
+				+ "  <wsa:ReferenceParameters/>" + "</wsa:EndpointReference>";
+
+		// Note: We'll subclass to avoid calling service
+		// and request attachmentList to trigger TAV-617-code and avoid
+		// parsing of the (missing) response
+		T2WSDLSOAPInvoker invoker = new DummyInvoker(wsrfEndpoint);
+		Map<String, Object> results = invoker.invoke(Collections.singletonMap(
+				"add", "10"));
+		assertEquals(1, results.size());
+		assertEquals("attachmentList", results.keySet().iterator().next());
+
+		SAXBuilder builder = new SAXBuilder();
+		Document doc = builder.build(new StringReader(requestXML.toString()));
+		Element header = doc.getRootElement()
+				.getChild("Header", SoapEnvelopeNS);
+		assertNotNull("Could not find soapenv:Header", header);
+		assertEquals("Unexpected number of children in header", 3, header
+				.getChildren().size());
+
+		// Check that everything was preserved as much as possible
+
+		Element counterChild = header.getChild("CounterKey", CounterNS);
+		assertEquals("15063581", counterChild.getText());
+		assertEquals("Did not preserve namespace", "counter", counterChild
+				.getNamespacePrefix());
+
+		Element difficultChild = header.getChild("one", DifficultNS);
+		assertNotNull("Could not find difficult:one", difficultChild);
+		assertEquals("Did not preserve namespace", "difficult", difficultChild
+				.getNamespacePrefix());
+		assertEquals("something", difficultChild.getAttribute("attrib",
+				DifficultNS).getValue());
+		assertEquals("else", difficultChild.getAttribute("attrib",
+				Namespace.NO_NAMESPACE).getValue());
+
+		Element counterFish = difficultChild.getChild("fish", DifficultNS)
+				.getChild("fish", CounterNS);
+		assertEquals("counter", counterFish.getNamespacePrefix());
+
+		Element emptyChild = header.getChild("emptyNamespace",
+				Namespace.NO_NAMESPACE);
+		Element defaultNamespace = emptyChild.getChild("defaultNamespace",
+				DefaultNS);
+		assertEquals("\n  default  \n ", defaultNamespace.getText());
+
+		Element stillEmpty = emptyChild.getChild("stillEmpty");
+		assertEquals(Namespace.NO_NAMESPACE, stillEmpty.getNamespace());
+
+	}
+
+
+	@Test
+	public void insertedEndpointWrapped() throws Exception {
+		// From T2-677 - support wsa:EndpointReference wrapped in <*> to avoid
+		// unnecessary XML splitters and to support legacy workflows
+
+		// Example from http://www.mygrid.org.uk/dev/issues/browse/TAV-23
+		String wsrfEndpoint = "" +
+				"<c:createCounterResponse xmlns:c='http://counter.com'>" +
+				"<wsa:EndpointReference "
+				+ "xmlns:wsa='http://schemas.xmlsoap.org/ws/2004/03/addressing' "
+				+ "xmlns:counter='http://counter.com'>"
+				+ "  <wsa:Address>http://130.88.195.110:8080/wsrf/services/CounterService</wsa:Address>"
+				+ "   <wsa:ReferenceProperties>"
+				+ "     <counter:CounterKey>15063581</counter:CounterKey>"
+				+ "      <difficult:one xmlns:difficult='http://difficult.com/' "
+				+ "             difficult:attrib='something' attrib='else' >"
+				+ "         <difficult:fish><counter:fish /></difficult:fish> "
+				+ "      </difficult:one>" + "      <emptyNamespace>"
+				+ "          <defaultNamespace xmlns='http://default/'>"
+				+ "\n  default  \n " + "</defaultNamespace>"
+				+ "          <stillEmpty />" + "      </emptyNamespace>"
+				+ "  </wsa:ReferenceProperties>"
+				+ "  <wsa:ReferenceParameters/>" + "</wsa:EndpointReference>" +
+				"</c:createCounterResponse>";
+
+		// Note: We'll subclass to avoid calling service
+		// and request attachmentList to trigger TAV-617-code and avoid
+		// parsing of the (missing) response
+		T2WSDLSOAPInvoker invoker = new DummyInvoker(wsrfEndpoint);
+		Map<String, Object> results = invoker.invoke(Collections.singletonMap(
+				"add", "10"));
+		assertEquals(1, results.size());
+		assertEquals("attachmentList", results.keySet().iterator().next());
+
+		SAXBuilder builder = new SAXBuilder();
+		Document doc = builder.build(new StringReader(requestXML.toString()));
+		Element header = doc.getRootElement()
+				.getChild("Header", SoapEnvelopeNS);
+		assertNotNull("Could not find soapenv:Header", header);
+		assertEquals("Unexpected number of children in header", 3, header
+				.getChildren().size());
+
+		// Check that everything was preserved as much as possible
+
+		Element counterChild = header.getChild("CounterKey", CounterNS);
+		assertEquals("15063581", counterChild.getText());
+		assertEquals("Did not preserve namespace", "counter", counterChild
+				.getNamespacePrefix());
+
+		Element difficultChild = header.getChild("one", DifficultNS);
+		assertNotNull("Could not find difficult:one", difficultChild);
+		assertEquals("Did not preserve namespace", "difficult", difficultChild
+				.getNamespacePrefix());
+		assertEquals("something", difficultChild.getAttribute("attrib",
+				DifficultNS).getValue());
+		assertEquals("else", difficultChild.getAttribute("attrib",
+				Namespace.NO_NAMESPACE).getValue());
+
+		Element counterFish = difficultChild.getChild("fish", DifficultNS)
+				.getChild("fish", CounterNS);
+		assertEquals("counter", counterFish.getNamespacePrefix());
+
+		Element emptyChild = header.getChild("emptyNamespace",
+				Namespace.NO_NAMESPACE);
+		Element defaultNamespace = emptyChild.getChild("defaultNamespace",
+				DefaultNS);
+		assertEquals("\n  default  \n ", defaultNamespace.getText());
+
+		Element stillEmpty = emptyChild.getChild("stillEmpty");
+		assertEquals(Namespace.NO_NAMESPACE, stillEmpty.getNamespace());
+
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/security/HTTPSConnectionsTest.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/security/HTTPSConnectionsTest.java b/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/security/HTTPSConnectionsTest.java
new file mode 100644
index 0000000..58d6dd5
--- /dev/null
+++ b/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/security/HTTPSConnectionsTest.java
@@ -0,0 +1,50 @@
+package net.sf.taverna.t2.activities.wsdl.security;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.cert.Certificate;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLHandshakeException;
+
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class HTTPSConnectionsTest {
+
+	@Test()
+	@Ignore("https://rpc103.cs.man.ac.uk:8443/wsrf/services no available")
+	public void testHTTPSConnections(){
+
+		String serviceURL = "https://rpc103.cs.man.ac.uk:8443/wsrf/services";
+
+			URL url;
+			try {
+				url = new URL(serviceURL);
+				SSLUtilities.trustAllHttpsCertificates();
+				HttpsURLConnection httpsConnection = (HttpsURLConnection) url.openConnection();
+				httpsConnection.connect();
+				Certificate[] certificates = httpsConnection.getServerCertificates();
+				Assert.assertFalse(certificates.length == 0);
+
+				SSLUtilities.stopTrustingAllHttpsCertificates();
+				HttpsURLConnection httpsConnection2 = (HttpsURLConnection) url.openConnection();
+				httpsConnection2.connect(); // This should now throw an SSLHandshakeException which is a subclass of IOException
+
+			} catch (MalformedURLException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+
+			} catch(SSLHandshakeException e){
+				// This is what we are expecting
+				e.printStackTrace();
+			}
+			catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/security/SecureServicesInvokerTest.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/security/SecureServicesInvokerTest.java b/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/security/SecureServicesInvokerTest.java
new file mode 100644
index 0000000..f0c3265
--- /dev/null
+++ b/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/security/SecureServicesInvokerTest.java
@@ -0,0 +1,116 @@
+package net.sf.taverna.t2.activities.wsdl.security;
+
+import static org.junit.Assert.assertEquals;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+import javax.xml.namespace.QName;
+
+import org.apache.axis.client.Call;
+import org.apache.axis.client.Service;
+import org.apache.axis.configuration.XMLStringProvider;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class SecureServicesInvokerTest {
+
+	// Broken service
+	@Ignore
+	@Test
+	public void testCreteCallAndInvoke() throws Exception { 
+			
+
+			String endpoint = "http://www.mygrid.org.uk/axis/services/UsernameHelloService"; // test server
+			//endpoint = "http://rpc212.cs.man.ac.uk/taverna/";
+			
+			HostnameVerifier hv = new HostnameVerifier() {
+				public boolean verify(String hostName, SSLSession session) {
+					return true;
+				}
+			};
+			HttpsURLConnection.setDefaultHostnameVerifier(hv);
+			//endpoint = "https://rpc103.cs.man.ac.uk:8443/wsrf/services/cagrid/SecureHelloWorld?wsdl";
+			
+			// Set the system property "javax.net.ssl.Truststore" to use Taverna's truststore 
+			//System.setProperty("javax.net.ssl.trustStore", "/Users/alex/Desktop/t2truststore.jks");
+			//System.setProperty("javax.net.ssl.trustStorePassword", "raehiekooshe0eghiPhi");
+			//System.clearProperty("javax.net.ssl.trustStoreType");
+			//System.clearProperty("javax.net.ssl.trustStoreProvider");
+			
+			//String endpoint = "http://www.mygrid.org.uk/axis/services/UsernameTimestampHelloService"; // test server
+			//String endpoint = "http://www.mygrid.org.uk/axis/services/UsernameDigestHelloService"; // test server
+			//String endpoint = "http://www.mygrid.org.uk/axis/services/UsernameDigestTimestampHelloService"; // test server
+			
+			//String endpoint = "http://localhost:8080/axis/services/UsernameHelloService" ; // local server
+			//String endpoint = "http://localhost:8080/axis/services/UsernameTimestampHelloService" ; 
+			//String endpoint = "http://localhost:8080/axis/services/UsernameDigestHelloService" ; 
+			//String endpoint = "http://localhost:8080/axis/services/UsernameDigestTimestampHelloService" ; 
+			
+			//Service service = new org.apache.axis.client.Service() ; 
+			
+			//String wssEngineConfigurationString = WSSecurityProfiles.wssUTTimestampProfile;
+			//String wssEngineConfigurationString = WSSecurityProfiles.wssUTDigestProfile;
+			//String wssEngineConfigurationString = WSSecurityProfiles.wssUTDigestTimestampProfile;
+		
+			XMLStringProvider wssEngineConfiguration = new XMLStringProvider("<deployment xmlns=\"http://xml.apache.org/axis/wsdd/\" " +
+					"xmlns:java=\"http://xml.apache.org/axis/wsdd/providers/java\">" +
+					"<globalConfiguration>" +
+					"<requestFlow>" +
+					"<handler type=\"java:org.apache.ws.axis.security.WSDoAllSender\">" + 
+					"<parameter name=\"action\" value=\"UsernameToken\"/>" +
+					"<parameter name=\"passwordType\" value=\"PasswordDigest\"/>" +
+					"</handler>"+
+					"</requestFlow>" + 
+					"</globalConfiguration>" + 
+					"<transport name=\"http\" pivot=\"java:org.apache.axis.transport.http.HTTPSender\"/>"+
+					"</deployment>");
+			
+			Service service = new Service(wssEngineConfiguration);
+		
+			Call call = new Call(service);			
+			
+			//call.setTransport(new HTTPTransport());
+			call.setTargetEndpointAddress(endpoint) ; 
+			call.setOperationName(new QName("hello")) ;
+			
+			String username = "testuser";
+			String password = "testpasswd";
+			
+			//WSS4J WSDoAllSender's invoke() method expects username not to be empty before the agent takes over 
+			// to set it so we set it to the WSDL location here (that is used as keystore alias) and later on overwrite it 
+			call.setProperty(Call.USERNAME_PROPERTY, "testuser");
+			call.setProperty(Call.PASSWORD_PROPERTY, "testpasswd");
+					
+			
+			// Set HTTP Basic AuthN
+//			MessageContext context = call.getMessageContext();
+//			Hashtable headers = (Hashtable) context
+//					.getProperty(HTTPConstants.REQUEST_HEADERS);
+//			if (headers == null) {
+//				headers = new Hashtable();
+//				context.setProperty(HTTPConstants.REQUEST_HEADERS, headers);
+//			}
+////			String authorization = Base64.encode(("hudsonadmin" + ":"
+////					+ "ch33se").getBytes());
+//			String authorization = Base64.encode((username + ":"
+//					+ password).getBytes());
+//			headers.put("Authorization", "Basic " + authorization);
+//			System.out.println("HTTP Authorization header: "
+//					+ headers.get("Authorization"));
+//			HTTPSender http = new HTTPSender();
+//			
+//			Transport transport = call.getTransportForProtocol("https");
+//			System.out.println(transport.getClass());
+//			
+			
+			
+		
+			String nickName = "Beauty" ; 
+			System.out.println("Sent: '" + nickName + "'") ; 
+			String ret = (String) call.invoke(new Object[] {nickName}) ;
+			System.out.println("Got: '" + ret + "'") ; 
+			assertEquals(ret, "Hello Beauty!");
+	} 
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/77704689/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/AddXMLSplitterEditTest.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/AddXMLSplitterEditTest.java b/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/AddXMLSplitterEditTest.java
new file mode 100644
index 0000000..4e31fcd
--- /dev/null
+++ b/taverna-wsdl-activity/src/test/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/AddXMLSplitterEditTest.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * 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.t2.activities.wsdl.xmlsplitter;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import net.sf.taverna.t2.activities.testutils.LocationConstants;
+import net.sf.taverna.t2.activities.wsdl.WSDLActivity;
+import net.sf.taverna.t2.workflowmodel.Edits;
+import net.sf.taverna.t2.workflowmodel.Processor;
+import net.sf.taverna.t2.workflowmodel.impl.DataflowImpl;
+import net.sf.taverna.t2.workflowmodel.impl.EditsImpl;
+import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class AddXMLSplitterEditTest implements LocationConstants {
+
+	private static final JsonNodeFactory JSON_NODE_FACTORY = JsonNodeFactory.instance;
+
+	private WSDLActivity activity;
+	private DataflowImpl dataflow;
+	private ObjectNode configBean;
+	private static ObjectNode operationConfigBean;
+	private String wsdlLocation = WSDL_TEST_BASE
+	+ "eutils/eutils_lite.wsdl";
+	private Edits edits;
+
+	@Ignore("Integration test")
+	@Before
+	public void setUp() throws Exception {
+		activity = new WSDLActivity(null);
+		configBean = JSON_NODE_FACTORY.objectNode();
+		operationConfigBean = configBean.objectNode();
+		configBean.put("operation", operationConfigBean);
+		operationConfigBean.put("name", "run_eInfo");
+		operationConfigBean.put("wsdl", wsdlLocation);
+		activity.configure(configBean);
+		edits = new EditsImpl();
+
+		dataflow = (DataflowImpl)edits.createDataflow();
+		Processor p=edits.createProcessor("run_eInfo");
+		edits.getDefaultDispatchStackEdit(p).doEdit();
+		edits.getAddActivityEdit(p, activity).doEdit();
+		edits.getMapProcessorPortsForActivityEdit(p).doEdit();
+		edits.getAddProcessorEdit(dataflow, p).doEdit();
+
+	}
+
+	@Ignore("Integration test")
+	@Test
+	public void testAddOutputSplitterToWSDLActivity() throws Exception {
+		AddXMLSplitterEdit edit = new AddXMLSplitterEdit(dataflow,activity,"parameters",false, new EditsImpl());
+		edit.doEdit();
+		assertEquals("The workflow should now contain 2 services",2,dataflow.getProcessors().size());
+		Processor processor=null;
+		for (Processor p : dataflow.getProcessors()) {
+			if (p.getLocalName().equals("parametersXML")) {
+				processor = p;
+				break;
+			}
+		}
+		assertNotNull("There should be a processor named parametersXML",processor);
+		assertEquals("There should be 1 activity",1,processor.getActivityList().size());
+
+		assertEquals("The processor should have 3 output ports",3,processor.getOutputPorts().size());
+		assertEquals("The processor should have 1 input port",1,processor.getInputPorts().size());
+
+		Activity<?>a = processor.getActivityList().get(0);
+		assertEquals("The activity should have 3 output ports",3,a.getOutputPorts().size());
+		assertEquals("The activity should have 1 input port",1,a.getInputPorts().size());
+
+		assertEquals("There should be 1 datalink",1,dataflow.getLinks().size());
+	}
+
+	@Ignore("Integration test")
+	@Test
+	public void testUndo() throws Exception {
+		AddXMLSplitterEdit edit = new AddXMLSplitterEdit(dataflow,activity,"parameters",false, new EditsImpl());
+		edit.doEdit();
+		edit.undo();
+		assertEquals("There should be only 1 processor",1,dataflow.getProcessors().size());
+		assertEquals("The processor should be called run_eInfo","run_eInfo",dataflow.getProcessors().get(0).getLocalName());
+		assertEquals("There should be no datalinks",0,dataflow.getLinks().size());
+	}
+
+	@Ignore("Integration test")
+	@Test
+	public void testAddInputSplitterToWSDLActivity() throws Exception {
+		AddXMLSplitterEdit edit = new AddXMLSplitterEdit(dataflow,activity,"parameters",true, new EditsImpl());
+		edit.doEdit();
+		assertEquals("The workflow should now contain 2 services",2,dataflow.getProcessors().size());
+		Processor processor=null;
+		for (Processor p : dataflow.getProcessors()) {
+			if (p.getLocalName().equals("parametersXML")) {
+				processor = p;
+				break;
+			}
+		}
+		assertNotNull("There should be a processor named parametersXML",processor);
+		assertEquals("There should be 1 activity",1,processor.getActivityList().size());
+		assertEquals("THe processor should have 3 input ports",3,processor.getInputPorts().size());
+		assertEquals("THe processor should have 1 output port",1,processor.getOutputPorts().size());
+
+		Activity<?>a = processor.getActivityList().get(0);
+
+		assertEquals("The activity should have 3 input ports",3,a.getInputPorts().size());
+		assertEquals("The activity 1 output port",1,a.getOutputPorts().size());
+
+		assertEquals("There should be 1 datalink",1,dataflow.getLinks().size());
+	}
+
+}