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

[17/50] [abbrv] incubator-taverna-engine git commit: taverna-activity-archetype/

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/config/__classPrefix__ConfigureAction.java
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/config/__classPrefix__ConfigureAction.java b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/config/__classPrefix__ConfigureAction.java
new file mode 100644
index 0000000..c7d5d10
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/config/__classPrefix__ConfigureAction.java
@@ -0,0 +1,49 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+package ${package}.ui.config;
+
+import java.awt.event.ActionEvent;
+
+import uk.org.taverna.commons.services.ServiceRegistry;
+import uk.org.taverna.scufl2.api.activity.Activity;
+
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+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.ActivityConfigurationAction;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ActivityConfigurationDialog;
+
+@SuppressWarnings("serial")
+public class ${classPrefix}ConfigureAction extends ActivityConfigurationAction {
+
+	private final EditManager editManager;
+	private final FileManager fileManager;
+	private final ServiceRegistry serviceRegistry;
+
+	public ${classPrefix}ConfigureAction(Activity activity,
+			EditManager editManager, FileManager fileManager,
+			ActivityIconManager activityIconManager,
+			ServiceDescriptionRegistry serviceDescriptionRegistry,
+			ServiceRegistry serviceRegistry) {
+		super(activity, activityIconManager, serviceDescriptionRegistry);
+		this.editManager = editManager;
+		this.fileManager = fileManager;
+		this.serviceRegistry = serviceRegistry;
+	}
+
+	public void actionPerformed(ActionEvent e) {
+		ActivityConfigurationDialog currentDialog = getDialog(getActivity());
+		if (currentDialog != null) {
+			currentDialog.toFront();
+			return;
+		}
+
+		${classPrefix}ConfigurationPanel panel = new ${classPrefix}ConfigurationPanel(getActivity(), serviceRegistry);
+		ActivityConfigurationDialog dialog = new ActivityConfigurationDialog(getActivity(), panel, editManager);
+
+		setDialog(getActivity(), dialog, fileManager);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/menu/__classPrefix__ConfigureMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/menu/__classPrefix__ConfigureMenuAction.java b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/menu/__classPrefix__ConfigureMenuAction.java
new file mode 100644
index 0000000..a257a4e
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/menu/__classPrefix__ConfigureMenuAction.java
@@ -0,0 +1,67 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+package ${package}.ui.menu;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import uk.org.taverna.commons.services.ServiceRegistry;
+
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+import net.sf.taverna.t2.ui.menu.ContextualMenuComponent;
+import net.sf.taverna.t2.ui.menu.MenuComponent;
+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;
+
+import ${package}.ui.config.${classPrefix}ConfigureAction;
+
+public class ${classPrefix}ConfigureMenuAction extends AbstractConfigureActivityMenuAction implements
+		MenuComponent, ContextualMenuComponent {
+
+	private static final URI ACTIVITY_TYPE = URI
+			.create("http://example.com/2013/activity/${rootArtifactId}");
+
+	private EditManager editManager;
+	private FileManager fileManager;
+	private ActivityIconManager activityIconManager;
+	private ServiceDescriptionRegistry serviceDescriptionRegistry;
+	private ServiceRegistry serviceRegistry;
+
+	public ${classPrefix}ConfigureMenuAction() {
+		super(ACTIVITY_TYPE);
+	}
+
+	@Override
+	protected Action createAction() {
+		Action result = new ${classPrefix}ConfigureAction(findActivity(), editManager, fileManager,
+				activityIconManager, serviceDescriptionRegistry, serviceRegistry);
+		result.putValue(Action.NAME, "Configure example service");
+		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-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/serviceprovider/__classPrefix__ServiceDesc.java
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/serviceprovider/__classPrefix__ServiceDesc.java b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/serviceprovider/__classPrefix__ServiceDesc.java
new file mode 100644
index 0000000..5de7bc4
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/serviceprovider/__classPrefix__ServiceDesc.java
@@ -0,0 +1,106 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+package ${package}.ui.serviceprovider;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.Icon;
+
+import uk.org.taverna.scufl2.api.configurations.Configuration;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import net.sf.taverna.t2.servicedescriptions.ServiceDescription;
+
+public class ${classPrefix}ServiceDesc extends ServiceDescription {
+
+	private static final URI ACTIVITY_TYPE = URI
+			.create("http://example.com/2013/activity/${rootArtifactId}");
+
+	// FIXME: Replace example fields and getters/setters with any required
+	// and optional fields. (All fields are searchable in the Service palette,
+	// for instance try a search for exampleString:3)
+	private String exampleString;
+	private String exampleUri;
+
+	public String getExampleString() {
+		return exampleString;
+	}
+	public void setExampleString(String exampleString) {
+		this.exampleString = exampleString;
+	}
+
+	public String getExampleUri() {
+		return exampleUri;
+	}
+	public void setExampleUri(String exampleUri) {
+		this.exampleUri = exampleUri;
+	}
+
+	/**
+	 * The type of Activity which should be instantiated when adding a service
+	 * for this description
+	 */
+	@Override
+	public URI getActivityType() {
+		return ACTIVITY_TYPE;
+	}
+
+	/**
+	 * The configuration  which is to be used for configuring the instantiated activity.
+	 * Making this configuration will typically require some of the fields set on this service
+	 * description, like an endpoint URL or method name.
+	 *
+	 */
+	@Override
+	public Configuration getActivityConfiguration() {
+		Configuration configuration = new Configuration();
+		configuration.setType(ACTIVITY_TYPE.resolve("#Config"));
+		ObjectNode json = configuration.getJsonAsObjectNode();
+		json.put("exampleString", exampleString);
+		json.put("exampleUri", exampleUri);
+		return configuration;
+	}
+
+	/**
+	 * An icon to represent this service description in the service palette.
+	 */
+	@Override
+	public Icon getIcon() {
+		return ${classPrefix}ServiceIcon.getIcon();
+	}
+
+	/**
+	 * The display name that will be shown in service palette and will
+	 * be used as a template for processor name when added to workflow.
+	 */
+	@Override
+	public String getName() {
+		return exampleString;
+	}
+
+	/**
+	 * The path to this service description in the service palette. Folders
+	 * will be created for each element of the returned path.
+	 */
+	@Override
+	public List<String> getPath() {
+		// For deeper paths you may return several strings
+		return Arrays.asList("${classPrefix}s " + exampleUri);
+	}
+
+	/**
+	 * Return a list of data values uniquely identifying this service
+	 * description (to avoid duplicates). Include only primary key like fields,
+	 * ie. ignore descriptions, icons, etc.
+	 */
+	@Override
+	protected List<? extends Object> getIdentifyingData() {
+		// FIXME: Use your fields instead of example fields
+		return Arrays.<Object>asList(exampleString, exampleUri);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/serviceprovider/__classPrefix__ServiceIcon.java
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/serviceprovider/__classPrefix__ServiceIcon.java b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/serviceprovider/__classPrefix__ServiceIcon.java
new file mode 100644
index 0000000..023edcb
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/serviceprovider/__classPrefix__ServiceIcon.java
@@ -0,0 +1,40 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+package ${package}.ui.serviceprovider;
+
+import java.net.URI;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI;
+
+public class ${classPrefix}ServiceIcon implements ActivityIconSPI {
+
+	private static final URI ACTIVITY_TYPE = URI
+			.create("http://example.com/2013/activity/${rootArtifactId}");
+
+	private static Icon icon;
+
+	@Override
+	public int canProvideIconScore(URI activityType) {
+		if (ACTIVITY_TYPE.equals(activityType)) {
+			return DEFAULT_ICON + 1;
+		}
+		return NO_ICON;
+	}
+
+	@Override
+	public Icon getIcon(URI activityType) {
+		return getIcon();
+	}
+
+	public static Icon getIcon() {
+		if (icon == null) {
+			icon = new ImageIcon(${classPrefix}ServiceIcon.class.getResource("/exampleIcon.png"));
+		}
+		return icon;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/serviceprovider/__classPrefix__ServiceProvider.java
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/serviceprovider/__classPrefix__ServiceProvider.java b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/serviceprovider/__classPrefix__ServiceProvider.java
new file mode 100644
index 0000000..8a30c6f
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/serviceprovider/__classPrefix__ServiceProvider.java
@@ -0,0 +1,75 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+package ${package}.ui.serviceprovider;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.Icon;
+
+import net.sf.taverna.t2.servicedescriptions.ServiceDescription;
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider;
+
+public class ${classPrefix}ServiceProvider implements ServiceDescriptionProvider {
+
+	private static final URI providerId = URI
+		.create("http://example.com/2011/service-provider/${rootArtifactId}");
+
+	/**
+	 * Do the actual search for services. Return using the callBack parameter.
+	 */
+	public void findServiceDescriptionsAsync(
+			FindServiceDescriptionsCallBack callBack) {
+		// Use callback.status() for long-running searches
+		// callBack.status("Resolving example services");
+
+		List<ServiceDescription> results = new ArrayList<ServiceDescription>();
+
+		// FIXME: Implement the actual service search/lookup instead
+		// of dummy for-loop
+		for (int i = 1; i <= 5; i++) {
+			${classPrefix}ServiceDesc service = new ${classPrefix}ServiceDesc();
+			// Populate the service description bean
+			service.setExampleString("Example " + i);
+			service.setExampleUri("http://localhost:8192/service");
+
+			// Optional: set description
+			service.setDescription("Service example number " + i);
+			results.add(service);
+		}
+
+		// partialResults() can also be called several times from inside
+		// for-loop if the full search takes a long time
+		callBack.partialResults(results);
+
+		// No more results will be coming
+		callBack.finished();
+	}
+
+	/**
+	 * Icon for service provider
+	 */
+	public Icon getIcon() {
+		return ${classPrefix}ServiceIcon.getIcon();
+	}
+
+	/**
+	 * Name of service provider, appears in right click for 'Remove service
+	 * provider'
+	 */
+	public String getName() {
+		return "My example service";
+	}
+
+	@Override
+	public String toString() {
+		return getName();
+	}
+
+	public String getId() {
+		return providerId.toASCIIString();
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/view/__classPrefix__ActivityContextViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/view/__classPrefix__ActivityContextViewFactory.java b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/view/__classPrefix__ActivityContextViewFactory.java
new file mode 100644
index 0000000..de87ef3
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/view/__classPrefix__ActivityContextViewFactory.java
@@ -0,0 +1,62 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+package ${package}.ui.view;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+
+import uk.org.taverna.commons.services.ServiceRegistry;
+import uk.org.taverna.scufl2.api.activity.Activity;
+
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+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;
+
+public class ${classPrefix}ActivityContextViewFactory implements ContextualViewFactory<Activity> {
+
+	private static final URI ACTIVITY_TYPE = URI
+			.create("http://example.com/2013/activity/${rootArtifactId}");
+
+	private EditManager editManager;
+	private FileManager fileManager;
+	private ActivityIconManager activityIconManager;
+	private ServiceDescriptionRegistry serviceDescriptionRegistry;
+	private ServiceRegistry serviceRegistry;
+
+	@Override
+	public boolean canHandle(Object object) {
+		return object instanceof Activity && ((Activity) object).getType().equals(ACTIVITY_TYPE);
+	}
+
+	@Override
+	public List<ContextualView> getViews(Activity selection) {
+		return Arrays.<ContextualView>asList(new ${classPrefix}ContextualView(selection, editManager,
+				fileManager, activityIconManager, 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 setServiceDescriptionRegistry(ServiceDescriptionRegistry serviceDescriptionRegistry) {
+		this.serviceDescriptionRegistry = serviceDescriptionRegistry;
+	}
+
+	public void setServiceRegistry(ServiceRegistry serviceRegistry) {
+		this.serviceRegistry = serviceRegistry;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/view/__classPrefix__ContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/view/__classPrefix__ContextualView.java b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/view/__classPrefix__ContextualView.java
new file mode 100644
index 0000000..b7066a0
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/java/ui/view/__classPrefix__ContextualView.java
@@ -0,0 +1,91 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+package ${package}.ui.view;
+
+import java.awt.Frame;
+
+import javax.swing.Action;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import uk.org.taverna.commons.services.ServiceRegistry;
+
+import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
+import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
+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.ActivityContextualView;
+
+import uk.org.taverna.scufl2.api.activity.Activity;
+
+import ${package}.ui.config.${classPrefix}ConfigureAction;
+
+@SuppressWarnings("serial")
+public class ${classPrefix}ContextualView extends ActivityContextualView {
+
+	private final EditManager editManager;
+	private final FileManager fileManager;
+	private final ActivityIconManager activityIconManager;
+	private final ServiceDescriptionRegistry serviceDescriptionRegistry;
+	private final ServiceRegistry serviceRegistry;
+
+	private JLabel description = new JLabel("ads");
+
+	public ${classPrefix}ContextualView(Activity activity, EditManager editManager,
+			FileManager fileManager, ActivityIconManager activityIconManager,
+			ServiceDescriptionRegistry serviceDescriptionRegistry, ServiceRegistry serviceRegistry) {
+		super(activity);
+		this.editManager = editManager;
+		this.fileManager = fileManager;
+		this.activityIconManager = activityIconManager;
+		this.serviceDescriptionRegistry = serviceDescriptionRegistry;
+		this.serviceRegistry = serviceRegistry;
+		initView();
+	}
+
+	@Override
+	public JComponent getMainFrame() {
+		JPanel jPanel = new JPanel();
+		jPanel.add(description);
+		refreshView();
+		return jPanel;
+	}
+
+	@Override
+	public String getViewTitle() {
+		JsonNode configuration = getConfigBean().getJson();
+		return "${classPrefix} service " + configuration.get("exampleString").asText();
+	}
+
+	/**
+	 * Typically called when the activity configuration has changed.
+	 */
+	@Override
+	public void refreshView() {
+		JsonNode configuration = getConfigBean().getJson();
+		description.setText("${classPrefix} service " + configuration.get("exampleUri").asText()
+				+ " - " + configuration.get("exampleString").asText());
+		// TODO: Might also show extra service information looked
+		// up dynamically from endpoint/registry
+	}
+
+	/**
+	 * View position hint
+	 */
+	@Override
+	public int getPreferredPosition() {
+		// We want to be on top
+		return 100;
+	}
+
+	@Override
+	public Action getConfigureAction(final Frame owner) {
+		return new ${classPrefix}ConfigureAction(getActivity(), editManager, fileManager,
+				activityIconManager, serviceDescriptionRegistry, serviceRegistry);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/resources/META-INF/spring/context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/resources/META-INF/spring/context-osgi.xml b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/resources/META-INF/spring/context-osgi.xml
new file mode 100644
index 0000000..32ad4f1
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/resources/META-INF/spring/context-osgi.xml
@@ -0,0 +1,26 @@
+<?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="${classPrefix}ServiceIcon" interface="net.sf.taverna.t2.workbench.activityicons.ActivityIconSPI" />
+
+	<service ref="${classPrefix}ServiceProvider" interface="net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider" />
+
+	<service ref="${classPrefix}ConfigureMenuAction" auto-export="interfaces" />
+
+	<service ref="${classPrefix}ActivityContextViewFactory" 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>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/resources/META-INF/spring/context.xml
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/resources/META-INF/spring/context.xml b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/resources/META-INF/spring/context.xml
new file mode 100644
index 0000000..cfc5a00
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/resources/META-INF/spring/context.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<bean id="${classPrefix}ServiceIcon"
+		class="${package}.ui.serviceprovider.${classPrefix}ServiceIcon" />
+
+	<bean id="${classPrefix}ServiceProvider"
+		class="${package}.ui.serviceprovider.${classPrefix}ServiceProvider" />
+
+	<bean id="${classPrefix}ConfigureMenuAction"
+		class="${package}.ui.menu.${classPrefix}ConfigureMenuAction">
+		<property name="editManager" ref="editManager" />
+		<property name="fileManager" ref="fileManager" />
+		<property name="activityIconManager" ref="activityIconManager" />
+		<property name="serviceDescriptionRegistry" ref="serviceDescriptionRegistry" />
+		<property name="serviceRegistry" ref="serviceRegistry" />
+	</bean>
+
+	<bean id="${classPrefix}ActivityContextViewFactory"
+		class="${package}.ui.view.${classPrefix}ActivityContextViewFactory">
+		<property name="editManager" ref="editManager" />
+		<property name="fileManager" ref="fileManager" />
+		<property name="activityIconManager" ref="activityIconManager" />
+		<property name="serviceDescriptionRegistry" ref="serviceDescriptionRegistry" />
+		<property name="serviceRegistry" ref="serviceRegistry" />
+	</bean>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/resources/exampleIcon.png
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/resources/exampleIcon.png b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/resources/exampleIcon.png
new file mode 100644
index 0000000..3ef7be4
Binary files /dev/null and b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity-ui/src/main/resources/exampleIcon.png differ

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/pom.xml b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/pom.xml
new file mode 100644
index 0000000..755b218
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>${groupId}</groupId>
+		<artifactId>${rootArtifactId}</artifactId>
+		<version>${version}</version>
+	</parent>
+	<artifactId>${artifactId}</artifactId>
+	<packaging>bundle</packaging>
+	<name>${classPrefix} Taverna activity</name>
+
+	<dependencies>
+		<dependency>
+			<groupId>net.sf.taverna.t2.core</groupId>
+			<artifactId>workflowmodel-api</artifactId>
+			<version>${t2.core.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.taverna.t2.core</groupId>
+			<artifactId>reference-api</artifactId>
+			<version>${t2.core.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-databind</artifactId>
+			<version>2.3.0</version>
+		</dependency>
+
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.4</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.taverna.t2.core</groupId>
+			<artifactId>workflowmodel-impl</artifactId>
+			<version>${t2.core.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.taverna.t2.activities</groupId>
+			<artifactId>activity-test-utils</artifactId>
+			<version>${t2.activities.version}</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/java/__classPrefix__Activity.java
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/java/__classPrefix__Activity.java b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/java/__classPrefix__Activity.java
new file mode 100644
index 0000000..6696cfe
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/java/__classPrefix__Activity.java
@@ -0,0 +1,135 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+package ${package};
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import net.sf.taverna.t2.invocation.InvocationContext;
+import net.sf.taverna.t2.reference.ReferenceService;
+import net.sf.taverna.t2.reference.T2Reference;
+import net.sf.taverna.t2.workflowmodel.processor.activity.AbstractAsynchronousActivity;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityConfigurationException;
+import net.sf.taverna.t2.workflowmodel.processor.activity.AsynchronousActivity;
+import net.sf.taverna.t2.workflowmodel.processor.activity.AsynchronousActivityCallback;
+
+/**
+ * ${classPrefix} <code>Activity<code>.
+ */
+public class ${classPrefix}Activity extends AbstractAsynchronousActivity<JsonNode>
+		implements AsynchronousActivity<JsonNode> {
+
+	public static final String ACTIVITY_TYPE = "http://example.com/2013/activity/${rootArtifactId}";
+
+	/*
+	 * Best practice: Keep port names as constants to avoid misspelling. This
+	 * would not apply if port names are looked up dynamically from the service
+	 * operation, like done for WSDL services.
+	 */
+	public static final String IN_FIRST_INPUT = "firstInput";
+	public static final String IN_EXTRA_DATA = "extraData";
+	public static final String OUT_MORE_OUTPUTS = "moreOutputs";
+	public static final String OUT_SIMPLE_OUTPUT = "simpleOutput";
+	public static final String OUT_REPORT = "report";
+
+	private JsonNode configuration;
+
+	@Override
+	public void configure(JsonNode configuration) throws ActivityConfigurationException {
+
+		// Any pre-config sanity checks
+		if (configuration.get("exampleString").asText().equals("invalidExample")) {
+			throw new ActivityConfigurationException(
+					"Example string can't be 'invalidExample'");
+		}
+		// Store for getConfiguration(), but you could also make
+		// getConfiguration() return a new bean from other sources
+		this.configuration = configuration;
+
+		// OPTIONAL:
+		// Do any server-side lookups and configuration, like resolving WSDLs
+
+		// myClient = new MyClient(configuration.get("exampleUri").asText());
+		// this.service = myClient.getService(configuration.get("exampleString").asText());
+
+	}
+
+	@Override
+	public JsonNode getConfiguration() {
+		return configuration;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public void executeAsynch(final Map<String, T2Reference> inputs,
+			final AsynchronousActivityCallback callback) {
+		// Don't execute service directly now, request to be run ask to be run
+		// from thread pool and return asynchronously
+		callback.requestRun(new Runnable() {
+
+			public void run() {
+				InvocationContext context = callback
+						.getContext();
+				ReferenceService referenceService = context
+						.getReferenceService();
+				// Resolve inputs
+				String firstInput = (String) referenceService.renderIdentifier(inputs.get(IN_FIRST_INPUT),
+						String.class, context);
+
+				// Support our configuration-dependendent input
+				boolean optionalPorts = configuration.get("exampleString").asText().equals("specialCase");
+
+				List<byte[]> special = null;
+				// We'll also allow IN_EXTRA_DATA to be optionally not provided
+				if (optionalPorts && inputs.containsKey(IN_EXTRA_DATA)) {
+					// Resolve as a list of byte[]
+					special = (List<byte[]>) referenceService.renderIdentifier(
+							inputs.get(IN_EXTRA_DATA), byte[].class, context);
+				}
+
+
+				// TODO: Do the actual service invocation
+//				try {
+//					results = this.service.invoke(firstInput, special)
+//				} catch (ServiceException ex) {
+//					callback.fail("Could not invoke ${classPrefix} service " + configBean.getExampleUri(),
+//							ex);
+//					// Make sure we don't call callback.receiveResult later
+//					return;
+//				}
+
+				// Register outputs
+				Map<String, T2Reference> outputs = new HashMap<>();
+				String simpleValue = "simple";
+				T2Reference simpleRef = referenceService.register(simpleValue, 0, true, context);
+				outputs.put(OUT_SIMPLE_OUTPUT, simpleRef);
+
+				// For list outputs, only need to register the top level list
+				List<String> moreValues = new ArrayList<>();
+				moreValues.add("Value 1");
+				moreValues.add("Value 2");
+				T2Reference moreRef = referenceService.register(moreValues, 1, true, context);
+				outputs.put(OUT_MORE_OUTPUTS, moreRef);
+
+				if (optionalPorts) {
+					// Populate our optional output port
+					// NOTE: Need to return output values for all defined output ports
+					String report = "Everything OK";
+					outputs.put(OUT_REPORT, referenceService.register(report,
+							0, true, context));
+				}
+
+				// return map of output data, with empty index array as this is
+				// the only and final result (this index parameter is used if
+				// pipelining output)
+				callback.receiveResult(outputs, new int[0]);
+			}
+		});
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/java/__classPrefix__ActivityFactory.java
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/java/__classPrefix__ActivityFactory.java b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/java/__classPrefix__ActivityFactory.java
new file mode 100644
index 0000000..0fcb08b
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/java/__classPrefix__ActivityFactory.java
@@ -0,0 +1,97 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+package ${package};
+
+import static ${package}.${classPrefix}Activity.*;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import net.sf.taverna.t2.workflowmodel.Edits;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityFactory;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityInputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityOutputPort;
+
+/**
+ * ${classPrefix} <code>ActivityFactory<code>.
+ */
+public class ${classPrefix}ActivityFactory implements ActivityFactory {
+
+	private Edits edits;
+
+	@Override
+	public ${classPrefix}Activity createActivity() {
+		return new ${classPrefix}Activity();
+	}
+
+	@Override
+	public URI getActivityType() {
+		return URI.create(${classPrefix}Activity.ACTIVITY_TYPE);
+	}
+
+	@Override
+	public JsonNode getActivityConfigurationSchema() {
+		ObjectMapper objectMapper = new ObjectMapper();
+		try {
+			return objectMapper.readTree(getClass().getResource("/schema.json"));
+		} catch (IOException e) {
+			return objectMapper.createObjectNode();
+		}
+	}
+
+	@Override
+	public Set<ActivityInputPort> getInputPorts(JsonNode configuration) {
+		Set<ActivityInputPort> inputPorts = new HashSet<>();
+
+		// FIXME: Replace with your input port definitions
+
+		// Hard coded input port, expecting a single String
+		inputPorts.add(edits.createActivityInputPort(IN_FIRST_INPUT, 0, true, null, String.class));
+
+		// Optional ports depending on configuration
+		if (configuration.get("exampleString").asText().equals("specialCase")) {
+			// depth 1, ie. list of binary byte[] arrays
+			inputPorts.add(edits.createActivityInputPort(IN_EXTRA_DATA, 1, true, null, byte[].class));
+		}
+
+		return inputPorts;
+	}
+
+	@Override
+	public Set<ActivityOutputPort> getOutputPorts(JsonNode configuration) {
+		Set<ActivityOutputPort> outputPorts = new HashSet<>();
+
+		// FIXME: Replace with your output port definitions
+
+		// Optional ports depending on configuration
+		if (configuration.get("exampleString").asText().equals("specialCase")) {
+			outputPorts.add(edits.createActivityOutputPort(OUT_REPORT, 0, 0));
+		}
+
+		// Single value output port (depth 0)
+		outputPorts.add(edits.createActivityOutputPort(OUT_SIMPLE_OUTPUT, 0, 0));
+		// Output port with list of values (depth 1)
+		outputPorts.add(edits.createActivityOutputPort(OUT_MORE_OUTPUTS, 1, 1));
+
+		return outputPorts;
+	}
+
+	/**
+	 * Sets the edits property.
+	 * <p>
+	 * This method is used by Spring. The property name must match the property specified
+	 * in the Spring context file.
+	 *
+	 * @param edits the <code>Edits</code> used to create input/output ports
+	 */
+	public void setEdits(Edits edits) {
+		this.edits = edits;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/java/__classPrefix__ActivityHealthChecker.java
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/java/__classPrefix__ActivityHealthChecker.java b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/java/__classPrefix__ActivityHealthChecker.java
new file mode 100644
index 0000000..f5568fc
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/java/__classPrefix__ActivityHealthChecker.java
@@ -0,0 +1,66 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+package ${package};
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import net.sf.taverna.t2.visit.VisitReport;
+import net.sf.taverna.t2.visit.VisitReport.Status;
+import net.sf.taverna.t2.workflowmodel.health.HealthCheck;
+import net.sf.taverna.t2.workflowmodel.health.HealthChecker;
+
+/**
+ * ${classPrefix} <code>HealthChecker</code>.
+ */
+public class ${classPrefix}ActivityHealthChecker implements
+		HealthChecker<${classPrefix}Activity> {
+
+	public boolean canVisit(Object o) {
+		// Return True if we can visit the object. We could do
+		// deeper (but not time consuming) checks here, for instance
+		// if the health checker only deals with ${classPrefix}Activity where
+		// a certain configuration option is enabled.
+		return o instanceof ${classPrefix}Activity;
+	}
+
+	public boolean isTimeConsuming() {
+		// Return true if the health checker does a network lookup
+		// or similar time consuming checks, in which case
+		// it would only be performed when using File->Validate workflow
+		// or File->Run.
+		return false;
+	}
+
+	public VisitReport visit(${classPrefix}Activity activity, List<Object> ancestry) {
+		JsonNode config = activity.getConfiguration();
+
+		// We'll build a list of subreports
+		List<VisitReport> subReports = new ArrayList<>();
+
+		if (!URI.create(config.get("exampleUri").asText()).isAbsolute()) {
+			// Report Severe problems we know won't work
+			VisitReport report = new VisitReport(HealthCheck.getInstance(),
+					activity, "Example URI must be absolute", HealthCheck.INVALID_URL,
+					Status.SEVERE);
+			subReports.add(report);
+		}
+
+		if (config.get("exampleString").asText().equals("")) {
+			// Warning on possible problems
+			subReports.add(new VisitReport(HealthCheck.getInstance(), activity,
+					"Example string empty", HealthCheck.NO_CONFIGURATION,
+					Status.WARNING));
+		}
+
+		// The default explanation here will be used if the subreports list is
+		// empty
+		return new VisitReport(HealthCheck.getInstance(), activity,
+				"${classPrefix} service OK", HealthCheck.NO_PROBLEM, subReports);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/resources/META-INF/spring/context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/resources/META-INF/spring/context-osgi.xml b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/resources/META-INF/spring/context-osgi.xml
new file mode 100644
index 0000000..e8d6e12
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/resources/META-INF/spring/context-osgi.xml
@@ -0,0 +1,17 @@
+<?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">
+
+	<!-- Services to be registered with the OSGi service register -->
+	<service ref="${classPrefix}ActivityHealthChecker" interface="net.sf.taverna.t2.workflowmodel.health.HealthChecker" />
+
+	<service ref="${classPrefix}ActivityFactory" interface="net.sf.taverna.t2.workflowmodel.processor.activity.ActivityFactory" />
+
+	<!-- References to services required from the OSGi service register -->
+	<reference id="edits" interface="net.sf.taverna.t2.workflowmodel.Edits" />
+
+</beans:beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/resources/META-INF/spring/context.xml
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/resources/META-INF/spring/context.xml b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/resources/META-INF/spring/context.xml
new file mode 100644
index 0000000..49f5428
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/resources/META-INF/spring/context.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans
+                           http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+	<bean id="${classPrefix}ActivityHealthChecker" class="${package}.${classPrefix}ActivityHealthChecker" />
+
+	<bean id="${classPrefix}ActivityFactory" class="${package}.${classPrefix}ActivityFactory">
+		<property name="edits" ref="edits" />
+	</bean>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/resources/schema.json
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/resources/schema.json b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/resources/schema.json
new file mode 100644
index 0000000..2916b11
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/main/resources/schema.json
@@ -0,0 +1,25 @@
+{
+    "$schema": "http://json-schema.org/draft-03/schema#",
+    "id": "http://example.com/2013/activity/${rootArtifactId}.schema.json",
+    "title": "${classPrefix} activity configuration",
+    "type": "object",
+    "properties": {
+        "@context": {
+            "description": "JSON-LD context for interpreting the configuration as RDF",
+            "required": true,
+            "enum": ["http://example.com/2013/activity/${rootArtifactId}.context.json"]
+        },
+        "exampleString": {
+            "title": "Example String",
+            "description": "An example string property",
+            "type": "string",
+            "required": true
+        },
+        "exampleUri": {
+            "title": "Example URI",
+            "description": "An example uri property",
+            "type": "string",
+            "required": true
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/test/java/__classPrefix__ActivityFactoryTest.java
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/test/java/__classPrefix__ActivityFactoryTest.java b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/test/java/__classPrefix__ActivityFactoryTest.java
new file mode 100644
index 0000000..4de382e
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/test/java/__classPrefix__ActivityFactoryTest.java
@@ -0,0 +1,103 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+package ${package};
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import net.sf.taverna.t2.workflowmodel.impl.EditsImpl;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityInputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityOutputPort;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class ${classPrefix}ActivityFactoryTest {
+
+	private ObjectNode configuration;
+
+	private ${classPrefix}ActivityFactory activityFactory;
+
+	@Before
+	public void setUp() throws Exception {
+		configuration = JsonNodeFactory.instance.objectNode();
+		configuration.put("exampleString", "something");
+		configuration.put("exampleUri", "http://localhost:8080/myEndPoint");
+
+		activityFactory = new ${classPrefix}ActivityFactory();
+		activityFactory.setEdits(new EditsImpl());
+	}
+
+	@Test
+	public void testCreateActivity() {
+		${classPrefix}Activity activity = activityFactory.createActivity();
+		assertNotNull(activity);
+		assertNotSame(activity, activityFactory.createActivity());
+	}
+
+	@Test
+	public void testGetActivityURI() {
+		assertEquals(URI.create(${classPrefix}Activity.ACTIVITY_TYPE), activityFactory.getActivityType());
+	}
+
+	@Test
+	public void testGetActivityConfigurationSchema() {
+		JsonNode configurationSchema = activityFactory.getActivityConfigurationSchema();
+		assertNotNull(configurationSchema);
+		assertTrue(configurationSchema.has("properties"));
+		JsonNode propertiesNode = configurationSchema.get("properties");
+		assertTrue(propertiesNode.has("exampleString"));
+		assertTrue(propertiesNode.has("exampleUri"));
+	}
+
+	@Test
+	public void testGetInputPorts() {
+		Set<String> expectedInputs = new HashSet<String>();
+		expectedInputs.add("firstInput");
+
+		Set<ActivityInputPort> inputPorts = activityFactory.getInputPorts(configuration);
+		assertEquals("Unexpected inputs", expectedInputs.size(), inputPorts.size());
+		for (ActivityInputPort inputPort : inputPorts) {
+			assertTrue("Wrong input : " + inputPort.getName(), expectedInputs
+					.remove(inputPort.getName()));
+		}
+
+		ObjectNode specialConfiguration = JsonNodeFactory.instance.objectNode();
+		specialConfiguration.put("exampleString", "specialCase");
+		specialConfiguration.put("exampleUri", "http://localhost:8080/myEndPoint");
+
+		assertEquals("Unexpected inputs", 2, activityFactory.getInputPorts(specialConfiguration).size());
+	}
+
+	@Test
+	public void testGetOutputPorts() {
+		Set<String> expectedOutputs = new HashSet<String>();
+		expectedOutputs.add("simpleOutput");
+		expectedOutputs.add("moreOutputs");
+
+		Set<ActivityOutputPort> outputPorts = activityFactory.getOutputPorts(configuration);
+		assertEquals("Unexpected outputs", expectedOutputs.size(), outputPorts.size());
+		for (ActivityOutputPort outputPort : outputPorts) {
+			assertTrue("Wrong output : " + outputPort.getName(),
+					expectedOutputs.remove(outputPort.getName()));
+		}
+
+		ObjectNode specialConfiguration = JsonNodeFactory.instance.objectNode();
+		specialConfiguration.put("exampleString", "specialCase");
+		specialConfiguration.put("exampleUri", "http://localhost:8080/myEndPoint");
+
+		assertEquals("Unexpected outputs", 3, activityFactory.getOutputPorts(specialConfiguration).size());
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/test/java/__classPrefix__ActivityTest.java
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/test/java/__classPrefix__ActivityTest.java b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/test/java/__classPrefix__ActivityTest.java
new file mode 100644
index 0000000..e992290
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-activity/src/test/java/__classPrefix__ActivityTest.java
@@ -0,0 +1,76 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+package ${package};
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import net.sf.taverna.t2.activities.testutils.ActivityInvoker;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityConfigurationException;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityInputPort;
+import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityOutputPort;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class ${classPrefix}ActivityTest {
+
+	private ObjectNode configuration;
+
+	private ${classPrefix}Activity activity = new ${classPrefix}Activity();
+
+	@Before
+	public void makeConfiguration() throws Exception {
+		configuration = JsonNodeFactory.instance.objectNode();
+		configuration.put("exampleString", "something");
+		configuration.put("exampleUri", "http://localhost:8080/myEndPoint");
+	}
+
+	@Test
+	public void configureActivity() throws Exception {
+		activity.configure(configuration);
+		assertTrue(configuration.equals(activity.getConfiguration()));
+	}
+
+	@Test(expected = ActivityConfigurationException.class)
+	public void invalidConfiguration() throws ActivityConfigurationException {
+		ObjectNode invalidBean = JsonNodeFactory.instance.objectNode();
+		invalidBean.put("exampleString", "invalidExample");
+		// Should throw ActivityConfigurationException
+		activity.configure(invalidBean);
+	}
+
+	@Test
+	public void executeAsynch() throws Exception {
+		activity.configure(configuration);
+
+		Map<String, Object> inputs = new HashMap<String, Object>();
+		inputs.put("firstInput", "hello");
+
+		Map<String, Class<?>> expectedOutputTypes = new HashMap<String, Class<?>>();
+		expectedOutputTypes.put("simpleOutput", String.class);
+		expectedOutputTypes.put("moreOutputs", String.class);
+
+		Map<String, Object> outputs = ActivityInvoker.invokeAsyncActivity(
+				activity, inputs, expectedOutputTypes);
+
+		assertEquals("Unexpected outputs", 2, outputs.size());
+		assertEquals("simple", outputs.get("simpleOutput"));
+		assertEquals(Arrays.asList("Value 1", "Value 2"), outputs
+				.get("moreOutputs"));
+
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-plugin/pom.xml b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-plugin/pom.xml
new file mode 100644
index 0000000..72c44ed
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/__rootArtifactId__-plugin/pom.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>${groupId}</groupId>
+		<artifactId>${rootArtifactId}</artifactId>
+		<version>${version}</version>
+	</parent>
+	<artifactId>${artifactId}</artifactId>
+	<packaging>taverna-plugin</packaging>
+	<name>${classPrefix} Taverna plugin</name>
+	<description>Description of Example Taverna plugin</description>
+	<dependencies>
+		<dependency>
+			<groupId>${project.groupId}</groupId>
+			<artifactId>${rootArtifactId}-activity</artifactId>
+			<version>${version}</version>
+		</dependency>
+		<dependency>
+			<groupId>${project.groupId}</groupId>
+			<artifactId>${rootArtifactId}-activity-ui</artifactId>
+			<version>${version}</version>
+		</dependency>
+	</dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/8dd0a1ed/taverna-activity-archetype/src/main/resources/archetype-resources/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-activity-archetype/src/main/resources/archetype-resources/pom.xml b/taverna-activity-archetype/src/main/resources/archetype-resources/pom.xml
new file mode 100644
index 0000000..57b4aa9
--- /dev/null
+++ b/taverna-activity-archetype/src/main/resources/archetype-resources/pom.xml
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<groupId>${groupId}</groupId>
+	<artifactId>${artifactId}</artifactId>
+	<version>${version}</version>
+	<packaging>pom</packaging>
+	<name>${classPrefix} Taverna project</name>
+
+	<properties>
+		<t2.core.version>2.0.1-SNAPSHOT</t2.core.version>
+		<t2.activities.version>2.0.1-SNAPSHOT</t2.activities.version>
+		<t2.ui.api.version>2.0-SNAPSHOT</t2.ui.api.version>
+	</properties>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.7</source>
+					<target>1.7</target>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+				<version>2.1.2</version>
+				<executions>
+					<execution>
+						<goals>
+							<goal>jar</goal>
+							<goal>test-jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-jar-plugin</artifactId>
+				<version>2.3.1</version>
+				<executions>
+					<execution>
+						<goals>
+							<goal>test-jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<version>2.7.1</version>
+				<configuration>
+					<skip>false</skip>
+					<systemProperties>
+						<property>
+							<name>java.awt.headless</name>
+							<value>true</value>
+						</property>
+					</systemProperties>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-bundle-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<groupId>net.sf.taverna.t2.maven.plugins</groupId>
+				<artifactId>taverna-maven-plugin</artifactId>
+				<version>0.3.1-SNAPSHOT</version>
+				<extensions>true</extensions>
+			</plugin>
+		</plugins>
+		<pluginManagement>
+			<plugins>
+				<plugin>
+					<groupId>org.apache.felix</groupId>
+					<artifactId>maven-bundle-plugin</artifactId>
+					<version>2.3.7</version>
+					<extensions>true</extensions>
+				</plugin>
+				<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+				<plugin>
+					<groupId>org.eclipse.m2e</groupId>
+					<artifactId>lifecycle-mapping</artifactId>
+					<version>1.0.0</version>
+					<configuration>
+						<lifecycleMappingMetadata>
+							<pluginExecutions>
+								<pluginExecution>
+									<pluginExecutionFilter>
+										<groupId>
+											net.sf.taverna.t2.maven.plugins
+										</groupId>
+										<artifactId>
+											taverna-maven-plugin
+										</artifactId>
+										<versionRange>
+											[0.3.1-SNAPSHOT,)
+										</versionRange>
+										<goals>
+											<goal>plugin-generate</goal>
+										</goals>
+									</pluginExecutionFilter>
+									<action>
+										<ignore></ignore>
+									</action>
+								</pluginExecution>
+							</pluginExecutions>
+						</lifecycleMappingMetadata>
+					</configuration>
+				</plugin>
+			</plugins>
+		</pluginManagement>
+	</build>
+
+	<dependencies>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.4</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+
+	<repositories>
+		<repository>
+			<!-- The myGrid repository for Taverna dependencies -->
+			<releases />
+			<snapshots>
+				<enabled>false</enabled>
+			</snapshots>
+			<id>mygrid-repository</id>
+			<name>myGrid Repository</name>
+			<url>http://www.mygrid.org.uk/maven/repository</url>
+		</repository>
+		<repository>
+			<!-- The myGrid snapshot repository for Taverna dependencies -->
+			<releases>
+				<enabled>false</enabled>
+			</releases>
+			<snapshots />
+			<id>mygrid-snapshot-repository</id>
+			<name>myGrid Snapshot Repository</name>
+			<url>http://www.mygrid.org.uk/maven/snapshot-repository</url>
+		</repository>
+		<repository>
+			<!-- The repository that your jars are deployed to -->
+			<id>my-repository</id>
+			<name>My Repository</name>
+			<url>http://www.example.com/maven/repository</url>
+		</repository>
+		<repository>
+			<!-- The repository that your snapshot jars are deployed to -->
+			<releases>
+				<enabled>false</enabled>
+			</releases>
+			<snapshots />
+			<id>my-snapshot-repository</id>
+			<name>My snapshot Repository</name>
+			<url>file:///tmp/test-plugins/</url>
+		</repository>
+	</repositories>
+
+	<pluginRepositories>
+		<pluginRepository>
+			<id>mygrid-repository</id>
+			<name>myGrid Repository</name>
+			<url>http://www.mygrid.org.uk/maven/repository</url>
+		</pluginRepository>
+	</pluginRepositories>
+
+	<!-- The location of your plugin site -->
+	<distributionManagement>
+		<repository>
+			<id>my-plugin-site</id>
+			<name>My Plugin Site</name>
+			<url>scpexe://example.com/www/taverna/plugins/</url>
+		</repository>
+		<snapshotRepository>
+			<id>my-test-plugin-site</id>
+			<name>My Test Plugin Site</name>
+			<url>file:///tmp/test-plugins/</url>
+		</snapshotRepository>
+	</distributionManagement>
+
+</project>