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 2018/06/29 10:55:02 UTC

[15/27] incubator-taverna-plugin-component git commit: package rename folders

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/ComponentHealthCheck.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/ComponentHealthCheck.java b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/ComponentHealthCheck.java
deleted file mode 100644
index a3585f4..0000000
--- a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/ComponentHealthCheck.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.util;
-
-import static org.apache.log4j.Logger.getLogger;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import io.github.taverna_extras.component.api.ComponentException;
-import io.github.taverna_extras.component.api.ComponentFactory;
-import io.github.taverna_extras.component.api.Version;
-import io.github.taverna_extras.component.ui.ComponentActivityConfigurationBean;
-
-import org.apache.taverna.scufl2.api.activity.Activity;
-import org.apache.taverna.scufl2.api.common.Visitor;
-import org.apache.taverna.scufl2.api.container.WorkflowBundle;
-import org.apache.taverna.scufl2.validation.correctness.DefaultDispatchingVisitor;
-import org.apache.taverna.visit.VisitKind;
-import org.apache.taverna.visit.VisitReport;
-
-public class ComponentHealthCheck extends VisitKind {
-	public static final int NO_PROBLEM = 0;
-	public static final int OUT_OF_DATE = 10;
-	public static final int NON_SHAREABLE = 20;
-	public static final int FAILS_PROFILE = 30;
-	private static Logger logger = getLogger(ComponentHealthCheck.class);
-	private static final String OUTDATED_MSG = "Component out of date";
-
-	private ComponentFactory factory;
-
-	public void setComponentFactory(ComponentFactory factory) {
-		this.factory = factory;
-	}
-
-	public List<Object> checkForOutdatedComponents(WorkflowBundle bundle) {
-		UpgradeChecker uc = new UpgradeChecker();
-		bundle.accept(uc);
-		return uc.warnings;
-	}
-
-	private class UpgradeChecker extends DefaultDispatchingVisitor {
-		ComponentFactory factory;
-		List<Object> warnings = new ArrayList<>();
-
-		@Override
-		public void visitActivity(Activity activity) {
-			ComponentActivityConfigurationBean config = new ComponentActivityConfigurationBean(
-					activity.getConfiguration().getJson(), factory);
-			Version v;
-			try {
-				v = config.getVersion();
-			} catch (ComponentException e) {
-				logger.error("failed to get component description", e);
-				warnings.add(e);//FIXME Just putting the exception in here isn't good
-				return;
-			}
-			visitComponent(activity, v);
-		}
-		protected void visitComponent(Activity activity, Version version) {
-			int latest = version.getComponent().getComponentVersionMap().lastKey();
-			if (latest > version.getVersionNumber())
-				warnings.add(new VisitReport(ComponentHealthCheck.this,
-						activity, OUTDATED_MSG, OUT_OF_DATE,
-						VisitReport.Status.WARNING));
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/Utils.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/Utils.java b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/Utils.java
deleted file mode 100644
index e81cbf6..0000000
--- a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/Utils.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.util;
-
-import static io.github.taverna_extras.component.ui.ComponentConstants.ACTIVITY_URI;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import io.github.taverna_extras.component.api.ComponentFactory;
-import io.github.taverna_extras.component.api.Version;
-import io.github.taverna_extras.component.ui.preference.ComponentPreference;
-import io.github.taverna_extras.component.ui.serviceprovider.ComponentServiceIcon;
-import io.github.taverna_extras.component.ui.serviceprovider.ComponentServiceProvider;
-
-import org.apache.taverna.scufl2.api.activity.Activity;
-import org.apache.taverna.scufl2.api.common.Named;
-import org.apache.taverna.scufl2.api.common.NamedSet;
-import org.apache.taverna.scufl2.api.configurations.Configuration;
-import org.apache.taverna.scufl2.api.container.WorkflowBundle;
-import org.apache.taverna.servicedescriptions.ServiceDescriptionRegistry;
-import org.apache.taverna.workbench.file.FileManager;
-//import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
-//import net.sf.taverna.t2.workbench.file.FileManager;
-
-/**
- * @author alanrw
- */
-public class Utils {
-	// From http://stackoverflow.com/questions/163360/regular-expresion-to-match-urls-in-java
-	public static String URL_PATTERN = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";
-	public static final String LONG_STRING = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
-	public static final String SHORT_STRING = "XXX";
-
-	private FileManager fileManager;
-	private ServiceDescriptionRegistry registry;
-	private ComponentFactory factory;
-	private ComponentPreference prefs;
-	private ComponentServiceIcon icon;
-
-	public void setComponentFactory(ComponentFactory factory) {
-		this.factory = factory;
-	}
-	
-	public void setFileManager(FileManager fileManager) {
-		this.fileManager = fileManager;
-	}
-
-	public void setIcon(ComponentServiceIcon icon) {
-		this.icon = icon;
-	}
-	
-	public void setPrefs(ComponentPreference prefs) {
-		this.prefs = prefs;
-	}
-	
-	public void setRegistry(ServiceDescriptionRegistry registry) {
-		this.registry = registry;
-	}
-
-	public void refreshComponentServiceProvider(Configuration config) {
-		ComponentServiceProvider provider = new ComponentServiceProvider(
-				factory, prefs, icon, this);
-		provider.configure(config);
-		registry.removeServiceDescriptionProvider(provider);
-		registry.addServiceDescriptionProvider(provider);
-	}
-
-	public void removeComponentServiceProvider(Configuration config) {
-		ComponentServiceProvider provider = new ComponentServiceProvider(
-				factory, prefs, icon, this);
-		provider.configure(config);
-		registry.removeServiceDescriptionProvider(provider);
-	}
-
-	public boolean dataflowIsComponent(WorkflowBundle d) {
-		if (d == null)
-			return false;
-		Object dataflowSource = fileManager.getDataflowSource(d);
-		return dataflowSource instanceof Version.ID;// FIXME Really?
-	}
-
-	public boolean currentDataflowIsComponent() {
-		return dataflowIsComponent(fileManager.getCurrentDataflow());
-	}
-
-	public static boolean isComponentActivity(Object obj) {
-		if (obj == null || !(obj instanceof Activity))
-			return false;
-		Configuration cfg = ((Activity) obj).getConfiguration();
-		return cfg != null && ACTIVITY_URI.equals(cfg.getType());
-	}
-
-	private static final Pattern SANITIZER_RE = Pattern
-			.compile("[^a-zA-Z0-9]+");
-	private static final Pattern SUFFIXED_RE = Pattern
-			.compile("^(.+)_([0-9]+)$");
-
-	/**
-	 * Pick a name that is unique within the context set. This is done by
-	 * appending "<tt>_<i>n</i></tt>" as necessary, where <tt><i>n</i></tt> is a
-	 * number.
-	 * 
-	 * @param name
-	 *            The suggested name; this is always checked first.
-	 * @param context
-	 *            The set of things that the name will have to be unique within.
-	 * @return A name that is definitely not the name of anything in the given
-	 *         set.
-	 */
-	public static String uniqueName(String name, NamedSet<? extends Named> context) {
-		String candidate = SANITIZER_RE.matcher(name).replaceAll("_");
-		if (context.getByName(candidate) == null)
-			return candidate;
-		int counter = 0;
-		String prefix = candidate;
-		Matcher m = SUFFIXED_RE.matcher(candidate);
-		if (m.matches()) {
-			prefix = m.group(1);
-			counter = Integer.parseInt(m.group(2));
-		}
-		do {
-			candidate = prefix + "_" + (++counter);
-		} while (context.getByName(candidate) != null);
-		return candidate;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivityContextViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivityContextViewFactory.java b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivityContextViewFactory.java
deleted file mode 100644
index c27278f..0000000
--- a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivityContextViewFactory.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.view;
-
-import static io.github.taverna_extras.component.api.config.ComponentConfig.URI;
-
-import java.awt.Frame;
-import java.net.MalformedURLException;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.swing.Action;
-
-import io.github.taverna_extras.component.api.ComponentFactory;
-import io.github.taverna_extras.component.ui.config.ComponentConfigureAction;
-
-import org.apache.taverna.scufl2.api.activity.Activity;
-import org.apache.taverna.servicedescriptions.ServiceDescriptionRegistry;
-import org.apache.taverna.services.ServiceRegistry;
-import org.apache.taverna.workbench.activityicons.ActivityIconManager;
-import org.apache.taverna.workbench.configuration.colour.ColourManager;
-import org.apache.taverna.workbench.edits.EditManager;
-import org.apache.taverna.workbench.file.FileManager;
-import org.apache.taverna.workbench.ui.actions.activity.HTMLBasedActivityContextualView;
-import org.apache.taverna.workbench.ui.views.contextualviews.ContextualView;
-import org.apache.taverna.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
-
-public class ComponentActivityContextViewFactory implements
-		ContextualViewFactory<Activity> {
-	private ColourManager colourManager;
-	private ViewUtil util;
-	private ComponentFactory factory;
-	private ActivityIconManager aim;
-	private ServiceDescriptionRegistry sdr;
-	private EditManager em;
-	private FileManager fm;
-	private ServiceRegistry sr;
-
-	public void setComponentFactory(ComponentFactory factory) {
-		this.factory = factory;
-	}
-
-	public void setColourManager(ColourManager colourManager) {
-		this.colourManager = colourManager;
-	}
-
-	public void setViewUtils(ViewUtil util) {
-		this.util = util;
-	}
-
-	public void setIconManager(ActivityIconManager aim) {
-		this.aim = aim;
-	}
-
-	public void setServiceDescriptionRegistry(ServiceDescriptionRegistry sdr) {
-		this.sdr = sdr;
-	}
-
-	public void setEditManager(EditManager em) {
-		this.em = em;
-	}
-
-	public void setFileManager(FileManager fm) {
-		this.fm = fm;
-	}
-
-	public void setServiceTypeRegistry(ServiceRegistry sr) {
-		this.sr = sr;
-	}
-
-	@Override
-	public boolean canHandle(Object selection) {
-		return selection instanceof Activity
-				&& ((Activity) selection).getType().equals(URI);
-	}
-
-	@Override
-	public List<ContextualView> getViews(Activity selection) {
-		return Arrays.<ContextualView>asList(new ComponentActivityContextualView(selection));
-	}
-
-	@SuppressWarnings("serial")
-	private class ComponentActivityContextualView extends
-			HTMLBasedActivityContextualView {
-		public ComponentActivityContextualView(Activity activity) {
-			super(activity, colourManager);
-			init();
-		}
-
-		private void init() {
-		}
-
-		@Override
-		public String getViewTitle() {
-			return "Component service";
-		}
-
-		/**
-		 * View position hint
-		 */
-		@Override
-		public int getPreferredPosition() {
-			// We want to be on top
-			return 100;
-		}
-
-		@Override
-		public Action getConfigureAction(Frame owner) {
-			return new ComponentConfigureAction(getActivity(), owner, factory,
-					aim, sdr, em, fm, sr);
-		}
-
-		@Override
-		protected String getRawTableRowsHtml() {
-			try {
-				return util.getRawTablesHtml(getConfigBean());
-			} catch (MalformedURLException e) {
-				return "<tr><td>malformed URL: <pre>" + e.getMessage()
-						+ "</pre></td></tr>";
-			}
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationContextViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationContextViewFactory.java b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationContextViewFactory.java
deleted file mode 100644
index fcb6e4a..0000000
--- a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationContextViewFactory.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.view;
-
-import static org.apache.log4j.Logger.getLogger;
-import static io.github.taverna_extras.component.api.config.ComponentConfig.URI;
-
-import java.net.MalformedURLException;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import io.github.taverna_extras.component.api.ComponentException;
-import io.github.taverna_extras.component.api.ComponentFactory;
-import io.github.taverna_extras.component.api.profile.Profile;
-import io.github.taverna_extras.component.ui.ComponentActivityConfigurationBean;
-import io.github.taverna_extras.component.ui.annotation.AbstractSemanticAnnotationContextualView;
-
-import org.apache.taverna.scufl2.api.activity.Activity;
-import org.apache.taverna.scufl2.api.core.Workflow;
-import org.apache.taverna.scufl2.api.port.InputActivityPort;
-import org.apache.taverna.scufl2.api.port.InputWorkflowPort;
-import org.apache.taverna.scufl2.api.port.OutputActivityPort;
-import org.apache.taverna.scufl2.api.port.OutputWorkflowPort;
-import org.apache.taverna.scufl2.api.port.Port;
-import org.apache.taverna.workbench.file.FileManager;
-import org.apache.taverna.workbench.ui.views.contextualviews.ContextualView;
-import org.apache.taverna.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
-
-public class ComponentActivitySemanticAnnotationContextViewFactory implements
-		ContextualViewFactory<Object> {
-	public static final String VIEW_TITLE = "Inherited Semantic Annotations";
-	private static final Logger logger = getLogger(ComponentActivitySemanticAnnotationContextViewFactory.class);
-
-	private FileManager fm;
-	private ComponentFactory factory;
-
-	public void setFileManager(FileManager fm) {
-		this.fm = fm;
-	}
-
-	public void setComponentFactory(ComponentFactory factory) {
-		this.factory = factory;
-	}
-
-	@Override
-	public boolean canHandle(Object selection) {
-		return getContainingComponentActivity(selection) != null;
-	}
-
-	public Activity getContainingComponentActivity(Object selection) {
-		if (selection instanceof Activity) {
-			Activity a = (Activity) selection;
-			if (a.getType().equals(URI))
-				return a;
-		}
-		if (selection instanceof InputActivityPort
-				|| selection instanceof OutputActivityPort)
-			return getContainingComponentActivity(((OutputActivityPort) selection)
-					.getParent());
-		return null;
-	}
-
-	@Override
-	public List<ContextualView> getViews(Object selection) {
-		return Arrays
-				.<ContextualView> asList(new SemanticAnnotationCV(
-						selection));
-	}
-
-	@SuppressWarnings("serial")
-	private class SemanticAnnotationCV extends
-			AbstractSemanticAnnotationContextualView {
-		private Profile componentProfile;
-
-		public SemanticAnnotationCV(Object selection) {
-			super(fm, false);
-			Activity componentActivity = getContainingComponentActivity(selection);
-			try {
-				ComponentActivityConfigurationBean configuration = new ComponentActivityConfigurationBean(
-						componentActivity.getConfiguration(), factory);
-				setAnnotatedThing(selection, configuration.getVersion()
-						.getImplementation().getMainWorkflow());
-				componentProfile = configuration.getComponent().getFamily()
-						.getComponentProfile();
-				setProfile(selection);
-				super.initialise();
-			} catch (ComponentException e) {
-				logger.error("problem querying registry", e);
-			} catch (MalformedURLException e) {
-				logger.error("malformed URL in component description", e);
-			}
-		}
-
-		private void setAnnotatedThing(Object selection,
-				Workflow underlyingDataflow) {
-			if (selection instanceof Activity) {
-				setAnnotated(underlyingDataflow);
-			} else if (selection instanceof InputActivityPort) {
-				String name = ((Port) selection).getName();
-				for (InputWorkflowPort dip : underlyingDataflow.getInputPorts())
-					if (dip.getName().equals(name)) {
-						setAnnotated(dip);
-						break;
-					}
-			} else if (selection instanceof OutputActivityPort) {
-				String name = ((Port) selection).getName();
-				for (OutputWorkflowPort dop : underlyingDataflow
-						.getOutputPorts())
-					if (dop.getName().equals(name)) {
-						setAnnotated(dop);
-						break;
-					}
-			}
-		}
-
-		private void setProfile(Object selection) throws ComponentException {
-			if (componentProfile == null)
-				return;
-			if (selection instanceof Activity) {
-				setSemanticAnnotationProfiles(componentProfile
-						.getSemanticAnnotations());
-			} else if (selection instanceof InputActivityPort) {
-				setSemanticAnnotationProfiles(componentProfile
-						.getInputSemanticAnnotationProfiles());
-			} else if (selection instanceof OutputActivityPort) {
-				setSemanticAnnotationProfiles(componentProfile
-						.getOutputSemanticAnnotationProfiles());
-			}
-		}
-		
-		@Override
-		public String getViewTitle() {
-			return VIEW_TITLE;
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationPanel.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationPanel.java b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationPanel.java
deleted file mode 100644
index d3580a8..0000000
--- a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationPanel.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.view;
-
-import static java.awt.Color.GRAY;
-import static java.awt.Color.WHITE;
-import static java.awt.GridBagConstraints.BOTH;
-import static java.awt.GridBagConstraints.EAST;
-import static java.awt.GridBagConstraints.HORIZONTAL;
-import static java.awt.GridBagConstraints.SOUTHEAST;
-import static java.lang.String.format;
-import static io.github.taverna_extras.component.ui.annotation.SemanticAnnotationUtils.getDisplayName;
-import static io.github.taverna_extras.component.ui.annotation.SemanticAnnotationUtils.getObjectName;
-
-import java.awt.Component;
-import java.awt.Graphics;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.util.Set;
-
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JTextArea;
-import javax.swing.border.AbstractBorder;
-import javax.swing.border.EmptyBorder;
-
-import io.github.taverna_extras.component.api.profile.SemanticAnnotationProfile;
-
-import org.apache.jena.ontology.OntProperty;
-import org.apache.jena.rdf.model.Statement;
-
-public class ComponentActivitySemanticAnnotationPanel extends JPanel {
-	private static final long serialVersionUID = 3599768150252711758L;
-	private static final String ANNTYPE_MSG = "Annotation type : %s";
-	private static final String NONE_MSG = "No semantic annotations";	
-	private SemanticAnnotationProfile profile;
-	private final Set<Statement> statements;
-
-	public ComponentActivitySemanticAnnotationPanel(
-			SemanticAnnotationProfile profile, Set<Statement> statements) {
-		this.profile = profile;
-		this.statements = statements;
-		initialize();
-	}
-
-	private void initialize() {
-		setLayout(new GridBagLayout());
-		setBorder(new AbstractBorder() {
-			private static final long serialVersionUID = -5921448975807056953L;
-
-			@Override
-			public void paintBorder(Component c, Graphics g, int x, int y,
-					int width, int height) {
-				g.setColor(GRAY);
-				g.drawLine(x, y + height - 1, x + width - 1, y + height - 1);
-			}
-		});
-
-		GridBagConstraints c = new GridBagConstraints();
-		c.anchor = SOUTHEAST;
-		c.fill = BOTH;
-		c.weightx = 1;
-		c.gridx = 0;
-
-		OntProperty predicate = profile.getPredicate();
-		c.gridwidth = 2;
-		JLabel label = new JLabel(format(ANNTYPE_MSG, getDisplayName(predicate)));
-		label.setBorder(new EmptyBorder(5, 5, 5, 5));
-		label.setBackground(WHITE);
-		label.setOpaque(true);
-		add(label, c);
-
-		c.insets = new Insets(5, 7, 0, 0);
-		c.anchor = EAST;
-		c.fill = HORIZONTAL;
-		if (statements.isEmpty()) {
-			c.gridwidth = 2;
-			// c.weightx = 1;
-			// c.gridy++;
-			add(new JLabel(NONE_MSG), c);
-		} else {
-			c.gridwidth = 1;
-			for (Statement statement : statements) {
-				c.gridx = 0;
-				c.weightx = 1;
-				JTextArea value = new JTextArea(getObjectName(statement));
-				value.setBackground(WHITE);
-				value.setOpaque(true);
-				value.setBorder(new EmptyBorder(2, 4, 2, 4));
-				add(value, c);
-			}
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextViewFactory.java b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextViewFactory.java
deleted file mode 100644
index 938a32e..0000000
--- a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextViewFactory.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.view;
-
-import static io.github.taverna_extras.component.api.config.ComponentConfig.URI;
-
-import java.util.Arrays;
-import java.util.List;
-
-import io.github.taverna_extras.component.api.Version;
-
-import org.apache.taverna.scufl2.api.activity.Activity;
-import org.apache.taverna.scufl2.api.container.WorkflowBundle;
-import org.apache.taverna.workbench.file.FileManager;
-import org.apache.taverna.workbench.ui.views.contextualviews.ContextualView;
-import org.apache.taverna.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
-
-public class ComponentContextViewFactory implements
-		ContextualViewFactory<WorkflowBundle> {
-	private FileManager fileManager;
-
-	public void setFileManager(FileManager fileManager) {
-		this.fileManager = fileManager;
-	}
-
-	@Override
-	public boolean canHandle(Object selection) {
-		if (selection instanceof WorkflowBundle) {
-			Object dataflowSource = fileManager
-					.getDataflowSource((WorkflowBundle) selection);
-			//FIXME Is this right?
-			return dataflowSource instanceof Version.ID;
-		}
-		return selection instanceof Activity
-				&& ((Activity) selection).getType().equals(URI);
-	}
-
-	@Override
-	public List<ContextualView> getViews(WorkflowBundle selection) {
-		Object dataflowSource = fileManager.getDataflowSource(selection);
-		return Arrays.<ContextualView> asList(new ComponentContextualView(
-				(Version.ID) dataflowSource));
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextualView.java b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextualView.java
deleted file mode 100644
index c763d06..0000000
--- a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextualView.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.view;
-
-import static java.lang.String.format;
-
-import java.awt.Color;
-
-import javax.swing.JComponent;
-import javax.swing.JEditorPane;
-
-import io.github.taverna_extras.component.api.Version;
-import org.apache.taverna.lang.ui.HtmlUtils;
-import org.apache.taverna.workbench.configuration.colour.ColourManager;
-import org.apache.taverna.workbench.ui.views.contextualviews.ContextualView;
-
-@SuppressWarnings("serial")
-public class ComponentContextualView extends ContextualView {
-	private JEditorPane editorPane;
-	private final Version.ID component;
-	ColourManager colourManager;//FIXME beaninject
-	ViewUtil viewUtils;//FIXME beaninject;
-
-	public ComponentContextualView(Version.ID component) {
-		this.component = component;
-		initView();
-	}
-
-	@Override
-	public JComponent getMainFrame() {
-		editorPane = HtmlUtils.createEditorPane(buildHtml());
-		return HtmlUtils.panelForHtml(editorPane);
-	}
-
-	private String buildHtml() {
-		StringBuilder html = new StringBuilder(HtmlUtils.getHtmlHead(getBackgroundColour()));
-		html.append(HtmlUtils.buildTableOpeningTag());
-		viewUtils.getRawTablesHtml(component, html);
-		return html.append("</table></body></html>").toString();
-	}
-
-	public String getBackgroundColour() {
-		Color colour = colourManager.getPreferredColour(
-				"io.github.taverna_extras.component.registry.Component");
-		return format("#%1$2x%2$2x%3$2x", colour.getRed(), colour.getGreen(),
-				colour.getBlue());
-	}
-
-	@Override
-	public int getPreferredPosition() {
-		return 50;
-	}
-
-	private static int MAX_LENGTH = 50;
-
-	private String limitName(String fullName) {
-		if (fullName.length() > MAX_LENGTH)
-			return fullName.substring(0, MAX_LENGTH - 3) + "...";
-		return fullName;
-	}
-
-	@Override
-	public String getViewTitle() {
-		return "Component " + limitName(component.getComponentName());
-	}
-
-	@Override
-	public void refreshView() {
-		editorPane.setText(buildHtml());
-		repaint();
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ViewUtil.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ViewUtil.java b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ViewUtil.java
deleted file mode 100644
index 5764f6c..0000000
--- a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ViewUtil.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.view;
-
-import static java.lang.String.format;
-import static org.apache.log4j.Logger.getLogger;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Set;
-
-import org.apache.log4j.Logger;
-import io.github.taverna_extras.component.api.Component;
-import io.github.taverna_extras.component.api.ComponentFactory;
-import io.github.taverna_extras.component.api.Family;
-import io.github.taverna_extras.component.api.Version;
-import io.github.taverna_extras.component.ui.ComponentActivityConfigurationBean;
-
-import org.apache.taverna.scufl2.api.configurations.Configuration;
-import org.apache.taverna.scufl2.api.container.WorkflowBundle;
-import org.apache.taverna.scufl2.api.port.InputWorkflowPort;
-import org.apache.taverna.scufl2.api.port.OutputWorkflowPort;
-
-/**
- * @author alanrw
- */
-public class ViewUtil {
-	private static Logger logger = getLogger(ViewUtil.class);
-
-	private static final String VERSION_DESCRIPTION_LABEL = "Component version description";
-	private static final String COMPONENT_DESCRIPTION_LABEL = "Component description";
-	private static final String FAMILY_DESCRIPTION_LABEL = "Family description";
-
-	private static final String plainFormat = "<tr><td><b>%1$s</b></td><td nowrap=\"wrap\" style=\"width:100px;\">%2$s</td></tr>";
-	private static final String headerFormat = "<tr><th>%1$s</th><th>%2$s</th></tr>";
-	private static final String rowFormat = "<tr><td><b>%1$s</b></td><td>%2$s</td></tr>";
-	private static final String rowLinkFormat = "<tr><td><b>%1$s</b></td><td><a href=\"%3$s\">%2$s</a></td></tr>";
-	private static final String descriptionFormat = "<tr><td colspan=\"2\"><b>%1$s</b></td></tr><tr><td colspan=\"2\" nowrap=\"wrap\" style=\"width:100px;\">%2$s</td></tr>";
-
-	private ComponentFactory factory;//FIXME beaninject
-
-	public void setComponentFactory(ComponentFactory factory) {
-		this.factory = factory;
-	}
-
-	public String getRawTablesHtml(Version.ID id) {
-		StringBuilder html = new StringBuilder();
-		getRawTablesHtml(id, html);
-		return html.toString();
-	}
-
-	public String getRawTablesHtml(Configuration config) throws MalformedURLException {
-		StringBuilder html = new StringBuilder();
-		getRawTablesHtml(
-				new ComponentActivityConfigurationBean(
-						config.getJsonAsObjectNode(), factory), html);
-		return html.toString();
-	}
-
-	public void getRawTablesHtml(Version.ID id, StringBuilder html) {
-		URL registryBase = id.getRegistryBase();
-		String registryLink = null;
-		if (registryBase.getProtocol().startsWith("http"))
-			registryLink = registryBase.toExternalForm();
-		/*
-		 * \u200b is a zero-width space, so the HTML renderer can know to break
-		 * lines.
-		 */
-		String registryName = registryBase.toString().replaceAll("/", "\u200b/");
-		appendRow(html, "Component registry base", registryName, registryLink);
-
-		String familyName = id.getFamilyName();
-		appendRow(html, "Component family", familyName, null);
-		try {
-			Family family = factory.getFamily(registryBase, familyName);
-			if (family != null)
-				appendDescriptionHtml(html, FAMILY_DESCRIPTION_LABEL,
-						family.getDescription());
-		} catch (Exception e) {
-			logger.error("failed to get component family description", e);
-		}
-
-		String componentName = id.getComponentName();
-		String helpLink = null;
-		try {
-			URL helpURL = factory.getVersion(id).getHelpURL();
-			if (helpURL != null)
-				helpLink = helpURL.toExternalForm();
-		} catch (Exception e) {
-			logger.error(e);
-		}
-
-		appendRow(html, "Component name", componentName, helpLink);
-		try {
-			Component component = factory.getComponent(registryBase,
-					familyName, componentName);
-			if (component != null)
-				appendDescriptionHtml(html, COMPONENT_DESCRIPTION_LABEL,
-						component.getDescription());
-		} catch (Exception e) {
-			logger.error("failed to get component description", e);
-		}
-
-		Integer componentVersion = id.getComponentVersion();
-
-		if (componentVersion == null)
-			appendRow(html, "Component version", "N/A", helpLink);
-		else {
-			appendRow(html, "Component version", componentVersion, helpLink);
-			try {
-				Version version = factory.getVersion(registryBase,
-						familyName, componentName, componentVersion);
-				if (version != null) {
-					appendDescriptionHtml(html, VERSION_DESCRIPTION_LABEL,
-							version.getDescription());
-					WorkflowBundle impl = version.getImplementation();
-					Set<InputWorkflowPort> inputs = impl.getMainWorkflow().getInputPorts();
-					if (!inputs.isEmpty()) {
-						appendHeaderRow(html, "Input Port Name", "Depth");
-						for (InputWorkflowPort input : inputs)
-							appendPlainRow(html, input.getName(), input.getDepth());
-					}
-					Set<OutputWorkflowPort> outputs = impl.getMainWorkflow().getOutputPorts();
-					if (!outputs.isEmpty()) {
-						appendHeaderRow(html, "Output Port Name", "Depth");
-						for (OutputWorkflowPort output : outputs) {
-							//FIXME get depth of output ports!
-							appendPlainRow(html, output.getName(), -1 /*output.getDepth()*/);
-						}
-					}
-				}
-			} catch (Exception e) {
-				logger.error("failed to get component version description", e);
-			}
-		}
-	}
-
-	private static void appendRow(StringBuilder html, Object label,
-			Object value, String link) {
-		if (link == null)
-			html.append(format(rowFormat, label, value));
-		else
-			html.append(format(rowLinkFormat, label, value, link));
-	}
-
-	private static void appendHeaderRow(StringBuilder html, Object label1,
-			Object label2) {
-		html.append(format(headerFormat, label1, label2));
-	}
-
-	private static void appendPlainRow(StringBuilder html, Object value1,
-			Object value2) {
-		html.append(format(plainFormat, value1, value2));
-	}
-
-	private static void appendDescriptionHtml(StringBuilder html,
-			String header, String description) {
-		if ((description != null) && !description.isEmpty())
-			html.append(format(descriptionFormat, header, description));
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivity.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivity.java b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivity.java
new file mode 100644
index 0000000..9619297
--- /dev/null
+++ b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivity.java
@@ -0,0 +1,167 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.apache.log4j.Logger.getLogger;
+
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import io.github.taverna_extras.component.api.ComponentException;
+import io.github.taverna_extras.component.api.profile.ExceptionHandling;
+import io.github.taverna_extras.component.registry.ComponentImplementationCache;
+import io.github.taverna_extras.component.registry.ComponentUtil;
+import io.github.taverna_extras.component.utils.AnnotationUtils;
+import io.github.taverna_extras.component.utils.SystemUtils;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.apache.taverna.activities.dataflow.DataflowActivity;
+import org.apache.taverna.annotation.annotationbeans.SemanticAnnotation;
+import org.apache.taverna.invocation.InvocationContext;
+import org.apache.taverna.invocation.impl.InvocationContextImpl;
+import org.apache.taverna.platform.execution.api.InvalidWorkflowException;
+import org.apache.taverna.reference.ReferenceService;
+import org.apache.taverna.reference.T2Reference;
+import org.apache.taverna.workflowmodel.Dataflow;
+import org.apache.taverna.workflowmodel.EditException;
+import org.apache.taverna.workflowmodel.Edits;
+import org.apache.taverna.workflowmodel.processor.activity.AbstractAsynchronousActivity;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityConfigurationException;
+import org.apache.taverna.workflowmodel.processor.activity.AsynchronousActivityCallback;
+import org.apache.taverna.workflowmodel.utils.AnnotationTools;
+
+public class ComponentActivity extends
+		AbstractAsynchronousActivity<JsonNode> {
+	public static final String URI = "http://ns.taverna.org.uk/2010/activity/component";
+	private Logger logger = getLogger(ComponentActivity.class);
+
+	private ComponentUtil util;
+	private ComponentImplementationCache cache;
+	private volatile DataflowActivity componentRealization;
+	private JsonNode json;
+	private ComponentActivityConfigurationBean bean;
+	private SystemUtils system;
+	private AnnotationUtils annUtils;
+	private ComponentExceptionFactory cef;
+	
+	private Dataflow realizingDataflow = null;
+
+	ComponentActivity(ComponentUtil util, ComponentImplementationCache cache,
+			Edits edits, SystemUtils system, AnnotationUtils annUtils, ComponentExceptionFactory exnFactory) {
+		this.util = util;
+		this.cache = cache;
+		this.system = system;
+		this.annUtils = annUtils;
+		setEdits(edits);
+		this.componentRealization = new DataflowActivity();
+		this.cef = exnFactory;
+	}
+
+	@Override
+	public void configure(JsonNode json) throws ActivityConfigurationException {
+		this.json = json;
+		try {
+			bean = new ComponentActivityConfigurationBean(json, util, cache);
+		} catch (MalformedURLException e) {
+			throw new ActivityConfigurationException(
+					"failed to understand configuration", e);
+		}
+		try {
+			configurePorts(bean.getPorts());
+		} catch (ComponentException e) {
+			throw new ActivityConfigurationException(
+					"failed to get component realization", e);
+		}
+	}
+
+	@Override
+	public void executeAsynch(Map<String, T2Reference> inputs,
+			AsynchronousActivityCallback callback) {
+		try {
+			ExceptionHandling exceptionHandling = bean.getExceptionHandling();
+			// InvocationContextImpl newContext = copyInvocationContext(callback);
+
+			getComponentRealization().executeAsynch(inputs, new ProxyCallback(
+					callback, callback.getContext(), exceptionHandling, cef));
+		} catch (ActivityConfigurationException e) {
+			callback.fail("Unable to execute component", e);
+		}
+	}
+
+	@SuppressWarnings("unused")
+	private InvocationContextImpl copyInvocationContext(
+			AsynchronousActivityCallback callback) {
+		InvocationContext originalContext = callback.getContext();
+		ReferenceService rs = originalContext.getReferenceService();
+		InvocationContextImpl newContext = new InvocationContextImpl(rs, null);
+		// for (Object o : originalContext.getEntities(Object.class)) {
+		// newContext.addEntity(o);
+		// }
+		return newContext;
+	}
+
+	@Override
+	public JsonNode getConfiguration() {
+		return json;
+	}
+
+	ComponentActivityConfigurationBean getConfigBean() {
+		return bean;
+	}
+
+	private DataflowActivity getComponentRealization()
+			throws ActivityConfigurationException {
+		synchronized (componentRealization) {
+			try {
+				if (componentRealization.getNestedDataflow() == null) {
+					if (realizingDataflow == null)
+						realizingDataflow = system.compile(util
+								.getVersion(bean).getImplementation());
+					componentRealization.setNestedDataflow(realizingDataflow);
+					copyAnnotations();
+				}
+			} catch (ComponentException e) {
+				logger.error("unable to read workflow", e);
+				throw new ActivityConfigurationException(
+						"unable to read workflow", e);
+			} catch (InvalidWorkflowException e) {
+				logger.error("unable to compile workflow", e);
+				throw new ActivityConfigurationException(
+						"unable to compile workflow", e);
+			}
+		}
+		
+		return componentRealization;
+	}
+
+	private void copyAnnotations() {
+		// FIXME Completely wrong way of doing this!
+		try {
+			//annUtils.getAnnotation(subject, uriForAnnotation)
+			String annotationValue = AnnotationTools.getAnnotationString(realizingDataflow,
+					SemanticAnnotation.class, null);
+			if (annotationValue != null)
+				AnnotationTools.setAnnotationString(this, SemanticAnnotation.class,
+						annotationValue, getEdits()).doEdit();
+		} catch (EditException e) {
+			logger.error("failed to set annotation string", e);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityConfigurationBean.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityConfigurationBean.java b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityConfigurationBean.java
new file mode 100644
index 0000000..6819b3f
--- /dev/null
+++ b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityConfigurationBean.java
@@ -0,0 +1,168 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.apache.log4j.Logger.getLogger;
+import static io.github.taverna_extras.component.api.config.ComponentPropertyNames.COMPONENT_NAME;
+import static io.github.taverna_extras.component.api.config.ComponentPropertyNames.COMPONENT_VERSION;
+import static io.github.taverna_extras.component.api.config.ComponentPropertyNames.FAMILY_NAME;
+import static io.github.taverna_extras.component.api.config.ComponentPropertyNames.REGISTRY_BASE;
+
+import java.io.Serializable;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+//import net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean;
+//import net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityOutputPortDefinitionBean;
+//import net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityPortsDefinitionBean;
+
+import org.apache.log4j.Logger;
+import io.github.taverna_extras.component.api.Version;
+import io.github.taverna_extras.component.api.profile.ExceptionHandling;
+import io.github.taverna_extras.component.registry.ComponentImplementationCache;
+import io.github.taverna_extras.component.registry.ComponentUtil;
+import io.github.taverna_extras.component.registry.ComponentVersionIdentification;
+
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.scufl2.api.port.InputWorkflowPort;
+import org.apache.taverna.scufl2.api.port.OutputWorkflowPort;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.apache.taverna.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean;
+import org.apache.taverna.workflowmodel.processor.activity.config.ActivityOutputPortDefinitionBean;
+import org.apache.taverna.workflowmodel.processor.activity.config.ActivityPortsDefinitionBean;
+
+/**
+ * Component activity configuration bean.
+ */
+public class ComponentActivityConfigurationBean extends
+		ComponentVersionIdentification implements Serializable {
+	public static final String ERROR_CHANNEL = "error_channel";
+	public static final List<String> ignorableNames = Arrays
+			.asList(ERROR_CHANNEL);
+	private static final long serialVersionUID = 5774901665863468058L;
+	private static final Logger logger = getLogger(ComponentActivity.class);
+
+	private transient ActivityPortsDefinitionBean ports = null;
+	private transient ExceptionHandling eh;
+	private transient ComponentUtil util;
+	private transient ComponentImplementationCache cache;
+
+	public ComponentActivityConfigurationBean(Version.ID toBeCopied,
+			ComponentUtil util, ComponentImplementationCache cache) {
+		super(toBeCopied);
+		this.util = util;
+		this.cache = cache;
+		try {
+			getPorts();
+		} catch (io.github.taverna_extras.component.api.ComponentException e) {
+			logger.error("failed to get component realization", e);
+		}
+	}
+
+	public ComponentActivityConfigurationBean(JsonNode json,
+			ComponentUtil util, ComponentImplementationCache cache) throws MalformedURLException {
+		super(getUrl(json), getFamily(json), getComponent(json),
+				getVersion(json));
+		this.util = util;
+		this.cache = cache;
+	}
+
+	private static URL getUrl(JsonNode json) throws MalformedURLException {
+		return new URL(json.get(REGISTRY_BASE).textValue());
+	}
+
+	private static String getFamily(JsonNode json) {
+		return json.get(FAMILY_NAME).textValue();
+	}
+
+	private static String getComponent(JsonNode json) {
+		return json.get(COMPONENT_NAME).textValue();
+	}
+
+	private static Integer getVersion(JsonNode json) {
+		JsonNode node = json.get(COMPONENT_VERSION);
+		if (node == null || !node.isInt())
+			return null;
+		return node.intValue();
+	}
+
+	private ActivityPortsDefinitionBean getPortsDefinition(WorkflowBundle w) {
+		ActivityPortsDefinitionBean result = new ActivityPortsDefinitionBean();
+		List<ActivityInputPortDefinitionBean> inputs = result
+				.getInputPortDefinitions();
+		List<ActivityOutputPortDefinitionBean> outputs = result
+				.getOutputPortDefinitions();
+
+		for (InputWorkflowPort iwp : w.getMainWorkflow().getInputPorts())
+			inputs.add(makeInputDefinition(iwp));
+		// FIXME: Get the ValidatorState (so we can get getPortResolvedDepth()
+		ValidatorState vs =  ... ;
+		for (OutputWorkflowPort owp : w.getMainWorkflow().getOutputPorts())
+			outputs.add(makeOutputDefinition(vs.getPortResolvedDepth(owp), owp.getName()));
+
+		try {
+			eh = util.getFamily(getRegistryBase(), getFamilyName())
+					.getComponentProfile().getExceptionHandling();
+			if (eh != null)
+				outputs.add(makeOutputDefinition(1, ERROR_CHANNEL));
+		} catch (io.github.taverna_extras.component.api.ComponentException e) {
+			logger.error("failed to get exception handling for family", e);
+		}
+		return result;
+	}
+
+	private ActivityInputPortDefinitionBean makeInputDefinition(
+			InputWorkflowPort dip) {
+		ActivityInputPortDefinitionBean activityInputPortDefinitionBean = new ActivityInputPortDefinitionBean();
+		activityInputPortDefinitionBean.setHandledReferenceSchemes(null);
+		activityInputPortDefinitionBean.setMimeTypes((List<String>) null);
+		activityInputPortDefinitionBean.setTranslatedElementType(String.class);
+		activityInputPortDefinitionBean.setAllowsLiteralValues(true);
+		activityInputPortDefinitionBean.setDepth(dip.getDepth());
+		activityInputPortDefinitionBean.setName(dip.getName());
+		return activityInputPortDefinitionBean;
+	}
+
+	private ActivityOutputPortDefinitionBean makeOutputDefinition(int depth,
+			String name) {
+		ActivityOutputPortDefinitionBean activityOutputPortDefinitionBean = new ActivityOutputPortDefinitionBean();
+		activityOutputPortDefinitionBean.setMimeTypes(new ArrayList<String>());
+		activityOutputPortDefinitionBean.setDepth(depth);
+		activityOutputPortDefinitionBean.setGranularDepth(depth);
+		activityOutputPortDefinitionBean.setName(name);
+		return activityOutputPortDefinitionBean;
+	}
+
+	/**
+	 * @return the ports
+	 */
+	public ActivityPortsDefinitionBean getPorts() throws io.github.taverna_extras.component.api.ComponentException{
+		if (ports == null)
+			ports = getPortsDefinition(cache.getImplementation(this));
+		return ports;
+	}
+
+	public ExceptionHandling getExceptionHandling() {
+		return eh;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityFactory.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityFactory.java b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityFactory.java
new file mode 100644
index 0000000..c90ea1a
--- /dev/null
+++ b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityFactory.java
@@ -0,0 +1,142 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+
+import io.github.taverna_extras.component.api.ComponentException;
+import io.github.taverna_extras.component.api.Version.ID;
+import io.github.taverna_extras.component.registry.ComponentImplementationCache;
+import io.github.taverna_extras.component.registry.ComponentUtil;
+import io.github.taverna_extras.component.utils.AnnotationUtils;
+import io.github.taverna_extras.component.utils.SystemUtils;
+import org.springframework.beans.factory.annotation.Required;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.taverna.workflowmodel.Edits;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityConfigurationException;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityFactory;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityInputPort;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityOutputPort;
+import org.apache.taverna.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean;
+import org.apache.taverna.workflowmodel.processor.activity.config.ActivityOutputPortDefinitionBean;
+
+public class ComponentActivityFactory extends ComponentExceptionFactory
+		implements ActivityFactory {
+	private ComponentUtil util;
+	private ComponentImplementationCache cache;
+	private Edits edits;
+	private SystemUtils system;
+	private AnnotationUtils annUtils;
+
+	@Override
+	public ComponentActivity createActivity() {
+		return new ComponentActivity(util, cache, edits, system, annUtils, this);
+	}
+
+	@Override
+	public URI getActivityType() {
+		return URI.create(ComponentActivity.URI);
+	}
+
+	@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)
+			throws ActivityConfigurationException {
+		try {
+			Set<ActivityInputPort> activityInputPorts = new HashSet<>();
+			for (ActivityInputPortDefinitionBean ipd : createConfiguration(
+					configuration).getPorts().getInputPortDefinitions())
+				activityInputPorts.add(edits.createActivityInputPort(
+						ipd.getName(), ipd.getDepth(), true, null,
+						ipd.getTranslatedElementType()));
+			return activityInputPorts;
+		} catch (MalformedURLException | ComponentException | RuntimeException e) {
+			throw new ActivityConfigurationException(
+					"failed to get implementation for configuration of inputs",
+					e);
+		}
+	}
+
+	@Override
+	public Set<ActivityOutputPort> getOutputPorts(JsonNode configuration)
+			throws ActivityConfigurationException {
+		try {
+			Set<ActivityOutputPort> activityOutputPorts = new HashSet<>();
+			for (ActivityOutputPortDefinitionBean opd : createConfiguration(
+					configuration).getPorts().getOutputPortDefinitions())
+				activityOutputPorts.add(edits.createActivityOutputPort(
+						opd.getName(), opd.getDepth(), opd.getGranularDepth()));
+			return activityOutputPorts;
+		} catch (MalformedURLException | ComponentException | RuntimeException e) {
+			throw new ActivityConfigurationException(
+					"failed to get implementation for configuration of outputs",
+					e);
+		}
+	}
+
+	public ComponentActivityConfigurationBean createConfiguration(ID id) {
+		return new ComponentActivityConfigurationBean(id, util, cache);
+	}
+
+	public ComponentActivityConfigurationBean createConfiguration(JsonNode json)
+			throws MalformedURLException {
+		return new ComponentActivityConfigurationBean(json, util, cache);
+	}
+
+	@Required
+	public void setComponentUtil(ComponentUtil util) {
+		this.util = util;
+	}
+
+	@Required
+	public void setDataflowCache(ComponentImplementationCache cache) {
+		this.cache = cache;
+	}
+
+	@Required
+	public void setEdits(Edits edits) {
+		this.edits = edits;
+	}
+
+	@Required
+	public void setSystemUtil(SystemUtils system) {
+		this.system = system;
+	}
+
+	@Required
+	public void setAnnotationUtils(AnnotationUtils annUtils) {
+		this.annUtils = annUtils;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityLocalChecker.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityLocalChecker.java b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityLocalChecker.java
new file mode 100644
index 0000000..d874241
--- /dev/null
+++ b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityLocalChecker.java
@@ -0,0 +1,69 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static io.github.taverna_extras.component.activity.ComponentHealthCheck.NON_SHAREABLE;
+
+import java.util.List;
+import org.apache.taverna.visit.VisitKind;
+import org.apache.taverna.visit.VisitReport;
+import static org.apache.taverna.visit.VisitReport.Status.WARNING;
+import org.apache.taverna.workflowmodel.health.HealthChecker;
+
+/**
+ * Component health checker
+ * 
+ */
+public class ComponentActivityLocalChecker implements
+		HealthChecker<ComponentActivity> {
+	private static final VisitKind visitKind = ComponentHealthCheck
+			.getInstance();
+
+	@Override
+	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 ComponentActivity where a certain configuration option is
+		 * enabled.
+		 */
+		return o instanceof ComponentActivity;
+	}
+
+	@Override
+	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;
+	}
+
+	@Override
+	public VisitReport visit(ComponentActivity activity, List<Object> ancestry) {
+		if (!activity.getConfigBean().getRegistryBase().getProtocol()
+				.startsWith("http"))
+			return new VisitReport(visitKind, activity,
+					"Local component makes workflow non-shareable",
+					NON_SHAREABLE, WARNING);
+		return null;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityUpgradeChecker.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityUpgradeChecker.java b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityUpgradeChecker.java
new file mode 100644
index 0000000..4d45b60
--- /dev/null
+++ b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityUpgradeChecker.java
@@ -0,0 +1,83 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.apache.log4j.Logger.getLogger;
+import static io.github.taverna_extras.component.activity.ComponentHealthCheck.OUT_OF_DATE;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import io.github.taverna_extras.component.api.ComponentException;
+import io.github.taverna_extras.component.registry.ComponentUtil;
+import org.apache.taverna.visit.VisitKind;
+import org.apache.taverna.visit.VisitReport;
+import static org.apache.taverna.visit.VisitReport.Status.WARNING;
+import org.apache.taverna.workflowmodel.health.HealthChecker;
+import org.springframework.beans.factory.annotation.Required;
+
+/**
+ * @author alanrw
+ * 
+ */
+public class ComponentActivityUpgradeChecker implements
+		HealthChecker<ComponentActivity> {
+	private static final String OUTDATED_MSG = "Component out of date";
+	private static final VisitKind visitKind = ComponentHealthCheck
+			.getInstance();
+	private static Logger logger = getLogger(ComponentActivityUpgradeChecker.class);
+	private ComponentUtil utils;
+
+	@Required
+	public void setComponentUtil(ComponentUtil util) {
+		this.utils = util;
+	}
+
+	@Override
+	public boolean canVisit(Object o) {
+		return o instanceof ComponentActivity;
+	}
+
+	@Override
+	public boolean isTimeConsuming() {
+		return false;
+	}
+
+	@Override
+	public VisitReport visit(ComponentActivity activity, List<Object> ancestry) {
+		ComponentActivityConfigurationBean config = activity.getConfigBean();
+		int versionNumber = config.getComponentVersion();
+		int latestVersion = 0;
+
+		try {
+			latestVersion = utils
+					.getComponent(config.getRegistryBase(),
+							config.getFamilyName(), config.getComponentName())
+					.getComponentVersionMap().lastKey();
+		} catch (ComponentException e) {
+			logger.error("failed to get component description", e);
+		}
+
+		if (latestVersion > versionNumber)
+			return new VisitReport(visitKind, activity, OUTDATED_MSG,
+					OUT_OF_DATE, WARNING);
+		return null;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentExceptionFactory.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentExceptionFactory.java b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentExceptionFactory.java
new file mode 100644
index 0000000..243fe84
--- /dev/null
+++ b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentExceptionFactory.java
@@ -0,0 +1,38 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+class ComponentExceptionFactory {
+	private static final String UNEXPECTED_ID = "http://ns.taverna.org.uk/2012/component/unexpected";
+
+	ComponentExceptionFactory() {
+	}
+
+	public ComponentImplementationException createComponentException(
+			String exceptionId, String message) {
+		ComponentImplementationException result = new ComponentImplementationException(message);
+		result.setExceptionId(exceptionId);
+		return result;
+	}
+
+	public ComponentImplementationException createUnexpectedComponentException(
+			String message) {
+		return createComponentException(UNEXPECTED_ID, message);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentHealthCheck.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentHealthCheck.java b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentHealthCheck.java
new file mode 100644
index 0000000..0381de1
--- /dev/null
+++ b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentHealthCheck.java
@@ -0,0 +1,42 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.taverna.visit.VisitKind;
+import org.apache.taverna.visit.Visitor;
+
+public class ComponentHealthCheck extends VisitKind {
+	public static final int NO_PROBLEM = 0;
+	public static final int OUT_OF_DATE = 10;
+	public static final int NON_SHAREABLE = 20;
+	public static final int FAILS_PROFILE = 30;
+
+	@Override
+	public Class<? extends Visitor<?>> getVisitorClass() {
+		return ComponentActivityUpgradeChecker.class;
+	}
+
+	private static class Singleton {
+		private static ComponentHealthCheck instance = new ComponentHealthCheck();
+	}
+
+	public static ComponentHealthCheck getInstance() {
+		return Singleton.instance;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentImplementationException.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentImplementationException.java b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentImplementationException.java
new file mode 100644
index 0000000..7ef77f7
--- /dev/null
+++ b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentImplementationException.java
@@ -0,0 +1,37 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class ComponentImplementationException extends Exception {
+	public ComponentImplementationException(String string) {
+		super(string);
+		this.setStackTrace(new StackTraceElement[] {});
+	}
+
+	private static final long serialVersionUID = -3844030382222698090L;
+	private String exceptionId;
+
+	public void setExceptionId(String exceptionId) {
+		this.exceptionId = exceptionId;
+	}
+
+	public String getExceptionId() {
+		return exceptionId;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ProxyCallback.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ProxyCallback.java b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ProxyCallback.java
new file mode 100644
index 0000000..3a04af3
--- /dev/null
+++ b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ProxyCallback.java
@@ -0,0 +1,264 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.apache.log4j.Logger.getLogger;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.xml.ws.Holder;
+
+import org.apache.log4j.Logger;
+import io.github.taverna_extras.component.api.profile.ExceptionHandling;
+import io.github.taverna_extras.component.api.profile.ExceptionReplacement;
+import io.github.taverna_extras.component.api.profile.HandleException;
+import org.apache.taverna.invocation.InvocationContext;
+import org.apache.taverna.reference.ErrorDocument;
+import org.apache.taverna.reference.ErrorDocumentService;
+import org.apache.taverna.reference.IdentifiedList;
+import org.apache.taverna.reference.ListService;
+import org.apache.taverna.reference.ReferenceService;
+import org.apache.taverna.reference.T2Reference;
+import static org.apache.taverna.reference.T2ReferenceType.ErrorDocument;
+import static org.apache.taverna.reference.T2ReferenceType.IdentifiedList;
+import static org.apache.taverna.reference.T2ReferenceType.ReferenceSet;
+import org.apache.taverna.workflowmodel.processor.activity.AsynchronousActivityCallback;
+import org.apache.taverna.workflowmodel.processor.dispatch.events.DispatchErrorType;
+
+/**
+ * @author alanrw
+ * 
+ */
+public class ProxyCallback implements AsynchronousActivityCallback {
+	private static final Logger logger = getLogger(ProxyCallback.class);
+
+	private final ComponentExceptionFactory cef;
+	private final AsynchronousActivityCallback proxiedCallback;
+	private final ReferenceService references;
+	private final InvocationContext context;
+	private final ExceptionHandling exceptionHandling;
+	private final ListService lists;
+	private final ErrorDocumentService errors;
+
+	/**
+	 * @param proxiedCallback
+	 * @param invocationContext
+	 * @param exceptionHandling
+	 * @param exnFactory
+	 */
+	ProxyCallback(AsynchronousActivityCallback proxiedCallback,
+			InvocationContext invocationContext,
+			ExceptionHandling exceptionHandling,
+			ComponentExceptionFactory exnFactory) {
+		this.proxiedCallback = proxiedCallback;
+		this.exceptionHandling = exceptionHandling;
+		context = invocationContext;
+		references = context.getReferenceService();
+		lists = references.getListService();
+		errors = references.getErrorDocumentService();
+		cef = exnFactory;
+	}
+
+	@Override
+	public InvocationContext getContext() {
+		return context;
+	}
+
+	@Override
+	public void requestRun(Runnable runMe) {
+		proxiedCallback.requestRun(runMe);
+	}
+
+	@Override
+	public void receiveResult(Map<String, T2Reference> data, int[] index) {
+		if (exceptionHandling == null) {
+			proxiedCallback.receiveResult(data, index);
+			return;
+		}
+
+		List<T2Reference> exceptions = new ArrayList<>();
+		Map<String, T2Reference> replacement = new HashMap<>();
+		for (Entry<String, T2Reference> entry : data.entrySet())
+			replacement.put(entry.getKey(),
+					considerReference(entry.getValue(), exceptions));
+		replacement.put("error_channel",
+				references.register(exceptions, 1, true, context));
+		proxiedCallback.receiveResult(replacement, index);
+	}
+
+	private T2Reference considerReference(T2Reference value,
+			List<T2Reference> exceptions) {
+		if (!value.containsErrors())
+			return value;
+		else if (!value.getReferenceType().equals(IdentifiedList))
+			return replaceErrors(value, value.getDepth(), exceptions);
+		else if (exceptionHandling.failLists())
+			return replaceErrors(findFirstFailure(value), value.getDepth(),
+					exceptions);
+
+		List<T2Reference> replacementList = new ArrayList<>();
+		for (T2Reference subValue : lists.getList(value))
+			replacementList.add(considerReference(subValue, exceptions));
+		return references.register(replacementList, value.getDepth(), true,
+				context);
+	}
+
+	private T2Reference findFirstFailure(T2Reference value) {
+		IdentifiedList<T2Reference> originalList = lists.getList(value);
+		for (T2Reference subValue : originalList) {
+			if (subValue.getReferenceType().equals(ErrorDocument))
+				return subValue;
+			if (subValue.getReferenceType().equals(IdentifiedList))
+				if (subValue.containsErrors())
+					return findFirstFailure(subValue);
+			// No need to consider value
+		}
+		return null;
+	}
+
+	private T2Reference replaceErrors(T2Reference value, int depth,
+			List<T2Reference> exceptions) {
+		ErrorDocument doc = errors.getError(value);
+
+		Holder<HandleException> handleException = new Holder<>();
+		Set<ErrorDocument> toConsider = new HashSet<>();
+		Set<ErrorDocument> considered = new HashSet<>();
+		toConsider.add(doc);
+
+		while (!toConsider.isEmpty())
+			try {
+				ErrorDocument nudoc = remapException(toConsider, considered,
+						handleException);
+				if (nudoc != null) {
+					doc = nudoc;
+					break;
+				}
+			} catch (Exception e) {
+				logger.error("failed to locate exception mapping", e);
+			}
+
+		String exceptionMessage = doc.getExceptionMessage();
+		// An exception that is not mentioned
+		if (handleException.value == null) {
+			ComponentImplementationException newException = cef
+					.createUnexpectedComponentException(exceptionMessage);
+			T2Reference replacement = errors.registerError(exceptionMessage,
+					newException, depth, context).getId();
+			exceptions.add(errors.registerError(exceptionMessage, newException,
+					0, context).getId());
+			return replacement;
+		}
+
+		if (handleException.value.pruneStack())
+			doc.getStackTraceStrings().clear();
+
+		ExceptionReplacement exnReplacement = handleException.value
+				.getReplacement();
+		if (exnReplacement == null) {
+			T2Reference replacement = references.register(doc, depth, true,
+					context);
+			exceptions.add(references.register(doc, 0, true, context));
+			return replacement;
+		}
+
+		ComponentImplementationException newException = cef
+				.createComponentException(exnReplacement.getReplacementId(),
+						exnReplacement.getReplacementMessage());
+		T2Reference replacement = errors.registerError(
+				exnReplacement.getReplacementMessage(), newException, depth,
+				context).getId();
+		exceptions.add(errors.registerError(
+				exnReplacement.getReplacementMessage(), newException, 0,
+				context).getId());
+		return replacement;
+	}
+
+	private ErrorDocument remapException(Set<ErrorDocument> toConsider,
+			Set<ErrorDocument> considered,
+			Holder<HandleException> handleException) {
+		ErrorDocument found = null;
+		ErrorDocument errorDoc = toConsider.iterator().next();
+
+		considered.add(errorDoc);
+		toConsider.remove(errorDoc);
+		String exceptionMessage = errorDoc.getExceptionMessage();
+		for (HandleException he : exceptionHandling.getHandleExceptions()) {
+			if (!he.matches(exceptionMessage))
+				continue;
+			handleException.value = he;
+			found = errorDoc;
+		}
+		if (!errorDoc.getErrorReferences().isEmpty())
+			for (T2Reference subRef : errorDoc.getErrorReferences())
+				for (T2Reference newErrorRef : getErrors(subRef)) {
+					ErrorDocument subDoc = errors.getError(newErrorRef);
+					if (subDoc == null)
+						logger.error("Error document contains references to non-existent sub-errors");
+					else if (!considered.contains(subDoc))
+						toConsider.add(subDoc);
+				}
+		return found;
+	}
+
+	private Set<T2Reference> getErrors(T2Reference ref) {
+		Set<T2Reference> result = new HashSet<>();
+		if (ref.getReferenceType().equals(ReferenceSet)) {
+			// nothing
+		} else if (ref.getReferenceType().equals(IdentifiedList)) {
+			IdentifiedList<T2Reference> originalList = lists.getList(ref);
+			for (T2Reference subValue : originalList)
+				if (subValue.containsErrors())
+					result.addAll(getErrors(subValue));
+		} else
+			result.add(ref);
+		return result;
+	}
+
+	@Override
+	public void receiveCompletion(int[] completionIndex) {
+		proxiedCallback.receiveCompletion(completionIndex);
+	}
+
+	@Override
+	public void fail(String message, Throwable t, DispatchErrorType errorType) {
+		proxiedCallback.fail(message, t, errorType);
+	}
+
+	@Override
+	public void fail(String message, Throwable t) {
+		proxiedCallback.fail(message, t);
+	}
+
+	@Override
+	public void fail(String message) {
+		proxiedCallback.fail(message);
+	}
+
+	@Override
+	public String getParentProcessIdentifier() {
+		// return "";
+		return proxiedCallback.getParentProcessIdentifier();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/package-info.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/package-info.java b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/package-info.java
new file mode 100644
index 0000000..086a49b
--- /dev/null
+++ b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package io.github.taverna_extras.component.activity;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/profile/ActivityProfileImpl.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/profile/ActivityProfileImpl.java b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/profile/ActivityProfileImpl.java
new file mode 100644
index 0000000..a948cd4
--- /dev/null
+++ b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/profile/ActivityProfileImpl.java
@@ -0,0 +1,53 @@
+package io.github.taverna_extras.component.profile;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import io.github.taverna_extras.component.api.profile.ActivityProfile;
+import io.github.taverna_extras.component.api.profile.SemanticAnnotationProfile;
+
+import io.github.taverna_extras.component.api.profile.doc.Activity;
+import io.github.taverna_extras.component.api.profile.doc.SemanticAnnotation;
+
+/**
+ * Specifies the semantic annotations that an activity must have.
+ * 
+ * @author David Withers
+ */
+public class ActivityProfileImpl implements ActivityProfile {
+	private final ComponentProfileImpl componentProfile;
+	private final Activity activity;
+
+	public ActivityProfileImpl(ComponentProfileImpl componentProfile,
+			Activity activity) {
+		this.componentProfile = componentProfile;
+		this.activity = activity;
+	}
+
+	@Override
+	public List<SemanticAnnotationProfile> getSemanticAnnotations() {
+		List<SemanticAnnotationProfile> saProfiles = new ArrayList<>();
+		for (SemanticAnnotation annotation : activity.getSemanticAnnotation())
+			saProfiles.add(new SemanticAnnotationProfileImpl(componentProfile,
+					annotation));
+		return saProfiles;
+	}
+}