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/03/20 15:22:59 UTC
[45/51] [abbrv] [partial] incubator-taverna-workbench git commit:
taverna-workbench-* -> taverna-*
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ActivityConfigurationPanel.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ActivityConfigurationPanel.java b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ActivityConfigurationPanel.java
new file mode 100644
index 0000000..cf7f42a
--- /dev/null
+++ b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ActivityConfigurationPanel.java
@@ -0,0 +1,214 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.activity;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.JPanel;
+
+import org.apache.log4j.Logger;
+
+import uk.org.taverna.commons.services.ActivityTypeNotFoundException;
+import uk.org.taverna.commons.services.InvalidConfigurationException;
+import uk.org.taverna.commons.services.ServiceRegistry;
+import uk.org.taverna.scufl2.api.activity.Activity;
+import uk.org.taverna.scufl2.api.common.Scufl2Tools;
+import uk.org.taverna.scufl2.api.configurations.Configuration;
+import uk.org.taverna.scufl2.api.port.ActivityPort;
+import uk.org.taverna.scufl2.api.port.InputActivityPort;
+import uk.org.taverna.scufl2.api.port.OutputActivityPort;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * @author alanrw
+ */
+@SuppressWarnings("serial")
+public abstract class ActivityConfigurationPanel extends JPanel {
+ private static final Logger logger = Logger.getLogger(ActivityConfigurationPanel.class);
+ private final static Scufl2Tools scufl2Tools = new Scufl2Tools();
+
+ // protected final URITools uriTools = new URITools();
+ private final Activity activity;
+ private final Configuration configuration;
+ private final List<ActivityPortConfiguration> inputPorts;
+ private final List<ActivityPortConfiguration> outputPorts;
+ protected ObjectNode json;
+
+ public ActivityConfigurationPanel(Activity activity) {
+ this(activity, scufl2Tools.configurationFor(activity,
+ activity.getParent()));
+ }
+
+ public ActivityConfigurationPanel(Activity activity,
+ Configuration configuration) {
+ this.activity = activity;
+ this.configuration = configuration;
+ inputPorts = new ArrayList<>();
+ outputPorts = new ArrayList<>();
+ }
+
+ /**
+ * Initializes the configuration panel. This method is also used to discard
+ * any changes and reset the panel to its initial state. Subclasses should
+ * implement this method to set up the panel and must call
+ * <tt>super.initialise()</tt> first.
+ */
+ protected void initialise() {
+ json = configuration.getJson().deepCopy();
+ inputPorts.clear();
+ for (InputActivityPort activityPort : activity.getInputPorts())
+ inputPorts.add(new ActivityPortConfiguration(activityPort));
+ outputPorts.clear();
+ for (OutputActivityPort activityPort : activity.getOutputPorts())
+ outputPorts.add(new ActivityPortConfiguration(activityPort));
+ }
+
+ public abstract boolean checkValues();
+
+ public abstract void noteConfiguration();
+
+ public boolean isConfigurationChanged() {
+ noteConfiguration();
+ if (portsChanged(inputPorts, activity.getInputPorts().size()))
+ return true;
+ if (portsChanged(outputPorts, activity.getOutputPorts().size()))
+ return true;
+ return !json.equals(configuration.getJson());
+ }
+
+ public Configuration getConfiguration() {
+ return configuration;
+ }
+
+ public ObjectNode getJson() {
+ return json;
+ }
+
+ protected void setJson(ObjectNode json) {
+ this.json = json;
+ }
+
+ public void refreshConfiguration() {
+ initialise();
+ }
+
+ public void whenOpened() {
+ }
+
+ public void whenClosed() {
+ }
+
+ /**
+ * Convenience method for getting simple String property values.
+ *
+ * @param name
+ * the property name
+ * @return the property value
+ */
+ protected String getProperty(String name) {
+ JsonNode jsonNode = json.get(name);
+ if (jsonNode == null)
+ return null;
+ return json.get(name).asText();
+ }
+
+ /**
+ * Convenience method for setting simple String property values.
+ *
+ * @param name
+ * the property name
+ * @param value
+ * the property value
+ */
+ protected void setProperty(String name, String value) {
+ json.put(name, value);
+ }
+
+ public List<ActivityPortConfiguration> getInputPorts() {
+ return inputPorts;
+ }
+
+ public List<ActivityPortConfiguration> getOutputPorts() {
+ return outputPorts;
+ }
+
+ protected void configureInputPorts(ServiceRegistry serviceRegistry) {
+ try {
+ Map<String, InputActivityPort> newInputPorts = new HashMap<>();
+ for (InputActivityPort port : serviceRegistry
+ .getActivityInputPorts(getActivity().getType(), getJson()))
+ newInputPorts.put(port.getName(), port);
+ List<ActivityPortConfiguration> inputPorts = getInputPorts();
+ for (ActivityPortConfiguration portConfig : new ArrayList<>(
+ inputPorts))
+ if (newInputPorts.containsKey(portConfig.getName())) {
+ InputActivityPort port = newInputPorts.remove(portConfig
+ .getName());
+ portConfig.setDepth(port.getDepth());
+ } else
+ inputPorts.remove(portConfig);
+ for (InputActivityPort newPort : newInputPorts.values())
+ inputPorts.add(new ActivityPortConfiguration(newPort.getName(),
+ newPort.getDepth()));
+ } catch (InvalidConfigurationException | ActivityTypeNotFoundException e) {
+ logger.warn("Error configuring input ports", e);
+ }
+ }
+
+ protected void configureOutputPorts(ServiceRegistry serviceRegistry) {
+ try {
+ Map<String, OutputActivityPort> newOutputPorts = new HashMap<>();
+ for (OutputActivityPort port : serviceRegistry
+ .getActivityOutputPorts(getActivity().getType(), getJson()))
+ newOutputPorts.put(port.getName(), port);
+ List<ActivityPortConfiguration> outputPorts = getOutputPorts();
+ for (ActivityPortConfiguration portConfig : new ArrayList<>(
+ outputPorts))
+ if (newOutputPorts.containsKey(portConfig.getName())) {
+ OutputActivityPort port = newOutputPorts.remove(portConfig
+ .getName());
+ portConfig.setDepth(port.getDepth());
+ portConfig.setGranularDepth(port.getGranularDepth());
+ } else
+ outputPorts.remove(portConfig);
+ for (OutputActivityPort newPort : newOutputPorts.values())
+ outputPorts.add(new ActivityPortConfiguration(
+ newPort.getName(), newPort.getDepth()));
+ } catch (InvalidConfigurationException | ActivityTypeNotFoundException e) {
+ logger.warn("Error configuring output ports", e);
+ }
+ }
+
+ private boolean portsChanged(List<ActivityPortConfiguration> portDefinitions, int ports) {
+ int checkedPorts = 0;
+ for (ActivityPortConfiguration portDefinition : portDefinitions) {
+ String portName = portDefinition.getName();
+ int portDepth = portDefinition.getDepth();
+ ActivityPort activityPort = portDefinition.getActivityPort();
+ if (activityPort == null)
+ // new port added
+ return true;
+ if (!activityPort.getName().equals(portName))
+ // port name changed
+ return true;
+ if (!activityPort.getDepth().equals(portDepth))
+ // port depth changed
+ return true;
+ checkedPorts++;
+ }
+ if (checkedPorts < ports)
+ // ports deleted
+ return true;
+ return false;
+ }
+
+ public Activity getActivity() {
+ return activity;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ActivityPortConfiguration.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ActivityPortConfiguration.java b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ActivityPortConfiguration.java
new file mode 100644
index 0000000..6b23fd5
--- /dev/null
+++ b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ActivityPortConfiguration.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (C) 2013 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.activity;
+
+import uk.org.taverna.scufl2.api.port.ActivityPort;
+
+/**
+ *
+ *
+ * @author David Withers
+ */
+public class ActivityPortConfiguration {
+
+ private ActivityPort activityPort;
+
+ private String name;
+
+ private int depth;
+
+ private int granularDepth;
+
+ public ActivityPortConfiguration(ActivityPort activityPort) {
+ this.activityPort = activityPort;
+ name = activityPort.getName();
+ depth = activityPort.getDepth();
+ }
+
+ public ActivityPortConfiguration(String name, int depth) {
+ this(name, depth, depth);
+ }
+
+ public ActivityPortConfiguration(String name, int depth, int granularDepth) {
+ this.name = name;
+ this.depth = depth;
+ this.granularDepth = granularDepth;
+ }
+
+ public ActivityPort getActivityPort() {
+ return activityPort;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getDepth() {
+ return depth;
+ }
+
+ public void setDepth(int depth) {
+ this.depth = depth;
+ }
+
+ public int getGranularDepth() {
+ return granularDepth;
+ }
+
+ public void setGranularDepth(int granularDepth) {
+ this.granularDepth = granularDepth;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ContextualViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ContextualViewFactory.java b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ContextualViewFactory.java
new file mode 100644
index 0000000..b5d29d7
--- /dev/null
+++ b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ContextualViewFactory.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.activity;
+
+import java.util.List;
+
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+
+/**
+ * Defines a factory class that when associated with a selected object creates a
+ * {@link ContextualView} for that selection.
+ * <p>
+ * This factory acts as an SPI to find {@link ContextualView}s for a given
+ * Activity and other workflow components.
+ * </p>
+ *
+ * @author Stuart Owen
+ * @author Ian Dunlop
+ * @author Stian Soiland-Reyes
+ *
+ *
+ * @param <SelectionType>
+ * - the selection type this factory is associated with
+ *
+ * @see ContextualView
+ * @see ContextualViewFactoryRegistry
+ */
+public interface ContextualViewFactory<SelectionType> {
+ /**
+ * @param selection
+ * - the object for which ContextualViews needs to be generated
+ * @return instance of {@link ContextualView}
+ */
+ public List<ContextualView> getViews(SelectionType selection);
+
+ /**
+ * Used by the SPI system to find the correct factory that can handle the
+ * given object type.
+ *
+ * @param selection
+ * @return true if this factory relates to the given selection type
+ * @see ContextualViewFactoryRegistry
+ */
+ public boolean canHandle(Object selection);
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ContextualViewFactoryRegistry.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ContextualViewFactoryRegistry.java b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ContextualViewFactoryRegistry.java
new file mode 100644
index 0000000..305f3c0
--- /dev/null
+++ b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ContextualViewFactoryRegistry.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.activity;
+
+import java.util.List;
+
+/**
+ * A registry for discovering ActivityViewFactories for a given object,
+ * like an {@link net.sf.taverna.t2.workflowmodel.processor.activity.Activity}.
+ *
+ * @author David Withers
+ */
+public interface ContextualViewFactoryRegistry {
+ /**
+ * Discover and return the ContextualViewFactory associated to the provided
+ * object. This is accomplished by returning the discovered
+ * {@link ContextualViewFactory#canHandle(Object)} that returns true for
+ * that Object.
+ *
+ * @param object
+ * @return
+ * @see ContextualViewFactory#canHandle(Object)
+ */
+ public <T> List<ContextualViewFactory<? super T>> getViewFactoriesForObject(T object);
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/DependencyConfigurationPanel.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/DependencyConfigurationPanel.java b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/DependencyConfigurationPanel.java
new file mode 100644
index 0000000..c28cb55
--- /dev/null
+++ b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/DependencyConfigurationPanel.java
@@ -0,0 +1,293 @@
+/*******************************************************************************
+ * Copyright (C) 2013 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.activity;
+
+import static java.awt.BorderLayout.CENTER;
+import static java.awt.BorderLayout.NORTH;
+import static java.awt.Color.RED;
+import static java.awt.GridBagConstraints.FIRST_LINE_START;
+import static java.awt.GridBagConstraints.HORIZONTAL;
+import static java.awt.event.ItemEvent.DESELECTED;
+import static java.awt.event.ItemEvent.SELECTED;
+import static java.util.Arrays.asList;
+import static javax.swing.Box.createRigidArea;
+import static javax.swing.BoxLayout.PAGE_AXIS;
+import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER;
+import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.BoxLayout;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.border.EmptyBorder;
+
+/**
+ * Component for configuring activities that require dependencies.
+ *
+ * @author David Withers
+ */
+@SuppressWarnings("serial")
+public class DependencyConfigurationPanel extends JPanel {
+ private String classLoaderSharing;
+ private List<String> localDependencies;
+ private File libDir;
+
+ public DependencyConfigurationPanel(String classLoaderSharing,
+ List<String> localDependencies, File libDir) {
+ this.classLoaderSharing = classLoaderSharing;
+ this.localDependencies = localDependencies;
+ this.libDir = libDir;
+ setLayout(new BoxLayout(this, PAGE_AXIS));
+
+ // Create panel with classloading options
+ JPanel classloadingPanel = new ClassloadingPanel();
+ // Create panel for selecting jar files
+ JPanel jarFilesPanel = new JarFilesPanel();
+
+ add(classloadingPanel);
+ add(createRigidArea(new Dimension(0,10)));
+ add(jarFilesPanel);
+ add(createRigidArea(new Dimension(0,10)));
+
+ }
+
+ public String getClassLoaderSharing() {
+ return classLoaderSharing;
+ }
+
+ public List<String> getLocalDependencies() {
+ return localDependencies;
+ }
+
+ // Classloading option 'workflow'
+ private static final String WORKFLOW = "Shared for whole workflow";
+ // Classloading option 'system'
+ private static final String SYSTEM = "System classloader";
+
+ // Panel containing classloading options
+ private class ClassloadingPanel extends JPanel {
+ // Combobox with classloading options
+ private JComboBox<String> jcbClassloadingOption;
+ // Classloading option descriptions
+ private HashMap<String, String> classloadingDescriptions;
+ // JLabel with classloading option description
+ private JLabel jlClassloadingDescription;
+
+ /*
+ * Panel containing a list of possible classloading options which users
+ * can select from
+ */
+ private ClassloadingPanel() {
+ super(new GridBagLayout());
+ jcbClassloadingOption = new JComboBox<>(new String[] { WORKFLOW,
+ SYSTEM });
+ // Set the current classlaoding option based on the configuration bean
+ if ("workflow".equals(classLoaderSharing)) {
+ jcbClassloadingOption.setSelectedItem(WORKFLOW);
+ } else if ("system".equals(classLoaderSharing)) {
+ jcbClassloadingOption.setSelectedItem(SYSTEM);
+ }
+
+ jcbClassloadingOption.addActionListener(new ActionListener(){
+ // Fires up when combobox selection changes
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Object selectedItem = jcbClassloadingOption.getSelectedItem();
+ jlClassloadingDescription.setText(classloadingDescriptions
+ .get(selectedItem));
+ if (selectedItem.equals(WORKFLOW))
+ classLoaderSharing = "workflow";
+ else if (selectedItem.equals(SYSTEM))
+ classLoaderSharing = "system";
+ }
+ });
+ //jcbClassloadingOption.setEnabled(false);
+
+ classloadingDescriptions = new HashMap<>();
+ classloadingDescriptions.put(WORKFLOW, "<html><small>"
+ + "Classes are shared across the whole workflow (with any service<br>"
+ + "also selecting this option), but are reinitialised for each workflow run.<br>"
+ + "This might be needed if a service passes objects to another, or <br>"
+ + "state is shared within static members of loaded classes."
+ + "</small></html>");
+ classloadingDescriptions.put(SYSTEM, "<html><small><p>"
+ + "The (global) system classloader is used, any dependencies defined here are<br>"
+ + "made available globally on the first run. Note that if you are NOT using<br>"
+ + "the defaulf Taverna BootstrapClassLoader, any settings here will be disregarded."
+ + "</p><p>"
+ + "This is mainly useful if you are using JNI-based libraries. Note that <br>"
+ + "for JNI you also have to specify <code>-Djava.library.path</code> and <br>"
+ + "probably your operating system's dynamic library search path<br>"
+ + "<code>LD_LIBRARY_PATH</code> / <code>DYLD_LIBRARY_PATH</code> / <code>PATH</code> </p>"
+ + "</small></html>");
+
+ /*
+ * Set the current classlaoding description based on the item
+ * selected in the combobox.
+ */
+ jlClassloadingDescription = new JLabel(classloadingDescriptions
+ .get(jcbClassloadingOption.getSelectedItem()));
+
+ // Add components to the ClassloadingPanel
+ GridBagConstraints c = new GridBagConstraints();
+ c.anchor = FIRST_LINE_START;
+ c.fill = HORIZONTAL;
+ c.gridx = 0;
+ c.insets = new Insets(10,0,0,0);
+ add(new JLabel("Classloader persistence"), c);
+ c.insets = new Insets(0,0,0,0);
+ add(jcbClassloadingOption, c);
+ c.insets = new Insets(0,30,0,0);
+ add(jlClassloadingDescription, c);
+ }
+ }
+
+ // Panel for users to add local JAR dependencies (contains a list of jar files which users can select from)
+ private class JarFilesPanel extends JPanel {
+ private JLabel warning = new JLabel(
+ "<html>"
+ + "<center<font color='red'>"
+ + "Warning: Depending on local libraries makes this workflow<br>"
+ + "difficult or impossible to run for other users. Try depending<br>"
+ + "on artifacts from a public repository if possible.</font></center>"
+ + "</html>");
+
+ private JarFilesPanel() {
+ super();
+ setMinimumSize(new Dimension(400, 150));
+ setLayout(new BorderLayout());
+ setBorder(new EmptyBorder(0,10,0,10));
+
+ JPanel labelPanel = new JPanel();
+ labelPanel.setLayout(new BoxLayout(labelPanel, PAGE_AXIS));
+ JLabel label = new JLabel("Local JAR files");
+ JLabel libLabel = new JLabel("<html><small>" + libDir.getAbsolutePath()
+ + "</small></html>");
+ labelPanel.add(label);
+ labelPanel.add(libLabel);
+
+ add(labelPanel, NORTH);
+ add(new JScrollPane(jarFiles(), VERTICAL_SCROLLBAR_AS_NEEDED,
+ HORIZONTAL_SCROLLBAR_NEVER), CENTER);
+
+ warning.setVisible(false);
+ /*
+ * We'll skip the warning until we actually have support for
+ * artifacts
+ */
+ //add(warning);
+ updateWarning();
+ }
+
+ private void updateWarning() {
+ // Show warning if there is any local dependencies
+ warning.setVisible(!localDependencies.isEmpty());
+ }
+
+ public JPanel jarFiles() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, PAGE_AXIS));
+
+ // List of all jar files in the lib directory
+ List<String> jarFiles = asList(libDir
+ .list(new FileExtFilter(".jar")));
+ /*
+ * We also add the list of jars that may have been configured
+ * sometime before but are now not present in the lib directory for
+ * some reason
+ */
+ Set<String> missingLocalDeps = new HashSet<>(localDependencies);
+ missingLocalDeps.removeAll(jarFiles);
+ /*
+ * jarFiles and missingLocalDeps now contain two sets of files that
+ * do not intersect
+ */
+ List<String> jarFilesList = new ArrayList<>();
+ // Put them all together
+ jarFilesList.addAll(jarFiles);
+ jarFilesList.addAll(missingLocalDeps);
+ Collections.sort(jarFilesList);
+
+ if (jarFilesList.isEmpty()) {
+ panel.add(new JLabel("<html><small>To depend on a JAR file, "
+ + "copy it to the above-mentioned folder.</small></html>"));
+ return panel;
+ }
+
+ for (String jarFile : jarFilesList) {
+ JCheckBox checkBox = new JCheckBox(jarFile);
+ // Has it already been selected in some previous configuring?
+ checkBox.setSelected(localDependencies.contains(jarFile));
+ checkBox.addItemListener(new ItemListener() {
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ JCheckBox box = (JCheckBox) e.getSource();
+ if (e.getStateChange() == SELECTED)
+ localDependencies.add(box.getText());
+ else if (e.getStateChange() == DESELECTED)
+ localDependencies.remove(box.getText());
+ updateWarning();
+ }
+ });
+ panel.add(checkBox);
+ // The jar may not be in the lib directory, so warn the user
+ if (!new File(libDir, jarFile).exists()) {
+ checkBox.setForeground(RED);
+ checkBox.setText(checkBox.getText() + " (missing file!)");
+ }
+ }
+ return panel;
+ }
+ }
+
+ public static class FileExtFilter implements FilenameFilter {
+ final String ext;
+
+ public FileExtFilter(String ext) {
+ this.ext = ext;
+ }
+
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.endsWith(ext);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ListConfigurationComponent.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ListConfigurationComponent.java b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ListConfigurationComponent.java
new file mode 100644
index 0000000..c0e3aab
--- /dev/null
+++ b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ListConfigurationComponent.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (C) 2012 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.activity;
+
+import static java.awt.BorderLayout.CENTER;
+import static java.awt.BorderLayout.EAST;
+import static java.awt.BorderLayout.SOUTH;
+import static java.awt.FlowLayout.RIGHT;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+
+/**
+ * @author David Withers
+ */
+@SuppressWarnings("serial")
+public abstract class ListConfigurationComponent<T> extends JPanel {
+ private static final String REMOVE = "Remove";
+ private static final String ADD = "Add";
+
+ private String name;
+ private List<T> items;
+ private JPanel listPanel;
+
+ public ListConfigurationComponent(String name, List<T> items) {
+ this.name = name;
+ setLayout(new BorderLayout());
+
+ listPanel = new JPanel(new ListLayout());
+ JPanel buttonPanel = new JPanel(new FlowLayout(RIGHT));
+ buttonPanel.add(new JButton(createAddAction()));
+
+ add(new JScrollPane(listPanel), CENTER);
+ add(buttonPanel, SOUTH);
+
+ setItems(items);
+ }
+
+ protected void setItems(List<T> items) {
+ this.items = items;
+ listPanel.removeAll();
+ for (T item : items)
+ addItemComponent(item);
+ }
+
+ protected void addItem(T item) {
+ items.add(item);
+ addItemComponent(item);
+ }
+
+ protected void addItemComponent(T item) {
+ JComponent itemPanel = new JPanel(new BorderLayout());
+ itemPanel.add(createItemComponent(item), CENTER);
+ itemPanel.add(new JButton(createRemoveAction(item)), EAST);
+ listPanel.add(itemPanel);
+ listPanel.revalidate();
+ listPanel.repaint();
+ }
+
+ protected void removeItem(T item) {
+ int index = items.indexOf(item);
+ if (index >= 0) {
+ items.remove(index);
+ listPanel.remove(index);
+ listPanel.revalidate();
+ listPanel.repaint();
+ }
+ }
+
+ private Action createRemoveAction(final T item) {
+ return new AbstractAction(REMOVE) {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ removeItem(item);
+ }
+ };
+ }
+
+ private Action createAddAction() {
+ return new AbstractAction(ADD + " " + name) {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ addItem(createDefaultItem());
+ }
+ };
+ }
+
+ protected abstract Component createItemComponent(T item);
+
+ protected abstract T createDefaultItem();
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ListLayout.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ListLayout.java b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ListLayout.java
new file mode 100644
index 0000000..0ce35b5
--- /dev/null
+++ b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ListLayout.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (C) 2012 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.activity;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+
+/**
+ * Lays out components vertically using their preferred height and the available
+ * width.
+ *
+ * @author David Withers
+ */
+public class ListLayout implements LayoutManager {
+ private static final int DEFAULT_GAP = 5;
+ private final int gap;
+
+ public ListLayout() {
+ this(DEFAULT_GAP);
+ }
+
+ public ListLayout(int gap) {
+ this.gap = gap;
+ }
+
+ @Override
+ public void removeLayoutComponent(Component comp) {
+ }
+
+ @Override
+ public void addLayoutComponent(String name, Component comp) {
+ }
+
+ @Override
+ public void layoutContainer(Container parent) {
+ Insets insets = parent.getInsets();
+ int x = insets.left;
+ int y = insets.top;
+ int width = parent.getWidth() - insets.left - insets.right;
+ Component[] components = parent.getComponents();
+ for (int i = 0; i < components.length; i++) {
+ components[i].setLocation(x, y);
+ components[i].setSize(width,
+ components[i].getPreferredSize().height);
+ y = y + gap + components[i].getHeight();
+ }
+ }
+
+ @Override
+ public Dimension minimumLayoutSize(Container parent) {
+ Insets insets = parent.getInsets();
+ int minimumWidth = 0;
+ int minimumHeight = 0;
+ Component[] components = parent.getComponents();
+ for (int i = 0; i < components.length; i++) {
+ Dimension size = components[i].getPreferredSize();
+ if (size.width > minimumWidth)
+ minimumWidth = size.width;
+ minimumHeight = minimumHeight + size.height + gap;
+ }
+ minimumWidth = minimumWidth + insets.left + insets.right;
+ minimumHeight = minimumHeight + insets.top + insets.bottom;
+
+ return new Dimension(minimumWidth, minimumHeight);
+ }
+
+ @Override
+ public Dimension preferredLayoutSize(Container parent) {
+ return minimumLayoutSize(parent);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/MultiPageActivityConfigurationPanel.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/MultiPageActivityConfigurationPanel.java b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/MultiPageActivityConfigurationPanel.java
new file mode 100644
index 0000000..19cd180
--- /dev/null
+++ b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/MultiPageActivityConfigurationPanel.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (C) 2012 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.activity;
+
+import static java.awt.BorderLayout.CENTER;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+
+import javax.swing.JTabbedPane;
+
+import uk.org.taverna.scufl2.api.activity.Activity;
+
+/**
+ * Component for configuring activities that have multiple configuration pages.
+ *
+ * @author David Withers
+ */
+@SuppressWarnings("serial")
+public abstract class MultiPageActivityConfigurationPanel extends
+ ActivityConfigurationPanel {
+ private JTabbedPane tabbedPane;
+
+ /**
+ * Constructs a new <code>MultiPageActivityConfigurationPanel</code>.
+ *
+ * @param activity
+ */
+ public MultiPageActivityConfigurationPanel(Activity activity) {
+ super(activity);
+ setLayout(new BorderLayout());
+ tabbedPane = new JTabbedPane();
+ add(tabbedPane, CENTER);
+ }
+
+ public void addPage(String name, Component component) {
+ tabbedPane.addTab(name, component);
+ }
+
+ public void removePage(String name) {
+ tabbedPane.removeTabAt(tabbedPane.indexOfTab(name));
+ }
+
+ public void removeAllPages() {
+ tabbedPane.removeAll();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ScriptConfigurationComponent.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ScriptConfigurationComponent.java b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ScriptConfigurationComponent.java
new file mode 100644
index 0000000..8cb7652
--- /dev/null
+++ b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ScriptConfigurationComponent.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (C) 2012 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.activity;
+
+import static java.awt.BorderLayout.CENTER;
+import static java.awt.BorderLayout.SOUTH;
+import static java.awt.Color.WHITE;
+import static java.awt.Font.PLAIN;
+import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
+import static javax.swing.JOptionPane.YES_NO_OPTION;
+import static javax.swing.JOptionPane.YES_OPTION;
+import static javax.swing.JOptionPane.showConfirmDialog;
+import static javax.swing.JOptionPane.showMessageDialog;
+import static net.sf.taverna.t2.lang.ui.FileTools.readStringFromFile;
+import static net.sf.taverna.t2.lang.ui.FileTools.saveStringToFile;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Set;
+
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JTextPane;
+
+import net.sf.taverna.t2.lang.ui.KeywordDocument;
+import net.sf.taverna.t2.lang.ui.LineEnabledTextPanel;
+import net.sf.taverna.t2.lang.ui.LinePainter;
+import net.sf.taverna.t2.lang.ui.NoWrapEditorKit;
+
+/**
+ * Component for configuring activities that have scripts.
+ *
+ * @author David Withers
+ */
+@SuppressWarnings("serial")
+public class ScriptConfigurationComponent extends JPanel {
+ private JTextPane scriptTextArea;
+
+ public ScriptConfigurationComponent(String script, Set<String> keywords,
+ Set<String> ports, final String scriptType,
+ final String fileExtension) {
+ this(script, keywords, ports, scriptType, fileExtension, "");
+ }
+
+ public ScriptConfigurationComponent(String script, Set<String> keywords,
+ Set<String> ports, final String scriptType,
+ final String fileExtension, final String resetScript) {
+ super(new BorderLayout());
+ scriptTextArea = new JTextPane();
+ new LinePainter(scriptTextArea, WHITE);
+
+ final KeywordDocument doc = new KeywordDocument(keywords, ports);
+
+ // NOTE: Due to T2-1145 - always set editor kit BEFORE setDocument
+ scriptTextArea.setEditorKit(new NoWrapEditorKit());
+ scriptTextArea.setFont(new Font("Monospaced", PLAIN, 14));
+ scriptTextArea.setDocument(doc);
+ scriptTextArea.setText(script);
+ scriptTextArea.setCaretPosition(0);
+ scriptTextArea.setPreferredSize(new Dimension(200, 100));
+
+ add(new LineEnabledTextPanel(scriptTextArea), CENTER);
+
+ final JButton checkScriptButton = new JButton("Check script");
+ checkScriptButton.setToolTipText("Check the " + scriptType + " script");
+ checkScriptButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent ex) {
+ showMessageDialog(ScriptConfigurationComponent.this, scriptType
+ + " script check not implemented", scriptType
+ + " script check", INFORMATION_MESSAGE);
+ }
+ });
+
+ JButton loadScriptButton = new JButton("Load script");
+ loadScriptButton.setToolTipText("Load a " + scriptType
+ + " script from a file");
+ loadScriptButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ String newScript = readStringFromFile(
+ ScriptConfigurationComponent.this, "Load " + scriptType
+ + " script", fileExtension);
+ if (newScript != null) {
+ scriptTextArea.setText(newScript);
+ scriptTextArea.setCaretPosition(0);
+ }
+ }
+ });
+
+ JButton saveRScriptButton = new JButton("Save script");
+ saveRScriptButton.setToolTipText("Save the " + scriptType
+ + " script to a file");
+ saveRScriptButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ saveStringToFile(ScriptConfigurationComponent.this, "Save "
+ + scriptType + " script", fileExtension,
+ scriptTextArea.getText());
+ }
+ });
+
+ JButton clearScriptButton = new JButton("Clear script");
+ clearScriptButton.setToolTipText("Clear current script from the edit area");
+ clearScriptButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (showConfirmDialog(ScriptConfigurationComponent.this,
+ "Do you really want to clear the script?",
+ "Clearing the script", YES_NO_OPTION) == YES_OPTION)
+ scriptTextArea.setText(resetScript);
+ }
+ });
+
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.setLayout(new FlowLayout());
+ buttonPanel.add(checkScriptButton);
+ buttonPanel.add(loadScriptButton);
+ buttonPanel.add(saveRScriptButton);
+ buttonPanel.add(clearScriptButton);
+
+ add(buttonPanel, SOUTH);
+ }
+
+ public String getScript() {
+ return scriptTextArea.getText();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ValidatingTextField.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ValidatingTextField.java b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ValidatingTextField.java
new file mode 100644
index 0000000..cf1ff96
--- /dev/null
+++ b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ValidatingTextField.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (C) 2012 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.activity;
+
+import javax.swing.JTextField;
+
+/**
+ * Adds a "<tt>valid</tt>" property to a JTextField.
+ *
+ * @author David Withers
+ */
+@SuppressWarnings("serial")
+public class ValidatingTextField extends JTextField {
+ private boolean valid = true;
+
+ public ValidatingTextField() {
+ }
+
+ public ValidatingTextField(String text) {
+ super(text);
+ }
+
+ @Override
+ public boolean isValid() {
+ return valid;
+ }
+
+ public void setValid(boolean valid) {
+ if (this.valid != valid) {
+ boolean old = this.valid;
+ this.valid = valid;
+ firePropertyChange("valid", old, valid);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ValidatingTextGroup.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ValidatingTextGroup.java b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ValidatingTextGroup.java
new file mode 100644
index 0000000..7597f7c
--- /dev/null
+++ b/taverna-contextual-views-api/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/ValidatingTextGroup.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (C) 2012 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.activity;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+/**
+ *
+ *
+ * @author David Withers
+ */
+public class ValidatingTextGroup {
+ private Map<ValidatingTextField, DocumentListener> textComponents;
+
+ public ValidatingTextGroup() {
+ textComponents = new HashMap<>();
+ }
+
+ public void addValidTextComponent(ValidatingTextField textComponent) {
+ setUniqueText(textComponent);
+ DocumentListener documentListener = new ValidatorDocumentListener();
+ textComponent.getDocument().addDocumentListener(documentListener);
+ textComponents.put(textComponent, documentListener);
+ }
+
+ public void addTextComponent(ValidatingTextField textComponent) {
+ DocumentListener documentListener = new ValidatorDocumentListener();
+ textComponent.getDocument().addDocumentListener(documentListener);
+ textComponents.put(textComponent, documentListener);
+ validate();
+ }
+
+ public void removeTextComponent(ValidatingTextField textComponent) {
+ textComponent.getDocument().removeDocumentListener(
+ textComponents.remove(textComponent));
+ validate();
+ }
+
+ private void setUniqueText(ValidatingTextField textComponent) {
+ String text = textComponent.getText();
+ if (textExists(text)) {
+ // Remove any existing number suffix
+ String nameTemplate = text.replaceAll("_\\d+$", "_");
+ long i = 1;
+ do {
+ text = nameTemplate + i++;
+ } while (textExists(text));
+
+ textComponent.setText(text);
+ }
+ }
+
+ private void validate() {
+ Map<String, ValidatingTextField> textValues = new HashMap<>();
+ Set<ValidatingTextField> maybeValid = new HashSet<>();
+ for (ValidatingTextField textComponent : textComponents.keySet()) {
+ ValidatingTextField duplicate = textValues.get(textComponent
+ .getText());
+ if (duplicate != null) {
+ duplicate.setValid(false);
+ maybeValid.remove(duplicate);
+ textComponent.setValid(false);
+ } else {
+ textValues.put(textComponent.getText(), textComponent);
+ maybeValid.add(textComponent);
+ }
+ }
+ for (ValidatingTextField textComponent : maybeValid)
+ textComponent.setValid(true);
+ }
+
+ private boolean textExists(String text) {
+ for (ValidatingTextField currentTextComponent : textComponents.keySet())
+ if (text.equals(currentTextComponent.getText()))
+ return true;
+ return false;
+ }
+
+ class ValidatorDocumentListener implements DocumentListener {
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ validate();
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ validate();
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ validate();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-api/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.zaria.UIComponentFactorySPI
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-api/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.zaria.UIComponentFactorySPI b/taverna-contextual-views-api/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.zaria.UIComponentFactorySPI
new file mode 100644
index 0000000..312f95b
--- /dev/null
+++ b/taverna-contextual-views-api/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.zaria.UIComponentFactorySPI
@@ -0,0 +1,2 @@
+#net.sf.taverna.t2.workbench.ui.actions.activity.draggable.ActivityDraggerPaletteComponentFactory
+#net.sf.taverna.t2.workbench.ui.views.contextualviews.DragActivitiesToHereComponentFactory
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-api/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.zaria.UIComponentSPI
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-api/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.zaria.UIComponentSPI b/taverna-contextual-views-api/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.zaria.UIComponentSPI
new file mode 100644
index 0000000..1448a49
--- /dev/null
+++ b/taverna-contextual-views-api/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.zaria.UIComponentSPI
@@ -0,0 +1,3 @@
+#net.sf.taverna.t2.workbench.ui.actions.activity.draggable.ActivityDraggerPaletteComponent
+#net.sf.taverna.t2.workbench.ui.views.contextualviews.DragActivitiesToHereComponent
+net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualViewComponent
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-api/src/main/resources/META-INF/spring/contextual-views-api-context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-api/src/main/resources/META-INF/spring/contextual-views-api-context-osgi.xml b/taverna-contextual-views-api/src/main/resources/META-INF/spring/contextual-views-api-context-osgi.xml
new file mode 100644
index 0000000..ab22b97
--- /dev/null
+++ b/taverna-contextual-views-api/src/main/resources/META-INF/spring/contextual-views-api-context-osgi.xml
@@ -0,0 +1,9 @@
+<?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">
+
+</beans:beans>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-api/src/main/resources/META-INF/spring/contextual-views-api-context.xml
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-api/src/main/resources/META-INF/spring/contextual-views-api-context.xml b/taverna-contextual-views-api/src/main/resources/META-INF/spring/contextual-views-api-context.xml
new file mode 100644
index 0000000..d662d87
--- /dev/null
+++ b/taverna-contextual-views-api/src/main/resources/META-INF/spring/contextual-views-api-context.xml
@@ -0,0 +1,6 @@
+<?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">
+
+</beans>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-impl/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-impl/pom.xml b/taverna-contextual-views-impl/pom.xml
new file mode 100644
index 0000000..c0398e9
--- /dev/null
+++ b/taverna-contextual-views-impl/pom.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<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>org.apache.taverna.workbench</groupId>
+ <artifactId>taverna-workbench</artifactId>
+ <version>3.1.0-incubating-SNAPSHOT</version>
+ </parent>
+ <artifactId>taverna-contextual-views-impl</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Taverna Contextual Views Impl</name>
+ <description>Contextual views for the activities</description>
+ <dependencies>
+ <dependency>
+ <groupId>${project.parent.groupId}</groupId>
+ <artifactId>taverna-contextual-views-api</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.parent.groupId}</groupId>
+ <artifactId>taverna-selection-api</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.taverna.language</groupId>
+ <artifactId>taverna-scufl2-api</artifactId>
+ <version>${taverna.language.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.help</groupId>
+ <artifactId>javahelp</artifactId>
+ <version>${javahelp.version}</version>
+ </dependency>
+
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/impl/ContextualViewFactoryRegistryImpl.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/impl/ContextualViewFactoryRegistryImpl.java b/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/impl/ContextualViewFactoryRegistryImpl.java
new file mode 100644
index 0000000..8bac354
--- /dev/null
+++ b/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/activity/impl/ContextualViewFactoryRegistryImpl.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+
+/**
+ * @author Alan R Williams
+ */
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactoryRegistry;
+
+/**
+ * An SPI registry for discovering ActivityViewFactories for a given object,
+ * like an {@link net.sf.taverna.t2.workflowmodel.processor.activity.Activity}.
+ * <p>
+ * For {@link ContextualViewFactory factories} to be found, its full qualified
+ * name needs to be defined as a resource file
+ * <code>/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualViewFactory</code>
+ *
+ * @author Stuart Owen
+ * @author Ian Dunlop
+ * @author Stian Soiland-Reyes
+ *
+ * @see ContextualViewFactory
+ */
+public class ContextualViewFactoryRegistryImpl implements
+ ContextualViewFactoryRegistry {
+ private List<ContextualViewFactory<?>> contextualViewFactories;
+
+ /**
+ * Discover and return the ContextualViewFactory associated to the provided
+ * object. This is accomplished by returning the discovered
+ * {@link ContextualViewFactory#canHandle(Object)} that returns true for
+ * that Object.
+ *
+ * @param object
+ * @return
+ * @see ContextualViewFactory#canHandle(Object)
+ */
+ @Override
+ public List<ContextualViewFactory<?>> getViewFactoriesForObject(
+ Object object) {
+ List<ContextualViewFactory<?>> result = new ArrayList<>();
+ for (ContextualViewFactory<?> factory : contextualViewFactories)
+ if (factory.canHandle(object))
+ result.add(factory);
+ return result;
+ }
+
+ public void setContextualViewFactories(
+ List<ContextualViewFactory<?>> contextualViewFactories) {
+ this.contextualViewFactories = contextualViewFactories;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualView.java b/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualView.java
new file mode 100644
index 0000000..018a121
--- /dev/null
+++ b/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualView.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.annotated;
+
+import static javax.swing.BoxLayout.Y_AXIS;
+
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+import java.util.regex.Pattern;
+
+import javax.swing.BoxLayout;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.TitledBorder;
+
+import net.sf.taverna.t2.annotation.Annotated;
+import net.sf.taverna.t2.annotation.AnnotationBeanSPI;
+import net.sf.taverna.t2.lang.ui.DialogTextArea;
+import net.sf.taverna.t2.workbench.edits.CompoundEdit;
+import net.sf.taverna.t2.workbench.edits.Edit;
+import net.sf.taverna.t2.workbench.edits.EditException;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.selection.SelectionManager;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.impl.ContextualViewComponent;
+
+import org.apache.log4j.Logger;
+
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+
+/**
+ * This is a ContextualView that should be able to display and allow editing of
+ * Annotation information for any Annotated. At the moment it is only used for
+ * Dataflow.
+ *
+ * @author Alan R Williams
+ */
+@SuppressWarnings("serial")
+class AnnotatedContextualView extends ContextualView {
+ private static final int WORKFLOW_NAME_LENGTH = 20;
+ public static final String VIEW_TITLE = "Annotations";
+ private final static String MISSING_VALUE = "Type here to give details";
+ private final static int DEFAULT_AREA_WIDTH = 60;
+ private final static int DEFAULT_AREA_ROWS = 8;
+
+ private static Logger logger = Logger
+ .getLogger(AnnotatedContextualView.class);
+ private static PropertyResourceBundle prb = (PropertyResourceBundle) ResourceBundle
+ .getBundle("annotatedcontextualview");
+
+ // TODO convert to scufl2
+ // private static AnnotationTools annotationTools = new AnnotationTools();
+
+ /**
+ * The object to which the Annotations apply
+ */
+ private Annotated<?> annotated;
+ private SelectionManager selectionManager;
+ private EditManager editManager;
+ private boolean isStandalone = false;
+ private JPanel panel;
+ @SuppressWarnings("unused")
+ private final List<AnnotationBeanSPI> annotationBeans;
+
+ public AnnotatedContextualView(Annotated<?> annotated,
+ EditManager editManager, SelectionManager selectionManager,
+ List<AnnotationBeanSPI> annotationBeans) {
+ super();
+ this.editManager = editManager;
+ this.selectionManager = selectionManager;
+ this.annotationBeans = annotationBeans;
+ this.annotated = annotated;
+
+ initialise();
+ initView();
+ }
+
+ @Override
+ public void refreshView() {
+ initialise();
+ }
+
+ private void initialise() {
+ if (panel == null) {
+ panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, Y_AXIS));
+ } else
+ panel.removeAll();
+ populatePanel();
+ revalidate();
+ }
+
+ @Override
+ public JComponent getMainFrame() {
+ return panel;
+ }
+
+ @Override
+ public String getViewTitle() {
+ return VIEW_TITLE;
+ }
+
+ private Map<String,String> getAnnotations() {
+ // TODO convert to scufl2
+ Map<String, String> result = new HashMap<>();
+ //for (Class<?> c : annotationTools.getAnnotatingClasses(annotated)) {
+ // String name = "";
+ // try {
+ // name = prb.getString(c.getCanonicalName());
+ // } catch (MissingResourceException e) {
+ // name = c.getCanonicalName();
+ // }
+ // String value = annotationTools.getAnnotationString(annotated, c,
+ // MISSING_VALUE);
+ // result.put(name,value);
+ //}
+ return result;
+ }
+ public void populatePanel() {
+ JPanel scrollPanel = new JPanel();
+ scrollPanel.setLayout(new BoxLayout(scrollPanel, Y_AXIS));
+ panel.setBorder(new EmptyBorder(5, 5, 5, 5));
+ Map<String,String>annotations = getAnnotations();
+ for (String name : annotations.keySet()) {
+ JPanel subPanel = new JPanel();
+ subPanel.setBorder(new TitledBorder(name));
+ subPanel.add(createTextArea(String.class, annotations.get(name)));
+ scrollPanel.add(subPanel);
+ }
+ JScrollPane scrollPane = new JScrollPane(scrollPanel);
+ panel.add(scrollPane);
+ }
+
+ private JScrollPane createTextArea(Class<?> c, String value) {
+ DialogTextArea area = new DialogTextArea(value);
+ area.setFocusable(true);
+ area.addFocusListener(new TextAreaFocusListener(area, c));
+ area.setColumns(DEFAULT_AREA_WIDTH);
+ area.setRows(DEFAULT_AREA_ROWS);
+ area.setLineWrap(true);
+ area.setWrapStyleWord(true);
+
+ return new JScrollPane(area);
+ }
+
+ private class TextAreaFocusListener implements FocusListener {
+ String oldValue = null;
+ Class<?> annotationClass;
+ DialogTextArea area = null;
+
+ public TextAreaFocusListener(DialogTextArea area, Class<?> c) {
+ annotationClass = c;
+ oldValue = area.getText();
+ this.area = area;
+ }
+
+ @Override
+ public void focusGained(FocusEvent e) {
+ if (area.getText().equals(MISSING_VALUE))
+ area.setText("");
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ String currentValue = area.getText();
+ if (currentValue.isEmpty() || currentValue.equals(MISSING_VALUE)) {
+ currentValue = MISSING_VALUE;
+ area.setText(currentValue);
+ }
+ if (!currentValue.equals(oldValue)) {
+ if (currentValue == MISSING_VALUE)
+ currentValue = "";
+ try {
+ WorkflowBundle currentDataflow = selectionManager
+ .getSelectedWorkflowBundle();
+ List<Edit<?>> editList = new ArrayList<>();
+ addWorkflowNameEdits(currentValue, currentDataflow,
+ editList);
+ if (!isStandalone)
+ ContextualViewComponent.selfGenerated = true;
+ editManager.doDataflowEdit(currentDataflow,
+ new CompoundEdit(editList));
+ ContextualViewComponent.selfGenerated = false;
+ } catch (EditException e1) {
+ logger.warn("Can't set annotation", e1);
+ }
+ oldValue = area.getText();
+ }
+ }
+
+ private boolean isTitleAnnotation() {
+ // TODO convert to scufl2
+ return prb.getString(annotationClass.getCanonicalName()).equals(
+ "Title");
+ }
+
+ // TODO convert to scufl2
+ private void addWorkflowNameEdits(String currentValue,
+ WorkflowBundle currentDataflow, List<Edit<?>> editList) {
+ //editList.add(annotationTools.setAnnotationString(annotated,
+ // annotationClass, currentValue, edits));
+ if (annotated == currentDataflow && isTitleAnnotation()
+ && !currentValue.isEmpty()) {
+ @SuppressWarnings("unused")
+ String sanitised = sanitiseName(currentValue);
+ //editList.add(edits.getUpdateDataflowNameEdit(currentDataflow,
+ // sanitised));
+ }
+ }
+ }
+
+ /**
+ * Checks that the name does not have any characters that are invalid for a
+ * processor name.
+ * <p>
+ * The resulting name must contain only the chars [A-Za-z_0-9].
+ *
+ * @param name
+ * the original name
+ * @return the sanitised name
+ */
+ private static String sanitiseName(String name) {
+ if (name.length() > WORKFLOW_NAME_LENGTH)
+ name = name.substring(0, WORKFLOW_NAME_LENGTH);
+ if (Pattern.matches("\\w++", name))
+ return name;
+ StringBuilder temp = new StringBuilder();
+ for (char c : name.toCharArray())
+ temp.append(Character.isLetterOrDigit(c) || c == '_' ? c : '_');
+ return temp.toString();
+ }
+
+ @Override
+ public int getPreferredPosition() {
+ return 500;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualViewFactory.java b/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualViewFactory.java
new file mode 100644
index 0000000..eb18803
--- /dev/null
+++ b/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/annotated/AnnotatedContextualViewFactory.java
@@ -0,0 +1,43 @@
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.annotated;
+
+import static java.util.Collections.singletonList;
+
+import java.util.List;
+
+import net.sf.taverna.t2.annotation.Annotated;
+import net.sf.taverna.t2.annotation.AnnotationBeanSPI;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.selection.SelectionManager;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
+import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
+
+public class AnnotatedContextualViewFactory implements
+ ContextualViewFactory<Annotated<?>> {
+ private EditManager editManager;
+ private List<AnnotationBeanSPI> annotationBeans;
+ private SelectionManager selectionManager;
+
+ @Override
+ public boolean canHandle(Object selection) {
+ return ((selection instanceof Annotated) && !(selection instanceof Activity));
+ }
+
+ @Override
+ public List<ContextualView> getViews(Annotated<?> selection) {
+ return singletonList((ContextualView) new AnnotatedContextualView(
+ selection, editManager, selectionManager, annotationBeans));
+ }
+
+ public void setEditManager(EditManager editManager) {
+ this.editManager = editManager;
+ }
+
+ public void setSelectionManager(SelectionManager selectionManager) {
+ this.selectionManager = selectionManager;
+ }
+
+ public void setAnnotationBeans(List<AnnotationBeanSPI> annotationBeans) {
+ this.annotationBeans = annotationBeans;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualView.java b/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualView.java
new file mode 100644
index 0000000..f9308b5
--- /dev/null
+++ b/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualView.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.condition;
+
+import java.awt.FlowLayout;
+
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.EmptyBorder;
+
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import uk.org.taverna.scufl2.api.core.BlockingControlLink;
+
+/**
+ * Contextual view for dataflow's control (condition) links.
+ *
+ * @author David Withers
+ */
+class ConditionContextualView extends ContextualView {
+ private static final long serialVersionUID = -894521200616176439L;
+
+ private final BlockingControlLink condition;
+ private JPanel contitionView;
+
+ public ConditionContextualView(BlockingControlLink condition) {
+ this.condition = condition;
+ initView();
+ }
+
+ @Override
+ public JComponent getMainFrame() {
+ refreshView();
+ return contitionView;
+ }
+
+ @Override
+ public String getViewTitle() {
+ return "Control link: " + condition.getBlock().getName()
+ + " runs after " + condition.getUntilFinished().getName();
+ }
+
+ @Override
+ public void refreshView() {
+ contitionView = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ contitionView.setBorder(new EmptyBorder(5, 5, 5, 5));
+ JLabel label = new JLabel(
+ "<html><body><i>No details available.</i></body><html>");
+ contitionView.add(label);
+ }
+
+ @Override
+ public int getPreferredPosition() {
+ return 100;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualViewFactory.java b/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualViewFactory.java
new file mode 100644
index 0000000..ea69f1a
--- /dev/null
+++ b/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/condition/ConditionContextualViewFactory.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.condition;
+
+import static java.util.Arrays.asList;
+
+import java.util.List;
+
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
+import net.sf.taverna.t2.workflowmodel.Condition;
+import uk.org.taverna.scufl2.api.core.BlockingControlLink;
+
+/**
+ * A factory of contextual views for dataflow's condition links.
+ *
+ * @author David Withers
+ *
+ */
+public class ConditionContextualViewFactory implements
+ ContextualViewFactory<BlockingControlLink> {
+ @Override
+ public boolean canHandle(Object object) {
+ return object instanceof Condition;
+ }
+
+ @Override
+ public List<ContextualView> getViews(BlockingControlLink condition) {
+ return asList(new ContextualView[] { new ConditionContextualView(
+ condition) });
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualView.java b/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualView.java
new file mode 100644
index 0000000..4a63868
--- /dev/null
+++ b/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualView.java
@@ -0,0 +1,108 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.dataflow;
+
+import static net.sf.taverna.t2.lang.ui.HtmlUtils.buildTableOpeningTag;
+import static net.sf.taverna.t2.lang.ui.HtmlUtils.createEditorPane;
+import static net.sf.taverna.t2.lang.ui.HtmlUtils.getHtmlHead;
+import static net.sf.taverna.t2.lang.ui.HtmlUtils.panelForHtml;
+
+import javax.swing.JComponent;
+import javax.swing.JEditorPane;
+
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workflowmodel.Dataflow;
+import uk.org.taverna.scufl2.api.core.Workflow;
+import uk.org.taverna.scufl2.api.port.InputWorkflowPort;
+import uk.org.taverna.scufl2.api.port.OutputWorkflowPort;
+
+/**
+ * @author alanrw
+ */
+@SuppressWarnings("serial")
+class DataflowContextualView extends ContextualView {
+ private static int MAX_LENGTH = 50;
+ private static final String ELLIPSIS = "...";
+
+ private Workflow dataflow;
+ private JEditorPane editorPane;
+ private final FileManager fileManager;
+ private final ColourManager colourManager;
+
+ public DataflowContextualView(Workflow dataflow, FileManager fileManager,
+ ColourManager colourManager) {
+ this.dataflow = dataflow;
+ this.fileManager = fileManager;
+ this.colourManager = colourManager;
+ initView();
+ }
+
+ @Override
+ public JComponent getMainFrame() {
+ editorPane = createEditorPane(buildHtml());
+ return panelForHtml(editorPane);
+ }
+
+ private String buildHtml() {
+ StringBuilder html = new StringBuilder(getHtmlHead(getBackgroundColour()));
+ html.append(buildTableOpeningTag());
+
+ html.append("<tr><td colspan=\"2\" align=\"center\"><b>Source</b></td></tr>");
+ String source = "Newly created";
+ if (fileManager.getDataflowSource(dataflow.getParent()) != null)
+ source = fileManager.getDataflowName(dataflow.getParent());
+
+ html.append("<tr><td colspan=\"2\" align=\"center\">").append(source)
+ .append("</td></tr>");
+ if (!dataflow.getInputPorts().isEmpty()) {
+ html.append("<tr><th>Input Port Name</th><th>Depth</th></tr>");
+ for (InputWorkflowPort dip : dataflow.getInputPorts())
+ html.append("<tr><td>")
+ .append(dip.getName())
+ .append("</td><td>")
+ .append(dip.getDepth() < 0 ? "invalid/unpredicted"
+ : dip.getDepth()).append("</td></tr>");
+ }
+ if (!dataflow.getOutputPorts().isEmpty()) {
+ html.append("<tr><th>Output Port Name</th><th>Depth</th></tr>");
+ for (OutputWorkflowPort dop : dataflow.getOutputPorts())
+ html.append("<tr><td>")
+ .append(dop.getName())
+ .append("</td><td>")
+ .append(/*(dop.getDepth() < 0 ?*/ "invalid/unpredicted" /*: dop.getDepth())*/)
+ .append("</td>" + "</tr>");
+ }
+
+ return html.append("</table>").append("</body></html>").toString();
+ }
+
+ public String getBackgroundColour() {
+ return colourManager.getDefaultPropertyMap().get(
+ Dataflow.class.toString());
+ }
+
+ @Override
+ public int getPreferredPosition() {
+ return 100;
+ }
+
+ private String limitName(String fullName) {
+ if (fullName.length() <= MAX_LENGTH)
+ return fullName;
+ return fullName.substring(0, MAX_LENGTH - ELLIPSIS.length()) + ELLIPSIS;
+ }
+
+ @Override
+ public String getViewTitle() {
+ return "Workflow " + limitName(dataflow.getName());
+ }
+
+ @Override
+ public void refreshView() {
+ editorPane.setText(buildHtml());
+ repaint();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualViewFactory.java b/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualViewFactory.java
new file mode 100644
index 0000000..0d7f3c0
--- /dev/null
+++ b/taverna-contextual-views-impl/src/main/java/net/sf/taverna/t2/workbench/ui/views/contextualviews/dataflow/DataflowContextualViewFactory.java
@@ -0,0 +1,41 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.workbench.ui.views.contextualviews.dataflow;
+
+import java.util.Arrays;
+import java.util.List;
+
+import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
+import uk.org.taverna.scufl2.api.core.Workflow;
+
+/**
+ * @author alanrw
+ */
+public class DataflowContextualViewFactory implements
+ ContextualViewFactory<Workflow> {
+ private FileManager fileManager;
+ private ColourManager colourManager;
+
+ @Override
+ public boolean canHandle(Object selection) {
+ return selection instanceof Workflow;
+ }
+
+ @Override
+ public List<ContextualView> getViews(Workflow selection) {
+ return Arrays.asList(new ContextualView[] {
+ new DataflowContextualView(selection, fileManager, colourManager)});
+ }
+
+ public void setFileManager(FileManager fileManager) {
+ this.fileManager = fileManager;
+ }
+
+ public void setColourManager(ColourManager colourManager) {
+ this.colourManager = colourManager;
+ }
+}