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/27 17:22:32 UTC

[19/23] incubator-taverna-workbench-common-activities git commit:

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/StringReplacementPanel.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/StringReplacementPanel.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/StringReplacementPanel.java
deleted file mode 100644
index 1f85d3a..0000000
--- a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/StringReplacementPanel.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/**
- * 
- */
-package net.sf.taverna.t2.activities.externaltool.views;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.awt.event.ActionEvent;
-import java.util.List;
-
-import javax.swing.AbstractAction;
-import javax.swing.BorderFactory;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
-import javax.swing.JTextField;
-import javax.swing.border.CompoundBorder;
-import javax.swing.border.EmptyBorder;
-
-import net.sf.taverna.t2.activities.externaltool.manager.ssh.ExternalToolSshNodeViewer;
-import net.sf.taverna.t2.activities.externaltool.utils.Tools;
-import net.sf.taverna.t2.lang.ui.DeselectingButton;
-
-/**
- * @author alanrw
- *
- */
-public class StringReplacementPanel extends JPanel {
-	
-	private static final String STRING_REPLACEMENT_DESCRIPTION = "You can use a string replacement to " +
-	"feed data into the service via an input port and have that data replace part of the " +
-	"command.";
-	private final List<ExternalToolStringReplacementViewer> stringReplacementViewList;
-	private int stringReplacementGridy = 1;
-	private final ExternalToolConfigView view;
-	
-	private static Insets insets = new Insets(1,5,1,5);
-	
-	private static String[] elementLabels = new String[] {"Taverna port name", "Replace port name", "String to replace"};
-	
-	private static CompoundBorder border = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5,5,5,5), BorderFactory.createLineBorder(Color.BLACK, 1));
-
-	
-	public StringReplacementPanel(final ExternalToolConfigView view, final List<ExternalToolStringReplacementViewer> stringReplacementViewList) {
-		super(new BorderLayout());
-		this.view = view;
-		this.stringReplacementViewList = stringReplacementViewList;
-
-		final JPanel inputEditPanel = new JPanel(new GridBagLayout());
-
-		final GridBagConstraints inputConstraint = new GridBagConstraints();
-
-		inputConstraint.anchor = GridBagConstraints.FIRST_LINE_START;
-		inputConstraint.gridx = 0;
-		inputConstraint.gridy = 0;
-		inputConstraint.weightx = 0.1;
-		inputConstraint.fill = GridBagConstraints.BOTH;
-
-		inputConstraint.gridx = 0;
-		synchronized (stringReplacementViewList) {
-			for (ExternalToolStringReplacementViewer inputView : stringReplacementViewList) {
-				addStringReplacementViewer(this, inputEditPanel,
-						inputView, elementLabels);
-
-			}
-		}
-
-		JTextArea descriptionText = new JTextArea(
-				STRING_REPLACEMENT_DESCRIPTION);
-		descriptionText.setEditable(false);
-		descriptionText.setFocusable(false);
-		descriptionText.setBorder(new EmptyBorder(5, 5, 10, 5));
-		descriptionText.setLineWrap(true);
-		descriptionText.setWrapStyleWord(true);
-
-		this.add(descriptionText, BorderLayout.NORTH);
-		this.add(new JScrollPane(inputEditPanel),
-				BorderLayout.CENTER);
-		JButton addInputPortButton = new DeselectingButton("Add string replacement",
-				new AbstractAction() {
-
-			public void actionPerformed(ActionEvent e) {
-
-				int portNumber = 1;
-				String name2 = "in" + portNumber++;
-				boolean nameExists = true;
-				while (nameExists == true) {
-					nameExists = view.portNameExists(name2);
-					if (nameExists) {
-						name2 = "in" + portNumber++;
-					}
-				}
-
-				ExternalToolStringReplacementViewer newViewer = new ExternalToolStringReplacementViewer(
-						name2);
-				synchronized (stringReplacementViewList) {
-					stringReplacementViewList.add(newViewer);
-					addStringReplacementViewer(StringReplacementPanel.this, inputEditPanel,
-							newViewer, elementLabels);
-					inputEditPanel.revalidate();
-					inputEditPanel.repaint();
-				}
-
-			}
-
-		});
-
-		JPanel buttonPanel = new JPanel();
-		buttonPanel.setLayout(new BorderLayout());
-
-		buttonPanel.add(addInputPortButton, BorderLayout.EAST);
-
-		this.add(buttonPanel, BorderLayout.SOUTH);
-	}
-	
-	private void addStringReplacementViewer(final JPanel outerPanel,
-			final JPanel innerPanel, final ExternalToolStringReplacementViewer viewer, String[] elementLabels) {
-		Tools.addViewer(innerPanel,
-				elementLabels,
-				new JComponent[] {viewer.getNameField(), viewer.getValueFromField(), viewer.getValueField()},
-				stringReplacementViewList,
-				viewer,
-				outerPanel);
-	}
-
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ToolXMLPanel.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ToolXMLPanel.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ToolXMLPanel.java
deleted file mode 100644
index b49211f..0000000
--- a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ToolXMLPanel.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * 
- */
-package net.sf.taverna.t2.activities.externaltool.views;
-
-import java.awt.BorderLayout;
-
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-
-import net.sf.taverna.t2.renderers.impl.XMLTree;
-
-import de.uni_luebeck.inb.knowarc.usecases.UseCaseDescription;
-
-/**
- * @author alanrw
- *
- */
-public class ToolXMLPanel extends JPanel {
-
-	public ToolXMLPanel(UseCaseDescription useCaseDescription) {
-		super(new BorderLayout());
-		XMLTree xmlTree = new XMLTree(useCaseDescription.writeToXMLElement());
-		this.add(new JScrollPane(xmlTree), BorderLayout.CENTER);
-	}
-
-	public void regenerateTree(UseCaseDescription useCaseDescription) {
-		this.removeAll();
-		XMLTree xmlTree = new XMLTree(useCaseDescription.writeToXMLElement());
-		this.add(new JScrollPane(xmlTree), BorderLayout.CENTER);		
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/actions/ExternalToolActivityConfigureAction.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/actions/ExternalToolActivityConfigureAction.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/actions/ExternalToolActivityConfigureAction.java
new file mode 100644
index 0000000..2e8d981
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/actions/ExternalToolActivityConfigureAction.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (C) 2009 Hajo Nils Krabbenhoeft, INB, University of Luebeck
+ * modified 2010 Hajo Nils Krabbenhoeft, spratpix GmbH & Co. KG
+ *
+ *  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 org.apache.taverna.activities.externaltool.actions;
+
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+
+import javax.swing.Action;
+
+import org.apache.taverna.activities.externaltool.ExternalToolActivity;
+import org.apache.taverna.activities.externaltool.ExternalToolActivityConfigurationBean;
+import org.apache.taverna.activities.externaltool.views.ExternalToolConfigView;
+import org.apache.taverna.workbench.activityicons.ActivityIconManager;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.ui.actions.activity.ActivityConfigurationAction;
+import org.apache.taverna.workbench.ui.views.contextualviews.activity.ActivityConfigurationDialog;
+
+/**
+ * This class implements an ActivityConfigurationAction to configure the ExternalToolActivity
+ * plugin. The configuration action is called "Configure UseCase invocation" and is implemented in
+ * the KnowARCConfigurationDialog inside the knowarc-usecases maven artifact.
+ *
+ * @author Hajo Nils Krabbenhoeft
+ */
+@SuppressWarnings("serial")
+public class ExternalToolActivityConfigureAction extends
+		ActivityConfigurationAction {// <ExternalToolActivity, ExternalToolActivityConfigurationBean> {
+
+	private final Frame owner;
+	private final EditManager editManager;
+	private final FileManager fileManager;
+
+	public ExternalToolActivityConfigureAction(ExternalToolActivity activity, Frame owner,
+			EditManager editManager, FileManager fileManager, ActivityIconManager activityIconManager) {
+		super(activity, activityIconManager);
+		this.editManager = editManager;
+		this.fileManager = fileManager;
+		putValue(Action.NAME, "Configure tool invocation");
+		this.owner = owner;
+	}
+
+	public void actionPerformed(ActionEvent e) {
+		/*
+		 * if (getActivity().getConfiguration() instanceof
+		 * RegisteredExternalToolActivityConfigurationBean) { new KnowARCConfigurationDialog(owner,
+		 * false, KnowARCConfigurationFactory.getConfiguration()).setVisible(true); } else
+		 */{
+			ActivityConfigurationDialog currentDialog = ActivityConfigurationAction
+					.getDialog(getActivity());
+			if (currentDialog != null) {
+				currentDialog.toFront();
+				return;
+			}
+			final ExternalToolConfigView externalToolConfigView = new ExternalToolConfigView(
+					(ExternalToolActivity) getActivity());
+			final ActivityConfigurationDialog<ExternalToolActivity, ExternalToolActivityConfigurationBean> dialog = new ActivityConfigurationDialog<ExternalToolActivity, ExternalToolActivityConfigurationBean>(
+					getActivity(), externalToolConfigView, editManager, fileManager);
+
+			ActivityConfigurationAction.setDialog(getActivity(), dialog, fileManager);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/configuration/ToolInvocationConfiguration.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/configuration/ToolInvocationConfiguration.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/configuration/ToolInvocationConfiguration.java
new file mode 100644
index 0000000..67f8f4b
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/configuration/ToolInvocationConfiguration.java
@@ -0,0 +1,57 @@
+/**
+ *
+ */
+package org.apache.taverna.activities.externaltool.configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import uk.org.taverna.configuration.AbstractConfigurable;
+
+
+/**
+ * @author alanrw
+ *
+ */
+public class ToolInvocationConfiguration extends AbstractConfigurable {
+
+	private static ToolInvocationConfiguration instance;
+
+	private Map<String, String> defaultPropertyMap;
+
+	public static ToolInvocationConfiguration getInstance() {
+		if (instance == null) {
+			instance = new ToolInvocationConfiguration();
+		}
+		return instance;
+	}
+
+	@Override
+	public String getCategory() {
+		return "general";
+	}
+
+	@Override
+	public Map<String, String> getDefaultPropertyMap() {
+		if (defaultPropertyMap == null) {
+			defaultPropertyMap = new HashMap<String, String>();
+		}
+		return defaultPropertyMap;
+	}
+
+	@Override
+	public String getDisplayName() {
+		return "Tool invocation";
+	}
+
+	@Override
+	public String getFilePrefix() {
+		return "ToolInvocation";
+	}
+
+	@Override
+	public String getUUID() {
+		return "B611F5C2-EB49-479E-B01A-7F3F56E6918A";
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/GroupPanel.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/GroupPanel.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/GroupPanel.java
new file mode 100644
index 0000000..46710e1
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/GroupPanel.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package org.apache.taverna.activities.externaltool.manager;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.border.EmptyBorder;
+import org.apache.taverna.activities.externaltool.manager.InvocationGroupManager;
+import org.apache.taverna.activities.externaltool.manager.InvocationMechanism;
+
+import org.apache.taverna.activities.externaltool.manager.impl.InvocationGroupManagerImpl;
+
+/**
+ * UI for creating/editing dataflow input ports.
+ *
+ * @author David Withers
+ */
+public class GroupPanel extends JPanel {
+
+	private static final long serialVersionUID = 1L;
+
+	private JTextField groupNameField;
+
+	private JComboBox mechanismComboBox;
+
+	private static InvocationGroupManager manager = InvocationGroupManagerImpl.getInstance();
+
+	public GroupPanel(Object[] mechanisms) {
+		super(new GridBagLayout());
+
+		groupNameField = new JTextField();
+
+
+		setBorder(new EmptyBorder(10, 10, 10, 10));
+
+		GridBagConstraints constraints = new GridBagConstraints();
+
+		constraints.anchor = GridBagConstraints.WEST;
+		constraints.gridx = 0;
+		constraints.gridy = 0;
+		constraints.ipadx = 10;
+		add(new JLabel("Name:"), constraints);
+
+		constraints.gridx = 1;
+		constraints.gridwidth = 2;
+		constraints.ipadx = 0;
+		constraints.weightx = 1d;
+		constraints.fill = GridBagConstraints.HORIZONTAL;
+		add(groupNameField, constraints);
+
+		constraints.gridx = 0;
+		constraints.gridy = 1;
+		constraints.gridwidth = 1;
+		constraints.weightx = 0d;
+		constraints.fill = GridBagConstraints.NONE;
+		constraints.ipadx = 10;
+		constraints.insets = new Insets(10, 0, 0, 0);
+		add(new JLabel("Explicit location:"), constraints);
+
+		mechanismComboBox = new JComboBox(mechanisms);
+		mechanismComboBox.setSelectedItem(manager.getDefaultMechanism());
+
+		constraints.gridx = 1;
+		constraints.gridwidth = 2;
+		constraints.ipadx = 0;
+		add(mechanismComboBox, constraints);
+	}
+
+	/**
+	 * Returns the portNameField.
+	 *
+	 * @return the portNameField
+	 */
+	public JTextField getGroupNameField() {
+		return groupNameField;
+	}
+
+	/**
+	 * Returns the group name.
+	 *
+	 * @return the group name
+	 */
+	public String getGroupName() {
+		return groupNameField.getText();
+	}
+
+	public InvocationMechanism getSelectedMechanism() {
+		return (InvocationMechanism) mechanismComboBox.getSelectedItem();
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/InvocationGroupManagerShutdownHook.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/InvocationGroupManagerShutdownHook.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/InvocationGroupManagerShutdownHook.java
new file mode 100644
index 0000000..c3fd2e2
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/InvocationGroupManagerShutdownHook.java
@@ -0,0 +1,34 @@
+/**
+ * 
+ */
+package org.apache.taverna.activities.externaltool.manager;
+
+import net.sf.taverna.t2.activities.externaltool.manager.impl.InvocationGroupManagerImpl;
+import org.apache.taverna.workbench.ShutdownSPI;
+
+/**
+ * @author alanrw
+ *
+ */
+public class InvocationGroupManagerShutdownHook implements ShutdownSPI {
+
+	/* (non-Javadoc)
+	 * @see net.sf.taverna.t2.workbench.ShutdownSPI#positionHint()
+	 */
+	@Override
+	public int positionHint() {
+		return 710;
+	}
+
+	/* (non-Javadoc)
+	 * @see net.sf.taverna.t2.workbench.ShutdownSPI#shutdown()
+	 */
+	@Override
+	public boolean shutdown() {
+		InvocationGroupManager manager = InvocationGroupManagerImpl.getInstance();
+		manager.saveConfiguration();
+		manager.persistInvocations();
+		return true;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/InvocationGroupManagerStartupHook.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/InvocationGroupManagerStartupHook.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/InvocationGroupManagerStartupHook.java
new file mode 100644
index 0000000..5e03bf7
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/InvocationGroupManagerStartupHook.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (C) 2010 The University of Manchester   
+ * 
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ * 
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *    
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *    
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package org.apache.taverna.activities.externaltool.manager;
+
+import org.apache.taverna.activities.externaltool.manager.impl.InvocationGroupManagerImpl;
+import org.apache.taverna.workbench.StartupSPI;
+
+/**
+ * Load previously saved workflow ids that were scheduled to be deleted before
+ * previous Taverna shutdown, and initiate deletion of them now.
+ * 
+ * @see StoreRunIdsToDeleteLaterShutdownHook
+ * @see DatabaseCleanup
+ * 
+ * @author Stian Soiland-Reyes
+ * 
+ */
+public class InvocationGroupManagerStartupHook implements StartupSPI {
+
+	public int positionHint() {
+		return 900;
+	}
+
+	public boolean startup() {
+		InvocationGroupManagerImpl.getInstance().loadInvocations();
+		return true;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/InvocationMechanismEditor.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/InvocationMechanismEditor.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/InvocationMechanismEditor.java
new file mode 100644
index 0000000..a4affaf
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/InvocationMechanismEditor.java
@@ -0,0 +1,28 @@
+/**
+ *
+ */
+package org.apache.taverna.activities.externaltool.manager;
+
+import javax.swing.JPanel;
+
+/**
+ * @author alanrw
+ *
+ */
+public abstract class InvocationMechanismEditor<T extends InvocationMechanism> extends JPanel {
+
+	public abstract String getName();
+
+	public abstract boolean canShow(Class<?> c);
+
+	public abstract void show(T invocationMechanism);
+
+	public abstract T updateInvocationMechanism();
+
+	public abstract InvocationMechanism createMechanism(String mechanismName);
+
+	public boolean isSingleton() {
+		return false;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/MechanismPanel.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/MechanismPanel.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/MechanismPanel.java
new file mode 100644
index 0000000..7f85c68
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/MechanismPanel.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package org.apache.taverna.activities.externaltool.manager;
+
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.util.List;
+
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.border.EmptyBorder;
+
+/**
+ * UI for creating/editing dataflow input ports.
+ *
+ * @author David Withers
+ */
+public class MechanismPanel extends JPanel {
+
+	private static final long serialVersionUID = 1L;
+
+	private JTextField mechanismNameField;
+
+	private JComboBox mechanismTypeSelector;
+
+	public MechanismPanel(List<InvocationMechanismEditor<?>> invocationMechanismEditors) {
+		super(new GridBagLayout());
+
+		mechanismNameField = new JTextField();
+
+
+		setBorder(new EmptyBorder(10, 10, 10, 10));
+
+		GridBagConstraints constraints = new GridBagConstraints();
+
+		constraints.anchor = GridBagConstraints.WEST;
+		constraints.gridx = 0;
+		constraints.gridy = 0;
+		constraints.ipadx = 10;
+		add(new JLabel("Name:"), constraints);
+
+		constraints.gridx = 1;
+		constraints.gridwidth = 2;
+		constraints.ipadx = 0;
+		constraints.weightx = 1d;
+		constraints.fill = GridBagConstraints.HORIZONTAL;
+		add(mechanismNameField, constraints);
+
+		constraints.gridx = 0;
+		constraints.gridy = 1;
+		constraints.gridwidth = 1;
+		constraints.weightx = 0d;
+		constraints.fill = GridBagConstraints.NONE;
+		constraints.ipadx = 10;
+		constraints.insets = new Insets(10, 0, 0, 0);
+		add(new JLabel("Type:"), constraints);
+
+		mechanismTypeSelector = new JComboBox();
+		for (InvocationMechanismEditor<?> ime : invocationMechanismEditors) {
+			if (!ime.isSingleton()) {
+				mechanismTypeSelector.addItem(ime.getName());
+			}
+		}
+		constraints.gridx = 1;
+		constraints.gridwidth = 2;
+		constraints.ipadx = 0;
+		add(mechanismTypeSelector, constraints);
+
+
+	}
+
+	/**
+	 * Returns the portNameField.
+	 *
+	 * @return the portNameField
+	 */
+	public JTextField getMechanismNameField() {
+		return mechanismNameField;
+	}
+
+	/**
+	 * Returns the port name.
+	 *
+	 * @return the port name
+	 */
+	public String getMechanismName() {
+		return mechanismNameField.getText();
+	}
+
+	public String getMechanismTypeName() {
+		return (String) mechanismTypeSelector.getSelectedItem();
+	}
+
+	public Component getMechanismTypeSelector() {
+		return mechanismTypeSelector;
+	}
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ToolInvocationConfigurationPanel.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ToolInvocationConfigurationPanel.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ToolInvocationConfigurationPanel.java
new file mode 100644
index 0000000..cabd832
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ToolInvocationConfigurationPanel.java
@@ -0,0 +1,383 @@
+/**
+ *
+ */
+package org.apache.taverna.activities.externaltool.manager;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.AbstractAction;
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.DefaultListModel;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingUtilities;
+import javax.swing.border.EmptyBorder;
+import org.apache.taverna.activities.externaltool.manager.InvocationGroup;
+import org.apache.taverna.activities.externaltool.manager.InvocationManagerEvent;
+import org.apache.taverna.activities.externaltool.manager.InvocationMechanism;
+import org.apache.taverna.activities.externaltool.manager.MechanismCreator;
+
+import org.apache.taverna.activities.externaltool.manager.impl.InvocationGroupManagerImpl;
+import org.apache.taverna.lang.observer.Observable;
+import org.apache.taverna.lang.observer.Observer;
+import org.apache.taverna.lang.ui.DeselectingButton;
+import org.apache.taverna.lang.ui.ValidatingUserInputDialog;
+import org.apache.taverna.workbench.helper.Helper;
+
+/**
+ * @author alanrw
+ *
+ */
+public class ToolInvocationConfigurationPanel extends JPanel implements
+		Observer<InvocationManagerEvent> {
+
+	public static final String HEADER_TEXT = "A tool can be set to run at an explicit location (e.g. on a specificic machine or one of a set of machines). Alternatively, it can be set to run at a symbolic location, which means the tool will then be run at the explicit location pointed to by the symbolic location.";
+
+	private static InvocationGroupManagerImpl manager = InvocationGroupManagerImpl.getInstance();
+
+	private final List<InvocationMechanismEditor<?>> invocationMechanismEditors;
+
+	private JTextArea headerText;
+
+	private static String EXPLICIT_LOCATIONS = "explicit locations";
+	private static String SYMBOLIC_LOCATIONS = "symbolic locations";
+
+	private List<MechanismCreator> mechanismCreators;
+
+	JList locationList = new JList();
+
+	DefaultListModel groupListModel = new DefaultListModel();
+	DefaultListModel mechanismListModel = new DefaultListModel();
+	JComboBox locationTypeCombo = new JComboBox(new String[] { EXPLICIT_LOCATIONS,
+			SYMBOLIC_LOCATIONS });
+
+	public ToolInvocationConfigurationPanel(List<MechanismCreator> mechanismCreators,
+			List<InvocationMechanismEditor<?>> invocationMechanismEditors) {
+		super();
+		this.mechanismCreators = mechanismCreators;
+		this.invocationMechanismEditors = invocationMechanismEditors;
+		manager.addObserver(this);
+
+		this.setLayout(new GridBagLayout());
+		GridBagConstraints gbc = new GridBagConstraints();
+
+		headerText = new JTextArea(HEADER_TEXT);
+		headerText.setLineWrap(true);
+		headerText.setWrapStyleWord(true);
+		headerText.setEditable(false);
+		headerText.setFocusable(false);
+		headerText.setBorder(new EmptyBorder(10, 10, 10, 10));
+
+		gbc.anchor = GridBagConstraints.WEST;
+		gbc.insets = new Insets(0, 0, 10, 0);
+		gbc.gridx = 0;
+		gbc.gridy = 0;
+		gbc.gridwidth = 1;
+		gbc.weightx = 1.0;
+		gbc.weighty = 0.0;
+		gbc.fill = GridBagConstraints.HORIZONTAL;
+		add(headerText, gbc);
+
+		JPanel locationPanel = new JPanel(new BorderLayout());
+		JPanel subPanel = new JPanel(new FlowLayout());
+		JLabel modify = new JLabel("Modify:");
+
+		locationTypeCombo.setSelectedItem(EXPLICIT_LOCATIONS);
+		locationTypeCombo.addActionListener(new ActionListener() {
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				switchList();
+			}
+		});
+		subPanel.add(modify);
+		subPanel.add(locationTypeCombo);
+
+		populateLists();
+		switchList();
+		locationList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+		locationList.setCellRenderer(new DefaultListCellRenderer() {
+			public Component getListCellRendererComponent(JList list, Object value, int index,
+					boolean isSelected, boolean cellHasFocus) {
+				Object toShow = value;
+				if (value instanceof InvocationGroup) {
+					InvocationGroup invocationGroup = (InvocationGroup) value;
+					toShow = invocationGroup.getName() + "  -->  "
+							+ invocationGroup.getMechanismName();
+				}
+				return super.getListCellRendererComponent(list, toShow, index, isSelected,
+						cellHasFocus);
+			}
+		});
+		locationPanel.add(new JScrollPane(locationList), BorderLayout.CENTER);
+		locationPanel.add(subPanel, BorderLayout.NORTH);
+
+		JPanel buttonPanel = new JPanel(new FlowLayout());
+		JButton helpButton = new DeselectingButton("Help", new AbstractAction() {
+
+			public void actionPerformed(ActionEvent e) {
+				Helper.showHelp(ToolInvocationConfigurationPanel.this);
+			}
+		});
+
+		buttonPanel.add(helpButton);
+
+		buttonPanel.add(addLocationButton());
+		buttonPanel.add(removeLocationButton());
+		buttonPanel.add(editLocationButton());
+		locationPanel.add(buttonPanel, BorderLayout.SOUTH);
+
+		gbc.gridy++;
+		gbc.weighty = 1;
+
+		gbc.fill = GridBagConstraints.BOTH;
+		gbc.anchor = GridBagConstraints.SOUTH;
+		gbc.insets = new Insets(10, 0, 0, 0);
+		this.add(locationPanel, gbc);
+	}
+
+	private void switchList() {
+		if (isShowingGroups()) {
+			locationList.setModel(groupListModel);
+		} else {
+			locationList.setModel(mechanismListModel);
+		}
+	}
+
+	private void populateLists() {
+		poopulateGroupList();
+		populateMechanismList();
+	}
+
+	private void populateMechanismList() {
+		Object currentSelection = locationList.getSelectedValue();
+		ArrayList<InvocationMechanism> mechanisms = new ArrayList<InvocationMechanism>();
+		mechanisms.addAll(manager.getMechanisms());
+		Collections.sort(mechanisms, new Comparator<InvocationMechanism>() {
+
+			@Override
+			public int compare(InvocationMechanism o1, InvocationMechanism o2) {
+				return o1.getName().compareTo(o2.getName());
+			}
+		});
+		mechanismListModel.clear();
+		for (InvocationMechanism m : mechanisms) {
+			mechanismListModel.addElement(m);
+		}
+		if ((currentSelection != null) && !isShowingGroups()) {
+			locationList.setSelectedValue(currentSelection, true);
+		}
+	}
+
+	private void poopulateGroupList() {
+		Object currentSelection = locationList.getSelectedValue();
+		ArrayList<InvocationGroup> groups = new ArrayList<InvocationGroup>();
+		groups.addAll(manager.getInvocationGroups());
+		Collections.sort(groups, new Comparator<InvocationGroup>() {
+
+			@Override
+			public int compare(InvocationGroup o1, InvocationGroup o2) {
+				return o1.getName().compareTo(o2.getName());
+			}
+		});
+		groupListModel.clear();
+		for (InvocationGroup g : groups) {
+			groupListModel.addElement(g);
+		}
+		if ((currentSelection != null) && isShowingGroups()) {
+			locationList.setSelectedValue(currentSelection, true);
+		}
+	}
+
+	private boolean isShowingGroups() {
+		return (locationTypeCombo.getSelectedItem().equals(SYMBOLIC_LOCATIONS));
+	}
+
+	private JButton addLocationButton() {
+		final JButton result = new DeselectingButton("Add", new AbstractAction() {
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				if (isShowingGroups()) {
+					Set<String> usedGroupNames = new HashSet<String>();
+					for (InvocationGroup g : manager.getInvocationGroups()) {
+						usedGroupNames.add(g.getName());
+					}
+
+					GroupPanel inputPanel = new GroupPanel(mechanismListModel.toArray());
+
+					ValidatingUserInputDialog vuid = new ValidatingUserInputDialog(
+							"Add symbolic location", inputPanel);
+					vuid.addTextComponentValidation(inputPanel.getGroupNameField(),
+							"Set the symbolic location name.", usedGroupNames,
+							"Duplicate symbolic location name.", "[\\p{L}\\p{Digit}_.]+",
+							"Invalid symbolic location name.");
+					vuid.setSize(new Dimension(400, 250));
+
+					if (vuid.show(ToolInvocationConfigurationPanel.this)) {
+						String groupName = inputPanel.getGroupName();
+						InvocationGroup newGroup = new InvocationGroup(mechanismCreators);
+						newGroup.setName(groupName);
+						newGroup.setMechanism(inputPanel.getSelectedMechanism());
+						manager.addInvocationGroup(newGroup);
+						locationList.setSelectedValue(newGroup, true);
+					}
+				} else {
+					Set<String> usedNames = new HashSet<String>();
+					for (InvocationMechanism m : manager.getMechanisms()) {
+						usedNames.add(m.getName());
+					}
+
+					MechanismPanel inputPanel = new MechanismPanel(invocationMechanismEditors);
+
+					ValidatingUserInputDialog vuid = new ValidatingUserInputDialog(
+							"Add explicit location", inputPanel);
+					vuid.addTextComponentValidation(inputPanel.getMechanismNameField(),
+							"Set the explicit location name.", usedNames,
+							"Duplicate explicit location name.", "[\\p{L}\\p{Digit}_.]+",
+							"Invalid explicit location name.");
+					vuid.addMessageComponent(inputPanel.getMechanismTypeSelector(),
+							"Set the location name and type.");
+					vuid.setSize(new Dimension(400, 250));
+
+					if (vuid.show(ToolInvocationConfigurationPanel.this)) {
+						String mechanismName = inputPanel.getMechanismName();
+						String mechanismTypeName = inputPanel.getMechanismTypeName();
+						InvocationMechanismEditor ime = findEditor(mechanismTypeName);
+						InvocationMechanism newMechanism = ime.createMechanism(mechanismName);
+						manager.addMechanism(newMechanism);
+						ime.show(newMechanism);
+						ime.setPreferredSize(new Dimension(550, 500));
+						int answer = JOptionPane.showConfirmDialog(
+								ToolInvocationConfigurationPanel.this, ime,
+								"New explicit location", JOptionPane.OK_CANCEL_OPTION,
+								JOptionPane.PLAIN_MESSAGE, null);
+						if (answer == JOptionPane.OK_OPTION) {
+							ime.updateInvocationMechanism();
+							InvocationGroupManagerImpl.getInstance().mechanismChanged(newMechanism);
+						}
+						locationList.setSelectedValue(newMechanism, true);
+					}
+				}
+			}
+		});
+		return result;
+	}
+
+	private JButton removeLocationButton() {
+		JButton result = new DeselectingButton("Remove", new AbstractAction() {
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				if (isShowingGroups()) {
+					InvocationGroup toRemove = (InvocationGroup) locationList.getSelectedValue();
+					if ((toRemove != null) && !toRemove.equals(manager.getDefaultGroup())) {
+						manager.removeInvocationGroup(toRemove);
+					}
+					locationList.setSelectedValue(manager.getDefaultGroup(), true);
+				} else {
+					InvocationMechanism toRemove = (InvocationMechanism) locationList
+							.getSelectedValue();
+					if ((toRemove != null) && !toRemove.equals(manager.getDefaultMechanism())) {
+						manager.removeMechanism(toRemove);
+						locationList.setSelectedValue(manager.getDefaultMechanism(), true);
+					}
+				}
+			}
+		});
+		return result;
+	}
+
+	private JButton editLocationButton() {
+		final JButton result = new DeselectingButton("Edit", new AbstractAction() {
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				if (isShowingGroups()) {
+					InvocationGroup toEdit = (InvocationGroup) locationList.getSelectedValue();
+					if (toEdit != null) {
+						InvocationMechanism chosenMechanism = (InvocationMechanism) JOptionPane
+								.showInputDialog(ToolInvocationConfigurationPanel.this,
+										"Select an explicit location", "Edit symbolic location",
+										JOptionPane.PLAIN_MESSAGE, null,
+										mechanismListModel.toArray(), toEdit.getMechanism());
+						if (chosenMechanism != null) {
+							toEdit.setMechanism(chosenMechanism);
+							manager.groupChanged(toEdit);
+						}
+					}
+				} else {
+					InvocationMechanism toEdit = (InvocationMechanism) locationList
+							.getSelectedValue();
+					if (toEdit != null) {
+						InvocationMechanismEditor ime = findEditor(toEdit.getClass());
+						ime.show(toEdit);
+						ime.setPreferredSize(new Dimension(550, 500));
+						int answer = JOptionPane.showConfirmDialog(
+								ToolInvocationConfigurationPanel.this, ime,
+								"Edit explicit location", JOptionPane.OK_CANCEL_OPTION,
+								JOptionPane.PLAIN_MESSAGE, null);
+						if (answer == JOptionPane.OK_OPTION) {
+							ime.updateInvocationMechanism();
+							InvocationGroupManagerImpl.getInstance().mechanismChanged(toEdit);
+						}
+					}
+				}
+			}
+		});
+		return result;
+	}
+
+	protected InvocationMechanismEditor findEditor(String name) {
+		for (InvocationMechanismEditor ime : invocationMechanismEditors) {
+			if (ime.getName().equalsIgnoreCase(name)) {
+				return ime;
+			}
+		}
+		return null;
+	}
+
+	protected InvocationMechanismEditor findEditor(Class c) {
+		for (InvocationMechanismEditor ime : invocationMechanismEditors) {
+			if (ime.canShow(c)) {
+				return ime;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public void notify(Observable<InvocationManagerEvent> arg0, InvocationManagerEvent arg1)
+			throws Exception {
+		if (SwingUtilities.isEventDispatchThread()) {
+			populateLists();
+		} else {
+			SwingUtilities.invokeLater(new Runnable() {
+				public void run() {
+					populateLists();
+				}
+			});
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ToolInvocationConfigurationUIFactory.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ToolInvocationConfigurationUIFactory.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ToolInvocationConfigurationUIFactory.java
new file mode 100644
index 0000000..3002a35
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ToolInvocationConfigurationUIFactory.java
@@ -0,0 +1,55 @@
+/**
+ *
+ */
+package org.apache.taverna.activities.externaltool.manager;
+
+import java.util.List;
+
+import javax.swing.JPanel;
+
+import uk.org.taverna.configuration.Configurable;
+import uk.org.taverna.configuration.ConfigurationUIFactory;
+
+import org.apache.taverna.activities.externaltool.configuration.ToolInvocationConfiguration;
+import org.apache.taverna.activities.externaltool.manager.MechanismCreator;
+
+/**
+ * @author alanrw
+ *
+ */
+public class ToolInvocationConfigurationUIFactory implements ConfigurationUIFactory {
+
+	private List<MechanismCreator> mechanismCreators;
+	private List<InvocationMechanismEditor<?>> invocationMechanismEditors;
+
+	private ToolInvocationConfigurationPanel configPanel;
+
+	@Override
+	public boolean canHandle(String uuid) {
+		return uuid.equals(getConfigurable().getUUID());
+	}
+
+	@Override
+	public Configurable getConfigurable() {
+		return ToolInvocationConfiguration.getInstance();
+	}
+
+	@Override
+	public JPanel getConfigurationPanel() {
+		if (configPanel == null) {
+			configPanel = new ToolInvocationConfigurationPanel(mechanismCreators,
+					invocationMechanismEditors);
+		}
+		return configPanel;
+	}
+
+	public void setMechanismCreators(List<MechanismCreator> mechanismCreators) {
+		this.mechanismCreators = mechanismCreators;
+	}
+
+	public void setInvocationMechanismEditors(
+			List<InvocationMechanismEditor<?>> invocationMechanismEditors) {
+		this.invocationMechanismEditors = invocationMechanismEditors;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/local/LocalInvocationMechanismEditor.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/local/LocalInvocationMechanismEditor.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/local/LocalInvocationMechanismEditor.java
new file mode 100644
index 0000000..70918f5
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/local/LocalInvocationMechanismEditor.java
@@ -0,0 +1,122 @@
+/**
+ * 
+ */
+package org.apache.taverna.activities.externaltool.manager.local;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import org.apache.taverna.activities.externaltool.local.ExternalToolLocalInvocationMechanism;
+import org.apache.taverna.activities.externaltool.manager.InvocationMechanism;
+import org.apache.taverna.activities.externaltool.manager.InvocationMechanismEditor;
+
+/**
+ * @author alanrw
+ *
+ */
+public final class LocalInvocationMechanismEditor extends
+		InvocationMechanismEditor<ExternalToolLocalInvocationMechanism> {
+
+	private ExternalToolLocalInvocationMechanism invocationMechanism;
+	
+	private JTextField directoryField = new JTextField(30);
+	
+	private JTextField shellPrefixField = new JTextField(30);
+	
+	private JTextField linkCommandField = new JTextField(30);
+	
+	private JCheckBox retrieveDataField = new JCheckBox();
+	
+
+	@Override
+	public boolean canShow(Class<?> c) {
+		return ExternalToolLocalInvocationMechanism.class.isAssignableFrom(c);
+	}
+
+	@Override
+	public String getName() {
+		return ("Local");
+	}
+
+	@Override
+	public void show(ExternalToolLocalInvocationMechanism invocationMechanism) {
+		this.invocationMechanism = invocationMechanism;
+		this.removeAll();
+		final JPanel innerPanel = new JPanel(new GridBagLayout());
+		final GridBagConstraints inputConstraint = new GridBagConstraints();
+//		inputConstraint.insets = new Insets(5,5,5,5);
+		inputConstraint.anchor = GridBagConstraints.FIRST_LINE_START;
+		inputConstraint.gridx = 0;
+		inputConstraint.gridy = 0;
+		inputConstraint.weightx = 0.1;
+		inputConstraint.fill = GridBagConstraints.BOTH;
+		innerPanel.add(new JLabel("Working directory: "), inputConstraint);
+		inputConstraint.gridx++;
+		directoryField.setText(invocationMechanism.getDirectory());
+		innerPanel.add(directoryField, inputConstraint);
+		inputConstraint.gridx = 0;
+		inputConstraint.gridy++;
+		innerPanel.add(new JLabel("Shell: "), inputConstraint);
+		inputConstraint.gridx++;
+		shellPrefixField.setText(invocationMechanism.getShellPrefix());
+		innerPanel.add(shellPrefixField, inputConstraint);
+		
+		inputConstraint.gridx = 0;
+		inputConstraint.gridy++;
+		innerPanel.add(new JLabel("Link command: "), inputConstraint);
+		inputConstraint.gridx++;
+		linkCommandField.setText(invocationMechanism.getLinkCommand());
+		innerPanel.add(linkCommandField, inputConstraint);
+		
+		inputConstraint.gridx = 0;
+		inputConstraint.gridy++;
+		innerPanel.add(new JLabel("Fetch data: "), inputConstraint);
+		inputConstraint.gridx++;
+		retrieveDataField.setSelected(invocationMechanism.isRetrieveData());
+		innerPanel.add(retrieveDataField, inputConstraint);
+		
+		this.add(innerPanel);
+	}
+
+	@Override
+	public ExternalToolLocalInvocationMechanism updateInvocationMechanism() {
+		if ((directoryField.getText() == null) || (directoryField.getText().length() == 0)) {
+			invocationMechanism.setDirectory(null);
+		} else {
+			invocationMechanism.setDirectory(directoryField.getText());
+		}
+		if ((shellPrefixField.getText() == null) || (shellPrefixField.getText().length() == 0)) {
+			invocationMechanism.setShellPrefix(null);
+		} else {
+			invocationMechanism.setShellPrefix(shellPrefixField.getText());
+		}
+		if ((shellPrefixField.getText() == null) || (shellPrefixField.getText().length() == 0)) {
+			invocationMechanism.setShellPrefix(null);
+		} else {
+			invocationMechanism.setShellPrefix(shellPrefixField.getText());
+		}
+		if ((linkCommandField.getText() == null) || (linkCommandField.getText().length() == 0)) {
+			invocationMechanism.setLinkCommand(null);
+		} else {
+			invocationMechanism.setLinkCommand(linkCommandField.getText());
+		}
+		invocationMechanism.setRetrieveData(retrieveDataField.isSelected());
+		return invocationMechanism;
+	}
+
+	@Override
+	public InvocationMechanism createMechanism(String mechanismName) {
+		ExternalToolLocalInvocationMechanism result = new ExternalToolLocalInvocationMechanism();
+		result.setName(mechanismName);
+		return(result);
+	}
+
+	public boolean isSingleton() {
+		return true;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ssh/ExternalToolSshNodeViewer.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ssh/ExternalToolSshNodeViewer.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ssh/ExternalToolSshNodeViewer.java
new file mode 100644
index 0000000..676d16d
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ssh/ExternalToolSshNodeViewer.java
@@ -0,0 +1,110 @@
+/**
+ * 
+ */
+package org.apache.taverna.activities.externaltool.manager.ssh;
+
+import javax.swing.JCheckBox;
+import javax.swing.JTextField;
+
+import org.apache.taverna.activities.externaltool.manager.InvocationMechanism;
+
+import de.uni_luebeck.inb.knowarc.usecases.invocation.ssh.SshNode;
+
+
+
+/**
+ * @author alanrw
+ *
+ */
+public class ExternalToolSshNodeViewer {
+	
+	private JTextField hostnameField;
+	private JTextField portField;
+	private JTextField directoryField;
+	private JTextField linkCommandField;
+	private JTextField copyCommandField;
+	private JCheckBox retrieveDataField;
+
+	public ExternalToolSshNodeViewer(SshNode node) {
+		this();
+		hostnameField.setText(node.getHost());
+		portField.setText(Integer.toString(node.getPort()));
+		if (node.getDirectory() != null) {
+			directoryField.setText(node.getDirectory());
+		} else {
+			directoryField.setText("");
+		}
+		if (node.getLinkCommand() != null) {
+			linkCommandField.setText(node.getLinkCommand());
+		} else {
+			linkCommandField.setText("");
+		}
+		if (node.getCopyCommand() != null) {
+			copyCommandField.setText(node.getCopyCommand());
+		} else {
+			copyCommandField.setText("");
+		}
+		retrieveDataField.setSelected(node.isRetrieveData());
+	}
+
+	public ExternalToolSshNodeViewer() {
+		hostnameField = new JTextField(30);
+		hostnameField.setText(SshNode.DEFAULT_HOST);
+		portField = new JTextField(3);
+		portField.setText("" + SshNode.DEFAULT_PORT);
+		directoryField = new JTextField(30);
+		directoryField.setText(SshNode.DEFAULT_DIRECTORY);
+		linkCommandField = new JTextField(30);
+		linkCommandField.setText(InvocationMechanism.UNIX_LINK);
+		copyCommandField = new JTextField(30);
+		copyCommandField.setText(InvocationMechanism.UNIX_COPY);
+		retrieveDataField = new JCheckBox();
+	}
+
+	public JTextField getHostnameField() {
+		return hostnameField;
+	}
+
+	public JTextField getPortField() {
+		return portField;
+	}
+	
+	public JTextField getDirectoryField() {
+		return directoryField;
+	}
+
+	public JTextField getLinkCommandField() {
+		return linkCommandField;
+	}
+
+	public JTextField getCopyCommandField() {
+		return copyCommandField;
+	}
+
+	public String getHostname() {
+		return hostnameField.getText();
+	}
+
+	public int getPort() {
+		return Integer.parseInt(portField.getText());
+	}
+	
+	public String getDirectory() {
+		return directoryField.getText();
+	}
+	
+	public String getLinkCommand() {
+		return linkCommandField.getText();
+	}
+	
+	public String getCopyCommand() {
+		return copyCommandField.getText();
+	}
+
+	/**
+	 * @return the retrieveDataField
+	 */
+	public JCheckBox getRetrieveDataField() {
+		return retrieveDataField;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ssh/SshInvocationMechanismEditor.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ssh/SshInvocationMechanismEditor.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ssh/SshInvocationMechanismEditor.java
new file mode 100644
index 0000000..1fd3c2b
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/manager/ssh/SshInvocationMechanismEditor.java
@@ -0,0 +1,234 @@
+/**
+ * 
+ */
+package org.apache.taverna.activities.externaltool.manager.ssh;
+
+import java.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+import javax.swing.border.CompoundBorder;
+
+import net.sf.taverna.t2.activities.externaltool.manager.InvocationMechanism;
+import org.apache.taverna.activities.externaltool.manager.InvocationMechanismEditor;
+import net.sf.taverna.t2.activities.externaltool.ssh.ExternalToolSshInvocationMechanism;
+import net.sf.taverna.t2.lang.ui.DeselectingButton;
+import de.uni_luebeck.inb.knowarc.usecases.invocation.ssh.SshNode;
+import de.uni_luebeck.inb.knowarc.usecases.invocation.ssh.SshNodeFactory;
+
+/**
+ * @author alanrw
+ *
+ */
+public final class SshInvocationMechanismEditor extends
+		InvocationMechanismEditor<ExternalToolSshInvocationMechanism> {
+	
+	private ArrayList<ExternalToolSshNodeViewer> nodeViewers = new ArrayList<ExternalToolSshNodeViewer>();
+	private int inputGridy = 0;
+	
+	private ExternalToolSshInvocationMechanism mechanism = null;
+	
+	private static Insets insets = new Insets(1,5,1,5);
+	
+	private static CompoundBorder border = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5,5,5,5), BorderFactory.createLineBorder(Color.BLACK, 1));
+
+	@Override
+	public boolean canShow(Class<?> c) {
+		return ExternalToolSshInvocationMechanism.class.isAssignableFrom(c);
+	}
+
+	@Override
+	public void show(ExternalToolSshInvocationMechanism invocationMechanism) {
+		mechanism = invocationMechanism;
+		this.removeAll();
+		inputGridy = 1;
+		final JPanel innerPanel = new JPanel(new GridBagLayout());
+
+		final GridBagConstraints inputConstraint = new GridBagConstraints();
+		inputConstraint.anchor = GridBagConstraints.FIRST_LINE_START;
+		inputConstraint.gridx = 0;
+		inputConstraint.gridy = 0;
+		inputConstraint.weightx = 0.1;
+		inputConstraint.fill = GridBagConstraints.BOTH;
+
+		inputConstraint.gridx = 0;
+			nodeViewers.clear();
+			for (SshNode node : invocationMechanism.getNodes()) {
+				ExternalToolSshNodeViewer nodeViewer = new ExternalToolSshNodeViewer(node);
+				addNodeViewer(this, innerPanel, nodeViewer);
+			}
+
+		this.setLayout(new GridBagLayout());
+		GridBagConstraints outerPanelConstraint = new GridBagConstraints();
+		outerPanelConstraint.gridx = 0;
+		outerPanelConstraint.gridy = 0;
+		outerPanelConstraint.weightx = 0.1;
+		outerPanelConstraint.weighty = 0.1;
+		outerPanelConstraint.fill = GridBagConstraints.BOTH;
+		this.add(new JScrollPane(innerPanel),
+				outerPanelConstraint);
+		outerPanelConstraint.weighty = 0;
+		final JButton addHostButton = new DeselectingButton("Add host",
+				new AbstractAction() {
+			public void actionPerformed(ActionEvent e) {
+
+				ExternalToolSshNodeViewer newViewer = new ExternalToolSshNodeViewer();
+
+					addNodeViewer(SshInvocationMechanismEditor.this, innerPanel, newViewer);
+					innerPanel.revalidate();
+					innerPanel.repaint();
+			}
+
+		});
+		JPanel buttonPanel = new JPanel();
+		buttonPanel.setLayout(new GridBagLayout());
+
+		JPanel filler = new JPanel();
+		outerPanelConstraint.weightx = 0.1;
+		outerPanelConstraint.weighty = 0;
+		outerPanelConstraint.gridx = 0;
+		outerPanelConstraint.gridy = 0;
+
+		buttonPanel.add(filler, outerPanelConstraint);
+
+		outerPanelConstraint.weightx = 0;
+		outerPanelConstraint.weighty = 0;
+		outerPanelConstraint.gridx = 1;
+		outerPanelConstraint.gridy = 0;
+
+		buttonPanel.add(addHostButton, outerPanelConstraint);
+
+		outerPanelConstraint.weightx = 0;
+		outerPanelConstraint.weighty = 0;
+		outerPanelConstraint.gridx = 0;
+		outerPanelConstraint.gridy = 1;
+		outerPanelConstraint.fill = GridBagConstraints.BOTH;
+		this.add(buttonPanel, outerPanelConstraint);
+	}
+
+	protected void addNodeViewer(final JPanel result, final JPanel innerPanel,
+			ExternalToolSshNodeViewer viewer) {
+		final JPanel subPanel = new JPanel();
+		subPanel.setLayout(new GridBagLayout());
+		subPanel.setBorder(border);
+		final GridBagConstraints inputConstraint = new GridBagConstraints();
+		inputConstraint.insets = insets;
+		inputConstraint.anchor = GridBagConstraints.FIRST_LINE_START;
+		inputConstraint.weightx = 0.1;
+		inputConstraint.fill = GridBagConstraints.BOTH;
+
+		inputConstraint.gridy = 0 ;
+		inputConstraint.gridx = 0;
+		
+		subPanel.add(new JLabel("Host: "), inputConstraint);
+		final JTextField hostnameField = viewer.getHostnameField();
+		inputConstraint.gridx++;
+		subPanel.add(hostnameField, inputConstraint);
+
+		inputConstraint.gridy++ ;
+		inputConstraint.gridx = 0;
+		subPanel.add(new JLabel("Port: "), inputConstraint);
+		final JTextField portField = viewer.getPortField();
+		inputConstraint.gridx++;
+		subPanel.add(portField ,inputConstraint);
+		
+		inputConstraint.gridy++ ;
+		inputConstraint.gridx = 0;
+		subPanel.add(new JLabel("Working directory: "), inputConstraint);
+		final JTextField directoryField = viewer.getDirectoryField();
+		inputConstraint.gridx++;
+		subPanel.add(directoryField ,inputConstraint);
+		
+		inputConstraint.gridy++ ;
+		inputConstraint.gridx = 0;
+		subPanel.add(new JLabel("Link command: "), inputConstraint);
+		final JTextField linkCommandField = viewer.getLinkCommandField();
+		inputConstraint.gridx++;
+		subPanel.add(linkCommandField ,inputConstraint);
+
+		inputConstraint.gridy++ ;
+		inputConstraint.gridx = 0;
+		subPanel.add(new JLabel("Copy command: "), inputConstraint);
+		final JTextField copyCommandField = viewer.getCopyCommandField();
+		inputConstraint.gridx++;
+		subPanel.add(copyCommandField ,inputConstraint);
+
+		inputConstraint.gridy++ ;
+		inputConstraint.gridx = 0;
+		subPanel.add(new JLabel("Fetch data: "), inputConstraint);
+		inputConstraint.gridx++;
+		final JCheckBox retrieveDataField = viewer.getRetrieveDataField();
+		subPanel.add(retrieveDataField ,inputConstraint);
+
+		inputConstraint.gridy++ ;
+		inputConstraint.gridx = 1;
+		inputConstraint.fill = GridBagConstraints.NONE;
+		inputConstraint.anchor = GridBagConstraints.EAST;
+		final ExternalToolSshNodeViewer v = viewer;
+		final JButton removeButton = new DeselectingButton("Remove",
+				new AbstractAction() {
+
+			public void actionPerformed(ActionEvent e) {
+				synchronized(nodeViewers) {
+					nodeViewers.remove(v);
+				}
+				innerPanel.remove(subPanel);
+				innerPanel.revalidate();
+				innerPanel.repaint();
+				result.revalidate();
+				result.repaint();
+			}
+
+		});
+		subPanel.add(removeButton, inputConstraint);
+		
+		inputConstraint.gridy = ++inputGridy;
+		innerPanel.add(subPanel, inputConstraint);
+
+		nodeViewers.add(viewer);
+		inputGridy++;		
+	}
+
+	private List<SshNode> getNodeList() {
+		List<SshNode> result = new ArrayList<SshNode>();
+		for (ExternalToolSshNodeViewer viewer : nodeViewers) {
+			SshNode node = SshNodeFactory.getInstance().getSshNode(viewer.getHostname(), viewer.getPort(), viewer.getDirectory());
+			node.setLinkCommand(viewer.getLinkCommand());
+			node.setCopyCommand(viewer.getCopyCommand());
+			node.setRetrieveData(viewer.getRetrieveDataField().isSelected());
+			result.add(node);
+		}
+		return result;
+	}
+
+	@Override
+	public ExternalToolSshInvocationMechanism updateInvocationMechanism() {
+		mechanism.setNodes(getNodeList());
+		return mechanism;
+	}
+
+	@Override
+	public InvocationMechanism createMechanism(String mechanismName) {
+		ExternalToolSshInvocationMechanism result = new ExternalToolSshInvocationMechanism();
+		result.setName(mechanismName);
+		return result;
+	}
+
+	@Override
+	public String getName() {
+		return ("SSH");
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/AddExternalToolContextualMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/AddExternalToolContextualMenuAction.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/AddExternalToolContextualMenuAction.java
new file mode 100644
index 0000000..956fd16
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/AddExternalToolContextualMenuAction.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (C) 2007-2009 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 org.apache.taverna.activities.externaltool.menu;
+
+import java.awt.event.ActionEvent;
+import java.net.URI;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+
+import org.apache.taverna.activities.externaltool.ExternalToolActivity;
+import org.apache.taverna.activities.externaltool.servicedescriptions.ExternalToolTemplateServiceDescription;
+import org.apache.taverna.ui.menu.AbstractContextualMenuAction;
+import org.apache.taverna.ui.menu.MenuManager;
+import org.apache.taverna.workbench.activityicons.ActivityIconManager;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.selection.SelectionManager;
+import org.apache.taverna.workbench.ui.workflowview.WorkflowView;
+import org.apache.taverna.workflowmodel.Dataflow;
+
+import org.apache.log4j.Logger;
+
+/**
+ * An action to add an external tool + a wrapping processor to the workflow.
+ *
+ * @author Alex Nenadic
+ * @author Alan Williamns
+ *
+ */
+@SuppressWarnings("serial")
+public class AddExternalToolContextualMenuAction extends AbstractContextualMenuAction {
+
+	private static final String ADD_EXTERNAL_TOOL = "Tool";
+
+	private static final URI insertSection = URI
+			.create("http://taverna.sf.net/2009/contextMenu/insert");
+
+	private static Logger logger = Logger.getLogger(AddExternalToolMenuAction.class);
+
+	private EditManager editManager;
+
+	private MenuManager menuManager;
+
+	private SelectionManager selectionManager;
+
+	private ActivityIconManager activityIconManager;
+
+	public AddExternalToolContextualMenuAction() {
+		super(insertSection, 900);
+	}
+
+	@Override
+	public boolean isEnabled() {
+		return super.isEnabled() && getContextualSelection().getSelection() instanceof Dataflow;
+	}
+
+	@Override
+	protected Action createAction() {
+
+		return new AddExternalToolAction();
+	}
+
+	protected class AddExternalToolAction extends AbstractAction {
+		AddExternalToolAction() {
+			super(ADD_EXTERNAL_TOOL, activityIconManager.iconForActivity(
+					new ExternalToolActivity()));
+		}
+
+		public void actionPerformed(ActionEvent e) {
+			WorkflowView.importServiceDescription(
+					ExternalToolTemplateServiceDescription.getServiceDescription(), false,
+					editManager, menuManager, selectionManager);
+		}
+	}
+
+	public void setEditManager(EditManager editManager) {
+		this.editManager = editManager;
+	}
+
+	public void setMenuManager(MenuManager menuManager) {
+		this.menuManager = menuManager;
+	}
+
+	public void setSelectionManager(SelectionManager selectionManager) {
+		this.selectionManager = selectionManager;
+	}
+
+	public void setActivityIconManager(ActivityIconManager activityIconManager) {
+		this.activityIconManager = activityIconManager;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/AddExternalToolMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/AddExternalToolMenuAction.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/AddExternalToolMenuAction.java
new file mode 100644
index 0000000..2877fcb
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/AddExternalToolMenuAction.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (C) 2007-2009 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 org.apache.taverna.activities.externaltool.menu;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.net.URI;
+
+import javax.swing.Action;
+import javax.swing.KeyStroke;
+
+import org.apache.taverna.activities.externaltool.ExternalToolActivity;
+import org.apache.taverna.activities.externaltool.servicedescriptions.ExternalToolTemplateServiceDescription;
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.ui.menu.DesignOnlyAction;
+import org.apache.taverna.ui.menu.MenuManager;
+import org.apache.taverna.workbench.activityicons.ActivityIconManager;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.selection.SelectionManager;
+import org.apache.taverna.workbench.ui.workflowview.WorkflowView;
+import org.apache.taverna.workbench.views.graph.menu.InsertMenu;
+
+import org.apache.log4j.Logger;
+
+/**
+ * An action to add a externaltool activity + a wrapping processor to the workflow.
+ *
+ * @author Alex Nenadic
+ * @author alanrw
+ *
+ */
+@SuppressWarnings("serial")
+public class AddExternalToolMenuAction extends AbstractMenuAction {
+
+	private static final String ADD_EXTERNAL_TOOL = "Tool";
+
+	private static final URI ADD_EXTERNAL_TOOL_URI = URI
+	.create("http://taverna.sf.net/2008/t2workbench/menu#graphMenuAddExternalTool");
+
+	private static Logger logger = Logger
+			.getLogger(AddExternalToolMenuAction.class);
+
+	private EditManager editManager;
+	private MenuManager menuManager;
+	private SelectionManager selectionManager;
+
+	private ActivityIconManager activityIconManager;
+
+	public AddExternalToolMenuAction() {
+		super(InsertMenu.INSERT, 900, ADD_EXTERNAL_TOOL_URI);
+	}
+
+	@Override
+	protected Action createAction() {
+
+		return new AddExternalToolAction();
+	}
+
+	protected class AddExternalToolAction extends DesignOnlyAction {
+		AddExternalToolAction () {
+			super ();
+			putValue(SMALL_ICON, activityIconManager.iconForActivity(
+					new ExternalToolActivity()));
+			putValue(NAME, ADD_EXTERNAL_TOOL);
+			putValue(SHORT_DESCRIPTION, "Tool");
+			putValue(Action.ACCELERATOR_KEY,
+					KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.SHIFT_DOWN_MASK | InputEvent.ALT_DOWN_MASK));
+		}
+
+		public void actionPerformed(ActionEvent e) {
+			WorkflowView.importServiceDescription(ExternalToolTemplateServiceDescription.getServiceDescription(),
+			false, editManager, menuManager, selectionManager);
+		}
+	}
+
+	public void setEditManager(EditManager editManager) {
+		this.editManager = editManager;
+	}
+
+	public void setMenuManager(MenuManager menuManager) {
+		this.menuManager = menuManager;
+	}
+
+	public void setSelectionManager(SelectionManager selectionManager) {
+		this.selectionManager = selectionManager;
+	}
+
+	public void setActivityIconManager(ActivityIconManager activityIconManager) {
+		this.activityIconManager = activityIconManager;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/ConfigureExternalToolMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/ConfigureExternalToolMenuAction.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/ConfigureExternalToolMenuAction.java
new file mode 100644
index 0000000..5f8b1bd
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/ConfigureExternalToolMenuAction.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (C) 2010 Hajo Nils Krabbenhoeft, spratpix GmbH & Co. KG
+ *
+ *  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 org.apache.taverna.activities.externaltool.menu;
+
+import javax.swing.Action;
+
+import org.apache.taverna.activities.externaltool.ExternalToolActivity;
+import org.apache.taverna.activities.externaltool.actions.ExternalToolActivityConfigureAction;
+import org.apache.taverna.workbench.activityicons.ActivityIconManager;
+import org.apache.taverna.workbench.activitytools.AbstractConfigureActivityMenuAction;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.file.FileManager;
+
+/**
+ * This class adds the plugin configuration action to the context menu of every use case activity.
+ *
+ * @author Hajo Nils Krabbenhoeft
+ */
+public class ConfigureExternalToolMenuAction extends
+		AbstractConfigureActivityMenuAction<ExternalToolActivity> {
+
+	private EditManager editManager;
+	private FileManager fileManager;
+	private ActivityIconManager activityIconManager;
+
+	public ConfigureExternalToolMenuAction() {
+		super(ExternalToolActivity.class);
+	}
+
+	@Override
+	protected Action createAction() {
+		ExternalToolActivityConfigureAction configAction = new ExternalToolActivityConfigureAction(
+				findActivity(), getParentFrame(), editManager, fileManager, activityIconManager);
+		addMenuDots(configAction);
+		return configAction;
+	}
+
+	public void setEditManager(EditManager editManager) {
+		this.editManager = editManager;
+	}
+
+	public void setFileManager(FileManager fileManager) {
+		this.fileManager = fileManager;
+	}
+
+	public void setActivityIconManager(ActivityIconManager activityIconManager) {
+		this.activityIconManager = activityIconManager;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/FeedbackMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/FeedbackMenuAction.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/FeedbackMenuAction.java
new file mode 100644
index 0000000..e85c0e4
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/menu/FeedbackMenuAction.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (C) 2010 Hajo Nils Krabbenhoeft, spratpix GmbH & Co. KG
+ *
+ *  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 org.apache.taverna.activities.externaltool.menu;
+
+import java.awt.Desktop;
+import java.awt.event.ActionEvent;
+import java.io.IOException;
+import java.net.URI;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.Icon;
+import javax.swing.JOptionPane;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+
+import org.apache.log4j.Logger;
+
+/**
+ * This class adds the feedback item to the context menu of every use case
+ * activity.
+ *
+ * @author Hajo Nils Krabbenhoeft
+ */
+public class FeedbackMenuAction extends AbstractMenuAction {
+
+	private static Logger logger = Logger.getLogger(FeedbackMenuAction.class);
+
+
+	private static final URI feedbackSection = URI.create("http://taverna.sf.net/2009/contextMenu/configure");
+
+	public FeedbackMenuAction() {
+		super(feedbackSection, 51);
+	}
+
+	protected Action createAction() {
+	    // final ImageIcon icon = KnowARCConfigurationFactory.getConfiguration().getIcon();
+		return new SendFeedbackAction("Send Feedback...", null);
+	}
+
+	private final class SendFeedbackAction extends AbstractAction {
+		private static final long serialVersionUID = 1L;
+
+		private static final String errTitle = "Could not open web browser for feedback:";
+		private static final String feedbackUrl = "http://www.taverna.org.uk/about/contact-us/feedback?product=ExternalToolService";
+
+		private SendFeedbackAction(String name, Icon icon) {
+			super(name, icon);
+		}
+
+		public void actionPerformed(ActionEvent e) {
+			if (Desktop.isDesktopSupported()) {
+				try {
+					Desktop.getDesktop().browse(URI.create(feedbackUrl));
+				} catch (IOException e1) {
+					JOptionPane.showMessageDialog(null, feedbackUrl + "\n" + e1.getLocalizedMessage(), errTitle, JOptionPane.ERROR_MESSAGE);
+				}
+			} else {
+				JOptionPane.showMessageDialog(null, "Go to " + feedbackUrl, errTitle, JOptionPane.ERROR_MESSAGE);
+			}
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/servicedescriptions/AddExternalToolServiceDialog.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/servicedescriptions/AddExternalToolServiceDialog.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/servicedescriptions/AddExternalToolServiceDialog.java
new file mode 100644
index 0000000..88d6afe
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/servicedescriptions/AddExternalToolServiceDialog.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester   
+ * 
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ * 
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *    
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *    
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package org.apache.taverna.activities.externaltool.servicedescriptions;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.border.EmptyBorder;
+
+import org.apache.taverna.workbench.MainWindow;
+import org.apache.taverna.workbench.helper.HelpEnabledDialog;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Dialog that lets user specify a URL of a Tool service they want 
+ * to add to the Service Panel. In the case the Tool URL is behind
+ * HTTPS or service's endpoints require HTTPS it will ask user to confirm
+ * if they want to trust it. 
+ * 
+ * @author Alex Nenadic
+ *
+ */
+@SuppressWarnings("serial")
+public abstract class AddExternalToolServiceDialog extends HelpEnabledDialog {
+
+	private JTextField toolLocationField;
+	private Logger logger = Logger.getLogger(AddExternalToolServiceDialog.class);
+
+	public AddExternalToolServiceDialog()  {
+		super(MainWindow.getMainWindow(), "Add tool service", true, null); // create a non-modal dialog
+		initComponents();
+		setLocationRelativeTo(getParent());
+	}
+
+	private void initComponents() {
+		JPanel mainPanel = new JPanel(new GridBagLayout());
+		mainPanel.setBorder(new EmptyBorder(10,10,10,10));
+		
+		JLabel toolLocatitionLabel = new JLabel("Tool registry location",ExternalToolActivityIcon.getExternalToolIcon(), JLabel.LEFT);		
+		GridBagConstraints gbc = new GridBagConstraints();
+		gbc.weighty = 0.0;
+		
+		gbc.weightx = 0.0;
+		gbc.gridx = 0;
+		gbc.gridy = 0;
+		gbc.fill = GridBagConstraints.NONE;
+		gbc.anchor = GridBagConstraints.WEST;
+		gbc.insets = new Insets(5, 10, 0, 0);
+		mainPanel.add(toolLocatitionLabel, gbc);
+        
+		toolLocationField = new JTextField("http://taverna.nordugrid.org/sharedRepository/xml.php");
+		gbc.weightx = 1.0;
+		gbc.gridx = 1;
+		gbc.gridy = 0;
+		gbc.fill = GridBagConstraints.HORIZONTAL;
+		gbc.anchor = GridBagConstraints.WEST;
+		gbc.insets = new Insets(5, 10, 0, 5);		
+		mainPanel.add(toolLocationField, gbc);
+		
+	    final JButton addServiceButton = new JButton("Add");
+	    addServiceButton.addActionListener(new ActionListener()
+	        {
+	            public void actionPerformed(ActionEvent evt)
+	            {
+	                addPressed();
+	            }
+	        });
+	    
+	    // When user presses "Return" key fire the action on the "Add" button
+	    addServiceButton.addKeyListener(new java.awt.event.KeyAdapter() {
+			public void keyPressed(java.awt.event.KeyEvent evt) {
+				if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
+					addPressed();
+				}
+			}
+		});
+		getRootPane().setDefaultButton(addServiceButton);
+	    
+        JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
+        buttonsPanel.add(addServiceButton);
+        
+        getContentPane().setLayout(new BorderLayout());
+        getContentPane().add(mainPanel, BorderLayout.CENTER);
+        getContentPane().add(buttonsPanel, BorderLayout.SOUTH);
+        
+		setSize(getPreferredSize());
+        pack();
+	}
+	
+    /**
+     * 'Add service' button pressed or otherwise activated.
+     */
+    private void addPressed()
+    {
+		final String toolURLString = toolLocationField.getText().trim();
+		new Thread("Adding tool " + toolURLString) {
+			public void run() {
+				// Only add the service provider for this service if service URL
+				// starts with 'http'
+				// or if it starts with 'https' and user explicitly said they
+				// wanted to trust this service.
+				/*
+				 * if (shouldTrust(toolURLString)){ addRegistry(toolURLString);
+				 * }
+				 */
+				try {
+					URL url = new URL(toolURLString);
+					URLConnection connection = url.openConnection();
+					try {
+						// If the url starts with 'https' - security hook for
+						// https connection's trust manager
+						// will be engaged and user will be asked automatically
+						// if they want
+						// to trust the connection (if it is not already
+						// trusted). If the urls starts with 'http' -
+						// this will not have any effect apart from checking if
+						// we can open a connection.
+						connection.connect(); // if this does not fail - add the
+						// tool
+						// service provider for this service to
+						// the registry
+					} finally {
+						try {
+							connection.getInputStream().close();
+						} catch (IOException ex) {
+						}
+					}
+					addRegistry(toolURLString);
+				} catch (Exception ex) { // anything failed
+					JOptionPane.showMessageDialog(null,
+							"Could not read the tool descriptions from "
+									+ toolURLString + ":\n" + ex,
+							"Could not add tool service",
+							JOptionPane.ERROR_MESSAGE);
+
+					logger.error(
+							"Failed to add tool description provider for service: "
+									+ toolURLString, ex);
+
+				}
+			};
+		}.start();
+		closeDialog();
+    }
+
+	protected abstract void addRegistry(String tool);	
+	
+	/**
+	 * Closes the dialog.
+	 */
+	private void closeDialog() {
+		setVisible(false);
+		dispose();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/163747de/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/servicedescriptions/ExternalToolActivityIcon.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/servicedescriptions/ExternalToolActivityIcon.java b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/servicedescriptions/ExternalToolActivityIcon.java
new file mode 100644
index 0000000..214285d
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/org/apache/taverna/activities/externaltool/servicedescriptions/ExternalToolActivityIcon.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * 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 org.apache.taverna.activities.externaltool.servicedescriptions;
+
+import java.awt.Color;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+
+import org.apache.taverna.activities.externaltool.ExternalToolActivity;
+import org.apache.taverna.workbench.activityicons.ActivityIconSPI;
+import org.apache.taverna.workbench.configuration.colour.ColourManager;
+import org.apache.taverna.workflowmodel.processor.activity.Activity;
+
+/**
+ * This class provides an icon for the use case activity.
+ *
+ * @author Hajo Nils Krabbenhoeft
+ */
+public class ExternalToolActivityIcon implements ActivityIconSPI {
+
+	private static final String PROCESSOR_COLOUR_STRING = "#F28C55";
+
+	private static Icon icon;
+
+	public int canProvideIconScore(Activity<?> activity) {
+		if (activity.getClass().getName().equals(ExternalToolActivity.class.getName()))
+			return DEFAULT_ICON + 1;
+		else
+			return NO_ICON;
+	}
+
+	public Icon getIcon(Activity<?> activity) {
+		return getExternalToolIcon();
+	}
+
+	public static Icon getExternalToolIcon() {
+		if (icon == null) {
+			icon = new ImageIcon(ExternalToolActivityIcon.class.getResource("/externaltool.png"));
+		}
+		return icon;
+	}
+
+	public static String getColourString() {
+		return PROCESSOR_COLOUR_STRING;
+	}
+
+	public void setColourManager(ColourManager colourManager) {
+		// set colour for XPath processors in the workflow diagram
+		colourManager.setPreferredColour(ExternalToolActivity.class.getCanonicalName(),
+				Color.decode(PROCESSOR_COLOUR_STRING));
+	}
+
+}