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:05:12 UTC

[27/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-examples/src/main/java/org/apache/taverna/examples/WorkflowMaker.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/WorkflowMaker.java b/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/WorkflowMaker.java
new file mode 100644
index 0000000..bdf9ac4
--- /dev/null
+++ b/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/WorkflowMaker.java
@@ -0,0 +1,412 @@
+package org.apache.taverna.examples;
+
+/*
+ * 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 java.io.File;
+import java.io.IOException;
+import java.net.URI;
+
+import org.apache.taverna.scufl2.api.activity.Activity;
+import org.apache.taverna.scufl2.api.common.Scufl2Tools;
+import org.apache.taverna.scufl2.api.configurations.Configuration;
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.scufl2.api.core.DataLink;
+import org.apache.taverna.scufl2.api.core.Processor;
+import org.apache.taverna.scufl2.api.core.Workflow;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.api.io.WorkflowBundleIO;
+import org.apache.taverna.scufl2.api.io.WriterException;
+import org.apache.taverna.scufl2.api.iterationstrategy.DotProduct;
+import org.apache.taverna.scufl2.api.iterationstrategy.PortNode;
+import org.apache.taverna.scufl2.api.port.InputActivityPort;
+import org.apache.taverna.scufl2.api.port.InputProcessorPort;
+import org.apache.taverna.scufl2.api.port.InputWorkflowPort;
+import org.apache.taverna.scufl2.api.port.OutputActivityPort;
+import org.apache.taverna.scufl2.api.port.OutputProcessorPort;
+import org.apache.taverna.scufl2.api.port.OutputWorkflowPort;
+import org.apache.taverna.scufl2.api.profiles.ProcessorBinding;
+import org.apache.taverna.scufl2.api.profiles.ProcessorInputPortBinding;
+import org.apache.taverna.scufl2.api.profiles.ProcessorOutputPortBinding;
+import org.apache.taverna.scufl2.api.profiles.Profile;
+
+public class WorkflowMaker {
+	private static Scufl2Tools scufl2Tools = new Scufl2Tools();
+	private static WorkflowBundleIO bundleIO = new WorkflowBundleIO();
+
+	public static void main(String[] args) throws Exception {
+		new WorkflowMaker().makeWorkflowBundle();
+	}
+
+	protected WorkflowBundle bundle;
+	protected Workflow workflow;
+	protected Processor p;
+	protected InputProcessorPort pIn;
+	protected OutputProcessorPort pOut;
+	protected Profile profile;
+	protected Activity myBeanshell;
+	protected File file;
+
+	
+	public void makeWorkflowBundle() throws IOException, WriterException,
+			ReaderException {
+
+		/** Top-level object is a Workflow Bundle */
+		bundle = new WorkflowBundle();
+
+		/** Generate the workflow structure **/
+		makeWorkflow();
+		
+		/** Specify the implementations **/
+		makeProfile();
+
+		/**
+		 * Before storing the workflow bundle, we'll make sure that everything
+		 * we made has a parent included (so that for instance a configuration
+		 * is stored together with its parent profile). The
+		 * scufl2Tools.setParents method will traverse the WorkflowBundle from
+		 * the top and fill in any blank parents.
+		 */
+		scufl2Tools.setParents(bundle);
+
+		/** Write bundle to StdOut and a new file */
+		writeBundleToFile();
+
+	}
+
+
+	private void makeWorkflow() {
+		workflow = new Workflow();
+		/** Workflow names must be unique within the WorkflowBundle */
+		workflow.setName("Echotest");
+	
+		bundle.setMainWorkflow(workflow);
+		/**
+		 * Additional (typically nested) workflows can be added:
+		 * 
+		 * <pre>
+		 * bundle.getWorkflows().add(workflow2)
+		 * </pre>
+		 * 
+		 * but the above is implied by setMainWorkflow()
+		 */
+	
+		/** Creating and adding a workflow port */
+		InputWorkflowPort in1 = new InputWorkflowPort();
+		in1.setName("in1");
+		in1.setDepth(0);
+		/** where does this input port belong? */
+		in1.setParent(workflow);
+		/**
+		 * implies:
+		 * 
+		 * <pre>
+		 * workflow.getInputPorts().add(in1);
+		 * </pre>
+		 */
+	
+		/**
+		 * If input should be a list instead of single value:
+		 * 
+		 * <pre>
+		 * in1.setDepth(1);
+		 * </pre>
+		 */
+	
+		/** Output, this time using the shorthand constructors */
+		OutputWorkflowPort out1 = new OutputWorkflowPort(workflow, "out1");
+	
+		/**
+		 * A processor is a unit which performs some work in a workflow. The
+		 * name must be unique within the parent workflow.
+		 * 
+		 */
+		p = new Processor(workflow, "p");
+	
+		/**
+		 * Same as:
+		 * 
+		 * <pre>
+		 * Processor p = new Processor();
+		 * p.setName(&quot;p&quot;);
+		 * p.setParent(workflow);
+		 * workflow.getProcessors().add(p);
+		 * </pre>
+		 */
+	
+		/**
+		 * Processors typically have inputs and outputs which are connected
+		 * within the workflow
+		 */
+		pIn = new InputProcessorPort(p, "pIn");
+		pIn.setDepth(0);
+		pOut = new OutputProcessorPort(p, "pOut");
+		pOut.setDepth(0);
+		pOut.setGranularDepth(0);
+		/**
+		 * .. any additional ports must have a unique name within the input or
+		 * output ports of that processor.
+		 */
+	
+		/**
+		 * Defining a data link from the workflow input port 'in1' to the
+		 * processor input port 'pIn' - this means that data will flow from
+		 * 'in1' to 'pIn'.
+		 */
+		DataLink link = new DataLink();
+		link.setReceivesFrom(in1);
+		link.setSendsTo(pIn);
+		/**
+		 * The ports must be either processor or workflow ports, and both of the
+		 * same workflow as the datalink is added to:
+		 */
+		workflow.getDataLinks().add(link);		
+	
+		/**
+		 * Or more compact style: pOut -> out1 .. connecting processor output
+		 * port 'pOut' to the workflow output port 'out1'
+		 */
+		new DataLink(workflow, pOut, out1);
+		/**
+		 * the constructor will perform for us:
+		 * 
+		 * <pre>
+		 * setParent(workflow)
+		 * 		workflow.getDataLinks().add(workflow)
+		 * </pre>
+		 */
+	
+		/**
+		 * Note: As datalinks are unique based on the connection, they don't
+		 * have names
+		 */
+		
+		/**
+		 * Not covered by this example:
+		 * 
+		 * Dispatch stack:
+		 * 
+		 * <pre>
+		 * DispatchStackLayer dispatchStackLayer = new DispatchStackLayer();
+		 * dispatchStackLayer
+		 * 		.setConfigurableType(URI
+		 * 				.create(&quot;http://ns.taverna.org.uk/2010/scufl2/taverna/dispatchlayer/Retry&quot;));
+		 * p.getDispatchStack().add(dispatchStackLayer);
+		 * Configuration retryConfig = new Configuration();
+		 * retryConfig.setConfigures(dispatchStackLayer);
+		 * // ..
+		 * </pre>
+		 */ 
+		
+		/*
+		 * Iteration strategies:
+		 */
+		 DotProduct dot = new DotProduct();
+		 PortNode e = new PortNode(dot, pIn);
+		 e.setDesiredDepth(0); 
+		 p.getIterationStrategyStack().add(dot);
+
+	}
+
+
+	private void makeProfile() {
+		profile = new Profile("default");
+
+		/**
+		 * One profile can be suggest as the 'main' profile - but alternative
+		 * execution profiles can also be added, for instance to provide
+		 * Grid-based activities rather than Web Service activities - each of
+		 * them must have a unique name within the profiles of the workflow
+		 * bundle.
+		 */
+		bundle.setMainProfile(profile);
+
+		/**
+		 * Additional profiles can be added with:
+		 * 
+		 * <pre>
+		 * bundle.getProfiles().add(profile2);
+		 * </pre>
+		 */
+
+		myBeanshell = new Activity("myBeanshell");
+
+		/**
+		 * Activities are of different types, identified by an URI. A workflow
+		 * engine will typically expose which activity types it supports.
+		 * <p>
+		 * The default types of Taverna have the prefix
+		 * http://ns.taverna.org.uk/2010/activity/, but other plugins will have
+		 * different URI bases.
+		 */
+		URI BEANSHELL = URI
+				.create("http://ns.taverna.org.uk/2010/activity/beanshell");
+		myBeanshell.setType(BEANSHELL);
+
+		
+		/**
+		 * Activities are activated within a particular profile (Therefore
+		 * execution of a profile requires the engine to support all types of
+		 * all activities of the profile)
+		 */
+		profile.getActivities().add(myBeanshell);
+
+		makeConfiguration();
+
+		/**
+		 * A Processor Binding connects a Processor ('p') with an Activity
+		 * 'myBeanshell'. This means that execution of p will use the activity.
+		 */
+		ProcessorBinding binding = new ProcessorBinding();
+		binding.setBoundProcessor(p);
+		binding.setBoundActivity(myBeanshell);
+
+		/**
+		 * It is possible, but not common, for multiple processor bindings to
+		 * reuse the same activity. On execution, the workflow engine might or
+		 * might not instantiate this as the same activity implementation.
+		 */
+
+		/** And add binding to the profile */
+		binding.setParent(profile);
+		/**
+		 * alternatively:
+		 * 
+		 * <pre>
+		 * profile.getProcessorBindings().add(binding)
+		 * </pre>
+		 */
+
+		/**
+		 * It is possible to bind more than one activity for the same processor,
+		 * in which case they will be used as alternate services on failure. (As
+		 * the default Dispatch Stack contains the Failover layer). In this
+		 * case, the processor bindings should specify the 'activity position',
+		 * which determines the ordering of activities within a processor:
+		 * 
+		 * <pre>
+		 * binding.setActivityPosition(15);
+		 * </pre>
+		 */
+
+		/**
+		 * Activities have input and output ports as well, normally these match
+		 * one-to-one with the bound processor's port names and depth.
+		 */
+		InputActivityPort aIn1 = new InputActivityPort(myBeanshell, "in1");
+		aIn1.setDepth(0);
+		myBeanshell.getInputPorts().add(aIn1);
+		OutputActivityPort aOut1 = new OutputActivityPort(myBeanshell, "out1");
+		aOut1.setDepth(0);
+		aOut1.setGranularDepth(0);
+		myBeanshell.getOutputPorts().add(aOut1);
+
+
+		
+		/**
+		 * But in case the activities don't match up (such as when multiple
+		 * activities are bound to the same processor, or as in this example
+		 * where the port matches the script), a port mapping must be specified
+		 * in the processor binding:
+		 */
+		binding.getInputPortBindings().add(
+				new ProcessorInputPortBinding(binding, pIn, aIn1));
+		new ProcessorOutputPortBinding(binding, aOut1, pOut);
+
+		/**
+		 * It is not required to bind any processor input port, but many
+		 * activities expect some or all their inputs bound. It is not required
+		 * to bind all activity output ports, but all processor output ports
+		 * must be bound for each processor binding.
+		 */
+
+		/** If the port names match up, the above can all be done in one go with */
+		//scufl2Tools.bindActivityToProcessorByMatchingPorts(myBeanshell, p);	
+	}
+
+
+
+	private void makeConfiguration() {
+		URI BEANSHELL = URI
+				.create("http://ns.taverna.org.uk/2010/activity/beanshell");
+		/**
+		 * Most activities also require a configuration in order to run. The
+		 * name of the configuration is not important, but must be unique within
+		 * the configurations of a profile. The default constructor
+		 * Configuration() generates a UUID-based name as a fallback.
+		 */
+		Configuration beanshellConfig = new Configuration("beanshellConf");
+		/**
+		 * The activity we configure. (DispatchStackLayer can also be
+		 * configured)
+		 */
+		beanshellConfig.setConfigures(myBeanshell);
+		/**
+		 * A configuration is of a specified type (specified as an URI), which
+		 * is typically related to (but different from) the activity type - but
+		 * might in some cases be shared amongst several activity types.
+		 */
+		beanshellConfig.setType(BEANSHELL.resolve("#Config"));
+
+		/**
+		 * Configurations are normally shared in the same profile as the
+		 * activity they configure (the parent) - but in some cases might also
+		 * be added by other profiles in order to reuse a configuration across
+		 * profiles. (Note: A profile is *stored* within its parent profile).
+		 */
+		beanshellConfig.setParent(profile);
+		profile.getConfigurations().add(beanshellConfig);
+
+		/**
+		 * Depending on the configuration type specified above, certain
+		 * *properties* should be specified, and other properties might be
+		 * optional. In this case, only "script" is
+		 * specified, as a string value. (more complex properties can be
+		 * specified using Jackson JSON methods of the ObjectNode)
+		 */
+		beanshellConfig.getJsonAsObjectNode().put("script", "out1 = in1");
+		/**
+		 * Note that property names are specified as URIs, which are often
+		 * related to the URI of the configuration type - but might be reused
+		 * across several configuration types.
+		 */
+	}
+
+
+	private void writeBundleToFile() throws IOException, WriterException,
+			ReaderException {
+		file = File.createTempFile("test", ".wfbundle");
+	
+		/**
+		 * Bundle IO 
+		 */
+		bundleIO.writeBundle(bundle, file,
+				"application/vnd.taverna.scufl2.workflow-bundle");
+		System.out.println("Written to " + file + "\n");
+	
+		// Read it back in
+		WorkflowBundle secondBundle = bundleIO.readBundle(file,
+				"application/vnd.taverna.scufl2.workflow-bundle");
+	
+		// Write in a debug text format
+		bundleIO.writeBundle(secondBundle, System.out,
+				"text/vnd.taverna.scufl2.structure");
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/src/main/python/processorNames.py
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/src/main/python/processorNames.py b/taverna-scufl2-examples/src/main/python/processorNames.py
new file mode 100644
index 0000000..d1d62fa
--- /dev/null
+++ b/taverna-scufl2-examples/src/main/python/processorNames.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+#
+#
+# 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 sys
+import zipfile
+import os.path
+import xml.etree.ElementTree
+from rdflib import Graph
+from rdflib import Namespace
+import urllib
+from rdflib.term import URIRef
+
+Scufl2NS = Namespace("http://ns.taverna.org.uk/2010/scufl2#")
+
+
+NS_CONTAINER="{urn:oasis:names:tc:opendocument:xmlns:container}"
+
+
+import rdflib
+
+class Scufl2(object):
+    def __init__(self, filename=None):
+        self.filename = filename
+        if filename is not None:
+            self.zip = zipfile.ZipFile(filename)
+            self.check_mime_type()
+            self.parse()    
+
+    def check_mime_type(self):       
+        mimetype = self.zip.open("mimetype").read()
+        if mimetype != "application/vnd.taverna.scufl2.workflow-bundle":
+            raise Scufl2Error("Unknown mimetype %r" % mimetype)
+
+    def _is_valid_prefix(self, filename):
+        valid_prefixes = ["workflow/", "annotation/", "profile/"]
+        for prefix in valid_prefixes:
+            if filename.startswith(prefix):
+                return True
+        return False        
+
+    def parse_all_graphs(self, sameAs):
+        filenames = {}
+        for filename in self.zip.namelist():
+            if not self._is_valid_prefix(filename):
+                continue
+            if filename.endswith(".ttl"):
+                base = filename[:-4]
+                filenames[base] = filename
+            elif filename.endswith(".rdf"):
+                base = filename[:-4]
+                if not base in filenames:
+                    filenames[base] = filename
+        
+        for name in filenames:
+            filename = filenames[name]
+            rdf_file = self.zip.open(filename)
+            format = "n3"
+            if filename.endswith(".rdf"):
+                format = "xml"
+            base = sameAs + filename
+            self.graph.parse(rdf_file, base, format=format)
+
+    def parse(self):
+        if "workflowBundle.ttl" in self.zip.namelist():
+            format = "n3" 
+            rootfile = "workflowBundle.ttl"
+        elif "workflowBundle.rdf" in self.zip.namelist():
+            rootfile = "workflowBundle.rdf"
+            format = "xml" 
+        else:
+            raise Scufl2Error("Can't find workflowBundle.ttl or "
+                              "workflowBundle.rdf")
+
+        self.uri = "file://" + urllib.pathname2url(os.path.abspath(self.filename)) + "/"
+        early_graph = Graph()    
+        rdf_file = self.zip.open(rootfile)
+        early_graph.parse(rdf_file, self.uri, format=format)
+        sameBaseAs = list(early_graph.objects(subject=URIRef(self.uri), predicate=Scufl2NS.sameBaseAs))
+
+        if not sameBaseAs:
+            # Fall back to the file:/// URIs   
+            self.graph = early_graph
+        else:    
+            # Use the sameBaseAs as the base
+            self.uri = sameBaseAs[0]
+            self.graph = Graph()
+            # Reparse it
+            rdf_file = self.zip.open(rootfile)
+            self.graph.parse(rdf_file, self.uri, format=format)
+
+        self.parse_all_graphs(self.uri)
+
+
+class Scufl2Error(Exception):
+    pass
+
+
+def main(prg="processorNames.py", filename=None):
+    if filename is None:
+        filename = os.path.join(os.path.dirname(prg), "..", "..", "..", "..", 
+        "scufl2-rdfxml", "src", "test", "resources",
+        "uk", "org", "taverna","scufl2","rdfxml", "example.wfbundle")
+    
+    scufl2 = Scufl2(filename)
+    
+    for workflowUri in scufl2.graph.objects(predicate=Scufl2NS.workflow):
+        for name in scufl2.graph.objects(workflowUri, Scufl2NS.name):
+            print name
+        for processorUri in scufl2.graph.objects(workflowUri, Scufl2NS.processor):
+            for name in scufl2.graph.objects(processorUri, Scufl2NS.name):
+                print "---", name, processorUri
+
+
+if __name__ == "__main__":
+    main(*sys.argv)
+

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/src/main/resources/context.json
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/src/main/resources/context.json b/taverna-scufl2-examples/src/main/resources/context.json
new file mode 100644
index 0000000..4286b54
--- /dev/null
+++ b/taverna-scufl2-examples/src/main/resources/context.json
@@ -0,0 +1,20 @@
+{
+  "@context" :  {
+    "foaf": "http://xmlns.com/foaf/0.1/",
+    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
+    "prov": "http://www.w3.org.ns/prov#",
+    "wfdesc": "http://purl.org/wf4ever/wfdesc#",
+    "scufl2": "http://ns.taverna.org.uk/2010/scufl2#",
+
+    "id": "@id",
+    "name": "rdfs:label",
+    "revisions": "prov:alternateOf",
+    "processors": "wfdesc:hasSubProcess",
+    "inputs": "wfdesc:hasInput",
+    "outputs": "wfdesc:hasOutput",
+    "depth": "scufl2:depth",
+    "granularDepth": "scufl2:granularDepth",
+    "workflow": "foaf:primaryTopic",
+    "generatedAtTime": "prov:generatedAtTime"
+  } 
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/src/main/ruby/processors.rb
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/src/main/ruby/processors.rb b/taverna-scufl2-examples/src/main/ruby/processors.rb
new file mode 100644
index 0000000..e3de933
--- /dev/null
+++ b/taverna-scufl2-examples/src/main/ruby/processors.rb
@@ -0,0 +1,93 @@
+#
+#
+# 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.
+#
+#
+
+require 'rubygems'
+require 'rdf'
+#require 'rdf/raptor'
+require 'zip/zipfilesystem'
+
+scufl2 = RDF::Vocabulary.new("http://ns.taverna.org.uk/2010/scufl2#")
+dc = RDF::Vocabulary.new("http://purl.org/dc/elements/1.1/")
+
+graph = RDF::Graph.load("../../../../taverna-scufl2-rdfxml/src/test/resources/org/apache/taverna/scufl2/rdfxml/example/workflowBundle.rdf")
+
+graph = RDF::Graph.new()
+Zip::ZipFile.open("../../../../taverna-scufl2-rdfxml/src/test/resources/org/apache/taverna/scufl2/rdfxml/example.wfbundle") {
+    |zipfile|
+    a = zipfile.file.read("workflowBundle.rdf")
+    RDF::Reader.for(:rdfxml).new(a) do |reader|
+      reader.each_statement do |statement|
+        graph << statement
+      end
+    end
+
+    base = "http://example.org/" 
+    graph.query([nil,scufl2.sameBaseAs,nil]) do |s,p,base|
+    end 
+
+    a = zipfile.file.read("workflowBundle.rdf")
+    RDF::Reader.for(:rdfxml).new(a) do |reader|
+      reader.each_statement do |statement|
+        graph << statement
+      end
+    end
+    # TODO: FOR-loop like in Python
+
+    a = zipfile.file.read("workflow/HelloWorld.rdf")
+    RDF::Reader.for(:rdfxml).new(a) do |reader|
+      reader.each_statement do |statement|
+        graph << statement
+      end
+    end
+    a = zipfile.file.read("annotation/workflow/HelloWorld.rdf")
+    RDF::Reader.for(:rdfxml).new(a) do |reader|
+      reader.each_statement do |statement|
+        graph << statement
+      end
+    end
+}
+
+graph.query([nil, scufl2.workflow, nil]) do |bundle,p,workflow|
+  graph.query([workflow, scufl2.name, nil]) do |wf,p,workflow_name|
+    # Should just be one
+    print workflow_name  
+  end
+  graph.query([workflow, dc.description, nil]) do |workflow,p,description|
+    # Optional description(s)
+    print "  "
+    print description
+  end
+  print "\n"
+
+  graph.query([workflow, scufl2.processor, nil]) do |workflow,p,processor|
+    graph.query([processor, scufl2.name, nil]) do |processor,p,processor_name|
+        print processor_name
+    end
+    graph.query([processor, dc.description, nil]) do |processor,p,description|
+        print "  "
+        print description
+    end
+    print "\n"
+    
+  end
+end
+
+

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestConvertT2flowScufl2.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestConvertT2flowScufl2.java b/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestConvertT2flowScufl2.java
new file mode 100644
index 0000000..5368a24
--- /dev/null
+++ b/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestConvertT2flowScufl2.java
@@ -0,0 +1,55 @@
+package org.apache.taverna.examples;
+
+/*
+ * 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.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.util.zip.ZipFile;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.taverna.examples.ConvertT2flowToWorkflowBundle;
+import org.junit.Test;
+
+
+public class TestConvertT2flowScufl2 {
+	@Test
+	public void convertToScufl2() throws Exception {
+		File tmp = File.createTempFile("helloworld", ".t2flow");
+		tmp.deleteOnExit();
+		InputStream ebi = getClass().getResourceAsStream("/workflows/t2flow/helloworld.t2flow");
+		FileOutputStream output = new FileOutputStream(tmp);
+		IOUtils.copy(ebi, output);
+		output.close();
+		
+		ConvertT2flowToWorkflowBundle.main(new String[]{tmp.getAbsolutePath()});		
+		File scufl2File = new File(tmp.getAbsolutePath().replace(".t2flow", ".wfbundle"));
+		assertTrue(scufl2File.isFile());
+		try (ZipFile zip = new ZipFile(scufl2File)) {
+			assertNotNull(zip.getEntry("workflowBundle.rdf"));
+		}
+		scufl2File.deleteOnExit();
+//		System.out.println(scufl2File);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestJsonExport.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestJsonExport.java b/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestJsonExport.java
new file mode 100644
index 0000000..ac1d415
--- /dev/null
+++ b/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestJsonExport.java
@@ -0,0 +1,75 @@
+package org.apache.taverna.examples;
+
+/*
+ * 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.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.taverna.examples.JsonExport;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class TestJsonExport {
+    @Test
+    public void jsonExportHelloAnyone() throws Exception {
+        File tmp = File.createTempFile("helloanyone", ".t2flow");
+        tmp.deleteOnExit();
+        InputStream ebi = getClass().getResourceAsStream("/workflows/t2flow/helloanyone.t2flow");
+        FileOutputStream output = new FileOutputStream(tmp);
+        IOUtils.copy(ebi, output);
+        output.close();
+
+        
+        JsonExport jsonExport = new JsonExport();
+        jsonExport.convert(new String[]{tmp.getAbsolutePath()});        
+        File jsonFile = new File(tmp.getAbsolutePath().replace(".t2flow", ".json"));
+        assertTrue(jsonFile.isFile());
+        jsonFile.deleteOnExit();
+//      System.out.println(scufl2File);
+        //System.out.println(FileUtils.readFileToString(jsonFile, "UTF-8"));
+    }
+    
+    @Ignore("Takes 24 seconds!")
+    @Test
+    public void jsonExportNested() throws Exception {
+        File tmp = File.createTempFile("enm", ".t2flow");
+        tmp.deleteOnExit();
+        InputStream ebi = getClass().getResourceAsStream("/workflows/t2flow/generic_enm_workflow_with_interaction_615643.t2flow");
+        FileOutputStream output = new FileOutputStream(tmp);
+        IOUtils.copy(ebi, output);
+        output.close();
+
+        
+        JsonExport jsonExport = new JsonExport();
+        jsonExport.convert(new String[]{tmp.getAbsolutePath()});        
+        File jsonFile = new File(tmp.getAbsolutePath().replace(".t2flow", ".json"));
+        assertTrue(jsonFile.isFile());
+//        jsonFile.deleteOnExit();
+      //System.out.println(jsonFile);
+//        System.out.println(FileUtils.readFileToString(jsonFile, "UTF-8"));
+    }
+    
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestProcessorNames.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestProcessorNames.java b/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestProcessorNames.java
new file mode 100644
index 0000000..ee3e844
--- /dev/null
+++ b/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestProcessorNames.java
@@ -0,0 +1,88 @@
+package org.apache.taverna.examples;
+
+/*
+ * 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.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.xml.bind.JAXBException;
+
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.api.io.WorkflowBundleIO;
+import org.junit.Test;
+
+public class TestProcessorNames {
+
+	@Test
+	public void processorNames() throws JAXBException, IOException, ReaderException {
+		InputStream workflow = getClass().getResourceAsStream(
+				"/workflows/t2flow/defaultActivitiesTaverna2.2.t2flow");
+		assertNotNull(workflow);
+
+		WorkflowBundleIO io = new WorkflowBundleIO();
+		WorkflowBundle ro = io.readBundle(workflow,
+				"application/vnd.taverna.t2flow+xml");
+
+		List<String> expected = Arrays.asList("Beanshell", "Nested_workflow",
+				"Rshell", "Send_an_Email", "SpreadsheetImport",
+				"String_constant", "TavernaResearchObject", "biomart",
+				"localWorker", "localWorker_bytearray", "mobyObject",
+				"mobyService", "run", "run_input", "run_output",
+				"setWorkflows", "soaplab", "wsdl_document", "wsdl_rpc",
+				"wsdl_secured", "xmlSplitter");
+		ProcessorNames processorNames = new ProcessorNames();
+		assertEquals(expected, processorNames.showProcessorNames(ro));
+	}
+	
+
+	@Test
+	public void nestedWorkflow() throws JAXBException, IOException, ReaderException {
+		InputStream workflow = getClass().getResourceAsStream(
+				"/workflows/t2flow/as.t2flow");
+		assertNotNull(workflow);
+
+		WorkflowBundleIO io = new WorkflowBundleIO();
+		WorkflowBundle ro = io.readBundle(workflow,
+				"application/vnd.taverna.t2flow+xml");
+		ProcessorNames processorNames = new ProcessorNames();
+		assertEquals(8, processorNames.showProcessorNames(ro).size());
+	}
+	
+
+	@Test
+	public void nestedWorkflowBundle() throws JAXBException, IOException, ReaderException {
+		InputStream workflow = getClass().getResourceAsStream(
+				"/workflows/wfbundle/as.wfbundle");
+		assertNotNull(workflow);
+
+		WorkflowBundleIO io = new WorkflowBundleIO();
+		WorkflowBundle ro = io.readBundle(workflow, null);
+		ProcessorNames processorNames = new ProcessorNames();
+		assertEquals(8, processorNames.showProcessorNames(ro).size());
+	}
+	
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestServiceTypes.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestServiceTypes.java b/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestServiceTypes.java
new file mode 100644
index 0000000..03fd0c8
--- /dev/null
+++ b/taverna-scufl2-examples/src/test/java/org/apache/taverna/examples/TestServiceTypes.java
@@ -0,0 +1,105 @@
+package org.apache.taverna.examples;
+
+/*
+ * 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.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+
+public class TestServiceTypes {
+	@Test
+	public void defaultActivitiesT2flow() throws Exception {
+		File tmp = File.createTempFile("defaultActivities2.2", ".t2flow");
+		tmp.deleteOnExit();
+		InputStream ebi = getClass()
+				.getResourceAsStream(
+						"/workflows/t2flow/defaultActivitiesTaverna2.2.t2flow");
+		FileOutputStream output = new FileOutputStream(tmp);
+		IOUtils.copy(ebi, output);
+		output.close();
+
+		Set<String> expectedTypes = new HashSet<String>();
+		expectedTypes.addAll(Arrays.asList(
+				"http://ns.taverna.org.uk/2010/activity/beanshell",
+				"http://ns.taverna.org.uk/2010/activity/nested-workflow",
+				"http://ns.taverna.org.uk/2010/activity/rshell",
+				"http://ns.taverna.org.uk/2010/activity/spreadsheet-import",
+				"http://ns.taverna.org.uk/2010/activity/constant",
+				"http://ns.taverna.org.uk/2010/activity/apiconsumer",
+				"http://ns.taverna.org.uk/2010/activity/biomart",
+				"http://ns.taverna.org.uk/2010/activity/biomoby/object",
+				"http://ns.taverna.org.uk/2010/activity/biomoby/service",
+				"http://ns.taverna.org.uk/2010/activity/wsdl",
+				"http://ns.taverna.org.uk/2010/activity/xml-splitter/in",
+				"http://ns.taverna.org.uk/2010/activity/xml-splitter/out",
+				"http://ns.taverna.org.uk/2010/activity/soaplab"));
+
+		Set<String> types = new ServiceTypes().serviceTypes(new String[] { tmp
+				.getAbsolutePath() });
+//		List<String> expected = new ArrayList<>(expectedTypes);
+//		List<String> actual = new ArrayList<>(types);
+//		Collections.sort(expected);
+//		Collections.sort(actual);
+//		assertEquals(expected.toString(), actual.toString());
+		assertEquals(expectedTypes, types);
+	}
+	
+	@Test
+	public void defaultActivitiesWfBundle() throws Exception {
+		File tmp = File.createTempFile("defaultActivities2.2", ".wfbundle");
+		tmp.deleteOnExit();
+		InputStream ebi = getClass()
+				.getResourceAsStream(
+						"/workflows/wfbundle/defaultActivitiesTaverna2.wfbundle");
+		FileOutputStream output = new FileOutputStream(tmp);
+		IOUtils.copy(ebi, output);
+		output.close();
+
+		Set<String> expectedTypes = new HashSet<String>();
+		expectedTypes.addAll(Arrays.asList(
+				"http://ns.taverna.org.uk/2010/activity/beanshell",
+				"http://ns.taverna.org.uk/2010/activity/nested-workflow",
+				"http://ns.taverna.org.uk/2010/activity/rshell",
+				"http://ns.taverna.org.uk/2010/activity/spreadsheet-import",
+				"http://ns.taverna.org.uk/2010/activity/constant",
+				"http://ns.taverna.org.uk/2010/activity/apiconsumer",
+				"http://ns.taverna.org.uk/2010/activity/biomart",
+				"http://ns.taverna.org.uk/2010/activity/biomoby/object",
+				"http://ns.taverna.org.uk/2010/activity/biomoby/service",
+				"http://ns.taverna.org.uk/2010/activity/wsdl",
+				"http://ns.taverna.org.uk/2010/activity/xml-splitter/in",
+				"http://ns.taverna.org.uk/2010/activity/xml-splitter/out",
+				"http://ns.taverna.org.uk/2010/activity/soaplab"));
+
+		Set<String> types = new ServiceTypes().serviceTypes(new String[] { tmp
+				.getAbsolutePath() });
+		assertEquals(expectedTypes, types);
+	}
+	
+}