http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopConfigureMenuAction.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopConfigureMenuAction.java b/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopConfigureMenuAction.java deleted file mode 100644 index caf77f5..0000000 --- a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopConfigureMenuAction.java +++ /dev/null @@ -1,97 +0,0 @@ -/********************************************************************** - * 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.loop; - -import java.awt.event.ActionEvent; -import java.net.URI; - -import javax.swing.AbstractAction; -import javax.swing.Action; - -import com.fasterxml.jackson.databind.node.ObjectNode; - -import org.apache.taverna.scufl2.api.core.Processor; - -import net.sf.taverna.t2.ui.menu.AbstractContextualMenuAction; -import net.sf.taverna.t2.workbench.edits.EditManager; -import net.sf.taverna.t2.workbench.file.FileManager; - -public class LoopConfigureMenuAction extends AbstractContextualMenuAction { - - public static final URI configureRunningSection = URI - .create("http://taverna.sf.net/2009/contextMenu/configureRunning"); - - private static final URI LOOP_CONFIGURE_URI = URI - .create("http://taverna.sf.net/2008/t2workbench/loopConfigure"); - - private static final String LOOP_CONFIGURE = "Loop configure"; - - private EditManager editManager; - - private FileManager fileManager; - - public LoopConfigureMenuAction() { - super(configureRunningSection, 20, LOOP_CONFIGURE_URI); - } - - @SuppressWarnings("serial") - @Override - protected Action createAction() { - return new AbstractAction("Looping...") { - public void actionPerformed(ActionEvent e) { - Processor p = (Processor) getContextualSelection().getSelection(); - configureLoopLayer(p, e); - } - }; - } - - public void configureLoopLayer(Processor p, ActionEvent e) { - ObjectNode loopLayer = getLoopLayer(p); - if (loopLayer != null) { - LoopConfigureAction loopConfigureAction = new LoopConfigureAction(null, null, loopLayer, editManager, fileManager); - loopConfigureAction.actionPerformed(e); - } - } - - public static ObjectNode getLoopLayer(Processor p) { - for (DispatchLayer dl : p.getDispatchStack().getLayers()) { - if (dl instanceof Loop) { - result = (Loop) dl; - break; - } - } - return result; - } - - public boolean isEnabled() { - Object selection = getContextualSelection().getSelection(); - return (super.isEnabled() && (selection instanceof Processor) && (getLoopLayer((Processor)selection) != null)); - } - - 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/a9a52bd5/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopContextualView.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopContextualView.java b/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopContextualView.java deleted file mode 100644 index 98223da..0000000 --- a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopContextualView.java +++ /dev/null @@ -1,172 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2008 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.loop; - -import java.awt.Frame; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.util.Properties; - -import javax.swing.Action; -import javax.swing.JComponent; -import javax.swing.JLabel; -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.loop.comparisons.Comparison; -import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView; - -import org.apache.log4j.Logger; - -import org.apache.taverna.scufl2.api.core.Processor; - -/** - * View of a processor, including it's iteration stack, activities, etc. - * - * @author Stian Soiland-Reyes - * - */ -public class LoopContextualView extends ContextualView { - - private static final long serialVersionUID = 1L; - - private static Logger logger = Logger.getLogger(LoopContextualView.class); - - private EditManager editManager; - private FileManager fileManager; - - private Loop loopLayer; - - private JPanel panel; - - private Processor processor; - - public LoopContextualView(Processor processor, EditManager editManager, FileManager fileManager) { - super(); - this.loopLayer = loopLayer; - this.editManager = editManager; - this.fileManager = fileManager; - this.processor = processor; - initialise(); - initView(); - } - - @Override - public Action getConfigureAction(Frame owner) { - return new LoopConfigureAction(owner, this, processor, editManager, fileManager); - } - - @Override - public void refreshView() { - initialise(); - } - - private void initialise() { - if (panel == null) { - panel = new JPanel(); - } else { - panel.removeAll(); - } - panel.setLayout(new GridBagLayout()); - updateUIByConfig(); - } - - @Override - public JComponent getMainFrame() { - return panel; - } - - @Override - public String getViewTitle() { - return "Loop of " + processor.getLocalName(); - } - - protected void updateUIByConfig() { - GridBagConstraints gbc = new GridBagConstraints(); - gbc.gridx = 0; - gbc.gridy = 1; - gbc.weightx = 0.1; - gbc.fill = GridBagConstraints.HORIZONTAL; - - StringBuilder description = new StringBuilder("<html><body>"); - Properties properties = loopLayer.getConfiguration().getProperties(); - if (properties.getProperty(ActivityGenerator.COMPARISON, - ActivityGenerator.CUSTOM_COMPARISON).equals( - ActivityGenerator.CUSTOM_COMPARISON)) { - Activity<?> condition = loopLayer.getConfiguration().getCondition(); - if (condition != null) { - description.append("Looping using custom conditional "); - if (condition instanceof BeanshellActivity) { - String script = ((BeanshellActivity)condition).getConfiguration().getScript(); - if (script != null) { - if (script.length() <= 100) { - description.append("<pre>\n"); - description.append(script); - description.append("</pre>\n"); - } - } - } - } else { - description.append("<i>Unconfigured, will not loop</i>"); - } - } else { - description.append("The service will be invoked repeatedly "); - description.append("until<br> its output <strong>"); - description.append(properties - .getProperty(ActivityGenerator.COMPARE_PORT)); - description.append("</strong> "); - - Comparison comparison = ActivityGenerator - .getComparisonById(properties - .getProperty(ActivityGenerator.COMPARISON)); - description.append(comparison.getName()); - - description.append(" the " + comparison.getValueType() + ": <pre>"); - description.append(properties - .getProperty(ActivityGenerator.COMPARE_VALUE)); - description.append("</pre>"); - - String delay = properties.getProperty(ActivityGenerator.DELAY, ""); - try { - if (Double.parseDouble(delay) > 0) { - description.append("adding a delay of " + delay - + " seconds between loops."); - } - } catch (NumberFormatException ex) { - } - } - description.append("</body></html>"); - - panel.add(new JLabel(description.toString()), gbc); - gbc.gridy++; - - revalidate(); - } - - - - @Override - public int getPreferredPosition() { - return 400; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopContextualViewFactory.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopContextualViewFactory.java b/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopContextualViewFactory.java deleted file mode 100644 index 7c3451d..0000000 --- a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopContextualViewFactory.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2008 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.loop; - -import java.util.Arrays; -import java.util.List; - -import org.apache.taverna.scufl2.api.core.Processor; - -import net.sf.taverna.t2.workbench.edits.EditManager; -import net.sf.taverna.t2.workbench.file.FileManager; -import net.sf.taverna.t2.workbench.ui.views.contextualviews.ContextualView; -import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory; - -public class LoopContextualViewFactory implements ContextualViewFactory<Processor> { - - private EditManager editManager; - private FileManager fileManager; - - public boolean canHandle(Object selection) { - return selection instanceof Processor; - } - - public List<ContextualView> getViews(Processor selection) { - return Arrays.asList(new ContextualView[] {new LoopContextualView(selection, 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/a9a52bd5/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopRemoveMenuAction.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopRemoveMenuAction.java b/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopRemoveMenuAction.java deleted file mode 100644 index 24a33bc..0000000 --- a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/LoopRemoveMenuAction.java +++ /dev/null @@ -1,92 +0,0 @@ -/********************************************************************** - * 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.loop; - -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.edits.EditManager; -import net.sf.taverna.t2.workbench.file.FileManager; - -import org.apache.log4j.Logger; - -import org.apache.taverna.scufl2.api.core.Processor; - -public class LoopRemoveMenuAction extends AbstractContextualMenuAction { - - private static Logger logger = Logger - .getLogger(LoopRemoveMenuAction.class); - - public static final URI configureRunningSection = URI - .create("http://taverna.sf.net/2009/contextMenu/configureRunning"); - - private static final URI LOOP_REMOVE_URI = URI - .create("http://taverna.sf.net/2008/t2workbench/loopRemove"); - - private static final String LOOP_REMOVE = "Loop remove"; - - public LoopRemoveMenuAction() { - super(configureRunningSection, 25, LOOP_REMOVE_URI); - } - - private EditManager editManager; - private FileManager fileManager; - - - @SuppressWarnings("serial") - @Override - protected Action createAction() { - return new AbstractAction("Disable looping") { - public void actionPerformed(ActionEvent e) { - Processor p = (Processor) getContextualSelection().getSelection(); - Loop loopLayer = LoopConfigureMenuAction.getLoopLayer(p); - Edit<DispatchStack> deleteEdit = editManager.getEdits().getDeleteDispatchLayerEdit( - p.getDispatchStack(), loopLayer); - // TODO: Should warn before removing "essential" layers - try { - editManager.doDataflowEdit(fileManager.getCurrentDataflow(), - deleteEdit); - } catch (EditException ex) { - logger.warn("Could not remove layer " + loopLayer, ex); - } - - } - }; - } - - public boolean isEnabled() { - Object selection = getContextualSelection().getSelection(); - return (super.isEnabled() && (selection instanceof Processor) && (LoopConfigureMenuAction.getLoopLayer((Processor)selection) != null)); - } - - 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/a9a52bd5/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/Comparison.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/Comparison.java b/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/Comparison.java deleted file mode 100644 index 608030c..0000000 --- a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/Comparison.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2008 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.loop.comparisons; - -import net.sf.taverna.t2.workbench.loop.LoopConfigurationPanel; - -/** - * A comparison beanshell template for {@link LoopConfigurationPanel}. - * <p> - * A comparison is a template for generating a beanshell that can be used for - * comparisons in say the {@link Loop} layer. - * - * @author Stian Soiland-Reyes - * - */ -public abstract class Comparison { - - public String toString() { - return getName(); - } - - public abstract String getId(); - - public abstract String getName(); - - public abstract String getValueType(); - - public abstract String getScriptTemplate(); -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/EqualTo.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/EqualTo.java b/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/EqualTo.java deleted file mode 100644 index dbfb8f5..0000000 --- a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/EqualTo.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2008 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.loop.comparisons; - -public class EqualTo extends Comparison { - - public String getId() { - return "EqualTo"; - } - - public String getName() { - return "is equal to"; - } - - public String getScriptTemplate() { - return "${loopPort} = \"\" + ! ${port}.equals(${value}); "; - } - - public String getValueType() { - return "string"; - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/IsGreaterThan.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/IsGreaterThan.java b/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/IsGreaterThan.java deleted file mode 100644 index fc6f56b..0000000 --- a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/IsGreaterThan.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2008 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.loop.comparisons; - -public class IsGreaterThan extends Comparison { - - public String getId() { - return "IsGreaterThan"; - } - - public String getName() { - return "is greater than"; - } - - public String getScriptTemplate() { - return "${loopPort} = \"\" + (! (Double.parseDouble(${port}) > Double.parseDouble(${value})));"; - } - - public String getValueType() { - return "number"; - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/IsLessThan.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/IsLessThan.java b/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/IsLessThan.java deleted file mode 100644 index d5fe38c..0000000 --- a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/IsLessThan.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2008 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.loop.comparisons; - -public class IsLessThan extends Comparison { - - public String getId() { - return "IsLessThan"; - } - - public String getName() { - return "is less than"; - } - - public String getScriptTemplate() { - return "${loopPort} = \"\" + (! (Double.parseDouble(${port}) < Double.parseDouble(${value})));"; - } - - public String getValueType() { - return "number"; - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/Matches.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/Matches.java b/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/Matches.java deleted file mode 100644 index fa84aeb..0000000 --- a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/Matches.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2008 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.loop.comparisons; - -public class Matches extends Comparison { - - public String getId() { - return "Matches"; - } - - public String getName() { - return "matches"; - } - - public String getScriptTemplate() { - return "${loopPort} = \"\" + ! ${port}.matches(${value});"; - } - - public String getValueType() { - return "regular expression"; - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/NotEqualTo.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/NotEqualTo.java b/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/NotEqualTo.java deleted file mode 100644 index 9c73835..0000000 --- a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/NotEqualTo.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2008 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.loop.comparisons; - -public class NotEqualTo extends Comparison { - - public String getId() { - return "NotEqualTo"; - } - - public String getName() { - return "is not equal to"; - } - - public String getScriptTemplate() { - return "${loopPort} = \"\" + ${port}.equals(${value});"; - } - - public String getValueType() { - return "string"; - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/NotMatches.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/NotMatches.java b/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/NotMatches.java deleted file mode 100644 index 803d5d7..0000000 --- a/taverna-loop-ui/src/main/java/net/sf/taverna/t2/workbench/loop/comparisons/NotMatches.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2008 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.loop.comparisons; - -public class NotMatches extends Comparison { - - public String getId() { - return "NotMatches"; - } - - public String getName() { - return "does not match"; - } - - public String getScriptTemplate() { - return "${loopPort} = \"\" + ${port}.matches(${value});"; - } - - public String getValueType() { - return "regular expression"; - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/ActivityGenerator.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/ActivityGenerator.java b/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/ActivityGenerator.java new file mode 100644 index 0000000..1239a2a --- /dev/null +++ b/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/ActivityGenerator.java @@ -0,0 +1,194 @@ +/******************************************************************************* + * Copyright (C) 2008 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 org.apache.taverna.workbench.loop; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.Map.Entry; + +import org.apache.taverna.workbench.loop.comparisons.Comparison; +import org.apache.taverna.workbench.loop.comparisons.EqualTo; +import org.apache.taverna.workbench.loop.comparisons.IsGreaterThan; +import org.apache.taverna.workbench.loop.comparisons.IsLessThan; +import org.apache.taverna.workbench.loop.comparisons.Matches; +import org.apache.taverna.workbench.loop.comparisons.NotEqualTo; +import org.apache.taverna.workbench.loop.comparisons.NotMatches; + +import org.apache.log4j.Logger; + +import org.apache.taverna.scufl2.api.activity.Activity; +import org.apache.taverna.scufl2.api.common.Scufl2Tools; +import org.apache.taverna.scufl2.api.configurations.Configuration; +import org.apache.taverna.scufl2.api.core.Processor; +import org.apache.taverna.scufl2.api.port.InputActivityPort; +import org.apache.taverna.scufl2.api.port.InputProcessorPort; +import org.apache.taverna.scufl2.api.port.OutputActivityPort; +import org.apache.taverna.scufl2.api.port.OutputProcessorPort; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +public class ActivityGenerator { + + private static final String LOOP_PORT = "loop"; + + private static final String SCRIPT = "script"; + + public static URI BEANSHELL_ACTIVITY = URI + .create("http://ns.taverna.org.uk/2010/activity/beanshell"); + + public static URI BEANSHELL_CONFIG = BEANSHELL_ACTIVITY.resolve("#Config"); + + + public static final double DEFAULT_DELAY_S = 0.2; + public static final String COMPARE_PORT = "comparePort"; + public static final String COMPARISON = "comparison"; + public static final String CUSTOM_COMPARISON = "custom"; + public static final String COMPARE_VALUE = "compareValue"; + public static final String IS_FEED_BACK = "isFeedBack"; + public static final String DELAY = "delay"; + + private static Logger logger = Logger.getLogger(ActivityGenerator.class); + private final ObjectNode loopProperties; + private final Processor processorToCompare; + private static Scufl2Tools scufl2Tools = new Scufl2Tools(); + + public ActivityGenerator(ObjectNode configuration, + Processor processorToCompare) { + this.loopProperties = configuration; + this.processorToCompare = processorToCompare; + } + + protected Activity generateActivity() { + Activity beanshell = new Activity(); + beanshell.setType(BEANSHELL_ACTIVITY); + Configuration config = generateBeanshellConfig(beanshell); + // TODO: Where to put the config? + return beanshell; + } + + private Configuration generateBeanshellConfig(Activity beanshell) { + Configuration config = scufl2Tools.createConfigurationFor(beanshell, BEANSHELL_CONFIG); + generateInputPorts(beanshell); + generateOutputPorts(beanshell); + config.getJsonAsObjectNode().put(SCRIPT, generateScript()); + return config; + } + + protected static List<Comparison> comparisons = Arrays.asList( + new EqualTo(), new NotEqualTo(), new Matches(), new NotMatches(), + new IsGreaterThan(), new IsLessThan()); + + protected static Comparison getComparisonById(String id) { + if (id == null || id.isEmpty()) { + return comparisons.get(0); + } + for (Comparison potentialComparison : comparisons) { + if (potentialComparison.getId().equals(id)) { + return potentialComparison; + } + } + return null; + } + + @SuppressWarnings("boxing") + private String generateScript() { + Map<String, String> replacements = new HashMap<String, String>(); + replacements.put("${loopPort}", LOOP_PORT); + replacements.put("${port}", loopProperties.findValue(COMPARE_PORT).asText()); + replacements.put("${value}", beanshellString(loopProperties + .findValue(COMPARE_VALUE).asText())); + + + // as seconds + Double delay = loopProperties.findPath(DELAY).asDouble(DEFAULT_DELAY_S); + // as milliseconds + delay = Math.max(0.0, delay) * 1000; + // as integer (for Thread.sleep) + replacements.put("${delay}", Integer.toString(delay.intValue())); + + String template = getComparisonById( + loopProperties.findValue(COMPARISON).asText()).getScriptTemplate(); + + if (delay > 0.0) { + template += "\nif (\"true\".matches(${loopPort})) {\n"; + template += " Thread.sleep(${delay});\n"; + template += "}"; + } + + String script = template; + for (Entry<String, String> mapping : replacements.entrySet()) { + script = script.replace(mapping.getKey(), mapping.getValue()); + } + return script; + } + + private String beanshellString(String value) { + value = value.replace("\\", "\\\\"); + value = value.replace("\n", "\\n"); + value = value.replace("\"", "\\\""); + return '"' + value + '"'; + } + + private void generateInputPorts(Activity beanshell) { + if (processorToCompare == null) { + return; + } + for (OutputProcessorPort procOut : processorToCompare.getOutputPorts()) { + // Any of the outputs are available to the script, giving + // a custom script that compares multiple outputs a better + // starting point. + String portName = procOut.getName(); + if (portName.equals(loopProperties.findValue(COMPARE_PORT).asText()) || + (loopProperties.findValue(IS_FEED_BACK).asBoolean())) { + InputActivityPort input = new InputActivityPort(beanshell, portName); + input.setDepth(procOut.getDepth()); + input.setParent(beanshell); + } + } + } + + private void generateOutputPorts(Activity beanshell) { + OutputActivityPort loopPort = new OutputActivityPort(beanshell, LOOP_PORT); + loopPort.setDepth(0); + loopPort.setGranularDepth(0); + if (processorToCompare == null) { + return; + } + if (! loopProperties.findValue(IS_FEED_BACK).asBoolean()) { + return; + } + for (InputProcessorPort procIn : processorToCompare.getInputPorts()) { + String portName = procIn.getName(); + if (processorToCompare.getOutputPorts().containsName(portName)) { + OutputActivityPort actOut = new OutputActivityPort(beanshell, portName); + actOut.setDepth(procIn.getDepth()); + actOut.setGranularDepth(procIn.getDepth()); + } + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/AddLoopFactory.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/AddLoopFactory.java b/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/AddLoopFactory.java new file mode 100644 index 0000000..087cba2 --- /dev/null +++ b/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/AddLoopFactory.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (C) 2008 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 org.apache.taverna.workbench.loop; + +import java.awt.event.ActionEvent; +import java.net.URI; +import java.util.List; + +import javax.swing.AbstractAction; +import javax.swing.Action; + +import org.apache.taverna.workbench.MainWindow; +import org.apache.taverna.workbench.edits.EditManager; +import org.apache.taverna.workbench.file.FileManager; +import org.apache.taverna.workbench.selection.SelectionManager; +import org.apache.taverna.workbench.ui.views.contextualviews.AddLayerFactorySPI; + +import org.apache.log4j.Logger; + +import uk.org.taverna.configuration.app.ApplicationConfiguration; +import org.apache.taverna.scufl2.api.common.Scufl2Tools; +import org.apache.taverna.scufl2.api.configurations.Configuration; +import org.apache.taverna.scufl2.api.core.Processor; + +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + +public class AddLoopFactory implements AddLayerFactorySPI { + + private static final URI LOOP_TYPE = URI.create("http://ns.taverna.org.uk/2010/scufl2/taverna/dispatchlayer/Loop"); + + + private static Logger logger = Logger.getLogger(AddLoopFactory.class); + private static final JsonNodeFactory JSON_NODE_FACTORY = JsonNodeFactory.instance; + private static Scufl2Tools scufl2Tools = new Scufl2Tools(); + + private EditManager editManager; + private FileManager fileManager; + private SelectionManager selectionManager; + private ApplicationConfiguration applicationConfig; + + public boolean canAddLayerFor(Processor processor) { + return findLoopLayer(processor) == null; + } + + + public ObjectNode findLoopLayer(Processor processor) { + List<Configuration> configs = scufl2Tools.configurationsFor(processor, selectionManager.getSelectedProfile()); + for (Configuration config : configs) { + if (config.getJson().has("loop")) { + return (ObjectNode) config.getJson().get("loop"); + } + } + return null; + } + + @SuppressWarnings("serial") + public Action getAddLayerActionFor(final Processor processor) { + return new AbstractAction("Add looping") { + + public void actionPerformed(ActionEvent e) { + ObjectNode loopLayer = findLoopLayer(processor); + if (loopLayer == null) { + loopLayer = JSON_NODE_FACTORY.objectNode(); + } + // Pop up the configure loop dialog + LoopConfigureAction loopConfigureAction = new LoopConfigureAction( + MainWindow.getMainWindow(), null, processor, loopLayer, + selectionManager.getSelectedProfile(), editManager, + fileManager, getApplicationConfig()); + loopConfigureAction.actionPerformed(e); + } + }; + } + + @Override + public boolean canCreateLayerClass(URI dispatchLayerType) { + return dispatchLayerType.equals(LOOP_TYPE); + } + + public void setEditManager(EditManager editManager) { + this.editManager = editManager; + } + + public void setFileManager(FileManager fileManager) { + this.fileManager = fileManager; + } + + public SelectionManager getSelectionManager() { + return selectionManager; + } + + public void setSelectionManager(SelectionManager selectionManager) { + this.selectionManager = selectionManager; + } + + + public ApplicationConfiguration getApplicationConfig() { + return applicationConfig; + } + + + public void setApplicationConfig(ApplicationConfiguration applicationConfig) { + this.applicationConfig = applicationConfig; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopAddMenuAction.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopAddMenuAction.java b/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopAddMenuAction.java new file mode 100644 index 0000000..571bc8d --- /dev/null +++ b/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopAddMenuAction.java @@ -0,0 +1,73 @@ +/********************************************************************** + * 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 org.apache.taverna.workbench.loop; + +import java.awt.event.ActionEvent; +import java.net.URI; + +import javax.swing.AbstractAction; +import javax.swing.Action; + +import org.apache.taverna.scufl2.api.core.Processor; + +import org.apache.taverna.ui.menu.AbstractContextualMenuAction; + +public class LoopAddMenuAction extends AbstractContextualMenuAction { + + public static final URI configureRunningSection = URI + .create("http://taverna.sf.net/2009/contextMenu/configureRunning"); + + private static final URI LOOP_ADD_URI = URI + .create("http://taverna.sf.net/2008/t2workbench/loopAdd"); + + private static final String LOOP_ADD = "Loop add"; + + public LoopAddMenuAction() { + super(configureRunningSection, 20, LOOP_ADD_URI); + } + + private AddLoopFactory addLoopFactory; + + @SuppressWarnings("serial") + @Override + protected Action createAction() { + return new AbstractAction("Looping...") { + public void actionPerformed(ActionEvent e) { + //Loop loopLayer = null; + Processor p = (Processor) getContextualSelection().getSelection(); + addLoopFactory.getAddLayerActionFor(p).actionPerformed(e); + //LoopConfigureMenuAction.configureLoopLayer(p, e); // Configuration dialog pop up is now done from getAddLayerActionFor() + } + }; + } + + public boolean isEnabled() { + Object selection = getContextualSelection().getSelection(); + return (super.isEnabled() && (selection instanceof Processor) && (LoopConfigureMenuAction.getLoopLayer((Processor)selection) == null)); + } + + public void setAddLoopFactory(AddLoopFactory addLoopFactory) { + this.addLoopFactory = addLoopFactory; + } + + + +} http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopConfigurationPanel.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopConfigurationPanel.java b/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopConfigurationPanel.java new file mode 100644 index 0000000..f9d768a --- /dev/null +++ b/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopConfigurationPanel.java @@ -0,0 +1,588 @@ +/******************************************************************************* + * Copyright (C) 2008 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 org.apache.taverna.workbench.loop; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Properties; + +import javax.swing.AbstractAction; +import javax.swing.Box; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SwingConstants; +import javax.swing.border.EmptyBorder; + +import net.sf.taverna.t2.activities.beanshell.views.BeanshellConfigurationPanel; +import org.apache.taverna.workbench.helper.HelpEnabledDialog; +import org.apache.taverna.workbench.loop.comparisons.Comparison; +import org.apache.taverna.workbench.ui.Utils; + +import org.apache.log4j.Logger; + +import uk.org.taverna.configuration.app.ApplicationConfiguration; +import org.apache.taverna.scufl2.api.activity.Activity; +import org.apache.taverna.scufl2.api.common.Scufl2Tools; +import org.apache.taverna.scufl2.api.configurations.Configuration; +import org.apache.taverna.scufl2.api.core.Processor; +import org.apache.taverna.scufl2.api.profiles.Profile; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * UI for {@link LoopConfiguration} + * + * @author Stian Soiland-Reyes + * + */ +@SuppressWarnings("serial") +public class LoopConfigurationPanel extends JPanel { + + private static final String CONDITION_ACTIVITY = "conditionActivity"; + private static final String DEFAULT_DELAY_S = "0.5"; + protected ObjectNode configuration; + + private static final Scufl2Tools scufl2tools = new Scufl2Tools(); + private ApplicationConfiguration applicationConfig; + + + protected final Processor processor; + + protected JPanel headerPanel = new JPanel(); + protected JPanel optionsPanel = new JPanel(); + protected JPanel configPanel = new JPanel(); + protected JPanel customPanel = new JPanel(); + + protected JLabel valueTypeLabel = new JLabel("the string"); + + protected JTextField valueField = new JTextField("", 15); + + protected JLabel delayLabel = new JLabel("adding a delay of "); + protected JTextField delayField = new JTextField( + Double.toString(ActivityGenerator.DEFAULT_DELAY_S), 4); + protected JLabel secondsLabel = new JLabel(" seconds between the loops."); + + private JComboBox<String> portCombo; + private JComboBox<Comparison> comparisonCombo; + private JButton customizeButton; + + protected ObjectNode loopLayer; + private Object Comparison; + private Activity originalCondition = null; + private Profile profile; + + public LoopConfigurationPanel(Processor processor, ObjectNode loopLayer, + Profile profile, ApplicationConfiguration applicationConfig) { + this.processor = processor; + this.loopLayer = loopLayer; + this.profile = profile; + this.applicationConfig = applicationConfig; + this.setBorder(new EmptyBorder(10,10,10,10)); + initialise(); + setConfiguration(loopLayer); + } + + public ObjectNode getConfiguration() { + uiToConfig(); + return loopLayer.deepCopy(); + } + + private static Logger logger = Logger + .getLogger(LoopConfigurationPanel.class); + + protected void uiToConfig() { + String comparisonStr = configuration.path(ActivityGenerator.COMPARISON).asText(); + if (comparisonStr.isEmpty()) { + comparisonStr = ActivityGenerator.CUSTOM_COMPARISON; + } + if (comparisonStr.equals(ActivityGenerator.CUSTOM_COMPARISON) + && ! configuration.path(CONDITION_ACTIVITY).asText().isEmpty()) { + // Ignore values + } else { + configuration.put("runFirst", true); + if (portCombo.getSelectedItem() == null) { + // unconfigured port + configuration.remove(ActivityGenerator.COMPARE_PORT); + configuration.putNull(CONDITION_ACTIVITY); + return; + } else { + configuration.put(ActivityGenerator.COMPARE_PORT, + ((String) portCombo.getSelectedItem())); + } + + Comparison comparison = (Comparison) comparisonCombo + .getSelectedItem(); + if (comparison == null) { + configuration.remove(ActivityGenerator.COMPARISON); + configuration.putNull(CONDITION_ACTIVITY); + return; + } else { + configuration + .put(ActivityGenerator.COMPARISON, comparison.getId()); + } + configuration.put(ActivityGenerator.COMPARE_VALUE, valueField + .getText()); + configuration.put(ActivityGenerator.DELAY, Double.parseDouble(delayField.getText())); + configuration.put(ActivityGenerator.IS_FEED_BACK, feedBackCheck.isSelected()); + + // Generate activity + ActivityGenerator activityGenerator = new ActivityGenerator( + configuration, processor); + configuration.put(CONDITION_ACTIVITY, activityGenerator.generateActivity().getName()); + } + } + + public class ResetAction extends AbstractAction { + public ResetAction() { + super("Clear"); + } + + public void actionPerformed(ActionEvent e) { + configuration.putNull(CONDITION_ACTIVITY); + configToUi(); + } + } + + private final class CustomizeAction implements ActionListener { + + +// public CustomizeAction() { +// super(); +// //putValue(NAME, "Customise loop condition"); +// } + + public void actionPerformed(ActionEvent e) { + uiToConfig(); + + String conditionName = configuration.path(CONDITION_ACTIVITY).asText(); + + Activity condition = profile.getActivities().getByName(conditionName); + if (condition == null) { + condition = new Activity(); + profile.getActivities().add(condition); + configuration.put(CONDITION_ACTIVITY, condition.getName()); + condition.setType(ActivityGenerator.BEANSHELL_ACTIVITY); + Configuration config = scufl2tools.createConfigurationFor(condition, ActivityGenerator.BEANSHELL_CONFIG); + } else if (!(condition.getType().equals(ActivityGenerator.BEANSHELL_ACTIVITY))) { + logger.warn("Can't configure unsupported loop condition of service type " + + condition.getType()); + return; + } + + Frame owner = Utils.getParentFrame(LoopConfigurationPanel.this); + + + final BeanshellConfigurationPanel beanshellConfigView = new BeanshellConfigurationPanel( + condition, applicationConfig); + + final JDialog dialog = new HelpEnabledDialog(owner, "Customize looping", true); + dialog.setLayout(new BorderLayout()); + dialog.add(beanshellConfigView, BorderLayout.NORTH); + dialog.setSize(600, 600); + JPanel buttonPanel = new JPanel(); + + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + + JButton applyButton = new JButton(new AbstractAction() { + + public void actionPerformed(ActionEvent e) { + if (beanshellConfigView.isConfigurationChanged()) { + beanshellConfigView.noteConfiguration(); +// beanshellActivity.configure(beanshellConfigView +// .getConfiguration()); +// configuration.setCondition(beanshellActivity); + Configuration config = beanshellConfigView.getConfiguration(); + // TODO: Do we need to store this somehow? + configuration.put( + ActivityGenerator.COMPARISON, + ActivityGenerator.CUSTOM_COMPARISON); + } + dialog.setVisible(false); + configToUi(); + } + + }); + applyButton.setText("Apply"); + + buttonPanel.add(applyButton); + JButton closeButton = new JButton(new AbstractAction() { + + public void actionPerformed(ActionEvent e) { + dialog.setVisible(false); + } + }); + closeButton.setText("Cancel"); + buttonPanel.add(closeButton); + dialog.add(buttonPanel, BorderLayout.SOUTH); + dialog.setLocationRelativeTo(customizeButton); + dialog.setVisible(true); + + } + } + + public void setConfiguration(ObjectNode configuration) { + this.configuration = configuration.deepCopy(); + configToUi(); + } + + protected void configToUi() { + + + String comparisonId; + + if (configuration.has(ActivityGenerator.COMPARISON)) { + comparisonId = configuration.get(ActivityGenerator.COMPARISON) + .asText(); + } else { + comparisonId = ActivityGenerator.CUSTOM_COMPARISON; + } + + if (comparisonId.equals(ActivityGenerator.CUSTOM_COMPARISON) + && configuration.has("conditionalActivity")) { + configPanel.setVisible(false); + customPanel.setVisible(true); + } else { + configPanel.setVisible(true); + customPanel.setVisible(false); + } + + portCombo.setSelectedItem(configuration.get(ActivityGenerator.COMPARE_PORT).asText()); + if (portCombo.getSelectedIndex() == -1 + && portCombo.getModel().getSize() > 0) { + portCombo.setSelectedIndex(0); + } + + Comparison comparison = ActivityGenerator + .getComparisonById(comparisonId); + comparisonCombo.setSelectedItem(comparison); + if (comparisonCombo.getSelectedIndex() == -1 + && comparisonCombo.getModel().getSize() > 0) { + comparisonCombo.setSelectedIndex(0); + } + + valueField.setText(configuration.get(ActivityGenerator.COMPARE_VALUE).asText()); + + if (configuration.has(ActivityGenerator.DELAY)) { + delayField.setText(configuration.get(ActivityGenerator.DELAY).asText()); + } else { + delayField.setText(DEFAULT_DELAY_S); + } + + feedBackCheck.setSelected(configuration.get(ActivityGenerator.IS_FEED_BACK).asBoolean()); + updateFeedbackHelp(); + } + + private void initialise() { + removeAll(); + setLayout(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.anchor = GridBagConstraints.FIRST_LINE_START; + gbc.gridx = 0; + gbc.weightx = 0.1; + + makeHeader(); + add(headerPanel, gbc); + + makeConfigPanel(); + gbc.weighty = 0.1; + gbc.anchor = GridBagConstraints.CENTER; + gbc.fill = GridBagConstraints.BOTH; + add(configPanel, gbc); + + makeCustomPanel(); + add(customPanel, gbc); + + makeOptions(); + add(optionsPanel, gbc); + } + + protected void makeCustomPanel() { + customPanel.removeAll(); + customPanel.setLayout(new GridBagLayout()); + + GridBagConstraints gbc = new GridBagConstraints(); + gbc.anchor = GridBagConstraints.LINE_START; + gbc.gridx = 0; + gbc.gridy = 0; + gbc.gridwidth = 2; + gbc.weightx = 0.1; + gbc.fill = GridBagConstraints.HORIZONTAL; + + JLabel helpLabel = new JLabel( + "<html><body>" + + "The service <strong>" + processor.getName() + "</strong> will be " + + "invoked repeatedly as " + + "long as the <em>customized loop condition service</em> returns a string equal " + + "to <strong>\"true\"</strong> on its output port <code>loop</code>." +// + "<br><br>" +// + "Input ports of the condition service will be populated with values from " +// + "the <em>corresponding output ports</em> of the main service invocation " +// + "(as long as they are also " +// + "<strong>connected</strong> in the containing workflow)." +// + "<br><br> " +// +// + "Any <em>matching " +// + "output ports</em> from the condition service will provide the corresponding " +// + "<em>inputs</em> to the main service while looping. You will need to connect " +// + "the <em>initial inputs</em> in the containing workflow." + + "</body></html>"); + customPanel.add(helpLabel, gbc); + + gbc.weightx = 0.1; + gbc.fill = GridBagConstraints.NONE; + gbc.gridx = 0; + gbc.gridy++; + gbc.gridwidth = 1; + gbc.anchor = GridBagConstraints.EAST; + JPanel customiseButtonPanel = new JPanel(new FlowLayout()); + customiseButtonPanel.setBorder(new EmptyBorder(10,0,0,0)); + customizeButton = new JButton("Customize loop condition"); + customizeButton.addActionListener(new CustomizeAction()); + customiseButtonPanel.add(customizeButton); + customiseButtonPanel.add(new JButton(new ResetAction())); + customPanel.add(customiseButtonPanel, gbc); + + } + + protected void makeConfigPanel() { + configPanel.removeAll(); + configPanel.setLayout(new GridBagLayout()); + + GridBagConstraints gbc = new GridBagConstraints(); + gbc.anchor = GridBagConstraints.LINE_START; + gbc.gridx = 0; + gbc.gridy = 0; + gbc.gridwidth = 4; + gbc.weightx = 0.1; + gbc.fill = GridBagConstraints.HORIZONTAL; + JLabel invokedRepeatedlyLabel = new JLabel( + + "<html><body>The service <strong>" + processor.getName() + "</strong> " + + "will be invoked repeatedly <em>until</em> its output port</body></html>"); + invokedRepeatedlyLabel.setBorder(new EmptyBorder(10,0,10,0)); // give some top and bottom border to the label + configPanel.add(invokedRepeatedlyLabel, gbc); + gbc.ipadx = 4; + gbc.ipady = 4; + + gbc.weightx = 0.0; + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.gridx = 0; + gbc.gridy = 1; + gbc.gridwidth = 1; + List<String> activityOutputPorts = getActivityOutputPorts(); + portCombo = new JComboBox(activityOutputPorts.toArray()); + configPanel.add(portCombo, gbc); + + comparisonCombo = new JComboBox(ActivityGenerator.comparisons.toArray()); + comparisonCombo.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Comparison selectedComparison = (Comparison) comparisonCombo + .getSelectedItem(); + if (selectedComparison != null) { + valueTypeLabel.setText("the " + + selectedComparison.getValueType()); + } + } + }); + if (comparisonCombo.getSelectedIndex() == -1) { + comparisonCombo.setSelectedIndex(0); + } + gbc.gridx = 1; + gbc.gridy = 1; + configPanel.add(comparisonCombo, gbc); + + gbc.gridx = 2; + gbc.gridy = 1; + valueTypeLabel.setHorizontalAlignment(SwingConstants.RIGHT); + configPanel.add(valueTypeLabel, gbc); + + gbc.gridx = 3; + gbc.gridy = 1; + gbc.weightx = 0.5; // request all extra space + gbc.fill = GridBagConstraints.HORIZONTAL; + configPanel.add(valueField, gbc); + + gbc.gridx = 0; + gbc.gridy = 2; + gbc.weightx = 0.0; + configPanel.add(delayLabel, gbc); + + gbc.gridx = 1; + gbc.gridx = 1; + gbc.gridy = 2; + gbc.weightx = 0.0; + delayField.setHorizontalAlignment(JTextField.RIGHT); + configPanel.add(delayField, gbc); + + gbc.gridx = 2; + gbc.gridy = 2; + gbc.gridwidth = 2; + gbc.weightx = 0.5; // request all extra space + gbc.fill = GridBagConstraints.HORIZONTAL; + configPanel.add(secondsLabel, gbc); + + if (activityOutputPorts.isEmpty()) { + JLabel warningLabel = new JLabel( + "<html><body><strong>Warning:</strong><br>" + + "<i>No single value output ports detected on the main service, " + + "cannot use built-in comparisons. You may still add a customized " + + "looping script</i></body></html>"); + gbc.gridx = 0; + gbc.gridy++; + gbc.gridwidth = 4; + gbc.weightx = 0.1; + gbc.fill = GridBagConstraints.BOTH; + gbc.gridy++; + configPanel.add(warningLabel, gbc); + invokedRepeatedlyLabel.setVisible(false); + portCombo.setVisible(false); + comparisonCombo.setVisible(false); + portWarning.setVisible(false); + valueTypeLabel.setVisible(false); + valueField.setVisible(false); + delayField.setVisible(false); + delayLabel.setVisible(false); + secondsLabel.setVisible(false); + } + + gbc.gridy++; + gbc.gridx = 0; + gbc.weightx = 0.1; + gbc.gridwidth = 4; + gbc.weightx = 0.1; + gbc.fill = GridBagConstraints.BOTH; + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.insets = new Insets(10, 0, 10, 0); + configPanel.add(portWarning, gbc); + + gbc.insets = new Insets(0, 0, 0, 0); + gbc.weightx = 0.1; + gbc.fill = GridBagConstraints.NONE; + gbc.gridx = 0; + gbc.gridy++; + gbc.gridwidth = 4; + gbc.anchor = GridBagConstraints.LAST_LINE_END; + JPanel customiseButtonPanel = new JPanel(new FlowLayout()); + customizeButton = new JButton("Customize loop condition"); + customizeButton.addActionListener(new CustomizeAction()); + customiseButtonPanel.add(customizeButton); + configPanel.add(customiseButtonPanel, gbc); + + // filler + gbc.gridy++; + gbc.fill = GridBagConstraints.BOTH; + gbc.gridx = 4; + gbc.weightx = 0.1; + gbc.weighty = 0.1; + gbc.gridwidth = 4; + configPanel.add(Box.createGlue(), gbc); + } + + private List<String> getActivityOutputPorts() { + // Should already be sorted + return new ArrayList<>(processor.getOutputPorts().getNames()); + } + + protected JCheckBox feedBackCheck = new JCheckBox( + "Enable output port to input port feedback"); + private JLabel portWarning = new JLabel( + "<html><body><small>Note that for Taverna to be able to execute this loop, " + + "the output port <strong>must</strong> be connected to an input of another service " + + "or a workflow output port.</small></body></html>"); + + protected void makeOptions() { + optionsPanel.removeAll(); + optionsPanel.setLayout(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.weightx = 0.1; + gbc.anchor = GridBagConstraints.FIRST_LINE_START; + gbc.fill = GridBagConstraints.HORIZONTAL; + feedBackCheck.setBorder(new EmptyBorder(0,0,10,0)); + optionsPanel.add(feedBackCheck, gbc); + feedBackCheck.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + updateFeedbackHelp(); + } + }); + updateFeedbackHelp(); + + gbc.gridy = 1; + gbc.fill = GridBagConstraints.HORIZONTAL; + optionsPanel.add(feedbackHelp, gbc); + } + + protected void updateFeedbackHelp() { + feedbackHelp.setEnabled(feedBackCheck.isSelected()); + Color color; + if (feedBackCheck.isSelected()) { + color = valueTypeLabel.getForeground(); + } else { + // Work around + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4303706 + // and assume gray is the 'disabled' colour in our Look n Feel + color = Color.gray; + } + feedbackHelp.setForeground(color); + + } + + JLabel feedbackHelp = new JLabel( + "<html><small>" + + "<p>When feedback is enabled, the value of the output port is used as input " + + "the next time the loop in invoked. The input and output ports used for feedback " + + "<strong>must</strong> have the same <strong>name</strong> and <strong>depth</strong>." + + "</p><br>" + + + "<p>Feedback can be useful for looping over a nested workflow, " + + "where the nested workflow's output determines its next input value.</p><br>" + + + "<p>In order to use feedback looping, you must provide an initial value to the input port by " + + "connecting it to the output of a previous service or workflow input port." + + "The output port used as feedback also has to be connected to a downstream service " + + "or a workflow output port.</p>" + + + "</small></html>"); + + protected void makeHeader() { + headerPanel.removeAll(); + headerPanel.setLayout(new BorderLayout()); + //headerPanel.add(new ShadedLabel("Looping for service" + // + processor.getLocalName(), ShadedLabel.ORANGE)); + } +} http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopConfigureAction.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopConfigureAction.java b/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopConfigureAction.java new file mode 100644 index 0000000..05b8a43 --- /dev/null +++ b/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopConfigureAction.java @@ -0,0 +1,262 @@ +/** + * + */ +package org.apache.taverna.workbench.loop; + +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +import org.apache.log4j.Logger; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +import uk.org.taverna.configuration.app.ApplicationConfiguration; +import org.apache.taverna.scufl2.api.core.Processor; +import org.apache.taverna.scufl2.api.profiles.Profile; + +import org.apache.taverna.workbench.edits.EditManager; +import org.apache.taverna.workbench.file.FileManager; +import org.apache.taverna.workbench.helper.HelpEnabledDialog; + +/** + * @author Alan R Williams + * @author Stian Soiland-Reyes + * + */ +@SuppressWarnings("serial") +public class LoopConfigureAction extends AbstractAction { + + private static Logger logger = Logger.getLogger(LoopConfigureAction.class); + + private final EditManager editManager; + private final FileManager fileManager; + + private final Frame owner; + private final ObjectNode loopLayer; + private final LoopContextualView contextualView; + private final Processor processor; + private final Profile profile; + + private ApplicationConfiguration applicationConfig; + + + protected LoopConfigureAction(Frame owner, + LoopContextualView contextualView, Processor processor, + ObjectNode loopLayer, Profile profile, EditManager editManager, + FileManager fileManager, ApplicationConfiguration applicationConfig) { + super("Configure"); + this.owner = owner; + this.contextualView = contextualView; + this.loopLayer = loopLayer; + this.profile = profile; + this.editManager = editManager; + this.fileManager = fileManager; + this.processor = processor; + this.applicationConfig = applicationConfig; + } + + public void actionPerformed(ActionEvent e) { + String title = "Looping for service " + processor.getName(); + final JDialog dialog = new HelpEnabledDialog(owner, title, true); + LoopConfigurationPanel loopConfigurationPanel = new LoopConfigurationPanel( + processor, loopLayer, profile, applicationConfig); + dialog.add(loopConfigurationPanel, BorderLayout.CENTER); + + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout()); + + JButton okButton = new JButton(new OKAction(dialog, loopConfigurationPanel)); + buttonPanel.add(okButton); + + JButton resetButton = new JButton(new ResetAction(loopConfigurationPanel)); + buttonPanel.add(resetButton); + + JButton cancelButton = new JButton(new CancelAction(dialog)); + buttonPanel.add(cancelButton); + + dialog.add(buttonPanel, BorderLayout.SOUTH); + dialog.pack(); + dialog.setSize(650, 430); + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); + } + + protected class CancelAction extends AbstractAction { + private final JDialog dialog; + + protected CancelAction(JDialog dialog) { + super("Cancel"); + this.dialog = dialog; + } + + public void actionPerformed(ActionEvent e) { + dialog.setVisible(false); + if (contextualView != null) { + contextualView.refreshView(); + } + } + + } + + protected class OKAction extends AbstractAction { + private final JDialog dialog; + private final LoopConfigurationPanel loopConfigurationPanel; + + protected OKAction(JDialog dialog, LoopConfigurationPanel loopConfigurationPanel) { + super("OK"); + this.dialog = dialog; + this.loopConfigurationPanel = loopConfigurationPanel; + } + + public void actionPerformed(ActionEvent e) { + try { + + List<Edit<?>> compoundEdit = new ArrayList<Edit<?>>(); + LoopConfiguration configuration = loopConfigurationPanel.getConfiguration(); + compoundEdit.add(edits.getConfigureEdit(loopLayer, configuration)); + compoundEdit.addAll(checkPortMappings(configuration.getCondition())); + + editManager.doDataflowEdit(fileManager.getCurrentDataflow(), new CompoundEdit( + compoundEdit)); + dialog.setVisible(false); + if (contextualView != null) { + contextualView.refreshView(); + } + } catch (RuntimeException ex) { + logger.warn("Could not configure looping", ex); + JOptionPane.showMessageDialog(owner, "Could not configure looping", + "An error occured when configuring looping: " + ex.getMessage(), + JOptionPane.ERROR_MESSAGE); + } catch (EditException ex) { + logger.warn("Could not configure looping", ex); + JOptionPane.showMessageDialog(owner, "Could not configure looping", + "An error occured when configuring looping: " + ex.getMessage(), + JOptionPane.ERROR_MESSAGE); + } + } + + protected List<Edit<?>> checkPortMappings(Activity<?> conditionActivity) { + + List<Edit<?>> compoundEdit = new ArrayList<Edit<?>>(); + if (processor.getActivityList().isEmpty()) { + return compoundEdit; + } + Set<String> newInputs = new HashSet<String>(); + Set<String> newOutputs = new HashSet<String>(); + + Activity<?> firstProcessorActivity; + firstProcessorActivity = processor.getActivityList().get(0); + if (conditionActivity != null) { + for (OutputPort condOutPort : conditionActivity.getOutputPorts()) { + String portName = condOutPort.getName(); + Map<String, String> mapping = firstProcessorActivity.getInputPortMapping(); + if (!mapping.containsKey(portName)) { + if (mapping.containsKey(portName)) { + logger.warn("Can't re-map input for " + "conditional output " + + portName); + } + for (InputPort inputPort : firstProcessorActivity.getInputPorts()) { + if (inputPort.equals(portName)) { + Edit<Activity<?>> edit = edits.getAddActivityInputPortMappingEdit( + firstProcessorActivity, portName, portName); + compoundEdit.add(edit); + newInputs.add(portName); + } + } + } + } + for (InputPort condInPort : conditionActivity.getInputPorts()) { + String portName = condInPort.getName(); + Map<String, String> mapping = firstProcessorActivity.getOutputPortMapping(); + if (!mapping.containsValue(portName)) { + for (OutputPort outputPort : firstProcessorActivity.getOutputPorts()) { + if (outputPort.equals(portName)) { + if (mapping.containsKey(portName)) { + logger.warn("Can't re-map output for " + "conditional input " + + portName); + } + Edit<Activity<?>> edit = edits.getAddActivityOutputPortMappingEdit( + firstProcessorActivity, portName, portName); + logger.info("Mapping for conditional non-outgoing activity port binding " + + portName); + compoundEdit.add(edit); + newOutputs.add(portName); + } + } + } + } + } + // Remove any stale bindings that no longer match neither + // conditional activity or the processor output ports + for (String processorIn : firstProcessorActivity.getInputPortMapping().keySet()) { + if (newInputs.contains(processorIn)) { + continue; + } + boolean foundMatch = false; + for (InputPort processorPort : processor.getInputPorts()) { + if (processorPort.getName().equals(processorIn)) { + foundMatch = true; + break; + } + } + if (!foundMatch) { + Edit<Activity<?>> edit = edits.getRemoveActivityInputPortMappingEdit( + firstProcessorActivity, processorIn); + logger.info("Removing stale input port binding " + processorIn); + compoundEdit.add(edit); + } + } + for (String processorOut : firstProcessorActivity.getOutputPortMapping().keySet()) { + if (newInputs.contains(processorOut)) { + continue; + } + boolean foundMatch = false; + for (OutputPort processorPort : processor.getOutputPorts()) { + if (processorPort.getName().equals(processorOut)) { + foundMatch = true; + break; + } + } + if (!foundMatch) { + Edit<Activity<?>> edit = edits.getRemoveActivityOutputPortMappingEdit( + firstProcessorActivity, processorOut); + logger.info("Removing stale output port binding " + processorOut); + compoundEdit.add(edit); + } + } + + return compoundEdit; + } + } + + protected class ResetAction extends AbstractAction { + private LoopConfigurationPanel loopConfigurationPanel; + + protected ResetAction(LoopConfigurationPanel loopConfigurationPanel) { + super("Reset"); + this.loopConfigurationPanel = loopConfigurationPanel; + } + + public void actionPerformed(ActionEvent e) { + if (contextualView != null) { + contextualView.refreshView(); + } + loopConfigurationPanel.setConfiguration(loopLayer.getConfiguration()); + } + + } + +} http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopConfigureMenuAction.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopConfigureMenuAction.java b/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopConfigureMenuAction.java new file mode 100644 index 0000000..061c225 --- /dev/null +++ b/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopConfigureMenuAction.java @@ -0,0 +1,97 @@ +/********************************************************************** + * 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 org.apache.taverna.workbench.loop; + +import java.awt.event.ActionEvent; +import java.net.URI; + +import javax.swing.AbstractAction; +import javax.swing.Action; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +import org.apache.taverna.scufl2.api.core.Processor; + +import org.apache.taverna.ui.menu.AbstractContextualMenuAction; +import org.apache.taverna.workbench.edits.EditManager; +import org.apache.taverna.workbench.file.FileManager; + +public class LoopConfigureMenuAction extends AbstractContextualMenuAction { + + public static final URI configureRunningSection = URI + .create("http://taverna.sf.net/2009/contextMenu/configureRunning"); + + private static final URI LOOP_CONFIGURE_URI = URI + .create("http://taverna.sf.net/2008/t2workbench/loopConfigure"); + + private static final String LOOP_CONFIGURE = "Loop configure"; + + private EditManager editManager; + + private FileManager fileManager; + + public LoopConfigureMenuAction() { + super(configureRunningSection, 20, LOOP_CONFIGURE_URI); + } + + @SuppressWarnings("serial") + @Override + protected Action createAction() { + return new AbstractAction("Looping...") { + public void actionPerformed(ActionEvent e) { + Processor p = (Processor) getContextualSelection().getSelection(); + configureLoopLayer(p, e); + } + }; + } + + public void configureLoopLayer(Processor p, ActionEvent e) { + ObjectNode loopLayer = getLoopLayer(p); + if (loopLayer != null) { + LoopConfigureAction loopConfigureAction = new LoopConfigureAction(null, null, loopLayer, editManager, fileManager); + loopConfigureAction.actionPerformed(e); + } + } + + public static ObjectNode getLoopLayer(Processor p) { + for (DispatchLayer dl : p.getDispatchStack().getLayers()) { + if (dl instanceof Loop) { + result = (Loop) dl; + break; + } + } + return result; + } + + public boolean isEnabled() { + Object selection = getContextualSelection().getSelection(); + return (super.isEnabled() && (selection instanceof Processor) && (getLoopLayer((Processor)selection) != null)); + } + + 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/a9a52bd5/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopContextualView.java ---------------------------------------------------------------------- diff --git a/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopContextualView.java b/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopContextualView.java new file mode 100644 index 0000000..fc5e837 --- /dev/null +++ b/taverna-loop-ui/src/main/java/org/apache/taverna/workbench/loop/LoopContextualView.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright (C) 2008 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 org.apache.taverna.workbench.loop; + +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.util.Properties; + +import javax.swing.Action; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import org.apache.taverna.workbench.edits.EditManager; +import org.apache.taverna.workbench.file.FileManager; +import org.apache.taverna.workbench.loop.comparisons.Comparison; +import org.apache.taverna.workbench.ui.views.contextualviews.ContextualView; + +import org.apache.log4j.Logger; + +import org.apache.taverna.scufl2.api.core.Processor; + +/** + * View of a processor, including it's iteration stack, activities, etc. + * + * @author Stian Soiland-Reyes + * + */ +public class LoopContextualView extends ContextualView { + + private static final long serialVersionUID = 1L; + + private static Logger logger = Logger.getLogger(LoopContextualView.class); + + private EditManager editManager; + private FileManager fileManager; + + private Loop loopLayer; + + private JPanel panel; + + private Processor processor; + + public LoopContextualView(Processor processor, EditManager editManager, FileManager fileManager) { + super(); + this.loopLayer = loopLayer; + this.editManager = editManager; + this.fileManager = fileManager; + this.processor = processor; + initialise(); + initView(); + } + + @Override + public Action getConfigureAction(Frame owner) { + return new LoopConfigureAction(owner, this, processor, editManager, fileManager); + } + + @Override + public void refreshView() { + initialise(); + } + + private void initialise() { + if (panel == null) { + panel = new JPanel(); + } else { + panel.removeAll(); + } + panel.setLayout(new GridBagLayout()); + updateUIByConfig(); + } + + @Override + public JComponent getMainFrame() { + return panel; + } + + @Override + public String getViewTitle() { + return "Loop of " + processor.getLocalName(); + } + + protected void updateUIByConfig() { + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 1; + gbc.weightx = 0.1; + gbc.fill = GridBagConstraints.HORIZONTAL; + + StringBuilder description = new StringBuilder("<html><body>"); + Properties properties = loopLayer.getConfiguration().getProperties(); + if (properties.getProperty(ActivityGenerator.COMPARISON, + ActivityGenerator.CUSTOM_COMPARISON).equals( + ActivityGenerator.CUSTOM_COMPARISON)) { + Activity<?> condition = loopLayer.getConfiguration().getCondition(); + if (condition != null) { + description.append("Looping using custom conditional "); + if (condition instanceof BeanshellActivity) { + String script = ((BeanshellActivity)condition).getConfiguration().getScript(); + if (script != null) { + if (script.length() <= 100) { + description.append("<pre>\n"); + description.append(script); + description.append("</pre>\n"); + } + } + } + } else { + description.append("<i>Unconfigured, will not loop</i>"); + } + } else { + description.append("The service will be invoked repeatedly "); + description.append("until<br> its output <strong>"); + description.append(properties + .getProperty(ActivityGenerator.COMPARE_PORT)); + description.append("</strong> "); + + Comparison comparison = ActivityGenerator + .getComparisonById(properties + .getProperty(ActivityGenerator.COMPARISON)); + description.append(comparison.getName()); + + description.append(" the " + comparison.getValueType() + ": <pre>"); + description.append(properties + .getProperty(ActivityGenerator.COMPARE_VALUE)); + description.append("</pre>"); + + String delay = properties.getProperty(ActivityGenerator.DELAY, ""); + try { + if (Double.parseDouble(delay) > 0) { + description.append("adding a delay of " + delay + + " seconds between loops."); + } + } catch (NumberFormatException ex) { + } + } + description.append("</body></html>"); + + panel.add(new JLabel(description.toString()), gbc); + gbc.gridy++; + + revalidate(); + } + + + + @Override + public int getPreferredPosition() { + return 400; + } + +}
