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:19:00 UTC

[8/8] incubator-taverna-commandline git commit: Revert "temporarily empty repository"

Revert "temporarily empty repository"

This reverts commit d57ed128cd36e12f5cc1e3304f67bd5c10f0735c.


Project: http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/commit/53c8a6c1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/tree/53c8a6c1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/diff/53c8a6c1

Branch: refs/heads/master
Commit: 53c8a6c1de9f892cc516afa2919ef32322abad32
Parents: d57ed12
Author: Stian Soiland-Reyes <st...@apache.org>
Authored: Mon Feb 23 10:17:05 2015 +0000
Committer: Stian Soiland-Reyes <st...@apache.org>
Committed: Mon Feb 23 10:17:05 2015 +0000

----------------------------------------------------------------------
 .gitignore                                      |  24 +
 .travis.yml                                     |   1 +
 README.md                                       |   6 +
 pom.xml                                         |  40 ++
 taverna-commandline-api/pom.xml                 |  12 +
 .../exceptions/ArgumentsParsingException.java   |  34 +
 .../CommandLineMasterPasswordException.java     |  34 +
 .../DatabaseConfigurationException.java         |  43 ++
 .../exceptions/InputMismatchException.java      |  61 ++
 .../exceptions/InvalidOptionException.java      |  30 +
 .../exceptions/OpenDataflowException.java       |  44 ++
 .../exceptions/ReadInputException.java          |  35 +
 .../exceptions/SaveResultsException.java        |  34 +
 .../commandline/options/CommandLineOptions.java | 119 ++++
 taverna-commandline-common/pom.xml              |  88 +++
 .../CommandLineMasterPasswordProvider.java      | 184 ++++++
 .../taverna/t2/commandline/CommandLineTool.java | 437 +++++++++++++
 .../data/DatabaseConfigurationHandler.java      | 154 +++++
 .../t2/commandline/data/ErrorValueHandler.java  |  72 +++
 .../t2/commandline/data/InputsHandler.java      | 280 ++++++++
 .../t2/commandline/data/SaveResultsHandler.java |  87 +++
 .../taverna-commandline-common-context-osgi.xml |  22 +
 .../taverna-commandline-common-context.xml      |  21 +
 .../main/resources/database-defaults.properties |  11 +
 .../src/main/resources/help.txt                 |  87 +++
 .../TestDatabaseConfigurationHandler.java       |  21 +
 taverna-commandline-launcher/pom.xml            |  83 +++
 .../commandline/CommandLineOptionsImpl.java     | 445 +++++++++++++
 .../taverna/commandline/TavernaCommandLine.java | 143 ++++
 .../src/main/resources/help.txt                 |  87 +++
 .../TestCommandLineOptionsHandler.java          | 267 ++++++++
 taverna-commandline-product/pom.xml             | 529 +++++++++++++++
 .../main/assembly/dependencies-component.xml    |  21 +
 .../src/main/assembly/developer-assembly.xml    |  13 +
 .../src/main/assembly/nightly-assembly.xml      |  15 +
 .../src/main/assembly/release-assembly.xml      |  15 +
 .../src/main/etc/conf/log4j.properties          |  14 +
 .../src/main/etc/conf/logging.properties        |  10 +
 .../src/main/etc/conf/taverna.app.properties    |   2 +
 .../src/main/etc/executeworkflow.bat            |  17 +
 .../src/main/etc/executeworkflow.sh             |  25 +
 taverna-commandline-tests/pom.xml               |  71 ++
 .../commandline/TavernaCommandLineTest.java     | 485 ++++++++++++++
 .../taverna/commandline/WorkflowTestRunner.java |  70 ++
 .../taverna/commandline/WorkflowTestSuite.java  |  79 +++
 .../biomartandembossanalysis.url                |   1 +
 .../biomartandembossanalysis/ignorePort         |   1 +
 .../biomoby_tutorial_workflow.url               |   1 +
 .../biomoby_tutorial_workflow/ignorePort        |   1 +
 .../biomoby_tutorial_workflow/inputs/id         |   1 +
 .../biomoby_tutorial_workflow/inputs/namespace  |   1 +
 .../demonstration_of_configurable_iteration.url |   1 +
 .../ebi_interproscan_newservices.url            |   1 +
 .../ebi_interproscan_newservices/ignorePort     |   1 +
 .../ebi_interproscan_newservices/inputs/email   |   1 +
 .../inputs/sequence                             |   8 +
 .../example_of_conditional_invocation.url       |   1 +
 .../inputs/condition                            |   1 +
 .../example_of_explicit_looping.url             |   1 +
 .../example_of_explicit_looping/inputs/end      |   1 +
 .../example_of_explicit_looping/inputs/start    |   1 +
 .../example_of_explicit_looping/inputs/step     |   1 +
 ...e_workflow_for_rest_and_xpath_activities.url |   1 +
 .../Name_Of_Location_for_Weather_Forecast       |   1 +
 .../fetch_dragon_images_from_biomoby.url        |   1 +
 .../fetch_pdb_flatfile_from_rcsb_server.url     |   1 +
 .../inputs/pdbID                                |   1 +
 .../fetch_today_s_xkcd_comic.url                |   1 +
 .../myexperiment/gbseq_test/gbseq_test.url      |   1 +
 .../myexperiment/hello_anyone/hello_anyone.url  |   1 +
 .../myexperiment/hello_anyone/inputs/name       |   1 +
 .../myexperiment/hello_world/hello_world.url    |   1 +
 .../pipelined_list_iteration/inputs/input       |   1 +
 .../pipelined_list_iteration.url                |   1 +
 .../retrieve_sequence_in_embl_format.url        |   1 +
 .../secure_rest_service_call_example.url        |   1 +
 .../secure_web_service_call_example.url         |   1 +
 .../spreadsheed_data_import_example.url         |   1 +
 .../unix_external_tools_with_zip_and_unzip.url  |   1 +
 .../unix_numerically_adding_two_values/inputs/a |   1 +
 .../unix_numerically_adding_two_values/inputs/b |   1 +
 .../unix_numerically_adding_two_values.url      |   1 +
 ...ix_tool_service_using_string_replacement.url |   1 +
 .../src/test/resources/security/t2keystore.ubr  | Bin 0 -> 3312 bytes
 .../test/resources/security/t2truststore.ubr    | Bin 0 -> 213408 bytes
 .../resources/security/taverna-keystore.ubr     | Bin 0 -> 3312 bytes
 .../resources/security/taverna-truststore.ubr   | Bin 0 -> 213408 bytes
 .../workflows/apiconsumer/apiconsumer.t2flow    | 178 +++++
 .../resources/workflows/apiconsumer/inputs/in   |   1 +
 .../workflows/beanshell/beanshell.t2flow        | 137 ++++
 .../resources/workflows/beanshell/inputs/in     |   1 +
 .../resources/workflows/biomart/biomart.t2flow  |  30 +
 .../workflows/dataflow/dataflow.t2flow          | 217 +++++++
 .../test/resources/workflows/dataflow/inputs/in |   1 +
 .../resources/workflows/in-out/in-out.t2flow    |  12 +
 .../test/resources/workflows/in-out/inputs/in   |   1 +
 .../resources/workflows/iteration/inputs/in     |   1 +
 .../workflows/iteration/iteration.t2flow        | 474 ++++++++++++++
 .../resources/workflows/localworker/inputs/in   |   1 +
 .../workflows/localworker/localworker.t2flow    |  67 ++
 .../test/resources/workflows/rest/rest.t2flow   | 154 +++++
 .../secure-basic-authentication-https.t2flow    |  74 +++
 .../secure-basic-authentication.t2flow          |  74 +++
 ...cure-client-cert-authentication-https.t2flow | 162 +++++
 .../secure-digest-authentication-https.t2flow   | 107 +++
 .../secure-digest-authentication.t2flow         | 129 ++++
 .../secure-ws-https/secure-ws-https.t2flow      | 180 ++++++
 .../workflows/secure-ws/secure-ws.t2flow        | 180 ++++++
 .../workflows/secure-wsdl/secure-wsdl.t2flow    | 131 ++++
 .../resources/workflows/soaplab/soaplab.t2flow  |  84 +++
 .../spreadsheetimport/spreadsheetimport.t2flow  | 646 +++++++++++++++++++
 .../stringconstant/stringconstant.t2flow        |  32 +
 .../test/resources/workflows/tool/tool.t2flow   | 158 +++++
 .../test/resources/workflows/wsdl/wsdl.t2flow   |  22 +
 .../resources/workflows/xmlSplitter/inputs/age  |   1 +
 .../workflows/xmlSplitter/inputs/firstName      |   1 +
 .../workflows/xmlSplitter/inputs/lastName       |   1 +
 .../workflows/xmlSplitter/xmlSplitter.t2flow    | 339 ++++++++++
 .../test/resources/workflows/xpath/xpath.t2flow | 127 ++++
 119 files changed, 8140 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ebe0e5b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,24 @@
