You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by re...@apache.org on 2015/03/23 17:38:00 UTC

[16/51] [partial] incubator-taverna-engine git commit:

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/MonitorManager.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/MonitorManager.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/MonitorManager.java
new file mode 100644
index 0000000..8662ebb
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/MonitorManager.java
@@ -0,0 +1,377 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.monitor;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.taverna.lang.observer.MultiCaster;
+import org.apache.taverna.lang.observer.Observable;
+import org.apache.taverna.lang.observer.Observer;
+import org.apache.taverna.monitor.MonitorManager.MonitorMessage;
+
+/**
+ * Manages a list of monitors implementations that get notified to register and
+ * deregister nodes (ie. {@link{org.apache.taverna.monitor.MonitorNode}s), in
+ * addition to the addition of {@link MonitorableProperty monitorable
+ * properties} of such nodes.
+ * <p>
+ * Nodes are identified by their owning process, which is an array of strings,
+ * for instance ["dataflow2", "processor5", "fish"]
+ * <p>
+ * To notify the (by default 0) monitors, use any of the
+ * {@link #addPropertiesToNode(String[], Set)},
+ * {@link #registerNode(Object, String[], Set)}, {@link #deregisterNode(String)}
+ * methods and variants.
+ * <p>
+ * To register a monitor, use {@link #addObserver(Observer)}.
+ * 
+ * @author Stian Soiland-Reyes
+ */
+public class MonitorManager implements Observable<MonitorMessage> {
+	private static MonitorManager instance;
+
+	/**
+	 * Get the MonitorManager singleton instance.
+	 * 
+	 * @return The MonitorManager singleton
+	 */
+	public synchronized static MonitorManager getInstance() {
+		if (instance == null)
+			setInstance(new MonitorManager());
+		return instance;
+	}
+
+	/**
+	 * Set the MonitorManager singleton instance. Only to be used by overriding
+	 * super classes at initialisation time.
+	 * 
+	 * @param instance
+	 *            MonitorManager singleton to be returned by
+	 *            {@link #getInstance()}.
+	 */
+	protected synchronized static void setInstance(MonitorManager instance) {
+		MonitorManager.instance = instance;
+	}
+
+	protected MultiCaster<MonitorMessage> multiCaster = new MultiCaster<>(this);
+
+	/**
+	 * Protected constructor, use singleton access
+	 * {@link MonitorManager#getInstance()} instead.
+	 * 
+	 */
+	protected MonitorManager() {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void addObserver(Observer<MonitorMessage> observer) {
+		multiCaster.addObserver(observer);
+	}
+
+	/**
+	 * Push new property get / set methods into the specified node. This is used
+	 * for monitor-able activities where we have to create the node in the state
+	 * tree before we have the set of monitor-able properties for it.
+	 * 
+	 * @param owningProcess
+	 *            the node path to add properties, this must already be
+	 *            registered in the state model, if not then this method fails
+	 *            silently and does nothing.
+	 * @param newProperties
+	 *            the set of properties to add to the specified node in the
+	 *            state model
+	 */
+	public void addPropertiesToNode(String[] owningProcess,
+			Set<MonitorableProperty<?>> newProperties) {
+		multiCaster.notify(new AddPropertiesMessage(owningProcess,
+				newProperties));
+	}
+
+	/**
+	 * Remove the specified node from the monitor. This must be called when the
+	 * final data or completion event leaves a boundary of control. The monitor
+	 * is free to delay the actual removal of state, in which case the node may
+	 * choose to throw exceptions when properties are accessed. The monitor
+	 * should eventually release all references to work-flow objects and process
+	 * identifiers - typically this is used to allow a UI a few seconds delay on
+	 * de-registration so that very fast register / de-register cycles are
+	 * visible to a user.
+	 * <p>
+	 * The specified process identifier must exist within the monitor.
+	 * 
+	 * @param owningProcess
+	 *            the identifier of the node to remove as a :-separated string
+	 */
+	public void deregisterNode(String owningProcessIdentifier) {
+		deregisterNode(owningProcessIdentifier.split(":"));
+	}
+
+	/**
+	 * Remove the specified node from the monitor. This must be called when the
+	 * final data or completion event leaves a boundary of control. The monitor
+	 * is free to delay the actual removal of state, in which case the node may
+	 * choose to throw exceptions when properties are accessed. The monitor
+	 * should eventually release all references to work-flow objects and process
+	 * identifiers - typically this is used to allow a UI a few seconds delay on
+	 * de-registration so that very fast register / de-register cycles are
+	 * visible to a user.
+	 * <p>
+	 * The specified process identifier must exist within the monitor.
+	 * 
+	 * @param owningProcess
+	 *            the identifier of the node to remove.
+	 */
+	public void deregisterNode(String[] owningProcess) {
+		multiCaster.notify(new DeregisterNodeMessage(owningProcess));
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public List<Observer<MonitorMessage>> getObservers() {
+		return multiCaster.getObservers();
+	}
+
+	/**
+	 * Register a new node with this monitor. New nodes can only be registered
+	 * when a new process identifier is allocated to data corresponding to entry
+	 * to a boundary of control in the data-flow. For cases where extensions
+	 * such as dispatch layers wish to augment existing state the plug-in point
+	 * is responsible for the aggregation of appropriate properties.
+	 * <p>
+	 * The process identifier must not already exist within the state tree, if
+	 * it does it will be ignored. Similarly the parent of the process
+	 * identifier must exist, you cannot specify orphan nodes with no parent.
+	 * 
+	 * @param workflowObject
+	 *            an object within the work-flow model which has received the
+	 *            data stream and caused this node to be created. This may or
+	 *            may not be a top level work-flow entity such as a processor or
+	 *            data-flow. It may be empty in which case null can be used but
+	 *            this is not recommended (there's almost always something you
+	 *            can put here, in general the code to create a new node is
+	 *            contained within something that's just received a data stream
+	 *            so a default approach would be to use the 'this'
+	 *            meta-variable)
+	 * @param owningProcess
+	 *            the :-separated process identifier as a string which has been
+	 *            assigned to data moving through the workflow object. The list
+	 *            of IDs must contain the new identifier as the last element.
+	 */
+	public void registerNode(Object workflowObject,
+			String owningProcessIdentifier) {
+		registerNode(workflowObject, owningProcessIdentifier.split(":"), null);
+	}
+
+	/**
+	 * Register a new node with this monitor. New nodes can only be registered
+	 * when a new process identifier is allocated to data corresponding to entry
+	 * to a boundary of control in the data-flow. For cases where extensions
+	 * such as dispatch layers wish to augment existing state the plug-in point
+	 * is responsible for the aggregation of appropriate properties.
+	 * <p>
+	 * The process identifier must not already exist within the state tree, if
+	 * it does it will be ignored. Similarly the parent of the process
+	 * identifier must exist, you cannot specify orphan nodes with no parent.
+	 * 
+	 * @param workflowObject
+	 *            an object within the work-flow model which has received the
+	 *            data stream and caused this node to be created. This may or
+	 *            may not be a top level work-flow entity such as a processor or
+	 *            data-flow. It may be empty in which case null can be used but
+	 *            this is not recommended (there's almost always something you
+	 *            can put here, in general the code to create a new node is
+	 *            contained within something that's just received a data stream
+	 *            so a default approach would be to use the 'this'
+	 *            meta-variable)
+	 * @param owningProcess
+	 *            the :-separated process identifier as a string which has been
+	 *            assigned to data moving through the workflow object. The list
+	 *            of IDs must contain the new identifier as the last element. *
+	 * @param properties
+	 *            the set of monitor-able, and potentially steer-able,
+	 *            properties which can be monitored from this node. Properties
+	 *            may cache, may become invalid and may make no guarantee about
+	 *            timely updates.
+	 */
+	public void registerNode(Object workflowObject,
+			String owningProcessIdentifier,
+			Set<MonitorableProperty<?>> properties) {
+		registerNode(workflowObject, owningProcessIdentifier.split(":"),
+				properties);
+	}
+
+	/**
+	 * Register a new node with this monitor. New nodes can only be registered
+	 * when a new process identifier is allocated to data corresponding to entry
+	 * to a boundary of control in the data-flow. For cases where extensions
+	 * such as dispatch layers wish to augment existing state the plug-in point
+	 * is responsible for the aggregation of appropriate properties.
+	 * <p>
+	 * The process identifier must not already exist within the state tree, if
+	 * it does it will be ignored. Similarly the parent of the process
+	 * identifier must exist, you cannot specify orphan nodes with no parent.
+	 * 
+	 * @param workflowObject
+	 *            an object within the work-flow model which has received the
+	 *            data stream and caused this node to be created. This may or
+	 *            may not be a top level work-flow entity such as a processor or
+	 *            data-flow. It may be empty in which case null can be used but
+	 *            this is not recommended (there's almost always something you
+	 *            can put here, in general the code to create a new node is
+	 *            contained within something that's just received a data stream
+	 *            so a default approach would be to use the 'this'
+	 *            meta-variable)
+	 * @param owningProcess
+	 *            the process identifier which has been assigned to data moving
+	 *            through the work-flow object. The list of IDs must contain the
+	 *            new identifier as the last element.
+	 */
+	public void registerNode(Object workflowObject, String[] owningProcess) {
+		registerNode(workflowObject, owningProcess, null);
+	}
+
+	/**
+	 * Register a new node with this monitor. New nodes can only be registered
+	 * when a new process identifier is allocated to data corresponding to entry
+	 * to a boundary of control in the data-flow. For cases where extensions
+	 * such as dispatch layers wish to augment existing state the plug-in point
+	 * is responsible for the aggregation of appropriate properties.
+	 * <p>
+	 * The process identifier must not already exist within the state tree, if
+	 * it does it will be ignored. Similarly the parent of the process
+	 * identifier must exist, you cannot specify orphan nodes with no parent.
+	 * 
+	 * @param workflowObject
+	 *            an object within the work-flow model which has received the
+	 *            data stream and caused this node to be created. This may or
+	 *            may not be a top level work-flow entity such as a processor or
+	 *            data-flow. It may be empty in which case null can be used but
+	 *            this is not recommended (there's almost always something you
+	 *            can put here, in general the code to create a new node is
+	 *            contained within something that's just received a data stream
+	 *            so a default approach would be to use the 'this'
+	 *            meta-variable)
+	 * @param owningProcess
+	 *            the process identifier which has been assigned to data moving
+	 *            through the work-flow object. The list of IDs must contain the
+	 *            new identifier as the last element.
+	 * @param properties
+	 *            the set of monitor-able, and potentially steer-able,
+	 *            properties which can be monitored from this node. Properties
+	 *            may cache, may become invalid and may make no guarantee about
+	 *            timely updates.
+	 */
+	public void registerNode(Object workflowObject, String[] owningProcess,
+			Set<MonitorableProperty<?>> properties) {
+		if (properties == null)
+			properties = new HashSet<>();
+		multiCaster.notify(new RegisterNodeMessage(workflowObject,
+				owningProcess, properties));
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void removeObserver(Observer<MonitorMessage> observer) {
+		multiCaster.removeObserver(observer);
+	}
+
+	/**
+	 * Message indicating that {@link #getNewProperties() new properties} have
+	 * been added to a node identified by given {@link #getOwningProcess()
+	 * owning process}.
+	 * 
+	 */
+	public class AddPropertiesMessage extends MonitorMessage {
+		private final Set<MonitorableProperty<?>> newProperties;
+
+		public AddPropertiesMessage(String[] owningProcess,
+				Set<MonitorableProperty<?>> newProperties) {
+			super(owningProcess);
+			this.newProperties = newProperties;
+		}
+
+		public Set<MonitorableProperty<?>> getNewProperties() {
+			return newProperties;
+		}
+	}
+
+	/**
+	 * Message indicating that the node of the given {@link #getOwningProcess()
+	 * owning process} is to be deregistered.
+	 * 
+	 */
+	public class DeregisterNodeMessage extends MonitorMessage {
+		public DeregisterNodeMessage(String[] owningProcess) {
+			super(owningProcess);
+		}
+	}
+
+	/**
+	 * Common abstract superclass for all monitor messages. Identifies the
+	 * {@link #getOwningProcess() owning process}.
+	 * 
+	 */
+	public abstract class MonitorMessage {
+		private final String[] owningProcess;
+
+		public MonitorMessage(String[] owningProcess) {
+			this.owningProcess = owningProcess;
+		}
+
+		public String[] getOwningProcess() {
+			return owningProcess;
+		}
+	}
+
+	/**
+	 * Message indicating that the node of the given {@link #getOwningProcess()
+	 * owning process} is to be registered. The node might have
+	 * {@link #getProperties() a set of monitorable properties} and a
+	 * {@link #getWorkflowObject workflow object}.
+	 */
+	public class RegisterNodeMessage extends MonitorMessage {
+		private final Set<MonitorableProperty<?>> properties;
+		private final Object workflowObject;
+
+		public RegisterNodeMessage(Object workflowObject,
+				String[] owningProcess, Set<MonitorableProperty<?>> properties) {
+			super(owningProcess);
+			this.workflowObject = workflowObject;
+			this.properties = properties;
+		}
+
+		public Set<MonitorableProperty<?>> getProperties() {
+			return properties;
+		}
+
+		public Object getWorkflowObject() {
+			return workflowObject;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/MonitorNode.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/MonitorNode.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/MonitorNode.java
new file mode 100644
index 0000000..9979db8
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/MonitorNode.java
@@ -0,0 +1,75 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.monitor;
+
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * A single node in the Monitor tree, containing an optional arbitrary workflow
+ * object and a set of properties which may or may not be mutable. For tree
+ * traversal operations the top level monitor tree must be used, instances of
+ * this class are not aware of the surrounding tree structure.
+ * 
+ * @author Tom Oinn
+ */
+public interface MonitorNode {
+	/**
+	 * Each monitor node can reference zero or one workflow object. This is the
+	 * object which is providing any properties the node exposes, so is likely
+	 * to be a workflow or processor but could be anything.
+	 * 
+	 * @return the workflow object providing this node's properties, or null if
+	 *         there is no directly corresponding workflow object. Note that
+	 *         this workflow object can be anything, and may not be a top level
+	 *         workflow object at all.
+	 */
+	Object getWorkflowObject();
+
+	/**
+	 * Each monitor node has an identity corresponding to the identifier stack
+	 * of the data flowing through the workflow object that created it. This
+	 * string array also defines its position in the monitor tree.
+	 */
+	String[] getOwningProcess();
+
+	/**
+	 * Each monitor node exposes a set of properties, which may or may not be
+	 * mutable
+	 */
+	Set<? extends MonitorableProperty<?>> getProperties();
+
+	/**
+	 * Each node has a creation date
+	 */
+	Date getCreationDate();
+
+	/**
+	 * Properties can be added to the monitor node after creation if required,
+	 * although this should be used only when necessary to avoid race conditions
+	 */
+	void addMonitorableProperty(MonitorableProperty<?> newProperty);
+
+	/**
+	 * Nodes can persist in the tree after they have expired, in which case this
+	 * will return true.
+	 */
+	boolean hasExpired();
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/MonitorableProperty.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/MonitorableProperty.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/MonitorableProperty.java
new file mode 100644
index 0000000..6e83652
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/MonitorableProperty.java
@@ -0,0 +1,54 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.monitor;
+
+import java.util.Date;
+
+/**
+ * A single readable property contained by a Monitorable. This is used to
+ * express properties that are dynamic with respect to workflow invocation as
+ * opposed to static properties defined by the workflow model. A typical example
+ * of this might be dispatch stack queue size or number of jobs completed. All
+ * properties are defined relative to a particular owning process identifier,
+ * this is the same mechanism as used in the workflow model to isolate different
+ * data streams.
+ * 
+ * @author Tom Oinn
+ */
+public interface MonitorableProperty<T> {
+	/**
+	 * Return the value of this property
+	 */
+	T getValue() throws NoSuchPropertyException;
+
+	/**
+	 * Return the name of this property, names are heirarchical in nature and
+	 * are defined as an array of String objects. This is to allow e.g. dispatch
+	 * layers to expose a set of related properties under the same root name.
+	 */
+	String[] getName();
+
+	/**
+	 * Get the last update date for this property, if the property is immutable
+	 * then this should be set to the date at which the implementation is
+	 * created.
+	 */
+	Date getLastModified();
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/NoSuchPropertyException.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/NoSuchPropertyException.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/NoSuchPropertyException.java
new file mode 100644
index 0000000..aeb75fc
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/NoSuchPropertyException.java
@@ -0,0 +1,49 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.monitor;
+
+/**
+ * Thrown when an attempt is made to access a monitorable property which is no
+ * longer current. This is quite a common event as the properties can change
+ * extremely quickly whereas the logic accessing them is expected not to.
+ * Consumers of state data must cope with this disparity by handling this
+ * exception where it is thrown.
+ * 
+ * @author Tom Oinn
+ */
+public class NoSuchPropertyException extends Exception {
+	private static final long serialVersionUID = 6320919057517500603L;
+
+	public NoSuchPropertyException() {
+		super();
+	}
+
+	public NoSuchPropertyException(String arg0, Throwable arg1) {
+		super(arg0, arg1);
+	}
+
+	public NoSuchPropertyException(String arg0) {
+		super(arg0);
+	}
+
+	public NoSuchPropertyException(Throwable arg0) {
+		super(arg0);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/SteerableProperty.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/SteerableProperty.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/SteerableProperty.java
new file mode 100644
index 0000000..95448fa
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/SteerableProperty.java
@@ -0,0 +1,36 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.monitor;
+
+/**
+ * Some monitorable properties are mutable and can be written to by steering
+ * agents or other clients.
+ * 
+ * @author Tom Oinn
+ */
+public interface SteerableProperty<T> extends MonitorableProperty<T> {
+	/**
+	 * Set the property value
+	 * 
+	 * @param newValue
+	 * @throws NoSuchPropertyException
+	 */
+	void setProperty(T newValue) throws NoSuchPropertyException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/package.html
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/package.html b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/package.html
new file mode 100644
index 0000000..17ee572
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/monitor/package.html
@@ -0,0 +1,36 @@
+<body>
+Defines the API for the monitoring and steering system. As data flows
+through a workflow it passes through a succession of bounds of control.
+Each of these boundaries corresponds to a workflow, a nested process or
+some other contained entity where a new owning process identifier is
+pushed onto the process identifier stack for that data item. This
+modification to the owning process identifier implicitly creates a tree
+structure where the parent of a particular identifier can be obtained by
+popping the last component off its identifier stack (in general this
+means splitting into a list by the ':' character and removing the last
+item).
+<p>Any entity issuing a new identifier to data in this way must
+implement the Monitorable interface and should register itself with the
+Monitor before or at the point of assigning this new identifier. Some
+cases may register child items rather than delegating to the children
+themselves, for example a workflow definition may register all its
+processors as children and deregister on workflow completion rather than
+the process happening for each processor but however it is accomplished
+the result is the creation within the Monitor of a tree where nodes
+contain references to Monitorable objects within the workflow
+definition.
+<p>The Monitorable interface defines a simple contract - once
+registered the implementing class can return a list of
+MonitorableProperty instances defining the exposed dynamic state at this
+node in the context of a given process identifier. Any of these
+properties may be mutable in which case they will extend
+SteerableProperty, a sub-interface of MonitorableProperty which allows
+for the mutation of the property.
+<p>By design the Monitor is rather powerful - it has the ability to
+modify steerable properties in any running workflow. It is obviously
+desirable to restrict this, passing any given monitoring or steering
+agent a restricted subset of the monitor tree rooted at a specific
+process identifier and preventing direct access to the Monitor class.
+The Monitor interface defines methods to expose subsets of the
+monitorable state for this reason.
+</body>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/AbstractProvenanceItem.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/AbstractProvenanceItem.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/AbstractProvenanceItem.java
new file mode 100644
index 0000000..1d2e390
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/AbstractProvenanceItem.java
@@ -0,0 +1,96 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.item;
+
+import org.apache.taverna.provenance.vocabulary.SharedVocabulary;
+
+public abstract class AbstractProvenanceItem implements ProvenanceItem {
+	@Override
+	public abstract SharedVocabulary getEventType();
+
+	private String identifier, parentId, processId, workflowId;
+
+	@Override
+	public final String getIdentifier() {
+		return identifier;
+	}
+
+	@Override
+	public int hashCode() {
+		return 31 + (identifier == null ? 0 : identifier.hashCode());
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		AbstractProvenanceItem other = (AbstractProvenanceItem) obj;
+		if (identifier == null) {
+			if (other.identifier != null)
+				return false;
+		} else if (!identifier.equals(other.identifier))
+			return false;
+		return true;
+	}
+
+	@Override
+	public final void setIdentifier(String identifier) {
+		this.identifier = identifier;
+	}
+
+	@Override
+	public final String getParentId() {
+		return parentId;
+	}
+
+	@Override
+	public final void setParentId(String parentId) {
+		this.parentId = parentId;
+	}
+
+	@Override
+	public final String getProcessId() {
+		return processId;
+	}
+
+	@Override
+	public final void setProcessId(String processId) {
+		this.processId = processId;
+	}
+
+	@Override
+	public final String getWorkflowId() {
+		return workflowId;
+	}
+
+	@Override
+	public final void setWorkflowId(String workflowId) {
+		this.workflowId = workflowId;
+	}
+	
+	@Override
+	public String toString() {
+		return getEventType() + " id:" + getIdentifier() + " parent:" + getParentId();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ActivityProvenanceItem.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ActivityProvenanceItem.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ActivityProvenanceItem.java
new file mode 100644
index 0000000..4167bdc
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ActivityProvenanceItem.java
@@ -0,0 +1,61 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.item;
+
+import org.apache.taverna.provenance.vocabulary.SharedVocabulary;
+import org.apache.taverna.workflowmodel.processor.activity.Activity;
+
+/**
+ * Contains details for an enacted Activity. Parent is a
+ * {@link ProcessorProvenanceItem}. Children are {@link IterationProvenanceItem}
+ * s. There could be multiple {@link ActivityProvenanceItem}s for each
+ * {@link ProcessorProvenanceItem}
+ * 
+ * @author Ian Dunlop
+ * @author Stuart Owen
+ * @author Paolo Missier
+ */
+public class ActivityProvenanceItem extends AbstractProvenanceItem implements ProvenanceItem  {
+	private Activity<?> activity;
+	private IterationProvenanceItem iterationProvenanceItem;
+	
+	public void setIterationProvenanceItem(
+			IterationProvenanceItem iterationProvenanceItem) {
+		this.iterationProvenanceItem = iterationProvenanceItem;
+	}
+
+	public IterationProvenanceItem getIterationProvenanceItem() {
+		return iterationProvenanceItem;
+	}
+
+	@Override
+	public SharedVocabulary getEventType() {
+		return SharedVocabulary.ACTIVITY_EVENT_TYPE;
+	}
+
+	public Activity<?> getActivity() {
+		return activity;
+	}
+
+	public void setActivity(Activity<?> activity) {
+		this.activity = activity;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/DataProvenanceItem.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/DataProvenanceItem.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/DataProvenanceItem.java
new file mode 100644
index 0000000..f3b366c
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/DataProvenanceItem.java
@@ -0,0 +1,62 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.item;
+
+import java.util.Map;
+
+import org.apache.taverna.reference.ReferenceService;
+import org.apache.taverna.reference.T2Reference;
+
+/**
+ * Contains references to data which a workflow has used or created. Parent is
+ * an {@link IterationProvenanceItem}
+ * 
+ * @author Ian Dunlop
+ * @auhor Stuart Owen
+ * @author Paolo Missier
+ */
+public abstract class DataProvenanceItem extends AbstractProvenanceItem {
+	/** A map of port name to data reference */
+	private Map<String, T2Reference> dataMap;
+	private ReferenceService referenceService;
+
+	/**
+	 * Is this {@link ProvenanceItem} for input or output data
+	 * 
+	 * @return
+	 */
+	protected abstract boolean isInput();
+
+	public Map<String, T2Reference> getDataMap() {
+		return dataMap;
+	}
+
+	public void setDataMap(Map<String, T2Reference> dataMap) {
+		this.dataMap = dataMap;
+	}
+	
+	public void setReferenceService(ReferenceService referenceService) {
+		this.referenceService = referenceService;
+	}
+
+	public ReferenceService getReferenceService() {
+		return referenceService;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/DataflowRunComplete.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/DataflowRunComplete.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/DataflowRunComplete.java
new file mode 100644
index 0000000..4d3eb2f
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/DataflowRunComplete.java
@@ -0,0 +1,60 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.item;
+
+import java.sql.Timestamp;
+
+import org.apache.taverna.facade.WorkflowInstanceFacade.State;
+import org.apache.taverna.provenance.vocabulary.SharedVocabulary;
+
+/**
+ * Informs the {@link ProvenanceConnector} that a workflow has been run to
+ * completion. If a {@link ProvenanceConnector} receives this event then it
+ * means that there are no further events to come and that the workflow has been
+ * enacted to completion
+ * 
+ * @author Ian Dunlop
+ */
+public class DataflowRunComplete extends AbstractProvenanceItem {
+	private SharedVocabulary eventType = SharedVocabulary.END_WORKFLOW_EVENT_TYPE;
+	private Timestamp invocationEnded;
+	private State state;
+
+	public Timestamp getInvocationEnded() {
+		return invocationEnded;
+	}
+
+	@Override
+	public SharedVocabulary getEventType() {
+		return eventType;
+	}
+
+	public void setInvocationEnded(Timestamp invocationEnded) {
+		this.invocationEnded = invocationEnded;
+	}
+
+	public void setState(State state) {
+		this.state = state;
+	}
+
+	public State getState() {
+		return state;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ErrorProvenanceItem.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ErrorProvenanceItem.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ErrorProvenanceItem.java
new file mode 100644
index 0000000..7f1f8a1
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ErrorProvenanceItem.java
@@ -0,0 +1,70 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.item;
+
+import org.apache.taverna.provenance.vocabulary.SharedVocabulary;
+
+/**
+ * When an error is received in the dispatch stack, one of these is created and
+ * sent across to the {@link ProvenanceConnector}. Parent is an
+ * {@link IterationProvenanceItem}
+ * 
+ * @author Ian Dunlop
+ * @author Stuart Owen
+ * @author Paolo Missier
+ */
+public class ErrorProvenanceItem extends AbstractProvenanceItem {
+	private Throwable cause;
+	private String message;
+	private String errorType;
+	private SharedVocabulary eventType = SharedVocabulary.ERROR_EVENT_TYPE;
+
+	public ErrorProvenanceItem() {
+	}
+
+	@Override
+	public SharedVocabulary getEventType() {
+		return eventType;
+	}
+
+	public Throwable getCause() {
+		return cause;
+	}
+
+	public void setCause(Throwable cause) {
+		this.cause = cause;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+
+	public void setMessage(String message) {
+		this.message = message;
+	}
+
+	public String getErrorType() {
+		return errorType;
+	}
+
+	public void setErrorType(String errorType) {
+		this.errorType = errorType;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/InputDataProvenanceItem.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/InputDataProvenanceItem.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/InputDataProvenanceItem.java
new file mode 100644
index 0000000..1c03726
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/InputDataProvenanceItem.java
@@ -0,0 +1,48 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.item;
+
+import org.apache.taverna.provenance.vocabulary.SharedVocabulary;
+
+/**
+ * Contains details of port names and the input data they receive. Parent is an
+ * {@link IterationProvenanceItem}
+ * 
+ * @author Paolo Missier
+ * @author Stuart Owen
+ * @author Ian Dunlop
+ */
+public class InputDataProvenanceItem extends DataProvenanceItem {
+	private SharedVocabulary eventType = SharedVocabulary.INPUTDATA_EVENT_TYPE;
+
+	/**
+	 * Used when generating the xml version by the {@link DataProvenanceItem}.
+	 * Identifies this {@link DataProvenanceItem} as containing input
+	 */
+	@Override
+	protected boolean isInput() {
+		return true;
+	}
+
+	@Override
+	public SharedVocabulary getEventType() {
+		return eventType;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/InvocationStartedProvenanceItem.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/InvocationStartedProvenanceItem.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/InvocationStartedProvenanceItem.java
new file mode 100644
index 0000000..9b5add4
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/InvocationStartedProvenanceItem.java
@@ -0,0 +1,60 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.item;
+
+import java.sql.Date;
+
+import org.apache.taverna.provenance.vocabulary.SharedVocabulary;
+import org.apache.taverna.workflowmodel.processor.activity.Activity;
+
+public class InvocationStartedProvenanceItem extends AbstractProvenanceItem {
+	private Activity<?> activity;
+	private String invocationProcessId;
+	private Date invocationStarted;
+
+	public final Date getInvocationStarted() {
+		return invocationStarted;
+	}
+
+	@Override
+	public SharedVocabulary getEventType() {
+		return SharedVocabulary.INVOCATION_STARTED_EVENT_TYPE;
+	}
+
+	public void setActivity(Activity<?> activity) {
+		this.activity = activity;
+	}
+
+	public Activity<?> getActivity() {
+		return activity;
+	}
+
+	public void setInvocationProcessId(String invocationProcessId) {
+		this.invocationProcessId = invocationProcessId;
+	}
+
+	public String getInvocationProcessId() {
+		return invocationProcessId;
+	}
+
+	public void setInvocationStarted(Date invocationStarted) {
+		this.invocationStarted = invocationStarted;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/IterationProvenanceItem.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/IterationProvenanceItem.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/IterationProvenanceItem.java
new file mode 100644
index 0000000..b411e6e
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/IterationProvenanceItem.java
@@ -0,0 +1,107 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.item;
+
+import java.sql.Timestamp;
+
+import org.apache.taverna.provenance.vocabulary.SharedVocabulary;
+
+/**
+ * One of these is created for each iteration inside an enacted activity.
+ * Contains both the input and output data and port names contained inside
+ * {@link DataProvenanceItem}s. The actual iteration number is contained inside
+ * an int array eg [1]
+ * 
+ * @author Ian Dunlop
+ * @author Paolo Missier
+ * @author Stuart Owen
+ */
+public class IterationProvenanceItem extends AbstractProvenanceItem {
+	private Timestamp enactmentEnded;
+	private Timestamp enactmentStarted;
+	private ErrorProvenanceItem errorItem;
+	private final SharedVocabulary eventType = SharedVocabulary.ITERATION_EVENT_TYPE;
+	private InputDataProvenanceItem inputDataItem;
+	private int[] iteration;
+	private OutputDataProvenanceItem outputDataItem;
+	private IterationProvenanceItem parentIterationItem = null;
+
+	public IterationProvenanceItem getParentIterationItem() {
+		return parentIterationItem;
+	}
+
+	public Timestamp getEnactmentEnded() {
+		return enactmentEnded;
+	}
+
+	public Timestamp getEnactmentStarted() {
+		return enactmentStarted;
+	}
+
+	public ErrorProvenanceItem getErrorItem() {
+		return errorItem;
+	}
+
+	@Override
+	public SharedVocabulary getEventType() {
+		return eventType;
+	}
+
+	public InputDataProvenanceItem getInputDataItem() {
+		return inputDataItem;
+	}
+
+	public int[] getIteration() {
+		return iteration;
+	}
+
+	public OutputDataProvenanceItem getOutputDataItem() {
+		return outputDataItem;
+	}
+
+	public void setEnactmentEnded(Timestamp enactmentEnded) {
+		this.enactmentEnded = enactmentEnded;
+	}
+
+	public void setEnactmentStarted(Timestamp enactmentStarted) {
+		this.enactmentStarted = enactmentStarted;
+	}
+
+	public void setErrorItem(ErrorProvenanceItem errorItem) {
+		this.errorItem = errorItem;
+	}
+
+	public void setInputDataItem(InputDataProvenanceItem inputDataItem) {
+		this.inputDataItem = inputDataItem;
+	}
+
+	public void setIteration(int[] iteration) {
+		this.iteration = iteration;
+	}
+
+	public void setOutputDataItem(OutputDataProvenanceItem outputDataItem) {
+		this.outputDataItem = outputDataItem;
+	}
+
+	public void setParentIterationItem(
+			IterationProvenanceItem parentIterationItem) {
+		this.parentIterationItem = parentIterationItem;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/OutputDataProvenanceItem.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/OutputDataProvenanceItem.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/OutputDataProvenanceItem.java
new file mode 100644
index 0000000..223947a
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/OutputDataProvenanceItem.java
@@ -0,0 +1,48 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.item;
+
+import org.apache.taverna.provenance.vocabulary.SharedVocabulary;
+
+/**
+ * Contains details of port names and the output data they receive. Parent is an
+ * {@link IterationProvenanceItem}
+ * 
+ * @author Paolo Missier
+ * @author Stuart Owen
+ * @author Ian Dunlop
+ */
+public class OutputDataProvenanceItem extends DataProvenanceItem {
+	private SharedVocabulary eventType = SharedVocabulary.OUTPUTDATA_EVENT_TYPE;
+
+	/**
+	 * Used when generating the xml version by the {@link DataProvenanceItem}.
+	 * Identifies this {@link DataProvenanceItem} as containing output
+	 */
+	@Override
+	protected boolean isInput() {
+		return false;
+	}
+
+	@Override
+	public SharedVocabulary getEventType() {
+		return eventType;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ProcessProvenanceItem.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ProcessProvenanceItem.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ProcessProvenanceItem.java
new file mode 100644
index 0000000..8789f08
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ProcessProvenanceItem.java
@@ -0,0 +1,88 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.item;
+
+import org.apache.taverna.provenance.vocabulary.SharedVocabulary;
+
+/**
+ * Each time a job is received by the dispatch stack one of these will be
+ * created. It has a {@link ProcessorProvenanceItem} as its child. Its parent is
+ * a {@link WorkflowProvenanceItem} which in turn knows the unique id of the
+ * workflow the provenance is being stored for. NOTE: May be superfluous since
+ * it essentially mimics the behaviour of its child item but may be more hastle
+ * than it is worth to remove it
+ * 
+ * @author Stuart owen
+ * @author Paolo Missier
+ * @author Ian Dunlop
+ */
+public class ProcessProvenanceItem extends AbstractProvenanceItem {
+	private String owningProcess;
+	private ProcessorProvenanceItem processorProvenanceItem;
+	private String facadeID;
+	private String dataflowID;
+	private SharedVocabulary eventType = SharedVocabulary.PROCESS_EVENT_TYPE;
+
+	/**
+	 * As {@link WorkflowInstanceFacade}s are created for a Processor the
+	 * details are appended to the owning process identifier. This is in the
+	 * form facadeX:dataflowY:ProcessorZ etc. This method returns the facadeX
+	 * part.
+	 * 
+	 * @return
+	 */
+	public String getFacadeID() {
+		return facadeID;
+	}
+
+	public void setProcessorProvenanceItem(
+			ProcessorProvenanceItem processorProvenanceItem) {
+		this.processorProvenanceItem = processorProvenanceItem;
+	}
+
+	public ProcessorProvenanceItem getProcessorProvenanceItem() {
+		return processorProvenanceItem;
+	}
+
+	@Override
+	public SharedVocabulary getEventType() {
+		return eventType;
+	}
+
+	public String getOwningProcess() {
+		return owningProcess;
+	}
+
+	public void setOwningProcess(String owningProcess) {
+		this.owningProcess = owningProcess;
+	}
+
+	public void setFacadeID(String facadeID) {
+		this.facadeID = facadeID;
+	}
+
+	public void setDataflowID(String dataflowID) {
+		this.dataflowID = dataflowID;
+	}
+
+	public String getDataflowID() {
+		return dataflowID;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ProcessorProvenanceItem.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ProcessorProvenanceItem.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ProcessorProvenanceItem.java
new file mode 100644
index 0000000..7c3239c
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ProcessorProvenanceItem.java
@@ -0,0 +1,56 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.item;
+
+import org.apache.taverna.provenance.vocabulary.SharedVocabulary;
+
+/**
+ * Each Processor inside a workflow will have one of these for each provenance
+ * run. Its parent is a {@link ProcessProvenanceItem} and child is an
+ * {@link ActivityProvenanceItem}. In theory there could be more than one
+ * {@link ActivityProvenanceItem} per processor to cope with failover etc
+ * 
+ * @author Ian Dunlop
+ * @author Stuart Owen
+ * @author Paolo Missier
+ */
+public class ProcessorProvenanceItem extends AbstractProvenanceItem {
+	private ActivityProvenanceItem activityProvenanceItem;
+	private String identifier;
+	private SharedVocabulary eventType = SharedVocabulary.PROCESSOR_EVENT_TYPE;
+
+	public void setActivityProvenanceItem(
+			ActivityProvenanceItem activityProvenanceItem) {
+		this.activityProvenanceItem = activityProvenanceItem;
+	}
+
+	public ActivityProvenanceItem getActivityProvenanceItem() {
+		return activityProvenanceItem;
+	}
+
+	public String getProcessorID() {
+		return identifier;
+	}
+
+	@Override
+	public SharedVocabulary getEventType() {
+		return eventType;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ProvenanceItem.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ProvenanceItem.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ProvenanceItem.java
new file mode 100644
index 0000000..2023c65
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/ProvenanceItem.java
@@ -0,0 +1,102 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.item;
+
+import org.apache.taverna.provenance.vocabulary.SharedVocabulary;
+
+/**
+ * Used to store some enactment information during a workflow run
+ * 
+ * @see AbstractProvenanceItem
+ * @author Ian Dunlop
+ */
+public interface ProvenanceItem {
+	/**
+	 * What type of information does the item contain. The
+	 * {@link SharedVocabulary} can be used to identify it
+	 * 
+	 * @return
+	 */
+	SharedVocabulary getEventType();
+
+	/**
+	 * The unique identifier for this item
+	 * 
+	 * @return
+	 */
+	String getIdentifier();
+
+	/**
+	 * A unique id for this event. Any children would use this as their parentId
+	 * 
+	 * @param identifier
+	 */
+	void setIdentifier(String identifier);
+
+	/**
+	 * The workflow model id that is supplied during enactment eg
+	 * facade0:dataflow2:processor1
+	 * 
+	 * @param processId
+	 */
+	void setProcessId(String processId);
+
+	/**
+	 * Get the enactor supplie identifier
+	 * 
+	 * @return
+	 */
+	String getProcessId();
+
+	/**
+	 * The parent of this provenance Item. The model is
+	 * WorkflowProvenanceItem>ProcessProvenanceItem
+	 * >ProcessorProvenanceItem>ActivityProvenanceITem
+	 * >IterationProvenanceItem>DataProvenanceItem
+	 * 
+	 * Additionally there is a WorkflowDataProvenanceItem that is sent when the
+	 * facade receives a completion event and a ErrorProvenanceItem when things
+	 * go wrong
+	 * 
+	 * @param parentId
+	 */
+	void setParentId(String parentId);
+
+	/**
+	 * Who is the parent of this item?
+	 * 
+	 * @return
+	 */
+	String getParentId();
+
+	/**
+	 * The uuid that belongs to the actual dataflow
+	 * 
+	 * @param workflowId
+	 */
+	void setWorkflowId(String workflowId);
+
+	/**
+	 * The uuid that belongs to the actual dataflow
+	 * 
+	 * @return a string representation of a uuid
+	 */
+	String getWorkflowId();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/WorkflowDataProvenanceItem.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/WorkflowDataProvenanceItem.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/WorkflowDataProvenanceItem.java
new file mode 100644
index 0000000..89a7a52
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/WorkflowDataProvenanceItem.java
@@ -0,0 +1,100 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.item;
+
+import org.apache.taverna.provenance.vocabulary.SharedVocabulary;
+import org.apache.taverna.reference.ReferenceService;
+import org.apache.taverna.reference.T2Reference;
+
+/**
+ * When the {@link WorkflowInstanceFacade} for a processor receives a data token
+ * one of these is created. This is especially important for data which flows
+ * straight through a facade without going into the dispatch stack (a rare event
+ * but it can happen)
+ * 
+ * @author Ian Dunlop
+ */
+public class WorkflowDataProvenanceItem extends AbstractProvenanceItem {
+	private ReferenceService referenceService;
+	/** The port name that the data is for */
+	private String portName;
+	/** A reference to the data token received in the facade */
+	private T2Reference data;
+	private SharedVocabulary eventType = SharedVocabulary.WORKFLOW_DATA_EVENT_TYPE;
+	private boolean isFinal;
+	private int[] index;
+	private boolean isInputPort;
+
+	public boolean isInputPort() {
+		return isInputPort;
+	}
+
+	public void setInputPort(boolean isInputPort) {
+		this.isInputPort = isInputPort;
+	}
+
+	public WorkflowDataProvenanceItem() {
+	}
+
+	@Override
+	public SharedVocabulary getEventType() {
+		return eventType;
+	}
+
+	public void setPortName(String portName) {
+		this.portName = portName;
+	}
+
+	public String getPortName() {
+		return portName;
+	}
+
+	public void setData(T2Reference data) {
+		this.data = data;
+	}
+
+	public T2Reference getData() {
+		return data;
+	}
+
+	public void setReferenceService(ReferenceService referenceService) {
+		this.referenceService = referenceService;
+	}
+
+	public ReferenceService getReferenceService() {
+		return referenceService;
+	}
+
+	public void setIndex(int[] index) {
+		this.index = index;
+	}
+
+	public int[] getIndex() {
+		return index;
+	}
+
+	public void setFinal(boolean isFinal) {
+		this.isFinal = isFinal;
+	}
+
+	public boolean isFinal() {
+		return isFinal;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/WorkflowProvenanceItem.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/WorkflowProvenanceItem.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/WorkflowProvenanceItem.java
new file mode 100644
index 0000000..939988c
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/item/WorkflowProvenanceItem.java
@@ -0,0 +1,100 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.item;
+
+import java.sql.Timestamp;
+
+import org.apache.taverna.facade.WorkflowInstanceFacade;
+import org.apache.taverna.provenance.vocabulary.SharedVocabulary;
+import org.apache.taverna.workflowmodel.Dataflow;
+
+/**
+ * The first {@link ProvenanceItem} that the {@link ProvenanceConnector} will
+ * receive for a workflow run. Contains the {@link Dataflow} itself as well as
+ * the process id for the {@link WorkflowInstanceFacade} (facadeX:dataflowY).
+ * Its child is a {@link ProcessProvenanceItem} and parent is the UUID of the
+ * {@link Dataflow} itself
+ * 
+ * @author Ian Dunlop
+ * @author Paolo Missier
+ * @author Stuart Owen
+ */
+public class WorkflowProvenanceItem extends AbstractProvenanceItem {
+	private Dataflow dataflow;
+	private SharedVocabulary eventType = SharedVocabulary.WORKFLOW_EVENT_TYPE;
+	private int[] index;
+	private boolean isFinal;
+
+	private Timestamp invocationStarted;
+
+	public Timestamp getInvocationStarted() {
+		return invocationStarted;
+	}
+
+	public WorkflowProvenanceItem() {
+	}
+
+	public Dataflow getDataflow() {
+		return dataflow;
+	}
+
+	public void setDataflow(Dataflow dataflow) {
+		this.dataflow = dataflow;
+	}
+
+	@Override
+	public SharedVocabulary getEventType() {
+		return eventType;
+	}
+
+	/**
+	 * @return the index
+	 */
+	public int[] getIndex() {
+		return index;
+	}
+
+	/**
+	 * @param index
+	 *            the index to set
+	 */
+	public void setIndex(int[] index) {
+		this.index = index;
+	}
+
+	/**
+	 * @return the isFinal
+	 */
+	public boolean isFinal() {
+		return isFinal;
+	}
+
+	/**
+	 * @param isFinal
+	 *            the isFinal to set
+	 */
+	public void setFinal(boolean isFinal) {
+		this.isFinal = isFinal;
+	}
+
+	public void setInvocationStarted(Timestamp invocationStarted) {
+		this.invocationStarted = invocationStarted;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/reporter/ProvenanceReporter.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/reporter/ProvenanceReporter.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/reporter/ProvenanceReporter.java
new file mode 100644
index 0000000..047b23c
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/reporter/ProvenanceReporter.java
@@ -0,0 +1,91 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.reporter;
+
+import java.util.List;
+
+import org.apache.taverna.invocation.InvocationContext;
+import org.apache.taverna.provenance.item.ProvenanceItem;
+import org.apache.taverna.provenance.item.WorkflowProvenanceItem;
+import org.apache.taverna.reference.ReferenceService;
+
+public interface ProvenanceReporter {
+	/**
+	 * Add a {@link ProvenanceItem} to the connector
+	 * 
+	 * @param provenanceItem
+	 * @param invocationContext
+	 */
+	void addProvenanceItem(ProvenanceItem provenanceItem);
+
+	// FIXME is this reference service really needed since we have the context?
+	/**
+	 * Tell the connector what {@link ReferenceService} it should use when
+	 * trying to dereference data items inside {@link ProvenanceItem}s
+	 * 
+	 * @param referenceService
+	 */
+	void setReferenceService(ReferenceService referenceService);
+
+	/**
+	 * Get the {@link ReferenceService} in use by this connector
+	 * 
+	 * @return
+	 */
+	ReferenceService getReferenceService();
+
+	/**
+	 * Get all the {@link ProvenanceItem}s that the connector currently knows
+	 * about
+	 * 
+	 * @return
+	 */
+	List<ProvenanceItem> getProvenanceCollection();
+
+	/**
+	 * Set the {@link InvocationContext} that this reporter should be using
+	 * 
+	 * @param invocationContext
+	 */
+	void setInvocationContext(InvocationContext invocationContext);
+
+	/**
+	 * Get the {@link InvocationContext} that this reporter should be using if
+	 * it needs to dereference any data
+	 * 
+	 * @return
+	 */
+	InvocationContext getInvocationContext();
+
+	/**
+	 * A unique identifier for this run of provenance, should correspond to the
+	 * initial {@link WorkflowProvenanceItem} idenifier that gets sent through
+	 * 
+	 * @param identifier
+	 */
+	void setSessionID(String sessionID);
+
+	/**
+	 * What is the unique identifier used by this connector
+	 * 
+	 * @return
+	 */
+	String getSessionID();
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/vocabulary/SharedVocabulary.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/vocabulary/SharedVocabulary.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/vocabulary/SharedVocabulary.java
new file mode 100644
index 0000000..c36a322
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/provenance/vocabulary/SharedVocabulary.java
@@ -0,0 +1,33 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.provenance.vocabulary;
+
+import org.apache.taverna.provenance.item.ProvenanceItem;
+
+/**
+ * Static strings which identify all the {@link ProvenanceItem}s and
+ * {@link ProvenanceEventType}s
+ * 
+ * @author Paolo Missier
+ * @author Ian Dunlop
+ */
+public enum SharedVocabulary {
+	DATAFLOW_EVENT_TYPE, PROCESS_EVENT_TYPE, PROVENANCE_EVENT_TYPE, ACTIVITY_EVENT_TYPE, DATA_EVENT_TYPE, ERROR_EVENT_TYPE, INMEMORY_EVENT_TYPE, INPUTDATA_EVENT_TYPE, ITERATION_EVENT_TYPE, OUTPUTDATA_EVENT_TYPE, PROCESSOR_EVENT_TYPE, WEBSERVICE_EVENT_TYPE, WORKFLOW_DATA_EVENT_TYPE, WORKFLOW_EVENT_TYPE, END_WORKFLOW_EVENT_TYPE, INVOCATION_STARTED_EVENT_TYPE;
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/utility/TreeModelAdapter.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/utility/TreeModelAdapter.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/utility/TreeModelAdapter.java
new file mode 100644
index 0000000..6b485f8
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/utility/TreeModelAdapter.java
@@ -0,0 +1,173 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.utility;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.swing.event.TreeModelEvent;
+import javax.swing.event.TreeModelListener;
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreePath;
+
+/**
+ * Wraps a typed tree model up in a standard tree model for use with JTree and
+ * friends.
+ * 
+ * @author Tom Oinn
+ */
+public final class TreeModelAdapter {
+	private static class TypedListenerPair<TT> {
+		TypedTreeModelListener<TT> typedListener;
+
+		TreeModelListener untypedListener;
+
+		TypedListenerPair(TypedTreeModelListener<TT> typedListener,
+				TreeModelListener untypedListener) {
+			this.typedListener = typedListener;
+			this.untypedListener = untypedListener;
+		}
+	}
+
+	private static Set<TypedListenerPair<Object>> mapping = new HashSet<>();
+
+	private static TreeModelAdapter instance = null;
+
+	private TreeModelAdapter() {
+		//
+	}
+
+	private synchronized static TreeModelAdapter getInstance() {
+		if (instance == null)
+			instance = new TreeModelAdapter();
+		return instance;
+	}
+
+	/**
+	 * Return an untyped TreeModel wrapper around the specified TypedTreeModel
+	 * 
+	 * @param <NodeType>
+	 *            the node type of the typed model being wrapped
+	 * @param typedModel
+	 *            typed model to wrap
+	 * @return a TreeModel acting as an untyped view of the typed tree model
+	 */
+	public static <NodeType extends Object> TreeModel untypedView(
+			TypedTreeModel<NodeType> typedModel) {
+		return getInstance().removeType(typedModel);
+	}
+
+	private <NodeType extends Object> TreeModel removeType(
+			final TypedTreeModel<NodeType> typedModel) {
+		return new TreeModel() {
+			@SuppressWarnings({ "rawtypes", "unchecked" })
+			@Override
+			public void addTreeModelListener(final TreeModelListener listener) {
+				TypedTreeModelListener<NodeType> typedListener = new TypedTreeModelListener<NodeType>() {
+					@Override
+					public void treeNodesChanged(TypedTreeModelEvent<NodeType> e) {
+						listener.treeNodesChanged(unwrapType(e));
+					}
+
+					@Override
+					public void treeNodesInserted(
+							TypedTreeModelEvent<NodeType> e) {
+						listener.treeNodesInserted(unwrapType(e));
+					}
+
+					@Override
+					public void treeNodesRemoved(TypedTreeModelEvent<NodeType> e) {
+						listener.treeNodesRemoved(unwrapType(e));
+					}
+
+					@Override
+					public void treeStructureChanged(
+							TypedTreeModelEvent<NodeType> e) {
+						listener.treeStructureChanged(unwrapType(e));
+					}
+
+					private TreeModelEvent unwrapType(
+							final TypedTreeModelEvent<NodeType> e) {
+						return new TreeModelEvent(e.getSource(),
+								e.getTreePath(), e.getChildIndices(),
+								e.getChildren());
+					}
+				};
+				synchronized (mapping) {
+					typedModel.addTreeModelListener(typedListener);
+					mapping.add(new TypedListenerPair(typedListener, listener));
+				}
+			}
+
+			@Override
+			@SuppressWarnings("unchecked")
+			public Object getChild(Object arg0, int arg1) {
+				return typedModel.getChild((NodeType) arg0, arg1);
+			}
+
+			@Override
+			@SuppressWarnings("unchecked")
+			public int getChildCount(Object arg0) {
+				return typedModel.getChildCount((NodeType) arg0);
+			}
+
+			@Override
+			@SuppressWarnings("unchecked")
+			public int getIndexOfChild(Object arg0, Object arg1) {
+				return typedModel.getIndexOfChild((NodeType) arg0,
+						(NodeType) arg1);
+			}
+
+			@Override
+			public Object getRoot() {
+				return typedModel.getRoot();
+			}
+
+			@Override
+			@SuppressWarnings("unchecked")
+			public boolean isLeaf(Object arg0) {
+				return typedModel.isLeaf((NodeType) arg0);
+			}
+
+			@Override
+			@SuppressWarnings("unchecked")
+			public void removeTreeModelListener(TreeModelListener arg0) {
+				synchronized (mapping) {
+					TypedListenerPair<NodeType> toRemove = null;
+					for (TypedListenerPair<Object> tpl : mapping)
+						if (tpl.untypedListener == arg0) {
+							toRemove = (TypedListenerPair<NodeType>) tpl;
+							typedModel
+									.removeTreeModelListener((TypedTreeModelListener<NodeType>) tpl.typedListener);
+							break;
+						}
+					if (toRemove == null)
+						return;
+					mapping.remove(toRemove);
+				}
+			}
+
+			@Override
+			public void valueForPathChanged(TreePath arg0, Object arg1) {
+				typedModel.valueForPathChanged(arg0, arg1);
+			}
+		};
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/utility/TypedTreeModel.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/utility/TypedTreeModel.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/utility/TypedTreeModel.java
new file mode 100644
index 0000000..9f65f57
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/utility/TypedTreeModel.java
@@ -0,0 +1,116 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.utility;
+
+import javax.swing.tree.TreePath;
+
+/**
+ * A replacement for TreeModel where nodes are typed rather than being generic
+ * objects. Because of the way interfaces and generics work this can't be
+ * related in any inheritance heirarchy to the actual javax.swing.TreeModel
+ * interface but is very similar (okay, identical) in operation. For cases where
+ * you want to use a normal TreeModel such as using this as the backing data
+ * model for a JTree you can use the TreeModelAdapter class to create an untyped
+ * view over the typed version defined here.
+ * 
+ * @author Tom Oinn
+ * 
+ * @see javax.swing.tree.TreeModel
+ * 
+ * @param <NodeType>
+ *            Each node in the tree is of this type
+ */
+public interface TypedTreeModel<NodeType> {
+	/**
+	 * Adds a listener for the TreeModelEvent posted after the tree changes.
+	 */
+	void addTreeModelListener(TypedTreeModelListener<NodeType> l);
+
+	/**
+	 * Returns the child of parent at index 'index' in the parent's child array.
+	 * 
+	 * @param parent
+	 *            parent instance of typed node type
+	 * @param index
+	 *            index within parent
+	 * @return child node at the specified index
+	 */
+	NodeType getChild(NodeType parent, int index);
+
+	/**
+	 * Returns the number of children of parent.
+	 * 
+	 * @param parent
+	 *            node to count children for
+	 * @return number of children
+	 */
+	int getChildCount(NodeType parent);
+
+	/**
+	 * Returns the index of child in parent.
+	 * 
+	 * @param parent
+	 *            a node in the tree, obtained from this data source
+	 * @param child
+	 *            the node we are interested in
+	 * @return the index of the child in the parent, or -1 if either child or
+	 *         parent are null
+	 */
+	int getIndexOfChild(NodeType parent, NodeType child);
+
+	/**
+	 * Returns the root of the tree. Returns null only if the tree has no nodes.
+	 * 
+	 * @return the root of the tree
+	 */
+	NodeType getRoot();
+
+	/**
+	 * Returns true if node is a leaf. It is possible for this method to return
+	 * false even if node has no children. A directory in a filesystem, for
+	 * example, may contain no files; the node representing the directory is not
+	 * a leaf, but it also has no children.
+	 * 
+	 * @param node
+	 *            a node in the tree, obtained from this data source
+	 * @return true if node is a leaf
+	 */
+	boolean isLeaf(NodeType node);
+
+	/**
+	 * Removes a listener previously added with addTreeModelListener.
+	 * 
+	 * @param l
+	 *            typed tree model listener to remove
+	 */
+	void removeTreeModelListener(TypedTreeModelListener<NodeType> l);
+
+	/**
+	 * Messaged when the user has altered the value for the item identified by
+	 * path to newValue. If newValue signifies a truly new value the model
+	 * should post a treeNodesChanged event.
+	 * 
+	 * @param path
+	 *            path to the node that the user has altered
+	 * @param newValue
+	 *            the new value from the TreeCellEditor
+	 */
+	void valueForPathChanged(TreePath path, Object newValue);
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/5f1ddb71/taverna-workflowmodel-api/src/main/java/org/apache/taverna/utility/TypedTreeModelEvent.java
----------------------------------------------------------------------
diff --git a/taverna-workflowmodel-api/src/main/java/org/apache/taverna/utility/TypedTreeModelEvent.java b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/utility/TypedTreeModelEvent.java
new file mode 100644
index 0000000..3bfb3d9
--- /dev/null
+++ b/taverna-workflowmodel-api/src/main/java/org/apache/taverna/utility/TypedTreeModelEvent.java
@@ -0,0 +1,150 @@
+/*
+* 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.
+*/
+
+package org.apache.taverna.utility;
+
+import javax.swing.tree.TreePath;
+
+/**
+ * Type aware version of TreeModelEvent
+ * 
+ * @author Tom Oinn
+ * 
+ * @see javax.swing.tree.TreeModelEvent
+ * 
+ * @param <NodeType>
+ *            the node type parameter of the TypedTreeModel to which this event
+ *            applies
+ */
+public class TypedTreeModelEvent<NodeType> {
+	protected int[] childIndices;
+	protected NodeType[] children;
+	protected TreePath path;
+	protected Object source;
+
+	/**
+	 * Used to create an event when the node structure has changed in some way,
+	 * identifying the path to the root of a modified subtree as an array of
+	 * Objects.
+	 * 
+	 * @param source
+	 * @param path
+	 */
+	public TypedTreeModelEvent(Object source, NodeType[] path) {
+		this.path = new TreePath(path);
+		this.source = source;
+		this.childIndices = new int[0];
+	}
+
+	/**
+	 * Used to create an event when the node structure has changed in some way,
+	 * identifying the path to the root of the modified subtree as a TreePath
+	 * object.
+	 * 
+	 * @param source
+	 * @param path
+	 */
+	public TypedTreeModelEvent(Object source, TreePath path) {
+		this.path = path;
+		this.source = source;
+		this.childIndices = new int[0];
+	}
+
+	/**
+	 * Used to create an event when nodes have been changed, inserted, or
+	 * removed, identifying the path to the parent of the modified items as a
+	 * TreePath object.
+	 * 
+	 * @param source
+	 * @param path
+	 * @param childIndices
+	 * @param children
+	 */
+	public TypedTreeModelEvent(Object source, TreePath path,
+			int[] childIndices, NodeType[] children) {
+		this.source = source;
+		this.path = path;
+		this.childIndices = childIndices;
+		this.children = children;
+	}
+
+	/**
+	 * Used to create an event when nodes have been changed, inserted, or
+	 * removed, identifying the path to the parent of the modified items as an
+	 * array of Objects.
+	 * 
+	 * @param source
+	 * @param path
+	 * @param childIndices
+	 * @param children
+	 */
+	public TypedTreeModelEvent(Object source, NodeType[] path,
+			int[] childIndices, NodeType[] children) {
+		this.path = new TreePath(path);
+		this.source = source;
+		this.childIndices = childIndices;
+		this.children = children;
+	}
+
+	/**
+	 * Returns the values of the child indexes.
+	 * 
+	 * @return
+	 */
+	public int[] getChildIndices() {
+		return this.childIndices;
+	}
+
+	/**
+	 * Returns the objects that are children of the node identified by getPath
+	 * at the locations specified by getChildIndices.
+	 * 
+	 * @return
+	 */
+	public NodeType[] getChildren() {
+		return this.children;
+	}
+
+	/**
+	 * The object on which the Event initially occurred.
+	 * 
+	 * @return
+	 */
+	public Object getSource() {
+		return this.source;
+	}
+
+	/**
+	 * For all events, except treeStructureChanged, returns the parent of the
+	 * changed nodes.
+	 * 
+	 * @return
+	 */
+	public TreePath getTreePath() {
+		return path;
+	}
+
+	/**
+	 * Returns a string that displays and identifies this object's properties.
+	 */
+	@Override
+	public String toString() {
+		return "Typed TreeModelEvent " + super.toString();
+	}
+}