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();
+ }
+}