You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2015/02/23 11:25:01 UTC

[14/16] incubator-taverna-workbench-common-activities git commit: Revert "Temporarily empty repository"

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/servicedescriptions/ExternalToolServiceProviderConfig.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/servicedescriptions/ExternalToolServiceProviderConfig.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/servicedescriptions/ExternalToolServiceProviderConfig.java
new file mode 100644
index 0000000..0967a6e
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/servicedescriptions/ExternalToolServiceProviderConfig.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * 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.servicedescriptions;
+
+import net.sf.taverna.t2.lang.beans.PropertyAnnotated;
+import net.sf.taverna.t2.lang.beans.PropertyAnnotation;
+
+/**
+ * ExternalToolServiceProviderConfig stores the URL of the use case repository XML file
+ * 
+ * @author Hajo Nils Krabbenhoeft
+ */
+public class ExternalToolServiceProviderConfig extends PropertyAnnotated {
+	private String repositoryUrl;
+
+	public ExternalToolServiceProviderConfig() {
+	}
+
+	public ExternalToolServiceProviderConfig(String repositoryUrl) {
+		this.repositoryUrl = repositoryUrl;
+	}
+
+	@PropertyAnnotation(displayName = "Tool registry location", preferred = true)
+	public String getRepositoryUrl() {
+		return repositoryUrl;
+	}
+
+	public void setRepositoryUrl(String repositoryUrl) {
+		this.repositoryUrl = repositoryUrl;
+	}
+
+	@Override
+	public String toString() {
+		return repositoryUrl;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/servicedescriptions/ExternalToolTemplateServiceDescription.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/servicedescriptions/ExternalToolTemplateServiceDescription.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/servicedescriptions/ExternalToolTemplateServiceDescription.java
new file mode 100644
index 0000000..30ae3eb
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/servicedescriptions/ExternalToolTemplateServiceDescription.java
@@ -0,0 +1,77 @@
+/**
+ * 
+ */
+package net.sf.taverna.t2.activities.externaltool.servicedescriptions;
+
+import java.net.URI;
+import java.util.UUID;
+
+import javax.swing.Icon;
+
+import de.uni_luebeck.inb.knowarc.usecases.UseCaseDescription;
+
+import net.sf.taverna.t2.activities.externaltool.ExternalToolActivity;
+import net.sf.taverna.t2.activities.externaltool.ExternalToolActivityConfigurationBean;
+import net.sf.taverna.t2.activities.externaltool.manager.InvocationGroupManager;
+import net.sf.taverna.t2.activities.externaltool.manager.impl.InvocationGroupManagerImpl;
+import net.sf.taverna.t2.servicedescriptions.AbstractTemplateService;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescription;
+import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
+
+/**
+ * @author alanrw
+ *
+ */
+public class ExternalToolTemplateServiceDescription extends
+		AbstractTemplateService<ExternalToolActivityConfigurationBean> {
+	
+	private static final URI providerId = URI
+	.create("http://taverna.sf.net/2010/service-provider/external-tool");
+	
+	private static final String EXTERNAL_TOOL = "Tool";
+	
+	private static InvocationGroupManager manager = InvocationGroupManagerImpl.getInstance();
+
+	@Override
+	public Class<? extends Activity<ExternalToolActivityConfigurationBean>> getActivityClass() {
+		return ExternalToolActivity.class;
+	}
+
+	@Override
+	public ExternalToolActivityConfigurationBean getActivityConfiguration() {
+		ExternalToolActivityConfigurationBean result = new ExternalToolActivityConfigurationBean();
+		result.setExternaltoolid(UUID.randomUUID().toString());
+		result.setUseCaseDescription(new UseCaseDescription(""));
+		result.setMechanism(manager.getDefaultMechanism());
+		return result;
+	}
+
+	@Override
+	public Icon getIcon() {
+		return ExternalToolActivityIcon.getExternalToolIcon();
+	}
+	
+	@Override
+	public String getDescription() {
+		return "A service that allows tools to be used as services";	
+	}
+	
+	@SuppressWarnings("unchecked")
+	public static ServiceDescription getServiceDescription() {
+		ExternalToolTemplateServiceDescription bts = new ExternalToolTemplateServiceDescription();
+		return bts.templateService;
+	}
+
+
+
+	@Override
+	public String getId() {
+		return providerId.toString();
+	}
+
+	@Override
+	public String getName() {
+		return EXTERNAL_TOOL;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/utils/Tools.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/utils/Tools.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/utils/Tools.java
new file mode 100644
index 0000000..55cda5c
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/utils/Tools.java
@@ -0,0 +1,129 @@
+/**
+ * 
+ */
+package net.sf.taverna.t2.activities.externaltool.utils;
+
+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 java.util.Map;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.CompoundBorder;
+
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInput;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInputUser;
+
+import net.sf.taverna.t2.lang.ui.DeselectingButton;
+
+/**
+ * @author alanrw
+ *
+ */
+public class Tools {
+	
+	private static CompoundBorder border = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5,5,5,5), BorderFactory.createLineBorder(Color.BLACK, 1));
+	
+	private static Insets insets = new Insets(5,5,5,5);
+	
+	public static void addViewer(final JPanel innerPanel, String[] labels, JComponent[] elements,
+			final List viewerList, final Object viewer, final JPanel outerPanel) {
+		final JPanel subPanel = new JPanel();
+		subPanel.setLayout(new GridBagLayout());
+		subPanel.setBorder(border);
+		
+		final GridBagConstraints labelConstraint = new GridBagConstraints();
+		labelConstraint.insets = insets;
+		labelConstraint.anchor = GridBagConstraints.FIRST_LINE_START;
+		labelConstraint.fill = GridBagConstraints.BOTH;
+		labelConstraint.gridy = 0;
+		labelConstraint.gridx = 0;
+		labelConstraint.weightx = 0;
+
+		final GridBagConstraints elementConstraint = new GridBagConstraints();
+		elementConstraint.insets = insets;
+		elementConstraint.anchor = GridBagConstraints.FIRST_LINE_START;
+		elementConstraint.fill = GridBagConstraints.BOTH;
+		elementConstraint.gridy = 0;
+		elementConstraint.gridx = 1;
+		elementConstraint.weightx = 1.0;
+		
+		final GridBagConstraints removeConstraint = new GridBagConstraints();
+		removeConstraint.insets = insets;
+		removeConstraint.anchor = GridBagConstraints.FIRST_LINE_START;
+		removeConstraint.fill = GridBagConstraints.BOTH;
+		removeConstraint.gridx = 1;
+		removeConstraint.weightx = 0;
+		removeConstraint.fill = GridBagConstraints.NONE;
+		removeConstraint.anchor = GridBagConstraints.EAST;
+		
+		final GridBagConstraints subPanelConstraint = new GridBagConstraints();
+		subPanelConstraint.insets = insets;
+		subPanelConstraint.anchor = GridBagConstraints.FIRST_LINE_START;
+		subPanelConstraint.fill = GridBagConstraints.BOTH;
+		subPanelConstraint.gridx = 1;
+//		subPanelConstraint.gridy = ++stringReplacementGridy;
+		subPanelConstraint.weightx = 1.00;
+		subPanelConstraint.fill = GridBagConstraints.HORIZONTAL;
+		subPanelConstraint.anchor = GridBagConstraints.WEST;		
+		
+		for (int i = 0; i < labels.length; i++) {
+			subPanel.add(new JLabel(labels[i] + ":"), labelConstraint);
+			subPanel.add(elements[i], elementConstraint);
+			labelConstraint.gridy++;
+			elementConstraint.gridy++;
+		}
+		
+		removeConstraint.gridy = labelConstraint.gridy + 1;
+		final JButton removeButton = new DeselectingButton("Remove",
+				new AbstractAction() {
+
+			public void actionPerformed(ActionEvent e) {
+				synchronized (viewerList) {
+					viewerList.remove(viewer);
+				}
+				innerPanel.remove(subPanel);
+				innerPanel.revalidate();
+				innerPanel.repaint();
+				outerPanel.revalidate();
+				outerPanel.repaint();
+			}
+
+		});
+		subPanel.add(removeButton, removeConstraint);
+		innerPanel.add(subPanel, subPanelConstraint);
+	}
+	
+	public static boolean isStringReplacement(ScriptInputUser si) {
+		return !si.isList() && !si.isFile() && !si.isTempFile();
+	}
+	
+	public static boolean isInputFile(ScriptInputUser si) {
+		return !si.isList() && si.isFile();
+	}
+
+	public static boolean isFileList(ScriptInputUser si) {
+		return si.isList() && si.isFile();
+	}
+	
+	public static boolean isUnderstood(ScriptInputUser si) {
+		return isStringReplacement(si) || isInputFile(si) || isFileList(si);
+	}
+	
+	public static boolean areAllUnderstood(Map<String, ScriptInput> inputs) {
+		for (ScriptInput si : inputs.values()) {
+			if ((si instanceof ScriptInputUser) && !isUnderstood((ScriptInputUser) si)) {
+				return false;
+			}
+		}
+		return true;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/AnnotationPanel.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/AnnotationPanel.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/AnnotationPanel.java
new file mode 100644
index 0000000..83e75e8
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/AnnotationPanel.java
@@ -0,0 +1,41 @@
+/**
+ * 
+ */
+package net.sf.taverna.t2.activities.externaltool.views;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.FlowLayout;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+/**
+ * @author alanrw
+ *
+ */
+public class AnnotationPanel extends JPanel {
+	
+	public AnnotationPanel(Component nameField, Component descriptionArea, Component groupField) {
+		super();
+		this.setLayout(new BorderLayout());
+		JPanel subPanel = new JPanel(new BorderLayout());
+		JPanel namePanel = new JPanel();
+		namePanel.setLayout(new FlowLayout(FlowLayout.LEFT));
+		namePanel.add(new JLabel("Name: "));
+		namePanel.add(nameField);
+		subPanel.add(namePanel, BorderLayout.NORTH);
+		JPanel groupPanel = new JPanel();
+		groupPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
+		groupPanel.add(new JLabel("Group: "));
+		groupPanel.add(groupField);
+		subPanel.add(groupPanel, BorderLayout.SOUTH);
+		this.add(subPanel, BorderLayout.NORTH);
+		JPanel descriptionPanel = new JPanel();
+		descriptionPanel.setLayout(new BorderLayout());
+		descriptionPanel.add(new JLabel("Description:"), BorderLayout.NORTH);
+		descriptionPanel.add(descriptionArea, BorderLayout.CENTER);
+		this.add(descriptionPanel, BorderLayout.CENTER);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/EditablePanel.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/EditablePanel.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/EditablePanel.java
new file mode 100644
index 0000000..b395983
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/EditablePanel.java
@@ -0,0 +1,76 @@
+/**
+ * 
+ */
+package net.sf.taverna.t2.activities.externaltool.views;
+
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.JButton;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+
+import de.uni_luebeck.inb.knowarc.usecases.UseCaseDescription;
+import de.uni_luebeck.inb.knowarc.usecases.UseCaseEnumeration;
+
+import net.sf.taverna.t2.activities.externaltool.ExternalToolActivityConfigurationBean;
+import net.sf.taverna.t2.activities.externaltool.servicedescriptions.ExternalToolServiceDescription;
+import net.sf.taverna.t2.activities.externaltool.utils.Tools;
+import net.sf.taverna.t2.lang.ui.DeselectingButton;
+
+/**
+ * @author alanrw
+ *
+ */
+public class EditablePanel extends JPanel {
+	public EditablePanel(final ExternalToolConfigView view) {
+		super(new FlowLayout());
+		
+		JButton update = new DeselectingButton("Update tool description",
+				new AbstractAction() {
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				ExternalToolActivityConfigurationBean bean = view.getConfiguration();
+				String repositoryUrl = bean.getRepositoryUrl();
+				String id = bean.getExternaltoolid();
+				UseCaseDescription usecase = null;
+				try {
+					usecase = UseCaseEnumeration.readDescriptionFromUrl(
+						repositoryUrl, id);
+				}
+				catch (IOException ex) {
+					// Already logged
+				}
+				if (usecase != null) {
+					bean.setUseCaseDescription(usecase);
+					view.refreshConfiguration(bean);
+				} else {
+					JOptionPane.showMessageDialog(view, "Unable to find tool description " + id, "Missing tool description", JOptionPane.ERROR_MESSAGE);
+				}
+			}});
+		this.add(update);
+		
+		JButton makeEditable = new DeselectingButton("Edit tool description",
+				new AbstractAction() {
+
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				ExternalToolActivityConfigurationBean config = view.makeConfiguration();
+				view.setEditable(true, config);
+				
+			}
+		});
+		makeEditable.setToolTipText("Edit the tool description");
+		if (Tools.areAllUnderstood(view.getConfiguration().getUseCaseDescription().getInputs())) {
+		this.add(makeEditable);
+		}
+		
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolActivityContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolActivityContextualView.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolActivityContextualView.java
new file mode 100644
index 0000000..46c14be
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolActivityContextualView.java
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * Copyright (C) 2010 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.views;
+
+import java.awt.Frame;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+import javax.swing.Action;
+
+import net.sf.taverna.t2.activities.externaltool.ExternalToolActivity;
+import net.sf.taverna.t2.activities.externaltool.ExternalToolActivityConfigurationBean;
+import net.sf.taverna.t2.activities.externaltool.actions.ExternalToolActivityConfigureAction;
+import net.sf.taverna.t2.activities.externaltool.servicedescriptions.ExternalToolActivityIcon;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.ui.actions.activity.HTMLBasedActivityContextualView;
+import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInput;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInputStatic;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptOutput;
+import de.uni_luebeck.inb.knowarc.usecases.UseCaseDescription;
+
+/**
+ * ExternalToolActivityContextualView displays the use case information in a HTML table. Currently,
+ * this is only the use case ID.
+ *
+ * @author Hajo Nils Krabbenhoeft
+ */
+public class ExternalToolActivityContextualView extends
+		HTMLBasedActivityContextualView<ExternalToolActivityConfigurationBean> {
+	private static final long serialVersionUID = 1L;
+	private final EditManager editManager;
+	private final FileManager fileManager;
+	private final ActivityIconManager activityIconManager;
+
+	public ExternalToolActivityContextualView(Activity<?> activity, EditManager editManager,
+			FileManager fileManager, ColourManager colourManager, ActivityIconManager activityIconManager) {
+		super(activity, colourManager);
+		this.editManager = editManager;
+		this.fileManager = fileManager;
+		this.activityIconManager = activityIconManager;
+	}
+
+	@Override
+	protected String getRawTableRowsHtml() {
+		String html = "";
+		ExternalToolActivityConfigurationBean bean = getConfigBean();
+		String repositoryUrl = bean.getRepositoryUrl();
+		if ((repositoryUrl == null) || repositoryUrl.isEmpty()) {
+			repositoryUrl = "<b>Not specified</b>";
+		}
+		html += "<tr><td>Repository URL</td><td>" + repositoryUrl + "</td></tr>";
+
+		String id = bean.getExternaltoolid();
+		if ((id == null) || id.isEmpty()) {
+			id = "<b>Not specified</b>";
+		}
+		html += "<tr><td>Id</td><td>" + id + "</td></tr>";
+
+		UseCaseDescription useCaseDescription = bean.getUseCaseDescription();
+		String name = useCaseDescription.getUsecaseid();
+		if ((name == null) || name.isEmpty()) {
+			name = "<b>Not specified</b>";
+		}
+		html += "<tr><td>Name</td><td>" + name + "</td></tr>";
+
+		Map<String, ScriptInput> stringReplacements = new TreeMap<String, ScriptInput>();
+		Map<String, ScriptInput> fileInputs = new TreeMap<String, ScriptInput>();
+
+		for (Entry<String, ScriptInput> entry : useCaseDescription.getInputs().entrySet()) {
+			String key = entry.getKey();
+			ScriptInput value = entry.getValue();
+			if (value.isFile()) {
+				fileInputs.put(key, value);
+			} else if (value.isTempFile()) {
+				// Nothing
+			} else {
+				stringReplacements.put(key, value);
+			}
+		}
+
+		if (!stringReplacements.isEmpty()) {
+			html += "<tr><td colspan=2 align=center><b>String replacements</b></td></tr>";
+			html += "<tr><td><b>Port name</b></td><td><b>Replaces</b></td></tr>";
+			for (String siName : stringReplacements.keySet()) {
+				html += "<tr><td>" + siName + "</td>";
+				ScriptInput si = stringReplacements.get(siName);
+				html += "<td>%%" + si.getTag() + "%%</td>";
+
+				html += "</tr>";
+			}
+		}
+
+		if (!fileInputs.isEmpty()) {
+			html += "<tr><td colspan=2 align=center><b>File inputs</b></td></tr>";
+			html += "<tr><td><b>Port name</b></td><td><b>To file</b></td></tr>";
+			for (String siName : fileInputs.keySet()) {
+				html += "<tr><td>" + siName + "</td>";
+				ScriptInput si = fileInputs.get(siName);
+				html += "<td>" + si.getTag() + "</td>";
+
+				html += "</tr>";
+			}
+		}
+
+		List<ScriptInputStatic> staticInputs = useCaseDescription.getStatic_inputs();
+		if (!staticInputs.isEmpty()) {
+			html += "<tr><td colspan=2 align=center><b>Static inputs</b></td></tr>";
+			html += "<tr><td><b>Type</b></td><td><b>To file</b></td></tr>";
+			for (ScriptInputStatic si : staticInputs) {
+				if (si.getUrl() != null) {
+					html += "<td><b>URL</b></td>";
+				} else {
+					html += "<td><b>Explicit content</b></td>";
+				}
+				if (si.isFile()) {
+					html += "<td>" + si.getTag() + "</td>";
+				}
+				html += "</tr>";
+			}
+		}
+		Map<String, ScriptOutput> outputs = useCaseDescription.getOutputs();
+		if (!outputs.isEmpty()) {
+			html += "<tr><td colspan=2 align=center><b>File outputs</b></td></tr>";
+			html += "<tr><td><b>Port name</b></td><td><b>From file</b></td></tr>";
+			for (String soName : outputs.keySet()) {
+				html += "<tr><td>" + soName + "</td>";
+				ScriptOutput so = outputs.get(soName);
+				html += "<td>" + so.getPath() + "</td>";
+				html += "</tr>";
+			}
+		}
+		return html;
+	}
+
+	@Override
+	public String getViewTitle() {
+		return "Tool service";
+	}
+
+	@Override
+	public Action getConfigureAction(final Frame owner) {
+		return new ExternalToolActivityConfigureAction((ExternalToolActivity) getActivity(), owner,
+				editManager, fileManager, activityIconManager);
+	}
+
+	public String getBackgroundColour() {
+
+		return ExternalToolActivityIcon.getColourString();
+	}
+
+	@Override
+	public int getPreferredPosition() {
+		return 100;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolActivityViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolActivityViewFactory.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolActivityViewFactory.java
new file mode 100644
index 0000000..902c736
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolActivityViewFactory.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (C) 2010 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.views;
+
+import java.util.Arrays;
+import java.util.List;
+
+import net.sf.taverna.t2.activities.externaltool.ExternalToolActivity;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
+
+/**
+ * ExternalToolActivityViewFactory produces an ExternalToolActivityContextualView to show
+ * information for a use case activity.
+ *
+ * @author Hajo Nils Krabbenhoeft
+ */
+public class ExternalToolActivityViewFactory implements ContextualViewFactory<ExternalToolActivity> {
+
+	private EditManager editManager;
+	private FileManager fileManager;
+	private ActivityIconManager activityIconManager;
+	private ColourManager colourManager;
+
+	public boolean canHandle(Object object) {
+		if (object instanceof ExternalToolActivity) {
+			return true;
+		}
+		return false;
+	}
+
+	public List<ContextualView> getViews(ExternalToolActivity selection) {
+		return Arrays.asList(new ContextualView[] { new ExternalToolActivityContextualView(
+				selection, editManager, fileManager, colourManager, activityIconManager) });
+	}
+
+	public void setEditManager(EditManager editManager) {
+		this.editManager = editManager;
+	}
+
+	public void setFileManager(FileManager fileManager) {
+		this.fileManager = fileManager;
+	}
+
+	public void setActivityIconManager(ActivityIconManager activityIconManager) {
+		this.activityIconManager = activityIconManager;
+	}
+
+	public void setColourManager(ColourManager colourManager) {
+		this.colourManager = colourManager;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolConfigView.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolConfigView.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolConfigView.java
new file mode 100644
index 0000000..4723a78
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolConfigView.java
@@ -0,0 +1,868 @@
+/*******************************************************************************
+ * 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 net.sf.taverna.t2.activities.externaltool.views;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+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 java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.help.CSH;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JEditorPane;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.JTextPane;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import net.sf.taverna.t2.activities.externaltool.ExternalToolActivity;
+import net.sf.taverna.t2.activities.externaltool.ExternalToolActivityConfigurationBean;
+import net.sf.taverna.t2.activities.externaltool.ExternalToolActivityHealthChecker;
+import net.sf.taverna.t2.activities.externaltool.utils.Tools;
+import net.sf.taverna.t2.lang.ui.KeywordDocument;
+import net.sf.taverna.t2.lang.ui.LinePainter;
+import net.sf.taverna.t2.lang.ui.NoWrapEditorKit;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ActivityConfigurationPanel;
+
+import org.apache.log4j.Logger;
+
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInput;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInputStatic;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInputUser;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptOutput;
+import de.uni_luebeck.inb.knowarc.usecases.UseCaseDescription;
+
+/**
+ * Provides the configurable view for a {@link ExternalToolActivity} through
+ * it's {@link ExternalToolActivityConfigurationBean}. Has 3 main tabs - Script,
+ * Ports & Dependencies. The {@link #inputViewList} contains the
+ * {@link ExternalToolInputViewer}s describing the input ports and
+ * {@link #outputViewList} has the {@link ExternalToolFileViewer}s
+ * 
+ * @author Ian Dunlop
+ * @author Alex Nenadic
+ * @author Alan R Williams
+ * 
+ */
+@SuppressWarnings("serial")
+public class ExternalToolConfigView
+		extends
+		ActivityConfigurationPanel<ExternalToolActivity, ExternalToolActivityConfigurationBean> {
+	
+	private static final Color LINE_COLOR = new Color(225,225,225);
+
+	private static final String FILE_INPUT_DESCRIPTION = "You can use a file input to feed data into " +
+			"the service via an input port and have that data written to the specified file.";
+
+	private static final String FILE_OUTPUT_DESCRIPTION = "You can use a file output to take the " +
+			"content of a file produced by the tool and send it to an output port of the service.";
+
+	private static final String FILE_LIST_DESCRIPTION = "If you feed a list of data into a file list " +
+			"input, then each data item is written to a temporary file. A file is produced containing " +
+			"the names of those temporary file. That index file can then be used as part of the tool " +
+			"command.";
+
+	private static final String VALID_NAME_REGEX = "[\\p{L}\\p{Digit}_]+";
+
+	private static Logger logger = Logger
+			.getLogger(ExternalToolConfigView.class);
+
+	/** The activity which this view describes */
+	protected ExternalToolActivity activity;
+
+	/** The configuration bean used to configure the activity */
+	private ExternalToolActivityConfigurationBean configuration;
+
+	private JTabbedPane tabbedPane = null;
+	private JPanel advancedPanel = null;
+	private JTabbedPane advancedTab = null;
+	private AnnotationPanel annotationPanel = null;
+	
+	private int stringReplacementGridy = 1;
+	private List<ExternalToolStringReplacementViewer> stringReplacementViewList = new ArrayList<ExternalToolStringReplacementViewer>();
+
+	private List<ExternalToolFileViewer> inputFileViewList = new ArrayList<ExternalToolFileViewer>();
+
+	private List<ExternalToolFileViewer> fileListViewList = new ArrayList<ExternalToolFileViewer>();
+
+	private int inputGridy = 1;
+
+	private int outputGridy = 1;
+	private List<ExternalToolFileViewer> outputViewList = new ArrayList<ExternalToolFileViewer>();
+
+	private int staticGridy = 1;
+	private List<ExternalToolStaticUrlViewer> staticUrlViewList = new ArrayList<ExternalToolStaticUrlViewer>();
+
+	private List<ExternalToolStaticStringViewer> staticStringViewList = new ArrayList<ExternalToolStaticStringViewer>();
+
+/*	private List<ExternalToolRuntimeEnvironmentViewer> runtimeEnvironmentViewList = new ArrayList<ExternalToolRuntimeEnvironmentViewer>();
+*/
+
+	private JTextField nameField = new JTextField(20);
+	private JTextField groupField = new JTextField(20);
+	private JTextArea descriptionArea = new JTextArea(6, 40);
+
+	private JEditorPane scriptTextArea;
+
+	private InvocationPanel invocationPanel;
+
+	private JCheckBox stdInCheckBox = new JCheckBox("Show STDIN");
+	private JCheckBox stdOutCheckBox = new JCheckBox("Show STDOUT");
+	private JCheckBox stdErrCheckBox = new JCheckBox("Show STDERR");
+	
+	private JTextField returnCodesField = new JTextField(20);
+
+	/**
+	 * Stores the {@link ExternalToolActivity}, gets its
+	 * {@link ExternalToolActivityConfigurationBean}, sets the layout and calls
+	 * {@link #initialise()} to get the view going
+	 * 
+	 * @param activity
+	 *            the {@link ExternalToolActivity} that the view is over
+	 */
+	public ExternalToolConfigView(ExternalToolActivity activity) {
+		this.activity = activity;
+		ExternalToolActivityHealthChecker.updateLocation(activity.getConfiguration());
+		configuration = (ExternalToolActivityConfigurationBean) cloneBean(activity
+				.getConfiguration());
+		setLayout(new GridBagLayout());
+		initialise(configuration);
+	}
+
+	public void noteConfiguration() {
+		configuration = makeConfiguration();
+	}
+
+	public ExternalToolActivityConfigurationBean makeConfiguration() {
+		ExternalToolActivityConfigurationBean newConfiguration = (ExternalToolActivityConfigurationBean) cloneBean(configuration);
+		ExternalToolActivityHealthChecker.updateLocation(newConfiguration);
+		
+
+		if (!isFromRepository()) {
+			UseCaseDescription ucd = newConfiguration.getUseCaseDescription();
+
+			ucd.setUsecaseid(nameField.getText());
+			if (groupField.getText().isEmpty()) {
+				ucd.setGroup(null);
+			} else {
+				ucd.setGroup(groupField.getText());
+			}
+			ucd.setDescription(descriptionArea.getText());
+			ucd.setCommand(scriptTextArea.getText());
+			ucd.setReturnCodesAsText(returnCodesField.getText());
+			ucd.setIncludeStdIn(stdInCheckBox.isSelected());
+			ucd.setIncludeStdOut(stdOutCheckBox.isSelected());
+			ucd.setIncludeStdErr(stdErrCheckBox.isSelected());
+
+			ucd.getInputs().clear();
+			ucd.getTags().clear();
+			synchronized (fileListViewList) {
+				for (ExternalToolFileViewer viewer : fileListViewList) {
+					ScriptInputUser si = new ScriptInputUser();
+					si.setBinary(viewer.isBinary());
+					si.setList(true);
+					si.setTag(viewer.getValue());
+					si.setTempFile(false);
+					si.setFile(true);
+					ucd.getInputs().put(viewer.getName(), si);
+				}
+			}
+
+			synchronized (stringReplacementViewList) {
+				for (ExternalToolStringReplacementViewer viewer : stringReplacementViewList) {
+					ScriptInputUser si = new ScriptInputUser();
+					si.setBinary(false);
+					si.setList(false);
+					si.setTag(viewer.getValue());
+					si.setTempFile(false);
+					si.setFile(false);
+					ucd.getTags().add(si.getTag());
+					ucd.getInputs().put(viewer.getName(), si);
+				}
+			}
+
+			synchronized (inputFileViewList) {
+				for (ExternalToolFileViewer viewer : inputFileViewList) {
+					ScriptInputUser si = new ScriptInputUser();
+					si.setBinary(viewer.isBinary());
+					si.setList(false);
+					si.setTag(viewer.getValue());
+					si.setTempFile(false);
+					si.setFile(true);
+					ucd.getInputs().put(viewer.getName(), si);
+				}
+			}
+
+			synchronized (outputViewList) {
+				ucd.getOutputs().clear();
+				for (ExternalToolFileViewer viewer : outputViewList) {
+					ScriptOutput so = new ScriptOutput();
+					so.setBinary(viewer.isBinary());
+					so.setPath(viewer.getValue());
+					ucd.getOutputs().put(viewer.getName(), so);
+				}
+			}
+			ucd.getStatic_inputs().clear();
+			synchronized (staticStringViewList) {
+				for (ExternalToolStaticStringViewer viewer : staticStringViewList) {
+					ScriptInputStatic sis = new ScriptInputStatic();
+					sis.setContent(viewer.getContent());
+					sis.setTag(viewer.getValue());
+					sis.setTempFile(false);
+					sis.setFile(true);
+					ucd.getStatic_inputs().add(sis);
+				}
+			}
+			synchronized (staticUrlViewList) {
+				for (ExternalToolStaticUrlViewer viewer : staticUrlViewList) {
+					ScriptInputStatic sis = new ScriptInputStatic();
+					sis.setUrl(viewer.getContent());
+					sis.setTag(viewer.getValue());
+					sis.setTempFile(false);
+					sis.setFile(true);
+					ucd.getStatic_inputs().add(sis);
+				}
+			}
+
+/*			synchronized (runtimeEnvironmentViewList) {
+				ucd.getREs().clear();
+				for (ExternalToolRuntimeEnvironmentViewer viewer : runtimeEnvironmentViewList) {
+					RuntimeEnvironmentConstraint newConstraint = new RuntimeEnvironmentConstraint(
+							viewer.getId(), viewer.getRelation());
+					ucd.getREs().add(newConstraint);
+				}
+			}*/
+		}
+		invocationPanel.fillInConfiguration(newConfiguration);
+
+		return newConfiguration;
+	}
+
+	public boolean isConfigurationChanged() {
+		String configurationString = convertBeanToString(activity
+				.getConfiguration());
+		return (!convertBeanToString(makeConfiguration()).equals(
+				configurationString));
+	}
+
+	/**
+	 * Adds a {@link JButton} which handles the reconfiguring of the
+	 * {@link ExternalToolActivity} through the altered
+	 * {@link ExternalToolActivityConfigurationBean}. Sets up the initial tabs -
+	 * Script (also sets the initial value), Ports & Dependencies and their
+	 * initial values through {@link #setDependencies()},
+	 * {@link #getPortPanel()}
+	 */
+	private void initialise(ExternalToolActivityConfigurationBean configuration) {
+		CSH.setHelpIDString(
+				this,
+				"net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ExternalToolConfigView");
+		this.configuration = configuration;
+		setBorder(javax.swing.BorderFactory.createTitledBorder(null, null,
+				javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
+				javax.swing.border.TitledBorder.DEFAULT_POSITION,
+				new java.awt.Font("Lucida Grande", 1, 12)));
+
+		tabbedPane = new JTabbedPane();
+		
+		if (invocationPanel != null) {
+			invocationPanel.stopObserving();
+		}
+
+		if (!isFromRepository()) {
+			UseCaseDescription useCaseDescription = configuration
+					.getUseCaseDescription();
+
+			nameField.setText(useCaseDescription.getUsecaseid());
+			if (useCaseDescription.getGroup() != null) {
+				groupField.setText(useCaseDescription.getGroup());
+			}
+			descriptionArea.setText(useCaseDescription.getDescription());
+			stringReplacementViewList = new ArrayList<ExternalToolStringReplacementViewer>();
+			inputFileViewList = new ArrayList<ExternalToolFileViewer>();
+			fileListViewList = new ArrayList<ExternalToolFileViewer>();
+			outputViewList = new ArrayList<ExternalToolFileViewer>();
+			staticUrlViewList = new ArrayList<ExternalToolStaticUrlViewer>();
+			staticStringViewList = new ArrayList<ExternalToolStaticStringViewer>();
+/*			runtimeEnvironmentViewList = new ArrayList<ExternalToolRuntimeEnvironmentViewer>();*/
+
+			for (Entry<String, ScriptInput> entry : useCaseDescription
+					.getInputs().entrySet()) {
+				String name = entry.getKey();
+				ScriptInputUser si = (ScriptInputUser) entry.getValue();
+				if (Tools.isStringReplacement(si)) {
+					final ExternalToolStringReplacementViewer inputView = new ExternalToolStringReplacementViewer(
+							name, si);
+					stringReplacementViewList.add(inputView);
+				}
+
+			}
+			Collections.sort(stringReplacementViewList,
+					new Comparator<ExternalToolStringReplacementViewer>() {
+
+						@Override
+						public int compare(
+								ExternalToolStringReplacementViewer o1,
+								ExternalToolStringReplacementViewer o2) {
+							return o1.getName().compareTo(o2.getName());
+						}
+					});
+
+			for (Entry<String, ScriptInput> entry : useCaseDescription
+					.getInputs().entrySet()) {
+				String name = entry.getKey();
+				ScriptInputUser si = (ScriptInputUser) entry.getValue();
+				if (Tools.isInputFile(si)) {
+					final ExternalToolFileViewer inputView = new ExternalToolFileViewer(
+							name, si.getTag(), si.isBinary());
+					inputFileViewList.add(inputView);
+				}
+
+			}
+			Collections.sort(inputFileViewList,
+					new Comparator<ExternalToolFileViewer>() {
+
+						@Override
+						public int compare(ExternalToolFileViewer o1,
+								ExternalToolFileViewer o2) {
+							return o1.getName().compareTo(o2.getName());
+						}
+					});
+
+			for (Entry<String, ScriptInput> entry : useCaseDescription
+					.getInputs().entrySet()) {
+				String name = entry.getKey();
+				ScriptInputUser si = (ScriptInputUser) entry.getValue();
+				if (Tools.isFileList(si)) {
+					final ExternalToolFileViewer inputView = new ExternalToolFileViewer(
+							name, si.getTag(), si.isBinary());
+					fileListViewList.add(inputView);
+				}
+
+			}
+			Collections.sort(fileListViewList,
+					new Comparator<ExternalToolFileViewer>() {
+
+						@Override
+						public int compare(ExternalToolFileViewer o1,
+								ExternalToolFileViewer o2) {
+							return o1.getName().compareTo(o2.getName());
+						}
+					});
+
+			for (Entry<String, ScriptOutput> entry : useCaseDescription
+					.getOutputs().entrySet()) {
+				ScriptOutput so = entry.getValue();
+				final ExternalToolFileViewer outputView = new ExternalToolFileViewer(
+						entry.getKey(), so.getPath(), so.isBinary());
+				outputViewList.add(outputView);
+			}
+			Collections.sort(outputViewList,
+					new Comparator<ExternalToolFileViewer>() {
+
+						@Override
+						public int compare(ExternalToolFileViewer o1,
+								ExternalToolFileViewer o2) {
+							return o1.getName().compareTo(o2.getName());
+						}
+					});
+
+			for (ScriptInputStatic siss : useCaseDescription.getStatic_inputs()) {
+				if ((siss.getUrl() == null) && siss.isFile()) {
+					final ExternalToolStaticStringViewer staticView = new ExternalToolStaticStringViewer(
+							siss);
+					staticStringViewList.add(staticView);
+				}
+			}
+			Collections.sort(staticStringViewList,
+					new Comparator<ExternalToolStaticStringViewer>() {
+
+						@Override
+						public int compare(ExternalToolStaticStringViewer o1,
+								ExternalToolStaticStringViewer o2) {
+							return o1.getContent().compareTo(o2.getContent());
+						}
+					});
+
+			for (ScriptInputStatic sis : useCaseDescription.getStatic_inputs()) {
+				if ((sis.getUrl() != null) && sis.isFile()) {
+					final ExternalToolStaticUrlViewer staticView = new ExternalToolStaticUrlViewer(
+							sis);
+					staticUrlViewList.add(staticView);
+				}
+			}
+			Collections.sort(staticUrlViewList,
+					new Comparator<ExternalToolStaticUrlViewer>() {
+
+						@Override
+						public int compare(ExternalToolStaticUrlViewer o1,
+								ExternalToolStaticUrlViewer o2) {
+							return o1.getContent().compareTo(o2.getContent());
+						}
+					});
+
+/*			for (RuntimeEnvironmentConstraint rec : useCaseDescription.getREs()) {
+				final ExternalToolRuntimeEnvironmentViewer newView = new ExternalToolRuntimeEnvironmentViewer(
+						rec.getID(), rec.getRelation());
+				runtimeEnvironmentViewList.add(newView);
+			}
+			Collections.sort(runtimeEnvironmentViewList,
+					new Comparator<ExternalToolRuntimeEnvironmentViewer>() {
+
+						@Override
+						public int compare(
+								ExternalToolRuntimeEnvironmentViewer o1,
+								ExternalToolRuntimeEnvironmentViewer o2) {
+							return o1.getId().compareTo(o2.getId());
+						}
+					});*/
+
+			scriptTextArea = new JTextPane();
+			new LinePainter(scriptTextArea, LINE_COLOR);
+
+			final KeywordDocument doc = new KeywordDocument(
+					new HashSet<String>());
+			// NOTE: Due to T2-1145 - always set editor kit BEFORE setDocument
+			scriptTextArea.setEditorKit(new NoWrapEditorKit());
+			scriptTextArea.setFont(new Font("Monospaced", Font.PLAIN, 14));
+			scriptTextArea.setDocument(doc);
+			scriptTextArea.setText(useCaseDescription.getCommand());
+			scriptTextArea.setCaretPosition(0);
+			scriptTextArea.setPreferredSize(new Dimension(200, 100));
+
+			tabbedPane.addTab("Command", new ScriptPanel(this, scriptTextArea, stdInCheckBox, stdOutCheckBox, stdErrCheckBox, returnCodesField));
+			tabbedPane.addTab("String replacements",
+					new StringReplacementPanel(this, stringReplacementViewList));
+			tabbedPane.addTab(
+					"File inputs",
+					new FilePanel(this, inputFileViewList, "To file", "File type",
+							"in", FILE_INPUT_DESCRIPTION, "Add file input"));
+			tabbedPane.addTab(
+					"File outputs",
+					new FilePanel(this, outputViewList, "From file", "File type",
+							"out", FILE_OUTPUT_DESCRIPTION, "Add file output"));
+			advancedPanel = new JPanel();
+			advancedPanel.setLayout(new GridBagLayout());
+			GridBagConstraints advancedConstraint = new GridBagConstraints();
+			advancedConstraint.anchor = GridBagConstraints.FIRST_LINE_START;
+			advancedConstraint.gridx = 0;
+			advancedConstraint.gridy = 0;
+
+			advancedConstraint.fill = GridBagConstraints.BOTH;
+			advancedConstraint.weighty = 0.1;
+			advancedConstraint.weightx = 0.1;
+			advancedTab = new JTabbedPane();
+			advancedTab.addTab("Strings", new StaticStringPanel(staticStringViewList));
+			advancedTab.addTab("URLs", new StaticUrlPanel(staticUrlViewList));
+			advancedTab.addTab(
+					"File lists",
+					new FilePanel(this, fileListViewList,
+							"To file containing list", "Individual file type",
+							"in", FILE_LIST_DESCRIPTION, "Add file list"));
+			annotationPanel = new AnnotationPanel(nameField, descriptionArea, groupField);
+			advancedTab.addTab("Annotation", annotationPanel);
+			final ToolXMLPanel toolXMLPanel = new ToolXMLPanel(configuration.getUseCaseDescription());
+			advancedTab.addTab("XML", toolXMLPanel);
+			advancedTab.addChangeListener(new ChangeListener() {
+
+				@Override
+				public void stateChanged(ChangeEvent e) {
+					if (advancedTab.getSelectedComponent() == toolXMLPanel) {
+						toolXMLPanel.regenerateTree(makeConfiguration().getUseCaseDescription());
+					}
+				}});
+			tabbedPane.addChangeListener(new ChangeListener() {
+
+				@Override
+				public void stateChanged(ChangeEvent e) {
+					if ((tabbedPane.getSelectedComponent() == advancedPanel) &&
+							(advancedTab.getSelectedComponent() == toolXMLPanel)) {
+						toolXMLPanel.regenerateTree(makeConfiguration().getUseCaseDescription());						
+					}
+				}
+				
+			});
+/*			advancedTab.addTab("Runtime environments",
+					createRuntimeEnvironmentPanel(runtimeEnvironmentViewList));*/
+			advancedPanel.add(advancedTab, advancedConstraint);
+			tabbedPane.addTab("Advanced", advancedPanel);
+		}
+		invocationPanel = new InvocationPanel(configuration);
+		
+		tabbedPane.addTab("Location", invocationPanel);
+		if (isFromRepository()) {
+			tabbedPane.addTab("Edit", new EditablePanel(this));
+		}
+		GridBagConstraints outerConstraint = new GridBagConstraints();
+		outerConstraint.anchor = GridBagConstraints.FIRST_LINE_START;
+		outerConstraint.gridx = 0;
+		outerConstraint.gridy = 0;
+
+		outerConstraint.fill = GridBagConstraints.BOTH;
+		outerConstraint.weighty = 0.1;
+		outerConstraint.weightx = 0.1;
+		add(tabbedPane, outerConstraint);
+
+		setPreferredSize(new Dimension(700, 500));
+		this.validate();
+	}
+
+	public void whenOpened() {
+		if (scriptTextArea != null) {
+			scriptTextArea.requestFocus();
+		}
+	}
+
+	private boolean isFromRepository() {
+		return (!this.configuration.isEdited() && isOriginallyFromRepository());
+	}
+	
+	public boolean isOriginallyFromRepository() {
+		String repositoryUrl = this.configuration.getRepositoryUrl();
+		return ((repositoryUrl != null) && !repositoryUrl
+				.isEmpty());
+		
+	}
+
+
+	@Override
+	public ExternalToolActivityConfigurationBean getConfiguration() {
+		return configuration;
+	}
+
+	public void refreshConfiguration(
+			ExternalToolActivityConfigurationBean config) {
+		int visibleTab = -1;
+		int secondaryTab = -1;
+		if (tabbedPane != null) {
+			visibleTab = tabbedPane.getSelectedIndex();
+			if (tabbedPane.getSelectedComponent().equals(advancedTab)) {
+				secondaryTab = advancedTab.getSelectedIndex();
+			}
+		}
+		this.removeAll();
+		initialise(config);
+		if (visibleTab != -1) {
+			tabbedPane.setSelectedIndex(visibleTab);
+		}
+		if (secondaryTab != -1) {
+			advancedTab.setSelectedIndex(secondaryTab);
+		}
+	}
+	
+	public void showAnnotationPanel() {
+		tabbedPane.setSelectedComponent(advancedPanel);
+		advancedTab.setSelectedComponent(annotationPanel);
+	}
+
+	@Override
+	public void refreshConfiguration() {
+		refreshConfiguration(activity.getConfiguration());
+	}
+
+	static Pattern tagPattern = Pattern.compile("%%([^%]*)%%");
+
+	@Override
+	/**
+	 * Need to check that the script contains the string replacements and only them - done
+	 * 
+	 * Need to check the input port names are valid and unique - done
+	 * Need to check the output port names are valid and unique - done
+	 * 
+	 * Need to check the input files and static files are unique - done
+	 * Need to check the file names are valid
+	 * Need to check the URLs are valid
+	 * Need to check the replacement tags are unique - done
+	 */
+	public boolean checkValues() {
+		if (isFromRepository()) {
+			return true;
+		}
+		boolean result = true;
+		String text = "";
+		Set<String> stringReplacementPortNames = new HashSet<String>();
+		Set<String> stringReplacementTags = new HashSet<String>();
+		for (ExternalToolStringReplacementViewer v : stringReplacementViewList) {
+			String name = v.getName();
+			if (name.equalsIgnoreCase("stdin") || name.equalsIgnoreCase("stdout") || name.equalsIgnoreCase("stderr")) {
+				text += "A string replacement port has a reserved name \"" + name + "\"\n";
+				result = false;
+			}
+			else if (stringReplacementPortNames.contains(name)) {
+				text += "Two string replacement ports have the name \"" + name
+						+ "\"\n";
+				result = false;
+			} else if (!name.matches(VALID_NAME_REGEX)) {
+				text += "String replacement port name \"" + name
+						+ "\" is invalid\n";
+				result = false;
+			} else {
+				stringReplacementPortNames.add(name);
+			}
+
+			String tag = v.getValue();
+			if (stringReplacementTags.contains(tag)) {
+				text += "Two string replacement ports replace \"%%" + tag
+						+ "%%\"\n";
+				result = false;
+			} else if (!tag.matches(VALID_NAME_REGEX)) {
+				text += "String replacement tag \"%%" + tag
+						+ "%%\" is invalid\n";
+				result = false;
+			} else {
+				stringReplacementTags.add(tag);
+			}
+		}
+
+		Matcher m = tagPattern.matcher(scriptTextArea.getText());
+		Set<String> tags = new HashSet<String>();
+		while (m.find()) {
+			String tag = m.group(1);
+			if (tag != null) {
+				if (tag.isEmpty()) {
+					text += "The command contains an empty tag i.e. %%%%\n";
+					result = false;
+				} else {
+					if (!tag.matches(VALID_NAME_REGEX)) {
+						text += "The command contains an invalid tag \"%%"
+								+ tag + "\"%%\n";
+						result = false;
+					}
+					if (!stringReplacementTags.contains(tag)) {
+						text += "There is no string replacement for %%" + tag
+								+ "%%\n";
+						result = false;
+					} else {
+						tags.add(tag);
+					}
+				}
+			}
+		}
+
+		for (String tag : stringReplacementTags) {
+			if (!tags.contains(tag)) {
+				text += "String replacement for %%" + tag
+						+ "%% is not used in the command\n";
+				result = false;
+			}
+		}
+
+		Set<String> inputFilePortNames = new HashSet<String>();
+		Set<String> inputFileNames = new HashSet<String>();
+		for (ExternalToolFileViewer v : inputFileViewList) {
+			String name = v.getName();
+			if (name.equalsIgnoreCase("stdin") || name.equalsIgnoreCase("stdout") || name.equalsIgnoreCase("stderr")) {
+				text += "An input file port has a reserved name \"" + name + "\"\n";
+				result = false;
+			}
+			else if (stringReplacementPortNames.contains(name)) {
+				text += "A string replacement port and an input file port have the name \""
+						+ name + "\"\n";
+				result = false;
+			} else if (inputFilePortNames.contains(name)) {
+				text += "Two file input ports have the name \"" + name + "\"\n";
+				result = false;
+			} else if (!name.matches(VALID_NAME_REGEX)) {
+				text += "File input port name \"" + name + "\" is invalid\n";
+				result = false;
+			} else {
+				inputFilePortNames.add(name);
+			}
+
+			String fileName = v.getValue();
+			if (inputFileNames.contains(fileName)) {
+				text += "Two file inputs ports write to the same file \""
+						+ fileName + "\"\n";
+				result = false;
+			} else {
+				inputFileNames.add(fileName);
+			}
+		}
+
+		Set<String> fileListPortNames = new HashSet<String>();
+		Set<String> fileListFileNames = new HashSet<String>();
+		for (ExternalToolFileViewer v : fileListViewList) {
+			String name = v.getName();
+			if (name.equalsIgnoreCase("stdin") || name.equalsIgnoreCase("stdout") || name.equalsIgnoreCase("stderr")) {
+				text += "A file list port has a reserved name \"" + name + "\"\n";
+				result = false;
+			} else if (stringReplacementPortNames.contains(name)) {
+				text += "A string replacement port and a file list port have the name \""
+						+ name + "\"\n";
+				result = false;
+			} else if (inputFilePortNames.contains(name)) {
+				text += "A file input port and a file list port have the name \""
+						+ name + "\"\n";
+				result = false;
+			} else if (fileListPortNames.contains(name)) {
+				text += "Two file list ports have the name \"" + name + "\"\n";
+				result = false;
+			} else if (!name.matches(VALID_NAME_REGEX)) {
+				text += "File list port name \"" + name + "\" is invalid\n";
+				result = false;
+			} else {
+				fileListPortNames.add(name);
+			}
+
+			String fileName = v.getValue();
+			if (fileListFileNames.contains(fileName)) {
+				text += "Two file list ports write to the same file \""
+						+ fileName + "\"\n";
+				result = false;
+			} else if (inputFileNames.contains(fileName)) {
+				text += "A file input port and a file list port write to the same file \""
+						+ fileName + "\"\n";
+				result = false;
+			} else {
+				fileListFileNames.add(fileName);
+			}
+		}
+
+		Set<String> staticStringFileNames = new HashSet<String>();
+		for (ExternalToolStaticStringViewer v : staticStringViewList) {
+			String fileName = v.getValue();
+			if (staticStringFileNames.contains(fileName)) {
+				text += "Two static strings write to the same file \""
+						+ fileName + "\"\n";
+				result = false;
+			} else if (inputFileNames.contains(fileName)) {
+				text += "A file input port and a static string write to the same file \""
+						+ fileName + "\"\n";
+				result = false;
+			} else if (fileListFileNames.contains(fileName)) {
+				text += "A file list port and a static string write to the same file \""
+						+ fileName + "\"\n";
+				result = false;
+			} else {
+				staticStringFileNames.add(fileName);
+			}
+		}
+
+		Set<String> staticUrlFileNames = new HashSet<String>();
+		for (ExternalToolStaticUrlViewer v : staticUrlViewList) {
+			String fileName = v.getValue();
+			if (staticUrlFileNames.contains(fileName)) {
+				text += "Two static URLss write to the same file \"" + fileName
+						+ "\"\n";
+				result = false;
+			} else if (inputFileNames.contains(fileName)) {
+				text += "A file input port and a static URL write to the same file \""
+						+ fileName + "\"\n";
+				result = false;
+			} else if (fileListFileNames.contains(fileName)) {
+				text += "A file list port and a static URL write to the same file \""
+						+ fileName + "\"\n";
+				result = false;
+			} else if (staticStringFileNames.contains(fileName)) {
+				text += "A static string and a static URL write to the same file \""
+						+ fileName + "\"\n";
+				result = false;
+			} else {
+				staticUrlFileNames.add(fileName);
+			}
+		}
+		Set<String> outputPortNames = new HashSet<String>();
+		for (ExternalToolFileViewer v : outputViewList) {
+			String name = v.getName();
+			if (name.equalsIgnoreCase("stdin") || name.equalsIgnoreCase("stdout") || name.equalsIgnoreCase("stderr")) {
+				text += "An output port has a reserved name \"" + name + "\"\n";
+				result = false;
+			} else if (outputPortNames.contains(name)) {
+				text += "Two output file ports have the name \"" + name
+						+ "\"\n";
+				result = false;
+			} else if (!name.matches(VALID_NAME_REGEX)) {
+				text += "Output file port name \"" + name + "\" is invalid\n";
+				result = false;
+			} else {
+				outputPortNames.add(name);
+			}
+		}
+		if (!result) {
+			JOptionPane.showMessageDialog(this, text, "Problems",
+					JOptionPane.ERROR_MESSAGE);
+		}
+		return result;
+	}
+
+	/**
+	 * Check the proposed port name against the set of ports
+	 * 
+	 * @return
+	 */
+	public boolean portNameExists(String name) {
+		if (name.equalsIgnoreCase("stdin") || name.equalsIgnoreCase("stdout") || name.equalsIgnoreCase("stderr")) {
+			return true;
+		}
+		
+		for (ExternalToolFileViewer v : inputFileViewList) {
+			if (name.equals(v.getName())) {
+				return true;
+			}
+		}
+		for (ExternalToolFileViewer v : fileListViewList) {
+			if (name.equals(v.getName())) {
+				return true;
+			}
+		}
+		for (ExternalToolStringReplacementViewer v : stringReplacementViewList) {
+			if (name.equals(v.getName())) {
+				return true;
+			}
+		}
+		for (ExternalToolFileViewer v : outputViewList) {
+			if (name.equals(v.getName())) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+
+	public void setEditable(boolean editable, ExternalToolActivityConfigurationBean config) {
+		ExternalToolActivityConfigurationBean newConfig = (ExternalToolActivityConfigurationBean) cloneBean(config);
+		ExternalToolActivityHealthChecker.updateLocation(newConfig);
+		newConfig.setEdited(editable);
+		refreshConfiguration(newConfig);		
+	}
+	
+	public void whenClosed() {
+		if (invocationPanel != null) {
+			invocationPanel.stopObserving();
+		}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolFileViewer.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolFileViewer.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolFileViewer.java
new file mode 100644
index 0000000..11fb0c4
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolFileViewer.java
@@ -0,0 +1,103 @@
+/**
+ * 
+ */
+package net.sf.taverna.t2.activities.externaltool.views;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JTextField;
+
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInput;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInputUser;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptOutput;
+
+/**
+ * @author alanrw
+ *
+ */
+public class ExternalToolFileViewer {
+	
+	private JTextField nameField;
+	private String name;
+	private JTextField valueField;
+	private JCheckBox valueFromField;
+	private JComboBox typeSelector;
+
+	public ExternalToolFileViewer(String name, String value, boolean isBinary) {
+		this(name);
+		nameField.setText(name);
+		if (!value.equals(name)) {
+			valueFromField.setSelected(false);
+			valueField.setText(value);
+			valueField.setEnabled(true);
+		}
+		if (isBinary) {
+			typeSelector.setSelectedItem("Binary");
+		} else {
+			typeSelector.setSelectedItem("Text");
+		}
+	}
+
+	public ExternalToolFileViewer(final String name) {
+		this.name = name;
+		nameField = new JTextField(20);
+		valueField = new JTextField(20);
+		valueFromField = new JCheckBox(new AbstractAction() {
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				if (valueFromField.isSelected()) {
+					valueField.setText("");
+					valueField.setEnabled(false);
+				} else {
+					valueField.setText(getName());
+					valueField.setEnabled(true);
+				}
+			}});
+		valueFromField.setSelected(true);
+		valueField.setEnabled(false);
+		typeSelector = new JComboBox(new String[] {"Binary", "Text"});
+		nameField.setText(name);
+		typeSelector.setSelectedItem("Text");
+		
+	}
+
+	public JTextField getNameField() {
+		return nameField;
+	}
+
+	public JTextField getValueField() {
+		return valueField;
+	}
+
+	public JComboBox getTypeSelector() {
+		return typeSelector;
+	}
+
+	public String getName() {
+		return nameField.getText();
+	}
+
+	public boolean isBinary() {
+		return (typeSelector.getSelectedItem().equals("Binary"));
+	}
+
+	public String getValue() {
+		if (valueFromField.isSelected()) {
+			return getName();
+		}
+		return valueField.getText();
+	}
+	
+	/**
+	 * @return the valueFromField
+	 */
+	public JCheckBox getValueFromField() {
+		return valueFromField;
+	}
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolRuntimeEnvironmentViewer.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolRuntimeEnvironmentViewer.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolRuntimeEnvironmentViewer.java
new file mode 100644
index 0000000..1451660
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolRuntimeEnvironmentViewer.java
@@ -0,0 +1,56 @@
+/**
+ * 
+ */
+package net.sf.taverna.t2.activities.externaltool.views;
+
+import javax.swing.JComboBox;
+import javax.swing.JTextField;
+
+import de.uni_luebeck.inb.knowarc.usecases.RuntimeEnvironmentConstraint;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInput;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInputUser;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptOutput;
+
+/**
+ * @author alanrw
+ *
+ */
+public class ExternalToolRuntimeEnvironmentViewer {
+	
+	private JTextField idField;
+	private JComboBox relationSelector;
+
+	public ExternalToolRuntimeEnvironmentViewer(String id, String relation) {
+		this(id);
+		idField.setText(id);
+		relationSelector.setSelectedItem(relation);
+	}
+
+	public ExternalToolRuntimeEnvironmentViewer(String id) {
+		this();
+		idField.setText(id);	
+	}
+	
+	public ExternalToolRuntimeEnvironmentViewer() {
+		idField = new JTextField(20);
+		relationSelector = new JComboBox(RuntimeEnvironmentConstraint.getAcceptedRelations());
+		relationSelector.setSelectedItem(RuntimeEnvironmentConstraint.getDefaultRelation());			
+	}
+
+	public JTextField getIdField() {
+		return idField;
+	}
+
+	public JComboBox getRelationSelector() {
+		return relationSelector;
+	}
+
+	public String getId() {
+		return idField.getText();
+	}
+
+	public String getRelation() {
+		return (String) relationSelector.getSelectedItem();
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolStaticStringViewer.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolStaticStringViewer.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolStaticStringViewer.java
new file mode 100644
index 0000000..d82d9b7
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolStaticStringViewer.java
@@ -0,0 +1,53 @@
+/**
+ * 
+ */
+package net.sf.taverna.t2.activities.externaltool.views;
+
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInputStatic;
+
+/**
+ * @author alanrw
+ *
+ */
+public class ExternalToolStaticStringViewer {
+	
+	ScriptInputStatic input;
+	private JTextArea contentField = new JTextArea();
+	private JTextField valueField;
+
+
+	public ExternalToolStaticStringViewer(ScriptInputStatic input) {
+		this();
+		this.input = input;
+			contentField.setText((String) input.getContent());
+		valueField.setText(input.getTag());
+	}
+
+	public ExternalToolStaticStringViewer() {
+		contentField = new JTextArea(5, 40);
+		contentField.setText("");
+		valueField = new JTextField(20);
+		valueField.setText("");
+	}
+
+	public String getContent() {
+		return contentField.getText();
+	}
+
+	public JTextArea getContentField() {
+		return contentField;
+	}
+
+
+	public JTextField getValueField() {
+		return valueField;
+	}
+
+	public String getValue() {
+		return valueField.getText();
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolStaticUrlViewer.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolStaticUrlViewer.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolStaticUrlViewer.java
new file mode 100644
index 0000000..f7a1793
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolStaticUrlViewer.java
@@ -0,0 +1,56 @@
+/**
+ * 
+ */
+package net.sf.taverna.t2.activities.externaltool.views;
+
+import javax.swing.JComboBox;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInput;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInputStatic;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInputUser;
+
+/**
+ * @author alanrw
+ *
+ */
+public class ExternalToolStaticUrlViewer {
+	
+	ScriptInputStatic input;
+	private JTextField contentField = new JTextField();
+	private JTextField valueField;
+
+
+	public ExternalToolStaticUrlViewer(ScriptInputStatic input) {
+		this();
+		this.input = input;
+		contentField.setText(input.getUrl());
+		valueField.setText(input.getTag());
+	}
+
+	public ExternalToolStaticUrlViewer() {
+		contentField = new JTextField(40);
+		contentField.setText("");
+		valueField = new JTextField(20);
+		valueField.setText("");
+	}
+
+	public String getContent() {
+		return contentField.getText();
+	}
+
+	public JTextField getContentField() {
+		return contentField;
+	}
+
+
+	public JTextField getValueField() {
+		return valueField;
+	}
+
+	public String getValue() {
+		return valueField.getText();
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolStringReplacementViewer.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolStringReplacementViewer.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolStringReplacementViewer.java
new file mode 100644
index 0000000..8e24183
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/ExternalToolStringReplacementViewer.java
@@ -0,0 +1,97 @@
+/**
+ * 
+ */
+package net.sf.taverna.t2.activities.externaltool.views;
+
+import java.awt.event.ActionEvent;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.swing.AbstractAction;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JTextField;
+
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInput;
+import de.uni_luebeck.inb.knowarc.usecases.ScriptInputUser;
+
+/**
+ * @author alanrw
+ *
+ */
+public class ExternalToolStringReplacementViewer {
+	
+	private static Pattern p = Pattern.compile("\\w+");
+	private static final String PERCENTS = "%%";
+	ScriptInput input;
+	private JTextField nameField;
+	private String name;
+	private JTextField valueField;
+	private JCheckBox valueFromField;
+
+	public ExternalToolStringReplacementViewer(String name, ScriptInputUser input) {
+		this(name);
+		this.input = input;
+		nameField.setText(name);
+		if (!input.getTag().equals(name)) {
+			valueFromField.setSelected(false);
+			valueField.setText(PERCENTS + input.getTag() + PERCENTS);
+			valueField.setEnabled(true);
+		}
+	}
+
+	public ExternalToolStringReplacementViewer(String name) {
+		this.name = name;
+		nameField = new JTextField(20);
+		nameField.setText(name);
+		valueField = new JTextField(20);
+		valueFromField = new JCheckBox(new AbstractAction() {
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				if (valueFromField.isSelected()) {
+					valueField.setText("");
+					valueField.setEnabled(false);
+				} else {
+					valueField.setText(PERCENTS + getName() + PERCENTS);
+					valueField.setEnabled(true);
+				}
+			}});
+		valueFromField.setSelected(true);
+		valueField.setEnabled(false);
+	}
+
+	public JTextField getNameField() {
+		return nameField;
+	}
+	
+	public JTextField getValueField() {
+		return valueField;
+	}
+
+	public String getName() {
+		return nameField.getText();
+	}
+
+	public String getValue() {
+		if (valueFromField.isSelected()) {
+			return getName();
+		}
+		String enteredValue = valueField.getText();
+
+		Matcher m = p.matcher(enteredValue);
+		String result = "";
+		if (m.find()) {
+			result = m.group();
+		}
+		return result;
+	}
+
+	/**
+	 * @return the valueFromField
+	 */
+	public JCheckBox getValueFromField() {
+		return valueFromField;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/FilePanel.java
----------------------------------------------------------------------
diff --git a/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/FilePanel.java b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/FilePanel.java
new file mode 100644
index 0000000..678711c
--- /dev/null
+++ b/taverna-external-tool-activity-ui/src/main/java/net/sf/taverna/t2/activities/externaltool/views/FilePanel.java
@@ -0,0 +1,119 @@
+/**
+ * 
+ */
+package net.sf.taverna.t2.activities.externaltool.views;
+
+import java.awt.BorderLayout;
+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.JButton;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.border.EmptyBorder;
+
+import net.sf.taverna.t2.activities.externaltool.utils.Tools;
+import net.sf.taverna.t2.lang.ui.DeselectingButton;
+import net.sf.taverna.t2.lang.ui.ReadOnlyTextArea;
+
+/**
+ * @author alanrw
+ *
+ */
+public class FilePanel extends JPanel {
+	
+	private int outputGridy = 1;
+	private final ExternalToolConfigView view;
+	
+	public FilePanel(final ExternalToolConfigView view,
+			final List<ExternalToolFileViewer> viewList,
+			String fileHeader, String typeHeader, final String portPrefix,
+			final String description, String addText) {
+		super();
+		this.view = view;
+		this.setLayout(new BorderLayout());
+		final JPanel fileEditPanel = new JPanel(new GridBagLayout());
+
+		final GridBagConstraints fileConstraint = new GridBagConstraints();
+		fileConstraint.insets = new Insets(5, 5, 5, 5);
+		fileConstraint.anchor = GridBagConstraints.FIRST_LINE_START;
+		fileConstraint.gridx = 0;
+		fileConstraint.gridy = 0;
+		fileConstraint.weightx = 0.1;
+		fileConstraint.fill = GridBagConstraints.BOTH;
+		
+		final String[] elementLabels = new String[] {"Taverna port name",
+				"Use port name for file",
+				fileHeader,
+				typeHeader
+		};
+
+		fileConstraint.gridx = 0;
+		synchronized (viewList) {
+			for (ExternalToolFileViewer outputView : viewList) {
+				addFileViewer(viewList, this, fileEditPanel,
+						outputView, elementLabels);
+			}
+		}
+		JButton addFilePortButton = new DeselectingButton(addText,
+				new AbstractAction() {
+			public void actionPerformed(ActionEvent e) {
+
+				int portNumber = 1;
+
+				String name2 = portPrefix + portNumber++;
+				boolean nameExists = true;
+				while (nameExists == true) {
+					nameExists = view.portNameExists(name2);
+					if (nameExists) {
+						name2 = portPrefix + portNumber++;
+					}
+				}
+
+				ExternalToolFileViewer newViewer = new ExternalToolFileViewer(
+						name2);
+				synchronized (viewList) {
+					viewList.add(newViewer);
+					addFileViewer(viewList, FilePanel.this, fileEditPanel,
+							newViewer, elementLabels);
+					fileEditPanel.revalidate();
+					fileEditPanel.repaint();
+				}
+			}
+
+		});
+		JTextArea descriptionText = new ReadOnlyTextArea(description);
+		descriptionText.setEditable(false);
+		descriptionText.setFocusable(false);
+		descriptionText.setBorder(new EmptyBorder(5, 5, 10, 5));
+
+		this.add(descriptionText, BorderLayout.NORTH);
+
+		this.add(new JScrollPane(fileEditPanel), BorderLayout.CENTER);
+
+		JPanel buttonPanel = new JPanel(new BorderLayout());
+
+		buttonPanel.add(addFilePortButton, BorderLayout.EAST);
+
+		this.add(buttonPanel, BorderLayout.SOUTH);
+	
+	}
+	
+	private void addFileViewer(final List<ExternalToolFileViewer> viewList,
+			final JPanel outerPanel, final JPanel panel,
+			ExternalToolFileViewer viewer, String[] elementLabels) {
+		Tools.addViewer(panel,
+				elementLabels,
+				new JComponent[] {viewer.getNameField(), viewer.getValueFromField(), viewer.getValueField(), viewer.getTypeSelector()},
+				viewList,
+				viewer,
+				outerPanel);
+	}
+
+}