You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2015/02/23 11:04:59 UTC

[14/79] [partial] incubator-taverna-language git commit: Revert "temporarily empty repository"

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/DataflowActivityParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/DataflowActivityParser.java b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/DataflowActivityParser.java
new file mode 100644
index 0000000..aaadeab
--- /dev/null
+++ b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/DataflowActivityParser.java
@@ -0,0 +1,86 @@
+package org.apache.taverna.scufl2.translator.t2flow.defaultactivities;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+
+import static org.apache.taverna.scufl2.api.core.Workflow.WORKFLOW_ROOT;
+import static org.apache.taverna.scufl2.translator.t2flow.T2FlowParser.ravenURI;
+
+import java.net.URI;
+
+import org.apache.taverna.scufl2.api.common.URITools;
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.core.Workflow;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.translator.t2flow.ParserState;
+import org.apache.taverna.scufl2.translator.t2flow.T2FlowParser;
+
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ConfigBean;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.DataflowConfig;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class DataflowActivityParser extends AbstractActivityParser {
+	private URITools uriTools = new URITools();
+	private static URI activityRavenURI = ravenURI
+			.resolve("net.sf.taverna.t2.activities/dataflow-activity/");
+	private static String activityClassName = "net.sf.taverna.t2.activities.dataflow.DataflowActivity";
+	public static URI nestedUri = URI
+			.create("http://ns.taverna.org.uk/2010/activity/nested-workflow");
+
+	@Override
+	public boolean canHandlePlugin(URI activityURI) {
+		String activityUriStr = activityURI.toASCIIString();
+		return activityUriStr.startsWith(activityRavenURI.toASCIIString())
+				&& activityUriStr.endsWith(activityClassName);
+	}
+
+	@Override
+	public URI mapT2flowRavenIdToScufl2URI(URI t2flowActivity) {
+		return nestedUri;
+	}
+
+	@Override
+	public Configuration parseConfiguration(T2FlowParser t2FlowParser,
+			ConfigBean configBean, ParserState parserState) throws ReaderException {
+		DataflowConfig dataflowConfig = unmarshallConfig(t2FlowParser,
+				configBean, "dataflow", DataflowConfig.class);
+		Configuration configuration = new Configuration();
+		configuration.setType(nestedUri.resolve("#Config"));		
+
+		String wfId = dataflowConfig.getRef();
+		URI wfUri = WORKFLOW_ROOT.resolve(wfId + "/");
+		Workflow wf = (Workflow) getUriTools().resolveUri(wfUri, parserState.getCurrentWorkflowBundle());		
+		if (wf == null)
+	        throw new ReaderException("Can't find nested workflow with id " + wfId);
+		ObjectNode json = configuration.getJsonAsObjectNode();
+		json.put("nestedWorkflow", wf.getName());
+		return configuration;
+	}
+
+	public void setUriTools(URITools uriTools) {
+		this.uriTools = uriTools;
+	}
+
+	public URITools getUriTools() {
+		return uriTools;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/InteractionActivityParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/InteractionActivityParser.java b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/InteractionActivityParser.java
new file mode 100644
index 0000000..73a3a22
--- /dev/null
+++ b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/InteractionActivityParser.java
@@ -0,0 +1,95 @@
+package org.apache.taverna.scufl2.translator.t2flow.defaultactivities;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+
+import static org.apache.taverna.scufl2.translator.t2flow.T2FlowParser.ravenURI;
+
+import java.net.URI;
+
+import org.apache.taverna.scufl2.api.activity.Activity;
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.translator.t2flow.ParserState;
+import org.apache.taverna.scufl2.translator.t2flow.T2FlowParser;
+
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ActivityPortDefinitionBean;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ConfigBean;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.InteractionConfig;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class InteractionActivityParser extends AbstractActivityParser {
+	private static final URI activityRavenURI = ravenURI
+			.resolve("net.sf.taverna.t2.activities/interaction-activity/");
+	private static final String activityClassName = "net.sf.taverna.t2.activities.interaction.InteractionActivity";
+	public static final URI ACTIVITY_URI = URI
+			.create("http://ns.taverna.org.uk/2010/activity/interaction");
+
+	@Override
+	public boolean canHandlePlugin(URI activityURI) {
+		String activityUriStr = activityURI.toASCIIString();
+		return activityUriStr.startsWith(activityRavenURI.toASCIIString())
+				&& activityUriStr.endsWith(activityClassName);
+	}
+
+	@Override
+	public URI mapT2flowRavenIdToScufl2URI(URI t2flowActivity) {
+		return ACTIVITY_URI;
+	}
+
+	@Override
+	public Configuration parseConfiguration(T2FlowParser t2FlowParser,
+			ConfigBean configBean, ParserState parserState)
+			throws ReaderException {
+		InteractionConfig interactionConfig = unmarshallConfig(t2FlowParser,
+				configBean, "xstream", InteractionConfig.class);
+
+		Configuration configuration = new Configuration();
+		configuration.setParent(parserState.getCurrentProfile());
+
+		ObjectNode json = (ObjectNode) configuration.getJson();
+		configuration.setType(ACTIVITY_URI.resolve("#Config"));
+		
+		String presentationOrigin = interactionConfig.getPresentationOrigin();
+		json.put("presentationOrigin", presentationOrigin);
+		
+		String interactionActivityType = interactionConfig.getInteractionActivityType();
+		json.put("interactionActivityType", interactionActivityType);
+		
+		boolean progressNotification = interactionConfig.getProgressNotification();
+		json.put("progressNotification", progressNotification);
+		
+		Activity activity = parserState.getCurrentActivity();
+		activity.getInputPorts().clear();
+		activity.getOutputPorts().clear();
+		for (ActivityPortDefinitionBean portBean : interactionConfig
+				.getInputs()
+				.getNetSfTavernaT2WorkflowmodelProcessorActivityConfigActivityInputPortDefinitionBean())
+			parseAndAddInputPortDefinition(portBean, configuration, activity);
+		for (ActivityPortDefinitionBean portBean : interactionConfig
+				.getOutputs()
+				.getNetSfTavernaT2WorkflowmodelProcessorActivityConfigActivityOutputPortDefinitionBean())
+			parseAndAddOutputPortDefinition(portBean, configuration, activity);
+		return configuration;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/RshellActivityParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/RshellActivityParser.java b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/RshellActivityParser.java
new file mode 100644
index 0000000..e9808eb
--- /dev/null
+++ b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/RshellActivityParser.java
@@ -0,0 +1,215 @@
+package org.apache.taverna.scufl2.translator.t2flow.defaultactivities;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+
+import static org.apache.taverna.scufl2.translator.t2flow.T2FlowParser.ravenURI;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.taverna.scufl2.api.activity.Activity;
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.translator.t2flow.ParserState;
+import org.apache.taverna.scufl2.translator.t2flow.T2FlowParser;
+
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ActivityPortDefinitionBean;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ConfigBean;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.RShellConfig;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.RShellConnection;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.RShellSymanticType;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.RShellSymanticType.RShellPortSymanticTypeBean;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class RshellActivityParser extends AbstractActivityParser {
+	/*
+	 * A lovely artifact of xstream 'efficiency' - Xpath backpointers to
+	 * previous elements. luckily we are here restricted within this specific
+	 * config bean
+	 * 
+	 * Example:
+	 * ../../net.sf.taverna.t2.activities.rshell.RShellPortSymanticTypeBean
+	 * [3]/symanticType
+	 * ../../../inputSymanticTypes/net.sf.taverna.t2.activities.
+	 * rshell.RShellPortSymanticTypeBean[2]/symanticType
+	 */
+	Pattern strangeXpath = Pattern
+			.compile("[./]+/(inputSymanticTypes)?.*TypeBean(\\[(\\d+)\\])?/symanticType$");
+
+	private static final URI activityRavenURI = ravenURI
+			.resolve("net.sf.taverna.t2.activities/rshell-activity/");
+	private static final String activityClassName = "net.sf.taverna.t2.activities.rshell.RshellActivity";
+	public static final URI ACTIVITY_URI = URI
+			.create("http://ns.taverna.org.uk/2010/activity/rshell");
+
+	@Override
+	public boolean canHandlePlugin(URI activityURI) {
+		String activityUriStr = activityURI.toASCIIString();
+		return activityUriStr.startsWith(activityRavenURI.toASCIIString())
+				&& activityUriStr.endsWith(activityClassName);
+	}
+
+	@Override
+	public URI mapT2flowRavenIdToScufl2URI(URI t2flowActivity) {
+		return ACTIVITY_URI;
+	}
+
+	@Override
+	public Configuration parseConfiguration(T2FlowParser t2FlowParser,
+			ConfigBean configBean, ParserState parserState) throws ReaderException {
+		RShellConfig rshellConfig = unmarshallConfig(t2FlowParser, configBean,
+				"xstream", RShellConfig.class);
+
+		Configuration configuration = new Configuration();
+		configuration.setParent(parserState.getCurrentProfile());
+
+		ObjectNode json = (ObjectNode) configuration.getJson();
+		configuration.setType(ACTIVITY_URI.resolve("#Config"));
+
+		// Basic properties
+		String script = rshellConfig.getScript();
+		json.put("script", script);
+//		if (rshellConfig.getRVersion() != null) {
+//            json.put("rVersion", rshellConfig.getRVersion());
+//		}
+
+		// Connection
+		ObjectNode connection = json.objectNode();
+		json.put("connection", connection);
+        RShellConnection conn = rshellConfig.getConnectionSettings();
+        connection.put("hostname", conn.getHost());
+        json.put("port", conn.getPort());
+
+		// ignored - Taverna 2.3+ uses credential manager
+		// connection.put("username", conn.getUsername());
+		// connection.put("password", conn.getPassword());
+        
+        connection.put("keepSessionAlive", conn.isKeepSessionAlive());
+
+		// ignoooooored - we won't support the legacy ones anymore
+		// if (rshellConfig.getConnectionSettings().isNewRVersion() == null || !
+		// rshellConfig.getConnectionSettings().isNewRVersion()) {
+		// connection.put("legacy", true);
+		// }
+
+		// Activity ports
+		Activity activity = parserState.getCurrentActivity();
+		activity.getInputPorts().clear();
+		activity.getOutputPorts().clear();
+		
+		for (ActivityPortDefinitionBean portBean : rshellConfig
+				.getInputs()
+				.getNetSfTavernaT2WorkflowmodelProcessorActivityConfigActivityInputPortDefinitionBean())
+			parseAndAddInputPortDefinition(portBean, configuration, activity);
+		for (ActivityPortDefinitionBean portBean : rshellConfig
+				.getOutputs()
+				.getNetSfTavernaT2WorkflowmodelProcessorActivityConfigActivityOutputPortDefinitionBean())
+			parseAndAddOutputPortDefinition(portBean, configuration, activity);
+		
+		RShellSymanticType inputSymanticTypes = rshellConfig
+				.getInputSymanticTypes();
+		List<String> foundInputTypes = new ArrayList<>();
+
+		ArrayNode inputPorts = json.arrayNode();
+		json.put("inputTypes", inputPorts);
+		for (RShellPortSymanticTypeBean symanticType : inputSymanticTypes
+				.getNetSfTavernaT2ActivitiesRshellRShellPortSymanticTypeBean()) {
+            ObjectNode port = json.objectNode();
+			port.put("port", symanticType.getName());
+			String dataType = symanticType.getSymanticType().getValue(); 
+			String reference = symanticType.getSymanticType().getReference();
+			if (reference != null) {
+				Matcher matcher = strangeXpath.matcher(reference);
+				if (matcher == null || !matcher.matches())
+					throw new ReaderException(
+							"Unhandled xstream xpath expression: " + reference);
+				String position = matcher.group(3);
+				if (position == null)
+					position = "1";
+				dataType = foundInputTypes.get(Integer.parseInt(position) - 1);
+			}
+			
+			foundInputTypes.add(dataType);
+			// Even if it's null - so the index is correct
+
+			if (dataType != null)
+			    port.put("dataType", dataType);
+		}
+		/*
+		 * FIXME: Avoid this repetition. Would require a fair bit of parser
+		 * state...
+		 */
+		RShellSymanticType outputSymanticTypes = rshellConfig
+				.getOutputSymanticTypes();
+		List<String> foundOutputTypes = new ArrayList<>();
+        ArrayNode outputPorts = json.arrayNode();
+        json.put("outputTypes", outputPorts);
+
+		for (RShellPortSymanticTypeBean symanticType : outputSymanticTypes
+				.getNetSfTavernaT2ActivitiesRshellRShellPortSymanticTypeBean()) {
+            ObjectNode port = json.objectNode();
+            port.put("port", symanticType.getName());
+
+			String dataType = symanticType.getSymanticType().getValue();
+			String reference = symanticType.getSymanticType().getReference();
+			if (reference != null) {
+				/*
+				 * A lovely artifact of xstream 'efficiency' - Xpath
+				 * backpointers to previous elements. luckily we are here
+				 * restricted within this specific config bean.
+				 *
+				 * Example:
+				 * ../../net.sf.taverna.t2.activities.rshell.RShellPortSymanticTypeBean[3]/symanticType
+				 * ../../../inputSymanticTypes/net.sf.taverna.t2.activities.rshell.RShellPortSymanticTypeBean[2]/symanticType
+				 */
+
+				Matcher matcher = strangeXpath.matcher(reference);
+				if (matcher == null || !matcher.matches())
+					throw new ReaderException(
+							"Unhandled xstream xpath expression: " + reference);
+
+				boolean isInputSymantic = matcher.group(1) != null;
+				String position = matcher.group(3);
+				if (position == null)
+					position = "1";
+				if (isInputSymantic)
+					dataType = foundInputTypes
+							.get(Integer.parseInt(position) - 1);
+				else
+					dataType = foundOutputTypes
+							.get(Integer.parseInt(position) - 1);
+			}
+
+			foundOutputTypes.add(dataType);
+			// Even if it's null - so the index is correct
+
+			if (dataType != null)
+                port.put("dataType", dataType);
+		}
+		return configuration;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/SoaplabActivityParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/SoaplabActivityParser.java b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/SoaplabActivityParser.java
new file mode 100644
index 0000000..b5ce171
--- /dev/null
+++ b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/SoaplabActivityParser.java
@@ -0,0 +1,89 @@
+package org.apache.taverna.scufl2.translator.t2flow.defaultactivities;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+
+import static org.apache.taverna.scufl2.translator.t2flow.T2FlowParser.ravenURI;
+
+import java.math.BigInteger;
+import java.net.URI;
+
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.translator.t2flow.ParserState;
+import org.apache.taverna.scufl2.translator.t2flow.T2FlowParser;
+
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ConfigBean;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.SoaplabConfig;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class SoaplabActivityParser extends AbstractActivityParser {
+	private static final URI activityRavenURI = ravenURI
+			.resolve("net.sf.taverna.t2.activities/soaplab-activity/");
+	private static final String activityClassName = "net.sf.taverna.t2.activities.soaplab.SoaplabActivity";
+	public static final URI scufl2Uri = URI
+			.create("http://ns.taverna.org.uk/2010/activity/soaplab");
+
+	@Override
+	public boolean canHandlePlugin(URI activityURI) {
+		String activityUriStr = activityURI.toASCIIString();
+		return activityUriStr.startsWith(activityRavenURI.toASCIIString())
+				&& activityUriStr.endsWith(activityClassName);
+	}
+
+	@Override
+	public URI mapT2flowRavenIdToScufl2URI(URI t2flowActivity) {
+		return scufl2Uri;
+	}
+
+	@Override
+	public Configuration parseConfiguration(T2FlowParser t2FlowParser,
+			ConfigBean configBean, ParserState parserState)
+			throws ReaderException {
+		SoaplabConfig soaplabConfig = unmarshallConfig(t2FlowParser,
+				configBean, "xstream", SoaplabConfig.class);
+
+		Configuration configuration = new Configuration();
+		configuration.setParent(parserState.getCurrentProfile());
+
+		ObjectNode json = (ObjectNode) configuration.getJson();
+		configuration.setType(scufl2Uri.resolve("#Config"));
+
+		String endpoint = soaplabConfig.getEndpoint();
+		if (endpoint == null || endpoint.isEmpty())
+			throw new ReaderException("Soablab config has no endpoint set");
+		json.put("endpoint", endpoint);
+
+		double pollingBackoff = soaplabConfig.getPollingBackoff();
+		json.put("pollingBackoff", pollingBackoff);
+
+		BigInteger pollingInterval = soaplabConfig.getPollingInterval();
+		if (pollingInterval != null)
+            json.put("pollingInterval", pollingInterval.intValue());
+
+		BigInteger pollingIntervalMax = soaplabConfig.getPollingIntervalMax();
+		if (pollingIntervalMax != null)
+            json.put("pollingIntervalMax", pollingIntervalMax.intValue());
+
+		return configuration;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/SpreadsheetActivityParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/SpreadsheetActivityParser.java b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/SpreadsheetActivityParser.java
new file mode 100644
index 0000000..e860171
--- /dev/null
+++ b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/SpreadsheetActivityParser.java
@@ -0,0 +1,125 @@
+package org.apache.taverna.scufl2.translator.t2flow.defaultactivities;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+
+import static org.apache.taverna.scufl2.translator.t2flow.T2FlowParser.ravenURI;
+
+import java.net.URI;
+
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.translator.t2flow.ParserState;
+import org.apache.taverna.scufl2.translator.t2flow.T2FlowParser;
+
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ConfigBean;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.SpreadsheetColumnNameEntry;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.SpreadsheetImportConfig;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.SpreadsheetRange;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class SpreadsheetActivityParser extends AbstractActivityParser {
+	private static final URI activityRavenURI = ravenURI
+			.resolve("net.sf.taverna.t2.activities/spreadsheet-import-activity/");
+	private static final String activityClassName = "net.sf.taverna.t2.activities.spreadsheet.SpreadsheetImportActivity";
+	public static final URI ACTIVITY_URI = URI
+			.create("http://ns.taverna.org.uk/2010/activity/spreadsheet-import");
+	public static final URI RANGE_URI = URI
+			.create("http://ns.taverna.org.uk/2010/activity/spreadsheet-import/Range");
+	public static final URI MAPPING_URI = URI
+			.create("http://ns.taverna.org.uk/2010/activity/spreadsheet-import/Mapping");
+
+	@Override
+	public boolean canHandlePlugin(URI activityURI) {
+		String activityUriStr = activityURI.toASCIIString();
+		return activityUriStr.startsWith(activityRavenURI.toASCIIString())
+				&& activityUriStr.endsWith(activityClassName);
+	}
+
+	@Override
+	public URI mapT2flowRavenIdToScufl2URI(URI t2flowActivity) {
+		return ACTIVITY_URI;
+	}
+
+	@Override
+	public Configuration parseConfiguration(T2FlowParser t2FlowParser, ConfigBean configBean,
+			ParserState parserState) throws ReaderException {
+		SpreadsheetImportConfig config = unmarshallConfig(t2FlowParser, configBean, "xstream",
+				SpreadsheetImportConfig.class);
+
+		Configuration configuration = new Configuration();
+		configuration.setParent(parserState.getCurrentProfile());
+
+		ObjectNode json = (ObjectNode) configuration.getJson();
+		configuration.setType(ACTIVITY_URI.resolve("#Config"));
+
+		ObjectNode columnRange = json.objectNode();
+		json.put("columnRange", columnRange);
+		makeRange(config.getColumnRange(), columnRange);
+
+		ObjectNode rowRange = json.objectNode();
+        json.put("rowRange", rowRange);
+        makeRange(config.getRowRange(), rowRange);
+
+		if (config.getEmptyCellValue() != null)
+		    json.put("emptyCellValue", config.getEmptyCellValue());
+		
+		ArrayNode columnNames = json.arrayNode();
+        if (config.getColumnNames() != null && config.getColumnNames().getEntry() != null) {
+    		for (SpreadsheetColumnNameEntry entry : config.getColumnNames().getEntry()) {
+    		    ObjectNode mapping = json.objectNode();
+    		    columnNames.add(mapping);
+                mapping.put("column", entry.getString().get(0));
+                mapping.put("port", entry.getString().get(1));
+    		}
+    		if (columnNames.size() > 0)
+    		    json.put("columnNames", columnNames);
+        }
+		
+		json.put("allRows", config.isAllRows());
+		json.put("excludeFirstRow", config.isExcludeFirstRow());
+		json.put("ignoreBlankRows", config.isIgnoreBlankRows());
+		if (config.getEmptyCellPolicy() != null)
+			json.put("emptyCellPolicy", config.getEmptyCellPolicy().value());
+		if (config.getOutputFormat() != null)
+			json.put("outputFormat", config.getOutputFormat().value());
+		if (config.getCsvDelimiter() != null)
+			json.put("csvDelimiter", config.getCsvDelimiter());
+
+		return configuration;
+	}
+
+	private void makeRange(SpreadsheetRange range, ObjectNode rangeJson) {
+		rangeJson.put("start", range.getStart().longValue());
+        rangeJson.put("end", range.getEnd().longValue());
+        
+        ArrayNode excludes = rangeJson.arrayNode();
+		for (SpreadsheetRange excludesRange : range.getExcludes().getExclude()) {
+			ObjectNode exclude = rangeJson.objectNode();
+			makeRange(excludesRange, exclude);
+		    excludes.add(exclude);
+		}
+		if (excludes.size() > 0)
+		    rangeJson.put("excludes", excludes);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/StringConstantActivityParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/StringConstantActivityParser.java b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/StringConstantActivityParser.java
new file mode 100644
index 0000000..cb77ef8
--- /dev/null
+++ b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/StringConstantActivityParser.java
@@ -0,0 +1,79 @@
+package org.apache.taverna.scufl2.translator.t2flow.defaultactivities;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+
+import static org.apache.taverna.scufl2.translator.t2flow.T2FlowParser.ravenURI;
+
+import java.net.URI;
+
+import org.apache.taverna.scufl2.api.activity.Activity;
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.api.port.OutputActivityPort;
+import org.apache.taverna.scufl2.translator.t2flow.ParserState;
+import org.apache.taverna.scufl2.translator.t2flow.T2FlowParser;
+
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ConfigBean;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.StringConstantConfig;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class StringConstantActivityParser extends AbstractActivityParser {
+	private static final String VALUE = "value";
+	private static final URI activityRavenURI = ravenURI
+			.resolve("net.sf.taverna.t2.activities/stringconstant-activity/");
+	private static final String activityClassName = "net.sf.taverna.t2.activities.stringconstant.StringConstantActivity";
+	public static final URI CONSTANT = URI
+			.create("http://ns.taverna.org.uk/2010/activity/constant");
+
+	@Override
+	public boolean canHandlePlugin(URI activityURI) {
+		String activityUriStr = activityURI.toASCIIString();
+		return activityUriStr.startsWith(activityRavenURI.toASCIIString())
+				&& activityUriStr.endsWith(activityClassName);
+	}
+
+	@Override
+	public URI mapT2flowRavenIdToScufl2URI(URI t2flowActivity) {
+		return CONSTANT;
+	}
+
+	@Override
+	public Configuration parseConfiguration(T2FlowParser t2FlowParser,
+			ConfigBean configBean, ParserState parserState) throws ReaderException {
+		StringConstantConfig strConfig = unmarshallConfig(t2FlowParser,
+				configBean, "xstream", StringConstantConfig.class);
+		String value = strConfig.getValue();
+		if (value == null)
+			throw new ReaderException("String constant configuration has no value set");
+		Configuration configuration = new Configuration();
+		ObjectNode json = (ObjectNode) configuration.getJson();
+		configuration.setType(CONSTANT.resolve("#Config"));
+		json.put("string", value);
+		
+		Activity activity = parserState.getCurrentActivity();
+		OutputActivityPort valuePort = new OutputActivityPort(activity, VALUE);
+		valuePort.setDepth(0);
+		valuePort.setGranularDepth(0);
+		return configuration;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/WSDLActivityParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/WSDLActivityParser.java b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/WSDLActivityParser.java
new file mode 100644
index 0000000..ffb6537
--- /dev/null
+++ b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/WSDLActivityParser.java
@@ -0,0 +1,104 @@
+package org.apache.taverna.scufl2.translator.t2flow.defaultactivities;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+
+import static org.apache.taverna.scufl2.translator.t2flow.T2FlowParser.ravenURI;
+
+import java.net.URI;
+
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.translator.t2flow.ParserState;
+import org.apache.taverna.scufl2.translator.t2flow.T2FlowParser;
+
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ConfigBean;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.WSDLConfig;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class WSDLActivityParser extends AbstractActivityParser {
+	private static final URI wsdlActivityRavenURI = ravenURI
+			.resolve("net.sf.taverna.t2.activities/wsdl-activity/");
+	private static final String wsdlActivityClassName = "net.sf.taverna.t2.activities.wsdl.WSDLActivity";
+	public static final URI WSDL = URI
+			.create("http://ns.taverna.org.uk/2010/activity/wsdl");
+	public static final URI SECURITY = WSDL.resolve("wsdl/security");
+	public static final URI OPERATION = WSDL.resolve("wsdl/operation");
+
+	@Override
+	public boolean canHandlePlugin(URI activityURI) {
+		String activityUriStr = activityURI.toASCIIString();
+		if (!activityUriStr.startsWith(wsdlActivityRavenURI.toASCIIString()))
+			return false;
+		if (activityUriStr.endsWith(wsdlActivityClassName))
+			return true;
+		return false;
+	}
+
+	@Override
+	public URI mapT2flowRavenIdToScufl2URI(URI t2flowActivity) {
+		return WSDL;
+	}
+
+	@Override
+	public Configuration parseConfiguration(T2FlowParser t2FlowParser,
+			ConfigBean configBean, ParserState parserState)
+			throws ReaderException {
+		WSDLConfig wsdlConfig = unmarshallConfig(t2FlowParser, configBean,
+				"xstream", WSDLConfig.class);
+
+		Configuration configuration = new Configuration();
+		configuration.setType(WSDL.resolve("#Config"));
+
+		URI wsdl;
+		try {
+			wsdl = URI.create(wsdlConfig.getWsdl());
+			if (!wsdl.isAbsolute())
+				throw new ReaderException("WSDL URI is not absolute: "
+						+ wsdlConfig.getWsdl());
+		} catch (IllegalArgumentException ex) {
+			throw new ReaderException("WSDL not a valid URI: "
+					+ wsdlConfig.getWsdl());
+		} catch (NullPointerException ex) {
+			throw new ReaderException("WSDL config has no wsdl set");
+		}
+		String operation = wsdlConfig.getOperation();
+		if (operation == null || operation.equals(""))
+			throw new ReaderException("WSDL config has no operation set");
+
+		ObjectNode json = (ObjectNode) configuration.getJson();
+
+		ObjectNode wsdlOperation = json.objectNode();
+		json.put("operation", wsdlOperation);
+
+		wsdlOperation.put("wsdl", wsdl.toString());
+		wsdlOperation.put("name", operation);
+
+		if (wsdlConfig.getSecurityProfile() != null
+				&& !wsdlConfig.getSecurityProfile().isEmpty()) {
+			URI securityProfileURI = SECURITY.resolve("#"
+					+ wsdlConfig.getSecurityProfile());
+			json.put("securityProfile", securityProfileURI.toString());
+		}
+		return configuration;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/WSDLXMLSplitterParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/WSDLXMLSplitterParser.java b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/WSDLXMLSplitterParser.java
new file mode 100644
index 0000000..2b9e64b
--- /dev/null
+++ b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultactivities/WSDLXMLSplitterParser.java
@@ -0,0 +1,102 @@
+package org.apache.taverna.scufl2.translator.t2flow.defaultactivities;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+
+import static org.apache.taverna.scufl2.translator.t2flow.defaultactivities.WSDLActivityParser.WSDL;
+
+import java.net.URI;
+
+import org.apache.taverna.scufl2.api.activity.Activity;
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.translator.t2flow.ParserState;
+import org.apache.taverna.scufl2.translator.t2flow.T2FlowParser;
+
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ActivityPortDefinitionBean;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ConfigBean;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.XMLSplitterConfig;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class WSDLXMLSplitterParser extends AbstractActivityParser {
+	private static final URI wsdlActivityRavenURI = T2FlowParser.ravenURI
+			.resolve("net.sf.taverna.t2.activities/wsdl-activity/");
+	private static final String inputSplitterClassName = "net.sf.taverna.t2.activities.wsdl.xmlsplitter.XMLInputSplitterActivity";
+	private static final String outputSplitterClassName = "net.sf.taverna.t2.activities.wsdl.xmlsplitter.XMLOutputSplitterActivity";
+	public static final URI SPLITTER = WSDL.resolve("xml-splitter");
+	public static final URI XML_INPUT_SPLITTER = SPLITTER
+			.resolve("xml-splitter/in");
+	public static final URI XML_OUTPUT_SPLITTER = SPLITTER
+			.resolve("xml-splitter/out");
+
+	@Override
+	public boolean canHandlePlugin(URI activityURI) {
+		String activityUriStr = activityURI.toASCIIString();
+		if (!activityUriStr.startsWith(wsdlActivityRavenURI.toASCIIString()))
+			return false;
+		return activityUriStr.endsWith(inputSplitterClassName)
+				|| activityUriStr.endsWith(outputSplitterClassName);
+	}
+
+	@Override
+	public URI mapT2flowRavenIdToScufl2URI(URI t2flowActivity) {
+		String activityUriStr = t2flowActivity.toASCIIString();
+		if (activityUriStr.endsWith(inputSplitterClassName))
+			return XML_INPUT_SPLITTER;
+		else if (activityUriStr.endsWith(outputSplitterClassName))
+			return XML_OUTPUT_SPLITTER;
+		throw new IllegalArgumentException("Unexpected URI " + t2flowActivity);
+	}
+
+	@Override
+	public Configuration parseConfiguration(T2FlowParser t2FlowParser,
+			ConfigBean configBean, ParserState parserState)
+			throws ReaderException {
+		XMLSplitterConfig splitterConfig = unmarshallConfig(t2FlowParser,
+				configBean, "xstream", XMLSplitterConfig.class);
+
+		Configuration configuration = new Configuration();
+		configuration.setParent(parserState.getCurrentProfile());
+
+		ObjectNode json = (ObjectNode) configuration.getJson();
+		configuration.setType(SPLITTER.resolve("#Config"));
+
+		String wrappedTypeXML = splitterConfig.getWrappedTypeXML();
+
+		json.put("wrappedType", wrappedTypeXML);
+
+		Activity activity = parserState.getCurrentActivity();
+		activity.getInputPorts().clear();
+		activity.getOutputPorts().clear();
+
+		for (ActivityPortDefinitionBean portBean : splitterConfig
+				.getInputs()
+				.getNetSfTavernaT2WorkflowmodelProcessorActivityConfigActivityInputPortDefinitionBean())
+			parseAndAddInputPortDefinition(portBean, configuration, activity);
+		for (ActivityPortDefinitionBean portBean : splitterConfig
+				.getOutputs()
+				.getNetSfTavernaT2WorkflowmodelProcessorActivityConfigActivityOutputPortDefinitionBean())
+			parseAndAddOutputPortDefinition(portBean, configuration, activity);
+
+		return configuration;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/ErrorBounceParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/ErrorBounceParser.java b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/ErrorBounceParser.java
new file mode 100644
index 0000000..ef8437d
--- /dev/null
+++ b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/ErrorBounceParser.java
@@ -0,0 +1,61 @@
+package org.apache.taverna.scufl2.translator.t2flow.defaultdispatchstack;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+
+import static org.apache.taverna.scufl2.translator.t2flow.T2FlowParser.ravenURI;
+
+import java.net.URI;
+
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.translator.t2flow.ParserState;
+import org.apache.taverna.scufl2.translator.t2flow.T2FlowParser;
+import org.apache.taverna.scufl2.translator.t2flow.defaultactivities.AbstractActivityParser;
+
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ConfigBean;
+
+public class ErrorBounceParser extends AbstractActivityParser {
+	private static final URI bouncerRavenURI = ravenURI
+			.resolve("net.sf.taverna.t2.core/workflowmodel-impl/");
+	private static final String className = "net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.ErrorBounce";
+	public static final URI scufl2Uri = URI
+			.create("http://ns.taverna.org.uk/2010/scufl2/taverna/dispatchlayer/ErrorBounce");
+
+	@Override
+	public boolean canHandlePlugin(URI pluginURI) {
+		String uriStr = pluginURI.toASCIIString();
+		return uriStr.startsWith(bouncerRavenURI.toASCIIString())
+				&& uriStr.endsWith(className);
+	}
+
+	@Override
+	public URI mapT2flowRavenIdToScufl2URI(URI t2flowActivity) {
+		return scufl2Uri;
+	}
+
+	@Override
+	public Configuration parseConfiguration(T2FlowParser t2FlowParser,
+			ConfigBean configBean, ParserState parserState)
+			throws ReaderException {
+		return null; // no config!
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/FailoverParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/FailoverParser.java b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/FailoverParser.java
new file mode 100644
index 0000000..6ea8864
--- /dev/null
+++ b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/FailoverParser.java
@@ -0,0 +1,60 @@
+package org.apache.taverna.scufl2.translator.t2flow.defaultdispatchstack;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+
+import static org.apache.taverna.scufl2.translator.t2flow.T2FlowParser.ravenURI;
+
+import java.net.URI;
+
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.translator.t2flow.ParserState;
+import org.apache.taverna.scufl2.translator.t2flow.T2FlowParser;
+import org.apache.taverna.scufl2.translator.t2flow.defaultactivities.AbstractActivityParser;
+
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ConfigBean;
+
+public class FailoverParser extends AbstractActivityParser {
+	private static final URI modelRavenURI = ravenURI
+			.resolve("net.sf.taverna.t2.core/workflowmodel-impl/");
+	private static final String className = "net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Failover";
+	public static final URI scufl2Uri = URI
+			.create("http://ns.taverna.org.uk/2010/scufl2/taverna/dispatchlayer/Failover");
+
+	@Override
+	public boolean canHandlePlugin(URI pluginURI) {
+		String uriStr = pluginURI.toASCIIString();
+		return uriStr.startsWith(modelRavenURI.toASCIIString())
+				&& uriStr.endsWith(className);
+	}
+
+	@Override
+	public URI mapT2flowRavenIdToScufl2URI(URI t2flowActivity) {
+		return scufl2Uri;
+	}
+
+	@Override
+	public Configuration parseConfiguration(T2FlowParser t2FlowParser,
+			ConfigBean configBean, ParserState parserState) throws ReaderException {
+		return null; // no config!
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/InvokeParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/InvokeParser.java b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/InvokeParser.java
new file mode 100644
index 0000000..25ae86c
--- /dev/null
+++ b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/InvokeParser.java
@@ -0,0 +1,61 @@
+package org.apache.taverna.scufl2.translator.t2flow.defaultdispatchstack;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+
+import static org.apache.taverna.scufl2.translator.t2flow.T2FlowParser.ravenURI;
+
+import java.net.URI;
+
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.translator.t2flow.ParserState;
+import org.apache.taverna.scufl2.translator.t2flow.T2FlowParser;
+import org.apache.taverna.scufl2.translator.t2flow.defaultactivities.AbstractActivityParser;
+
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ConfigBean;
+
+public class InvokeParser extends AbstractActivityParser {
+	private static final URI modelRavenURI = ravenURI
+			.resolve("net.sf.taverna.t2.core/workflowmodel-impl/");
+	private static final String className = "net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Invoke";
+	public static final URI scufl2Uri = URI
+			.create("http://ns.taverna.org.uk/2010/scufl2/taverna/dispatchlayer/Invoke");
+
+	@Override
+	public boolean canHandlePlugin(URI pluginURI) {
+		String uriStr = pluginURI.toASCIIString();
+		return uriStr.startsWith(modelRavenURI.toASCIIString())
+				&& uriStr.endsWith(className);
+	}
+
+	@Override
+	public URI mapT2flowRavenIdToScufl2URI(URI t2flowActivity) {
+		return scufl2Uri;
+	}
+
+	@Override
+	public Configuration parseConfiguration(T2FlowParser t2FlowParser,
+			ConfigBean configBean, ParserState parserState)
+			throws ReaderException {
+		return null; // no config!
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/LoopParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/LoopParser.java b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/LoopParser.java
new file mode 100644
index 0000000..d742c82
--- /dev/null
+++ b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/LoopParser.java
@@ -0,0 +1,138 @@
+package org.apache.taverna.scufl2.translator.t2flow.defaultdispatchstack;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+
+import static org.apache.taverna.scufl2.translator.t2flow.T2FlowParser.ravenURI;
+
+import java.net.URI;
+
+import javax.xml.bind.JAXBException;
+
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.translator.t2flow.ParserState;
+import org.apache.taverna.scufl2.translator.t2flow.T2FlowParser;
+import org.apache.taverna.scufl2.translator.t2flow.defaultactivities.AbstractActivityParser;
+
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.Activity;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ConfigBean;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.LoopConfig;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.Property;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class LoopParser extends AbstractActivityParser {
+	/**
+	 * Expose some of the useful activity/config parser methods to LoopParser
+	 * with a different parser state.
+	 * <p>
+	 * TODO: Refactor T2FlowParser to avoid the need for this 
+	 */
+	protected class ConditionalActivityParser extends T2FlowParser {
+		public ConditionalActivityParser(ParserState origState) throws JAXBException {
+			super();
+			parserState.get().setCurrentProfile(origState.getCurrentProfile());
+			parserState.get().setCurrentProcessor(origState.getCurrentProcessor());
+		}
+		@Override
+		public org.apache.taverna.scufl2.api.activity.Activity parseActivity(
+				Activity origActivity) throws ReaderException {
+			org.apache.taverna.scufl2.api.activity.Activity parsed = super.parseActivity(origActivity);
+			parserState.get().setCurrentActivity(parsed);
+			return parsed;
+		}
+		@Override
+		protected Configuration parseConfiguration(ConfigBean configBean)
+				throws JAXBException, ReaderException {
+			return super.parseConfiguration(configBean);
+		}
+	}
+
+	private static final URI modelRavenURI = ravenURI
+			.resolve("net.sf.taverna.t2.core/workflowmodel-impl/");
+	private static final String className = "net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Loop";
+	public static final URI scufl2Uri = URI
+			.create("http://ns.taverna.org.uk/2010/scufl2/taverna/dispatchlayer/Loop");
+
+	@Override
+	public boolean canHandlePlugin(URI pluginURI) {
+		String uriStr = pluginURI.toASCIIString();
+		return uriStr.startsWith(modelRavenURI.toASCIIString())
+				&& uriStr.endsWith(className);
+	}
+
+	@Override
+	public URI mapT2flowRavenIdToScufl2URI(URI t2flowActivity) {
+		return scufl2Uri;
+	}
+
+	@Override
+	public Configuration parseConfiguration(T2FlowParser t2FlowParser,
+			ConfigBean configBean, ParserState parserState)
+			throws ReaderException {
+		LoopConfig loopConfig = unmarshallConfig(t2FlowParser, configBean,
+				"xstream", LoopConfig.class);
+
+		final Configuration c = new Configuration();
+		c.setType(scufl2Uri.resolve("Config"));
+
+		ObjectNode json = (ObjectNode) c.getJson();
+
+		json.put("runFirst", loopConfig.isRunFirst());
+
+		for (Property prop : loopConfig.getProperties().getProperty())
+			json.put(prop.getName(), prop.getValue());
+		
+		String conditionXml = loopConfig.getConditionXML();	
+		if (conditionXml == null)
+		    // activity is unconfigured (bug in T2). 
+		    // Return c only if there are properties beyond "runFirst"
+			return json.size() > 1 ? c : null;
+		Activity conditionActivity = unmarshallXml(
+				parserState.getT2FlowParser(), conditionXml, Activity.class);
+		try {
+			ConditionalActivityParser internalParser = new ConditionalActivityParser(
+					parserState);
+
+			org.apache.taverna.scufl2.api.activity.Activity newActivity = internalParser
+					.parseActivity(conditionActivity);
+			String name = parserState.getCurrentProcessor().getName() + "-loop";
+			newActivity.setName(name);
+			parserState.getCurrentProfile().getActivities()
+					.addWithUniqueName(newActivity);
+			newActivity.setParent(parserState.getCurrentProfile());
+
+			Configuration newConfig = internalParser
+					.parseConfiguration(conditionActivity.getConfigBean());
+			newConfig.setName(name);
+			newConfig.setConfigures(newActivity);
+			parserState.getCurrentProfile().getConfigurations()
+					.addWithUniqueName(newConfig);
+			// URI uriActivity = uriTools.relativeUriForBean(newActivity, parserState.getCurrentProfile());
+			json.put("conditionActivity", newActivity.getName());
+		} catch (JAXBException e) {
+			throw new ReaderException("Can't parse conditional loop activity",
+					e);
+		}
+		return c;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/ParallelizeParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/ParallelizeParser.java b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/ParallelizeParser.java
new file mode 100644
index 0000000..977b4c9
--- /dev/null
+++ b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/ParallelizeParser.java
@@ -0,0 +1,83 @@
+package org.apache.taverna.scufl2.translator.t2flow.defaultdispatchstack;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+
+import static org.apache.taverna.scufl2.translator.t2flow.T2FlowParser.ravenURI;
+
+import java.math.BigInteger;
+import java.net.URI;
+
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.translator.t2flow.ParserState;
+import org.apache.taverna.scufl2.translator.t2flow.T2FlowParser;
+import org.apache.taverna.scufl2.translator.t2flow.defaultactivities.AbstractActivityParser;
+
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ConfigBean;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ParallelizeConfig;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class ParallelizeParser extends AbstractActivityParser {
+
+	private static URI modelRavenURI = ravenURI
+			.resolve("net.sf.taverna.t2.core/workflowmodel-impl/");
+
+	private static String className = "net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Parallelize";
+
+	public static URI scufl2Uri = URI
+			.create("http://ns.taverna.org.uk/2010/scufl2/taverna/dispatchlayer/Parallelize");
+
+	public static class Defaults {
+		public static int maxJobs = 1;
+	}
+
+	@Override
+	public boolean canHandlePlugin(URI pluginURI) {
+		String uriStr = pluginURI.toASCIIString();
+		return uriStr.startsWith(modelRavenURI.toASCIIString())
+				&& uriStr.endsWith(className);
+	}
+
+	@Override
+	public URI mapT2flowRavenIdToScufl2URI(URI t2flowActivity) {
+		return scufl2Uri;
+	}
+
+	@Override
+	public Configuration parseConfiguration(T2FlowParser t2FlowParser,
+			ConfigBean configBean, ParserState parserState)
+			throws ReaderException {
+		ParallelizeConfig parallelConfig = unmarshallConfig(t2FlowParser,
+				configBean, "xstream", ParallelizeConfig.class);
+		Configuration c = new Configuration();
+		c.setType(scufl2Uri.resolve("#Config"));
+
+		BigInteger maxJobs = parallelConfig.getMaxJobs();
+		if (maxJobs != null && maxJobs.intValue() > 0
+				&& maxJobs.intValue() != Defaults.maxJobs) {
+			ObjectNode json = (ObjectNode) c.getJson();
+			json.put("maxJobs", maxJobs.intValue());
+		}
+		return c;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/RetryParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/RetryParser.java b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/RetryParser.java
new file mode 100644
index 0000000..e1194f0
--- /dev/null
+++ b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/defaultdispatchstack/RetryParser.java
@@ -0,0 +1,107 @@
+package org.apache.taverna.scufl2.translator.t2flow.defaultdispatchstack;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+
+import static org.apache.taverna.scufl2.translator.t2flow.T2FlowParser.ravenURI;
+import static org.apache.taverna.scufl2.translator.t2flow.defaultdispatchstack.RetryParser.Defaults.BACKOFF_FACTOR;
+import static org.apache.taverna.scufl2.translator.t2flow.defaultdispatchstack.RetryParser.Defaults.INITIAL_DELAY;
+import static org.apache.taverna.scufl2.translator.t2flow.defaultdispatchstack.RetryParser.Defaults.MAX_DELAY;
+import static org.apache.taverna.scufl2.translator.t2flow.defaultdispatchstack.RetryParser.Defaults.MAX_RETRIES;
+
+import java.math.BigInteger;
+import java.net.URI;
+
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.translator.t2flow.ParserState;
+import org.apache.taverna.scufl2.translator.t2flow.T2FlowParser;
+import org.apache.taverna.scufl2.translator.t2flow.defaultactivities.AbstractActivityParser;
+
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ConfigBean;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.RetryConfig;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class RetryParser extends AbstractActivityParser {
+	private static final URI modelRavenURI =
+		ravenURI.resolve("net.sf.taverna.t2.core/workflowmodel-impl/");
+	private static final String className = "net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Retry";
+	public static final URI scufl2Uri = URI
+			.create("http://ns.taverna.org.uk/2010/scufl2/taverna/dispatchlayer/Retry");
+
+	@Override
+	public boolean canHandlePlugin(URI pluginURI) {
+		String uriStr = pluginURI.toASCIIString();
+		return uriStr.startsWith(modelRavenURI.toASCIIString())
+				&& uriStr.endsWith(className);
+	}
+
+	/**
+	 * Default values - ignored for now
+	 */
+	public static final class Defaults {
+		public static final int MAX_RETRIES = 0;
+		public static final int INITIAL_DELAY = 1000;
+		public static final int MAX_DELAY = 5000;
+		public static final double BACKOFF_FACTOR = 1.0;
+	}
+	
+	@Override
+	public URI mapT2flowRavenIdToScufl2URI(URI t2flowActivity) {
+		return scufl2Uri;
+	}
+
+	@Override
+	public Configuration parseConfiguration(T2FlowParser t2FlowParser,
+			ConfigBean configBean, ParserState parserState)
+			throws ReaderException {
+		RetryConfig config = unmarshallConfig(t2FlowParser, configBean,
+				"xstream", RetryConfig.class);
+
+		Configuration c = new Configuration();
+		c.setType(scufl2Uri.resolve("#Config"));
+
+		ObjectNode json = (ObjectNode) c.getJson();
+
+		BigInteger maxRetries = config.getMaxRetries();
+		if (maxRetries != null
+				&& (maxRetries.longValue() != MAX_RETRIES || maxRetries
+						.longValue() < 0))
+			json.put("maxRetries", maxRetries.longValue());
+
+		if (maxRetries != null && maxRetries.longValue() != 0) {
+			// Neither of these makes sense if retries are disabled
+
+			if (config.getInitialDelay() != INITIAL_DELAY
+					&& config.getInitialDelay() > -1)
+				json.put("initialDelay", config.getInitialDelay());
+
+			if (config.getMaxDelay() != MAX_DELAY && config.getMaxDelay() > -1)
+				json.put("maxDelay", config.getMaxDelay());
+
+			double delta = Math.abs(config.getBackoffFactor() - BACKOFF_FACTOR);
+			if (config.getBackoffFactor() > 0 && delta > 1e-14)
+				json.put("backoffFactor", config.getBackoffFactor());
+		}
+		return c;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/t23activities/ExternalToolActivityParser.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/t23activities/ExternalToolActivityParser.java b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/t23activities/ExternalToolActivityParser.java
new file mode 100644
index 0000000..7f5aa8c
--- /dev/null
+++ b/taverna-scufl2-t2flow/src/main/java/org/apache/taverna/scufl2/translator/t2flow/t23activities/ExternalToolActivityParser.java
@@ -0,0 +1,522 @@
+package org.apache.taverna.scufl2.translator.t2flow.t23activities;
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+
+import static org.apache.taverna.scufl2.translator.t2flow.T2FlowParser.ravenURI;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.translator.t2flow.ParserState;
+import org.apache.taverna.scufl2.translator.t2flow.T2FlowParser;
+import org.apache.taverna.scufl2.translator.t2flow.defaultactivities.AbstractActivityParser;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ConfigBean;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.Entry;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ExternalToolConfig;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.Group;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ScriptInputStatic;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ScriptInputUser;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.ScriptOutput;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.UsecaseConfig;
+import org.apache.taverna.scufl2.xml.t2flow.jaxb.UsecaseDescription;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class ExternalToolActivityParser extends AbstractActivityParser {
+	@SuppressWarnings("unused")
+	private static final String STDOUT = "STDOUT";
+	@SuppressWarnings("unused")
+	private static final String STDIN = "STDIN";
+	@SuppressWarnings("unused")
+	private static final String STDERR = "STDERR";
+	private static final String EXTERNALTOOLACTIVITY_XSD = "/org/apache/taverna/scufl2/translator/t2flow/xsd/externaltoolactivity.xsd";
+	public static final URI CNT = URI.create("http://www.w3.org/2011/content#");
+	public static final URI CHARSET = URI
+			.create("http://www.iana.org/assignments/character-sets#");
+	// or http://www.iana.org/assignments/charset-reg/ ?
+	private static final URI usecaseActivityRavenUri = ravenURI
+			.resolve("net.sf.taverna.t2.activities/usecase-activity/");
+	private static final String usecaseActivityClass = "net.sf.taverna.t2.activities.usecase.UseCaseActivity";
+	private static final URI externalToolRavenUri = ravenURI
+			.resolve("net.sf.taverna.t2.activities/external-tool-activity/");
+	private static final String externalToolClass = "net.sf.taverna.t2.activities.externaltool.ExternalToolActivity";
+	public static final URI ACTIVITY_URI = URI
+			.create("http://ns.taverna.org.uk/2010/activity/tool");
+	public static final URI DC = URI.create("http://purl.org/dc/elements/1.1/");
+
+	@SuppressWarnings("unused")
+	private Map<URI, URI> mappedMechanismTypes = makeMappedMechanismTypes();
+
+	private Map<URI, URI> makeMappedMechanismTypes() {
+		Map<URI, URI> map = new HashMap<>();
+		map.put(ACTIVITY_URI.resolve("#789663B8-DA91-428A-9F7D-B3F3DA185FD4"),
+				ACTIVITY_URI.resolve("#local"));
+		map.put(ACTIVITY_URI.resolve("#D0A4CDEB-DD10-4A8E-A49C-8871003083D8"),
+				ACTIVITY_URI.resolve("#ssh"));
+		return map;
+	}
+
+	@Override
+	public boolean canHandlePlugin(URI activityURI) {
+		String activityUriStr = activityURI.toASCIIString();
+		if (activityUriStr.startsWith(usecaseActivityRavenUri.toASCIIString())
+				&& activityUriStr.endsWith(usecaseActivityClass))
+			return true;
+		return activityUriStr.startsWith(externalToolRavenUri.toASCIIString())
+				&& activityUriStr.endsWith(externalToolClass);
+	}
+
+	@Override
+	public List<URI> getAdditionalSchemas() {
+		URL externalToolXsd = ExternalToolActivityParser.class
+				.getResource(EXTERNALTOOLACTIVITY_XSD);
+		try {
+			return Arrays.asList(externalToolXsd.toURI());
+		} catch (Exception e) {
+			throw new IllegalStateException("Can't find external tool schema "
+					+ externalToolXsd);
+		}
+	}
+
+	@Override
+	public URI mapT2flowRavenIdToScufl2URI(URI t2flowActivity) {
+		return ACTIVITY_URI;
+	}
+
+	@Override
+	public Configuration parseConfiguration(T2FlowParser t2FlowParser,
+			ConfigBean configBean, ParserState parserState)
+			throws ReaderException {
+		ExternalToolConfig externalToolConfig = null;
+		UsecaseConfig usecaseConfig = null;
+
+		try {
+			externalToolConfig = unmarshallConfig(t2FlowParser, configBean,
+					"xstream", ExternalToolConfig.class);
+		} catch (ReaderException ex) {
+			usecaseConfig = unmarshallConfig(t2FlowParser, configBean,
+					"xstream", UsecaseConfig.class);
+		}
+
+		Configuration configuration = new Configuration();
+		configuration.setParent(parserState.getCurrentProfile());
+		parserState.setCurrentConfiguration(configuration);
+		try {
+			ObjectNode json = configuration.getJsonAsObjectNode();
+
+			configuration.setType(ACTIVITY_URI.resolve("#Config"));
+
+			if (usecaseConfig != null) {
+				if (usecaseConfig.getRepositoryUrl() != null)
+					json.put("repositoryUrl", usecaseConfig.getRepositoryUrl());
+				json.put("toolId", usecaseConfig.getUsecaseid());
+			} else if (externalToolConfig != null) {
+				if (externalToolConfig.getRepositoryUrl() != null)
+					json.put("repositoryUrl",
+							externalToolConfig.getRepositoryUrl());
+				json.put("toolId", externalToolConfig.getExternaltoolid());
+				if (externalToolConfig.isEdited())
+					json.put("edited", externalToolConfig.isEdited());
+			}
+
+			if (externalToolConfig != null) {
+				Group group = externalToolConfig.getGroup();
+				if (group != null) {
+					ObjectNode invocationGroup = json.objectNode();
+					json.put("invocationGroup", invocationGroup);
+					invocationGroup.put("name", group.getInvocationGroupName());
+					invocationGroup.put("mechanismType",
+							group.getMechanismType());
+					invocationGroup.put("mechanismName",
+							group.getMechanismName());
+					invocationGroup
+							.put("mechanismXML", group.getMechanismXML());
+				} else {
+					json.put("mechanismType",
+							externalToolConfig.getMechanismType());
+					json.put("mechanismName",
+							externalToolConfig.getMechanismName());
+					json.put("mechanismXML",
+							externalToolConfig.getMechanismXML());
+				}
+//				URI mechanismTypeURI = ACTIVITY_URI.resolve("#"
+//						+ uriTools.validFilename(mechanismType));
+//				if (mappedMechanismTypes.containsKey(mechanismTypeURI)) {
+//					mechanismTypeURI = mappedMechanismTypes.get(mechanismTypeURI);
+//				}
+//				invocation.addPropertyReference(ACTIVITY_URI.resolve("#mechanismType"),
+//						mechanismTypeURI);
+//
+//				invocation.addPropertyAsString(ACTIVITY_URI.resolve("#mechanismName"),
+//						mechanismName);
+//				invocation.addProperty(ACTIVITY_URI.resolve("#mechanismXML"), new PropertyLiteral(
+//						mechanismXML, PropertyLiteral.XML_LITERAL));
+                
+                // TODO: Extract SSH hostname etc. from mechanismXML
+//				parseMechanismXML(json);
+
+				ObjectNode toolDescription = json.objectNode();
+				parseToolDescription(toolDescription,
+						externalToolConfig.getUseCaseDescription(), parserState);
+				json.put("toolDescription", toolDescription);
+
+//				configResource.addProperty(ACTIVITY_URI.resolve("#invocationGroup"),
+//						parseGroup(externalToolConfig.getGroup()));
+
+			}
+
+			return configuration;
+		} finally {
+			parserState.setCurrentConfiguration(null);
+		}
+	}
+
+//	private void parseMechanismXML(ObjectNode invocation) {
+//	    type = invocatoin.
+//	    
+//		URI type = invocation.getPropertyAsResourceURI(ACTIVITY_URI.resolve("#mechanismType"));
+//		if (type.equals(ACTIVITY_URI.resolve("#local"))) {
+//			Element xml = invocation.getPropertyAsLiteral(ACTIVITY_URI.resolve("#mechanismXML"))
+//					.getLiteralValueAsElement();
+//
+//			String directory = elementByTag(xml, "directory");
+//			String linkCommand = elementByTag(xml, "linkCommand");
+//			String shellPrefix = elementByTag(xml, "shellPrefix");
+//			PropertyResource node = new PropertyResource();
+//			node.setTypeURI(ACTIVITY_URI.resolve("#LocalNode"));
+//			if (directory != null) {
+//				node.addPropertyAsString(ACTIVITY_URI.resolve("#directory"), directory);
+//			}
+//			if (linkCommand != null) {
+//				node.addPropertyAsString(ACTIVITY_URI.resolve("#linkCommand"), linkCommand);
+//			}
+//			if (shellPrefix != null) {
+//				node.addPropertyAsString(ACTIVITY_URI.resolve("#shellPrefix"), shellPrefix);
+//			}
+//			if (!node.getProperties().isEmpty()) {
+//				// Only add if it is customized
+//				invocation.addProperty(ACTIVITY_URI.resolve("#node"), node);
+//			}
+//
+//			invocation.getProperties().remove(ACTIVITY_URI.resolve("#mechanismXML"));
+//		} else if (type.equals(ACTIVITY_URI.resolve("#ssh"))) {
+//			Element xml = invocation.getPropertyAsLiteral(ACTIVITY_URI.resolve("#mechanismXML"))
+//					.getLiteralValueAsElement();
+//			for (Element sshNode : elementIter(xml.getElementsByTagName("sshNode"))) {
+//				String hostname = elementByTag(sshNode, "host");
+//				String port = elementByTag(sshNode, "port");
+//				String directory = elementByTag(sshNode, "directory");
+//				String linkCommand = elementByTag(sshNode, "linkCommand");
+//				String copyCommand = elementByTag(sshNode, "copyCommand");
+//
+//				PropertyResource node = invocation.addPropertyAsNewResource(
+//						ACTIVITY_URI.resolve("#node"), ACTIVITY_URI.resolve("#SSHNode"));
+//				node.addPropertyAsString(ACTIVITY_URI.resolve("#hostname"), hostname);
+//				if (port != null) {
+//					PropertyLiteral portLit = new PropertyLiteral(port, PropertyLiteral.XSD_INT);
+//					node.addProperty(ACTIVITY_URI.resolve("#port"), portLit);
+//				}
+//				if (directory != null) {
+//					node.addPropertyAsString(ACTIVITY_URI.resolve("#directory"), directory);
+//				}
+//				if (linkCommand != null) {
+//					node.addPropertyAsString(ACTIVITY_URI.resolve("#linkCommand"), linkCommand);
+//				}
+//				if (copyCommand != null) {
+//					node.addPropertyAsString(ACTIVITY_URI.resolve("#copyCommand"), copyCommand);
+//				}
+//			}
+//			invocation.clearProperties(ACTIVITY_URI.resolve("#mechanismXML"));
+//		} else {
+//
+//		}
+//	}
+
+	@SuppressWarnings("unused")
+	private Iterable<Element> elementIter(final NodeList nodeList) {
+		return new Iterable<Element>() {
+			@Override
+			public Iterator<Element> iterator() {
+				return new Iterator<Element>() {
+					int position = 0;
+
+					@Override
+					public boolean hasNext() {
+						return nodeList.getLength() > position;
+					}
+
+					@Override
+					public Element next() {
+						return (Element) nodeList.item(position++);
+					}
+
+					@Override
+					public void remove() {
+						throw new UnsupportedOperationException();
+					}
+				};
+			}
+		};
+	}
+
+	@SuppressWarnings("unused")
+	private String elementByTag(Element el, String tagName) {
+		NodeList nodeList = el.getElementsByTagName(tagName);
+		if (nodeList.getLength() == 0)
+			return null;
+		return nodeList.item(0).getTextContent();
+	}
+
+	protected ObjectNode parseToolDescription(ObjectNode json, UsecaseDescription toolDesc,
+			ParserState parserState) {
+	    	    ObjectNode description = json.objectNode();
+	    description.put("dc:title", toolDesc.getUsecaseid());
+		if (toolDesc.getGroup() != null)
+		    description.put("group", toolDesc.getGroup());
+		if (toolDesc.getDescription() != null)
+		      description.put("dc:description", toolDesc.getDescription());
+
+		description.put("command", toolDesc.getCommand());
+
+		description.put("preparingTimeoutInSeconds",
+				toolDesc.getPreparingTimeoutInSeconds());
+		description.put("executionTimeoutInSeconds",
+				toolDesc.getExecutionTimeoutInSeconds());
+
+		// Ignoring tags, REs, queue__preferred, queue__deny
+
+        ArrayNode staticInputs = json.arrayNode();
+        // static inputs
+		for (ScriptInputStatic inputStatic : toolDesc.getStaticInputs()
+				.getDeUniLuebeckInbKnowarcUsecasesScriptInputStatic()) {
+		    ObjectNode input = json.objectNode();
+		    staticInputs.add(input);
+		    input.put("tag", inputStatic.getTag());
+		    input.put("file", inputStatic.isFile());
+            input.put("tempFile", inputStatic.isTempFile());
+            input.put("binary", inputStatic.isBinary());
+            input.put("charsetName", inputStatic.getCharsetName());
+            input.put("forceCopy", inputStatic.isForceCopy());
+			if (inputStatic.getUrl() != null)
+	            input.put("url", inputStatic.getUrl());
+			if (inputStatic.getContent() != null)
+                input.put("content", inputStatic.getContent().getValue());
+		}
+		if (staticInputs.size() > 0)
+		    json.put("staticInputs", staticInputs);
+        
+//		for (ScriptInputStatic inputStatic : toolDesc.getStaticInputs()
+//				.getDeUniLuebeckInbKnowarcUsecasesScriptInputStatic()) {
+//			String portName = inputStatic.getTag();
+//			PropertyResource staticInput = generatePortDefinition(portName, inputStatic.getTag(),
+//					inputStatic.getCharsetName(), true, false, inputStatic.isBinary(),
+//					inputStatic.isFile(), inputStatic.isTempFile(), inputStatic.isForceCopy(),
+//					false, true, parserState);
+//
+//			configResource.addProperty(ACTIVITY_URI.resolve("#staticInput"), staticInput);
+//			if (inputStatic.getUrl() != null) {
+//				staticInput.addPropertyReference(ACTIVITY_URI.resolve("#source"),
+//						URI.create(inputStatic.getUrl()));
+//			} else {
+//				PropertyResource content = staticInput.addPropertyAsNewResource(
+//						ACTIVITY_URI.resolve("#source"), CNT.resolve("#ContentAsText"));
+//				content.addPropertyAsString(CNT.resolve("#chars"), inputStatic.getContent()
+//						.getValue());
+//				// TODO: Support bytes?
+//			}
+//		}
+
+		
+		
+		// Inputs
+		ArrayNode inputs = json.arrayNode();
+        for (Entry entry : toolDesc.getInputs().getEntry()) {
+            ObjectNode mapping = json.objectNode();
+            mapping.put("port", entry.getString());
+            ObjectNode input = json.objectNode();
+            mapping.put("input", input);
+
+            ScriptInputUser scriptInput = entry
+                    .getDeUniLuebeckInbKnowarcUsecasesScriptInputUser();
+            input.put("tag", scriptInput.getTag());
+            input.put("file", scriptInput.isFile());
+            input.put("tempFile", scriptInput.isTempFile());
+            input.put("binary", scriptInput.isBinary());
+
+            input.put("charsetName", scriptInput.getCharsetName());
+            input.put("forceCopy", scriptInput.isForceCopy());
+            input.put("list", scriptInput.isList());
+            input.put("concatenate", scriptInput.isConcatenate());
+        }
+		if (inputs.size() > 0)
+		    json.put("inputs", inputs);
+//		for (Entry entry : toolDesc.getInputs().getEntry()) {
+//			String portName = entry.getString();
+//			ScriptInputUser scriptInput = entry.getDeUniLuebeckInbKnowarcUsecasesScriptInputUser();
+//			PropertyResource portDef = generatePortDefinition(portName, scriptInput.getTag(),
+//					scriptInput.getCharsetName(), true, scriptInput.isList(),
+//					scriptInput.isBinary(), scriptInput.isFile(), scriptInput.isTempFile(),
+//					scriptInput.isForceCopy(), scriptInput.isConcatenate(), false, parserState);
+//			configResource.addProperty(Scufl2Tools.PORT_DEFINITION.resolve("#inputPortDefinition"),
+//					portDef);
+//		}
+		
+		// Outputs		
+		ArrayNode outputs = json.arrayNode();
+		for (Entry entry : toolDesc.getOutputs().getEntry()) {
+			ObjectNode mapping = json.objectNode();
+			mapping.put("port", entry.getString());
+			ObjectNode output = json.objectNode();
+			mapping.put("output", output);
+
+			ScriptOutput scriptOutput = entry
+					.getDeUniLuebeckInbKnowarcUsecasesScriptOutput();
+			output.put("path", scriptOutput.getPath());
+			output.put("binary", scriptOutput.isBinary());
+		}
+		if (outputs.size() > 0)
+			json.put("outputs", outputs);
+//		for (Entry entry : toolDesc.getOutputs().getEntry()) {
+//			String portName = entry.getString();
+//			ScriptOutput scriptOutput = entry.getDeUniLuebeckInbKnowarcUsecasesScriptOutput();
+//			PropertyResource portDef = generatePortDefinition(portName, scriptOutput.getPath(),
+//					null, false, false, scriptOutput.isBinary(), true, false, false, false, false,
+//					parserState);
+//			configResource.addProperty(
+//					Scufl2Tools.PORT_DEFINITION.resolve("#outputPortDefinition"), portDef);
+        // }
+
+        json.put("includeStdIn", toolDesc.isIncludeStdIn());
+        json.put("includeStdOut", toolDesc.isIncludeStdOut());
+        json.put("includeStdErr", toolDesc.isIncludeStdErr());
+
+//		if (toolDesc.isIncludeStdIn()) {
+//			InputActivityPort stdin = new InputActivityPort(parserState.getCurrentActivity(), STDIN);
+//			stdin.setDepth(0);
+//		}
+//		if (toolDesc.isIncludeStdOut()) {
+//			OutputActivityPort stdout = new OutputActivityPort(parserState.getCurrentActivity(),
+//					STDOUT);
+//			stdout.setDepth(0);
+//			stdout.setGranularDepth(0);
+//		}
+//		if (toolDesc.isIncludeStdErr()) {
+//			OutputActivityPort stderr = new OutputActivityPort(parserState.getCurrentActivity(),
+//					STDERR);
+//			stderr.setDepth(0);
+//			stderr.setGranularDepth(0);
+//		}
+
+		return description;
+	}
+//
+//	private PropertyResource generatePortDefinition(String portName, String tag, String charSet,
+//			boolean isInput, boolean isList, boolean isBinary, boolean isFile, boolean isTempFile,
+//			boolean isForceCopy, boolean isConcatenate, boolean isStatic, ParserState parserState) {
+//
+//		ActivityPort actPort;
+//		if (isStatic) {
+//			resource.setTypeURI(ACTIVITY_URI.resolve("#StaticInput"));
+//		} else {
+//
+//			if (isInput) {
+//				resource.setTypeURI(Scufl2Tools.PORT_DEFINITION.resolve("#InputPortDefinition"));
+//				actPort = new InputActivityPort(parserState.getCurrentActivity(), portName);
+//				URI portUri = uriTools.relativeUriForBean(actPort,
+//						parserState.getCurrentConfiguration());
+//				resource.addPropertyReference(
+//						Scufl2Tools.PORT_DEFINITION.resolve("#definesInputPort"), portUri);
+//			} else {
+//				resource.setTypeURI(Scufl2Tools.PORT_DEFINITION.resolve("#OutputPortDefinition"));
+//				actPort = new OutputActivityPort(parserState.getCurrentActivity(), portName);
+//				URI portUri = uriTools.relativeUriForBean(actPort,
+//						parserState.getCurrentConfiguration());
+//				resource.addPropertyReference(
+//						Scufl2Tools.PORT_DEFINITION.resolve("#definesOutputPort"), portUri);
+//			}
+//
+//			if (isList) {
+//				actPort.setDepth(1);
+//			} else {
+//				actPort.setDepth(0);
+//			}
+//		}
+//
+//		URI dataType = PropertyLiteral.XSD_STRING;
+//		if (isFile || isTempFile) {
+//			if (isForceCopy) {
+//				resource.addProperty(ACTIVITY_URI.resolve("#forceCopy"), new PropertyLiteral(true));
+//			}
+//
+//			if (isBinary) {
+//				// FIXME: Is there a good URI for raw bytes? xsd:byte is just
+//				// one byte,
+//				// xsd:hexBinary and xsd:base64Binary both mandate an encoding
+//				dataType = Scufl2Tools.PORT_DEFINITION.resolve("#binary");
+//			} else if (charSet != null) {
+//				resource.addPropertyReference(ACTIVITY_URI.resolve("#charset"),
+//						CHARSET.resolve("#" + uriTools.validFilename(charSet)));
+//				// TODO: Check with
+//				// http://www.w3.org/International/www-international.html if
+//				// this URI scheme really make sense
+//			} else {
+//				resource.addPropertyReference(ACTIVITY_URI.resolve("#charset"),
+//						CHARSET.resolve("#UTF-8"));
+//			}
+//		}
+//		resource.addPropertyReference(Scufl2Tools.PORT_DEFINITION.resolve("#dataType"), dataType);
+//
+//		resource.addPropertyAsString(ACTIVITY_URI.resolve("#substitutes"), tag);
+//		URI subsitutionType;
+//		if (isFile) {
+//			subsitutionType = ACTIVITY_URI.resolve("#File");
+//		} else if (isTempFile) {
+//			subsitutionType = ACTIVITY_URI.resolve("#TempFile");
+//		} else {
+//			subsitutionType = ACTIVITY_URI.resolve("#Parameter");
+//		}
+//		resource.addPropertyReference(ACTIVITY_URI.resolve("#substitutionType"), subsitutionType);
+//
+//		if (isList && isConcatenate) {
+//			resource.addProperty(ACTIVITY_URI.resolve("#concatenate"), new PropertyLiteral(true));
+//		}
+//
+//		return resource;
+//	}
+
+//	protected PropertyObject parseGroup(Group group) {
+//		PropertyResource propertyResource = new PropertyResource();
+//		propertyResource.setTypeURI(ACTIVITY_URI.resolve("#InvocationGroup"));
+//		return propertyResource;
+//	}
+}