You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2015/02/23 11:22:46 UTC
[23/51] [partial] incubator-taverna-workbench git commit: Revert
"temporarily empty repository"
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-httpproxy-config/src/main/java/net/sf/taverna/t2/workbench/httpproxy/config/HttpProxyConfigurationPanel.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-httpproxy-config/src/main/java/net/sf/taverna/t2/workbench/httpproxy/config/HttpProxyConfigurationPanel.java b/taverna-workbench-httpproxy-config/src/main/java/net/sf/taverna/t2/workbench/httpproxy/config/HttpProxyConfigurationPanel.java
new file mode 100644
index 0000000..1229d57
--- /dev/null
+++ b/taverna-workbench-httpproxy-config/src/main/java/net/sf/taverna/t2/workbench/httpproxy/config/HttpProxyConfigurationPanel.java
@@ -0,0 +1,582 @@
+/*******************************************************************************
+ * 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.httpproxy.config;
+
+import static java.awt.GridBagConstraints.BOTH;
+import static java.awt.GridBagConstraints.CENTER;
+import static java.awt.GridBagConstraints.HORIZONTAL;
+import static java.awt.GridBagConstraints.NONE;
+import static java.awt.GridBagConstraints.WEST;
+import static javax.swing.JOptionPane.showMessageDialog;
+import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
+import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
+import static net.sf.taverna.t2.workbench.helper.Helper.showHelp;
+import static uk.org.taverna.configuration.proxy.HttpProxyConfiguration.PROXY_USE_OPTION;
+import static uk.org.taverna.configuration.proxy.HttpProxyConfiguration.SYSTEM_NON_PROXY_HOSTS;
+import static uk.org.taverna.configuration.proxy.HttpProxyConfiguration.SYSTEM_PROXY_HOST;
+import static uk.org.taverna.configuration.proxy.HttpProxyConfiguration.SYSTEM_PROXY_PASSWORD;
+import static uk.org.taverna.configuration.proxy.HttpProxyConfiguration.SYSTEM_PROXY_PORT;
+import static uk.org.taverna.configuration.proxy.HttpProxyConfiguration.SYSTEM_PROXY_USER;
+import static uk.org.taverna.configuration.proxy.HttpProxyConfiguration.TAVERNA_NON_PROXY_HOSTS;
+import static uk.org.taverna.configuration.proxy.HttpProxyConfiguration.TAVERNA_PROXY_HOST;
+import static uk.org.taverna.configuration.proxy.HttpProxyConfiguration.TAVERNA_PROXY_PASSWORD;
+import static uk.org.taverna.configuration.proxy.HttpProxyConfiguration.TAVERNA_PROXY_PORT;
+import static uk.org.taverna.configuration.proxy.HttpProxyConfiguration.TAVERNA_PROXY_USER;
+import static uk.org.taverna.configuration.proxy.HttpProxyConfiguration.USE_NO_PROXY_OPTION;
+import static uk.org.taverna.configuration.proxy.HttpProxyConfiguration.USE_SPECIFIED_VALUES_OPTION;
+import static uk.org.taverna.configuration.proxy.HttpProxyConfiguration.USE_SYSTEM_PROPERTIES_OPTION;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.AbstractAction;
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.border.EmptyBorder;
+
+import net.sf.taverna.t2.lang.ui.DialogTextArea;
+import uk.org.taverna.configuration.proxy.HttpProxyConfiguration;
+
+/**
+ * The HttpProxyConfigurationPanel provides the user interface to a
+ * {@link HttpProxyConfiguration} to determine how HTTP Connections are made by
+ * Taverna.
+ *
+ * @author alanrw
+ * @author David Withers
+ */
+public class HttpProxyConfigurationPanel extends JPanel {
+ static final long serialVersionUID = 3668473431971125038L;
+ /**
+ * The size of the field for the JTextFields.
+ */
+ private static int TEXTFIELD_SIZE = 25;
+
+ private final HttpProxyConfiguration httpProxyConfiguration;
+ /**
+ * RadioButtons that are in a common ButtonGroup. Selecting one of them
+ * indicates whether the system http proxy settings, the ad hoc specified
+ * values or no proxy settings at all should be used.
+ */
+ private JRadioButton useSystemProperties;
+ private JRadioButton useSpecifiedValues;
+ private JRadioButton useNoProxy;
+ /**
+ * JTextFields and one DialogTextArea to hold the settings for the HTTP
+ * proxy properties. The values are only editable if the user picks
+ * useSpecifiedValues.
+ */
+ private JTextField proxyHostField;
+ private JTextField proxyPortField;
+ private JTextField proxyUserField;
+ private JTextField proxyPasswordField;
+ private DialogTextArea nonProxyHostsArea;
+ private JScrollPane nonProxyScrollPane;
+ /**
+ * A string that indicates which HTTP setting option the user has currently
+ * picked. This does not necesarily match that which has been applied.
+ */
+ private String shownOption = USE_SYSTEM_PROPERTIES_OPTION;
+
+ /**
+ * The HttpProxyConfigurationPanel consists of a set of properties where the
+ * configuration values for HTTP can be specified and a set of buttons where
+ * the more general apply, help etc. appear.
+ */
+ public HttpProxyConfigurationPanel(
+ HttpProxyConfiguration httpProxyConfiguration) {
+ this.httpProxyConfiguration = httpProxyConfiguration;
+ initComponents();
+ }
+
+ /**
+ * Populates the panel with a representation of the current HTTP proxy
+ * settings for the specified {@link HttpProxyConfiguration} and also the
+ * capability to alter them.
+ */
+ private void initComponents() {
+ shownOption = httpProxyConfiguration.getProperty(PROXY_USE_OPTION);
+
+ this.setLayout(new GridBagLayout());
+
+ GridBagConstraints gbc = new GridBagConstraints();
+
+ // Title describing what kind of settings we are configuring here
+ JTextArea descriptionText = new JTextArea("HTTP proxy configuration");
+ descriptionText.setLineWrap(true);
+ descriptionText.setWrapStyleWord(true);
+ descriptionText.setEditable(false);
+ descriptionText.setFocusable(false);
+ descriptionText.setBorder(new EmptyBorder(10, 10, 10, 10));
+ gbc.anchor = WEST;
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.gridwidth = 2;
+ gbc.weightx = 1.0;
+ gbc.weighty = 0.0;
+ gbc.fill = HORIZONTAL;
+ this.add(descriptionText, gbc);
+
+ /**
+ * Generate the three radio buttons and put them in a group. Each button
+ * is bound to an action that alters the shownOption and re-populates
+ * the shown HTTP property fields.
+ */
+ useNoProxy = new JRadioButton("Do not use a proxy");
+ useNoProxy.setAlignmentX(LEFT_ALIGNMENT);
+ gbc.gridx = 0;
+ gbc.gridy = 1;
+ gbc.gridwidth = 2;
+ gbc.weightx = 0.0;
+ gbc.weighty = 0.0;
+ gbc.fill = NONE;
+ gbc.insets = new Insets(10, 0, 0, 0);
+ this.add(useNoProxy, gbc);
+ ActionListener useNoProxyListener = new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ shownOption = USE_NO_PROXY_OPTION;
+ populateFields();
+ }
+ };
+ useNoProxy.addActionListener(useNoProxyListener);
+
+ useSystemProperties = new JRadioButton("Use system properties");
+ useSystemProperties.setAlignmentX(LEFT_ALIGNMENT);
+ gbc.gridx = 0;
+ gbc.gridy = 2;
+ gbc.insets = new Insets(0, 0, 0, 0);
+ this.add(useSystemProperties, gbc);
+ ActionListener systemPropertiesListener = new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ shownOption = USE_SYSTEM_PROPERTIES_OPTION;
+ populateFields();
+ }
+ };
+ useSystemProperties.addActionListener(systemPropertiesListener);
+
+ useSpecifiedValues = new JRadioButton("Use specified values");
+ useSpecifiedValues.setAlignmentX(LEFT_ALIGNMENT);
+ gbc.gridx = 0;
+ gbc.gridy = 3;
+ this.add(useSpecifiedValues, gbc);
+ ActionListener specifiedValuesListener = new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ shownOption = USE_SPECIFIED_VALUES_OPTION;
+ populateFields();
+ }
+ };
+ useSpecifiedValues.addActionListener(specifiedValuesListener);
+
+ ButtonGroup bg = new ButtonGroup();
+ bg.add(useSystemProperties);
+ bg.add(useSpecifiedValues);
+ bg.add(useNoProxy);
+
+ /**
+ * Create the fields to show the HTTP proxy property values. These
+ * become editable if the shown option is to use specified values.
+ */
+ proxyHostField = new JTextField(TEXTFIELD_SIZE);
+ gbc.gridx = 0;
+ gbc.gridy = 4;
+ gbc.gridwidth = 1;
+ gbc.fill = NONE;
+ gbc.insets = new Insets(10, 0, 0, 0);
+ this.add(new JLabel("Proxy host"), gbc);
+ gbc.gridx = 1;
+ gbc.gridy = 4;
+ gbc.gridwidth = 1;
+ gbc.fill = HORIZONTAL;
+ this.add(proxyHostField, gbc);
+
+ proxyPortField = new JTextField(TEXTFIELD_SIZE);
+ gbc.gridx = 0;
+ gbc.gridy = 5;
+ gbc.gridwidth = 1;
+ gbc.fill = NONE;
+ gbc.insets = new Insets(0, 0, 0, 0);
+ this.add(new JLabel("Proxy port"), gbc);
+ gbc.gridx = 1;
+ gbc.gridy = 5;
+ gbc.gridwidth = 1;
+ gbc.fill = HORIZONTAL;
+ this.add(proxyPortField, gbc);
+
+ proxyUserField = new JTextField(TEXTFIELD_SIZE);
+ gbc.gridx = 0;
+ gbc.gridy = 6;
+ gbc.gridwidth = 1;
+ gbc.fill = NONE;
+ this.add(new JLabel("Proxy user"), gbc);
+ gbc.gridx = 1;
+ gbc.gridy = 6;
+ gbc.gridwidth = 1;
+ gbc.fill = HORIZONTAL;
+ this.add(proxyUserField, gbc);
+
+ proxyPasswordField = new JTextField(TEXTFIELD_SIZE);
+ gbc.gridx = 0;
+ gbc.gridy = 7;
+ gbc.gridwidth = 1;
+ gbc.fill = NONE;
+ this.add(new JLabel("Proxy password"), gbc);
+ gbc.gridx = 1;
+ gbc.gridy = 7;
+ gbc.gridwidth = 1;
+ gbc.fill = HORIZONTAL;
+ this.add(proxyPasswordField, gbc);
+
+ nonProxyHostsArea = new DialogTextArea(10, 40);
+ nonProxyScrollPane = new JScrollPane(nonProxyHostsArea);
+ nonProxyScrollPane
+ .setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ nonProxyScrollPane
+ .setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_AS_NEEDED);
+ // nonProxyScrollPane.setPreferredSize(new Dimension(300, 500));
+ gbc.gridx = 0;
+ gbc.gridy = 8;
+ gbc.gridwidth = 2;
+ gbc.fill = NONE;
+ gbc.insets = new Insets(10, 0, 0, 0);
+ this.add(new JLabel("Non-proxy hosts"), gbc);
+ gbc.gridx = 0;
+ gbc.gridy = 9;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ gbc.gridwidth = 2;
+ gbc.insets = new Insets(0, 0, 0, 0);
+ gbc.fill = BOTH;
+ this.add(nonProxyScrollPane, gbc);
+
+ // Add buttons panel
+ gbc.gridx = 0;
+ gbc.gridy = 10;
+ gbc.weightx = 0.0;
+ gbc.weighty = 0.0;
+ gbc.gridwidth = 2;
+ gbc.fill = HORIZONTAL;
+ gbc.anchor = CENTER;
+ gbc.insets = new Insets(10, 0, 0, 0);
+ this.add(createButtonPanel(), gbc);
+
+ setFields();
+ }
+
+ /**
+ * Populate the fields in the property panel according to which option is
+ * being shown and the stored values within the
+ * {@link HttpProxyConfiguration}.
+ */
+ private void populateFields() {
+ /**
+ * Editing of the property fields is only available when the option is
+ * to use the specified values.
+ */
+ boolean editingEnabled = shownOption
+ .equals(USE_SPECIFIED_VALUES_OPTION);
+
+ if (shownOption.equals(USE_SYSTEM_PROPERTIES_OPTION)) {
+ proxyHostField.setText(httpProxyConfiguration
+ .getProperty(SYSTEM_PROXY_HOST));
+ proxyPortField.setText(httpProxyConfiguration
+ .getProperty(SYSTEM_PROXY_PORT));
+ proxyUserField.setText(httpProxyConfiguration
+ .getProperty(SYSTEM_PROXY_USER));
+ proxyPasswordField.setText(httpProxyConfiguration
+ .getProperty(SYSTEM_PROXY_PASSWORD));
+ nonProxyHostsArea.setText(httpProxyConfiguration
+ .getProperty(SYSTEM_NON_PROXY_HOSTS));
+ } else if (shownOption.equals(USE_SPECIFIED_VALUES_OPTION)) {
+ proxyHostField.setText(httpProxyConfiguration
+ .getProperty(TAVERNA_PROXY_HOST));
+ proxyPortField.setText(httpProxyConfiguration
+ .getProperty(TAVERNA_PROXY_PORT));
+ proxyUserField.setText(httpProxyConfiguration
+ .getProperty(TAVERNA_PROXY_USER));
+ proxyPasswordField.setText(httpProxyConfiguration
+ .getProperty(TAVERNA_PROXY_PASSWORD));
+ nonProxyHostsArea.setText(httpProxyConfiguration
+ .getProperty(TAVERNA_NON_PROXY_HOSTS));
+ } else {
+ proxyHostField.setText(null);
+ proxyPortField.setText(null);
+ proxyUserField.setText(null);
+ proxyPasswordField.setText(null);
+ nonProxyHostsArea.setText(null);
+ }
+
+ proxyHostField.setEnabled(editingEnabled);
+ proxyPortField.setEnabled(editingEnabled);
+ proxyUserField.setEnabled(editingEnabled);
+ proxyPasswordField.setEnabled(editingEnabled);
+ nonProxyHostsArea.setEnabled(editingEnabled);
+ nonProxyHostsArea.setEditable(editingEnabled);
+ nonProxyScrollPane.setEnabled(editingEnabled);
+ }
+
+ /**
+ * Create the panel to contain the buttons
+ *
+ * @return
+ */
+ @SuppressWarnings("serial")
+ private JPanel createButtonPanel() {
+ final JPanel panel = new JPanel();
+
+ /**
+ * The helpButton shows help about the current component
+ */
+ JButton helpButton = new JButton(new AbstractAction("Help") {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ showHelp(panel);
+ }
+ });
+ panel.add(helpButton);
+
+ /**
+ * The resetButton changes the property values shown to those
+ * corresponding to the configuration currently applied.
+ */
+ JButton resetButton = new JButton(new AbstractAction("Reset") {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ setFields();
+ }
+ });
+ panel.add(resetButton);
+
+ /**
+ * The applyButton applies the shown field values to the
+ * {@link HttpProxyConfiguration} and saves them for future.
+ */
+ JButton applyButton = new JButton(new AbstractAction("Apply") {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ applySettings();
+ setFields();
+ }
+ });
+ panel.add(applyButton);
+
+ return panel;
+ }
+
+ /**
+ * Checks that the specified values for the HTTP properties are a valid
+ * combination and, if so, saves them for future use. It does not apply them
+ * to the currently executing Taverna.
+ */
+ private void saveSettings() {
+ if (useSystemProperties.isSelected()) {
+ httpProxyConfiguration.setProperty(PROXY_USE_OPTION,
+ USE_SYSTEM_PROPERTIES_OPTION);
+ } else if (useNoProxy.isSelected()) {
+ httpProxyConfiguration.setProperty(PROXY_USE_OPTION,
+ USE_NO_PROXY_OPTION);
+ } else {
+ if (validateFields()) {
+ httpProxyConfiguration.setProperty(PROXY_USE_OPTION,
+ USE_SPECIFIED_VALUES_OPTION);
+ httpProxyConfiguration.setProperty(TAVERNA_PROXY_HOST,
+ proxyHostField.getText());
+ httpProxyConfiguration.setProperty(TAVERNA_PROXY_PORT,
+ proxyPortField.getText());
+ httpProxyConfiguration.setProperty(TAVERNA_PROXY_USER,
+ proxyUserField.getText());
+ httpProxyConfiguration.setProperty(TAVERNA_PROXY_PASSWORD,
+ proxyPasswordField.getText());
+ httpProxyConfiguration.setProperty(TAVERNA_NON_PROXY_HOSTS,
+ nonProxyHostsArea.getText());
+ }
+ }
+ }
+
+ /**
+ * Validates and, where appropriate formats, the properties values specified
+ * for HTTP Proxy configuration.
+ *
+ * @return
+ */
+ private boolean validateFields() {
+ boolean result = true;
+ result = result && validateHostField();
+ result = result && validatePortField();
+ result = result && validateUserField();
+ result = result && validatePasswordField();
+ result = result && validateNonProxyHostsArea();
+ return result;
+ }
+
+ /**
+ * Checks that, if a value is specified for non-proxy hosts then a proxy
+ * host has also been specified. Formats the non-proxy hosts string so that
+ * if the user has entered the hosts on separate lines, then the stored
+ * values are separated by bars.
+ *
+ * @return
+ */
+ private boolean validateNonProxyHostsArea() {
+ boolean result = true;
+ String value = nonProxyHostsArea.getText();
+ if ((value != null) && (!value.equals(""))) {
+ value = value.replaceAll("\\n", "|");
+ nonProxyHostsArea.setText(value);
+ result = result
+ && dependsUpon("non-proxy host", "host",
+ proxyHostField.getText());
+ }
+ return result;
+ }
+
+ /**
+ * Checks that, if a password has been specified, then a user has also been
+ * specified.
+ *
+ * @return
+ */
+ private boolean validatePasswordField() {
+ boolean result = true;
+ String value = proxyPasswordField.getText();
+ if ((value != null) && !value.isEmpty())
+ result = result
+ && dependsUpon("password", "user", proxyHostField.getText());
+ return result;
+ }
+
+ /**
+ * Checks that if a user has been specified, then a host has also been
+ * specified.
+ *
+ * @return
+ */
+ private boolean validateUserField() {
+ boolean result = true;
+ String value = proxyUserField.getText();
+ if ((value != null) && !value.isEmpty())
+ result = result
+ && dependsUpon("user", "host", proxyHostField.getText());
+ return result;
+ }
+
+ /**
+ * Checks that if a port has been specified then a host has also been
+ * specified. Checks that the port number is a non-negative integer. If the
+ * port has not been specified, then if a host has been specified, the
+ * default value 80 is used.
+ *
+ * @return
+ */
+ private boolean validatePortField() {
+ boolean result = true;
+ String value = proxyPortField.getText();
+ if ((value != null) && (!value.equals(""))) {
+ result = result
+ && dependsUpon("port", "host", proxyHostField.getText());
+ try {
+ int parsedNumber = Integer.parseInt(value);
+ if (parsedNumber <= 0) {
+ showMessageDialog(this, "The port must be non-negative");
+ result = false;
+ }
+ } catch (NumberFormatException e) {
+ showMessageDialog(this, "The port must be an integer");
+ result = false;
+ }
+ } else {
+ String hostField = proxyHostField.getText();
+ if ((hostField != null) && !hostField.isEmpty())
+ proxyPortField.setText("80");
+ }
+ return result;
+ }
+
+ /**
+ * Checks if the targetValue has been specified. If not then a message is
+ * displayed indicating that the dependent cannot be specified with the
+ * target.
+ *
+ * @param dependent
+ * @param target
+ * @param targetValue
+ * @return
+ */
+ private boolean dependsUpon(String dependent, String target,
+ String targetValue) {
+ boolean result = true;
+ if ((targetValue == null) || target.equals("")) {
+ showMessageDialog(this, "A " + dependent
+ + " cannot be specified without a " + target);
+ result = false;
+ }
+ return result;
+ }
+
+ /**
+ * Could validate the host field e.g. by establishing a connection.
+ * Currently no validation is done.
+ *
+ * @return
+ */
+ private boolean validateHostField() {
+ boolean result = true;
+ // String value = proxyHostField.getText();
+ return result;
+ }
+
+ /**
+ * Save the currently set field values (if valid) to the
+ * {@link HttpProxyConfiguration}. Also applies those values to the
+ * currently running Taverna.
+ */
+ private void applySettings() {
+ if (validateFields()) {
+ saveSettings();
+ httpProxyConfiguration.changeProxySettings();
+ }
+ }
+
+ /**
+ * Set the shown field values to those currently in use (i.e. last saved
+ * configuration).
+ */
+ private void setFields() {
+ shownOption = httpProxyConfiguration.getProperty(PROXY_USE_OPTION);
+ useSystemProperties.setSelected(shownOption
+ .equals(USE_SYSTEM_PROPERTIES_OPTION));
+ useSpecifiedValues.setSelected(shownOption
+ .equals(USE_SPECIFIED_VALUES_OPTION));
+ useNoProxy.setSelected(shownOption.equals(USE_NO_PROXY_OPTION));
+ populateFields();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-httpproxy-config/src/main/java/net/sf/taverna/t2/workbench/httpproxy/config/HttpProxyConfigurationUIFactory.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-httpproxy-config/src/main/java/net/sf/taverna/t2/workbench/httpproxy/config/HttpProxyConfigurationUIFactory.java b/taverna-workbench-httpproxy-config/src/main/java/net/sf/taverna/t2/workbench/httpproxy/config/HttpProxyConfigurationUIFactory.java
new file mode 100644
index 0000000..9f6ac8c
--- /dev/null
+++ b/taverna-workbench-httpproxy-config/src/main/java/net/sf/taverna/t2/workbench/httpproxy/config/HttpProxyConfigurationUIFactory.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * 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.httpproxy.config;
+
+import javax.swing.JPanel;
+
+import uk.org.taverna.configuration.Configurable;
+import uk.org.taverna.configuration.ConfigurationUIFactory;
+import uk.org.taverna.configuration.proxy.HttpProxyConfiguration;
+
+/**
+ * A Factory to create a HttpProxyConfiguration
+ *
+ * @author alanrw
+ * @author David Withers
+ */
+public class HttpProxyConfigurationUIFactory implements ConfigurationUIFactory {
+ private HttpProxyConfiguration httpProxyConfiguration;
+
+ @Override
+ public boolean canHandle(String uuid) {
+ return uuid.equals(getConfigurable().getUUID());
+ }
+
+ @Override
+ public JPanel getConfigurationPanel() {
+ return new HttpProxyConfigurationPanel(httpProxyConfiguration);
+ }
+
+ @Override
+ public Configurable getConfigurable() {
+ return httpProxyConfiguration;
+ }
+
+ public void setHttpProxyConfiguration(HttpProxyConfiguration httpProxyConfiguration) {
+ this.httpProxyConfiguration = httpProxyConfiguration;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-httpproxy-config/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory
----------------------------------------------------------------------
diff --git a/taverna-workbench-httpproxy-config/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory b/taverna-workbench-httpproxy-config/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory
new file mode 100644
index 0000000..d87772b
--- /dev/null
+++ b/taverna-workbench-httpproxy-config/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory
@@ -0,0 +1 @@
+net.sf.taverna.t2.workbench.httpproxy.config.HttpProxyConfigurationUIFactory
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context-osgi.xml b/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context-osgi.xml
new file mode 100644
index 0000000..631bdb4
--- /dev/null
+++ b/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context-osgi.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans:beans xmlns="http://www.springframework.org/schema/osgi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:beans="http://www.springframework.org/schema/beans"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/osgi
+ http://www.springframework.org/schema/osgi/spring-osgi.xsd">
+
+ <service ref="HttpProxyConfigurationUIFactory" interface="uk.org.taverna.configuration.ConfigurationUIFactory" />
+
+ <reference id="httpProxyConfiguration" interface="uk.org.taverna.configuration.proxy.HttpProxyConfiguration" />
+
+</beans:beans>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context.xml b/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context.xml
new file mode 100644
index 0000000..6d6060f
--- /dev/null
+++ b/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <bean id="HttpProxyConfigurationUIFactory" class="net.sf.taverna.t2.workbench.httpproxy.config.HttpProxyConfigurationUIFactory">
+ <property name="httpProxyConfiguration" ref="httpProxyConfiguration" />
+ </bean>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-iteration-strategy-ui/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-iteration-strategy-ui/pom.xml b/taverna-workbench-iteration-strategy-ui/pom.xml
new file mode 100644
index 0000000..0b6ff81
--- /dev/null
+++ b/taverna-workbench-iteration-strategy-ui/pom.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>net.sf.taverna.t2</groupId>
+ <artifactId>ui-components</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </parent>
+ <groupId>net.sf.taverna.t2.ui-components</groupId>
+ <artifactId>iteration-strategy-ui</artifactId>
+ <packaging>bundle</packaging>
+ <name>Menu generation API</name>
+ <description>An SPI system for building UI menues</description>
+ <dependencies>
+ <dependency>
+ <groupId>net.sf.taverna.t2.core</groupId>
+ <artifactId>workflowmodel-api</artifactId>
+ <version>${t2.core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.taverna.t2.lang</groupId>
+ <artifactId>ui</artifactId>
+ <version>${t2.lang.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.taverna.t2.ui-api</groupId>
+ <artifactId>workbench-api</artifactId>
+ <version>${t2.ui.api.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.taverna.t2.ui-api</groupId>
+ <artifactId>contextual-views-api</artifactId>
+ <version>${t2.ui.api.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.taverna.t2.ui-api</groupId>
+ <artifactId>edits-api</artifactId>
+ <version>${t2.ui.api.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.taverna.t2.ui-api</groupId>
+ <artifactId>file-api</artifactId>
+ <version>${t2.ui.api.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.taverna.t2.ui-api</groupId>
+ <artifactId>helper-api</artifactId>
+ <version>${t2.ui.api.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.taverna.t2.core</groupId>
+ <artifactId>workflowmodel-impl</artifactId>
+ <version>${t2.core.version}</version>
+ <!-- <scope>test</scope> -->
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/IterationStrategyIcons.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/IterationStrategyIcons.java b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/IterationStrategyIcons.java
new file mode 100644
index 0000000..350c0cc
--- /dev/null
+++ b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/IterationStrategyIcons.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * 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.iterationstrategy;
+
+import javax.swing.ImageIcon;
+
+import org.apache.log4j.Logger;
+
+public class IterationStrategyIcons {
+
+ private static Logger logger = Logger
+ .getLogger(IterationStrategyIcons.class);
+
+ public static ImageIcon joinIteratorIcon, lockStepIteratorIcon,
+ leafnodeicon;
+
+ static {
+ try {
+ Class<?> c = IterationStrategyIcons.class;
+ joinIteratorIcon = new ImageIcon(c
+ .getResource("icons/crossproducticon.png"));
+ lockStepIteratorIcon = new ImageIcon(c
+ .getResource("icons/dotproducticon.png"));
+ leafnodeicon = new ImageIcon(c
+ .getResource("icons/leafnodeicon.png"));
+ } catch (Exception ex) {
+ logger.warn("Could not find icon", ex);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/contextview/IterationStrategyConfigurationDialog.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/contextview/IterationStrategyConfigurationDialog.java b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/contextview/IterationStrategyConfigurationDialog.java
new file mode 100644
index 0000000..1af83cb
--- /dev/null
+++ b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/contextview/IterationStrategyConfigurationDialog.java
@@ -0,0 +1,148 @@
+/**
+ *
+ */
+package net.sf.taverna.t2.workbench.iterationstrategy.contextview;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.helper.HelpEnabledDialog;
+import net.sf.taverna.t2.workbench.iterationstrategy.editor.IterationStrategyEditorControl;
+import net.sf.taverna.t2.workflowmodel.Edit;
+import net.sf.taverna.t2.workflowmodel.EditException;
+import net.sf.taverna.t2.workflowmodel.Edits;
+import net.sf.taverna.t2.workflowmodel.Processor;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.IterationStrategy;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.IterationStrategyStack;
+
+import org.apache.log4j.Logger;
+
+/**
+ * @author alanrw
+ *
+ */
+@SuppressWarnings("serial")
+public class IterationStrategyConfigurationDialog extends HelpEnabledDialog {
+
+ private static Logger logger = Logger
+ .getLogger(IterationStrategyConfigurationDialog.class);
+
+ private final EditManager editManager;
+ private final FileManager fileManager;
+
+
+ private final Frame owner;
+ private final Processor processor;
+ private final IterationStrategyStack originalStack;
+
+ private IterationStrategyStack workingStack;
+
+ public IterationStrategyConfigurationDialog(Frame owner, Processor processor, IterationStrategyStack iStack, EditManager editManager, FileManager fileManager) {
+ super (owner, "List handling for " + processor.getLocalName(), true, null);
+ this.owner = owner;
+ this.processor = processor;
+ this.originalStack = iStack;
+ this.editManager = editManager;
+ this.fileManager = fileManager;
+ this.workingStack = IterationStrategyContextualView.copyIterationStrategyStack(originalStack);
+ IterationStrategy iterationStrategy = IterationStrategyContextualView.getIterationStrategy(workingStack);
+ IterationStrategyEditorControl iterationStrategyEditorControl = new IterationStrategyEditorControl(
+ iterationStrategy);
+ this.add(iterationStrategyEditorControl, BorderLayout.CENTER);
+
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.setLayout(new FlowLayout());
+
+ JButton okButton = new JButton(new OKAction(this));
+ buttonPanel.add(okButton);
+
+ JButton resetButton = new JButton(new ResetAction(
+ iterationStrategyEditorControl));
+ buttonPanel.add(resetButton);
+
+ JButton cancelButton = new JButton(new CancelAction(this));
+ buttonPanel.add(cancelButton);
+
+ this.add(buttonPanel, BorderLayout.SOUTH);
+ this.pack();
+ this.setSize(new Dimension(getPreferredSize().width, getPreferredSize().height > 400 ? 400 : getPreferredSize().height));
+ }
+
+ private final class OKAction extends AbstractAction {
+ private final JDialog dialog;
+
+ private OKAction(JDialog dialog) {
+ super("OK");
+ this.dialog = dialog;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ Edits edits = editManager.getEdits();
+ try {
+ Edit<?> edit = edits.getSetIterationStrategyStackEdit(
+ processor,
+ IterationStrategyContextualView.copyIterationStrategyStack(workingStack));
+ editManager.doDataflowEdit(
+ fileManager.getCurrentDataflow(), edit);
+ dialog.setVisible(false);
+ } catch (RuntimeException ex) {
+ logger.warn("Could not set list handling", ex);
+ JOptionPane.showMessageDialog(owner,
+ "Can't set list handling",
+ "An error occured when setting list handling: "
+ + ex.getMessage(),
+ JOptionPane.ERROR_MESSAGE);
+ } catch (EditException ex) {
+ logger.warn("Could not set list handling", ex);
+ JOptionPane.showMessageDialog(owner,
+ "Can't set list handling",
+ "An error occured when setting list handling: "
+ + ex.getMessage(),
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+
+ private final class ResetAction extends AbstractAction {
+ private final IterationStrategyEditorControl strategyEditorControl;
+
+ private ResetAction(
+ IterationStrategyEditorControl strategyEditorControl) {
+ super("Reset");
+ this.strategyEditorControl = strategyEditorControl;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ workingStack = IterationStrategyContextualView.copyIterationStrategyStack(originalStack);
+ strategyEditorControl
+ .setIterationStrategy(IterationStrategyContextualView.getIterationStrategy(workingStack));
+ }
+
+ }
+
+ private final class CancelAction extends AbstractAction {
+ private final JDialog dialog;
+
+ private CancelAction(JDialog dialog) {
+ super("Cancel");
+ this.dialog = dialog;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ dialog.setVisible(false);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/contextview/IterationStrategyContextualView.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/contextview/IterationStrategyContextualView.java b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/contextview/IterationStrategyContextualView.java
new file mode 100644
index 0000000..369bea4
--- /dev/null
+++ b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/contextview/IterationStrategyContextualView.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * 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.iterationstrategy.contextview;
+
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JComponent;
+
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.helper.HelpEnabledDialog;
+import net.sf.taverna.t2.workbench.iterationstrategy.editor.IterationStrategyTree;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workflowmodel.Processor;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.IterationStrategy;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.IterationStrategyStack;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.impl.IterationStrategyImpl;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.impl.IterationStrategyStackImpl;
+
+import org.apache.log4j.Logger;
+import org.jdom.Content;
+import org.jdom.Element;
+import org.jdom.filter.ElementFilter;
+
+/**
+ * Contextual view of an {@link IterationStrategyStack}.
+ *
+ * @author Stian Soiland-Reyes
+ *
+ */
+public class IterationStrategyContextualView extends ContextualView {
+
+ private static Logger logger = Logger
+ .getLogger(IterationStrategyContextualView.class);
+
+ private EditManager editManager;
+
+ private FileManager fileManager;
+
+ private IterationStrategyStack iterationStack;
+
+ private final Processor processor;
+
+ private IterationStrategyTree strategyTree = new IterationStrategyTree();
+
+ static {
+
+// This should be enabled and modified for T2-822
+/* editManager.addObserver(new Observer<EditManagerEvent> () {
+
+ private void examineEdit(Edit edit) {
+ if (edit instanceof ConnectDatalinkEdit) {
+ processConnectDatalinkEdit((ConnectDatalinkEdit) edit);
+ }
+ if (edit instanceof CompoundEdit) {
+ processCompoundEdit((CompoundEdit) edit);
+ }
+ }
+
+ private void processConnectDatalinkEdit(ConnectDatalinkEdit edit) {
+ Datalink d = ((ConnectDatalinkEdit) edit).getSubject();
+ EventHandlingInputPort sink = d.getSink();
+ if (sink instanceof ProcessorInputPort) {
+ ProcessorInputPort pip = (ProcessorInputPort) sink;
+ Processor p = pip.getProcessor();
+ final HelpEnabledDialog dialog = new IterationStrategyConfigurationDialog(null, p, copyIterationStrategyStack(p.getIterationStrategy()));
+ dialog.setVisible(true);
+ }
+ }
+
+ private void processCompoundEdit(CompoundEdit edit) {
+ for (Edit e : edit.getChildEdits()) {
+ examineEdit(e);
+ }
+ }
+
+ @Override
+ public void notify(Observable<EditManagerEvent> sender,
+ EditManagerEvent message) throws Exception {
+ if (!(message instanceof DataflowEditEvent)) {
+ return;
+ }
+ examineEdit(message.getEdit());
+ }});*/
+ }
+
+ public IterationStrategyContextualView(Processor processor, EditManager editManager, FileManager fileManager) {
+ if (processor == null || processor.getIterationStrategy() == null) {
+ throw new NullPointerException(
+ "Iteration strategy stack can't be null");
+ }
+ this.processor = processor;
+ this.editManager = editManager;
+ this.fileManager = fileManager;
+ refreshIterationStrategyStack();
+ initView();
+ }
+
+ @Override
+ public Action getConfigureAction(final Frame owner) {
+ return new ConfigureIterationStrategyAction(owner);
+ }
+
+ public Processor getProcessor() {
+ return processor;
+ }
+
+ @Override
+ public void refreshView() {
+ refreshIterationStrategyStack();
+ strategyTree.setIterationStrategy(getIterationStrategy(iterationStack));
+ }
+
+ public static IterationStrategyStack copyIterationStrategyStack(
+ IterationStrategyStack stack) {
+ Element asXML = ((IterationStrategyStackImpl)stack).asXML();
+ stripEmptyElements(asXML);
+ IterationStrategyStackImpl copyStack = new IterationStrategyStackImpl();
+ copyStack.configureFromElement(asXML);
+ if (copyStack.getStrategies().isEmpty()) {
+ copyStack.addStrategy(new IterationStrategyImpl());
+ }
+ return copyStack;
+ }
+
+ private static void stripEmptyElements(Element asXML) {
+ int childCount = asXML.getContent().size();
+ int index = 0;
+ while (index < childCount) {
+ Content child = asXML.getContent(index);
+ if (child instanceof Element) {
+ Element childElement = (Element) child;
+ if (childElement.getName().equals("port")) {
+ index++;
+ }
+ else if (childElement.getDescendants(new ElementFilter("port")).hasNext()) {
+ stripEmptyElements(childElement);
+ index++;
+ } else {
+ asXML.removeContent(childElement);
+ childCount--;
+ }
+ }
+ }
+ }
+
+ public static IterationStrategy getIterationStrategy(IterationStrategyStack iStack) {
+ List<? extends IterationStrategy> strategies = iStack
+ .getStrategies();
+ if (strategies.isEmpty()) {
+ throw new IllegalStateException("Empty iteration stack");
+ }
+ IterationStrategy strategy = strategies.get(0);
+ if (!(strategy instanceof IterationStrategyImpl)) {
+ throw new IllegalStateException(
+ "Can't edit unknown iteration strategy implementation "
+ + strategy);
+ }
+ return (IterationStrategyImpl) strategy;
+ }
+
+ private void refreshIterationStrategyStack() {
+ IterationStrategyStack originalIterationStrategy = processor
+ .getIterationStrategy();
+ if (!(originalIterationStrategy instanceof IterationStrategyStackImpl)) {
+ throw new IllegalStateException(
+ "Unknown iteration strategy implementation "
+ + originalIterationStrategy);
+ }
+ this.iterationStack = copyIterationStrategyStack((IterationStrategyStackImpl) originalIterationStrategy);
+ }
+
+ @Override
+ public JComponent getMainFrame() {
+ refreshView();
+ return strategyTree;
+ }
+
+ @Override
+ public String getViewTitle() {
+ return "List handling";
+ }
+
+ private final class ConfigureIterationStrategyAction extends AbstractAction {
+ private final Frame owner;
+
+ private ConfigureIterationStrategyAction(Frame owner) {
+ super("Configure");
+ this.owner = owner;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ final HelpEnabledDialog dialog = new IterationStrategyConfigurationDialog(owner, processor, iterationStack, editManager, fileManager);
+ dialog.setVisible(true);
+ refreshView();
+ }
+
+
+
+ }
+
+ @Override
+ public int getPreferredPosition() {
+ return 200;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/contextview/IterationStrategyContextualViewFactory.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/contextview/IterationStrategyContextualViewFactory.java b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/contextview/IterationStrategyContextualViewFactory.java
new file mode 100644
index 0000000..a970239
--- /dev/null
+++ b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/contextview/IterationStrategyContextualViewFactory.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.iterationstrategy.contextview;
+
+import java.util.Arrays;
+import java.util.List;
+
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView;
+import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
+import net.sf.taverna.t2.workflowmodel.Processor;
+
+public class IterationStrategyContextualViewFactory implements
+ ContextualViewFactory<Processor> {
+
+ private EditManager editManager;
+ private FileManager fileManager;
+
+ public boolean canHandle(Object selection) {
+ return selection instanceof Processor;
+ }
+
+ public List<ContextualView> getViews(Processor p) {
+ return Arrays.asList(new ContextualView[] {new IterationStrategyContextualView(p, editManager, fileManager)});
+ }
+
+ public void setEditManager(EditManager editManager) {
+ this.editManager = editManager;
+ }
+
+ public void setFileManager(FileManager fileManager) {
+ this.fileManager = fileManager;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyCellRenderer.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyCellRenderer.java b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyCellRenderer.java
new file mode 100644
index 0000000..4c31574
--- /dev/null
+++ b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyCellRenderer.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.iterationstrategy.editor;
+
+import java.awt.Component;
+
+import javax.swing.JTree;
+import javax.swing.tree.DefaultTreeCellRenderer;
+
+import net.sf.taverna.t2.workbench.icons.WorkbenchIcons;
+import net.sf.taverna.t2.workbench.iterationstrategy.IterationStrategyIcons;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.CrossProduct;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.DotProduct;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.NamedInputPortNode;
+
+import org.apache.log4j.Logger;
+
+@SuppressWarnings("serial")
+final class IterationStrategyCellRenderer extends DefaultTreeCellRenderer {
+
+ @SuppressWarnings("unused")
+ private static Logger logger = Logger
+ .getLogger(IterationStrategyCellRenderer.class);
+
+ @Override
+ public Component getTreeCellRendererComponent(JTree tree, Object value,
+ boolean selected, boolean expanded, boolean leaf, int row,
+ boolean hasFocus) {
+ super.getTreeCellRendererComponent(tree, value, selected, expanded,
+ leaf, row, hasFocus);
+ if (value instanceof CrossProduct) {
+ setIcon(IterationStrategyIcons.joinIteratorIcon);
+ setText("Cross product");
+ } else if (value instanceof DotProduct) {
+ setIcon(IterationStrategyIcons.lockStepIteratorIcon);
+ setText("Dot product");
+ } else if (value instanceof NamedInputPortNode) {
+ setIcon(IterationStrategyIcons.leafnodeicon);
+ NamedInputPortNode namedInput = (NamedInputPortNode) value;
+ setText(namedInput.getPortName());
+ } else {
+ setText("List handling");
+ if (!leaf){
+ if (expanded) {
+ setIcon(WorkbenchIcons.folderOpenIcon);
+ } else {
+ setIcon(WorkbenchIcons.folderClosedIcon);
+ }
+ }
+ }
+ return this;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyEditor.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyEditor.java b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyEditor.java
new file mode 100644
index 0000000..add5201
--- /dev/null
+++ b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyEditor.java
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ * 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.iterationstrategy.editor;
+
+import java.awt.GraphicsEnvironment;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+//import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+import javax.swing.DropMode;
+import javax.swing.JComponent;
+import javax.swing.JTree;
+import javax.swing.TransferHandler;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.TreeSelectionModel;
+
+import net.sf.taverna.t2.workbench.ui.zaria.UIComponentSPI;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.AbstractIterationStrategyNode;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.IterationStrategy;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.NamedInputPortNode;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.TerminalNode;
+
+import org.apache.log4j.Logger;
+
+@SuppressWarnings("serial")
+public class IterationStrategyEditor extends IterationStrategyTree implements
+ UIComponentSPI {
+
+ private static Logger logger = Logger
+ .getLogger(IterationStrategyEditor.class);
+
+ //private BufferedImage imgGhost; // The 'drag image'
+
+ // mouse was clicked
+
+ public IterationStrategyEditor() {
+ super();
+ // Make this a drag source
+ if (!GraphicsEnvironment.isHeadless()) {
+ this.setDragEnabled(true);
+ this.setDropMode(DropMode.ON_OR_INSERT);
+ this.setTransferHandler(new TreeTransferHandler());
+ this.getSelectionModel().setSelectionMode(
+ TreeSelectionModel.CONTIGUOUS_TREE_SELECTION);
+ expandTree();
+ }
+
+ //
+ }
+
+ public IterationStrategyEditor(IterationStrategy theStrategy) {
+ this();
+ setIterationStrategy(theStrategy);
+ }
+
+ /**
+ *
+ * This code is freely adapted from code derived
+ *
+ */
+ class TreeTransferHandler extends TransferHandler {
+ DataFlavor nodesFlavor;
+ DataFlavor[] flavors = new DataFlavor[1];
+
+ public TreeTransferHandler() {
+ getNodesFlavor();
+ }
+
+ private DataFlavor getNodesFlavor() {
+ if (nodesFlavor == null) {
+ try {
+ nodesFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType +
+ ";class=" + AbstractIterationStrategyNode.class.getName(),
+ "AbstractIterationStrategyNode",
+ this.getClass().getClassLoader());
+ flavors[0] = nodesFlavor;
+ } catch(Exception e) {
+ logger.error("Problem creating nodesFlavor:" + e);
+ }
+ }
+ return nodesFlavor;
+ }
+
+ public boolean canImport(TransferHandler.TransferSupport support) {
+ if(!support.isDrop()) {
+ logger.error("isDrop not supported");
+ return false;
+ }
+
+ if(!support.isDataFlavorSupported(getNodesFlavor())) {
+ logger.info("Not correct flavor");
+ return false;
+ }
+ // Do not allow a drop on the drag source selections.
+ JTree.DropLocation dl =
+ (JTree.DropLocation)support.getDropLocation();
+ TreePath dest = dl.getPath();
+ AbstractIterationStrategyNode destination =
+ (AbstractIterationStrategyNode)dest.getLastPathComponent();
+ Transferable t = support.getTransferable();
+ if (destination instanceof TerminalNode) {
+ return false;
+ }
+ try {
+ AbstractIterationStrategyNode node = (AbstractIterationStrategyNode) t.getTransferData(getNodesFlavor());
+ if (node.isNodeDescendant(destination)) {
+ return false;
+ }
+ } catch (UnsupportedFlavorException e) {
+ return false;
+ } catch (IOException e) {
+ return false;
+ }
+// JTree tree = (JTree) support.getComponent();
+// int dropRow = tree.getRowForPath(dl.getPath());
+// int selRow = tree.getLeadSelectionRow();
+// if (selRow == dropRow) {
+// logger.info("Dragging to source");
+// return false;
+//
+// }
+ support.setShowDropLocation(true);
+ return true;
+ }
+
+ protected Transferable createTransferable(JComponent c) {
+ JTree tree = (JTree)c;
+ TreePath[] paths = tree.getSelectionPaths();
+ if(paths != null) {
+ AbstractIterationStrategyNode node =
+ (AbstractIterationStrategyNode)paths[0].getLastPathComponent();
+ return new NodeTransferable(node);
+ }
+ return null;
+ }
+
+ protected void exportDone(JComponent source, Transferable data, int action) {
+ }
+
+ public int getSourceActions(JComponent c) {
+ return MOVE;
+ }
+
+ public boolean importData(TransferHandler.TransferSupport support) {
+ if(!canImport(support)) {
+ logger.info("Cannot import");
+ return false;
+ }
+ // Extract transfer data.
+ AbstractIterationStrategyNode node = null;
+ try {
+ Transferable t = support.getTransferable();
+ node = (AbstractIterationStrategyNode) t.getTransferData(getNodesFlavor());
+ } catch(UnsupportedFlavorException ufe) {
+ logger.error("UnsupportedFlavor", ufe);
+ } catch (Exception e) {
+ logger.error("Problem getting transfer data", e);
+ }
+
+ // Get drop location info.
+ JTree.DropLocation dl =
+ (JTree.DropLocation)support.getDropLocation();
+ int childIndex = dl.getChildIndex();
+ TreePath dest = dl.getPath();
+ AbstractIterationStrategyNode parent =
+ (AbstractIterationStrategyNode)dest.getLastPathComponent();
+ int index = childIndex;
+ logger.info ("parent is a " + parent.getClass().getName());
+ if (parent instanceof NamedInputPortNode) {
+ AbstractIterationStrategyNode sibling = parent;
+ parent = (AbstractIterationStrategyNode) sibling.getParent();
+ index = parent.getIndex(sibling);
+ } else if (index == -1) {
+ index = parent.getChildCount();
+ }
+ if (parent instanceof TerminalNode) {
+ if (parent.getChildCount() > 0) {
+ parent = (AbstractIterationStrategyNode) parent.getChildAt(0);
+ index = parent.getChildCount();
+ }
+
+ }
+ logger.info("parent is a " + parent.getClass().getName());
+
+ try {
+ // The parent insert removes from the oldParent
+ parent.insert(node, index++);
+ DefaultTreeModel model = IterationStrategyEditor.this
+ .getModel();
+ refreshModel();
+ } catch (IllegalStateException e) {
+ logger.error(e);
+ } catch (IllegalArgumentException e) {
+ logger.error(e);
+ }
+ return true;
+ }
+
+ public String toString() {
+ return getClass().getName();
+ }
+
+ public class NodeTransferable implements Transferable {
+ AbstractIterationStrategyNode node;
+
+ public NodeTransferable(AbstractIterationStrategyNode node) {
+ this.node = node;
+ }
+
+ public AbstractIterationStrategyNode getTransferData(DataFlavor flavor)
+ throws UnsupportedFlavorException {
+ if(!isDataFlavorSupported(flavor))
+ throw new UnsupportedFlavorException(flavor);
+ return node;
+ }
+
+ public DataFlavor[] getTransferDataFlavors() {
+ return flavors;
+ }
+
+ public boolean isDataFlavorSupported(DataFlavor flavor) {
+ return getNodesFlavor().equals(flavor);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyEditorControl.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyEditorControl.java b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyEditorControl.java
new file mode 100644
index 0000000..c745283
--- /dev/null
+++ b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyEditorControl.java
@@ -0,0 +1,439 @@
+/*******************************************************************************
+ * 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
+ ******************************************************************************/
+/**
+ * This file is a component of the Taverna project,
+ * and is licensed under the GNU LGPL.
+ * Copyright Tom Oinn, EMBL-EBI
+ */
+package net.sf.taverna.t2.workbench.iterationstrategy.editor;
+
+import java.awt.event.ActionEvent;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JToolBar;
+import javax.swing.SwingConstants;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+
+import net.sf.taverna.t2.workbench.icons.WorkbenchIcons;
+import net.sf.taverna.t2.workbench.iterationstrategy.IterationStrategyIcons;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.CrossProduct;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.DotProduct;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.IterationStrategy;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.IterationStrategyNode;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.TerminalNode;
+
+import org.apache.log4j.Logger;
+
+/**
+ * A control panel for the iteration tree editor allowing the user to manipulate
+ * the tree, removing and adding nodes into the tree based on the context.
+ *
+ * @author Tom Oinn
+ * @author Stian Soiland-Reyes
+ *
+ */
+@SuppressWarnings("serial")
+public class IterationStrategyEditorControl extends JPanel {
+
+ protected static Set<IterationStrategyNode> descendentsOfNode(
+ IterationStrategyNode node) {
+ Set<IterationStrategyNode> descendants = new HashSet<IterationStrategyNode>();
+ Set<IterationStrategyNode> nodesToVisit = new HashSet<IterationStrategyNode>();
+ Set<IterationStrategyNode> visitedNodes = new HashSet<IterationStrategyNode>();
+
+ // Note: Not added to descendants
+ nodesToVisit.add(node);
+ while (!nodesToVisit.isEmpty()) {
+ // pick the first one
+ IterationStrategyNode visiting = nodesToVisit.iterator().next();
+ visitedNodes.add(visiting);
+ nodesToVisit.remove(visiting);
+
+ // Find new and interesting children
+ List<IterationStrategyNode> children = visiting.getChildren();
+ Set<IterationStrategyNode> newNodes = new HashSet<IterationStrategyNode>(
+ children);
+ newNodes.removeAll(visitedNodes);
+
+ descendants.addAll(newNodes);
+ nodesToVisit.addAll(newNodes);
+ }
+ return descendants;
+ }
+
+ private static Logger logger = Logger
+ .getLogger(IterationStrategyEditorControl.class);
+
+ private IterationStrategyNode selectedNode = null;
+
+ private IterationStrategyTree tree;
+
+ protected AddCrossAction addCross = new AddCrossAction();
+ protected AddDotAction addDot = new AddDotAction();
+ protected ChangeAction change = new ChangeAction();
+ protected NormalizeAction normalize = new NormalizeAction();
+ protected RemoveAction remove = new RemoveAction();
+ protected MoveUpAction moveUp = new MoveUpAction();
+
+ //private static final int ICON_SIZE = 15;
+
+ protected ImageIcon arrowUpIcon = WorkbenchIcons.upArrowIcon;
+ protected ImageIcon arrowDownIcon = WorkbenchIcons.downArrowIcon;
+ //protected ImageIcon arrowLeft = WorkbenchIcons.leftArrowIcon;
+ //protected ImageIcon arrowRight = WorkbenchIcons.rightArrowIcon;
+ protected ImageIcon normalizeIcon = WorkbenchIcons.normalizeIcon;
+
+ private final IterationStrategy strategy;
+
+ /**
+ * Create a new panel from the supplied iteration strategy
+ */
+ public IterationStrategyEditorControl(IterationStrategy strategy) {
+
+ this.strategy = strategy;
+ setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
+
+ // Create the components
+ tree = new IterationStrategyEditor(strategy);
+
+ JButton addCrossButton = new JButton(addCross);
+ addCrossButton.setHorizontalAlignment(SwingConstants.LEFT);
+ JButton addDotButton = new JButton(addDot);
+ addDotButton.setHorizontalAlignment(SwingConstants.LEFT);
+ JButton normalizeButton = new JButton(normalize);
+ normalizeButton.setHorizontalAlignment(SwingConstants.LEFT);
+ normalizeButton.setIcon(normalizeIcon);
+ JButton removeButton = new JButton(remove);
+ removeButton.setHorizontalAlignment(SwingConstants.LEFT);
+ JButton changeButton = new JButton(change);
+ changeButton.setHorizontalAlignment(SwingConstants.LEFT);
+
+ JButton moveUpButton = new JButton(moveUp);
+ moveUpButton.setIcon(arrowUpIcon);
+ moveUpButton.setHorizontalAlignment(SwingConstants.LEFT);
+
+ // Set the default enabled state to off on all buttons other than the
+ // normalizeButton
+ // one.
+ disableButtons();
+
+ // Create a layout with the tree on the right and the buttons in a grid
+ // layout on the left
+ JToolBar toolbar = new JToolBar();
+ toolbar.setFloatable(false);
+ toolbar.setRollover(true);
+ // toolbar.setLayout(new GridLayout(2,2));
+ toolbar.add(normalizeButton);
+ toolbar.add(addCrossButton);
+ toolbar.add(addDotButton);
+ toolbar.add(removeButton);
+ toolbar.add(changeButton);
+ toolbar.add(moveUpButton);
+
+ toolbar.setAlignmentX(LEFT_ALIGNMENT);
+
+ // Listen to tree selection events and enable buttons appropriately
+ tree.addTreeSelectionListener(new ButtonEnabler());
+
+ // Add components to the control panel
+ add(toolbar);
+ JScrollPane treePane = new JScrollPane(tree);
+ //treePane.setPreferredSize(new Dimension(0, 0));
+ add(treePane);
+ }
+
+ public void setIterationStrategy(IterationStrategy iterationStrategy) {
+ tree.setIterationStrategy(iterationStrategy);
+ disableButtons();
+ selectNode(null);
+ }
+
+ private void disableButtons() {
+ remove.setEnabled(false);
+ addCross.setEnabled(false);
+ addDot.setEnabled(false);
+ change.setEnabled(false);
+ }
+
+ private IterationStrategyNode findRoot() {
+ IterationStrategyNode root = (IterationStrategyNode) tree.getModel()
+ .getRoot();
+ if (root.getChildCount() > 0) {
+ return root.getChildAt(0);
+ }
+ return root;
+ }
+
+ protected void selectNode(TreeNode newNode) {
+ DefaultTreeModel model = tree.getModel();
+ if (newNode == null) {
+ newNode = (TreeNode) model.getRoot();
+ }
+ TreeNode[] pathToRoot = model.getPathToRoot(newNode);
+ tree.setSelectionPath(new TreePath(pathToRoot));
+ }
+
+ /**
+ * Add a cross product node as a child of the selected node
+ */
+ protected class AddCrossAction extends AbstractAction {
+
+ public AddCrossAction() {
+ super("Add Cross", IterationStrategyIcons.joinIteratorIcon);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ CrossProduct newNode = new CrossProduct();
+ newNode.setParent(selectedNode);
+ tree.refreshModel();
+ }
+ }
+
+ /**
+ * Add a dot product node as a child of the selected node
+ *
+ * @author Stian Soiland-Reyes
+ *
+ */
+ protected class AddDotAction extends AbstractAction {
+
+ public AddDotAction() {
+ super("Add Dot", IterationStrategyIcons.lockStepIteratorIcon);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ DotProduct newNode = new DotProduct();
+ newNode.setParent(selectedNode);
+ tree.refreshModel();
+ }
+ }
+
+ protected class ButtonEnabler implements TreeSelectionListener {
+ public void valueChanged(TreeSelectionEvent e) {
+ TreePath selectedPath = e.getPath();
+ IterationStrategyNode selectedObject = (IterationStrategyNode) selectedPath
+ .getLastPathComponent();
+ selectedNode = selectedObject;
+ if (selectedObject instanceof CrossProduct
+ || selectedObject instanceof DotProduct) {
+ if ((selectedObject.getParent() == null) || (selectedObject.getParent() instanceof TerminalNode)) {
+ remove.setEnabled(false);
+ } else {
+ remove.setEnabled(true);
+ }
+ if (selectedObject instanceof CrossProduct) {
+ change.putValue(Action.NAME, "Change to Dot Product");
+ change.putValue(Action.SMALL_ICON,
+ IterationStrategyIcons.lockStepIteratorIcon);
+ } else {
+ change.putValue(Action.NAME, "Change to Cross Product");
+ change.putValue(Action.SMALL_ICON,
+ IterationStrategyIcons.joinIteratorIcon);
+ }
+ addCross.setEnabled(true);
+ addDot.setEnabled(true);
+ change.setEnabled(true);
+ } else {
+ // Top- or leaf node
+ remove.setEnabled(false);
+ addCross.setEnabled(false);
+ addDot.setEnabled(false);
+ change.setEnabled(false);
+ }
+ }
+ }
+
+ /**
+ * Add a cross product node as a child of the selected node
+ */
+ protected class ChangeAction extends AbstractAction {
+
+ public ChangeAction() {
+ super("Switch to...", IterationStrategyIcons.joinIteratorIcon);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ IterationStrategyNode newNode;
+ if (selectedNode instanceof CrossProduct) {
+ newNode = new DotProduct();
+ } else {
+ newNode = new CrossProduct();
+ }
+
+ List<IterationStrategyNode> children = new ArrayList<IterationStrategyNode>(
+ selectedNode.getChildren());
+ for (IterationStrategyNode child : children) {
+ child.setParent(newNode);
+ }
+
+ DefaultTreeModel model = tree.getModel();
+ if (selectedNode.getParent() == null) {
+ model.setRoot(newNode);
+ tree.refreshModel();
+ newNode.setParent(null);
+ } else {
+ IterationStrategyNode parent = selectedNode.getParent();
+ int index = parent.getIndex(selectedNode);
+ selectedNode.setParent(null);
+ parent.insert(newNode, index);
+ tree.refreshModel();
+ }
+
+ selectNode(newNode);
+ }
+
+ }
+
+ /**
+ * Normalize the tree when the button is pressed
+ *
+ */
+ protected class NormalizeAction extends AbstractAction {
+ public NormalizeAction() {
+ super("Normalize", normalizeIcon);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ strategy.normalize();
+ // Expand all the nodes in the tree
+ //DefaultTreeModel model = tree.getModel();
+ tree.refreshModel();
+ }
+ }
+
+ /**
+ * Remove the selected node, moving any descendant leaf nodes to the parent
+ * to prevent them getting lost
+ */
+ protected class RemoveAction extends AbstractAction {
+ public RemoveAction() {
+ super("Remove node", WorkbenchIcons.deleteIcon);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ IterationStrategyNode nodeToBeRemoved = selectedNode;
+
+ //DefaultTreeModel model = tree.getModel();
+
+ // Now removeButton the candidate nodes from their parents and
+ // put them back into the root node
+ IterationStrategyNode root = findRoot();
+ if (root == selectedNode) {
+ return;
+ }
+ IterationStrategyNode oldParent = nodeToBeRemoved.getParent();
+
+ for (IterationStrategyNode nodeToMove : descendentsOfNode(nodeToBeRemoved)) {
+ nodeToMove.setParent(oldParent);
+ }
+ nodeToBeRemoved.setParent(null);
+ tree.refreshModel();
+ // Disable the various buttons, as the current selection
+ // is now invalid.
+ remove.setEnabled(false);
+ addCross.setEnabled(false);
+ addDot.setEnabled(false);
+ change.setEnabled(false);
+ selectNode(oldParent);
+ }
+ }
+
+ protected class MoveUpAction extends AbstractAction {
+
+ public MoveUpAction() {
+ super("Move up", arrowUpIcon);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ //DefaultTreeModel model = tree.getModel();
+
+ IterationStrategyNode aboveNode = aboveSelectedNode();
+ if ((aboveNode == null) || ((aboveNode instanceof TerminalNode) && (aboveNode.getChildCount() > 0))) {
+ logger.warn("Can't move above top");
+ return;
+ }
+ IterationStrategyNode selectedParent = selectedNode.getParent();
+ IterationStrategyNode aboveParent = aboveNode.getParent();
+ if (selectedParent != null && selectedParent.equals(aboveParent)) {
+ // Siblings
+ int aboveChildIndex = selectedParent.getIndex(aboveNode);
+ selectedParent.insert(selectedNode, aboveChildIndex);
+ tree.refreshModel();
+ selectNode(selectedNode);
+ } else if (aboveNode.equals(selectedParent)) {
+ if (aboveParent instanceof TerminalNode
+ && selectedNode.getAllowsChildren()) {
+ aboveNode.setParent(selectedNode);
+ selectedNode.setParent(aboveParent);
+ tree.refreshModel();
+ selectNode(selectedNode);
+ } else if (!(aboveParent instanceof TerminalNode)){
+ int aboveChildIndex = aboveParent.getIndex(aboveNode);
+ aboveParent.insert(selectedNode, aboveChildIndex);
+ tree.refreshModel();
+ selectNode(selectedNode);
+ }
+ } else {
+
+ }
+
+ }
+
+ }
+
+ protected IterationStrategyNode belowSelectedNode() {
+ return offsetFromSelectedNode(1);
+ }
+
+ protected IterationStrategyNode offsetFromSelectedNode(int offset) {
+ int currentRow = tree.getRowForPath(tree.getSelectionPath());
+ int offsetRow = currentRow + offset;
+ TreePath offsetPath = tree.getPathForRow(offsetRow);
+ if (offsetPath == null) {
+ return null;
+ }
+ IterationStrategyNode offsetNode = (IterationStrategyNode) offsetPath
+ .getLastPathComponent();
+ if (offsetNode == tree.getModel().getRoot()) {
+ return null;
+ }
+ return offsetNode;
+ }
+
+ protected IterationStrategyNode aboveSelectedNode() {
+ return offsetFromSelectedNode(-1);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyTree.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyTree.java b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyTree.java
new file mode 100644
index 0000000..c4665c6
--- /dev/null
+++ b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/editor/IterationStrategyTree.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * 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.iterationstrategy.editor;
+
+import java.util.Enumeration;
+
+import javax.swing.ImageIcon;
+import javax.swing.JTree;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.TreeSelectionModel;
+
+import net.sf.taverna.t2.workbench.iterationstrategy.IterationStrategyIcons;
+import net.sf.taverna.t2.workbench.ui.zaria.UIComponentSPI;
+import net.sf.taverna.t2.workflowmodel.processor.iteration.IterationStrategy;
+
+@SuppressWarnings("serial")
+public class IterationStrategyTree extends JTree implements UIComponentSPI {
+
+ private IterationStrategy strategy = null;
+
+ public IterationStrategyTree() {
+ super();
+ setCellRenderer(new IterationStrategyCellRenderer());
+ }
+
+ public ImageIcon getIcon() {
+ return IterationStrategyIcons.leafnodeicon;
+ }
+
+ public void onDisplay() {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void onDispose() {
+ this.strategy = null;
+ setModel(null);
+ }
+
+ public synchronized void setIterationStrategy(
+ IterationStrategy theStrategy) {
+ if (theStrategy != this.strategy) {
+ this.strategy = theStrategy;
+ TreeNode terminal = theStrategy.getTerminalNode();
+ setModel(new DefaultTreeModel(terminal));
+ this.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+ expandTree();
+ revalidate();
+ }
+ }
+
+ protected synchronized void refreshModel() {
+ this.getModel().nodeStructureChanged(strategy.getTerminalNode());
+ expandTree();
+ }
+
+ @Override
+ public DefaultTreeModel getModel() {
+ return (DefaultTreeModel) super.getModel();
+ }
+
+ @Override
+ public void setModel(TreeModel newModel) {
+ if (newModel != null && !(newModel instanceof DefaultTreeModel)) {
+ throw new IllegalArgumentException(
+ "Model must be a DefaultTreeModel");
+ }
+ super.setModel(newModel);
+ }
+
+ protected void expandTree() {
+ DefaultMutableTreeNode root =
+ (DefaultMutableTreeNode)this.getModel().getRoot();
+ Enumeration e = root.breadthFirstEnumeration();
+ while(e.hasMoreElements()) {
+ DefaultMutableTreeNode node =
+ (DefaultMutableTreeNode)e.nextElement();
+ if(node.isLeaf()) continue;
+ int row = this.getRowForPath(new TreePath(node.getPath()));
+ this.expandRow(row);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/menu/IterationStrategyConfigureMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/menu/IterationStrategyConfigureMenuAction.java b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/menu/IterationStrategyConfigureMenuAction.java
new file mode 100644
index 0000000..f8c7f73
--- /dev/null
+++ b/taverna-workbench-iteration-strategy-ui/src/main/java/net/sf/taverna/t2/workbench/iterationstrategy/menu/IterationStrategyConfigureMenuAction.java
@@ -0,0 +1,65 @@
+/**********************************************************************
+ * Copyright (C) 2007-2009 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ **********************************************************************/
+package net.sf.taverna.t2.workbench.iterationstrategy.menu;
+
+import java.awt.event.ActionEvent;
+import java.net.URI;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+
+import net.sf.taverna.t2.ui.menu.AbstractContextualMenuAction;
+import net.sf.taverna.t2.workbench.helper.HelpEnabledDialog;
+import net.sf.taverna.t2.workbench.iterationstrategy.contextview.IterationStrategyConfigurationDialog;
+import net.sf.taverna.t2.workbench.iterationstrategy.contextview.IterationStrategyContextualView;
+import net.sf.taverna.t2.workflowmodel.Processor;
+
+public class IterationStrategyConfigureMenuAction extends AbstractContextualMenuAction {
+
+
+
+ public static final URI configureRunningSection = URI
+ .create("http://taverna.sf.net/2009/contextMenu/configureRunning");
+
+ private static final URI ITERATION_STRATEGY_CONFIGURE_URI = URI
+ .create("http://taverna.sf.net/2008/t2workbench/iterationStrategyConfigure");
+
+ public IterationStrategyConfigureMenuAction() {
+ super(configureRunningSection, 40, ITERATION_STRATEGY_CONFIGURE_URI);
+ }
+
+ @SuppressWarnings("serial")
+ @Override
+ protected Action createAction() {
+ return new AbstractAction("List handling...") {
+ public void actionPerformed(ActionEvent e) {
+ Processor p = (Processor) getContextualSelection().getSelection();
+ final HelpEnabledDialog dialog = new IterationStrategyConfigurationDialog(null, p, IterationStrategyContextualView.copyIterationStrategyStack(p.getIterationStrategy()));
+ dialog.setVisible(true);
+ }
+ };
+ }
+
+ public boolean isEnabled() {
+ return super.isEnabled() && (getContextualSelection().getSelection() instanceof Processor);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-iteration-strategy-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
----------------------------------------------------------------------
diff --git a/taverna-workbench-iteration-strategy-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent b/taverna-workbench-iteration-strategy-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
new file mode 100644
index 0000000..6f25f4e
--- /dev/null
+++ b/taverna-workbench-iteration-strategy-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
@@ -0,0 +1 @@
+net.sf.taverna.t2.workbench.iterationstrategy.menu.IterationStrategyConfigureMenuAction
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/8c4b365e/taverna-workbench-iteration-strategy-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
----------------------------------------------------------------------
diff --git a/taverna-workbench-iteration-strategy-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory b/taverna-workbench-iteration-strategy-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
new file mode 100644
index 0000000..a6a27b0
--- /dev/null
+++ b/taverna-workbench-iteration-strategy-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
@@ -0,0 +1 @@
+net.sf.taverna.t2.workbench.iterationstrategy.contextview.IterationStrategyContextualViewFactory