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:24:54 UTC

[07/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-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/il8n/SpreadsheetImportUIText.java
----------------------------------------------------------------------
diff --git a/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/il8n/SpreadsheetImportUIText.java b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/il8n/SpreadsheetImportUIText.java
new file mode 100644
index 0000000..82f8436
--- /dev/null
+++ b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/il8n/SpreadsheetImportUIText.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (C) 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 net.sf.taverna.t2.activities.spreadsheet.il8n;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Access to a resource bundle containing UI text.
+ *
+ * @author David Withers
+ */
+public class SpreadsheetImportUIText {
+	private static final String BUNDLE_NAME = "net.sf.taverna.t2.activities.spreadsheet.iln8.ui-text";
+
+	private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
+
+	private SpreadsheetImportUIText() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return RESOURCE_BUNDLE.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/menu/SpreadsheetImportAddTemplateAction.java
----------------------------------------------------------------------
diff --git a/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/menu/SpreadsheetImportAddTemplateAction.java b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/menu/SpreadsheetImportAddTemplateAction.java
new file mode 100644
index 0000000..3073acb
--- /dev/null
+++ b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/menu/SpreadsheetImportAddTemplateAction.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (C) 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 net.sf.taverna.t2.activities.spreadsheet.menu;
+
+import java.awt.event.ActionEvent;
+import java.net.URI;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+
+import net.sf.taverna.t2.activities.spreadsheet.il8n.SpreadsheetImportUIText;
+import net.sf.taverna.t2.activities.spreadsheet.servicedescriptions.SpreadsheetImportTemplateService;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+import net.sf.taverna.t2.ui.menu.AbstractContextualMenuAction;
+import net.sf.taverna.t2.ui.menu.MenuManager;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.selection.SelectionManager;
+import net.sf.taverna.t2.workbench.ui.workflowview.WorkflowView;
+import uk.org.taverna.commons.services.ServiceRegistry;
+import uk.org.taverna.scufl2.api.core.Workflow;
+
+/**
+ * An action to add a spreadsheet import activity + a wrapping processor to the workflow.
+ *
+ * @author David Withers
+ */
+@SuppressWarnings("serial")
+public class SpreadsheetImportAddTemplateAction extends AbstractContextualMenuAction {
+
+	private static final URI insertSection = URI
+			.create("http://taverna.sf.net/2009/contextMenu/insert");
+
+	private EditManager editManager;
+	private MenuManager menuManager;
+	private SelectionManager selectionManager;
+	private ActivityIconManager activityIconManager;
+	private ServiceDescriptionRegistry serviceDescriptionRegistry;
+	private ServiceRegistry serviceRegistry;
+
+	public SpreadsheetImportAddTemplateAction() {
+		super(insertSection, 700);
+	}
+
+	@Override
+	public boolean isEnabled() {
+		return super.isEnabled() && getContextualSelection().getSelection() instanceof Workflow;
+	}
+
+	@Override
+	protected Action createAction() {
+
+		AbstractAction action = new AbstractAction(
+				SpreadsheetImportUIText.getString("SpreadsheetImportAddTemplateAction.addMenu"),
+				activityIconManager.iconForActivity(SpreadsheetImportTemplateService.ACTIVITY_TYPE)) {
+
+			public void actionPerformed(ActionEvent e) {
+				WorkflowView.importServiceDescription(serviceDescriptionRegistry
+						.getServiceDescription(SpreadsheetImportTemplateService.ACTIVITY_TYPE), false,
+						editManager, menuManager, selectionManager, serviceRegistry);
+			}
+
+		};
+
+		return action;
+	}
+
+	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;
+	}
+
+	public void setServiceDescriptionRegistry(ServiceDescriptionRegistry serviceDescriptionRegistry) {
+		this.serviceDescriptionRegistry = serviceDescriptionRegistry;
+	}
+
+	public void setServiceRegistry(ServiceRegistry serviceRegistry) {
+		this.serviceRegistry = serviceRegistry;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/menu/SpreadsheetImportAddTemplateMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/menu/SpreadsheetImportAddTemplateMenuAction.java b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/menu/SpreadsheetImportAddTemplateMenuAction.java
new file mode 100644
index 0000000..048073a
--- /dev/null
+++ b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/menu/SpreadsheetImportAddTemplateMenuAction.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * 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 net.sf.taverna.t2.activities.spreadsheet.menu;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.net.URI;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.KeyStroke;
+
+import net.sf.taverna.t2.activities.spreadsheet.il8n.SpreadsheetImportUIText;
+import net.sf.taverna.t2.activities.spreadsheet.servicedescriptions.SpreadsheetImportTemplateService;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+import net.sf.taverna.t2.ui.menu.AbstractMenuAction;
+import net.sf.taverna.t2.ui.menu.DesignOnlyAction;
+import net.sf.taverna.t2.ui.menu.MenuManager;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.selection.SelectionManager;
+import net.sf.taverna.t2.workbench.ui.workflowview.WorkflowView;
+import uk.org.taverna.commons.services.ServiceRegistry;
+
+/**
+ * An action to add a spreadsheet import activity + a wrapping processor to the workflow.
+ *
+ * @author Alan R Williams
+ */
+@SuppressWarnings("serial")
+public class SpreadsheetImportAddTemplateMenuAction extends AbstractMenuAction {
+
+	private static final URI ADD_SPREADSHEET_IMPORT_URI = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#graphMenuAddSpreadsheetImport");
+
+	private static final URI INSERT = URI
+			.create("http://taverna.sf.net/2008/t2workbench/menu#insert");
+
+	private static String ADD_SPREADSHEET_IMPORT = SpreadsheetImportUIText
+			.getString("SpreadsheetImportAddTemplateAction.addMenu");
+
+	private EditManager editManager;
+	private MenuManager menuManager;
+	private SelectionManager selectionManager;
+	private ActivityIconManager activityIconManager;
+	private ServiceDescriptionRegistry serviceDescriptionRegistry;
+	private ServiceRegistry serviceRegistry;
+
+	public SpreadsheetImportAddTemplateMenuAction() {
+		super(INSERT, 700, ADD_SPREADSHEET_IMPORT_URI);
+	}
+
+	@Override
+	protected Action createAction() {
+		return new AddSpreadsheetImportMenuAction();
+	}
+
+	protected class AddSpreadsheetImportMenuAction extends AbstractAction implements
+			DesignOnlyAction {
+		AddSpreadsheetImportMenuAction() {
+			super();
+			putValue(SMALL_ICON,
+					activityIconManager
+							.iconForActivity(SpreadsheetImportTemplateService.ACTIVITY_TYPE));
+			putValue(NAME, ADD_SPREADSHEET_IMPORT);
+			putValue(SHORT_DESCRIPTION, ADD_SPREADSHEET_IMPORT);
+			putValue(
+					Action.ACCELERATOR_KEY,
+					KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.SHIFT_DOWN_MASK
+							| InputEvent.ALT_DOWN_MASK));
+
+		}
+
+		public void actionPerformed(ActionEvent e) {
+			WorkflowView.importServiceDescription(serviceDescriptionRegistry
+					.getServiceDescription(SpreadsheetImportTemplateService.ACTIVITY_TYPE), false,
+					editManager, menuManager, selectionManager, serviceRegistry);
+		}
+	}
+
+	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;
+	}
+
+	public void setServiceDescriptionRegistry(ServiceDescriptionRegistry serviceDescriptionRegistry) {
+		this.serviceDescriptionRegistry = serviceDescriptionRegistry;
+	}
+
+	public void setServiceRegistry(ServiceRegistry serviceRegistry) {
+		this.serviceRegistry = serviceRegistry;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/menu/SpreadsheetImportConfigureMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/menu/SpreadsheetImportConfigureMenuAction.java b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/menu/SpreadsheetImportConfigureMenuAction.java
new file mode 100644
index 0000000..7d1fa0a
--- /dev/null
+++ b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/menu/SpreadsheetImportConfigureMenuAction.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (C) 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 net.sf.taverna.t2.activities.spreadsheet.menu;
+
+import javax.swing.Action;
+
+import uk.org.taverna.commons.services.ServiceRegistry;
+
+import net.sf.taverna.t2.activities.spreadsheet.actions.SpreadsheetImportActivityConfigurationAction;
+import net.sf.taverna.t2.activities.spreadsheet.il8n.SpreadsheetImportUIText;
+import net.sf.taverna.t2.activities.spreadsheet.servicedescriptions.SpreadsheetImportTemplateService;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+import net.sf.taverna.t2.workbench.activitytools.AbstractConfigureActivityMenuAction;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+
+/**
+ * Menu action for SpreadsheetImport activity configuration.
+ *
+ * @author David Withers
+ */
+public class SpreadsheetImportConfigureMenuAction extends AbstractConfigureActivityMenuAction {
+
+	private EditManager editManager;
+	private FileManager fileManager;
+	private ActivityIconManager activityIconManager;
+	private ServiceDescriptionRegistry serviceDescriptionRegistry;
+	private ServiceRegistry serviceRegistry;
+
+	public SpreadsheetImportConfigureMenuAction() {
+		super(SpreadsheetImportTemplateService.ACTIVITY_TYPE);
+	}
+
+	@Override
+	protected Action createAction() {
+		Action result = new SpreadsheetImportActivityConfigurationAction(findActivity(),
+				getParentFrame(), editManager, fileManager, activityIconManager,
+				serviceDescriptionRegistry, serviceRegistry);
+		result.putValue(Action.NAME, SpreadsheetImportUIText
+				.getString("SpreadsheetImportConfigureMenuAction.configureMenu"));
+		addMenuDots(result);
+		return result;
+	}
+
+	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 setServiceDescriptionRegistry(ServiceDescriptionRegistry serviceDescriptionRegistry) {
+		this.serviceDescriptionRegistry = serviceDescriptionRegistry;
+	}
+
+	public void setServiceRegistry(ServiceRegistry serviceRegistry) {
+		this.serviceRegistry = serviceRegistry;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/servicedescriptions/SpreadsheetImportActivityIcon.java
----------------------------------------------------------------------
diff --git a/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/servicedescriptions/SpreadsheetImportActivityIcon.java b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/servicedescriptions/SpreadsheetImportActivityIcon.java
new file mode 100644
index 0000000..1987364
--- /dev/null
+++ b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/servicedescriptions/SpreadsheetImportActivityIcon.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (C) 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 net.sf.taverna.t2.activities.spreadsheet.servicedescriptions;
+
+import java.awt.Color;
+import java.net.URI;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI;
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+
+/**
+ * UI icon for the SpreadsheetImport Activity.
+ *
+ * @author David Withers
+ */
+public class SpreadsheetImportActivityIcon implements ActivityIconSPI {
+
+	public static final String SPREADSHEET_COLOUR_HTML = "#40e0d0";
+	public static final Color SPREADSHEET_COLOUR = Color.decode(SPREADSHEET_COLOUR_HTML);
+
+	private static Icon icon = null;
+
+	@Override
+	public int canProvideIconScore(URI activityType) {
+		if (SpreadsheetImportTemplateService.ACTIVITY_TYPE.equals(activityType))
+			return DEFAULT_ICON + 1;
+		else
+			return NO_ICON;
+	}
+
+	@Override
+	public Icon getIcon(URI activityType) {
+		return getSpreadsheetImportIcon();
+	}
+
+	public static Icon getSpreadsheetImportIcon() {
+		if (icon == null) {
+			icon = new ImageIcon(
+					SpreadsheetImportActivityIcon.class.getResource("/spreadsheet-import.png"));
+		}
+		return icon;
+	}
+
+	public void setColourManager(ColourManager colourManager) {
+		colourManager.setPreferredColour(
+				"http://ns.taverna.org.uk/2010/activity/spreadsheet-import",
+				SPREADSHEET_COLOUR);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/servicedescriptions/SpreadsheetImportTemplateService.java
----------------------------------------------------------------------
diff --git a/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/servicedescriptions/SpreadsheetImportTemplateService.java b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/servicedescriptions/SpreadsheetImportTemplateService.java
new file mode 100644
index 0000000..8057f2d
--- /dev/null
+++ b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/servicedescriptions/SpreadsheetImportTemplateService.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (C) 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 net.sf.taverna.t2.activities.spreadsheet.servicedescriptions;
+
+import java.net.URI;
+
+import javax.swing.Icon;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import net.sf.taverna.t2.activities.spreadsheet.il8n.SpreadsheetImportUIText;
+import net.sf.taverna.t2.servicedescriptions.AbstractTemplateService;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescription;
+import uk.org.taverna.scufl2.api.configurations.Configuration;
+
+/**
+ * Definition of the SpreadsheetImport spreadsheet import template service.
+ *
+ * @author David Withers
+ */
+public class SpreadsheetImportTemplateService extends AbstractTemplateService {
+
+	public static final URI ACTIVITY_TYPE = URI
+			.create("http://ns.taverna.org.uk/2010/activity/spreadsheet-import");
+
+	private static final String SERVICE_NAME = SpreadsheetImportUIText
+			.getString("SpreadsheetImportTemplateService.serviceName");
+
+	private static final URI providerId = URI
+			.create("http://taverna.sf.net/2010/service-provider/spreadsheet");
+
+	public String getName() {
+		return SERVICE_NAME;
+	}
+
+	@Override
+	public URI getActivityType() {
+		return ACTIVITY_TYPE;
+	}
+
+	@Override
+	public Configuration getActivityConfiguration() {
+		Configuration configuration = new Configuration();
+		configuration.setType(ACTIVITY_TYPE.resolve("#Config"));
+		ObjectNode json = (ObjectNode) configuration.getJson();
+		json.put("columnRange", json.objectNode().put("start", 0).put("end", 1));
+		json.put("rowRange", json.objectNode().put("start", 0).put("end", -1));
+		json.put("emptyCellValue", "");
+		json.put("allRows", true);
+		json.put("excludeFirstRow", false);
+		json.put("ignoreBlankRows", false);
+		json.put("emptyCellPolicy", "EMPTY_STRING");
+		json.put("outputFormat", "PORT_PER_COLUMN");
+		json.put("csvDelimiter", ",");
+		return configuration;
+	}
+
+	@Override
+	public Icon getIcon() {
+		return SpreadsheetImportActivityIcon.getSpreadsheetImportIcon();
+	}
+
+	@Override
+	public String getDescription() {
+		return SpreadsheetImportUIText
+				.getString("SpreadsheetImportTemplateService.serviceDescription");
+	}
+
+	public static ServiceDescription getServiceDescription() {
+		SpreadsheetImportTemplateService bts = new SpreadsheetImportTemplateService();
+		return bts.templateService;
+	}
+
+	public String getId() {
+		return providerId.toString();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportConfigTableModel.java
----------------------------------------------------------------------
diff --git a/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportConfigTableModel.java b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportConfigTableModel.java
new file mode 100644
index 0000000..0409b8e
--- /dev/null
+++ b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportConfigTableModel.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (C) 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 net.sf.taverna.t2.activities.spreadsheet.views;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.table.AbstractTableModel;
+
+import net.sf.taverna.t2.activities.spreadsheet.SpreadsheetUtils;
+import net.sf.taverna.t2.activities.spreadsheet.il8n.SpreadsheetImportUIText;
+
+/**
+ * TableModel for mapping column labels to port names.
+ * <p>
+ * The default mapping is for the port name to be the same as the column label. The
+ * columnToPortMapping only contains entries for port names that are not the same as the column
+ * label.
+ *
+ * @author David Withers
+ */
+@SuppressWarnings("serial")
+public class SpreadsheetImportConfigTableModel extends AbstractTableModel {
+
+	private Map<String, String> columnToPortMapping;
+
+	private int fromColumn, toColumn;
+
+	/**
+	 * Constructs a TableModel that maps column labels to port names for the specified range of
+	 * columns.
+	 *
+	 * @param fromColumn
+	 *            the start of the column range
+	 * @param toColumn
+	 *            the end of the column range
+	 * @param columnToPortMapping
+	 *            existing column to port mappings (can be null)
+	 */
+	public SpreadsheetImportConfigTableModel(String fromColumn, String toColumn,
+			Map<String, String> columnToPortMapping) {
+		if (columnToPortMapping == null) {
+			this.columnToPortMapping = new HashMap<String, String>();
+		} else {
+			this.columnToPortMapping = new HashMap<String, String>(columnToPortMapping);
+		}
+		this.fromColumn = SpreadsheetUtils.getColumnIndex(fromColumn);
+		this.toColumn = SpreadsheetUtils.getColumnIndex(toColumn);
+	}
+
+	/**
+	 * Sets the start of the column range.
+	 *
+	 * @param fromColumn
+	 *            the start of the column range
+	 */
+	public void setFromColumn(int fromColumn) {
+		if (this.fromColumn != fromColumn) {
+			this.fromColumn = fromColumn;
+			fireTableStructureChanged();
+		}
+	}
+
+	/**
+	 * Sets the end of the column range.
+	 *
+	 * @param toColumn
+	 *            the end of the column range
+	 */
+	public void setToColumn(int toColumn) {
+		if (this.toColumn != toColumn) {
+			this.toColumn = toColumn;
+			fireTableStructureChanged();
+		}
+	}
+
+	/**
+	 * Returns the port name for the given column label.
+	 * <p>
+	 * If the columnLabel is the columnToPortMapping the value is returned; otherwise the
+	 * columnLabel is returned.
+	 *
+	 * @param columnLabel
+	 *            the column to find the port name for
+	 * @return the port name for the given column label
+	 */
+	public String getPortName(String columnLabel) {
+		String portName;
+		if (columnToPortMapping.containsKey(columnLabel)) {
+			portName = columnToPortMapping.get(columnLabel);
+		} else {
+			portName = columnLabel;
+		}
+		return portName;
+	}
+
+	/**
+	 * Sets the port name for the column label.
+	 * <p>
+	 * If the port name is not the same as the column label the port name is added the
+	 * columnToPortMapping.
+	 *
+	 * @param columnLabel
+	 * @param portName
+	 */
+	public void setPortName(String columnLabel, String portName) {
+		if (columnLabel.equals(portName)) {
+			columnToPortMapping.remove(columnLabel);
+		} else {
+			columnToPortMapping.put(columnLabel, portName);
+		}
+	}
+
+	/**
+	 * Returns the map of column labels to port names.
+	 * <p>
+	 * The map only contains entries for port names that are not the same as their corresponding
+	 * column label.
+	 *
+	 * @return the map of column labels to port names
+	 */
+	public Map<String, String> getColumnToPortMapping() {
+		return columnToPortMapping;
+	}
+
+	// TableModel methods
+
+	@Override
+	public Class<?> getColumnClass(int columnIndex) {
+		return String.class;
+	}
+
+	public int getColumnCount() {
+		return 2;
+	}
+
+	@Override
+	public String getColumnName(int columnIndex) {
+		if (columnIndex == 0) {
+			return SpreadsheetImportUIText.getString("SpreadsheetImportConfigTableModel.column");
+		} else {
+			return SpreadsheetImportUIText.getString("SpreadsheetImportConfigTableModel.portName");
+		}
+	}
+
+	public int getRowCount() {
+		return toColumn - fromColumn + 1;
+	}
+
+	public Object getValueAt(int rowIndex, int columnIndex) {
+		String columnLabel = SpreadsheetUtils.getColumnLabel(rowIndex + fromColumn);
+		if (columnIndex == 0) {
+			return columnLabel;
+		} else {
+			return getPortName(columnLabel);
+		}
+	}
+
+	@Override
+	public boolean isCellEditable(int rowIndex, int columnIndex) {
+		return columnIndex == 1;
+	}
+
+	@Override
+	public void setValueAt(Object value, int rowIndex, int columnIndex) {
+		if (columnIndex == 1) {
+			setPortName(SpreadsheetUtils.getColumnLabel(rowIndex + fromColumn), value.toString());
+		}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportConfigView.java
----------------------------------------------------------------------
diff --git a/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportConfigView.java b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportConfigView.java
new file mode 100644
index 0000000..af57c44
--- /dev/null
+++ b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportConfigView.java
@@ -0,0 +1,1082 @@
+/*******************************************************************************
+ * Copyright (C) 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 net.sf.taverna.t2.activities.spreadsheet.views;
+
+import java.awt.BorderLayout;
+import java.awt.CardLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.Graphics;
+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.ItemEvent;
+import java.awt.event.ItemListener;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.Stack;
+
+import javax.swing.ButtonGroup;
+import javax.swing.DefaultCellEditor;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.SwingConstants;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.table.DefaultTableColumnModel;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableColumn;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.PlainDocument;
+
+import net.sf.taverna.t2.activities.spreadsheet.Range;
+import net.sf.taverna.t2.activities.spreadsheet.SpreadsheetUtils;
+import net.sf.taverna.t2.activities.spreadsheet.il8n.SpreadsheetImportUIText;
+import net.sf.taverna.t2.lang.ui.DialogTextArea;
+import net.sf.taverna.t2.lang.ui.icons.Icons;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ActivityConfigurationPanel;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.log4j.Logger;
+
+import uk.org.taverna.commons.services.ServiceRegistry;
+import uk.org.taverna.scufl2.api.activity.Activity;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Configuration panel for the spreadsheet import activity.
+ *
+ * @author David Withers
+ */
+@SuppressWarnings("serial")
+public class SpreadsheetImportConfigView extends ActivityConfigurationPanel {
+
+	private static final String INCONSISTENT_ROW_MESSAGE = SpreadsheetImportUIText
+			.getString("SpreadsheetImportConfigView.INCONSISTENT_ROW_MESSAGE");
+
+	private static final String INCONSISTENT_COLUMN_MESSAGE = SpreadsheetImportUIText
+			.getString("SpreadsheetImportConfigView.INCONSISTENT_COLUMN_MESSAGE");
+
+	private static final String FROM_COLUMN_ERROR_MESSAGE = SpreadsheetImportUIText
+			.getString("SpreadsheetImportConfigView.FROM_COLUMN_ERROR_MESSAGE");
+
+	private static final String TO_COLUMN_ERROR_MESSAGE = SpreadsheetImportUIText
+			.getString("SpreadsheetImportConfigView.TO_COLUMN_ERROR_MESSAGE");
+
+	private static final String FROM_ROW_ERROR_MESSAGE = SpreadsheetImportUIText
+			.getString("SpreadsheetImportConfigView.FROM_ROW_ERROR_MESSAGE");
+
+	private static final String TO_ROW_ERROR_MESSAGE = SpreadsheetImportUIText
+			.getString("SpreadsheetImportConfigView.TO_ROW_ERROR_MESSAGE");
+
+	private static final String DEFAULT_MESSAGE = SpreadsheetImportUIText
+			.getString("SpreadsheetImportConfigView.DEFAULT_MESSAGE");
+
+	private static final String EMPTY_FROM_ROW_ERROR_MESSAGE = SpreadsheetImportUIText
+			.getString("SpreadsheetImportConfigView.EMPTY_FROM_ROW_ERROR_MESSAGE");
+
+	private static final String EMPTY_FROM_COLUMN_ERROR_MESSAGE = SpreadsheetImportUIText
+			.getString("SpreadsheetImportConfigView.EMPTY_FROM_COLUMN_ERROR_MESSAGE");
+
+	private static final String EMPTY_TO_COLUMN_ERROR_MESSAGE = SpreadsheetImportUIText
+			.getString("SpreadsheetImportConfigView.EMPTY_TO_COLUMN_ERROR_MESSAGE");
+
+	private static final String DUPLICATE_PORT_NAME_ERROR_MESSAGE = SpreadsheetImportUIText
+			.getString("SpreadsheetImportConfigView.DUPLICATE_PORT_NAME_ERROR_MESSAGE");
+
+	private static Logger logger = Logger.getLogger(SpreadsheetImportConfigView.class);
+
+	private JPanel titlePanel, contentPanel, buttonPanel, page1, page2;
+
+	private JLabel titleLabel, titleIcon, rowLabel, columnLabel;
+
+	private JLabel emptyCellLabel, outputFormatLabel, outputFormatDelimiterLabel, columnMappingLabel;
+
+	private DialogTextArea titleMessage;
+
+	private JTextField columnFromValue, columnToValue, rowFromValue, rowToValue;
+
+	private JTextField emptyCellUserDefinedValue, outputFormatDelimiter;
+
+	private JCheckBox rowSelectAllOption, rowExcludeFirstOption, rowIgnoreBlankRows;
+
+	private ButtonGroup emptyCellButtonGroup, outputFormatButtonGroup;
+
+	private JRadioButton emptyCellEmptyStringOption, emptyCellUserDefinedOption,
+	emptyCellErrorValueOption;
+
+	private JRadioButton outputFormatMultiplePort, outputFormatSinglePort;
+
+	private JTable columnMappingTable;
+
+	private SpreadsheetImportConfigTableModel columnMappingTableModel;
+
+	private JButton nextButton, backButton;
+
+	private CardLayout cardLayout = new CardLayout();
+
+	private Stack<String> warningMessages = new Stack<String>();
+
+	private Stack<String> errorMessages = new Stack<String>();
+
+	private ObjectNode newConfiguration;
+
+	private final ServiceRegistry serviceRegistry;
+
+	/**
+	 * Constructs a configuration view for an SpreadsheetImport Activity.
+	 *
+	 * @param activity
+	 */
+	public SpreadsheetImportConfigView(Activity activity, ServiceRegistry serviceRegistry) {
+		super(activity);
+		this.serviceRegistry = serviceRegistry;
+		initialise();
+	}
+
+	@Override
+	protected void initialise() {
+		super.initialise();
+		newConfiguration = getJson().deepCopy();
+
+		// title
+		titlePanel = new JPanel(new BorderLayout());
+		titlePanel.setBackground(Color.WHITE);
+		addDivider(titlePanel, SwingConstants.BOTTOM, true);
+
+		titleLabel = new JLabel(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.panelTitle"));
+		titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, 13.5f));
+		titleIcon = new JLabel("");
+		titleMessage = new DialogTextArea(DEFAULT_MESSAGE);
+		titleMessage.setMargin(new Insets(5, 10, 10, 10));
+		// titleMessage.setMinimumSize(new Dimension(0, 30));
+		titleMessage.setFont(titleMessage.getFont().deriveFont(11f));
+		titleMessage.setEditable(false);
+		titleMessage.setFocusable(false);
+		// titleMessage.setFont(titleLabel.getFont().deriveFont(Font.PLAIN,
+		// 12f));
+
+		// column range
+		columnLabel = new JLabel(SpreadsheetImportUIText
+				.getString("SpreadsheetImportConfigView.columnSectionLabel"));
+
+		JsonNode columnRange = newConfiguration.get("columnRange");
+		columnFromValue = new JTextField(new UpperCaseDocument(), SpreadsheetUtils.getColumnLabel(columnRange.get("start").intValue()), 4);
+		columnFromValue.setMinimumSize(columnFromValue.getPreferredSize());
+		columnToValue = new JTextField(new UpperCaseDocument(), SpreadsheetUtils.getColumnLabel(columnRange.get("end").intValue()), 4);
+		columnToValue.setMinimumSize(columnToValue.getPreferredSize());
+
+		columnFromValue.getDocument().addDocumentListener(new DocumentListener() {
+			public void changedUpdate(DocumentEvent e) {
+			}
+
+			public void insertUpdate(DocumentEvent e) {
+				checkValue(columnFromValue.getText());
+			}
+
+			public void removeUpdate(DocumentEvent e) {
+				checkValue(columnFromValue.getText());
+			}
+
+			private void checkValue(String text) {
+				if (text.trim().equals("")) {
+					addErrorMessage(EMPTY_FROM_COLUMN_ERROR_MESSAGE);
+				} else if (text.trim().matches("[A-Za-z]+")) {
+					String fromColumn = columnFromValue.getText().toUpperCase();
+					String toColumn = columnToValue.getText().toUpperCase();
+					int fromColumnIndex = SpreadsheetUtils.getColumnIndex(fromColumn);
+					int toColumnIndex = SpreadsheetUtils.getColumnIndex(toColumn);
+					if (checkColumnRange(fromColumnIndex, toColumnIndex)) {
+						columnMappingTableModel.setFromColumn(fromColumnIndex);
+						columnMappingTableModel.setToColumn(toColumnIndex);
+						newConfiguration.set("columnRange", newConfiguration.objectNode().put("start", fromColumnIndex).put("end", toColumnIndex));
+						validatePortNames();
+					}
+					removeErrorMessage(FROM_COLUMN_ERROR_MESSAGE);
+					removeErrorMessage(EMPTY_FROM_COLUMN_ERROR_MESSAGE);
+				} else {
+					addErrorMessage(FROM_COLUMN_ERROR_MESSAGE);
+					removeErrorMessage(EMPTY_FROM_COLUMN_ERROR_MESSAGE);
+				}
+			}
+
+		});
+
+		columnToValue.getDocument().addDocumentListener(new DocumentListener() {
+			public void changedUpdate(DocumentEvent e) {
+			}
+
+			public void insertUpdate(DocumentEvent e) {
+				checkValue(columnToValue.getText());
+			}
+
+			public void removeUpdate(DocumentEvent e) {
+				checkValue(columnToValue.getText());
+			}
+
+			private void checkValue(String text) {
+				if (text.trim().equals("")) {
+					addErrorMessage(EMPTY_TO_COLUMN_ERROR_MESSAGE);
+				} else if (text.trim().matches("[A-Za-z]+")) {
+					String fromColumn = columnFromValue.getText().toUpperCase();
+					String toColumn = columnToValue.getText().toUpperCase();
+					int fromColumnIndex = SpreadsheetUtils.getColumnIndex(fromColumn);
+					int toColumnIndex = SpreadsheetUtils.getColumnIndex(toColumn);
+					if (checkColumnRange(fromColumnIndex, toColumnIndex)) {
+						columnMappingTableModel.setFromColumn(fromColumnIndex);
+						columnMappingTableModel.setToColumn(toColumnIndex);
+						newConfiguration.set("columnRange", newConfiguration.objectNode().put("start", fromColumnIndex).put("end", toColumnIndex));
+						validatePortNames();
+					}
+					removeErrorMessage(TO_COLUMN_ERROR_MESSAGE);
+					removeErrorMessage(EMPTY_TO_COLUMN_ERROR_MESSAGE);
+
+				} else {
+					addErrorMessage(TO_COLUMN_ERROR_MESSAGE);
+					removeErrorMessage(EMPTY_TO_COLUMN_ERROR_MESSAGE);
+				}
+			}
+		});
+
+		// row range
+		rowLabel = new JLabel(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.rowSectionLabel"));
+		addDivider(rowLabel, SwingConstants.TOP, false);
+
+		rowSelectAllOption = new JCheckBox(SpreadsheetImportUIText
+				.getString("SpreadsheetImportConfigView.selectAllRowsOption"));
+		rowExcludeFirstOption = new JCheckBox(SpreadsheetImportUIText
+				.getString("SpreadsheetImportConfigView.excludeHeaderRowOption"));
+		rowIgnoreBlankRows = new JCheckBox(SpreadsheetImportUIText
+				.getString("SpreadsheetImportConfigView.ignoreBlankRowsOption"));
+		rowSelectAllOption.setFocusable(false);
+		rowExcludeFirstOption.setFocusable(false);
+
+		JsonNode rowRange = newConfiguration.get("rowRange");
+		rowFromValue = new JTextField(new NumericDocument(), String.valueOf(rowRange.get("start").intValue() + 1), 4);
+		if (rowRange.get("end").intValue() == -1) {
+			rowToValue = new JTextField(new NumericDocument(), "", 4);
+		} else {
+			rowToValue = new JTextField(new NumericDocument(), String.valueOf(rowRange.get("end").intValue() + 1), 4);
+		}
+		rowFromValue.setMinimumSize(rowFromValue.getPreferredSize());
+		rowToValue.setMinimumSize(rowToValue.getPreferredSize());
+
+		if (newConfiguration.get("allRows").booleanValue()) {
+			rowSelectAllOption.setSelected(true);
+			rowFromValue.setEditable(false);
+			rowFromValue.setEnabled(false);
+			rowToValue.setEditable(false);
+			rowToValue.setEnabled(false);
+		} else {
+			rowExcludeFirstOption.setEnabled(false);
+		}
+		rowExcludeFirstOption.setSelected(newConfiguration.get("excludeFirstRow").booleanValue());
+		rowIgnoreBlankRows.setSelected(newConfiguration.get("ignoreBlankRows").booleanValue());
+
+		rowFromValue.getDocument().addDocumentListener(new DocumentListener() {
+			public void changedUpdate(DocumentEvent e) {
+			}
+
+			public void insertUpdate(DocumentEvent e) {
+				checkValue(rowFromValue.getText());
+			}
+
+			public void removeUpdate(DocumentEvent e) {
+				checkValue(rowFromValue.getText());
+			}
+
+			private void checkValue(String text) {
+				if (text.trim().equals("")) {
+					addErrorMessage(EMPTY_FROM_ROW_ERROR_MESSAGE);
+				} else if (text.trim().matches("[1-9][0-9]*")) {
+					checkRowRange(rowFromValue.getText(), rowToValue.getText());
+					int fromRow = Integer.parseInt(rowFromValue.getText());
+					((ObjectNode) newConfiguration.get("rowRange")).put("start", fromRow - 1);
+					removeErrorMessage(FROM_ROW_ERROR_MESSAGE);
+					removeErrorMessage(EMPTY_FROM_ROW_ERROR_MESSAGE);
+				} else {
+					addErrorMessage(FROM_ROW_ERROR_MESSAGE);
+					removeErrorMessage(EMPTY_FROM_ROW_ERROR_MESSAGE);
+				}
+			}
+		});
+
+		rowToValue.getDocument().addDocumentListener(new DocumentListener() {
+			public void changedUpdate(DocumentEvent e) {
+			}
+
+			public void insertUpdate(DocumentEvent e) {
+				checkValue(rowToValue.getText());
+			}
+
+			public void removeUpdate(DocumentEvent e) {
+				checkValue(rowToValue.getText());
+			}
+
+			private void checkValue(String text) {
+				if (text.trim().equals("")) {
+					((ObjectNode) newConfiguration.get("rowRange")).put("end", -1);
+					removeErrorMessage(TO_ROW_ERROR_MESSAGE);
+					removeErrorMessage(INCONSISTENT_ROW_MESSAGE);
+				} else if (text.trim().matches("[0-9]+")) {
+					checkRowRange(rowFromValue.getText(), rowToValue.getText());
+					int toRow = Integer.parseInt(rowToValue.getText());
+					((ObjectNode) newConfiguration.get("rowRange")).put("end", toRow - 1);
+					removeErrorMessage(TO_ROW_ERROR_MESSAGE);
+				} else {
+					addErrorMessage(TO_ROW_ERROR_MESSAGE);
+				}
+			}
+		});
+
+		rowSelectAllOption.addItemListener(new ItemListener() {
+			public void itemStateChanged(ItemEvent e) {
+				if (e.getStateChange() == ItemEvent.SELECTED) {
+					newConfiguration.put("allRows", true);
+					rowExcludeFirstOption.setEnabled(true);
+					if (rowExcludeFirstOption.isSelected()) {
+						rowFromValue.setText("2");
+					} else {
+						rowFromValue.setText("1");
+					}
+					rowToValue.setText("");
+					rowFromValue.setEditable(false);
+					rowFromValue.setEnabled(false);
+					rowToValue.setEditable(false);
+					rowToValue.setEnabled(false);
+				} else {
+					newConfiguration.put("allRows", false);
+					rowExcludeFirstOption.setEnabled(false);
+					rowFromValue.setEditable(true);
+					rowFromValue.setEnabled(true);
+					rowToValue.setEditable(true);
+					rowToValue.setEnabled(true);
+				}
+			}
+		});
+
+		rowExcludeFirstOption.addItemListener(new ItemListener() {
+			public void itemStateChanged(ItemEvent e) {
+				if (e.getStateChange() == ItemEvent.SELECTED) {
+					newConfiguration.put("excludeFirstRow", true);
+					rowFromValue.setText("2");
+					((ObjectNode) newConfiguration.get("rowRange")).put("start", 1);
+				} else {
+					newConfiguration.put("excludeFirstRow", false);
+					rowFromValue.setText("1");
+					((ObjectNode) newConfiguration.get("rowRange")).put("start", 0);
+				}
+			}
+		});
+
+		rowIgnoreBlankRows.addItemListener(new ItemListener() {
+			public void itemStateChanged(ItemEvent e) {
+				newConfiguration.put("ignoreBlankRows", e.getStateChange() == ItemEvent.SELECTED);
+			}
+		});
+
+		// empty cells
+		emptyCellLabel = new JLabel(SpreadsheetImportUIText
+				.getString("SpreadsheetImportConfigView.emptyCellSectionLabel"));
+		addDivider(emptyCellLabel, SwingConstants.TOP, false);
+
+		emptyCellButtonGroup = new ButtonGroup();
+		emptyCellEmptyStringOption = new JRadioButton(SpreadsheetImportUIText
+				.getString("SpreadsheetImportConfigView.emptyStringOption"));
+		emptyCellUserDefinedOption = new JRadioButton(SpreadsheetImportUIText
+				.getString("SpreadsheetImportConfigView.userDefinedOption"));
+		emptyCellErrorValueOption = new JRadioButton(SpreadsheetImportUIText
+				.getString("SpreadsheetImportConfigView.generateErrorOption"));
+		emptyCellEmptyStringOption.setFocusable(false);
+		emptyCellUserDefinedOption.setFocusable(false);
+		emptyCellErrorValueOption.setFocusable(false);
+
+		emptyCellUserDefinedValue = new JTextField(newConfiguration.get("emptyCellValue").textValue());
+
+		emptyCellButtonGroup.add(emptyCellEmptyStringOption);
+		emptyCellButtonGroup.add(emptyCellUserDefinedOption);
+		emptyCellButtonGroup.add(emptyCellErrorValueOption);
+
+		if (newConfiguration.get("emptyCellPolicy").textValue().equals("GENERATE_ERROR")) {
+			emptyCellErrorValueOption.setSelected(true);
+			emptyCellUserDefinedValue.setEnabled(false);
+			emptyCellUserDefinedValue.setEditable(false);
+		} else if (newConfiguration.get("emptyCellPolicy").textValue().equals("EMPTY_STRING")) {
+			emptyCellEmptyStringOption.setSelected(true);
+			emptyCellUserDefinedValue.setEnabled(false);
+			emptyCellUserDefinedValue.setEditable(false);
+		} else {
+			emptyCellUserDefinedOption.setSelected(true);
+			emptyCellUserDefinedValue.setText(newConfiguration.get("emptyCellValue").textValue());
+			emptyCellUserDefinedValue.setEnabled(true);
+			emptyCellUserDefinedValue.setEditable(true);
+		}
+
+		emptyCellEmptyStringOption.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				newConfiguration.put("emptyCellPolicy", "EMPTY_STRING");
+				emptyCellUserDefinedValue.setEnabled(false);
+				emptyCellUserDefinedValue.setEditable(false);
+			}
+		});
+		emptyCellUserDefinedOption.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				newConfiguration.put("emptyCellPolicy", "USER_DEFINED");
+				emptyCellUserDefinedValue.setEnabled(true);
+				emptyCellUserDefinedValue.setEditable(true);
+				emptyCellUserDefinedValue.requestFocusInWindow();
+			}
+		});
+		emptyCellErrorValueOption.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				newConfiguration.put("emptyCellPolicy", "GENERATE_ERROR");
+				emptyCellUserDefinedValue.setEnabled(false);
+				emptyCellUserDefinedValue.setEditable(false);
+			}
+		});
+
+		emptyCellUserDefinedValue.getDocument().addDocumentListener(new DocumentListener() {
+			public void changedUpdate(DocumentEvent e) {
+				newConfiguration.put("emptyCellValue", emptyCellUserDefinedValue.getText());
+			}
+
+			public void insertUpdate(DocumentEvent e) {
+				newConfiguration.put("emptyCellValue", emptyCellUserDefinedValue.getText());
+			}
+
+			public void removeUpdate(DocumentEvent e) {
+				newConfiguration.put("emptyCellValue", emptyCellUserDefinedValue.getText());
+			}
+		});
+
+		// column mappings
+		columnMappingLabel = new JLabel(SpreadsheetImportUIText
+				.getString("SpreadsheetImportConfigView.columnMappingSectionLabel"));
+		addDivider(columnMappingLabel, SwingConstants.TOP, false);
+
+		Map<String, String> columnToPortMapping = new HashMap<>();
+		if (newConfiguration.has("columnNames")) {
+			for (JsonNode columnName : newConfiguration.get("columnNames")) {
+				columnToPortMapping.put(columnName.get("column").textValue(), columnName.get("port").textValue());
+			}
+		}
+		columnMappingTableModel = new SpreadsheetImportConfigTableModel(columnFromValue.getText(),
+				columnToValue.getText(), columnToPortMapping);
+
+		columnMappingTable = new JTable();
+		columnMappingTable.setRowSelectionAllowed(false);
+		columnMappingTable.getTableHeader().setReorderingAllowed(false);
+		columnMappingTable.setGridColor(Color.LIGHT_GRAY);
+		// columnMappingTable.setFocusable(false);
+
+		columnMappingTable.setColumnModel(new DefaultTableColumnModel() {
+			public TableColumn getColumn(int columnIndex) {
+				TableColumn column = super.getColumn(columnIndex);
+				if (columnIndex == 0) {
+					column.setMaxWidth(100);
+				}
+				return column;
+			}
+		});
+
+		TableCellEditor defaultEditor = columnMappingTable.getDefaultEditor(String.class);
+		if (defaultEditor instanceof DefaultCellEditor) {
+			DefaultCellEditor defaultCellEditor = (DefaultCellEditor) defaultEditor;
+			defaultCellEditor.setClickCountToStart(1);
+			Component editorComponent = defaultCellEditor.getComponent();
+			if (editorComponent instanceof JTextComponent) {
+				final JTextComponent textField = (JTextComponent) editorComponent;
+				textField.getDocument().addDocumentListener(new DocumentListener() {
+					public void changedUpdate(DocumentEvent e) {
+						updateModel(textField.getText());
+					}
+
+					public void insertUpdate(DocumentEvent e) {
+						updateModel(textField.getText());
+					}
+
+					public void removeUpdate(DocumentEvent e) {
+						updateModel(textField.getText());
+					}
+
+					private void updateModel(String text) {
+						int row = columnMappingTable.getEditingRow();
+						int column = columnMappingTable.getEditingColumn();
+						columnMappingTableModel.setValueAt(text, row, column);
+
+						ArrayNode columnNames = newConfiguration.arrayNode();
+						Map<String, String> columnToPortMapping = columnMappingTableModel.getColumnToPortMapping();
+						for (Entry<String,String> entry : columnToPortMapping.entrySet()) {
+							columnNames.add(newConfiguration.objectNode().put("column", entry.getKey()).put("port", entry.getValue()));
+						}
+						newConfiguration.put("columnNames", columnNames);
+						validatePortNames();
+					}
+
+				});
+			}
+		}
+
+		columnMappingTable.setModel(columnMappingTableModel);
+
+		// output format
+		outputFormatLabel = new JLabel(SpreadsheetImportUIText
+				.getString("SpreadsheetImportConfigView.outputFormatSectionLabel"));
+
+		outputFormatMultiplePort = new JRadioButton(SpreadsheetImportUIText
+				.getString("SpreadsheetImportConfigView.multiplePortOption"));
+		outputFormatSinglePort = new JRadioButton(SpreadsheetImportUIText
+				.getString("SpreadsheetImportConfigView.singlePortOption"));
+		outputFormatMultiplePort.setFocusable(false);
+		outputFormatSinglePort.setFocusable(false);
+
+		outputFormatDelimiterLabel = new JLabel(SpreadsheetImportUIText
+				.getString("SpreadsheetImportConfigView.userDefinedCsvDelimiter"));
+		outputFormatDelimiter = new JTextField(newConfiguration.get("csvDelimiter").textValue(), 5);
+
+		outputFormatButtonGroup = new ButtonGroup();
+		outputFormatButtonGroup.add(outputFormatMultiplePort);
+		outputFormatButtonGroup.add(outputFormatSinglePort);
+
+		if (newConfiguration.get("outputFormat").textValue().equals("PORT_PER_COLUMN")) {
+			outputFormatMultiplePort.setSelected(true);
+			outputFormatDelimiterLabel.setEnabled(false);
+			outputFormatDelimiter.setEnabled(false);
+		} else {
+			outputFormatSinglePort.setSelected(true);
+			columnMappingLabel.setEnabled(false);
+			enableTable(columnMappingTable, false);
+		}
+
+		outputFormatMultiplePort.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				outputFormatDelimiterLabel.setEnabled(false);
+				outputFormatDelimiter.setEnabled(false);
+				columnMappingLabel.setEnabled(true);
+				enableTable(columnMappingTable, true);
+				newConfiguration.put("outputFormat", "PORT_PER_COLUMN");
+			}
+		});
+		outputFormatSinglePort.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				outputFormatDelimiterLabel.setEnabled(true);
+				outputFormatDelimiter.setEnabled(true);
+				columnMappingLabel.setEnabled(false);
+				enableTable(columnMappingTable, false);
+				newConfiguration.put("outputFormat", "SINGLE_PORT");
+			}
+
+		});
+		outputFormatDelimiter.getDocument().addDocumentListener(new DocumentListener() {
+			public void changedUpdate(DocumentEvent e) {
+				handleUpdate();
+			}
+
+			public void insertUpdate(DocumentEvent e) {
+				handleUpdate();
+			}
+
+			public void removeUpdate(DocumentEvent e) {
+				handleUpdate();
+			}
+
+			private void handleUpdate() {
+				String text = null;
+				try {
+					text = StringEscapeUtils.unescapeJava(outputFormatDelimiter.getText());
+				} catch (RuntimeException re) {}
+				if (text == null || text.length() == 0) {
+					newConfiguration.put("csvDelimiter", ",");
+				} else {
+					newConfiguration.put("csvDelimiter", text.substring(0, 1));
+				}
+			}
+
+		});
+
+		// buttons
+		nextButton = new JButton(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.nextButton"));
+		nextButton.setFocusable(false);
+		nextButton.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				backButton.setVisible(true);
+				nextButton.setVisible(false);
+				cardLayout.last(contentPanel);
+			}
+		});
+
+		backButton = new JButton(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.backButton"));
+		backButton.setFocusable(false);
+		backButton.setVisible(false);
+		backButton.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				nextButton.setVisible(true);
+				backButton.setVisible(false);
+				cardLayout.first(contentPanel);
+			}
+		});
+
+		buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+		addDivider(buttonPanel, SwingConstants.TOP, true);
+
+		removeAll();
+		layoutPanel();
+	}
+
+	@Override
+	public void noteConfiguration() {
+		setJson(newConfiguration);
+		configureInputPorts(serviceRegistry);
+		configureOutputPorts(serviceRegistry);
+	}
+
+	@Override
+	public boolean checkValues() {
+		return errorMessages.isEmpty();
+	}
+
+	private void layoutPanel() {
+		setPreferredSize(new Dimension(450, 400));
+		setLayout(new BorderLayout());
+
+		page1 = new JPanel(new GridBagLayout());
+		page2 = new JPanel(new GridBagLayout());
+
+		contentPanel = new JPanel(cardLayout);
+		contentPanel.add(page1, "page1");
+		contentPanel.add(page2, "page2");
+		add(contentPanel, BorderLayout.CENTER);
+
+		// title
+		titlePanel.setBorder(new CompoundBorder(titlePanel.getBorder(), new EmptyBorder(10, 10, 0, 10)));
+		add(titlePanel, BorderLayout.NORTH);
+		titlePanel.add(titleLabel, BorderLayout.NORTH);
+		titlePanel.add(titleIcon, BorderLayout.WEST);
+		titlePanel.add(titleMessage, BorderLayout.CENTER);
+
+		GridBagConstraints c = new GridBagConstraints();
+		c.anchor = GridBagConstraints.WEST;
+		c.fill = GridBagConstraints.HORIZONTAL;
+		c.weightx = 1;
+		c.gridx = 0;
+		c.gridwidth = GridBagConstraints.REMAINDER;
+
+		// column range
+		c.insets = new Insets(10, 10, 0, 10);
+		page1.add(columnLabel, c);
+
+		c.insets = new Insets(10, 25, 0, 0);
+		c.gridwidth = 1;
+		c.weightx = 0;
+		page1.add(new JLabel(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.from")), c);
+		c.insets = new Insets(10, 0, 0, 0);
+		c.gridx = 1;
+		page1.add(columnFromValue, c);
+		c.gridx = 2;
+		page1.add(new JLabel(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.to")), c);
+		c.gridx = 3;
+		page1.add(columnToValue, c);
+
+		c.gridx = 0;
+		c.weightx = 1;
+		c.insets = new Insets(10, 10, 0, 10);
+		c.gridwidth = GridBagConstraints.REMAINDER;
+
+		// row range
+		page1.add(rowLabel, c);
+
+		c.insets = new Insets(10, 25, 0, 0);
+		c.gridwidth = 1;
+		c.gridx = 0;
+		c.weightx = 0;
+		page1.add(new JLabel(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.from")), c);
+		c.insets = new Insets(10, 0, 0, 0);
+		c.gridx = 1;
+		page1.add(rowFromValue, c);
+		c.gridx = 2;
+		page1.add(new JLabel(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.to")), c);
+		c.gridx = 3;
+		page1.add(rowToValue, c);
+		c.gridx = 4;
+		page1.add(rowSelectAllOption, c);
+		c.gridx = 5;
+		c.gridwidth = GridBagConstraints.REMAINDER;
+		c.insets = new Insets(10, 0, 0, 10);
+		page1.add(rowExcludeFirstOption, c);
+		c.insets = new Insets(10, 25, 0, 0);
+		c.gridx = 0;
+		page1.add(rowIgnoreBlankRows, c);
+
+		c.gridx = 0;
+
+		// empty cells
+		c.insets = new Insets(10, 10, 10, 10);
+		page1.add(emptyCellLabel, c);
+
+		c.insets = new Insets(0, 25, 0, 10);
+		page1.add(emptyCellEmptyStringOption, c);
+		JPanel userDefinedPanel = new JPanel(new BorderLayout());
+		userDefinedPanel.add(emptyCellUserDefinedOption, BorderLayout.WEST);
+		userDefinedPanel.add(emptyCellUserDefinedValue, BorderLayout.CENTER);
+		page1.add(userDefinedPanel, c);
+		c.weighty = 1;
+		c.anchor = GridBagConstraints.NORTHWEST;
+		page1.add(emptyCellErrorValueOption, c);
+
+		// output format
+		c.insets = new Insets(10, 10, 10, 10);
+		c.weighty = 0;
+		c.weightx = 1;
+		page2.add(outputFormatLabel, c);
+
+		c.insets = new Insets(0, 25, 0, 10);
+		page2.add(outputFormatMultiplePort, c);
+		page2.add(outputFormatSinglePort, c);
+
+		c.insets = new Insets(0, 50, 0, 10);
+		JPanel outputFormatDelimiterPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
+		outputFormatDelimiterPanel.add(outputFormatDelimiterLabel);
+		outputFormatDelimiterPanel.add(outputFormatDelimiter);
+		page2.add(outputFormatDelimiterPanel, c);
+
+		// column mapping
+		c.insets = new Insets(10, 10, 0, 10);
+		page2.add(columnMappingLabel, c);
+
+		c.insets = new Insets(10, 10, 10, 10);
+		c.fill = GridBagConstraints.BOTH;
+		c.weighty = 1;
+		page2.add(new JScrollPane(columnMappingTable), c);
+
+		buttonPanel.add(backButton);
+		buttonPanel.add(nextButton);
+		add(buttonPanel, BorderLayout.SOUTH);
+	}
+
+	/**
+	 * Displays the message with no icon.
+	 *
+	 * @param message
+	 *            the message to display
+	 */
+	public void setMessage(String message) {
+		titleIcon.setIcon(null);
+		titleMessage.setText(message);
+	}
+
+	/**
+	 * Adds the message to the top of the warning message stack. If the message is already in the
+	 * stack it is moved to the top. If there are no error messages the message is displayed.
+	 *
+	 * @param message
+	 *            the warning message to add
+	 */
+	public void addWarningMessage(String message) {
+		if (warningMessages.contains(message)) {
+			warningMessages.remove(message);
+		}
+		warningMessages.push(message);
+		if (errorMessages.isEmpty()) {
+			setWarningMessage(message);
+		}
+	}
+
+	/**
+	 * Removes the message from the warning message stack. If there are no error messages the next
+	 * warning message is displayed. If there are no warning messages the default message is
+	 * displayed.
+	 *
+	 * @param message
+	 *            the warning message to remove
+	 */
+	public void removeWarningMessage(String message) {
+		warningMessages.remove(message);
+		if (errorMessages.isEmpty()) {
+			if (warningMessages.isEmpty()) {
+				setMessage(DEFAULT_MESSAGE);
+			} else {
+				setWarningMessage(warningMessages.peek());
+			}
+		}
+	}
+
+	/**
+	 * Displays the message and a warning icon.
+	 *
+	 * @param message
+	 *            the warning message to display
+	 */
+	public void setWarningMessage(String message) {
+		titleIcon.setIcon(Icons.warningIcon);
+		titleMessage.setText(message);
+	}
+
+	/**
+	 * Adds the message to the top of the error message stack. If the message is already in the
+	 * stack it is moved to the top. The message is then displayed.
+	 *
+	 * @param message
+	 *            the error message to add
+	 */
+	public void addErrorMessage(String message) {
+		if (errorMessages.contains(message)) {
+			errorMessages.remove(message);
+		}
+		errorMessages.push(message);
+		setErrorMessage(message);
+	}
+
+	/**
+	 * Removes the message from the error message stack and displays the next error message. If
+	 * there are no error messages the next warning message is displayed. If there are no warning
+	 * messages the default message is displayed.
+	 *
+	 * @param message
+	 *            the error message to remove
+	 */
+	public void removeErrorMessage(String message) {
+		errorMessages.remove(message);
+		if (errorMessages.isEmpty()) {
+			if (warningMessages.isEmpty()) {
+				setMessage(DEFAULT_MESSAGE);
+			} else {
+				setWarningMessage(warningMessages.peek());
+			}
+		} else {
+			setErrorMessage(errorMessages.peek());
+		}
+	}
+
+	/**
+	 * Displays the message and an error icon.
+	 *
+	 * @param message
+	 *            the error message to display
+	 */
+	public void setErrorMessage(String message) {
+		titleIcon.setIcon(Icons.severeIcon);
+		titleMessage.setText(message);
+	}
+
+	protected boolean validatePortNames() {
+		boolean isValid = true;
+		Range columnRange = SpreadsheetUtils.getRange(newConfiguration.get("columnRange"));
+		Map<String, String> mapping = new HashMap<>();
+		if (newConfiguration.has("columnNames")) {
+			for (JsonNode columnName : newConfiguration.get("columnNames")) {
+				mapping.put(columnName.get("column").textValue(), columnName.get("port").textValue());
+			}
+		}
+		Set<String> usedNames = new HashSet<String>();
+		for (Entry<String, String> entry : mapping.entrySet()) {
+			if (columnRange.contains(SpreadsheetUtils.getColumnIndex(entry.getKey()))) {
+				String portName = entry.getValue();
+				if (!usedNames.add(portName)) {
+					isValid = false;
+					break;
+				}
+				if (portName.matches("[A-Z]+")) {
+					if (!mapping.containsKey(portName)) {
+						int columnIndex = SpreadsheetUtils.getColumnIndex(portName);
+						if (columnRange.contains(columnIndex)) {
+							isValid = false;
+							break;
+						}
+					}
+				}
+			}
+		}
+		if (isValid) {
+			removeErrorMessage(DUPLICATE_PORT_NAME_ERROR_MESSAGE);
+		} else {
+			addErrorMessage(DUPLICATE_PORT_NAME_ERROR_MESSAGE);
+		}
+		return isValid;
+	}
+
+	protected boolean checkRowRange(String from, String to) {
+		boolean result = false;
+		try {
+			int fromRow = Integer.parseInt(from);
+			int toRow = Integer.parseInt(to);
+			if (toRow < fromRow) {
+				addErrorMessage(INCONSISTENT_ROW_MESSAGE);
+			} else {
+				removeErrorMessage(INCONSISTENT_ROW_MESSAGE);
+				result = true;
+			}
+		} catch (NumberFormatException e) {
+			logger.warn("Problem checking row range", e);
+		}
+		return result;
+	}
+
+	protected boolean checkColumnRange(int fromColumn, int toColumn) {
+		boolean result = false;
+		if (toColumn < fromColumn) {
+			addErrorMessage(INCONSISTENT_COLUMN_MESSAGE);
+		} else {
+			removeErrorMessage(INCONSISTENT_COLUMN_MESSAGE);
+			result = true;
+		}
+		return result;
+	}
+
+	/**
+	 * Adds a light gray or etched border to the top or bottom of a JComponent.
+	 *
+	 * @param component
+	 */
+	protected void addDivider(JComponent component, final int position, final boolean etched) {
+		component.setBorder(new Border() {
+			private final Color borderColor = new Color(.6f, .6f, .6f);
+
+			public Insets getBorderInsets(Component c) {
+				if (position == SwingConstants.TOP) {
+					return new Insets(5, 0, 0, 0);
+				} else {
+					return new Insets(0, 0, 5, 0);
+				}
+			}
+
+			public boolean isBorderOpaque() {
+				return false;
+			}
+
+			public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
+				if (position == SwingConstants.TOP) {
+					if (etched) {
+						g.setColor(borderColor);
+						g.drawLine(x, y, x + width, y);
+						g.setColor(Color.WHITE);
+						g.drawLine(x, y + 1, x + width, y + 1);
+					} else {
+						g.setColor(Color.LIGHT_GRAY);
+						g.drawLine(x, y, x + width, y);
+					}
+				} else {
+					if (etched) {
+						g.setColor(borderColor);
+						g.drawLine(x, y + height - 2, x + width, y + height - 2);
+						g.setColor(Color.WHITE);
+						g.drawLine(x, y + height - 1, x + width, y + height - 1);
+					} else {
+						g.setColor(Color.LIGHT_GRAY);
+						g.drawLine(x, y + height - 1, x + width, y + height - 1);
+					}
+				}
+			}
+
+		});
+	}
+
+	private void enableTable(JTable table, boolean enabled) {
+		table.setEnabled(enabled);
+		Component editor = table.getEditorComponent();
+		if (editor != null) {
+			editor.setEnabled(enabled);
+		}
+		if (enabled) {
+			table.setForeground(Color.BLACK);
+			table.getTableHeader().setForeground(Color.BLACK);
+		} else {
+			table.setForeground(Color.LIGHT_GRAY);
+			table.getTableHeader().setForeground(Color.LIGHT_GRAY);
+		}
+	}
+
+	static class UpperCaseDocument extends PlainDocument {
+        @Override
+        public void replace(int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
+        	if (text.matches("[A-Za-z]+")) {
+        		text = text.toUpperCase();
+        		super.replace(offset, length, text, attrs);
+        	}
+        }
+     }
+
+	static class NumericDocument extends PlainDocument {
+        @Override
+        public void replace(int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
+        	if (text.length() == 0 || text.matches("[0-9]+")) {
+        		text = text.toUpperCase();
+        		super.replace(offset, length, text, attrs);
+        	}
+        }
+     }
+
+	/**
+	 * Main method for testing the panel.
+	 *
+	 * @param args
+	 * @throws ActivityConfigurationException
+	 */
+//	public static void main(String[] args) throws ActivityConfigurationException {
+//		final JFrame frame = new JFrame();
+//		SpreadsheetImportActivity activity = new SpreadsheetImportActivity();
+//		activity.configure(new SpreadsheetImportConfiguration());
+//		final SpreadsheetImportConfigView config = new SpreadsheetImportConfigView(activity);
+//		config.setOkAction(new AbstractAction("Finish") {
+//			public void actionPerformed(ActionEvent arg0) {
+//				Range columnRange = config.getConfiguration().getColumnRange();
+//				String fromColumn = SpreadsheetUtils.getColumnLabel(columnRange.getStart());
+//				String toColumn = SpreadsheetUtils.getColumnLabel(columnRange.getEnd());
+//				System.out.printf("%s (%s) - %s (%s)", fromColumn, columnRange.getStart(),
+//						toColumn, columnRange.getEnd());
+//				frame.setVisible(false);
+//				frame.dispose();
+//			}
+//		});
+//		config.setCancelAction(new AbstractAction("Cancel") {
+//			public void actionPerformed(ActionEvent arg0) {
+//				frame.setVisible(false);
+//				frame.dispose();
+//			}
+//		});
+//		frame.add(config);
+//		frame.pack();
+//		frame.setVisible(true);
+//	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportContextualView.java b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportContextualView.java
new file mode 100644
index 0000000..2078faa
--- /dev/null
+++ b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportContextualView.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (C) 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 net.sf.taverna.t2.activities.spreadsheet.views;
+
+import java.awt.Frame;
+
+import javax.swing.Action;
+
+import net.sf.taverna.t2.activities.spreadsheet.actions.SpreadsheetImportActivityConfigurationAction;
+import net.sf.taverna.t2.activities.spreadsheet.il8n.SpreadsheetImportUIText;
+import net.sf.taverna.t2.activities.spreadsheet.servicedescriptions.SpreadsheetImportActivityIcon;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+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 uk.org.taverna.commons.services.ServiceRegistry;
+import uk.org.taverna.scufl2.api.activity.Activity;
+import uk.org.taverna.scufl2.api.port.InputActivityPort;
+import uk.org.taverna.scufl2.api.port.OutputActivityPort;
+
+/**
+ * A simple non editable HTML table view over a {@link SpreadsheetImportActivity}. Clicking on the
+ * configure button shows the editable {@link SpreadsheetImportConfigView}
+ *
+ * @author David Withers
+ */
+public class SpreadsheetImportContextualView extends HTMLBasedActivityContextualView {
+
+	private static final long serialVersionUID = 1L;
+	private final EditManager editManager;
+	private final FileManager fileManager;
+	private final ActivityIconManager activityIconManager;
+	private final ServiceDescriptionRegistry serviceDescriptionRegistry;
+	private final ServiceRegistry serviceRegistry;
+
+	public SpreadsheetImportContextualView(Activity activity, EditManager editManager,
+			FileManager fileManager, ActivityIconManager activityIconManager,
+			ColourManager colourManager, ServiceDescriptionRegistry serviceDescriptionRegistry, ServiceRegistry serviceRegistry) {
+		super(activity, colourManager);
+		this.editManager = editManager;
+		this.fileManager = fileManager;
+		this.activityIconManager = activityIconManager;
+		this.serviceDescriptionRegistry = serviceDescriptionRegistry;
+		this.serviceRegistry = serviceRegistry;
+	}
+
+	@Override
+	protected String getRawTableRowsHtml() {
+		StringBuilder html = new StringBuilder();
+		html.append("<tr><th>");
+		html.append(SpreadsheetImportUIText
+				.getString("SpreadsheetImportContextualView.inputPortName"));
+		html.append("</th><th>");
+		html.append(SpreadsheetImportUIText.getString("SpreadsheetImportContextualView.depth"));
+		html.append("</th></tr>");
+		for (InputActivityPort port : getActivity().getInputPorts()) {
+			html.append("<tr><td>");
+			html.append(port.getName());
+			html.append("</td><td>");
+			html.append(port.getDepth());
+			html.append("</td></tr>");
+		}
+		html.append("<tr><th>");
+		html.append(SpreadsheetImportUIText
+				.getString("SpreadsheetImportContextualView.outputPortName"));
+		html.append("</th><th>");
+		html.append(SpreadsheetImportUIText.getString("SpreadsheetImportContextualView.depth"));
+		html.append("</th></tr>");
+		for (OutputActivityPort port : getActivity().getOutputPorts()) {
+			html.append("<tr><td>");
+			html.append(port.getName());
+			html.append("</td><td>");
+			html.append(port.getDepth());
+			html.append("</td></tr>");
+		}
+		return html.toString();
+	}
+
+	@Override
+	public String getViewTitle() {
+		return SpreadsheetImportUIText.getString("SpreadsheetImportContextualView.activityName");
+	}
+
+	@Override
+	public Action getConfigureAction(Frame owner) {
+		return new SpreadsheetImportActivityConfigurationAction(
+				getActivity(), owner, editManager, fileManager,
+				activityIconManager, serviceDescriptionRegistry, serviceRegistry);
+	}
+
+	@Override
+	public String getBackgroundColour() {
+		return SpreadsheetImportActivityIcon.SPREADSHEET_COLOUR_HTML;
+	}
+
+	@Override
+	public int getPreferredPosition() {
+		return 100;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportContextualViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportContextualViewFactory.java b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportContextualViewFactory.java
new file mode 100644
index 0000000..7e49168
--- /dev/null
+++ b/taverna-spreadsheet-import-activity-ui/src/main/java/net/sf/taverna/t2/activities/spreadsheet/views/SpreadsheetImportContextualViewFactory.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (C) 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 net.sf.taverna.t2.activities.spreadsheet.views;
+
+import java.util.Arrays;
+import java.util.List;
+
+import net.sf.taverna.t2.activities.spreadsheet.servicedescriptions.SpreadsheetImportTemplateService;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+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;
+import uk.org.taverna.commons.services.ServiceRegistry;
+import uk.org.taverna.scufl2.api.activity.Activity;
+
+/**
+ * Factory for creating contextual a view of the SpreadsheetImport Activity
+ *
+ * @author David Withers
+ */
+public class SpreadsheetImportContextualViewFactory implements ContextualViewFactory<Activity> {
+
+	private EditManager editManager;
+	private FileManager fileManager;
+	private ActivityIconManager activityIconManager;
+	private ColourManager colourManager;
+	private ServiceDescriptionRegistry serviceDescriptionRegistry;
+	private ServiceRegistry serviceRegistry;
+
+	public boolean canHandle(Object object) {
+		return object instanceof Activity
+				&& ((Activity) object).getType().equals(
+						SpreadsheetImportTemplateService.ACTIVITY_TYPE);
+	}
+
+	public List<ContextualView> getViews(Activity activity) {
+		return Arrays.asList(new ContextualView[] { new SpreadsheetImportContextualView(activity,
+				editManager, fileManager, activityIconManager, colourManager,
+				serviceDescriptionRegistry, serviceRegistry) });
+	}
+
+	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;
+	}
+
+	public void setServiceDescriptionRegistry(ServiceDescriptionRegistry serviceDescriptionRegistry) {
+		this.serviceDescriptionRegistry = serviceDescriptionRegistry;
+	}
+
+	public void setServiceRegistry(ServiceRegistry serviceRegistry) {
+		this.serviceRegistry = serviceRegistry;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider
----------------------------------------------------------------------
diff --git a/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider b/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider
new file mode 100644
index 0000000..b1628b6
--- /dev/null
+++ b/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider
@@ -0,0 +1 @@
+net.sf.taverna.t2.activities.spreadsheet.servicedescriptions.SpreadsheetImportTemplateService

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
----------------------------------------------------------------------
diff --git a/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent b/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
new file mode 100644
index 0000000..6720b04
--- /dev/null
+++ b/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
@@ -0,0 +1,3 @@
+net.sf.taverna.t2.activities.spreadsheet.menu.SpreadsheetImportAddTemplateAction
+net.sf.taverna.t2.activities.spreadsheet.menu.SpreadsheetImportConfigureMenuAction
+net.sf.taverna.t2.activities.spreadsheet.menu.SpreadsheetImportAddTemplateMenuAction

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI
----------------------------------------------------------------------
diff --git a/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI b/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI
new file mode 100644
index 0000000..2dd012f
--- /dev/null
+++ b/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI
@@ -0,0 +1 @@
+net.sf.taverna.t2.activities.spreadsheet.servicedescriptions.SpreadsheetImportActivityIcon
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
----------------------------------------------------------------------
diff --git a/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory b/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
new file mode 100644
index 0000000..4b9dd11
--- /dev/null
+++ b/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
@@ -0,0 +1 @@
+net.sf.taverna.t2.activities.spreadsheet.views.SpreadsheetImportContextualViewFactory
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench-common-activities/blob/54050685/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/spring/spreadsheet-import-activity-ui-context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/spring/spreadsheet-import-activity-ui-context-osgi.xml b/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/spring/spreadsheet-import-activity-ui-context-osgi.xml
new file mode 100644
index 0000000..72ffb77
--- /dev/null
+++ b/taverna-spreadsheet-import-activity-ui/src/main/resources/META-INF/spring/spreadsheet-import-activity-ui-context-osgi.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans:beans xmlns="http://www.springframework.org/schema/osgi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:beans="http://www.springframework.org/schema/beans"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans.xsd
+                      http://www.springframework.org/schema/osgi
+                      http://www.springframework.org/schema/osgi/spring-osgi.xsd">
+
+	<service ref="SpreadsheetImportActivityIcon" interface="net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI" />
+
+	<service ref="SpreadsheetImportTemplateService" interface="net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider" />
+
+	<service ref="SpreadsheetImportAddTemplateAction" auto-export="interfaces" />
+	<service ref="SpreadsheetImportConfigureMenuAction" auto-export="interfaces" />
+	<service ref="SpreadsheetImportAddTemplateMenuAction" auto-export="interfaces" />
+
+	<service ref="SpreadsheetImportContextualViewFactory" interface="net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory" />
+
+	<reference id="editManager" interface="net.sf.taverna.t2.workbench.edits.EditManager" />
+	<reference id="fileManager" interface="net.sf.taverna.t2.workbench.file.FileManager" />
+	<reference id="menuManager" interface="net.sf.taverna.t2.ui.menu.MenuManager" />
+	<reference id="selectionManager" interface="net.sf.taverna.t2.workbench.selection.SelectionManager" />
+	<reference id="activityIconManager" interface="net.sf.taverna.t2.workbench.activityicons.ActivityIconManager" />
+	<reference id="colourManager" interface="net.sf.taverna.t2.workbench.configuration.colour.ColourManager" />
+	<reference id="serviceDescriptionRegistry" interface="net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry" />
+	<reference id="serviceRegistry" interface="uk.org.taverna.commons.services.ServiceRegistry" />
+
+</beans:beans>