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

[33/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/WSDLActivity.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivity.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivity.java
new file mode 100644
index 0000000..763cbee
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivity.java
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ * 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 java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.SocketTimeoutException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.wsdl.WSDLException;
+import javax.xml.parsers.ParserConfigurationException;
+
+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.security.credentialmanager.CredentialManager;
+import net.sf.taverna.t2.workflowmodel.OutputPort;
+import net.sf.taverna.t2.workflowmodel.health.RemoteHealthChecker;
+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.ActivityOutputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.AsynchronousActivityCallback;
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+import net.sf.taverna.wsdl.parser.UnknownOperationException;
+import net.sf.taverna.wsdl.parser.WSDLParser;
+
+import org.apache.log4j.Logger;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * An asynchronous Activity that is concerned with WSDL based web-services.
+ * <p>
+ * The activity is configured according to the WSDL location and the operation.<br>
+ * The ports are defined dynamically according to the WSDL specification, and in
+ * addition an output<br>
+ * port <em>attachmentList</em> is added to represent any attachements that are
+ * returned by the webservice.
+ * </p>
+ *
+ * @author Stuart Owen
+ * @author Stian Soiland-Reyes
+ */
+public class WSDLActivity extends
+		AbstractAsynchronousActivity<JsonNode> implements
+		InputPortTypeDescriptorActivity, OutputPortTypeDescriptorActivity {
+
+	public static final String URI = "http://ns.taverna.org.uk/2010/activity/wsdl";
+
+	public static final String ENDPOINT_REFERENCE = "EndpointReference";
+	private JsonNode configurationBean;
+	private WSDLParser parser;
+//	private Map<String, Integer> outputDepth = new HashMap<String, Integer>();
+	private boolean isWsrfService = false;
+//	private String endpointReferenceInputPortName;
+	private CredentialManager credentialManager;
+
+	public WSDLActivity(CredentialManager credentialManager) {
+		this.credentialManager = credentialManager;
+	}
+
+	public boolean isWsrfService() {
+		return isWsrfService;
+	}
+
+	private static Logger logger = Logger.getLogger(WSDLActivity.class);
+
+	/**
+	 * Configures the activity according to the information passed by the
+	 * configuration bean.<br>
+	 * During this process the WSDL is parsed to determine the input and output
+	 * ports.
+	 *
+	 * @param bean
+	 *            the {@link WSDLActivityConfigurationBean} configuration bean
+	 */
+	@Override
+	public void configure(JsonNode bean)
+			throws ActivityConfigurationException {
+		this.configurationBean = bean;
+		try {
+			parseWSDL();
+		} catch (Exception ex) {
+			throw new ActivityConfigurationException(
+					"Unable to parse the WSDL " + bean.get("operation").get("wsdl").textValue(), ex);
+		}
+	}
+
+	@Override
+	public JsonNode getConfiguration() {
+		return configurationBean;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @seenet.sf.taverna.t2.activities.wsdl.InputPortTypeDescriptorActivity#
+	 * getTypeDescriptorForInputPort(java.lang.String)
+	 */
+	public TypeDescriptor getTypeDescriptorForInputPort(String portName)
+			throws UnknownOperationException, IOException {
+		List<TypeDescriptor> inputDescriptors = parser
+				.getOperationInputParameters(configurationBean.get("operation").get("name").textValue());
+		TypeDescriptor result = null;
+		for (TypeDescriptor descriptor : inputDescriptors) {
+			if (descriptor.getName().equals(portName)) {
+				result = descriptor;
+				break;
+			}
+		}
+		return result;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @seenet.sf.taverna.t2.activities.wsdl.InputPortTypeDescriptorActivity#
+	 * getTypeDescriptorsForInputPorts()
+	 */
+	public Map<String, TypeDescriptor> getTypeDescriptorsForInputPorts()
+			throws UnknownOperationException, IOException {
+		Map<String, TypeDescriptor> descriptors = new HashMap<String, TypeDescriptor>();
+		List<TypeDescriptor> inputDescriptors = parser
+				.getOperationInputParameters(configurationBean.get("operation").get("name").textValue());
+		for (TypeDescriptor descriptor : inputDescriptors) {
+			descriptors.put(descriptor.getName(), descriptor);
+		}
+		return descriptors;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @seenet.sf.taverna.t2.activities.wsdl.OutputPortTypeDescriptorActivity#
+	 * getTypeDescriptorForOutputPort(java.lang.String)
+	 */
+	public TypeDescriptor getTypeDescriptorForOutputPort(String portName)
+			throws UnknownOperationException, IOException {
+		TypeDescriptor result = null;
+		List<TypeDescriptor> outputDescriptors = parser
+				.getOperationOutputParameters(configurationBean.get("operation").get("name").textValue());
+		for (TypeDescriptor descriptor : outputDescriptors) {
+			if (descriptor.getName().equals(portName)) {
+				result = descriptor;
+				break;
+			}
+		}
+		return result;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @seenet.sf.taverna.t2.activities.wsdl.OutputPortTypeDescriptorActivity#
+	 * getTypeDescriptorsForOutputPorts()
+	 */
+	public Map<String, TypeDescriptor> getTypeDescriptorsForOutputPorts()
+			throws UnknownOperationException, IOException {
+		Map<String, TypeDescriptor> descriptors = new HashMap<String, TypeDescriptor>();
+		List<TypeDescriptor> inputDescriptors = parser
+				.getOperationOutputParameters(configurationBean.get("operation").get("name").textValue());
+		for (TypeDescriptor descriptor : inputDescriptors) {
+			descriptors.put(descriptor.getName(), descriptor);
+		}
+		return descriptors;
+	}
+
+	private void parseWSDL() throws ParserConfigurationException,
+			WSDLException, IOException, SAXException, UnknownOperationException {
+		String wsdlLocation = configurationBean.get("operation").get("wsdl").textValue();
+		URLConnection connection = null;
+		try {
+			URL wsdlURL = new URL(wsdlLocation);
+			connection = wsdlURL.openConnection();
+			connection.setConnectTimeout(RemoteHealthChecker.getTimeoutInSeconds() * 1000);
+			connection.connect();
+		} catch (MalformedURLException e) {
+			throw new IOException("Malformed URL", e);
+		} catch (SocketTimeoutException e) {
+			throw new IOException("Timeout", e);
+		} catch (IOException e) {
+			throw e;
+		} finally {
+			if ((connection != null) && (connection.getInputStream() != null)) {
+				connection.getInputStream().close();
+			}
+		}
+		parser = new WSDLParser(wsdlLocation);
+		isWsrfService = parser.isWsrfService();
+	}
+
+	@Override
+	public void executeAsynch(final Map<String, T2Reference> data,
+			final AsynchronousActivityCallback callback) {
+
+		callback.requestRun(new Runnable() {
+
+			public void run() {
+
+				ReferenceService referenceService = callback.getContext()
+						.getReferenceService();
+
+				Map<String, T2Reference> outputData = new HashMap<String, T2Reference>();
+				Map<String, Object> invokerInputMap = new HashMap<String, Object>();
+				String endpointReferenceInputPortName = getEndpointReferenceInputPortName();
+
+				try {
+					String endpointReference = null;
+					for (String key : data.keySet()) {
+						Object renderIdentifier = referenceService
+								.renderIdentifier(data.get(key), String.class,
+										callback.getContext());
+						if (isWsrfService()
+								&& key.equals(endpointReferenceInputPortName)) {
+							endpointReference = (String) renderIdentifier;
+						} else {
+							invokerInputMap.put(key, renderIdentifier);
+						}
+					}
+					List<String> outputNames = new ArrayList<String>();
+					for (OutputPort port : getOutputPorts()) {
+						outputNames.add(port.getName());
+					}
+
+					T2WSDLSOAPInvoker invoker = new T2WSDLSOAPInvoker(parser,
+							configurationBean.get("operation").get("name").textValue(), outputNames,
+							endpointReference, credentialManager);
+
+					Map<String, Object> invokerOutputMap = invoker.invoke(
+							invokerInputMap, configurationBean);
+					
+					for (String outputName : invokerOutputMap.keySet()) {
+					    Object value = invokerOutputMap.get(outputName);
+						
+						if (value != null) {
+							Integer depth = getOutputPortDepth(outputName);
+							if (depth != null) {
+								outputData.put(outputName, referenceService
+										.register(value, depth, true, callback
+												.getContext()));
+							} else {
+								logger.info("Skipping unknown output port :"
+												+ outputName);
+//								// TODO what should the depth be in this case?
+//								outputData.put(outputName, referenceService
+//										.register(value, 0, true, callback
+//												.getContext()));
+							}
+						}
+					}
+					callback.receiveResult(outputData, new int[0]);
+				} catch (ReferenceServiceException e) {
+					logger.error("Error finding the input data for "
+							+ getConfiguration().get("operation"), e);
+					callback.fail("Unable to find input data", e);
+					return;
+				} catch (Exception e) {
+					logger.error("Error invoking WSDL service "
+							+ getConfiguration().get("operation"), e);
+					callback.fail(
+							"An error occurred invoking the WSDL service", e);
+					return;
+				}
+
+			}
+
+		});
+
+	}
+
+	private Integer getOutputPortDepth(String portName) {
+		for (ActivityOutputPort outputPort : getOutputPorts()) {
+			if (outputPort.getName().equals(portName)) {
+				return outputPort.getDepth();
+			}
+		}
+		return null;
+	}
+
+	private String getEndpointReferenceInputPortName() {
+		String endpointReferenceInputPortName = null;
+		if (parser.isWsrfService()) {
+			Set<String> inputPorts = new HashSet<>();
+			try {
+				List<TypeDescriptor> inputDescriptors = parser.getOperationInputParameters(configurationBean
+						.get("operation").get("name").textValue());
+				for (TypeDescriptor descriptor : inputDescriptors) {
+					inputPorts.add(descriptor.getName());
+				}
+			} catch (UnknownOperationException | IOException e) {
+			}
+			// Make sure the port name is unique
+			endpointReferenceInputPortName = WSDLActivity.ENDPOINT_REFERENCE;
+			int counter = 0;
+			while (inputPorts.contains(endpointReferenceInputPortName)) {
+				endpointReferenceInputPortName = WSDLActivity.ENDPOINT_REFERENCE + counter++;
+			}
+		}
+		return endpointReferenceInputPortName;
+	}
+
+}

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/WSDLActivityConfigurationBean.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityConfigurationBean.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityConfigurationBean.java
new file mode 100644
index 0000000..80b0bd5
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityConfigurationBean.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * 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 java.net.URI;
+
+import net.sf.taverna.t2.workflowmodel.processor.config.ConfigurationBean;
+import net.sf.taverna.t2.workflowmodel.processor.config.ConfigurationProperty;
+
+/**
+ * A standard Java Bean that provides the details required to configure a WSDLActivity.
+ * <p>
+ * This contains details about the WSDL and the Operation that the WSDLActivity is intended to invoke.
+ * </p>
+ * @author Stuart Owen
+ */
+@ConfigurationBean(uri = WSDLActivity.URI + "#Config")
+public class WSDLActivityConfigurationBean {
+    private WSDLOperationConfigurationBean operation;
+    private URI securityProfile;
+
+    // In the case service requires username and password for authentication,
+    // but do not serialise these variables to file
+    //transient private String username;
+    //transient private String password;
+
+    /** Creates a new instance of WSDLActivityConfigurationBean */
+    public WSDLActivityConfigurationBean() {
+    }
+
+    public WSDLOperationConfigurationBean getOperation() {
+        return operation;
+    }
+
+	@ConfigurationProperty(name = "operation", label = "WSDL Operation", description = "The WSDL operation")
+    public void setOperation(WSDLOperationConfigurationBean operation) {
+        this.operation = operation;
+    }
+
+	public URI getSecurityProfile() {
+		return securityProfile;
+	}
+
+	@ConfigurationProperty(name = "securityProfile", label = "Security Profile", description = "WS-Security settings required by the web service", required = false)
+	public void setSecurityProfile(URI securityProfile) {
+		this.securityProfile = securityProfile;
+	}
+
+//	public void setUsername(String username) {
+//		this.username = username;
+//	}
+//
+//	public String getUsername() {
+//		return username;
+//	}
+//
+//	public void setPassword(String password) {
+//		this.password = password;
+//	}
+//
+//	public String getPassword() {
+//		return password;
+//	}
+}

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/WSDLActivityDescriptorChecker.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityDescriptorChecker.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityDescriptorChecker.java
new file mode 100644
index 0000000..5a41cde
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityDescriptorChecker.java
@@ -0,0 +1,147 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.activities.wsdl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import net.sf.taverna.t2.visit.VisitReport;
+import net.sf.taverna.t2.visit.VisitReport.Status;
+import net.sf.taverna.t2.workflowmodel.Dataflow;
+import net.sf.taverna.t2.workflowmodel.Datalink;
+import net.sf.taverna.t2.workflowmodel.Merge;
+import net.sf.taverna.t2.workflowmodel.MergeInputPort;
+import net.sf.taverna.t2.workflowmodel.MergeOutputPort;
+import net.sf.taverna.t2.workflowmodel.MergePort;
+import net.sf.taverna.t2.workflowmodel.Port;
+import net.sf.taverna.t2.workflowmodel.Processor;
+import net.sf.taverna.t2.workflowmodel.ProcessorInputPort;
+import net.sf.taverna.t2.workflowmodel.ProcessorPort;
+import net.sf.taverna.t2.workflowmodel.health.HealthCheck;
+import net.sf.taverna.t2.workflowmodel.health.HealthChecker;
+import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityInputPort;
+import net.sf.taverna.t2.workflowmodel.utils.Tools;
+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 org.apache.log4j.Logger;
+
+/**
+ * @author alanrw
+ *
+ */
+public final class WSDLActivityDescriptorChecker implements HealthChecker<InputPortTypeDescriptorActivity> {
+
+	private static Logger logger = Logger.getLogger(WSDLActivityDescriptorChecker.class);
+
+	public boolean canVisit(Object o) {
+		return ((o != null) && (o instanceof InputPortTypeDescriptorActivity));
+	}
+
+	public boolean isTimeConsuming() {
+		return false;
+	}
+
+	public VisitReport visit(InputPortTypeDescriptorActivity o,
+			List<Object> ancestry) {
+		List<VisitReport> reports = new ArrayList<VisitReport>();
+		try {
+			Map<String, TypeDescriptor> typeMap = o.getTypeDescriptorsForInputPorts();
+			Processor p = (Processor) VisitReport.findAncestor(ancestry, Processor.class);
+			Dataflow d = (Dataflow) VisitReport.findAncestor(ancestry, Dataflow.class);
+
+
+			for (Entry<String, TypeDescriptor> entry : typeMap.entrySet()) {
+				TypeDescriptor descriptor = entry.getValue();
+				if (!descriptor.getMimeType().contains("'text/xml'")) {
+					continue;
+				}
+				if (!((descriptor instanceof ArrayTypeDescriptor) || (descriptor instanceof ComplexTypeDescriptor))) {
+					continue;
+				}
+				// Find the processor port, if any that corresponds to the activity port
+				ActivityInputPort aip = Tools.getActivityInputPort((Activity<?>) o, entry.getKey());
+				if (aip == null) {
+					continue;
+				}
+				ProcessorInputPort pip = Tools.getProcessorInputPort(p, (Activity<?>) o, aip);
+
+				if (pip == null) {
+					continue;
+				}
+
+				for (Datalink dl : d.getLinks()) {
+
+					if (dl.getSink().equals(pip)) {
+						Port source = dl.getSource();
+						Set<VisitReport> subReports = checkSource(source, d, (Activity<?>) o, aip);
+						for (VisitReport vr : subReports) {
+						    vr.setProperty("activity", o);
+						    vr.setProperty("sinkPort", pip);
+						}
+						reports.addAll(subReports);
+					}
+				}
+
+			}
+		} catch (UnknownOperationException e) {
+			logger.error("Problem getting type descriptors for activity", e);
+		} catch (IOException e) {
+			logger.error("Problem getting type descriptors for activity", e);
+		} catch (NullPointerException e) {
+			logger.error("Problem getting type desciptors for activity", e);
+		}
+		if (reports.isEmpty()) {
+			return null;
+		}
+		if (reports.size() == 1) {
+			return reports.get(0);
+		}
+		else {
+			return new VisitReport(HealthCheck.getInstance(), o, "Collation", HealthCheck.DEFAULT_VALUE, reports);
+		}
+	}
+
+	private Set<VisitReport> checkSource(Port source, Dataflow d, Activity<?> o, ActivityInputPort aip) {
+		Set<VisitReport> reports = new HashSet<VisitReport>();
+		if (source instanceof ProcessorPort) {
+			ProcessorPort processorPort = (ProcessorPort) source;
+			Processor sourceProcessor = processorPort.getProcessor();
+			Activity<?> sourceActivity = sourceProcessor.getActivityList().get(0);
+			if (!(sourceActivity instanceof InputPortTypeDescriptorActivity)) {
+				VisitReport newReport = new VisitReport(HealthCheck.getInstance(), o, "Source of " + aip.getName(), HealthCheck.DATATYPE_SOURCE, Status.WARNING);
+				newReport.setProperty("sinkPortName", aip.getName());
+				newReport.setProperty("sourceName", sourceProcessor.getLocalName());
+				newReport.setProperty("isProcessorSource", "true");
+				reports.add(newReport);
+			}
+		} else if (source instanceof MergeOutputPort) {
+			Merge merge = ((MergePort) source).getMerge();
+			for (MergeInputPort mip : merge.getInputPorts()) {
+				for (Datalink dl : d.getLinks()) {
+					if (dl.getSink().equals(mip)) {
+						reports.addAll(checkSource(dl.getSource(), d, o, aip));
+					}
+				}
+
+			}
+		} else /* if (source instanceof DataflowInputPort) */  {
+			VisitReport newReport = new VisitReport(HealthCheck.getInstance(), o, "Source of " + aip.getName(), HealthCheck.DATATYPE_SOURCE, Status.WARNING);
+			newReport.setProperty("sinkPortName", aip.getName());
+			newReport.setProperty("sourceName", source.getName());
+			newReport.setProperty("isProcessorSource", "false");
+			reports.add(newReport);
+		}
+		return reports;
+	}
+
+}

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/WSDLActivityFactory.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityFactory.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityFactory.java
new file mode 100644
index 0000000..eeb7c5a
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityFactory.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * 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 java.io.IOException;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.wsdl.WSDLException;
+import javax.xml.parsers.ParserConfigurationException;
+
+import net.sf.taverna.t2.security.credentialmanager.CredentialManager;
+import net.sf.taverna.t2.workflowmodel.Edits;
+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 net.sf.taverna.wsdl.parser.TypeDescriptor;
+import net.sf.taverna.wsdl.parser.UnknownOperationException;
+import net.sf.taverna.wsdl.parser.WSDLParser;
+
+import org.apache.log4j.Logger;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * An {@link ActivityFactory} for creating <code>WSDLActivity</code>.
+ *
+ * @author David Withers
+ */
+public class WSDLActivityFactory implements ActivityFactory {
+
+	private static Logger logger = Logger.getLogger(WSDLActivityFactory.class);
+
+	private CredentialManager credentialManager;
+	private Edits edits;
+
+	@Override
+	public WSDLActivity createActivity() {
+		return new WSDLActivity(credentialManager);
+	}
+
+	@Override
+	public URI getActivityType() {
+		return URI.create(WSDLActivity.URI);
+	}
+
+	@Override
+	public JsonNode getActivityConfigurationSchema() {
+		ObjectMapper objectMapper = new ObjectMapper();
+		try {
+			return objectMapper.readTree(getClass().getResource("/schema.json"));
+		} catch (IOException e) {
+			return objectMapper.createObjectNode();
+		}
+	}
+
+	public void setCredentialManager(CredentialManager credentialManager) {
+		this.credentialManager = credentialManager;
+	}
+
+	@Override
+	public Set<ActivityInputPort> getInputPorts(JsonNode configuration) {
+		Map<String, ActivityInputPort> inputPorts = new HashMap<>();
+		try {
+			WSDLParser parser = new WSDLParser(configuration.get("operation").get("wsdl").textValue());
+			List<TypeDescriptor> inputDescriptors = parser.getOperationInputParameters(configuration
+					.get("operation").get("name").textValue());
+			for (TypeDescriptor descriptor : inputDescriptors) {
+				inputPorts.put(descriptor.getName(), edits.createActivityInputPort(
+						descriptor.getName(), descriptor.getDepth(), true, null, String.class));
+			}
+			if (parser.isWsrfService()) {
+				// Make sure the port name is unique
+				String endpointReferenceInputPortName = WSDLActivity.ENDPOINT_REFERENCE;
+				int counter = 0;
+				while (inputPorts.containsKey(endpointReferenceInputPortName)) {
+					endpointReferenceInputPortName = WSDLActivity.ENDPOINT_REFERENCE + counter++;
+				}
+				inputPorts.put(endpointReferenceInputPortName, edits.createActivityInputPort(
+						endpointReferenceInputPortName, 0, true, null, String.class));
+			}
+		} catch (ParserConfigurationException | WSDLException | IOException | SAXException | UnknownOperationException e) {
+			logger.warn(
+					"Unable to parse the WSDL " + configuration.get("operation").get("wsdl").textValue(), e);
+		}
+
+		return new HashSet<>(inputPorts.values());
+	}
+
+	@Override
+	public Set<ActivityOutputPort> getOutputPorts(JsonNode configuration) {
+		Set<ActivityOutputPort> outputPorts = new HashSet<>();
+		try {
+			WSDLParser parser = new WSDLParser(configuration.get("operation").get("wsdl")
+					.textValue());
+			List<TypeDescriptor> outputDescriptors = parser
+					.getOperationOutputParameters(configuration.get("operation").get("name")
+							.textValue());
+			for (TypeDescriptor descriptor : outputDescriptors) {
+				outputPorts.add(edits.createActivityOutputPort(descriptor.getName(),
+						descriptor.getDepth(), descriptor.getDepth()));
+			}
+			// add output for attachment list
+			outputPorts.add(edits.createActivityOutputPort("attachmentList", 1, 1));
+		} catch (ParserConfigurationException | WSDLException | IOException | SAXException | UnknownOperationException e) {
+			logger.warn(
+					"Unable to parse the WSDL " + configuration.get("operation").get("wsdl").textValue(), e);
+		}
+
+		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/WSDLActivityHealthChecker.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityHealthChecker.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityHealthChecker.java
new file mode 100644
index 0000000..0437ff6
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLActivityHealthChecker.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * 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 java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.wsdl.WSDLException;
+import javax.xml.parsers.ParserConfigurationException;
+
+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.RemoteHealthChecker;
+import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
+import net.sf.taverna.t2.workflowmodel.processor.activity.DisabledActivity;
+import net.sf.taverna.wsdl.parser.UnknownOperationException;
+import net.sf.taverna.wsdl.parser.WSDLParser;
+
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+public class WSDLActivityHealthChecker extends RemoteHealthChecker {
+
+	private Activity<?> activity;
+
+	public boolean canVisit(Object subject) {
+		if (subject == null) {
+			return false;
+		}
+		if (subject instanceof WSDLActivity) {
+			return true;
+		}
+		if (subject instanceof DisabledActivity) {
+			return (((DisabledActivity) subject).getActivity() instanceof WSDLActivity);
+		}
+		return false;
+	}
+
+	public VisitReport visit(Object o, List<Object> ancestors) {
+		List<VisitReport> reports = new ArrayList<VisitReport>();
+		activity = (Activity<?>) o;
+		String endpoint = null;
+
+		WSDLParser parser;
+		try {
+			JsonNode configuration = null;
+			if (activity instanceof WSDLActivity) {
+				configuration = ((WSDLActivity)activity).getConfiguration();
+			} else if (activity instanceof DisabledActivity) {
+				configuration = (JsonNode) ((DisabledActivity) activity).getActivityConfiguration();
+			}
+			endpoint = configuration.get("operation").get("wsdl").asText();
+			VisitReport wsdlEndpointReport = RemoteHealthChecker.contactEndpoint(activity, endpoint);
+			reports.add(wsdlEndpointReport);
+			if (!wsdlEndpointReport.getStatus().equals(Status.SEVERE)) {
+			    parser = new WSDLParser(endpoint);
+
+			    String operationName = configuration.get("operation").get("name").asText();
+			    try {
+                reports.add(testStyleAndUse(endpoint,
+							    parser,
+							    operationName));
+				reports.add(testEndpoint(parser, operationName));
+			    } catch (UnknownOperationException e) {
+				VisitReport vr = new VisitReport(HealthCheck.getInstance(), activity,
+							 "Operation not found", HealthCheck.UNKNOWN_OPERATION,
+							 Status.SEVERE);
+				vr.setProperty("operationName", operationName);
+				vr.setProperty("endpoint", endpoint);
+				reports.add(vr);
+			    }
+			}
+
+		} catch (ParserConfigurationException e) {
+			VisitReport vr = new VisitReport(HealthCheck.getInstance(), activity, "Invalid WSDL", HealthCheck.BAD_WSDL, Status.SEVERE);
+			vr.setProperty("exception", e);
+			vr.setProperty("endpoint", endpoint);
+			reports.add(vr);
+		} catch (WSDLException e) {
+			VisitReport vr = new VisitReport(HealthCheck.getInstance(), activity, "Invalid WSDL", HealthCheck.BAD_WSDL, Status.SEVERE);
+			vr.setProperty("exception", e);
+			vr.setProperty("endpoint", endpoint);
+			reports.add(vr);
+		} catch (IOException e) {
+			VisitReport vr = new VisitReport(HealthCheck.getInstance(), activity, "Read problem", HealthCheck.IO_PROBLEM, Status.SEVERE);
+			vr.setProperty("exception", e);
+			vr.setProperty("endpoint", endpoint);
+			reports.add(vr);
+		} catch (SAXException e) {
+			VisitReport vr = new VisitReport(HealthCheck.getInstance(), activity, "Invalid WSDL", HealthCheck.BAD_WSDL, Status.SEVERE);
+			vr.setProperty("exception", e);
+			vr.setProperty("endpoint", endpoint);
+			reports.add(vr);
+		}
+
+		Status status = VisitReport.getWorstStatus(reports);
+		VisitReport report = new VisitReport(HealthCheck.getInstance(), activity, "WSDL Activity report", HealthCheck.NO_PROBLEM,
+				status, reports);
+
+		return report;
+	}
+	
+	public static boolean checkStyleAndUse(String style, String use) {
+		return !(style.equalsIgnoreCase("rpc") && use.equalsIgnoreCase("literal"));
+	}
+
+	private VisitReport testStyleAndUse(String endpoint, WSDLParser parser, String operationName) throws
+                UnknownOperationException {
+		VisitReport report;
+		String style = parser.getStyle().toLowerCase();
+		String use = "?";
+		use = parser.getUse(operationName).toLowerCase();
+		if (!checkStyleAndUse(style, use)) {
+		    report = new VisitReport(HealthCheck.getInstance(), activity,
+					     "Unsupported style", HealthCheck.UNSUPPORTED_STYLE,
+					     Status.SEVERE);
+		    report.setProperty("use", use);
+		    report.setProperty("style", style);
+		    report.setProperty("endpoint", endpoint);
+		} else {
+		    report = new VisitReport(HealthCheck.getInstance(), activity, style + "/"
+					     + use + " is OK", HealthCheck.NO_PROBLEM, Status.OK);
+		}
+		return report;
+	}
+
+	private VisitReport testEndpoint(WSDLParser parser, String operationName) {
+		List<VisitReport> reports = new ArrayList<VisitReport>();
+		List<String> endpoints = parser
+				.getOperationEndpointLocations(operationName);
+		for (String endpoint : endpoints) {
+			reports.add(RemoteHealthChecker.contactEndpoint(activity, endpoint));
+		}
+
+		Status status = VisitReport.getWorstStatus(reports);
+		if (reports.size()==1) {
+			return reports.get(0);
+		}
+		else if (reports.size()==0) {
+		    VisitReport report = new VisitReport(HealthCheck.getInstance(), activity, "Service could not be located.", HealthCheck.NO_ENDPOINTS, Status.SEVERE);
+		    report.setProperty("operationName", operationName);
+		    return report;
+		}
+		else {
+			return new VisitReport(HealthCheck.getInstance(), activity, "Endpoint tests",  HealthCheck.NO_PROBLEM, status, reports);
+		}
+	}
+
+}

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/WSDLOperationConfigurationBean.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLOperationConfigurationBean.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLOperationConfigurationBean.java
new file mode 100644
index 0000000..ac012ae
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/WSDLOperationConfigurationBean.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (C) 2011 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 java.net.URI;
+
+import net.sf.taverna.t2.workflowmodel.processor.config.ConfigurationBean;
+import net.sf.taverna.t2.workflowmodel.processor.config.ConfigurationProperty;
+
+/**
+ * Configuration for a WSDL operation.
+ *
+ * @author David Withers
+ */
+@ConfigurationBean(uri = WSDLActivity.URI + "/operation")
+public class WSDLOperationConfigurationBean {
+
+	private URI wsdl;
+	private String operationName;
+
+	public URI getWsdl() {
+		return wsdl;
+	}
+
+	@ConfigurationProperty(name = "wsdl", label = "WSDL URL", description = "The location of the WSDL definition for the web service")
+	public void setWsdl(URI wsdl) {
+		this.wsdl = wsdl;
+	}
+
+	public String getOperationName() {
+		return operationName;
+	}
+
+	@ConfigurationProperty(name = "name", label = "Operation Name", description = "The name of the WSDL operation")
+	public void setOperationName(String operationName) {
+		this.operationName = operationName;
+	}
+
+}

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/package.html
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/package.html b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/package.html
new file mode 100644
index 0000000..e38a14e
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/package.html
@@ -0,0 +1,3 @@
+<body>
+Contains the activity classes required to interact with a WSDL based web-service.
+</body>
\ 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/java/net/sf/taverna/t2/activities/wsdl/security/SSLUtilities.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/SSLUtilities.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/SSLUtilities.java
new file mode 100644
index 0000000..69033bb
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/SSLUtilities.java
@@ -0,0 +1,151 @@
+package net.sf.taverna.t2.activities.wsdl.security;
+
+import java.security.GeneralSecurityException;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * This class provide various static methods that relax X509 certificate and 
+ * hostname verification while using the SSL over the HTTP protocol.
+ * <p>
+ * Call:
+ * SSLUtilities.trustAllHostnames() to turn off the default hostname verification on HTTPS connection;
+ * SSLUtilities.trustAllHttpsCertificates() to turn off the default certificate validation on HTTPS connection.
+ * SSLUtilities.stopTrustingAllHttpsCertificates() to stop trusting all hosts' certificates and go back to default Java settings.
+ *
+ * @author    Francis Labrie
+ */
+public final class SSLUtilities {
+
+  /**
+   * Hostname verifier.
+   */
+  private static HostnameVerifier hostnameVerifier;
+  /**
+   * Thrust managers.
+   */
+  private static TrustManager[] trustManagers;
+
+  /**
+   * Set the default Hostname Verifier to an instance of a fake class that 
+   * trust all hostnames.
+   */
+  public static void trustAllHostnames() {
+      // Create a trust manager that does not validate certificate chains
+      if(hostnameVerifier == null) {
+          hostnameVerifier = new FakeHostnameVerifier();
+      } // if
+        // Install the all-trusting host name verifier:
+      HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
+  } // _trustAllHttpsCertificates
+  
+  /**
+   * Set the default X509 Trust Manager to an instance of a fake class that 
+   * trust all certificates, even the self-signed ones.
+   */
+  public static void trustAllHttpsCertificates() {
+      SSLContext context;
+      
+      // Create a trust manager that does not validate certificate chains
+      if(trustManagers == null) {
+          trustManagers = new TrustManager[] {new FakeX509TrustManager()};
+      } // if
+      // Install the all-trusting trust manager:
+      try {
+      context = SSLContext.getInstance("SSL");
+      context.init(null, trustManagers, new SecureRandom());
+      } catch(GeneralSecurityException gse) {
+          throw new IllegalStateException(gse.getMessage());
+      } // catch
+      HttpsURLConnection.setDefaultSSLSocketFactory(context.
+          getSocketFactory());
+  } // _trustAllHttpsCertificates
+  
+  /**
+   * This class implements a fake hostname verificator, trusting any host 
+   * name.
+   *
+   * @author    Francis Labrie
+   */
+  public static class FakeHostnameVerifier implements HostnameVerifier {
+      
+      /**
+       * Always return true, indicating that the host name is 
+       * an acceptable match with the server's authentication scheme.
+       *
+       * @param hostname        the host name.
+       * @param session         the SSL session used on the connection to 
+       * host.
+       * @return                the true boolean value 
+       * indicating the host name is trusted.
+       */
+      public boolean verify(String hostname, 
+          javax.net.ssl.SSLSession session) {
+          return(true);
+      } // verify
+  } // FakeHostnameVerifier
+
+  /**
+   * This class allow any X509 certificates to be used to authenticate the 
+   * remote side of a secure socket, including self-signed certificates.
+   *
+   * @author    Francis Labrie
+   */
+  public static class FakeX509TrustManager implements X509TrustManager {
+
+      /**
+       * Empty array of certificate authority certificates.
+       */
+      private static final X509Certificate[] _AcceptedIssuers = 
+          new X509Certificate[] {};
+
+      /**
+       * Always trust for client SSL chain peer certificate 
+       * chain with any authType authentication types.
+       *
+       * @param chain           the peer certificate chain.
+       * @param authType        the authentication type based on the client 
+       * certificate.
+       */
+      public void checkClientTrusted(X509Certificate[] chain, 
+          String authType) {
+      } // checkClientTrusted
+      
+      /**
+       * Always trust for server SSL chain peer certificate 
+       * chain with any authType exchange algorithm types.
+       *
+       * @param chain           the peer certificate chain.
+       * @param authType        the key exchange algorithm used.
+       */
+      public void checkServerTrusted(X509Certificate[] chain, 
+          String authType) {
+      } // checkServerTrusted
+      
+      /**
+       * Return an empty array of certificate authority certificates which 
+       * are trusted for authenticating peers.
+       *
+       * @return                a empty array of issuer certificates.
+       */
+      public X509Certificate[] getAcceptedIssuers() {
+          return(_AcceptedIssuers);
+      } // getAcceptedIssuers
+  } // FakeX509TrustManager
+  
+  /**
+   * Stop trusting all certificates and go back to the default settings.
+   * 
+   * @author Alex Nenadic
+   */
+  public static void stopTrustingAllHttpsCertificates(){
+      HttpsURLConnection.setDefaultSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault());
+  }
+} // SSLUtilities
+

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/security/SecurityProfiles.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/SecurityProfiles.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/SecurityProfiles.java
new file mode 100644
index 0000000..aa8084b
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/SecurityProfiles.java
@@ -0,0 +1,130 @@
+package net.sf.taverna.t2.activities.wsdl.security;
+
+import java.net.URI;
+
+import net.sf.taverna.t2.activities.wsdl.WSDLActivity;
+
+/**
+ * Various security profiles for Web services.
+ *
+ * @author Alex Nenadic
+ *
+ */
+public class SecurityProfiles {
+
+	public static URI SECURITY = URI.create(WSDLActivity.URI).resolve("wsdl/security");
+
+	/**
+	  * Security profile for Web services that require
+	 * UsernameToken authentication with plaintext password.
+	 * Such services should typically be invoked over HTTPS.
+	 */
+	public static final URI WSSECURITY_USERNAMETOKEN_PLAINTEXTPASSWORD = SECURITY.resolve("#WSSecurityUsernameTokenPlainTextPassword");
+	/**
+	 * XML string for configuring Axis engine with wss4j handlers to handle setting security
+	 * headers on the SOAP message for profile WSSECURITY_USERNAMETOKEN_PLAINTEXTPASSWORD.
+	 */
+	public static final String WSSECURITY_USERNAMETOKEN_PLAINTEXTPASSWORD_CONFIG = "<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=\"PasswordText\"/>" +
+	"</handler>"+
+	"</requestFlow>" +
+	"</globalConfiguration>" +
+	"<transport name=\"http\" pivot=\"java:org.apache.axis.transport.http.HTTPSender\"/>"+
+	"</deployment>";
+
+	 /**
+	  * Security profile for Web services that require
+	 * UsernameToken authentication with digest password.
+	 * Such services would typically be invoked over HTTPS.
+	 */
+	public static final URI WSSECURITY_USERNAMETOKEN_DIGESTPASSWORD = SECURITY.resolve("#WSSecurityUsernameTokenDigestPassword");
+	/**
+	 * XML string for configuring Axis engine with wss4j handlers to handle setting security
+	 * headers on the SOAP message for profile WSSECURITY_USERNAMETOKEN_DIGESTPASSWORD.
+	 */
+	public static final String WSSECURITY_USERNAMETOKEN_DIGESTPASSWORD_CONFIG = "<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>";
+
+	 /**
+	  * Security profile for Web services that require a timestamp SOAP header
+	  * to be sent in addition to UsernameToken authentication with plaintext password.
+	 * Such services should typically be invoked over HTTPS.
+	 */
+	public static final URI WSSECURITY_TIMESTAMP_USERNAMETOKEN_PLAINTEXTPASSWORD = SECURITY.resolve("#WSSecurityTimestampUsernameTokenPlainTextPassword");
+	/**
+	 * XML string for configuring Axis engine with wss4j handlers to handle setting security
+	 * headers on the SOAP message for profile WSSECURITY_TIMESTAMP_USERNAMETOKEN_DIGESTPASSWORD.
+	 */
+	public static final String WSSECURITY_TIMESTAMP_USERNAMETOKEN_PLAINTETPASSWORD_CONFIG = "<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=\"Timestamp UsernameToken\"/>" +
+	"<parameter name=\"passwordType\" value=\"PasswordText\"/>" +
+	"</handler>"+
+	"</requestFlow>" +
+	"<responseFlow>" +
+	"<handler type=\"java:org.apache.ws.axis.security.WSDoAllReceiver\">" +
+	"<parameter name=\"action\" value=\"Timestamp\"/>" +
+	"</handler>"+
+	"</responseFlow>" +
+	"</globalConfiguration>" +
+	"<transport name=\"http\" pivot=\"java:org.apache.axis.transport.http.HTTPSender\"/>"+
+	"</deployment>";
+
+	 /**
+	  * Security profile for Web services that require a timestamp SOAP header
+	  * to be sent in addition to UsernameToken authentication with digest password.
+	 * Such services would typically be invoked over HTTPS.
+	 */
+	public static final URI WSSECURITY_TIMESTAMP_USERNAMETOKEN_DIGESTPASSWORD = SECURITY.resolve("#WSSecurityTimestampUsernameTokenDigestPassword");
+	/**
+	 * XML string for configuring Axis engine with wss4j handlers to handle setting security
+	 * headers on the SOAP message for profile WSSECURITY_TIMESTAMP_USERNAMETOKEN_DIGESTPASSWORD.
+	 */
+	public static final String WSSECURITY_TIMESTAMP_USERNAMETOKEN_DIGESTPASSWORD_CONFIG = "<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=\"Timestamp UsernameToken\"/>" +
+	"<parameter name=\"passwordType\" value=\"PasswordDigest\"/>" +
+	"</handler>"+
+	"</requestFlow>" +
+	"<responseFlow>" +
+	"<handler type=\"java:org.apache.ws.axis.security.WSDoAllReceiver\">" +
+	"<parameter name=\"action\" value=\"Timestamp\"/>" +
+	"</handler>"+
+	"</responseFlow>" +
+	"</globalConfiguration>" +
+	"<transport name=\"http\" pivot=\"java:org.apache.axis.transport.http.HTTPSender\"/>"+
+	"</deployment>";
+
+	/**
+	 * Security profile for Web services that require HTTP Basic Authentication.
+	 * There is no WS-Security involved.
+	 * Such services should typically be invoked over HTTPS.
+	 */
+	public static final URI HTTP_BASIC_AUTHN = SECURITY.resolve("#HTTPBasicAuthNPlainTextPassword");
+
+	/**
+	 * Security profile for Web services that require HTTP Digest Authentication.
+	 * There is no WS-Security involved.
+	 * Such services would typically be invoked over HTTPS.
+	 */
+	public static final URI HTTP_DIGEST_AUTHN = SECURITY.resolve("#HTTPDigestAuthN");
+
+
+}

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/security/TavernaAxisCustomSSLSocketFactory.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/TavernaAxisCustomSSLSocketFactory.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/TavernaAxisCustomSSLSocketFactory.java
new file mode 100644
index 0000000..19ecb14
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/TavernaAxisCustomSSLSocketFactory.java
@@ -0,0 +1,40 @@
+package net.sf.taverna.t2.activities.wsdl.security;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.Hashtable;
+
+import javax.net.ssl.SSLContext;
+
+import org.apache.axis.components.net.BooleanHolder;
+import org.apache.axis.components.net.JSSESocketFactory;
+
+public class TavernaAxisCustomSSLSocketFactory extends JSSESocketFactory {
+
+
+	public TavernaAxisCustomSSLSocketFactory(Hashtable attributes) {
+		super(attributes);
+	}
+
+	@Override
+	public Socket create(String host, int port, StringBuffer otherHeaders,
+			BooleanHolder useFullURL) throws Exception {
+		// Make sure we always pick up the default socket factory from SSLContext, which is based on 
+		// Taverna's Keystore and Truststore and gets updated when they get updated (it may have
+		// been updated in the menatime so just refresh it here just in case).
+		initFactory();
+		return super.create(host, port, otherHeaders, useFullURL);
+	}
+	
+	@Override
+	protected void initFactory() throws IOException {
+		try{
+			// Set it to the default one from the SSLContext which is set to use Taverna's Keystore and Truststore
+			sslFactory = SSLContext.getDefault().getSocketFactory();
+		}
+		catch (Exception e) {
+			throw new IOException("Could not get the Taverna's default SSLSocketFactory from SSLContext",e);
+		}
+	}
+	
+}

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/security/ThreadLocalSSLSocketFactory.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/ThreadLocalSSLSocketFactory.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/ThreadLocalSSLSocketFactory.java
new file mode 100644
index 0000000..5660cbe
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/security/ThreadLocalSSLSocketFactory.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.security;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.log4j.Logger;
+
+/**
+ * An implementation of SSLSocketFactory which delegates to one of two internal
+ * SSLSocketFactory implementations. The implementation delegated to is
+ * determined by a thread local property and is either the default SSL socket or
+ * a customized one with a trust manager that allows the use of unsigned server
+ * certificates.
+ * <p>
+ * To set this as the default call install() prior to making any HTTPS
+ * connections, then bracket code which needs to trust unsigned certificates in
+ * the startTrustingEverything() and stopTrustingEverything() methods.
+ * 
+ * @author Tom Oinn
+ * 
+ */
+public class ThreadLocalSSLSocketFactory extends SSLSocketFactory {
+
+	private static Logger logger = Logger
+	.getLogger(ThreadLocalSSLSocketFactory.class);
+
+	/**
+	 * Calls to open HTTPS connections will trust unsigned certificates afer
+	 * this call is made, this is scoped to the current thread only.
+	 */
+	public static void startTrustingEverything() {
+		threadLocalFactory.set(createAlwaysTrustingFactory());
+	}
+
+	/**
+	 * Stop trusting unsigned certificates, reverting to the default behaviour
+	 * for the current thread.
+	 */
+	public static void stopTrustingEverything() {
+		threadLocalFactory.set(null);
+	}
+
+	/**
+	 * Set this as the default global socket factory for HTTPS connections
+	 */
+	public static void install() {
+		HttpsURLConnection
+				.setDefaultSSLSocketFactory(new ThreadLocalSSLSocketFactory());
+	}
+
+	/**
+	 * Determine whether the current thread will trust unsigned certificates
+	 */
+	public static boolean isTrustingEverything() {
+		return (threadLocalFactory.get() != null);
+	}
+
+	/**
+	 * Never construct manually
+	 */
+	private ThreadLocalSSLSocketFactory() {
+		super();
+	}
+
+	private static ThreadLocal<SSLSocketFactory> threadLocalFactory = new ThreadLocal<SSLSocketFactory>();
+
+	private static SSLSocketFactory createAlwaysTrustingFactory() {
+		SSLContext sc = null;
+		try {
+			sc = SSLContext.getInstance("SSL");
+		} catch (NoSuchAlgorithmException e1) {
+
+			logger.error("No SSL algorithm", e1);
+		}
+		TrustManager overlyTrusting = new X509TrustManager() {
+
+			public void checkClientTrusted(X509Certificate[] arg0, String arg1)
+					throws CertificateException {
+
+			}
+
+			public void checkServerTrusted(X509Certificate[] arg0, String arg1)
+					throws CertificateException {
+
+			}
+
+			public X509Certificate[] getAcceptedIssuers() {
+				return null;
+			}
+
+		};
+		try {
+			sc.init(null, new TrustManager[] { overlyTrusting },
+					new SecureRandom());
+		} catch (KeyManagementException e) {
+			logger.error("Unable to initialize SSLContext", e);
+		}
+		return sc.getSocketFactory();
+
+	}
+
+	private SSLSocketFactory getFactory() {
+		if (threadLocalFactory.get() == null) {
+			return (SSLSocketFactory) SSLSocketFactory.getDefault();
+		} else {
+			return threadLocalFactory.get();
+		}
+	}
+
+	@Override
+	public Socket createSocket(Socket arg0, String arg1, int arg2, boolean arg3)
+			throws IOException {
+		return getFactory().createSocket(arg0, arg1, arg2, arg3);
+	}
+
+	@Override
+	public String[] getDefaultCipherSuites() {
+		return getFactory().getDefaultCipherSuites();
+	}
+
+	@Override
+	public String[] getSupportedCipherSuites() {
+		return getFactory().getSupportedCipherSuites();
+	}
+
+	@Override
+	public Socket createSocket() throws IOException {
+		return getFactory().createSocket();
+	}
+
+	@Override
+	public Socket createSocket(String arg0, int arg1) throws IOException,
+			UnknownHostException {
+		return getFactory().createSocket(arg0, arg1);
+	}
+
+	@Override
+	public Socket createSocket(InetAddress arg0, int arg1) throws IOException {
+		return getFactory().createSocket(arg0, arg1);
+	}
+
+	@Override
+	public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3)
+			throws IOException, UnknownHostException {
+		return getFactory().createSocket(arg0, arg1, arg2, arg3);
+	}
+
+	@Override
+	public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2,
+			int arg3) throws IOException {
+		return getFactory().createSocket(arg0, arg1, arg2, arg3);
+	}
+}
\ 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/java/net/sf/taverna/t2/activities/wsdl/wss4j/T2WSDoAllSender.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/wss4j/T2WSDoAllSender.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/wss4j/T2WSDoAllSender.java
new file mode 100644
index 0000000..7e9f909
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/wss4j/T2WSDoAllSender.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * 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.wss4j;
+
+import java.util.Vector;
+
+//import net.sf.taverna.t2.security.agents.SAException;
+//import net.sf.taverna.t2.security.agents.WSSecurityAgent;
+
+//import org.apache.commons.logging.Log;
+//import org.apache.commons.logging.LogFactory;
+//import org.apache.log4j.Logger;
+import org.apache.ws.axis.security.WSDoAllSender;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSEncryptionPart;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.handler.RequestData;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+
+public class T2WSDoAllSender extends WSDoAllSender{
+	
+    /**
+	 * This is a security handler for wss4j that invokes security agents
+	 * whenever access to the user's credentials (passwords, private keys) 
+	 * or secret keys is required. The security agent performs the necessary
+	 * security operations on the message to be sent and returns the message. 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	//private static Log log = LogFactory.getLog(T2WSDoAllSender.class.getName());
+
+   // private boolean doDebug = log.isDebugEnabled();
+    
+   // private static Logger logger = Logger.getLogger(T2WSDoAllSender.class);
+    
+    /**                                                             
+     * Performs all defined security actions to set-up the SOAP request.
+     * 
+     * This method overrides the doSenderAction() method of WSHandler class
+     * by setting the actions to be executed to use T2 security agents.
+     * 
+     * 
+     * @param doAction a set defining the actions to do 
+     * @param doc   the request as DOM document 
+     * @param reqData a data storage to pass values around bewteen methods
+     * @param actions a vector holding the actions to do in the order defined
+     *                in the deployment file or property
+     * @throws WSSecurityException
+     */
+    @Override
+    protected void doSenderAction(int doAction, Document doc,
+                                  RequestData reqData, Vector actions, 
+				  boolean isRequest)
+            throws WSSecurityException {
+    	
+
+        boolean mu = decodeMustUnderstand(reqData);
+
+        WSSConfig wssConfig = WSSConfig.getNewInstance();
+        
+        wssConfig
+	    .setEnableSignatureConfirmation(decodeEnableSignatureConfirmation(reqData));
+        
+        wssConfig
+	    .setPrecisionInMilliSeconds(decodeTimestampPrecision(reqData));
+        reqData.setWssConfig(wssConfig);
+
+        Object mc = reqData.getMsgContext();
+        String actor = getString(WSHandlerConstants.ACTOR, mc);
+        reqData.setActor(actor);
+
+        WSSecHeader secHeader = new WSSecHeader(actor, mu);
+        secHeader.insertSecurityHeader(doc);
+        
+        reqData.setSecHeader(secHeader);
+        reqData.setSoapConstants(WSSecurityUtil.getSOAPConstants(doc
+                .getDocumentElement()));
+        /*
+         * Here we have action, username, password, and actor, mustUnderstand.
+         * Now get the action specific parameters.
+         */
+        if ((doAction & WSConstants.UT) == WSConstants.UT) {
+            decodeUTParameter(reqData);
+        }
+        /*
+         * Here we have action, username, password, and actor, mustUnderstand.
+         * Now get the action specific parameters.
+         */
+        if ((doAction & WSConstants.UT_SIGN) == WSConstants.UT_SIGN) {
+            decodeUTParameter(reqData);
+            decodeSignatureParameter(reqData);
+        }
+        /*
+         * Get and check the Signature specific parameters first because they
+         * may be used for encryption too.
+         */
+        if ((doAction & WSConstants.SIGN) == WSConstants.SIGN) {
+            reqData.setSigCrypto(loadSignatureCrypto(reqData));
+            decodeSignatureParameter(reqData);
+        }
+        /*
+         * If we need to handle signed SAML token then we need may of the
+         * Signature parameters. The handle procedure loads the signature crypto
+         * file on demand, thus don't do it here.
+         */
+        if ((doAction & WSConstants.ST_SIGNED) == WSConstants.ST_SIGNED) {
+            decodeSignatureParameter(reqData);
+        }
+        /*
+         * Set and check the encryption specific parameters, if necessary take
+         * over signature parameters username and crypto instance.
+         */
+        if ((doAction & WSConstants.ENCR) == WSConstants.ENCR) {
+            reqData.setEncCrypto(loadEncryptionCrypto(reqData));
+            decodeEncryptionParameter(reqData);
+        }
+        /*
+         * If after all the parsing no Signature parts defined, set here a
+         * default set. This is necessary because we add SignatureConfirmation
+         * and therefore the default (Body) must be set here. The default setting
+         * in WSSignEnvelope doesn't work because the vector is not empty anymore.
+         */
+        if (reqData.getSignatureParts().isEmpty()) {
+            WSEncryptionPart encP = new WSEncryptionPart(reqData.getSoapConstants()
+                    .getBodyQName().getLocalPart(), reqData.getSoapConstants()
+                    .getEnvelopeURI(), "Content");
+            reqData.getSignatureParts().add(encP);
+        }
+        /*
+         * If SignatureConfirmation is enabled and this is a reqsponse then
+         * insert SignatureCOnfrmation elements, note their wsu:id in the signature
+         * parts. They will be signed automatically during a (probably) defined
+         * SIGN action.
+         */
+        if (wssConfig.isEnableSignatureConfirmation() && !isRequest) {
+            String done;
+            if ((done = (String) getProperty(reqData.getMsgContext(),
+                    WSHandlerConstants.SIG_CONF_DONE)) == null
+                    || !DONE.equals(done)) {
+                Vector results = null;
+                if ((results = (Vector) getProperty(reqData.getMsgContext(),
+                        WSHandlerConstants.RECV_RESULTS)) != null) {
+                    wssConfig.getAction(WSConstants.SC).execute(this, WSConstants.SC, doc, reqData);
+                }
+            }
+        }
+        /*
+         * Here we have all necessary information to perform the requested
+         * action(s).
+         */
+        
+        // Get the security agent
+       /* WSSecurityAgent sa = (WSSecurityAgent) ((MessageContext)reqData.getMsgContext()).getProperty("security_agent");
+   
+        // Perform security actions
+        for (int i = 0; i < actions.size(); i++) {
+
+            int actionToDo = ((Integer) actions.get(i)).intValue();
+            if (doDebug) {
+                log.debug("Performing Action: " + actionToDo);
+            }
+
+            switch (actionToDo) {
+                case WSConstants.UT:{
+                	try {
+    					sa.wssUsernameToken(doc, reqData);
+    				} catch (SAException e) {
+    					logger.error("", e);
+    				} break;
+				}
+                case WSConstants.ENCR:
+                case WSConstants.SIGN:{//sa.wssSign(doc, reqData); break;}
+                case WSConstants.ST_SIGNED:
+                case WSConstants.ST_UNSIGNED:
+                case WSConstants.TS:
+                case WSConstants.UT_SIGN:
+                    wssConfig.getAction(actionToDo).execute(this, actionToDo, doc, reqData);
+                    break;
+                case WSConstants.NO_SERIALIZE:
+                    reqData.setNoSerialization(true);
+                    break;
+            }
+        } */
+
+        /*
+         * If this is a request then store all signature values. Add ours to
+         * already gathered values because of chained handlers, e.g. for
+         * other actors.
+         */
+
+        if (wssConfig.isEnableSignatureConfirmation() && isRequest) {
+            if (reqData.getSignatureValues().size() > 0) {
+                Vector sigv = null;
+                if ((sigv = (Vector) getProperty(reqData.getMsgContext(),
+                        WSHandlerConstants.SEND_SIGV)) == null) {
+                    sigv = new Vector();
+                    setProperty(reqData.getMsgContext(),
+                            WSHandlerConstants.SEND_SIGV, sigv);
+                }
+                // sigv.add(reqData.getSignatureValues());
+                sigv.addAll(reqData.getSignatureValues());
+            }
+        }
+    }
+
+}
+
+

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/AddXMLSplitterEdit.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/AddXMLSplitterEdit.java b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/AddXMLSplitterEdit.java
new file mode 100644
index 0000000..a30c6a2
--- /dev/null
+++ b/taverna-wsdl-activity/src/main/java/net/sf/taverna/t2/activities/wsdl/xmlsplitter/AddXMLSplitterEdit.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.t2.activities.wsdl.xmlsplitter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sf.taverna.t2.activities.wsdl.WSDLActivity;
+import net.sf.taverna.t2.workflowmodel.CompoundEdit;
+import net.sf.taverna.t2.workflowmodel.Dataflow;
+import net.sf.taverna.t2.workflowmodel.Edit;
+import net.sf.taverna.t2.workflowmodel.EditException;
+import net.sf.taverna.t2.workflowmodel.Edits;
+import net.sf.taverna.t2.workflowmodel.EventForwardingOutputPort;
+import net.sf.taverna.t2.workflowmodel.EventHandlingInputPort;
+import net.sf.taverna.t2.workflowmodel.InputPort;
+import net.sf.taverna.t2.workflowmodel.OutputPort;
+import net.sf.taverna.t2.workflowmodel.Processor;
+import net.sf.taverna.t2.workflowmodel.ProcessorInputPort;
+import net.sf.taverna.t2.workflowmodel.ProcessorOutputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
+import net.sf.taverna.t2.workflowmodel.utils.Tools;
+import net.sf.taverna.wsdl.parser.ArrayTypeDescriptor;
+import net.sf.taverna.wsdl.parser.TypeDescriptor;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+public class AddXMLSplitterEdit implements Edit<Dataflow> {
+
+	private final Edits edits;
+	private final Activity<?> activity;
+	private final String portName;
+	private final boolean isInput;
+	private CompoundEdit compoundEdit1 = null;
+	private Edit<?> linkUpEdit;
+	private final Dataflow dataflow;
+	private boolean applied = false;
+
+	public AddXMLSplitterEdit(Dataflow dataflow, Activity<?> activity,
+			String portName, boolean isInput, Edits edits) {
+		this.dataflow = dataflow;
+		this.activity = activity;
+		this.portName = portName;
+		this.isInput = isInput;
+		this.edits = edits;
+	}
+
+	@Override
+	public Dataflow doEdit() throws EditException {
+		if (applied) throw new EditException("Edit has already been applied!");
+		List<Edit<?>> editList = new ArrayList<Edit<?>>();
+
+		Activity<JsonNode> splitter = null;
+		String sourcePortName = "";
+		Processor sourceProcessor = null;
+		Activity<?> sourceActivity = null;
+
+		String sinkPortName = "";
+		Processor sinkProcessor = null;
+		Activity<?> sinkActivity = null;
+
+
+		Processor activityProcessor = findProcessorForActivity(dataflow,
+				activity);
+		if (activityProcessor == null) {
+			throw new EditException(
+					"Cannot find the processor that the activity belongs to");
+		}
+
+
+		String displayName = portName;
+		if (portName.equals("parameters")) {
+			displayName = isInput ? "input" : "output";
+		}
+		String processorName = activityProcessor.getLocalName();
+		String candidateName;
+		if (displayName.startsWith(processorName)) {
+			// No need to make GetRequest_GetRequestResponse
+			candidateName = displayName;
+		} else {
+			// Combine with processor name
+			String displayProcessorName;
+			if (activity instanceof XMLOutputSplitterActivity || activity instanceof XMLInputSplitterActivity) {
+				// For splitters on splitters - avoid adding up blah_bluh_blih_more_stuff
+				String[] processorNameSplit = processorName.replace("_input", "").replace("_output", "").split("_");
+				displayProcessorName = processorNameSplit[processorNameSplit.length-1];
+			} else {
+				displayProcessorName = activityProcessor.getLocalName();
+			}
+			candidateName = displayProcessorName + "_" + displayName;
+		}
+		String name = Tools.uniqueProcessorName(candidateName, dataflow);
+		Processor splitterProcessor = edits.createProcessor(name);
+
+		try {
+			if (activity instanceof XMLInputSplitterActivity) {
+				if (!isInput) {
+					throw new EditException(
+							"Can only add an input splitter to another input splitter");
+				}
+				TypeDescriptor descriptor = ((XMLInputSplitterActivity) activity)
+						.getTypeDescriptorForInputPort(portName);
+				if (descriptor instanceof ArrayTypeDescriptor && !((ArrayTypeDescriptor)descriptor).isWrapped()) {
+					descriptor=((ArrayTypeDescriptor)descriptor).getElementType();
+				}
+
+				JsonNode bean = XMLSplitterConfigurationBeanBuilder
+						.buildBeanForInput(descriptor);
+				splitter = new XMLInputSplitterActivity();
+				editList.add(edits.getConfigureActivityEdit(splitter, bean));
+
+			} else if (activity instanceof XMLOutputSplitterActivity) {
+				if (isInput) {
+					throw new EditException(
+							"Can only add an output splitter to another output splitter");
+				}
+				TypeDescriptor descriptor = ((XMLOutputSplitterActivity) activity)
+						.getTypeDescriptorForOutputPort(portName);
+
+				if (descriptor instanceof ArrayTypeDescriptor && !((ArrayTypeDescriptor)descriptor).isWrapped()) {
+					descriptor=((ArrayTypeDescriptor)descriptor).getElementType();
+				}
+
+				JsonNode bean = XMLSplitterConfigurationBeanBuilder
+						.buildBeanForOutput(descriptor);
+				splitter = new XMLOutputSplitterActivity();
+				editList.add(edits.getConfigureActivityEdit(splitter, bean));
+
+			} else if (activity instanceof WSDLActivity) {
+				if (isInput) {
+					TypeDescriptor descriptor = ((WSDLActivity) activity)
+							.getTypeDescriptorForInputPort(portName);
+					JsonNode bean = XMLSplitterConfigurationBeanBuilder
+							.buildBeanForInput(descriptor);
+					splitter = new XMLInputSplitterActivity();
+					editList
+							.add(edits.getConfigureActivityEdit(splitter, bean));
+				} else {
+					TypeDescriptor descriptor = ((WSDLActivity) activity)
+							.getTypeDescriptorForOutputPort(portName);
+					JsonNode bean = XMLSplitterConfigurationBeanBuilder
+							.buildBeanForOutput(descriptor);
+					splitter = new XMLOutputSplitterActivity();
+					editList
+							.add(edits.getConfigureActivityEdit(splitter, bean));
+				}
+			} else {
+				throw new EditException(
+						"The activity type is not suitable for adding xml processing processors");
+			}
+		} catch (Exception e) {
+			throw new EditException(
+					"An error occured whilst tyring to add an XMLSplitter to the activity:"
+							+ activity, e);
+		}
+
+		if (isInput) {
+			sourcePortName = "output";
+			sinkPortName = portName;
+			sinkProcessor = activityProcessor;
+			sinkActivity = activity;
+			sourceProcessor = splitterProcessor;
+			sourceActivity = splitter;
+		}
+		else {
+			sourcePortName = portName;
+			sinkPortName = "input";
+			sinkProcessor = splitterProcessor;
+			sinkActivity = splitter;
+			sourceProcessor = activityProcessor;
+			sourceActivity = activity;
+		}
+
+		editList.add(edits.getDefaultDispatchStackEdit(splitterProcessor));
+		editList.add(edits.getAddActivityEdit(splitterProcessor, splitter));
+//		editList.add(edits
+//				.getMapProcessorPortsForActivityEdit(splitterProcessor));
+		editList.add(edits.getAddProcessorEdit(dataflow, splitterProcessor));
+
+		compoundEdit1 = new CompoundEdit(editList);
+		compoundEdit1.doEdit();
+
+		List<Edit<?>> linkUpEditList = new ArrayList<Edit<?>>();
+
+		EventForwardingOutputPort source = getSourcePort(sourceProcessor, sourceActivity,
+				sourcePortName, linkUpEditList);
+		EventHandlingInputPort sink = getSinkPort(sinkProcessor, sinkActivity, sinkPortName, linkUpEditList);
+
+		if (source == null)
+			throw new EditException(
+					"Unable to find the source port when linking up "
+							+ sourcePortName + " to " + sinkPortName);
+		if (sink == null)
+			throw new EditException(
+					"Unable to find the sink port when linking up "
+							+ sourcePortName + " to " + sinkPortName);
+
+		linkUpEditList.add(net.sf.taverna.t2.workflowmodel.utils.Tools.getCreateAndConnectDatalinkEdit(dataflow, source, sink, edits));
+
+		linkUpEdit = new CompoundEdit(linkUpEditList);
+		linkUpEdit.doEdit();
+		applied = true;
+		return dataflow;
+	}
+
+	private EventHandlingInputPort getSinkPort(Processor processor, Activity<?> activity,
+			String portName, List<Edit<?>> editList) {
+		InputPort activityPort = net.sf.taverna.t2.workflowmodel.utils.Tools.getActivityInputPort(activity, portName);
+		//check if processor port exists
+		EventHandlingInputPort input = net.sf.taverna.t2.workflowmodel.utils.Tools.getProcessorInputPort(processor, activity, activityPort);
+		if (input == null) {
+			//port doesn't exist so create a processor port and map it
+			ProcessorInputPort processorInputPort =
+				edits.createProcessorInputPort(processor, activityPort.getName(), activityPort.getDepth());
+			editList.add(edits.getAddProcessorInputPortEdit(processor, processorInputPort));
+			editList.add(edits.getAddActivityInputPortMappingEdit(activity, activityPort.getName(), activityPort.getName()));
+			input = processorInputPort;
+		}
+		return input;
+	}
+
+	private EventForwardingOutputPort getSourcePort(Processor processor, Activity<?> activity,
+			String portName, List<Edit<?>> editList) {
+		OutputPort activityPort = net.sf.taverna.t2.workflowmodel.utils.Tools.getActivityOutputPort(activity, portName);
+		//check if processor port exists
+		EventForwardingOutputPort output = net.sf.taverna.t2.workflowmodel.utils.Tools.getProcessorOutputPort(processor, activity, activityPort);
+		if (output == null) {
+			//port doesn't exist so create a processor port and map it
+			ProcessorOutputPort processorOutputPort =
+				edits.createProcessorOutputPort(processor, activityPort.getName(), activityPort.getDepth(), activityPort.getGranularDepth());
+			editList.add(edits.getAddProcessorOutputPortEdit(processor, processorOutputPort));
+			editList.add(edits.getAddActivityOutputPortMappingEdit(activity, activityPort.getName(), activityPort.getName()));
+			output = processorOutputPort;
+		}
+		return output;
+	}
+
+	@Override
+	public void undo() {
+		if (!applied) {
+			throw new RuntimeException(
+					"Attempt to undo edit that was never applied");
+		}
+		if (linkUpEdit.isApplied())
+			linkUpEdit.undo();
+		if (compoundEdit1.isApplied())
+			compoundEdit1.undo();
+		applied = false;
+	}
+
+	@Override
+	public boolean isApplied() {
+		return applied;
+	}
+
+	private Processor findProcessorForActivity(Dataflow dataflow,
+			Activity<?> activity) {
+		for (Processor p : dataflow.getProcessors()) {
+			for (Activity<?> a : p.getActivityList()) {
+				if (a == activity)
+					return p;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public Object getSubject() {
+		return dataflow;
+	}
+
+}