+# ignore project files #
+.classpath
+.project
+.settings/
+catalog-v001.xml
+
+# ignore target files #
+target/
+bin/
+build/
+dist/
+apidoc/
+*.swp
+
+# ignore svn files if there
+.svn
+
+# ignore log files #
+*.log
+/logs/*
+*/logs/*
+
+
+

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..dff5f3a
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1 @@
+language: java

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..bcd653c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,6 @@
+# Apache Taverna Commandline
+
+[![Build Status](https://travis-ci.org/taverna-incubator/incubator-taverna-commandline.svg)](https://travis-ci.org/taverna-incubator/incubator-taverna-commandline)
+
+After building, see taverna-commandline-product/target/apache-taverna-commandline-3.1.0-incubating-SNAPSHOT-dev/apache-taverna-commandline-3.1.0-incubating-SNAPSHOT/ or equivalent
+

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..0355623
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,40 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.apache.taverna</groupId>
+		<artifactId>taverna-parent</artifactId>
+		<version>1-incubating-SNAPSHOT</version>
+	</parent>
+	<groupId>org.apache.taverna.commandline</groupId>
+	<artifactId>taverna-commandline</artifactId>
+	<version>3.1.0.incubating-SNAPSHOT</version>
+	<packaging>pom</packaging>
+	<name>Apache Taverna Command Line</name>
+  <properties>
+    <taverna.language.version>0.15.0-incubating-SNAPSHOT</taverna.language.version>
+    <taverna.osgi.version>0.2.0-incubating-SNAPSHOT</taverna.osgi.version>
+    <taverna.engine.version>3.1.0-incubating-SNAPSHOT</taverna.engine.version>
+    <taverna.commonactivities.version>2.1.0-incubating-SNAPSHOT</taverna.commonactivities.version>
+  </properties>
+	<modules>
+    <module>taverna-commandline-api</module>
+    <module>taverna-commandline-common</module>
+    <module>taverna-commandline-launcher</module>
+    <module>taverna-commandline-product</module>
+    <!--
+    <module>taverna-commandline-tests</module>
+    -->
+  </modules>
+  <repositories>
+    <repository>
+      <id>taverna-incubating</id>
+      <name>Apache Taverna incubating Repository</name>
+        <url>http://repository.mygrid.org.uk/artifactory/incubator-snapshot-local/</url>
+      <releases>
+        <enabled>false</enabled>
+      </releases>
+      <snapshots />
+    </repository>
+  </repositories>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-api/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-commandline-api/pom.xml b/taverna-commandline-api/pom.xml
new file mode 100644
index 0000000..98ae247
--- /dev/null
+++ b/taverna-commandline-api/pom.xml
@@ -0,0 +1,12 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.apache.taverna.commandline</groupId>
+		<artifactId>taverna-commandline</artifactId>
+		<version>3.1.0.incubating-SNAPSHOT</version>
+	</parent>
+	<packaging>bundle</packaging>
+	<artifactId>taverna-commandline-api</artifactId>
+	<name>Apache Taverna Commandline API</name>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/ArgumentsParsingException.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/ArgumentsParsingException.java b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/ArgumentsParsingException.java
new file mode 100644
index 0000000..eb21cd7
--- /dev/null
+++ b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/ArgumentsParsingException.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester   
+ * 
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ * 
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *    
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *    
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.commandline.exceptions;
+
+@SuppressWarnings("serial")
+public class ArgumentsParsingException extends Exception {
+
+	public ArgumentsParsingException(String message) {
+		super(message);
+	}
+	
+	public ArgumentsParsingException(String message, Throwable cause) {
+		super(message, cause);
+	}
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/CommandLineMasterPasswordException.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/CommandLineMasterPasswordException.java b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/CommandLineMasterPasswordException.java
new file mode 100644
index 0000000..0714275
--- /dev/null
+++ b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/CommandLineMasterPasswordException.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester   
+ * 
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ * 
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *    
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *    
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.commandline.exceptions;
+
+@SuppressWarnings("serial")
+public class CommandLineMasterPasswordException extends Exception {
+
+	public CommandLineMasterPasswordException(String message) {
+		super(message);
+	}
+	
+	public CommandLineMasterPasswordException(String message, Throwable cause) {
+		super(message, cause);
+	}
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/DatabaseConfigurationException.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/DatabaseConfigurationException.java b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/DatabaseConfigurationException.java
new file mode 100644
index 0000000..616fb70
--- /dev/null
+++ b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/DatabaseConfigurationException.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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.commandline.exceptions;
+
+public class DatabaseConfigurationException extends Exception {
+	
+	private static final long serialVersionUID = -4128248547532355697L;
+
+	public DatabaseConfigurationException() {
+
+	}
+
+	public DatabaseConfigurationException(String message) {
+		super(message);
+	}
+
+	public DatabaseConfigurationException(Throwable cause) {
+		super(cause);
+	}
+
+	public DatabaseConfigurationException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/InputMismatchException.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/InputMismatchException.java b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/InputMismatchException.java
new file mode 100644
index 0000000..da03891
--- /dev/null
+++ b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/InputMismatchException.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * 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.commandline.exceptions;
+
+import java.util.Set;
+
+public class InputMismatchException extends InvalidOptionException {	
+	
+	private static final long serialVersionUID = -5368068332397293706L;
+	private final Set<String> expectedInputNames;
+	private final Set<String> providedInputNames;
+	
+	public InputMismatchException(String msg, Set<String> expectedInputNames, Set<String> providedInputNames) {
+		super(msg);
+		this.expectedInputNames = expectedInputNames;
+		this.providedInputNames = providedInputNames;				
+	}
+
+	public String getMessage() {
+		String result = super.getMessage();
+		
+		if (expectedInputNames != null){
+			result += "\n" + expectedInputNames.size() + " inputs were expected";
+			if (expectedInputNames.size()>0) result += " which are:\n";
+			for (String name : expectedInputNames) {
+				result += "'"+name+"' ";			
+			}			
+		}
+		
+		if (providedInputNames != null){
+			result += "\n" + providedInputNames.size()
+					+ " inputs were provided";
+			if (providedInputNames.size() > 0)
+				result += " which are:\n";
+			for (String name : providedInputNames) {
+				result += "'" + name + "' ";
+			}
+		}
+		return result;
+	}
+	
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/InvalidOptionException.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/InvalidOptionException.java b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/InvalidOptionException.java
new file mode 100644
index 0000000..c07a19f
--- /dev/null
+++ b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/InvalidOptionException.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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.commandline.exceptions;
+
+public class InvalidOptionException extends Exception {
+
+	private static final long serialVersionUID = 2467409785164223258L;
+
+	public InvalidOptionException(String message) {
+		super(message);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/OpenDataflowException.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/OpenDataflowException.java b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/OpenDataflowException.java
new file mode 100644
index 0000000..664ab71
--- /dev/null
+++ b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/OpenDataflowException.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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.commandline.exceptions;
+
+public class OpenDataflowException extends Exception {
+
+	
+	private static final long serialVersionUID = 4778578311101082197L;
+
+	public OpenDataflowException() {
+		
+	}
+
+	public OpenDataflowException(String message) {
+		super(message);	
+	}
+
+	public OpenDataflowException(Throwable cause) {
+		super(cause);
+	}
+
+	public OpenDataflowException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/ReadInputException.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/ReadInputException.java b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/ReadInputException.java
new file mode 100644
index 0000000..226d6ea
--- /dev/null
+++ b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/ReadInputException.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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.commandline.exceptions;
+
+public class ReadInputException extends Exception {
+		
+	private static final long serialVersionUID = -3494432791254643055L;
+
+	public ReadInputException(String msg) {
+		super(msg); 
+	}
+	
+	public ReadInputException(String msg, Throwable e) {
+		super(msg,e); 
+	}
+	
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/SaveResultsException.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/SaveResultsException.java b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/SaveResultsException.java
new file mode 100644
index 0000000..7ad460d
--- /dev/null
+++ b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/exceptions/SaveResultsException.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester   
+ * 
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ * 
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *    
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *    
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.commandline.exceptions;
+
+@SuppressWarnings("serial")
+public class SaveResultsException extends Exception {
+
+	public SaveResultsException(String message) {
+		super(message);
+	}
+	
+	public SaveResultsException(String message, Throwable cause) {
+		super(message, cause);
+	}
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/options/CommandLineOptions.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/options/CommandLineOptions.java b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/options/CommandLineOptions.java
new file mode 100644
index 0000000..dd8e20f
--- /dev/null
+++ b/taverna-commandline-api/src/main/java/net/sf/taverna/t2/commandline/options/CommandLineOptions.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (C) 2013 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.commandline.options;
+
+import net.sf.taverna.t2.commandline.exceptions.InvalidOptionException;
+
+/**
+ *
+ *
+ * @author David Withers
+ */
+public interface CommandLineOptions {
+
+	public static final String CREDENTIAL_MANAGER_DIR_OPTION = "cmdir";
+	public static final String CREDENTIAL_MANAGER_PASSWORD_OPTION = "cmpassword";
+
+	public boolean askedForHelp();
+
+	public boolean isProvenanceEnabled();
+
+	public void displayHelp();
+
+	public void displayHelp(boolean showFullText);
+
+	public String[] getArgs();
+
+	/**
+	 *
+	 * @return the port that the database should run on
+	 */
+	public String getDatabasePort();
+
+	/**
+	 *
+	 * @return a path to a properties file that contains database configuration
+	 *         settings
+	 */
+	public String getDatabaseProperties();
+
+	/**
+	 * Returns an array that alternates between a portname and path to a file
+	 * containing the input values. Therefore the array will always contain an
+	 * even number of elements
+	 *
+	 * @return an array of portname and path to files containing individual
+	 *         inputs.
+	 */
+	public String[] getInputFiles();
+
+	public String[] getInputValues();
+
+	public String getLogFile();
+
+	/**
+	 *
+	 * @return the directory to write the results to
+	 */
+	public String getOutputDirectory();
+
+	public boolean getStartDatabase();
+
+	/**
+	 * @return the directory with Credential Manager's files
+	 */
+	public String getCredentialManagerDir();
+
+	public boolean getStartDatabaseOnly() throws InvalidOptionException;
+
+	public String getWorkflow() throws InvalidOptionException;
+
+	public boolean hasDelimiterFor(String inputName);
+
+	public boolean hasInputFiles();
+
+	public boolean hasInputValues();
+
+	public boolean hasLogFile();
+
+	public boolean hasOption(String option);
+	
+	public boolean hasSaveResultsToBundle() ;
+
+	public String inputDelimiter(String inputName);
+
+	public boolean isClientServer();
+
+	public boolean isEmbedded();
+
+	public boolean isInMemory();
+
+	/**
+	 * Save the results to a directory if -outputdir has been explicitly defined,
+	 * or if -outputdoc has not been defined.
+	 *
+	 * @return boolean
+	 */
+	public boolean saveResultsToDirectory();
+
+	public String saveResultsToBundle();
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-common/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-commandline-common/pom.xml b/taverna-commandline-common/pom.xml
new file mode 100644
index 0000000..17c6a42
--- /dev/null
+++ b/taverna-commandline-common/pom.xml
@@ -0,0 +1,88 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.apache.taverna.commandline</groupId>
+		<artifactId>taverna-commandline</artifactId>
+		<version>3.1.0.incubating-SNAPSHOT</version>
+	</parent>
+	<artifactId>taverna-commandline-common</artifactId>
+	<packaging>bundle</packaging>
+	<name>Apache Taverna Commandline Common</name>
+	<dependencies>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-commandline-api</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.taverna.engine</groupId>
+			<artifactId>taverna-run-api</artifactId>
+			<version>${taverna.engine.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.engine</groupId>
+			<artifactId>taverna-database-configuration-api</artifactId>
+			<version>${taverna.engine.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.taverna.language</groupId>
+			<artifactId>taverna-scufl2-api</artifactId>
+			<version>${taverna.language.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.language</groupId>
+			<artifactId>taverna-scufl2-validation</artifactId>
+			<version>${taverna.language.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.language</groupId>
+			<artifactId>taverna-scufl2-validation-structural</artifactId>
+			<version>${taverna.language.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.language</groupId>
+			<artifactId>taverna-scufl2-validation-correctness</artifactId>
+			<version>${taverna.language.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taverna.language</groupId>
+			<artifactId>taverna-databundle</artifactId>
+			<version>${taverna.language.version}</version>
+		</dependency>
+
+<!--
+		<dependency>
+			<groupId>org.apache.taverna.engine</groupId>
+			<artifactId>provenanceconnector</artifactId>
+			<version>${taverna.engine.version}</version>
+		</dependency>
+ -->
+		<dependency>
+			<groupId>org.apache.taverna.engine</groupId>
+			<artifactId>taverna-credential-manager</artifactId>
+			<version>${taverna.engine.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+			<version>${commons.io.version}</version>
+		</dependency>
+
+		<!-- <dependency> <groupId>uk.org.mygrid.resources.mimeutil</groupId> <artifactId>mime-util</artifactId>
+			<version>2.1.2-2</version> </dependency> -->
+
+		<!-- TEST -->
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>${junit.version}</version>
+			<scope>test</scope>
+		</dependency>
+
+	</dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/CommandLineMasterPasswordProvider.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/CommandLineMasterPasswordProvider.java b/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/CommandLineMasterPasswordProvider.java
new file mode 100644
index 0000000..048e582
--- /dev/null
+++ b/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/CommandLineMasterPasswordProvider.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (C) 2008-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.commandline;
+
+import java.io.BufferedReader;
+import java.io.Console;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import net.sf.taverna.t2.commandline.exceptions.CommandLineMasterPasswordException;
+import net.sf.taverna.t2.commandline.options.CommandLineOptions;
+import net.sf.taverna.t2.security.credentialmanager.MasterPasswordProvider;
+
+import org.apache.log4j.Logger;
+
+/**
+ * An implementation of {@link MasterPasswordProvider} that reads Credential Manager's
+ * master password from stdin (pipe or terminal) is -cmpassword option is present in command
+ * line arguments. Otherwise it tries to read it from a special file password.txt in a special
+ * directory specified by -cmdir option, if present.
+ *
+ * @author Alex Nenadic
+ */
+public class CommandLineMasterPasswordProvider implements MasterPasswordProvider {
+
+	private static final String CREDENTIAL_MANAGER_MASTER_PASSWORD_OPTION = "cmpassword";
+	private static final String CREDENTIAL_MANAGER_DIRECTORY_OPTION = "cmdir";
+
+	private static Logger logger = Logger.getLogger(CommandLineMasterPasswordProvider.class);
+
+	private String masterPassword = null;
+	private int priority = 200;
+
+	private boolean finishedReadingPassword = false;
+	private final CommandLineOptions commandLineOptions;
+
+	public CommandLineMasterPasswordProvider(CommandLineOptions commandLineOptions) {
+		this.commandLineOptions = commandLineOptions;
+	}
+
+	@Override
+	public String getMasterPassword(boolean firstTime) {
+		if (!finishedReadingPassword) {
+			// -cmpassword option was present in the command line arguments
+			if (commandLineOptions.hasOption(CREDENTIAL_MANAGER_MASTER_PASSWORD_OPTION)) {
+				// Try to read the password from stdin (terminal or pipe)
+				try {
+					masterPassword = getCredentialManagerPasswordFromStdin();
+				} catch (CommandLineMasterPasswordException e) {
+					masterPassword = null;
+				}
+			}
+			// -cmpassword option was not present in the command line arguments
+			// and -cmdir option was there - try to get the master password from
+			// the "special" password file password.txt inside the Cred. Manager directory.
+			else {
+				if (commandLineOptions.hasOption(CREDENTIAL_MANAGER_DIRECTORY_OPTION)) {
+					// Try to read the password from a special file located in
+					// Credential Manager directory (if the dir was not null)
+					try {
+						masterPassword = getCredentialManagerPasswordFromFile();
+					} catch (CommandLineMasterPasswordException ex) {
+						masterPassword = null;
+					}
+				}
+			}
+			finishedReadingPassword = true; // we do not want to attempt to read from stdin several
+											// times
+		}
+		return masterPassword;
+	}
+
+	public void setMasterPassword(String masterPassword) {
+		this.masterPassword = masterPassword;
+		finishedReadingPassword = true;
+	}
+
+	@Override
+	public int getProviderPriority() {
+		return priority;
+	}
+
+	private String getCredentialManagerPasswordFromStdin()
+			throws CommandLineMasterPasswordException {
+
+		String password = null;
+
+		Console console = System.console();
+
+		if (console == null) { // password is being piped in, not entered in the terminal by user
+			BufferedReader buffReader = null;
+			try {
+				buffReader = new BufferedReader(new InputStreamReader(System.in));
+				password = buffReader.readLine();
+			} catch (IOException ex) {
+				// For some reason the error of the exception thrown
+				// does not get printed from the Launcher so print it here as
+				// well as it gives more clue as to what is going wrong.
+				logger.error(
+						"An error occured while trying to read Credential Manager's password that was piped in: "
+								+ ex.getMessage(), ex);
+				throw new CommandLineMasterPasswordException(
+						"An error occured while trying to read Credential Manager's password that was piped in: "
+								+ ex.getMessage(), ex);
+			} finally {
+				try {
+					buffReader.close();
+				} catch (Exception ioe1) {
+					// Ignore
+				}
+			}
+		} else { // read the password from the terminal as entered by the user
+			try {
+				// Block until user enters password
+				char passwordArray[] = console.readPassword("Password for Credential Manager: ");
+				if (passwordArray != null) { // user did not abort input
+					password = new String(passwordArray);
+				} // else password will be null
+
+			} catch (Exception ex) {
+				// For some reason the error of the exception thrown
+				// does not get printed from the Launcher so print it here as
+				// well as it gives more clue as to what is going wrong.
+				logger.error(
+						"An error occured while trying to read Credential Manager's password from the terminal: "
+								+ ex.getMessage(), ex);
+				throw new CommandLineMasterPasswordException(
+						"An error occured while trying to read Credential Manager's password from the terminal: "
+								+ ex.getMessage(), ex);
+			}
+		}
+		return password;
+	}
+
+	private String getCredentialManagerPasswordFromFile() throws CommandLineMasterPasswordException {
+		String password = null;
+		if (commandLineOptions.hasOption(CREDENTIAL_MANAGER_DIRECTORY_OPTION)) {
+			String cmDir = commandLineOptions.getCredentialManagerDir();
+
+			File passwordFile = new File(cmDir, "password.txt");
+			BufferedReader buffReader = null;
+			try {
+				buffReader = new BufferedReader(new FileReader(passwordFile));
+				password = buffReader.readLine();
+			} catch (IOException ioe) {
+				// For some reason the error of the exception thrown
+				// does not get printed from the Launcher so print it here as
+				// well as it gives more clue as to what is going wrong.
+				logger.error("There was an error reading the Credential Manager password from "
+						+ passwordFile.toString() + ": " + ioe.getMessage(), ioe);
+				throw new CommandLineMasterPasswordException(
+						"There was an error reading the Credential Manager password from "
+								+ passwordFile.toString() + ": " + ioe.getMessage(), ioe);
+			} finally {
+				try {
+					buffReader.close();
+				} catch (Exception ioe1) {
+					// Ignore
+				}
+			}
+		}
+		return password;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/CommandLineTool.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/CommandLineTool.java b/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/CommandLineTool.java
new file mode 100644
index 0000000..368527d
--- /dev/null
+++ b/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/CommandLineTool.java
@@ -0,0 +1,437 @@
+/*******************************************************************************
+ * 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.commandline;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.naming.NamingException;
+
+import net.sf.taverna.t2.commandline.data.DatabaseConfigurationHandler;
+import net.sf.taverna.t2.commandline.data.InputsHandler;
+import net.sf.taverna.t2.commandline.data.SaveResultsHandler;
+import net.sf.taverna.t2.commandline.exceptions.DatabaseConfigurationException;
+import net.sf.taverna.t2.commandline.exceptions.InputMismatchException;
+import net.sf.taverna.t2.commandline.exceptions.InvalidOptionException;
+import net.sf.taverna.t2.commandline.exceptions.OpenDataflowException;
+import net.sf.taverna.t2.commandline.exceptions.ReadInputException;
+import net.sf.taverna.t2.commandline.options.CommandLineOptions;
+import net.sf.taverna.t2.security.credentialmanager.CMException;
+import net.sf.taverna.t2.security.credentialmanager.CredentialManager;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.PatternLayout;
+import org.apache.log4j.PropertyConfigurator;
+import org.apache.log4j.RollingFileAppender;
+import org.purl.wf4ever.robundle.Bundle;
+
+import uk.org.taverna.configuration.database.DatabaseConfiguration;
+import uk.org.taverna.configuration.database.DatabaseManager;
+import uk.org.taverna.databundle.DataBundles;
+import uk.org.taverna.platform.execution.api.ExecutionEnvironment;
+import uk.org.taverna.platform.execution.api.InvalidExecutionIdException;
+import uk.org.taverna.platform.execution.api.InvalidWorkflowException;
+import uk.org.taverna.platform.report.State;
+import uk.org.taverna.platform.report.WorkflowReport;
+import uk.org.taverna.platform.run.api.InvalidRunIdException;
+import uk.org.taverna.platform.run.api.RunProfile;
+import uk.org.taverna.platform.run.api.RunProfileException;
+import uk.org.taverna.platform.run.api.RunService;
+import uk.org.taverna.platform.run.api.RunStateException;
+import uk.org.taverna.scufl2.api.common.NamedSet;
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+import uk.org.taverna.scufl2.api.core.Workflow;
+import uk.org.taverna.scufl2.api.io.ReaderException;
+import uk.org.taverna.scufl2.api.io.WorkflowBundleIO;
+import uk.org.taverna.scufl2.api.port.InputWorkflowPort;
+import uk.org.taverna.scufl2.api.port.OutputWorkflowPort;
+import uk.org.taverna.scufl2.validation.ValidationException;
+import uk.org.taverna.scufl2.validation.correctness.CorrectnessValidator;
+import uk.org.taverna.scufl2.validation.correctness.ReportCorrectnessValidationListener;
+import uk.org.taverna.scufl2.validation.structural.ReportStructuralValidationListener;
+import uk.org.taverna.scufl2.validation.structural.StructuralValidator;
+
+/**
+ * A utility class that wraps the process of executing a workflow, allowing workflows to be easily
+ * executed independently of the GUI.
+ *
+ * @author Stuart Owen
+ * @author Alex Nenadic
+ */
+public class CommandLineTool {
+	private static boolean BOOTSTRAP_LOGGING = false;
+	private static Logger logger = Logger.getLogger(CommandLineTool.class);
+
+	private RunService runService;
+	private CredentialManager credentialManager;
+	private CommandLineOptions commandLineOptions;
+	private WorkflowBundle workflowBundle;
+	private WorkflowBundleIO workflowBundleIO;
+	private DatabaseConfiguration databaseConfiguration;
+	private DatabaseManager databaseManager;
+
+	public void run() {
+		try {
+			if (BOOTSTRAP_LOGGING)
+				initialiseLogging();
+			int result = setupAndExecute();
+			System.exit(result);
+		} catch (InvalidOptionException | IOException | ReadInputException
+				| InvalidRunIdException | RunStateException
+				| InvalidExecutionIdException | OpenDataflowException
+				| RunProfileException e) {
+			error(e.getMessage());
+		} catch (CMException e) {
+			error("There was an error initializing Taverna's SSLSocketFactory from Credential Manager. "
+					+ e.getMessage());
+		} catch (ReaderException e) {
+			error("There was an error reading the workflow: " + e.getMessage());
+		} catch (ValidationException e) {
+			error("There was an error validating the workflow: " + e.getMessage());
+		} catch (InvalidWorkflowException e) {
+			error("There was an error validating the workflow: " + e.getMessage());
+		} catch (DatabaseConfigurationException e) {
+			error("There was an error configuring the database: " + e.getMessage());
+		}
+		System.exit(1);
+	}
+
+	private void initialiseLogging() {
+		LogManager.resetConfiguration();
+
+		if (System.getProperty("log4j.configuration") == null) {
+			try {
+				PropertyConfigurator.configure(CommandLineTool.class.getClassLoader()
+						.getResource("cl-log4j.properties").toURI().toURL());
+			} catch (MalformedURLException e) {
+				logger.error("There was a serious error reading the default logging configuration",
+						e);
+			} catch (URISyntaxException e) {
+				logger.error("There was a serious error reading the default logging configuration",
+						e);
+			}
+
+		} else {
+			PropertyConfigurator.configure(System.getProperty("log4j.configuration"));
+		}
+
+		if (commandLineOptions.hasLogFile()) {
+			RollingFileAppender appender;
+			try {
+
+				PatternLayout layout = new PatternLayout("%-5p %d{ISO8601} (%c:%L) - %m%n");
+				appender = new RollingFileAppender(layout, commandLineOptions.getLogFile());
+				appender.setMaxFileSize("1MB");
+				appender.setEncoding("UTF-8");
+				appender.setMaxBackupIndex(4);
+				// Let root logger decide level
+				appender.setThreshold(Level.ALL);
+				LogManager.getRootLogger().addAppender(appender);
+			} catch (IOException e) {
+				System.err.println("Could not log to " + commandLineOptions.getLogFile());
+			}
+		}
+	}
+
+	public int setupAndExecute() throws InputMismatchException, InvalidOptionException,
+			CMException, OpenDataflowException, ReaderException, IOException, ValidationException,
+			ReadInputException, InvalidWorkflowException, RunProfileException,
+			InvalidRunIdException, RunStateException, InvalidExecutionIdException, DatabaseConfigurationException {
+
+		if (!commandLineOptions.askedForHelp()) {
+			 setupDatabase(commandLineOptions);
+
+			if (commandLineOptions.getWorkflow() != null) {
+				
+				/* Set context class loader to us, 
+				 * so that things such as JSON-LD caching of
+				 * robundle works.
+				 */
+				
+				Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+				
+				
+				/*
+				 * Initialise Credential Manager and SSL stuff quite early as
+				 * parsing and validating the workflow may require it
+				 */
+				String credentialManagerDirPath = commandLineOptions.getCredentialManagerDir();
+
+				/*
+				 * If credentialManagerDirPath is null, the Credential Manager
+				 * will be initialized from the default location in
+				 * <TAVERNA_HOME>/security somewhere inside user's home
+				 * directory. This should not be used when running command line
+				 * tool on a server and the Credential Manager dir path should
+				 * always be passed in as we do not want to store the security
+				 * files in user's home directory on the server (we do not even
+				 * know which user the command line tool will be running as).
+				 */
+				if (credentialManagerDirPath != null) {
+					credentialManager.setConfigurationDirectoryPath(new File(
+							credentialManagerDirPath));
+				}
+
+				// Initialise the SSL stuff - set the SSLSocketFactory
+				// to use Taverna's Keystore and Truststore.
+				credentialManager.initializeSSL();
+
+				URL workflowURL = readWorkflowURL(commandLineOptions.getWorkflow());
+
+				workflowBundle = workflowBundleIO.readBundle(workflowURL, null);
+
+				logger.debug("Read the wf bundle");
+
+				validateWorkflowBundle(workflowBundle);
+				logger.debug("Validated the wf bundle");
+
+
+				Set<ExecutionEnvironment> executionEnvironments = runService
+						.getExecutionEnvironments();
+
+				ExecutionEnvironment executionEnvironment = null;
+
+				/*
+				 * Find the right execution environment, e.g. local execution
+				 * with the correct reference service based on command line
+				 * options
+				 */
+				while (executionEnvironments.iterator().hasNext()) {
+					// TODO Choose the right one
+					// take the fist one for now
+					executionEnvironment = executionEnvironments.iterator().next();
+					break;
+				}
+
+				logger.debug("Got the execution environment");
+
+				InputsHandler inputsHandler = new InputsHandler();
+				Map<String, InputWorkflowPort> portMap = new HashMap<String, InputWorkflowPort>();
+
+				Workflow workflow = workflowBundle.getMainWorkflow();
+
+				for (InputWorkflowPort port : workflow.getInputPorts()) {
+					portMap.put(port.getName(), port);
+				}
+				inputsHandler.checkProvidedInputs(portMap, commandLineOptions);
+				logger.debug("Checked inputs");
+
+				Bundle inputs = inputsHandler.registerInputs(portMap, commandLineOptions, null);
+				logger.debug("Registered inputs");
+
+				RunProfile runProfile = new RunProfile(executionEnvironment, workflowBundle, inputs);
+
+				String runId = runService.createRun(runProfile);
+
+				runService.start(runId);
+				logger.debug("Started wf run");
+
+				WorkflowReport report = runService.getWorkflowReport(runId);
+
+				while (!workflowFinished(report)) {
+					try {
+						Thread.sleep(500);
+					} catch (InterruptedException e) {
+						System.err.println("Interrupted while waiting for workflow to finish");
+						return 1;
+					}
+				}
+
+				NamedSet<OutputWorkflowPort> workflowOutputPorts = workflow.getOutputPorts();
+				if (!workflowOutputPorts.isEmpty()) {
+					File outputDir = null;
+
+					if (commandLineOptions.saveResultsToDirectory()) {
+						outputDir = determineOutputDir(commandLineOptions, workflowBundle.getName());
+						outputDir.mkdirs();
+					}
+
+					Path outputs = DataBundles.getOutputs(runService.getDataBundle(runId));
+
+					if (outputDir != null) {
+						SaveResultsHandler saveResultsHandler = new SaveResultsHandler(outputDir);
+
+						for (OutputWorkflowPort outputWorkflowPort : workflowOutputPorts) {
+							String workflowOutputPortName = outputWorkflowPort.getName();
+							Path output = DataBundles.getPort(outputs, workflowOutputPortName);
+							if (!DataBundles.isMissing(output)) {
+								saveResultsHandler.saveResultsForPort(workflowOutputPortName, output);
+							}
+						}
+					}
+				}
+				if (commandLineOptions.saveResultsToBundle() != null) {
+					Path bundlePath = Paths.get(commandLineOptions.saveResultsToBundle());
+					DataBundles.closeAndSaveBundle(runService.getDataBundle(runId), bundlePath);
+					System.out.println("Workflow Run Bundle saved to: " + bundlePath.toAbsolutePath());
+				} else {
+					System.out.println("Workflow Run Bundle: " + runService.getDataBundle(runId).getSource());
+					// For debugging we'll leave it in /tmp for now
+					runService.getDataBundle(runId).setDeleteOnClose(false);
+					DataBundles.closeBundle(runService.getDataBundle(runId));
+				}
+
+				if (report.getState().equals(State.FAILED)) {
+					System.out.println("Workflow failed - see report below.");
+					System.out.println(report);
+				} else if (report.getState().equals(State.COMPLETED)) {
+					System.out.println("Workflow completed.");
+				}
+
+			}
+		} else {
+			commandLineOptions.displayHelp();
+		}
+
+		// wait until user hits CTRL-C before exiting
+		if (commandLineOptions.getStartDatabaseOnly()) {
+			// FIXME: need to do this more gracefully.
+			while (true) {
+				try {
+					Thread.sleep(500);
+				} catch (InterruptedException e) {
+					return 0;
+				}
+			}
+		}
+
+		return 0;
+	}
+
+	private boolean workflowFinished(WorkflowReport report) {
+		State state = report.getState();
+		if (state == State.CANCELLED || state == State.COMPLETED || state == State.FAILED) {
+			return true;
+		}
+		return false;
+	}
+
+	protected void validateWorkflowBundle(WorkflowBundle workflowBundle) throws ValidationException {
+		CorrectnessValidator cv = new CorrectnessValidator();
+		ReportCorrectnessValidationListener rcvl = new ReportCorrectnessValidationListener();
+		cv.checkCorrectness(workflowBundle, true, rcvl);
+		if (rcvl.detectedProblems()) {
+			throw rcvl.getException();
+		}
+
+		StructuralValidator sv = new StructuralValidator();
+		ReportStructuralValidationListener rsvl = new ReportStructuralValidationListener();
+		sv.checkStructure(workflowBundle, rsvl);
+		if (rsvl.detectedProblems()) {
+			throw rcvl.getException();
+		}
+	}
+
+	private void setupDatabase(CommandLineOptions options)
+			throws DatabaseConfigurationException {
+		DatabaseConfigurationHandler dbHandler = new DatabaseConfigurationHandler(
+				options, databaseConfiguration, databaseManager);
+		dbHandler.configureDatabase();
+		try {
+			if (!options.isInMemory())
+				dbHandler.testDatabaseConnection();
+		} catch (NamingException e) {
+			throw new DatabaseConfigurationException(
+					"There was an error trying to setup the database datasource: "
+							+ e.getMessage(), e);
+		} catch (SQLException e) {
+			if (options.isClientServer())
+				throw new DatabaseConfigurationException(
+						"There was an error whilst making a test database connection. If running with -clientserver you should check that a server is running (check -startdb or -dbproperties)",
+						e);
+			if (options.isEmbedded())
+				throw new DatabaseConfigurationException(
+						"There was an error whilst making a test database connection. If running with -embedded you should make sure that another process isn't using the database, or a server running through -startdb",
+						e);
+		}
+	}
+
+	private File determineOutputDir(CommandLineOptions options, String dataflowName) {
+		File result = new File(dataflowName + "_output");
+		int x = 1;
+		while (result.exists()) {
+			result = new File(dataflowName + "_output_" + x);
+			x++;
+		}
+		System.out.println("Outputs will be saved to the directory: "
+				+ result.getAbsolutePath());
+		return result;
+	}
+
+	protected void error(String msg) {
+		System.err.println(msg);
+	}
+
+	private URL readWorkflowURL(String workflowOption) throws OpenDataflowException {
+		try {
+			return new URL(new URL("file:"), workflowOption);
+		} catch (MalformedURLException e) {
+			throw new OpenDataflowException("The was an error processing the URL to the workflow: "
+					+ e.getMessage(), e);
+		}
+	}
+
+	public void setCommandLineOptions(CommandLineOptions commandLineOptions){
+		this.commandLineOptions = commandLineOptions;
+	}
+
+	public void setRunService(RunService runService) {
+		this.runService = runService;
+	}
+
+	public void setCredentialManager(CredentialManager credentialManager) {
+		this.credentialManager = credentialManager;
+	}
+
+	public void setWorkflowBundleIO(WorkflowBundleIO workflowBundleIO) {
+		this.workflowBundleIO = workflowBundleIO;
+	}
+
+	/**
+	 * Sets the databaseConfiguration.
+	 *
+	 * @param databaseConfiguration the new value of databaseConfiguration
+	 */
+	public void setDatabaseConfiguration(DatabaseConfiguration databaseConfiguration) {
+		this.databaseConfiguration = databaseConfiguration;
+	}
+
+	/**
+	 * Sets the databaseManager.
+	 *
+	 * @param databaseManager the new value of databaseManager
+	 */
+	public void setDatabaseManager(DatabaseManager databaseManager) {
+		this.databaseManager = databaseManager;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/DatabaseConfigurationHandler.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/DatabaseConfigurationHandler.java b/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/DatabaseConfigurationHandler.java
new file mode 100644
index 0000000..46b6c92
--- /dev/null
+++ b/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/DatabaseConfigurationHandler.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * 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.commandline.data;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import javax.naming.NamingException;
+
+import net.sf.taverna.t2.commandline.exceptions.DatabaseConfigurationException;
+import net.sf.taverna.t2.commandline.options.CommandLineOptions;
+
+import org.apache.log4j.Logger;
+
+import uk.org.taverna.configuration.database.DatabaseConfiguration;
+import uk.org.taverna.configuration.database.DatabaseManager;
+
+/**
+ * Handles the initialisation and configuration of the data source according to
+ * the command line arguments, or a properties file.
+ * This also handles starting a network based instance of a Derby server, if requested.
+ *
+ * @author Stuart Owen
+ *
+ */
+public class DatabaseConfigurationHandler {
+
+	private static Logger logger = Logger.getLogger(DatabaseConfigurationHandler.class);
+	private final CommandLineOptions options;
+	private final DatabaseConfiguration dbConfig;
+	private final DatabaseManager databaseManager;
+
+	public DatabaseConfigurationHandler(CommandLineOptions options, DatabaseConfiguration databaseConfiguration, DatabaseManager databaseManager) {
+		this.options = options;
+		this.dbConfig = databaseConfiguration;
+		this.databaseManager = databaseManager;
+		databaseConfiguration.disableAutoSave();
+	}
+
+	public void configureDatabase() throws DatabaseConfigurationException {
+		overrideDefaults();
+		useOptions();
+		if (dbConfig.getStartInternalDerbyServer()) {
+			databaseManager.startDerbyNetworkServer();
+			System.out.println("Started Derby Server on Port: "
+					+ dbConfig.getCurrentPort());
+		}
+	}
+
+	public DatabaseConfiguration getDBConfig() {
+		return dbConfig;
+	}
+
+	private void importConfigurationFromStream(InputStream inStr)
+			throws IOException {
+		Properties p = new Properties();
+		p.load(inStr);
+		for (Object key : p.keySet()) {
+			dbConfig.setProperty((String)key, p.getProperty((String)key).trim());
+		}
+	}
+
+	protected void overrideDefaults() throws DatabaseConfigurationException {
+
+		InputStream inStr = DatabaseConfigurationHandler.class.getClassLoader().getResourceAsStream("database-defaults.properties");
+		try {
+			importConfigurationFromStream(inStr);
+		} catch (IOException e) {
+			throw new DatabaseConfigurationException("There was an error reading the default database configuration settings: "+e.getMessage(),e);
+		}
+	}
+
+	protected void readConfigirationFromFile(String filename) throws IOException {
+		FileInputStream fileInputStream = new FileInputStream(filename);
+		importConfigurationFromStream(fileInputStream);
+		fileInputStream.close();
+	}
+
+	public void testDatabaseConnection()
+			throws DatabaseConfigurationException, NamingException, SQLException {
+		//try and get a connection
+		Connection con = null;
+		try {
+			con = databaseManager.getConnection();
+		} finally {
+			if (con!=null)
+				try {
+					con.close();
+				} catch (SQLException e) {
+					logger.warn("There was an SQL error whilst closing the test connection: "+e.getMessage(),e);
+				}
+		}
+	}
+
+	public void useOptions() throws DatabaseConfigurationException {
+
+		if (options.hasOption("port")) {
+			dbConfig.setPort(options.getDatabasePort());
+		}
+
+		if (options.hasOption("startdb")) {
+			dbConfig.setStartInternalDerbyServer(true);
+		}
+
+		if (options.hasOption("inmemory")) {
+			dbConfig.setInMemory(true);
+		}
+
+		if (options.hasOption("embedded")) {
+			dbConfig.setInMemory(false);
+			dbConfig.setDriverClassName("org.apache.derby.jdbc.EmbeddedDriver");
+		}
+
+		if (options.isProvenanceEnabled()) {
+			dbConfig.setProvenanceEnabled(true);
+		}
+
+		if (options.hasOption("clientserver")) {
+			dbConfig.setInMemory(false);
+			dbConfig.setDriverClassName("org.apache.derby.jdbc.ClientDriver");
+			dbConfig.setJDBCUri("jdbc:derby://localhost:" + dbConfig.getPort() + "/t2-database;create=true;upgrade=true");
+		}
+
+		if (options.hasOption("dbproperties")) {
+			try {
+				readConfigirationFromFile(options.getDatabaseProperties());
+			} catch (IOException e) {
+				throw new DatabaseConfigurationException("There was an error reading the database configuration options at "+options.getDatabaseProperties()+" : "+e.getMessage(),e);
+			}
+		}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/ErrorValueHandler.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/ErrorValueHandler.java b/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/ErrorValueHandler.java
new file mode 100644
index 0000000..44faea5
--- /dev/null
+++ b/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/ErrorValueHandler.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.commandline.data;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.List;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+
+import uk.org.taverna.databundle.DataBundles;
+import uk.org.taverna.databundle.ErrorDocument;
+
+/**
+ * Handles ErrorValues and transforming them into String representations
+ * that can be stored as a file, or within a Baclava document.
+ *
+ * @author Stuart Owen
+ * @author David Withers
+ */
+public class ErrorValueHandler {
+
+	/**
+	 * Creates a string representation of the ErrorValue.
+	 * @throws IOException
+	 */
+	public static String buildErrorValueString(ErrorDocument errorValue) throws IOException {
+
+		String errDocumentString = errorValue.getMessage() + "\n";
+
+		String exceptionMessage = errorValue.getMessage();
+		if (exceptionMessage != null && !exceptionMessage.equals("")) {
+			DefaultMutableTreeNode exceptionMessageNode = new DefaultMutableTreeNode(
+					exceptionMessage);
+			errDocumentString += exceptionMessageNode + "\n";
+			errDocumentString += errorValue.getTrace();
+		}
+
+		List<Path> errorReferences = errorValue.getCausedBy();
+		if (!errorReferences.isEmpty()) {
+			errDocumentString += "Set of cause errors to follow." + "\n";
+		}
+		int errorCounter = 1;
+		for (Path cause : errorReferences) {
+			if (DataBundles.isError(cause)) {
+			errDocumentString += "ErrorValue " + (errorCounter++) + "\n";
+			errDocumentString += buildErrorValueString(DataBundles.getError(cause)) + "\n";
+			}
+		}
+
+		return errDocumentString;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/InputsHandler.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/InputsHandler.java b/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/InputsHandler.java
new file mode 100644
index 0000000..bcaa7fb
--- /dev/null
+++ b/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/InputsHandler.java
@@ -0,0 +1,280 @@
+/*******************************************************************************
+ * 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.commandline.data;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import net.sf.taverna.t2.commandline.exceptions.InputMismatchException;
+import net.sf.taverna.t2.commandline.exceptions.InvalidOptionException;
+import net.sf.taverna.t2.commandline.exceptions.ReadInputException;
+import net.sf.taverna.t2.commandline.options.CommandLineOptions;
+import net.sf.taverna.t2.invocation.InvocationContext;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.log4j.Logger;
+import org.jdom.JDOMException;
+import org.purl.wf4ever.robundle.Bundle;
+
+import uk.org.taverna.databundle.DataBundles;
+import uk.org.taverna.scufl2.api.port.InputWorkflowPort;
+
+/**
+ * Handles the reading, or processing, or input values according to arguments provided to the
+ * commandline.
+ * The may be either as direct values, from a file, or from a Baclava document.
+ * Also handles registering the input values with the Data Service, ready to initiate
+ * the workflow run.
+ *
+ * @author Stuart Owen
+ */
+public class InputsHandler {
+
+	private static Logger logger = Logger.getLogger(InputsHandler.class);
+
+	public void checkProvidedInputs(Map<String, InputWorkflowPort> portMap,
+			CommandLineOptions options) throws InputMismatchException {
+		// we dont check for the document
+                Set<String> providedInputNames = new HashSet<String>();
+                for (int i = 0; i < options.getInputFiles().length; i += 2) {
+                        // If it already contains a value for the input port, e.g
+                        // two inputs are provided for the same port
+                        if (providedInputNames.contains(options.getInputFiles()[i])) {
+                                throw new InputMismatchException(
+                                        "Two input values were provided for the same input port "
+                                        + options.getInputFiles()[i] + ".", null, null);
+                        }
+                        providedInputNames.add(options.getInputFiles()[i]);
+                }
+
+                for (int i = 0; i < options.getInputValues().length; i += 2) {
+                        // If it already contains a value for the input port, e.g
+                        // two inputs are provided for the same port
+                        if (providedInputNames.contains(options.getInputValues()[i])) {
+                                throw new InputMismatchException(
+                                        "Two input values were provided for the same input port "
+                                        + options.getInputValues()[i] + ".", null, null);
+                        }
+                        providedInputNames.add(options.getInputValues()[i]);
+                }
+
+                if (portMap.size() * 2 != (options.getInputFiles().length + options.getInputValues().length)) {
+                        throw new InputMismatchException(
+                                    "The number of inputs provided does not match the number of input ports.",
+						portMap.keySet(), providedInputNames);
+                }
+
+                for (String portName : portMap.keySet()) {
+                        if (!providedInputNames.contains(portName)) {
+                                throw new InputMismatchException(
+                                        "The provided inputs does not contain an input for the port '"
+                                        + portName + "'", portMap.keySet(), providedInputNames);
+			}
+		}
+	}
+
+	public Bundle registerInputs(Map<String, InputWorkflowPort> portMap,
+			CommandLineOptions options, InvocationContext context) throws InvalidOptionException,
+			ReadInputException, IOException {
+		Bundle inputDataBundle;
+		inputDataBundle = DataBundles.createBundle();
+		inputDataBundle.setDeleteOnClose(false);
+		System.out.println("Bundle: " + inputDataBundle.getSource());
+		
+		Path inputs = DataBundles.getInputs(inputDataBundle);
+
+		URL url;
+		try {
+			url = new URL("file:");
+		} catch (MalformedURLException e1) {
+			// Should never happen, but just in case:
+			throw new ReadInputException(
+					"The was an internal error setting up the URL to open the inputs. You should contact Taverna support.",
+					e1);
+		}
+
+		if (options.hasInputFiles()) {
+			regesterInputsFromFiles(portMap, options, inputs, url);
+		}
+
+		if (options.hasInputValues()) {
+			registerInputsFromValues(portMap, options, inputs);
+
+		}
+
+		return inputDataBundle;
+	}
+
+	private void registerInputsFromValues(Map<String, InputWorkflowPort> portMap,
+			CommandLineOptions options, Path inputs) throws InvalidOptionException {
+		String[] inputParams = options.getInputValues();
+		for (int i = 0; i < inputParams.length; i = i + 2) {
+			String inputName = inputParams[i];
+			try {
+				String inputValue = inputParams[i + 1];
+				InputWorkflowPort port = portMap.get(inputName);
+
+				if (port == null) {
+					throw new InvalidOptionException("Cannot find an input port named '"
+							+ inputName + "'");
+				}
+
+				Path portPath = DataBundles.getPort(inputs, inputName);
+				if (options.hasDelimiterFor(inputName)) {
+					String delimiter = options.inputDelimiter(inputName);
+					Object value = checkForDepthMismatch(1, port.getDepth(), inputName,
+							inputValue.split(delimiter));
+					setValue(portPath, value);
+				} else {
+					Object value = checkForDepthMismatch(0, port.getDepth(), inputName, inputValue);
+					setValue(portPath, value);
+				}
+
+			} catch (IndexOutOfBoundsException e) {
+				throw new InvalidOptionException("Missing input value for input " + inputName);
+			} catch (IOException e) {
+				throw new InvalidOptionException("Error creating value for input " + inputName);
+			}
+		}
+	}
+
+	private void regesterInputsFromFiles(Map<String, InputWorkflowPort> portMap,
+			CommandLineOptions options, Path inputs, URL url) throws InvalidOptionException {
+		String[] inputParams = options.getInputFiles();
+		for (int i = 0; i < inputParams.length; i = i + 2) {
+			String inputName = inputParams[i];
+			try {
+				URL inputURL = new URL(url, inputParams[i + 1]);
+				InputWorkflowPort port = portMap.get(inputName);
+
+				if (port == null) {
+					throw new InvalidOptionException("Cannot find an input port named '"
+							+ inputName + "'");
+				}
+
+				Path portPath = DataBundles.getPort(inputs, inputName);
+				if (options.hasDelimiterFor(inputName)) {
+					String delimiter = options.inputDelimiter(inputName);
+					Object value = IOUtils.toString(inputURL.openStream()).split(delimiter);
+					value = checkForDepthMismatch(1, port.getDepth(), inputName, value);
+					setValue(portPath, value);
+				} else {
+					Object value = IOUtils.toByteArray(inputURL.openStream());
+					value = checkForDepthMismatch(0, port.getDepth(), inputName, value);
+					setValue(portPath, value);
+				}
+			} catch (IndexOutOfBoundsException e) {
+				throw new InvalidOptionException("Missing input filename for input " + inputName);
+			} catch (IOException e) {
+				throw new InvalidOptionException("Could not read input " + inputName + ": "
+						+ e.getMessage());
+			}
+		}
+	}
+
+	private void setValue(Path port, Object userInput) throws IOException {
+		if (userInput instanceof File) {
+			DataBundles.setReference(port, ((File) userInput).toURI());
+		} else if (userInput instanceof URL) {
+			try {
+				DataBundles.setReference(port, ((URL) userInput).toURI());
+			} catch (URISyntaxException e) {
+				logger.warn(String.format("Error converting %1$s to URI", userInput), e);
+			}
+		} else if (userInput instanceof String) {
+			DataBundles.setStringValue(port, (String) userInput);
+		} else if (userInput instanceof byte[]) {
+			Files.write(port, (byte[]) userInput, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
+		} else if (userInput instanceof List<?>) {
+			DataBundles.createList(port);
+			List<?> list = (List<?>) userInput;
+			for (Object object : list) {
+				setValue(DataBundles.newListItem(port), object);
+			}
+		} else {
+			logger.warn("Unknown input type : " + userInput.getClass().getName());
+		}
+	}
+
+	private Object checkForDepthMismatch(int inputDepth, int portDepth, String inputName,
+			Object inputValue) throws InvalidOptionException {
+		if (inputDepth != portDepth) {
+			if (inputDepth < portDepth) {
+				logger.warn("Wrapping input for '" + inputName + "' from a depth of " + inputDepth
+						+ " to the required depth of " + portDepth);
+				while (inputDepth < portDepth) {
+					List<Object> l = new ArrayList<Object>();
+					l.add(inputValue);
+					inputValue = l;
+					inputDepth++;
+				}
+			} else {
+				String msg = "There is a mismatch between depth of the list for the input port '"
+						+ inputName + "' and the data presented. The input port requires a "
+						+ depthToString(portDepth) + " and the data presented is a "
+						+ depthToString(inputDepth);
+				throw new InvalidOptionException(msg);
+			}
+		}
+
+		return inputValue;
+	}
+
+	private String depthToString(int depth) {
+		switch (depth) {
+		case 0:
+			return "single item";
+		case 1:
+			return "list";
+		case 2:
+			return "list of lists";
+		default:
+			return "list of depth " + depth;
+		}
+	}
+
+	private int getObjectDepth(Object o) {
+		int result = 0;
+		if (o instanceof Iterable) {
+			result++;
+			Iterator i = ((Iterable) o).iterator();
+
+			if (i.hasNext()) {
+				Object child = i.next();
+				result = result + getObjectDepth(child);
+			}
+		}
+		return result;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/53c8a6c1/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/SaveResultsHandler.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/SaveResultsHandler.java b/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/SaveResultsHandler.java
new file mode 100644
index 0000000..1df05c2
--- /dev/null
+++ b/taverna-commandline-common/src/main/java/net/sf/taverna/t2/commandline/data/SaveResultsHandler.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * 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.commandline.data;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Map;
+
+import uk.org.taverna.databundle.DataBundles;
+
+/**
+ * Handles all recording of results as they are received by the {@link CommandLineResultListener} or
+ * when the workflow enactment has completed.
+ * This includes saving as a Baclava Document, or storing individual results.
+ *
+ * @author Stuart Owen
+ * @see BaclavaHandler
+ * @see CommandLineResultListener
+ */
+public class SaveResultsHandler {
+
+	private final File outputDirectory;
+
+	public SaveResultsHandler(File rootOutputDir) {
+		this.outputDirectory = rootOutputDir;
+	}
+
+	/**
+	 * Given the Data on an output port, saves the data on a disk in the
+	 * output directory.
+	 *
+	 * @param portName
+	 * @param data
+	 * @throws IOException
+	 */
+	public void saveResultsForPort(String portName, Path data) throws IOException {
+		if (DataBundles.isList(data)) {
+			Path outputPath = outputDirectory.toPath().resolve(portName);
+			Files.createDirectories(outputPath);
+			saveList(DataBundles.getList(data), outputPath);
+		} else if (DataBundles.isError(data)) {
+			Files.copy(data, outputDirectory.toPath().resolve(portName + ".error"));
+		} else {
+			Files.copy(data, outputDirectory.toPath().resolve(portName));
+		}
+	}
+
+	private void saveList(List<Path> list, Path destination) throws IOException {
+		int index = 1;
+		for (Path data : list) {
+			if (data != null) {
+				if (DataBundles.isList(data)) {
+					Path outputPath = destination.resolve(String.valueOf(index));
+					Files.createDirectories(outputPath);
+					saveList(DataBundles.getList(data), outputPath);
+				} else if (DataBundles.isError(data)) {
+					Files.copy(data, destination.resolve(String.valueOf(index) + ".error"));
+				} else {
+					Files.copy(data, destination.resolve(String.valueOf(index)));
+				}
+			}
+			index++;
+		}
+	}
+
+}