You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2015/02/17 12:37:16 UTC
[56/70] [abbrv] incubator-taverna-common-activities git commit:
taverna-external-tool-activity/
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivity.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivity.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivity.java
new file mode 100755
index 0000000..1e6ef77
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivity.java
@@ -0,0 +1,301 @@
+/*******************************************************************************
+ * Copyright (C) 2009 Hajo Nils Krabbenhoeft, INB, University of Luebeck
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+
+package net.sf.taverna.t2.activities.externaltool;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.sf.taverna.t2.activities.externaltool.manager.InvocationGroup;
+import net.sf.taverna.t2.activities.externaltool.manager.InvocationMechanism;
+import net.sf.taverna.t2.annotation.Annotated;
+import net.sf.taverna.t2.annotation.annotationbeans.MimeType;
+import net.sf.taverna.t2.reference.ExternalReferenceSPI;
+import net.sf.taverna.t2.reference.ReferenceService;
+import net.sf.taverna.t2.reference.T2Reference;
+import net.sf.taverna.t2.reference.WorkflowRunIdEntity;
+import net.sf.taverna.t2.workflowmodel.EditException;
+import net.sf.taverna.t2.workflowmodel.processor.activity.AbstractAsynchronousActivity;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityConfigurationException;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityInputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityOutputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.AsynchronousActivityCallback;
+
+import org.apache.log4j.Logger;
+
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInput;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInputUser;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptOutput;
+import de.uni_luebeck.inb.knowarc.usecases.UseCaseDescription;
+import de.uni_luebeck.inb.knowarc.usecases.invocation.InvocationException;
+import de.uni_luebeck.inb.knowarc.usecases.invocation.UseCaseInvocation;
+
+/**
+ * This is the main class of the use case activity plugin. Here we store the
+ * configuration and the description of a use case activity, configure the input
+ * and output port and provide use case activity invocation
+ *
+ * @author Hajo Nils Krabbenhoeft
+ */
+public class ExternalToolActivity extends AbstractAsynchronousActivity<ExternalToolActivityConfigurationBean> {
+
+ public static final String URI = "http://ns.taverna.org.uk/2010/activity/tool";
+
+ private static final String STDERR = "STDERR";
+
+ private static final String STDOUT = "STDOUT";
+
+ private static final String STDIN = "STDIN";
+
+ private static Logger logger = Logger.getLogger(ExternalToolActivity.class);
+
+ private ExternalToolActivityConfigurationBean configurationBean;
+ private UseCaseDescription mydesc;
+
+ private List<InvocationCreator> invocationCreators;
+
+ /**
+ * Add the given MIME types to the given input/output port.
+ *
+ * @param annotated
+ * The port to which to add the MIME types.
+ * @param mimeTypes
+ * A list of Strings specifying the MIME types to add.
+ */
+ private void addMimeTypes(Annotated<?> annotated, List<String> mimeTypes) {
+ for (String mimeType : mimeTypes) {
+ MimeType mimeTypeAnnotation = new MimeType();
+ mimeTypeAnnotation.setText(mimeType);
+ try {
+ getEdits().getAddAnnotationChainEdit(annotated, mimeTypeAnnotation).doEdit();
+ } catch (EditException e) {
+ Logger.getLogger(ExternalToolActivity.class).error(e);
+ }
+ }
+ }
+
+ /**
+ * Create a new input port with the given name, depth, element class and
+ * MIME types.
+ *
+ * @param portName
+ * Name of the new port
+ * @param portDepth
+ * Depth of the new port
+ * @param translatedElementClass
+ * Which class of elements would this port like?
+ * @param mimeTypes
+ * Accepted mime types for this port
+ */
+ private void addInputWithMime(String portName, int portDepth, Class<?> translatedElementClass, List<String> mimeTypes) {
+ List<Class<? extends ExternalReferenceSPI>> handledReferenceSchemes = Collections.emptyList();
+ ActivityInputPort inputPort = getEdits().createActivityInputPort(portName, portDepth, true, handledReferenceSchemes,
+ translatedElementClass);
+ inputPorts.add(inputPort);
+ if (mimeTypes != null) {
+ addMimeTypes(inputPort, mimeTypes);
+ }
+ }
+
+ /**
+ * Create a new output port with the given MIME types
+ *
+ * @param portName
+ * Name of the new port
+ * @param portDepth
+ * Depth of the new port
+ * @param mimeTypes
+ * Accepted mime types for this port
+ */
+ private void addOutputWithMime(String portName, int portDepth, List<String> mimeTypes) {
+ ActivityOutputPort outputPort = getEdits().createActivityOutputPort(portName, portDepth, portDepth);
+ outputPorts.add(outputPort);
+ addMimeTypes(outputPort, mimeTypes);
+ }
+
+ @Override
+ public void configure(ExternalToolActivityConfigurationBean bean) throws ActivityConfigurationException {
+ this.configurationBean = bean;
+
+ try {
+ mydesc = bean.getUseCaseDescription();
+
+ inputPorts.clear();
+ outputPorts.clear();
+
+ if (mydesc != null) {
+
+ // loop through all script inputs and add them as taverna activity
+ // input ports
+ for (Map.Entry<String, ScriptInput> cur : mydesc.getInputs().entrySet()) {
+ ScriptInputUser scriptInputUser = (ScriptInputUser) cur.getValue();
+ // if the input port is a list, depth is 1 otherwise it is a
+ // single element, therefore depth 0
+ // if the input port is binary, we would like byte arrays,
+ // otherwise we require strings
+ addInputWithMime(cur.getKey(), scriptInputUser.isList() ? 1 : 0, cur.getValue().isBinary() ? byte[].class : String.class, scriptInputUser.getMime());
+
+ }
+ // loop through all script outputs and add them to taverna
+ for (Map.Entry<String, ScriptOutput> cur : mydesc.getOutputs().entrySet()) {
+ addOutputWithMime(cur.getKey(), 0, cur.getValue().getMime());
+ }
+ }
+
+ if (mydesc.isIncludeStdIn()) {
+ addInputWithMime(STDIN, 0, byte[].class, null);
+ }
+ if (mydesc.isIncludeStdOut()) {
+ addOutput(STDOUT, 0);
+ }
+ if (mydesc.isIncludeStdErr()) {
+ addOutput(STDERR, 0);
+ }
+ } catch (Exception e) {
+ throw new ActivityConfigurationException("Couldn't create ExternalTool Activity", e);
+ }
+ }
+
+ @Override
+ public ExternalToolActivityConfigurationBean getConfiguration() {
+ if (configurationBean != null) {
+ InvocationGroup invocationGroup = configurationBean.getInvocationGroup();
+ if (invocationGroup == null) {
+ if (configurationBean.getMechanism() != null) {
+ configurationBean.convertMechanismToDetails();
+ }
+ } else {
+ if (invocationGroup.getMechanism() != null) {
+ invocationGroup.convertMechanismToDetails();
+ }
+ }
+ }
+ return configurationBean;
+ }
+
+ public ExternalToolActivityConfigurationBean getConfigurationNoConversion() {
+ return configurationBean;
+ }
+
+ public InvocationMechanism recreateMechanism() {
+ if (configurationBean.getInvocationGroup() != null) {
+ if (configurationBean.getInvocationGroup().getMechanism() == null) {
+ configurationBean.getInvocationGroup().convertDetailsToMechanism();
+ }
+ return configurationBean.getInvocationGroup().getMechanism();
+ } else {
+ if (configurationBean.getMechanism() == null) {
+ configurationBean.convertDetailsToMechanism();
+ }
+ return configurationBean.getMechanism();
+ }
+ }
+
+ @Override
+ public void executeAsynch(final Map<String, T2Reference> data, final AsynchronousActivityCallback callback) {
+
+ callback.requestRun(new Runnable() {
+
+ public void run() {
+ ReferenceService referenceService = callback.getContext().getReferenceService();
+ UseCaseInvocation invoke = null;
+
+ /**
+ * Note that retrying needs to be either done via Taverna's retry mechanism or as part of the specific invocation
+ */
+ try {
+
+ invoke = getInvocation(recreateMechanism(),
+ configurationBean.getUseCaseDescription(), data, referenceService);
+ if (invoke == null) {
+ logger.error("Invoke is null");
+ callback.fail("No invocation mechanism found");
+ }
+ String runId = callback.getContext()
+ .getEntities(WorkflowRunIdEntity.class).get(0)
+ .getWorkflowRunId();
+ logger.info("Run id is " + runId);
+ invoke.rememberRun(runId);
+
+ invoke.setContext(callback.getContext());
+
+ // look at every use dynamic case input
+ for (String cur : invoke.getInputs()) {
+ if (!cur.equals(STDIN)) {
+ invoke.setInput(cur, referenceService,
+ data.get(cur));
+ }
+ }
+
+ if (mydesc.isIncludeStdIn() && (data.get(STDIN) != null)) {
+ invoke.setStdIn(referenceService, data.get(STDIN));
+ }
+
+ // submit the use case to its invocation mechanism
+ invoke.submit_generate_job(referenceService);
+
+ // retrieve the result.
+ Map<String, Object> downloads = invoke
+ .submit_wait_fetch_results(referenceService);
+ Map<String, T2Reference> result = new HashMap<String, T2Reference>();
+ for (Map.Entry<String, Object> cur : downloads.entrySet()) {
+ Object value = cur.getValue();
+
+ // register the result value with taverna
+ T2Reference reference = referenceService.register(
+ value, 0, true, callback.getContext());
+
+ // store the reference into the activity result
+ // set
+ result.put(cur.getKey(), reference);
+ }
+ callback.receiveResult(result, new int[0]);
+ } catch (InvocationException e) {
+ callback.fail(e.getMessage(), e);
+ }
+ }
+
+ });
+
+ }
+
+ public void setInvocationCreators(List<InvocationCreator> invocationCreators) {
+ this.invocationCreators = invocationCreators;
+ }
+
+ private UseCaseInvocation getInvocation(InvocationMechanism mechanism, UseCaseDescription description, Map<String, T2Reference> data, ReferenceService referenceService) {
+ UseCaseInvocation result = null;
+ InvocationCreator creator = null;
+ for (InvocationCreator c : invocationCreators) {
+ if (c.canHandle(mechanism.getType())) {
+ creator = c;
+ break;
+ }
+ }
+ if (creator != null) {
+ result = creator.convert(mechanism, description, data, referenceService);
+ }
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityConfigurationBean.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityConfigurationBean.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityConfigurationBean.java
new file mode 100755
index 0000000..ce3387b
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityConfigurationBean.java
@@ -0,0 +1,194 @@
+package net.sf.taverna.t2.activities.externaltool;
+
+import java.util.List;
+
+import net.sf.taverna.t2.activities.externaltool.manager.InvocationGroup;
+import net.sf.taverna.t2.activities.externaltool.manager.InvocationMechanism;
+import net.sf.taverna.t2.activities.externaltool.manager.MechanismCreator;
+import net.sf.taverna.t2.workflowmodel.processor.config.ConfigurationBean;
+import net.sf.taverna.t2.workflowmodel.processor.config.ConfigurationProperty;
+import de.uni_luebeck.inb.knowarc.usecases.UseCaseDescription;
+
+@ConfigurationBean(uri = ExternalToolActivity.URI + "#Config")
+public final class ExternalToolActivityConfigurationBean {
+
+ private InvocationGroup group;
+
+ private String mechanismType;
+
+ private String mechanismName;
+
+ private String mechanismXML;
+
+ private transient InvocationMechanism mechanism;
+
+ protected String repositoryUrl;
+ protected String externaltoolid;
+ protected UseCaseDescription useCaseDescription = null;
+ private boolean edited = false;
+
+ private List<MechanismCreator> mechanismCreators;
+
+ public boolean isEdited() {
+ return edited;
+ }
+
+ public ExternalToolActivityConfigurationBean() {
+ }
+
+ public InvocationGroup getInvocationGroup() {
+ return group;
+ }
+
+ @ConfigurationProperty(name = "invocationGroup", label = "InvocationGroup", required=false)
+ public void setInvocationGroup(
+ InvocationGroup group) {
+ this.group = group;
+ clearMechanismInformation();
+ }
+
+ private void clearMechanismInformation() {
+ this.mechanismType = null;
+ this.mechanismName = null;
+ this.mechanismXML = null;
+ this.mechanism = null;
+ }
+
+ /**
+ * @return the repositoryUrl
+ */
+ public String getRepositoryUrl() {
+ return repositoryUrl;
+ }
+
+ /**
+ * @param repositoryUrl the repositoryUrl to set
+ */
+ @ConfigurationProperty(name = "repositoryUrl", label = "Repository URL", required=false)
+ public void setRepositoryUrl(String repositoryUrl) {
+ this.repositoryUrl = repositoryUrl;
+ }
+
+ /**
+ * @return the externaltoolid
+ */
+ public String getExternaltoolid() {
+ return externaltoolid;
+ }
+
+ /**
+ * @param externaltoolid the externaltoolid to set
+ */
+ @ConfigurationProperty(name = "toolId", label = "Tool ID")
+ public void setExternaltoolid(String externaltoolid) {
+ this.externaltoolid = externaltoolid;
+ }
+
+ /**
+ * @return the useCaseDescription
+ */
+ public UseCaseDescription getUseCaseDescription() {
+ return useCaseDescription;
+ }
+
+ /**
+ * @param useCaseDescription the useCaseDescription to set
+ */
+ @ConfigurationProperty(name = "toolDescription", label = "Tool Description")
+ public void setUseCaseDescription(UseCaseDescription useCaseDescription) {
+ this.useCaseDescription = useCaseDescription;
+ }
+
+ @ConfigurationProperty(name = "edited", label = "Edited", required=false)
+ public void setEdited(boolean b) {
+ this.edited = b;
+ }
+
+ /**
+ * Note this also sets the details
+ *
+ * @param mechanism the mechanism to set
+ */
+ public void setMechanism(InvocationMechanism mechanism) {
+ this.mechanism = mechanism;
+ convertMechanismToDetails();
+ this.group = null;
+ }
+
+ public void convertMechanismToDetails() {
+ if (mechanism != null) {
+ this.setMechanismXML(mechanism.getXML());
+ this.setMechanismName(mechanism.getName());
+ this.setMechanismType(mechanism.getType());
+ }
+ }
+
+ /**
+ * @param mechanismType the mechanismType to set
+ */
+ @ConfigurationProperty(name = "mechanismType", label = "Mechanism Type", required=false)
+ public void setMechanismType(String mechanismType) {
+ this.mechanismType = mechanismType;
+ }
+
+ /**
+ * @param mechanismName the mechanismName to set
+ */
+ @ConfigurationProperty(name = "mechanismName", label = "Mechanism Name", required=false)
+ public void setMechanismName(String mechanismName) {
+ this.mechanismName = mechanismName;
+ }
+
+ /**
+ * @param mechanismXML the mechanismXML to set
+ */
+ @ConfigurationProperty(name = "mechanismXML", label = "Mechanism XML", required=false)
+ public void setMechanismXML(String mechanismXML) {
+ this.mechanismXML = mechanismXML;
+ }
+
+ public void convertDetailsToMechanism() {
+ if (mechanismXML != null) {
+ for (MechanismCreator mc : mechanismCreators) {
+ if (mc.canHandle(getMechanismType())) {
+ mechanism = mc.convert(getMechanismXML(), getMechanismName());
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * @return the mechanism
+ */
+ public InvocationMechanism getMechanism() {
+
+ return mechanism;
+ }
+
+ /**
+ * @return the mechanismType
+ */
+ public String getMechanismType() {
+ return mechanismType;
+ }
+
+ /**
+ * @return the mechanismName
+ */
+ public String getMechanismName() {
+ return mechanismName;
+ }
+
+ /**
+ * @return the mechanismXML
+ */
+ public String getMechanismXML() {
+ return mechanismXML;
+ }
+
+ public void setMechanismCreators(List<MechanismCreator> mechanismCreators) {
+ this.mechanismCreators = mechanismCreators;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityFactory.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityFactory.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityFactory.java
new file mode 100644
index 0000000..dc27b11
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityFactory.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.externaltool;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.List;
+import java.util.Set;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import net.sf.taverna.t2.activities.externaltool.manager.MechanismCreator;
+import net.sf.taverna.t2.workflowmodel.Edits;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityConfigurationException;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityFactory;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityInputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityOutputPort;
+
+/**
+ * An {@link ActivityFactory} for creating <code>ExternalToolActivity</code>.
+ *
+ * @author David Withers
+ */
+public class ExternalToolActivityFactory implements ActivityFactory {
+
+ private List<InvocationCreator> invocationCreators;
+
+ private List<MechanismCreator> mechanismCreators;
+
+ private Edits edits;
+
+ @Override
+ public ExternalToolActivity createActivity() {
+ ExternalToolActivity activity = new ExternalToolActivity();
+ activity.setInvocationCreators(invocationCreators);
+ activity.setEdits(edits);
+ return activity;
+ }
+
+ @Override
+ public URI getActivityType() {
+ return URI.create(ExternalToolActivity.URI);
+ }
+
+ @Override
+ public JsonNode getActivityConfigurationSchema() {
+ ObjectMapper objectMapper = new ObjectMapper();
+ try {
+ return objectMapper.readTree(getClass().getResource("/schema.json"));
+ } catch (IOException e) {
+ return objectMapper.createObjectNode();
+ }
+ }
+
+ public void setInvocationCreators(List<InvocationCreator> invocationCreators) {
+ this.invocationCreators = invocationCreators;
+ }
+
+ public void setMechanismCreators(List<MechanismCreator> mechanismCreators) {
+ this.mechanismCreators = mechanismCreators;
+ }
+
+ @Override
+ public Set<ActivityInputPort> getInputPorts(JsonNode configuration)
+ throws ActivityConfigurationException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Set<ActivityOutputPort> getOutputPorts(JsonNode configuration)
+ throws ActivityConfigurationException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setEdits(Edits edits) {
+ this.edits = edits;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityHealthChecker.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityHealthChecker.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityHealthChecker.java
new file mode 100755
index 0000000..b65da68
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityHealthChecker.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (C) 2009 Hajo Nils Krabbenhoeft, INB, University of Luebeck
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+
+package net.sf.taverna.t2.activities.externaltool;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+import net.sf.taverna.t2.activities.externaltool.manager.InvocationGroup;
+import net.sf.taverna.t2.activities.externaltool.manager.InvocationGroupManager;
+import net.sf.taverna.t2.activities.externaltool.manager.InvocationMechanism;
+import net.sf.taverna.t2.visit.VisitReport;
+import net.sf.taverna.t2.visit.VisitReport.Status;
+import net.sf.taverna.t2.workflowmodel.health.HealthCheck;
+import net.sf.taverna.t2.workflowmodel.health.HealthChecker;
+import net.sf.taverna.t2.workflowmodel.utils.Tools;
+
+public class ExternalToolActivityHealthChecker implements HealthChecker<ExternalToolActivity> {
+
+ private InvocationGroupManager invocationGroupManager;
+ private ExternalToolActivity activity;
+
+ public boolean canVisit(Object subject) {
+ return subject != null && subject instanceof ExternalToolActivity;
+ }
+
+ public VisitReport visit(ExternalToolActivity activity, List<Object> ancestry) {
+ this.activity = activity;
+ ExternalToolActivityConfigurationBean configuration = activity.getConfigurationNoConversion();
+ List<VisitReport> reports = new ArrayList<VisitReport>();
+
+ VisitReport locationReport = checkLocation(configuration);
+ if (locationReport != null) {
+ reports.add(locationReport);
+ }
+
+ VisitReport report = new VisitReport(HealthCheck.getInstance(), activity, "External tool service", HealthCheck.NO_PROBLEM, reports);
+
+ return report;
+ }
+
+
+ private VisitReport checkLocation(
+ ExternalToolActivityConfigurationBean configuration) {
+
+ if (!updateLocation(configuration)) {
+ return new VisitReport(HealthCheck.getInstance(), activity, "Unmanaged invocation mechanism", HealthCheck.UNMANAGED_LOCATION, Status.WARNING);
+ } else {
+ return null;
+ }
+ }
+
+ public boolean updateLocation(ExternalToolActivityConfigurationBean configuration) {
+ InvocationGroup invocationGroup = configuration.getInvocationGroup();
+ String invocationGroupSpecification = null;
+ String invocationMechanismSpecification = null;
+ if (invocationGroup != null) {
+ if (invocationGroupManager.containsGroup(invocationGroup)) {
+ return true;
+ }
+ InvocationGroup replacementGroup = invocationGroupManager.getGroupReplacement(invocationGroup);
+ if (replacementGroup != null) {
+ configuration.setInvocationGroup(replacementGroup);
+ return true;
+ }
+ invocationGroupSpecification = invocationGroup.getName() + ":" + invocationGroup.getMechanismXML();
+ InvocationGroup importedGroup = invocationGroupManager.getImportedGroup(invocationGroupSpecification);
+ if (importedGroup != null) {
+ configuration.setInvocationGroup(importedGroup);
+ return true;
+ }
+ }
+
+ InvocationMechanism invocationMechanism = configuration.getMechanism();
+ if (invocationMechanism != null) {
+ if (invocationGroupManager.containsMechanism(invocationMechanism)) {
+ return true;
+ }
+ }
+ String mechanismXML = null;
+ String mechanismName = null;
+
+ if (invocationGroup != null) {
+ mechanismXML = invocationGroup.getMechanismXML();
+ mechanismName = invocationGroup.getMechanismName();
+ } else {
+ mechanismXML = configuration.getMechanismXML();
+ mechanismName = configuration.getMechanismName();
+ }
+ invocationMechanismSpecification = mechanismName + ":" + mechanismXML;
+
+ InvocationMechanism foundMechanism = null;
+ HashSet<String> mechanismNames = new HashSet<String>();
+ for (InvocationMechanism mechanism : invocationGroupManager.getMechanisms()) {
+ mechanismNames.add(mechanism.getName());
+ if (mechanism.getName().equals(mechanismName) && (mechanism.getXML().equals(mechanismXML))) {
+ if (invocationMechanism != mechanism) {
+ foundMechanism = mechanism;
+ }
+ }
+ }
+
+ if (foundMechanism == null) {
+ foundMechanism = invocationGroupManager.getMechanismReplacement(invocationMechanismSpecification);
+ if (foundMechanism == null) {
+ foundMechanism = invocationGroupManager.getImportedMechanism(invocationMechanismSpecification);
+ }
+ }
+
+ if (foundMechanism != null) {
+ if (invocationGroup != null) {
+ invocationGroup.setMechanism(foundMechanism);
+ // Cannot return because invocationGroup is still unknown
+ } else {
+ configuration.setMechanism(foundMechanism);
+ return true;
+ }
+ }
+
+ if (foundMechanism == null) {
+ InvocationMechanism createdMechanism;
+ if (invocationGroup != null) {
+ invocationGroup.convertDetailsToMechanism();
+ createdMechanism = invocationGroup.getMechanism();
+ } else {
+ configuration.convertDetailsToMechanism();
+ createdMechanism = configuration.getMechanism();
+ }
+
+ String chosenMechanismName = Tools.uniqueObjectName(mechanismName,
+ mechanismNames);
+ createdMechanism.setName(chosenMechanismName);
+ if (invocationGroup != null) {
+ invocationGroup.setMechanism(createdMechanism);
+ } else {
+ configuration.setMechanism(createdMechanism);
+ }
+ invocationGroupManager.importMechanism(invocationMechanismSpecification, createdMechanism);
+
+
+ if (invocationGroup == null) {
+ return true;
+ }
+ }
+
+ InvocationGroup foundGroup = null;
+ HashSet<String> groupNames = new HashSet<String>();
+ for (InvocationGroup group : invocationGroupManager.getInvocationGroups()) {
+ groupNames.add(group.getName());
+ if (group.getName().equals(invocationGroup.getName()) && (group.getMechanism() == invocationGroup.getMechanism())) {
+ foundGroup = group;
+ }
+ }
+ if (foundGroup != null) {
+ configuration.setInvocationGroup(foundGroup);
+ return true;
+ }
+ invocationGroup.setName(Tools.uniqueObjectName(invocationGroup.getName(), groupNames));
+ invocationGroupManager.importInvocationGroup(invocationGroupSpecification, invocationGroup);
+ return true;
+ }
+
+ public boolean isTimeConsuming() {
+ return false;
+ }
+
+ /**
+ * Sets the invocationGroupManager.
+ *
+ * @param invocationGroupManager the new value of invocationGroupManager
+ */
+ public void setInvocationGroupManager(InvocationGroupManager invocationGroupManager) {
+ this.invocationGroupManager = invocationGroupManager;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityMimeTypeChecker.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityMimeTypeChecker.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityMimeTypeChecker.java
new file mode 100644
index 0000000..4ab8f93
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolActivityMimeTypeChecker.java
@@ -0,0 +1,174 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.activities.externaltool;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import net.sf.taverna.t2.visit.VisitReport;
+import net.sf.taverna.t2.visit.VisitReport.Status;
+import net.sf.taverna.t2.workflowmodel.Dataflow;
+import net.sf.taverna.t2.workflowmodel.Datalink;
+import net.sf.taverna.t2.workflowmodel.Merge;
+import net.sf.taverna.t2.workflowmodel.MergeInputPort;
+import net.sf.taverna.t2.workflowmodel.MergeOutputPort;
+import net.sf.taverna.t2.workflowmodel.MergePort;
+import net.sf.taverna.t2.workflowmodel.OutputPort;
+import net.sf.taverna.t2.workflowmodel.Port;
+import net.sf.taverna.t2.workflowmodel.Processor;
+import net.sf.taverna.t2.workflowmodel.ProcessorInputPort;
+import net.sf.taverna.t2.workflowmodel.ProcessorPort;
+import net.sf.taverna.t2.workflowmodel.health.HealthCheck;
+import net.sf.taverna.t2.workflowmodel.health.HealthChecker;
+import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityInputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityOutputPort;
+import net.sf.taverna.t2.workflowmodel.utils.Tools;
+
+import org.apache.log4j.Logger;
+
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInputUser;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptOutput;
+
+/**
+ * @author alanrw
+ *
+ */
+public final class ExternalToolActivityMimeTypeChecker implements HealthChecker<ExternalToolActivity> {
+
+ private static Logger logger = Logger.getLogger(ExternalToolActivityMimeTypeChecker.class);
+
+ public boolean canVisit(Object o) {
+ return o != null && o instanceof ExternalToolActivity;
+ }
+
+ public boolean isTimeConsuming() {
+ return false;
+ }
+
+ public VisitReport visit(ExternalToolActivity o,
+ List<Object> ancestry) {
+ List<VisitReport> reports = new ArrayList<VisitReport>();
+ Processor p = (Processor) VisitReport.findAncestor(ancestry, Processor.class);
+ Dataflow d = (Dataflow) VisitReport.findAncestor(ancestry, Dataflow.class);
+
+ for (ActivityInputPort aip : o.getInputPorts()) {
+ Set<String> sinkMimeSet = getMimeTypesForInput(o, aip);
+ if (sinkMimeSet.isEmpty()) {
+ continue;
+ }
+ ProcessorInputPort pip = Tools.getProcessorInputPort(p, (Activity<?>) o, aip);
+
+ for (Datalink dl : d.getLinks()) {
+
+ if (dl.getSink().equals(pip)) {
+ Port source = dl.getSource();
+ Set<VisitReport> subReports = checkSource(dl, source, d, (Activity) o, aip, sinkMimeSet);
+ for (VisitReport vr : subReports) {
+ vr.setProperty("sinkProcessor", p);
+ vr.setProperty("activity", o);
+ vr.setProperty("sinkPort", pip);
+ }
+ reports.addAll(subReports);
+ }
+ }
+ }
+
+ if (reports.isEmpty()) {
+ return null;
+ }
+ if (reports.size() == 1) {
+ return reports.get(0);
+ }
+ else {
+ return new VisitReport(HealthCheck.getInstance(), o, "Collation", HealthCheck.DEFAULT_VALUE, reports);
+ }
+ }
+
+ private Set<VisitReport> checkSource(Datalink datalink, Port source, Dataflow d, Activity o, ActivityInputPort aip, Set<String> sinkMimeSet) {
+ Set<VisitReport> reports = new HashSet<VisitReport>();
+ if (source instanceof ProcessorPort) {
+ ProcessorPort processorPort = (ProcessorPort) source;
+ Processor sourceProcessor = processorPort.getProcessor();
+ Activity sourceActivity = sourceProcessor.getActivityList().get(0);
+ if (sourceActivity instanceof ExternalToolActivity) {
+ ActivityOutputPort aop = getActivityOutputPort(sourceActivity, processorPort);
+ Set<String> sourceMimeTypes = getMimeTypesForOutput((ExternalToolActivity) sourceActivity, aop);
+ if (!sourceMimeTypes.isEmpty()) {
+ Set<String> sinkMimeTypesClone = new HashSet<String>();
+ sinkMimeTypesClone.addAll(sinkMimeSet);
+ sinkMimeTypesClone.retainAll(sourceMimeTypes);
+ if (sinkMimeTypesClone.isEmpty()) {
+ VisitReport vr = new VisitReport(HealthCheck.getInstance(), o, "Incompatible mime types", HealthCheck.INCOMPATIBLE_MIMETYPES, Status.WARNING);
+ vr.setProperty("sourcePort", processorPort);
+ vr.setProperty("sourceProcessor", sourceProcessor);
+ vr.setProperty("link", datalink);
+ reports.add(vr);
+ }
+ }
+ }
+ } else if (source instanceof MergeOutputPort) {
+ Merge merge = ((MergePort) source).getMerge();
+ for (MergeInputPort mip : merge.getInputPorts()) {
+ for (Datalink dl : d.getLinks()) {
+ if (dl.getSink().equals(mip)) {
+ reports.addAll(checkSource(dl, dl.getSource(), d, o, aip, sinkMimeSet));
+ }
+ }
+
+ }
+ }
+ return reports;
+ }
+
+ private Set<String> getMimeTypesForOutput(ExternalToolActivity o, ActivityOutputPort aop) {
+ ScriptOutput so = (ScriptOutput) o.getConfiguration().getUseCaseDescription().getOutputs().get(aop.getName());
+ if (so == null) {
+ return Collections.EMPTY_SET;
+ }
+ List mimeList = Arrays.asList(so.getMime());
+ Set mimeSet = new HashSet(mimeList);
+ return mimeSet;
+ }
+
+ private Set<String> getMimeTypesForInput(ExternalToolActivity a, ActivityInputPort aip) {
+ ScriptInputUser si = (ScriptInputUser) a.getConfiguration().getUseCaseDescription().getInputs().get(aip.getName());
+ if (si == null) {
+ return Collections.EMPTY_SET;
+ }
+ ArrayList<String> mime = si.getMime();
+ if (mime != null) {
+ List mimeList = Arrays.asList(mime);
+ Set mimeSet = new HashSet(mimeList);
+
+ return mimeSet;
+ } else {
+ return Collections.EMPTY_SET;
+ }
+ }
+
+ private static ActivityOutputPort getActivityOutputPort(
+ Activity<?> activity, ProcessorPort processorOutputPort) {
+ ProcessorInputPort result = null;
+ for (Entry<String, String> mapEntry : activity.getOutputPortMapping()
+ .entrySet()) {
+ if (mapEntry.getKey().equals(processorOutputPort.getName())) {
+ for (OutputPort activityOutputPort : activity
+ .getOutputPorts()) {
+ if (activityOutputPort.getName().equals(mapEntry.getValue())) {
+ return (ActivityOutputPort) activityOutputPort;
+ }
+ }
+ break;
+ }
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolRunDeletionListener.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolRunDeletionListener.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolRunDeletionListener.java
new file mode 100644
index 0000000..bbb53ce
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/ExternalToolRunDeletionListener.java
@@ -0,0 +1,38 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.activities.externaltool;
+
+import net.sf.taverna.t2.activities.externaltool.manager.InvocationGroupManager;
+import net.sf.taverna.t2.workflowmodel.RunDeletionListener;
+
+import org.apache.log4j.Logger;
+
+/**
+ * @author alanrw
+ *
+ */
+public class ExternalToolRunDeletionListener implements RunDeletionListener {
+
+ private static Logger logger = Logger.getLogger(ExternalToolRunDeletionListener.class);
+
+ private InvocationGroupManager invocationGroupManager;
+
+ /* (non-Javadoc)
+ * @see net.sf.taverna.t2.workflowmodel.RunDeletionListener#deleteRun(java.lang.String)
+ */
+ @Override
+ public void deleteRun(String runToDelete) {
+ invocationGroupManager.deleteRun(runToDelete);
+ }
+
+ /**
+ * Sets the invocationGroupManager.
+ *
+ * @param invocationGroupManager the new value of invocationGroupManager
+ */
+ public void setInvocationGroupManager(InvocationGroupManager invocationGroupManager) {
+ this.invocationGroupManager = invocationGroupManager;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/InvocationCreator.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/InvocationCreator.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/InvocationCreator.java
new file mode 100644
index 0000000..5184794
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/InvocationCreator.java
@@ -0,0 +1,25 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.activities.externaltool;
+
+import java.util.Map;
+
+import de.uni_luebeck.inb.knowarc.usecases.UseCaseDescription;
+import de.uni_luebeck.inb.knowarc.usecases.invocation.UseCaseInvocation;
+
+import net.sf.taverna.t2.activities.externaltool.manager.InvocationMechanism;
+import net.sf.taverna.t2.reference.ReferenceService;
+import net.sf.taverna.t2.reference.T2Reference;
+
+/**
+ * @author alanrw
+ *
+ */
+public interface InvocationCreator {
+
+ public boolean canHandle(String mechanismType);
+
+ public UseCaseInvocation convert(InvocationMechanism mechanism, UseCaseDescription description, Map<String, T2Reference> data, ReferenceService referenceService);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/RetrieveLoginFromTaverna.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/RetrieveLoginFromTaverna.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/RetrieveLoginFromTaverna.java
new file mode 100644
index 0000000..949f70a
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/RetrieveLoginFromTaverna.java
@@ -0,0 +1,57 @@
+package net.sf.taverna.t2.activities.externaltool;
+
+import java.net.URI;
+
+import net.sf.taverna.t2.security.credentialmanager.CMException;
+import net.sf.taverna.t2.security.credentialmanager.CredentialManager;
+import net.sf.taverna.t2.security.credentialmanager.UsernamePassword;
+import de.uni_luebeck.inb.knowarc.usecases.invocation.AskUserForPw;
+
+public class RetrieveLoginFromTaverna implements AskUserForPw {
+ private final String url;
+ private final CredentialManager credentialManager;
+
+ public RetrieveLoginFromTaverna(String url, CredentialManager credentialManager) {
+ this.url = url;
+ this.credentialManager = credentialManager;
+ }
+
+ private UsernamePassword getUserPass() {
+ try {
+ final String urlStr = url;
+ URI userpassUrl = URI.create(urlStr.replace("//", "/"));
+ final UsernamePassword userAndPass = credentialManager.getUsernameAndPasswordForService(userpassUrl, false, null);
+ return userAndPass;
+ } catch (CMException e) {
+ throw new RuntimeException("Error in Taverna Credential Manager", e);
+ }
+ }
+
+ public String getUsername() throws RuntimeException {
+ final UsernamePassword userPass = getUserPass();
+ if (userPass == null) {
+ throw new RuntimeException("Unable to obtain valid username and password");
+ }
+ userPass.resetPassword();
+ return userPass.getUsername();
+ }
+
+ public String getPassword() {
+ final UsernamePassword userPass = getUserPass();
+ final String pw = userPass.getPasswordAsString();
+ userPass.resetPassword();
+ return pw;
+ }
+
+
+ public String getKeyfile() {
+ return "";
+ }
+
+ public String getPassphrase() {
+ return "";
+ }
+
+ public void authenticationSucceeded() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/ExternalToolLocalInvocationMechanism.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/ExternalToolLocalInvocationMechanism.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/ExternalToolLocalInvocationMechanism.java
new file mode 100644
index 0000000..d276407
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/ExternalToolLocalInvocationMechanism.java
@@ -0,0 +1,131 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.activities.externaltool.local;
+
+import net.sf.taverna.t2.activities.externaltool.manager.InvocationMechanism;
+
+import org.jdom.Element;
+import org.jdom.Text;
+
+import de.uni_luebeck.inb.knowarc.usecases.invocation.local.LocalUseCaseInvocation;
+
+/**
+ * @author alanrw
+ *
+ */
+public class ExternalToolLocalInvocationMechanism extends
+ InvocationMechanism {
+
+ private String directory;
+
+ private String shellPrefix;
+
+ private String linkCommand;
+
+ private boolean retrieveData;
+
+ /**
+ *
+ */
+ public ExternalToolLocalInvocationMechanism() {
+ super();
+ String os = System.getProperty("os.name");
+ if (!os.startsWith("Windows")) {
+ setShellPrefix(UNIX_SHELL);
+ setLinkCommand(UNIX_LINK);
+ }
+ }
+
+ @Override
+ public String getType() {
+ return LocalUseCaseInvocation.LOCAL_USE_CASE_INVOCATION_TYPE;
+ }
+
+ @Override
+ public Element getXMLElement() {
+ Element result = new Element("localInvocation");
+ if ((directory != null) && !directory.isEmpty()){
+ Element directoryElement = new Element("directory");
+ directoryElement.addContent(new Text(directory));
+ result.addContent(directoryElement);
+ }
+ if ((shellPrefix != null) && !shellPrefix.isEmpty()) {
+ Element shellPrefixElement = new Element("shellPrefix");
+ shellPrefixElement.addContent(new Text(shellPrefix));
+ result.addContent(shellPrefixElement);
+ }
+ if ((linkCommand != null) && !linkCommand.isEmpty()) {
+ Element linkCommandElement = new Element("linkCommand");
+ linkCommandElement.addContent(new Text(linkCommand));
+ result.addContent(linkCommandElement);
+ }
+ if (isRetrieveData()) {
+ Element retrieveDataElement = new Element("retrieveData");
+ result.addContent(retrieveDataElement);
+ }
+ return result;
+ }
+
+
+ /**
+ * @return the directory
+ */
+ public String getDirectory() {
+ return directory;
+ }
+
+ /**
+ * @param directory the directory to set
+ */
+ public void setDirectory(String directory) {
+ this.directory = directory;
+ }
+
+ /**
+ * @return the shellPrefix
+ */
+ public String getShellPrefix() {
+ return shellPrefix;
+ }
+
+ /**
+ * @param shellPrefix the shellPrefix to set
+ */
+ public void setShellPrefix(String shellPrefix) {
+ this.shellPrefix = shellPrefix;
+ }
+
+ /**
+ * @return the linkCommand
+ */
+ public String getLinkCommand() {
+ return linkCommand;
+ }
+
+ /**
+ * @param linkCommand the linkCommand to set
+ */
+ public void setLinkCommand(String linkCommand) {
+ if ((linkCommand == null) || linkCommand.isEmpty()) {
+ this.linkCommand = null;
+ } else {
+ this.linkCommand = linkCommand;
+ }
+ }
+
+ /**
+ * @return the retrieveData
+ */
+ public boolean isRetrieveData() {
+ return retrieveData;
+ }
+
+ /**
+ * @param retrieveData the retrieveData to set
+ */
+ public void setRetrieveData(boolean retrieveData) {
+ this.retrieveData = retrieveData;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/LocalInvocationCreator.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/LocalInvocationCreator.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/LocalInvocationCreator.java
new file mode 100644
index 0000000..393686f
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/LocalInvocationCreator.java
@@ -0,0 +1,49 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.activities.externaltool.local;
+
+import java.io.IOException;
+import java.util.Map;
+
+import net.sf.taverna.t2.activities.externaltool.InvocationCreator;
+import net.sf.taverna.t2.activities.externaltool.manager.InvocationMechanism;
+import net.sf.taverna.t2.reference.ReferenceService;
+import net.sf.taverna.t2.reference.T2Reference;
+
+import org.apache.log4j.Logger;
+
+import de.uni_luebeck.inb.knowarc.usecases.UseCaseDescription;
+import de.uni_luebeck.inb.knowarc.usecases.invocation.UseCaseInvocation;
+import de.uni_luebeck.inb.knowarc.usecases.invocation.local.LocalUseCaseInvocation;
+
+/**
+ * @author alanrw
+ *
+ */
+public final class LocalInvocationCreator implements
+ InvocationCreator {
+
+ private static Logger logger = Logger.getLogger(LocalInvocationCreator.class);
+
+ public boolean equals(Object o) {
+ return (o instanceof LocalInvocationCreator);
+ }
+
+ @Override
+ public boolean canHandle(String mechanismType) {
+ return mechanismType.equals(LocalUseCaseInvocation.LOCAL_USE_CASE_INVOCATION_TYPE);
+ }
+
+ @Override
+ public UseCaseInvocation convert(InvocationMechanism m, UseCaseDescription description, Map<String, T2Reference> data, ReferenceService referenceService) {
+ ExternalToolLocalInvocationMechanism mechanism = (ExternalToolLocalInvocationMechanism) m;
+ UseCaseInvocation result = null;
+ try {
+ result = new LocalUseCaseInvocation(description, mechanism.isRetrieveData(), mechanism.getDirectory(), mechanism.getShellPrefix(), mechanism.getLinkCommand());
+ } catch (IOException e) {
+ logger.error(e);
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/LocalInvocationPersister.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/LocalInvocationPersister.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/LocalInvocationPersister.java
new file mode 100644
index 0000000..f12f4f6
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/LocalInvocationPersister.java
@@ -0,0 +1,45 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.activities.externaltool.local;
+
+import java.io.File;
+
+import org.apache.log4j.Logger;
+
+import de.uni_luebeck.inb.knowarc.usecases.invocation.InvocationException;
+import de.uni_luebeck.inb.knowarc.usecases.invocation.local.LocalUseCaseInvocation;
+import de.uni_luebeck.inb.knowarc.usecases.invocation.ssh.SshUseCaseInvocation;
+import net.sf.taverna.t2.activities.externaltool.manager.InvocationPersister;
+import net.sf.taverna.t2.activities.externaltool.ssh.SshInvocationPersister;
+
+/**
+ * @author alanrw
+ *
+ */
+public class LocalInvocationPersister extends InvocationPersister {
+
+ private static Logger logger = Logger.getLogger(LocalInvocationPersister.class);
+
+ /* (non-Javadoc)
+ * @see net.sf.taverna.t2.activities.externaltool.manager.InvocationPersister#load()
+ */
+ @Override
+ public void load(File directory) {
+ LocalUseCaseInvocation.load(directory);
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.taverna.t2.activities.externaltool.manager.InvocationPersister#persist()
+ */
+ @Override
+ public void persist(File directory) {
+ LocalUseCaseInvocation.persist(directory);
+ }
+
+ @Override
+ public void deleteRun(String runId) {
+ LocalUseCaseInvocation.cleanup(runId);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/LocalMechanismCreator.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/LocalMechanismCreator.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/LocalMechanismCreator.java
new file mode 100644
index 0000000..e053a4c
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/local/LocalMechanismCreator.java
@@ -0,0 +1,48 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.activities.externaltool.local;
+
+import org.jdom.Element;
+
+import de.uni_luebeck.inb.knowarc.usecases.invocation.local.LocalUseCaseInvocation;
+import net.sf.taverna.t2.activities.externaltool.manager.InvocationMechanism;
+import net.sf.taverna.t2.activities.externaltool.manager.MechanismCreator;
+
+/**
+ * @author alanrw
+ *
+ */
+public class LocalMechanismCreator extends MechanismCreator {
+
+ /* (non-Javadoc)
+ * @see net.sf.taverna.t2.activities.externaltool.manager.MechanismCreator#canHandle(java.lang.String)
+ */
+ @Override
+ public boolean canHandle(String mechanismType) {
+ return mechanismType.equals(LocalUseCaseInvocation.LOCAL_USE_CASE_INVOCATION_TYPE);
+ }
+
+ public InvocationMechanism convert(Element detailsElement,
+ String mechanismName) {
+ ExternalToolLocalInvocationMechanism result = new ExternalToolLocalInvocationMechanism();
+ result.setName(mechanismName);
+ Element directoryElement = detailsElement.getChild("directory");
+ if (directoryElement != null) {
+ result.setDirectory(directoryElement.getText());
+ }
+ Element shellPrefixElement = detailsElement.getChild("shellPrefix");
+ if (shellPrefixElement != null) {
+ result.setShellPrefix(shellPrefixElement.getText());
+ }
+ Element linkCommandElement = detailsElement.getChild("linkCommand");
+ if (linkCommandElement != null) {
+ result.setLinkCommand(linkCommandElement.getText());
+ }
+ Element retrieveDataElement = detailsElement.getChild("retrieveData");
+ result.setRetrieveData(retrieveDataElement != null);
+
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroup.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroup.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroup.java
new file mode 100644
index 0000000..ec453f5
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroup.java
@@ -0,0 +1,141 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.activities.externaltool.manager;
+
+import java.util.List;
+
+import net.sf.taverna.t2.activities.externaltool.ExternalToolActivity;
+import net.sf.taverna.t2.workflowmodel.processor.config.ConfigurationBean;
+import net.sf.taverna.t2.workflowmodel.processor.config.ConfigurationProperty;
+
+import org.apache.log4j.Logger;
+
+/**
+ * @author alanrw
+ *
+ */
+@ConfigurationBean(uri = ExternalToolActivity.URI + "#InvocationGroup")
+public class InvocationGroup {
+
+ private static Logger logger = Logger.getLogger(InvocationGroup.class);
+
+ private String invocationGroupName;
+
+ private String mechanismType;
+
+ private String mechanismName;
+
+ private String mechanismXML;
+
+ private transient InvocationMechanism mechanism;
+
+ private List<MechanismCreator> mechanismCreators;
+
+ public InvocationGroup(List<MechanismCreator> mechanismCreators) {
+ setMechanismCreators(mechanismCreators);
+ }
+
+ /**
+ * @return the invocationGroupName
+ */
+ public String getName() {
+ return invocationGroupName;
+ }
+
+ /**
+ * @param invocationGroupName the invocationGroupName to set
+ */
+ @ConfigurationProperty(name = "name", label = "Invocation Group Name")
+ public void setName(String invocationGroupName) {
+ this.invocationGroupName = invocationGroupName;
+ }
+
+ /**
+ * @return the mechanismType
+ */
+ public String getMechanismType() {
+ return mechanismType;
+ }
+
+ /**
+ * @param mechanismType the mechanismType to set
+ */
+ @ConfigurationProperty(name = "mechanismType", label = "Mechanism Type")
+ public void setMechanismType(String mechanismType) {
+ this.mechanismType = mechanismType;
+ }
+
+ /**
+ * @return the mechanismName
+ */
+ public String getMechanismName() {
+ return mechanismName;
+ }
+
+ /**
+ * @param mechanismName the mechanismName to set
+ */
+ @ConfigurationProperty(name = "mechanismName", label = "Mechanism Name")
+ public void setMechanismName(String mechanismName) {
+ this.mechanismName = mechanismName;
+ }
+
+ /**
+ * @return the mechanismXML
+ */
+ public String getMechanismXML() {
+ return mechanismXML;
+ }
+
+ /**
+ * @param mechanismXML the mechanismXML to set
+ */
+ @ConfigurationProperty(name = "mechanismXML", label = "Mechanism XML")
+ public void setMechanismXML(String mechanismXML) {
+ this.mechanismXML = mechanismXML;
+ }
+
+ /**
+ * @return the mechanism
+ */
+ public InvocationMechanism getMechanism() {
+ return mechanism;
+ }
+
+ /**
+ * Note this also sets the corresponding details
+ *
+ * @param mechanism the mechanism to set
+ */
+ public void setMechanism(InvocationMechanism mechanism) {
+ this.mechanism = mechanism;
+ convertMechanismToDetails();
+ }
+
+ public String toString() {
+ return getName();
+ }
+
+ public void convertMechanismToDetails() {
+ this.setMechanismXML(mechanism.getXML());
+ this.setMechanismName(mechanism.getName());
+ this.setMechanismType(mechanism.getType());
+ }
+
+ public void convertDetailsToMechanism() {
+ if (mechanismXML != null) {
+ for (MechanismCreator mc : mechanismCreators) {
+ if (mc.canHandle(getMechanismType())) {
+ mechanism = mc.convert(getMechanismXML(), getMechanismName());
+ break;
+ }
+ }
+ }
+ }
+
+ public void setMechanismCreators(List<MechanismCreator> mechanismCreators) {
+ this.mechanismCreators = mechanismCreators;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupAddedEvent.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupAddedEvent.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupAddedEvent.java
new file mode 100644
index 0000000..1f14b37
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupAddedEvent.java
@@ -0,0 +1,18 @@
+package net.sf.taverna.t2.activities.externaltool.manager;
+
+public class InvocationGroupAddedEvent extends InvocationManagerEvent {
+
+ private InvocationGroup addedGroup;
+
+ public InvocationGroupAddedEvent(InvocationGroup addedGroup) {
+ this.addedGroup = addedGroup;
+ }
+
+ /**
+ * @return the addedGroup
+ */
+ public InvocationGroup getAddedGroup() {
+ return addedGroup;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupChangedEvent.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupChangedEvent.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupChangedEvent.java
new file mode 100644
index 0000000..05c6617
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupChangedEvent.java
@@ -0,0 +1,18 @@
+package net.sf.taverna.t2.activities.externaltool.manager;
+
+public class InvocationGroupChangedEvent extends InvocationManagerEvent {
+
+ private InvocationGroup changedGroup;
+
+ public InvocationGroupChangedEvent(InvocationGroup changedGroup) {
+ this.changedGroup = changedGroup;
+ }
+
+ /**
+ * @return the changedGroup
+ */
+ public InvocationGroup getChangedGroup() {
+ return changedGroup;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupManager.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupManager.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupManager.java
new file mode 100644
index 0000000..b398000
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupManager.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (C) 2012 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.activities.externaltool.manager;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import net.sf.taverna.t2.lang.observer.Observer;
+
+/**
+ *
+ *
+ * @author David Withers
+ */
+public interface InvocationGroupManager {
+
+ public void addInvocationGroup(InvocationGroup group);
+
+ public void replaceInvocationGroup(InvocationGroup originalGroup,
+ InvocationGroup replacementGroup);
+
+ public void removeInvocationGroup(InvocationGroup group);
+
+ public void replaceInvocationMechanism(InvocationMechanism originalMechanism,
+ InvocationMechanism replacementMechanism);
+
+ public void removeMechanism(InvocationMechanism mechanism);
+
+ public HashSet<InvocationGroup> getInvocationGroups();
+
+ public InvocationGroup getDefaultGroup();
+
+ public Set<InvocationMechanism> getMechanisms();
+
+ public void addMechanism(InvocationMechanism mechanism);
+
+ public InvocationMechanism getDefaultMechanism();
+
+ public boolean containsGroup(InvocationGroup group);
+
+ public InvocationMechanism getInvocationMechanism(String defaultMechanismName);
+
+ public void mechanismChanged(InvocationMechanism im);
+
+ /**
+ * Get the directory where the invocation information will be/is saved to.
+ */
+ public File getInvocationManagerDirectory();
+
+ public void saveConfiguration();
+
+ public void groupChanged(InvocationGroup group);
+
+ public void addObserver(Observer<InvocationManagerEvent> observer);
+
+ public List<Observer<InvocationManagerEvent>> getObservers();
+
+ public void removeObserver(Observer<InvocationManagerEvent> observer);
+
+ public void deleteRun(String runId);
+
+ public void persistInvocations();
+
+ public void loadInvocations();
+
+ public boolean containsMechanism(InvocationMechanism invocationMechanism);
+
+ public InvocationGroup getGroupReplacement(InvocationGroup group);
+
+ public InvocationMechanism getMechanismReplacement(String invocationMechanismSpecification);
+
+ public InvocationGroup getImportedGroup(String groupSpecification);
+
+ public InvocationMechanism getImportedMechanism(String mechanismSpecification);
+
+ public void importMechanism(String invocationMechanismSpecification,
+ InvocationMechanism createdMechanism);
+
+ public void importInvocationGroup(String invocationGroupSpecification,
+ InvocationGroup invocationGroup);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupRemovedEvent.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupRemovedEvent.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupRemovedEvent.java
new file mode 100644
index 0000000..da14f7b
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationGroupRemovedEvent.java
@@ -0,0 +1,24 @@
+package net.sf.taverna.t2.activities.externaltool.manager;
+
+public class InvocationGroupRemovedEvent extends InvocationManagerEvent {
+
+ private InvocationGroup removedGroup;
+ private final InvocationGroup replacementGroup;
+
+ public InvocationGroupRemovedEvent(InvocationGroup removedGroup, InvocationGroup replacementGroup) {
+ this.removedGroup = removedGroup;
+ this.replacementGroup = replacementGroup;
+ }
+
+ /**
+ * @return the removedGroup
+ */
+ public InvocationGroup getRemovedGroup() {
+ return removedGroup;
+ }
+
+ public InvocationGroup getReplacementGroup() {
+ return replacementGroup;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationManagerEvent.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationManagerEvent.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationManagerEvent.java
new file mode 100644
index 0000000..146e2df
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationManagerEvent.java
@@ -0,0 +1,5 @@
+package net.sf.taverna.t2.activities.externaltool.manager;
+
+public abstract class InvocationManagerEvent {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanism.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanism.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanism.java
new file mode 100644
index 0000000..ada8e6d
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanism.java
@@ -0,0 +1,60 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.activities.externaltool.manager;
+
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.XMLOutputter;
+
+/**
+ * @author alanrw
+ *
+ */
+public abstract class InvocationMechanism {
+
+ protected static XMLOutputter outputter = new XMLOutputter();
+
+
+ public static String UNIX_SHELL = "/bin/sh -c";
+
+ public static String UNIX_LINK = "/bin/ln -s %%PATH_TO_ORIGINAL%% %%TARGET_NAME%%";
+
+ public static String UNIX_COPY = "/bin/cp %%PATH_TO_ORIGINAL%% %%TARGET_NAME%%";
+
+
+ private String name;
+
+ public final String getXML() {
+ Document document = new Document(getXMLElement());
+ String result = null;
+ synchronized (outputter) {
+ result = outputter.outputString(document);
+ }
+ return result;
+ }
+
+ public abstract Element getXMLElement();
+
+ public abstract String getType();
+
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name the name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String toString() {
+ return getName();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanismAddedEvent.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanismAddedEvent.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanismAddedEvent.java
new file mode 100644
index 0000000..2babb1e
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanismAddedEvent.java
@@ -0,0 +1,18 @@
+package net.sf.taverna.t2.activities.externaltool.manager;
+
+public class InvocationMechanismAddedEvent extends InvocationManagerEvent {
+
+ private InvocationMechanism addedMechanism;
+
+ public InvocationMechanismAddedEvent(InvocationMechanism addedMechanism) {
+ this.addedMechanism = addedMechanism;
+ }
+
+ /**
+ * @return the addeMechanism
+ */
+ public InvocationMechanism getAddedMechanism() {
+ return addedMechanism;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanismChangedEvent.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanismChangedEvent.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanismChangedEvent.java
new file mode 100644
index 0000000..7b26bcd
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanismChangedEvent.java
@@ -0,0 +1,18 @@
+package net.sf.taverna.t2.activities.externaltool.manager;
+
+public class InvocationMechanismChangedEvent extends InvocationManagerEvent {
+
+ private InvocationMechanism changedMechanism;
+
+ public InvocationMechanismChangedEvent(InvocationMechanism changedMechanism) {
+ this.changedMechanism = changedMechanism;
+ }
+
+ /**
+ * @return the changedMechanism
+ */
+ public InvocationMechanism getChangedMechanism() {
+ return changedMechanism;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanismRemovedEvent.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanismRemovedEvent.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanismRemovedEvent.java
new file mode 100644
index 0000000..d7c5878
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationMechanismRemovedEvent.java
@@ -0,0 +1,24 @@
+package net.sf.taverna.t2.activities.externaltool.manager;
+
+public class InvocationMechanismRemovedEvent extends InvocationManagerEvent {
+
+ private InvocationMechanism removedMechanism;
+ private final InvocationMechanism replacementMechanism;
+
+ public InvocationMechanismRemovedEvent(InvocationMechanism removedMechanism, InvocationMechanism replacementMechanism) {
+ this.removedMechanism = removedMechanism;
+ this.replacementMechanism = replacementMechanism;
+ }
+
+ /**
+ * @return the addeMechanism
+ */
+ public InvocationMechanism getRemovedMechanism() {
+ return removedMechanism;
+ }
+
+ public InvocationMechanism getReplacementMechanism() {
+ return replacementMechanism;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationPersister.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationPersister.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationPersister.java
new file mode 100644
index 0000000..d345595
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/InvocationPersister.java
@@ -0,0 +1,20 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.activities.externaltool.manager;
+
+import java.io.File;
+
+/**
+ * @author alanrw
+ *
+ */
+public abstract class InvocationPersister {
+
+ public abstract void persist(File directory);
+
+ public abstract void load(File directory);
+
+ public abstract void deleteRun(String runId);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/6bc470a3/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/MechanismCreator.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/MechanismCreator.java b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/MechanismCreator.java
new file mode 100644
index 0000000..81ef1fb
--- /dev/null
+++ b/taverna-external-tool-activity/src/main/java/net/sf/taverna/t2/activities/externaltool/manager/MechanismCreator.java
@@ -0,0 +1,49 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.activities.externaltool.manager;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import org.apache.log4j.Logger;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+
+/**
+ * @author alanrw
+ *
+ */
+public abstract class MechanismCreator {
+
+ private static SAXBuilder builder = new SAXBuilder();
+
+ private static Logger logger = Logger.getLogger(MechanismCreator.class);
+
+ public abstract boolean canHandle(String mechanismType);
+
+ public InvocationMechanism convert(String xml, String name) {
+
+ Document document;
+ try {
+ synchronized (builder) {
+ document = builder.build(new StringReader(xml));
+ }
+ } catch (JDOMException e1) {
+ logger.error("Null invocation", e1);
+ return null;
+ } catch (IOException e1) {
+ logger.error("Null invocation", e1);
+ return null;
+ }
+ Element top = document.getRootElement();
+
+ return convert(top, name);
+ }
+
+ public abstract InvocationMechanism convert(Element detailsElement,
+ String mechanismName);
+
+}