You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2015/03/20 15:22:47 UTC
[33/51] [abbrv] [partial] incubator-taverna-workbench git commit:
taverna-workbench-* -> taverna-*
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileOpenRecentMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileOpenRecentMenuAction.java b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileOpenRecentMenuAction.java
new file mode 100644
index 0000000..76ef759
--- /dev/null
+++ b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileOpenRecentMenuAction.java
@@ -0,0 +1,418 @@
+package net.sf.taverna.t2.workbench.file.impl.menu;
+
+import static java.awt.event.KeyEvent.VK_0;
+import static java.awt.event.KeyEvent.VK_R;
+import static javax.swing.Action.MNEMONIC_KEY;
+import static javax.swing.Action.NAME;
+import static javax.swing.JOptionPane.ERROR_MESSAGE;
+import static javax.swing.JOptionPane.showMessageDialog;
+import static javax.swing.SwingUtilities.invokeLater;
+import static net.sf.taverna.t2.workbench.file.impl.menu.FileOpenMenuSection.FILE_OPEN_SECTION_URI;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+
+import net.sf.taverna.t2.lang.observer.Observable;
+import net.sf.taverna.t2.lang.observer.Observer;
+import net.sf.taverna.t2.ui.menu.AbstractMenuCustom;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.file.FileType;
+import net.sf.taverna.t2.workbench.file.events.AbstractDataflowEvent;
+import net.sf.taverna.t2.workbench.file.events.ClosedDataflowEvent;
+import net.sf.taverna.t2.workbench.file.events.FileManagerEvent;
+import net.sf.taverna.t2.workbench.file.events.OpenedDataflowEvent;
+import net.sf.taverna.t2.workbench.file.events.SavedDataflowEvent;
+import net.sf.taverna.t2.workbench.file.exceptions.OpenException;
+
+import org.apache.log4j.Logger;
+import org.jdom.Document;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+
+import uk.org.taverna.configuration.app.ApplicationConfiguration;
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+
+public class FileOpenRecentMenuAction extends AbstractMenuCustom implements
+ Observer<FileManagerEvent> {
+ public static final URI RECENT_URI = URI
+ .create("http://taverna.sf.net/2008/t2workbench/menu#fileOpenRecent");
+ private static final String CONF = "conf";
+ private static Logger logger = Logger
+ .getLogger(FileOpenRecentMenuAction.class);
+ private static final String RECENT_WORKFLOWS_XML = "recentWorkflows.xml";
+ private static final int MAX_ITEMS = 10;
+
+ private FileManager fileManager;
+ private ApplicationConfiguration applicationConfiguration;
+ private JMenu menu;
+ private List<Recent> recents = new ArrayList<>();
+ private Thread loadRecentThread;
+
+ public FileOpenRecentMenuAction(FileManager fileManager) {
+ super(FILE_OPEN_SECTION_URI, 30, RECENT_URI);
+ this.fileManager = fileManager;
+ fileManager.addObserver(this);
+ }
+
+ @Override
+ public void notify(Observable<FileManagerEvent> sender,
+ FileManagerEvent message) throws Exception {
+ FileManager fileManager = (FileManager) sender;
+ if (message instanceof OpenedDataflowEvent
+ || message instanceof SavedDataflowEvent) {
+ AbstractDataflowEvent dataflowEvent = (AbstractDataflowEvent) message;
+ WorkflowBundle dataflow = dataflowEvent.getDataflow();
+ Object dataflowSource = fileManager.getDataflowSource(dataflow);
+ FileType dataflowType = fileManager.getDataflowType(dataflow);
+ addRecent(dataflowSource, dataflowType);
+ }
+ if (message instanceof ClosedDataflowEvent)
+ // Make sure enabled/disabled status is correct
+ updateRecentMenu();
+ }
+
+ public void updateRecentMenu() {
+ invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ updateRecentMenuGUI();
+ }
+ });
+ saveRecent();
+ }
+
+ protected void addRecent(Object dataflowSource, FileType dataflowType) {
+ if (dataflowSource == null)
+ return;
+ if (!(dataflowSource instanceof Serializable)) {
+ logger.warn("Can't serialize workflow source for 'Recent workflows': "
+ + dataflowSource);
+ return;
+ }
+ synchronized (recents) {
+ Recent recent = new Recent((Serializable) dataflowSource, dataflowType);
+ if (recents.contains(recent))
+ recents.remove(recent);
+ recents.add(0, recent); // Add to front
+ }
+ updateRecentMenu();
+ }
+
+ @Override
+ protected Component createCustomComponent() {
+ action = new DummyAction("Recent workflows");
+ action.putValue(MNEMONIC_KEY, VK_R);
+ menu = new JMenu(action);
+ // Disabled until we have loaded the recent workflows
+ menu.setEnabled(false);
+ loadRecentThread = new Thread("Loading recent workflow menu") {
+ // Avoid hanging GUI initialization while deserialising
+ @Override
+ public void run() {
+ loadRecent();
+ updateRecentMenu();
+ }
+ };
+ loadRecentThread.start();
+ return menu;
+ }
+
+ protected synchronized void loadRecent() {
+ File confDir = new File(applicationConfiguration.getApplicationHomeDir(), CONF);
+ confDir.mkdir();
+ File recentFile = new File(confDir, RECENT_WORKFLOWS_XML);
+ if (!recentFile.isFile())
+ return;
+ try {
+ loadRecent(recentFile);
+ } catch (JDOMException|IOException e) {
+ logger.warn("Could not read recent workflows from file "
+ + recentFile, e);
+ }
+ }
+
+ private void loadRecent(File recentFile) throws FileNotFoundException,
+ IOException, JDOMException {
+ SAXBuilder builder = new SAXBuilder();
+ @SuppressWarnings("unused")
+ Document document;
+ try (InputStream fileInputStream = new BufferedInputStream(
+ new FileInputStream(recentFile))) {
+ document = builder.build(fileInputStream);
+ }
+ synchronized (recents) {
+ recents.clear();
+ //RecentDeserializer deserialiser = new RecentDeserializer();
+ try {
+ // recents.addAll(deserialiser.deserializeRecent(document
+ // .getRootElement()));
+ } catch (Exception e) {
+ logger.warn("Could not read recent workflows from file "
+ + recentFile, e);
+ }
+ }
+ }
+
+ protected synchronized void saveRecent() {
+ File confDir = new File(applicationConfiguration.getApplicationHomeDir(), CONF);
+ confDir.mkdir();
+ File recentFile = new File(confDir, RECENT_WORKFLOWS_XML);
+
+ try {
+ saveRecent(recentFile);
+// } catch (JDOMException e) {
+// logger.warn("Could not generate XML for recent workflows to file "
+// + recentFile, e);
+ } catch (IOException e) {
+ logger.warn("Could not write recent workflows to file "
+ + recentFile, e);
+ }
+ }
+
+ private void saveRecent(File recentFile) throws FileNotFoundException,
+ IOException {
+ // RecentSerializer serializer = new RecentSerializer();
+ // XMLOutputter outputter = new XMLOutputter();
+
+ // Element serializedRecent;
+ synchronized (recents) {
+ if (recents.size() > MAX_ITEMS)
+ // Remove excess entries
+ recents.subList(MAX_ITEMS, recents.size()).clear();
+ // serializedRecent = serializer.serializeRecent(recents);
+ }
+ try (OutputStream outputStream = new BufferedOutputStream(
+ new FileOutputStream(recentFile))) {
+ // outputter.output(serializedRecent, outputStream);
+ }
+ }
+
+ protected void updateRecentMenuGUI() {
+ int items = 0;
+ menu.removeAll();
+ synchronized (recents) {
+ for (Recent recent : recents) {
+ if (++items >= MAX_ITEMS)
+ break;
+ OpenRecentAction openRecentAction = new OpenRecentAction(
+ recent, fileManager);
+ if (fileManager.getDataflowBySource(recent.getDataflowSource()) != null)
+ openRecentAction.setEnabled(false);
+ // else setEnabled(true)
+ JMenuItem menuItem = new JMenuItem(openRecentAction);
+ if (items < 10) {
+ openRecentAction.putValue(NAME, items + " "
+ + openRecentAction.getValue(NAME));
+ menuItem.setMnemonic(VK_0 + items);
+ }
+ menu.add(menuItem);
+ }
+ }
+ menu.setEnabled(items > 0);
+ menu.revalidate();
+ }
+
+ @SuppressWarnings("serial")
+ public static class OpenRecentAction extends AbstractAction implements
+ Runnable {
+ private final Recent recent;
+ private Component component = null;
+ private final FileManager fileManager;
+
+ public OpenRecentAction(Recent recent, FileManager fileManager) {
+ this.recent = recent;
+ this.fileManager = fileManager;
+ Serializable source = recent.getDataflowSource();
+ String name;
+ if (source instanceof File)
+ name = ((File) source).getAbsolutePath();
+ else
+ name = source.toString();
+ this.putValue(NAME, name);
+ this.putValue(SHORT_DESCRIPTION, "Open the workflow " + name);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ component = null;
+ if (e.getSource() instanceof Component)
+ component = (Component) e.getSource();
+ setEnabled(false);
+ new Thread(this, "Opening workflow from "
+ + recent.getDataflowSource()).start();
+ }
+
+ /**
+ * Opening workflow in separate thread
+ */
+ @Override
+ public void run() {
+ final Serializable source = recent.getDataflowSource();
+ try {
+ fileManager.openDataflow(recent.makefileType(), source);
+ } catch (OpenException ex) {
+ logger.warn("Failed to open the workflow from " + source
+ + " \n", ex);
+ showMessageDialog(component,
+ "Failed to open the workflow from url " + source
+ + " \n" + ex.getMessage(), "Error!",
+ ERROR_MESSAGE);
+ } finally {
+ setEnabled(true);
+ }
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public static class Recent implements Serializable {
+ private final class RecentFileType extends FileType {
+ @Override
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ @Override
+ public String getExtension() {
+ return extension;
+ }
+
+ @Override
+ public String getDescription() {
+ return "File type " + extension + " " + mimeType;
+ }
+ }
+
+ private Serializable dataflowSource;
+ private String mimeType;
+ private String extension;
+
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ public void setMimeType(String mimeType) {
+ this.mimeType = mimeType;
+ }
+
+ public String getExtension() {
+ return extension;
+ }
+
+ public void setExtension(String extension) {
+ this.extension = extension;
+ }
+
+ public Recent() {
+ }
+
+ public FileType makefileType() {
+ if (mimeType == null && extension == null)
+ return null;
+ return new RecentFileType();
+ }
+
+ public Recent(Serializable dataflowSource, FileType dataflowType) {
+ setDataflowSource(dataflowSource);
+ if (dataflowType != null) {
+ setMimeType(dataflowType.getMimeType());
+ setExtension(dataflowType.getExtension());
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime
+ * result
+ + ((dataflowSource == null) ? 0 : dataflowSource.hashCode());
+ result = prime * result
+ + ((extension == null) ? 0 : extension.hashCode());
+ result = prime * result
+ + ((mimeType == null) ? 0 : mimeType.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof Recent))
+ return false;
+ Recent other = (Recent) obj;
+
+ if (dataflowSource == null) {
+ if (other.dataflowSource != null)
+ return false;
+ } else if (!dataflowSource.equals(other.dataflowSource))
+ return false;
+
+ if (extension == null) {
+ if (other.extension != null)
+ return false;
+ } else if (!extension.equals(other.extension))
+ return false;
+
+ if (mimeType == null) {
+ if (other.mimeType != null)
+ return false;
+ } else if (!mimeType.equals(other.mimeType))
+ return false;
+
+ return true;
+ }
+
+ public Serializable getDataflowSource() {
+ return dataflowSource;
+ }
+
+ public void setDataflowSource(Serializable dataflowSource) {
+ this.dataflowSource = dataflowSource;
+ }
+
+ @Override
+ public String toString() {
+ return getDataflowSource() + "";
+ }
+ }
+
+ // TODO find new serialization
+// protected static class RecentDeserializer extends AbstractXMLDeserializer {
+// public Collection<Recent> deserializeRecent(Element el) {
+// return (Collection<Recent>) super.createBean(el, getClass()
+// .getClassLoader());
+// }
+// }
+//
+// protected static class RecentSerializer extends AbstractXMLSerializer {
+// public Element serializeRecent(List<Recent> x) throws JDOMException,
+// IOException {
+// Element beanAsElement = super.beanAsElement(x);
+// return beanAsElement;
+// }
+// }
+
+ public void setApplicationConfiguration(
+ ApplicationConfiguration applicationConfiguration) {
+ this.applicationConfiguration = applicationConfiguration;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveAllMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveAllMenuAction.java b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveAllMenuAction.java
new file mode 100644
index 0000000..86edacb
--- /dev/null
+++ b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveAllMenuAction.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.file.impl.menu;
+
+import static net.sf.taverna.t2.workbench.file.impl.menu.FileSaveMenuSection.FILE_SAVE_SECTION_URI;
+
+import javax.swing.Action;
+
+import net.sf.taverna.t2.ui.menu.AbstractMenuAction;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.file.impl.actions.SaveAllWorkflowsAction;
+
+public class FileSaveAllMenuAction extends AbstractMenuAction {
+ private final EditManager editManager;
+ private final FileManager fileManager;
+
+ public FileSaveAllMenuAction(EditManager editManager,
+ FileManager fileManager) {
+ super(FILE_SAVE_SECTION_URI, 30);
+ this.editManager = editManager;
+ this.fileManager = fileManager;
+ }
+
+ @Override
+ protected Action createAction() {
+ return new SaveAllWorkflowsAction(editManager, fileManager);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveAsMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveAsMenuAction.java b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveAsMenuAction.java
new file mode 100644
index 0000000..77917c9
--- /dev/null
+++ b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveAsMenuAction.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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.file.impl.menu;
+
+import static net.sf.taverna.t2.workbench.file.impl.menu.FileSaveMenuSection.FILE_SAVE_SECTION_URI;
+
+import javax.swing.Action;
+
+import net.sf.taverna.t2.ui.menu.AbstractMenuAction;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.file.impl.actions.SaveWorkflowAsAction;
+
+public class FileSaveAsMenuAction extends AbstractMenuAction {
+ private final FileManager fileManager;
+
+ public FileSaveAsMenuAction(FileManager fileManager) {
+ super(FILE_SAVE_SECTION_URI, 20);
+ this.fileManager = fileManager;
+ }
+
+ @Override
+ protected Action createAction() {
+ return new SaveWorkflowAsAction(fileManager);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveMenuAction.java b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveMenuAction.java
new file mode 100644
index 0000000..eeaecb3
--- /dev/null
+++ b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveMenuAction.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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.file.impl.menu;
+
+import static net.sf.taverna.t2.workbench.file.impl.menu.FileSaveMenuSection.FILE_SAVE_SECTION_URI;
+
+import javax.swing.Action;
+
+import net.sf.taverna.t2.ui.menu.AbstractMenuAction;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.file.impl.actions.SaveWorkflowAction;
+
+public class FileSaveMenuAction extends AbstractMenuAction {
+ private final EditManager editManager;
+ private final FileManager fileManager;
+
+ public FileSaveMenuAction(EditManager editManager, FileManager fileManager) {
+ super(FILE_SAVE_SECTION_URI, 10);
+ this.editManager = editManager;
+ this.fileManager = fileManager;
+ }
+
+ @Override
+ protected Action createAction() {
+ return new SaveWorkflowAction(editManager, fileManager);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveMenuSection.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveMenuSection.java b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveMenuSection.java
new file mode 100644
index 0000000..a75a855
--- /dev/null
+++ b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/FileSaveMenuSection.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * 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.file.impl.menu;
+
+import java.net.URI;
+
+import net.sf.taverna.t2.ui.menu.AbstractMenuSection;
+
+public class FileSaveMenuSection extends AbstractMenuSection {
+ public static final URI FILE_URI = URI
+ .create("http://taverna.sf.net/2008/t2workbench/menu#file");
+ public static final URI FILE_SAVE_SECTION_URI = URI
+ .create("http://taverna.sf.net/2008/t2workbench/menu#fileSaveSection");
+
+ public FileSaveMenuSection() {
+ super(FILE_URI, 40, FILE_SAVE_SECTION_URI);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/WorkflowsMenu.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/WorkflowsMenu.java b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/WorkflowsMenu.java
new file mode 100644
index 0000000..e056572
--- /dev/null
+++ b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/menu/WorkflowsMenu.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * 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.file.impl.menu;
+
+import static java.awt.event.KeyEvent.VK_0;
+import static java.awt.event.KeyEvent.VK_W;
+import static javax.swing.Action.MNEMONIC_KEY;
+import static javax.swing.SwingUtilities.invokeLater;
+import static net.sf.taverna.t2.ui.menu.DefaultMenuBar.DEFAULT_MENU_BAR;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.ButtonGroup;
+import javax.swing.JMenu;
+import javax.swing.JRadioButtonMenuItem;
+
+import net.sf.taverna.t2.lang.observer.Observable;
+import net.sf.taverna.t2.lang.observer.Observer;
+import net.sf.taverna.t2.ui.menu.AbstractMenuCustom;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.edits.EditManager.AbstractDataflowEditEvent;
+import net.sf.taverna.t2.workbench.edits.EditManager.EditManagerEvent;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.file.events.AbstractDataflowEvent;
+import net.sf.taverna.t2.workbench.file.events.FileManagerEvent;
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+
+public class WorkflowsMenu extends AbstractMenuCustom {
+ private EditManagerObserver editManagerObserver = new EditManagerObserver();
+ private FileManager fileManager;
+ private FileManagerObserver fileManagerObserver = new FileManagerObserver();
+
+ private JMenu workflowsMenu;
+
+ public WorkflowsMenu(EditManager editManager, FileManager fileManager) {
+ super(DEFAULT_MENU_BAR, 900);
+ this.fileManager = fileManager;
+ fileManager.addObserver(fileManagerObserver);
+ editManager.addObserver(editManagerObserver);
+ }
+
+ @Override
+ protected Component createCustomComponent() {
+ DummyAction action = new DummyAction("Workflows");
+ action.putValue(MNEMONIC_KEY, VK_W);
+
+ workflowsMenu = new JMenu(action);
+
+ updateWorkflowsMenu();
+ return workflowsMenu;
+ }
+
+ public void updateWorkflowsMenu() {
+ invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ updateWorkflowsMenuUI();
+ }
+ });
+ }
+
+ protected void updateWorkflowsMenuUI() {
+ workflowsMenu.setEnabled(false);
+ workflowsMenu.removeAll();
+ ButtonGroup workflowsGroup = new ButtonGroup();
+
+ int i = 0;
+ WorkflowBundle currentDataflow = fileManager.getCurrentDataflow();
+ for (WorkflowBundle workflowBundle : fileManager.getOpenDataflows()) {
+ String name = fileManager.getDataflowName(workflowBundle);
+ if (fileManager.isDataflowChanged(workflowBundle))
+ name = "*" + name;
+ // A counter
+ name = ++i + " " + name;
+
+ SwitchWorkflowAction switchWorkflowAction = new SwitchWorkflowAction(
+ name, workflowBundle);
+ if (i < 10)
+ switchWorkflowAction.putValue(MNEMONIC_KEY, new Integer(VK_0
+ + i));
+
+ JRadioButtonMenuItem switchWorkflowMenuItem = new JRadioButtonMenuItem(
+ switchWorkflowAction);
+ workflowsGroup.add(switchWorkflowMenuItem);
+ if (workflowBundle.equals(currentDataflow))
+ switchWorkflowMenuItem.setSelected(true);
+ workflowsMenu.add(switchWorkflowMenuItem);
+ }
+ if (i == 0)
+ workflowsMenu.add(new NoWorkflowsOpen());
+ workflowsMenu.setEnabled(true);
+ workflowsMenu.revalidate();
+ }
+
+ private final class EditManagerObserver implements
+ Observer<EditManagerEvent> {
+ @Override
+ public void notify(Observable<EditManagerEvent> sender,
+ EditManagerEvent message) throws Exception {
+ if (message instanceof AbstractDataflowEditEvent)
+ updateWorkflowsMenu();
+ }
+ }
+
+ private final class FileManagerObserver implements
+ Observer<FileManagerEvent> {
+ @Override
+ public void notify(Observable<FileManagerEvent> sender,
+ FileManagerEvent message) throws Exception {
+ if (message instanceof AbstractDataflowEvent)
+ updateWorkflowsMenu();
+ // TODO: Don't rebuild whole menu
+ }
+ }
+
+ @SuppressWarnings("serial")
+ private final class NoWorkflowsOpen extends AbstractAction {
+ private NoWorkflowsOpen() {
+ super("No workflows open");
+ setEnabled(false);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ // No-op
+ }
+ }
+
+ @SuppressWarnings("serial")
+ private final class SwitchWorkflowAction extends AbstractAction {
+ private final WorkflowBundle workflowBundle;
+
+ private SwitchWorkflowAction(String name, WorkflowBundle workflowBundle) {
+ super(name);
+ this.workflowBundle = workflowBundle;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ fileManager.setCurrentDataflow(workflowBundle);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/CloseToolbarAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/CloseToolbarAction.java b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/CloseToolbarAction.java
new file mode 100644
index 0000000..68ef3f9
--- /dev/null
+++ b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/CloseToolbarAction.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * 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.file.impl.toolbar;
+
+import static net.sf.taverna.t2.workbench.file.impl.toolbar.FileToolbarMenuSection.FILE_TOOLBAR_SECTION;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import net.sf.taverna.t2.ui.menu.AbstractMenuAction;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.file.impl.actions.CloseWorkflowAction;
+
+/**
+ * Action to close the current workflow.
+ *
+ * @author Alex Nenadic
+ */
+public class CloseToolbarAction extends AbstractMenuAction {
+ private static final URI FILE_CLOSE_URI = URI
+ .create("http://taverna.sf.net/2008/t2workbench/menu#fileToolbarClose");
+ private final EditManager editManager;
+ private final FileManager fileManager;
+
+ public CloseToolbarAction(EditManager editManager, FileManager fileManager) {
+ super(FILE_TOOLBAR_SECTION, 30, FILE_CLOSE_URI);
+ this.editManager = editManager;
+ this.fileManager = fileManager;
+ }
+
+ @Override
+ protected Action createAction() {
+ return new CloseWorkflowAction(editManager, fileManager);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/FileToolbarMenuSection.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/FileToolbarMenuSection.java b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/FileToolbarMenuSection.java
new file mode 100644
index 0000000..257d590
--- /dev/null
+++ b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/FileToolbarMenuSection.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * 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.file.impl.toolbar;
+
+import static net.sf.taverna.t2.ui.menu.DefaultToolBar.DEFAULT_TOOL_BAR;
+
+import java.net.URI;
+
+import net.sf.taverna.t2.ui.menu.AbstractMenuSection;
+
+public class FileToolbarMenuSection extends AbstractMenuSection {
+ public static final URI FILE_TOOLBAR_SECTION = URI
+ .create("http://taverna.sf.net/2008/t2workbench/menu#fileToolbarSection");
+
+ public FileToolbarMenuSection() {
+ super(DEFAULT_TOOL_BAR, 10, FILE_TOOLBAR_SECTION);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/NewToolbarAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/NewToolbarAction.java b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/NewToolbarAction.java
new file mode 100644
index 0000000..2c8e922
--- /dev/null
+++ b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/NewToolbarAction.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.file.impl.toolbar;
+
+import static net.sf.taverna.t2.workbench.file.impl.toolbar.FileToolbarMenuSection.FILE_TOOLBAR_SECTION;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import net.sf.taverna.t2.ui.menu.AbstractMenuAction;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.file.impl.actions.NewWorkflowAction;
+
+public class NewToolbarAction extends AbstractMenuAction {
+ private static final URI FILE_NEW_URI = URI
+ .create("http://taverna.sf.net/2008/t2workbench/menu#fileToolbarNew");
+ private final FileManager fileManager;
+
+ public NewToolbarAction(FileManager fileManager) {
+ super(FILE_TOOLBAR_SECTION, 10, FILE_NEW_URI);
+ this.fileManager = fileManager;
+ }
+
+ @Override
+ protected Action createAction() {
+ return new NewWorkflowAction(fileManager);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/OpenToolbarAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/OpenToolbarAction.java b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/OpenToolbarAction.java
new file mode 100644
index 0000000..ae99509
--- /dev/null
+++ b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/OpenToolbarAction.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.file.impl.toolbar;
+
+import static net.sf.taverna.t2.workbench.file.impl.toolbar.FileToolbarMenuSection.FILE_TOOLBAR_SECTION;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import net.sf.taverna.t2.ui.menu.AbstractMenuAction;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.file.impl.actions.OpenWorkflowAction;
+
+public class OpenToolbarAction extends AbstractMenuAction {
+ private static final URI FILE_OPEN_URI = URI
+ .create("http://taverna.sf.net/2008/t2workbench/menu#fileToolbarOpen");
+ private final FileManager fileManager;
+
+ public OpenToolbarAction(FileManager fileManager) {
+ super(FILE_TOOLBAR_SECTION, 20, FILE_OPEN_URI);
+ this.fileManager = fileManager;
+ }
+
+ @Override
+ protected Action createAction() {
+ return new OpenWorkflowAction(fileManager);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/OpenWorkflowFromURLToolbarAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/OpenWorkflowFromURLToolbarAction.java b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/OpenWorkflowFromURLToolbarAction.java
new file mode 100644
index 0000000..2554063
--- /dev/null
+++ b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/OpenWorkflowFromURLToolbarAction.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.file.impl.toolbar;
+
+import static net.sf.taverna.t2.workbench.file.impl.toolbar.FileToolbarMenuSection.FILE_TOOLBAR_SECTION;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import net.sf.taverna.t2.ui.menu.AbstractMenuAction;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.file.impl.actions.OpenWorkflowFromURLAction;
+
+public class OpenWorkflowFromURLToolbarAction extends AbstractMenuAction {
+ private static final URI FILE_OPEN_FROM_URL_URI = URI
+ .create("http://taverna.sf.net/2008/t2workbench/menu#fileToolbarOpenFromURL");
+ private final FileManager fileManager;
+
+ public OpenWorkflowFromURLToolbarAction(FileManager fileManager) {
+ super(FILE_TOOLBAR_SECTION, 25, FILE_OPEN_FROM_URL_URI);
+ this.fileManager = fileManager;
+ }
+
+ @Override
+ protected Action createAction() {
+ return new OpenWorkflowFromURLAction(null, fileManager);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/SaveToolbarAction.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/SaveToolbarAction.java b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/SaveToolbarAction.java
new file mode 100644
index 0000000..53ba720
--- /dev/null
+++ b/taverna-file-impl/src/main/java/net/sf/taverna/t2/workbench/file/impl/toolbar/SaveToolbarAction.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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.file.impl.toolbar;
+
+import static net.sf.taverna.t2.workbench.file.impl.toolbar.FileToolbarMenuSection.FILE_TOOLBAR_SECTION;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import net.sf.taverna.t2.ui.menu.AbstractMenuAction;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.file.impl.actions.SaveWorkflowAction;
+
+public class SaveToolbarAction extends AbstractMenuAction {
+ private static final URI FILE_SAVE_URI = URI
+ .create("http://taverna.sf.net/2008/t2workbench/menu#fileToolbarSave");
+ private final EditManager editManager;
+ private final FileManager fileManager;
+
+ public SaveToolbarAction(EditManager editManager, FileManager fileManager) {
+ super(FILE_TOOLBAR_SECTION, 40, FILE_SAVE_URI);
+ this.editManager = editManager;
+ this.fileManager = fileManager;
+ }
+
+ @Override
+ protected Action createAction() {
+ return new SaveWorkflowAction(editManager, fileManager);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent b/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
new file mode 100644
index 0000000..100915c
--- /dev/null
+++ b/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuComponent
@@ -0,0 +1,20 @@
+net.sf.taverna.t2.workbench.file.impl.menu.FileCloseMenuAction
+net.sf.taverna.t2.workbench.file.impl.menu.FileNewMenuAction
+net.sf.taverna.t2.workbench.file.impl.menu.FileOpenMenuAction
+net.sf.taverna.t2.workbench.file.impl.menu.FileOpenFromURLMenuAction
+net.sf.taverna.t2.workbench.file.impl.menu.FileOpenMenuSection
+net.sf.taverna.t2.workbench.file.impl.menu.FileOpenRecentMenuAction
+net.sf.taverna.t2.workbench.file.impl.menu.FileSaveMenuSection
+net.sf.taverna.t2.workbench.file.impl.menu.FileSaveMenuAction
+net.sf.taverna.t2.workbench.file.impl.menu.FileSaveAllMenuAction
+net.sf.taverna.t2.workbench.file.impl.menu.FileSaveAsMenuAction
+
+net.sf.taverna.t2.workbench.file.impl.menu.WorkflowsMenu
+net.sf.taverna.t2.workbench.file.impl.menu.FileCloseAllMenuAction
+
+net.sf.taverna.t2.workbench.file.impl.toolbar.FileToolbarMenuSection
+net.sf.taverna.t2.workbench.file.impl.toolbar.NewToolbarAction
+net.sf.taverna.t2.workbench.file.impl.toolbar.OpenToolbarAction
+net.sf.taverna.t2.workbench.file.impl.toolbar.OpenWorkflowFromURLToolbarAction
+net.sf.taverna.t2.workbench.file.impl.toolbar.SaveToolbarAction
+net.sf.taverna.t2.workbench.file.impl.toolbar.CloseToolbarAction
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ShutdownSPI
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ShutdownSPI b/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ShutdownSPI
new file mode 100644
index 0000000..cc53d36
--- /dev/null
+++ b/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.ShutdownSPI
@@ -0,0 +1 @@
+net.sf.taverna.t2.workbench.file.impl.hooks.CloseWorkflowsOnShutdown
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.file.DataflowPersistenceHandler
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.file.DataflowPersistenceHandler b/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.file.DataflowPersistenceHandler
new file mode 100644
index 0000000..cfd1c7a
--- /dev/null
+++ b/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.file.DataflowPersistenceHandler
@@ -0,0 +1,2 @@
+net.sf.taverna.t2.workbench.file.impl.T2DataflowOpener
+net.sf.taverna.t2.workbench.file.impl.DataflowFromDataflowPersistenceHandler
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.file.FileManager
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.file.FileManager b/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.file.FileManager
new file mode 100644
index 0000000..656feeb
--- /dev/null
+++ b/taverna-file-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.file.FileManager
@@ -0,0 +1 @@
+net.sf.taverna.t2.workbench.file.impl.FileManagerImpl
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/resources/META-INF/spring/file-impl-context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/resources/META-INF/spring/file-impl-context-osgi.xml b/taverna-file-impl/src/main/resources/META-INF/spring/file-impl-context-osgi.xml
new file mode 100644
index 0000000..7c6e290
--- /dev/null
+++ b/taverna-file-impl/src/main/resources/META-INF/spring/file-impl-context-osgi.xml
@@ -0,0 +1,100 @@
+<?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="FileCloseMenuAction" auto-export="interfaces">
+ <service-properties>
+ <beans:entry key="menu.action" value="file.close" />
+ </service-properties>
+ </service>
+ <service ref="FileNewMenuAction" auto-export="interfaces">
+ <service-properties>
+ <beans:entry key="menu.action" value="file.new" />
+ </service-properties>
+ </service>
+ <service ref="FileOpenMenuAction" auto-export="interfaces">
+ <service-properties>
+ <beans:entry key="menu.action" value="file.open" />
+ </service-properties>
+ </service>
+ <service ref="FileOpenFromURLMenuAction" auto-export="interfaces">
+ <service-properties>
+ <beans:entry key="menu.action" value="file.open.url" />
+ </service-properties>
+ </service>
+ <service ref="FileOpenMenuSection" auto-export="interfaces" />
+ <service ref="FileOpenRecentMenuAction" auto-export="interfaces">
+ <service-properties>
+ <beans:entry key="menu.action" value="file.open.recent" />
+ </service-properties>
+ </service>
+ <service ref="FileSaveMenuSection" auto-export="interfaces" />
+ <service ref="FileSaveMenuAction" auto-export="interfaces">
+ <service-properties>
+ <beans:entry key="menu.action" value="file.save" />
+ </service-properties>
+ </service>
+ <service ref="FileSaveAllMenuAction" auto-export="interfaces">
+ <service-properties>
+ <beans:entry key="menu.action" value="file.save.all" />
+ </service-properties>
+ </service>
+ <service ref="FileSaveAsMenuAction" auto-export="interfaces">
+ <service-properties>
+ <beans:entry key="menu.action" value="file.save.as" />
+ </service-properties>
+ </service>
+ <service ref="WorkflowsMenu" auto-export="interfaces" />
+ <service ref="FileCloseAllMenuAction" auto-export="interfaces">
+ <service-properties>
+ <beans:entry key="menu.action" value="file.close.all" />
+ </service-properties>
+ </service>
+ <service ref="FileToolbarMenuSection" auto-export="interfaces" />
+ <service ref="NewToolbarAction" auto-export="interfaces">
+ <service-properties>
+ <beans:entry key="menu.action" value="toolbar.new" />
+ </service-properties>
+ </service>
+ <service ref="OpenToolbarAction" auto-export="interfaces">
+ <service-properties>
+ <beans:entry key="menu.action" value="toolbar.open" />
+ </service-properties>
+ </service>
+ <service ref="OpenWorkflowFromURLToolbarAction" auto-export="interfaces">
+ <service-properties>
+ <beans:entry key="menu.action" value="toolbar.open.url" />
+ </service-properties>
+ </service>
+ <service ref="SaveToolbarAction" auto-export="interfaces">
+ <service-properties>
+ <beans:entry key="menu.action" value="toolbar.save" />
+ </service-properties>
+ </service>
+ <service ref="CloseToolbarAction" auto-export="interfaces">
+ <service-properties>
+ <beans:entry key="menu.action" value="toolbar.close" />
+ </service-properties>
+ </service>
+
+ <service ref="T2DataflowOpener" interface="net.sf.taverna.t2.workbench.file.DataflowPersistenceHandler" />
+
+ <service ref="WorkflowBundleOpener" interface="net.sf.taverna.t2.workbench.file.DataflowPersistenceHandler" />
+ <service ref="WorkflowBundleSaver" interface="net.sf.taverna.t2.workbench.file.DataflowPersistenceHandler" />
+
+ <service ref="CloseWorkflowsOnShutdown" interface="net.sf.taverna.t2.workbench.ShutdownSPI" />
+
+ <service ref="FileManagerImpl" interface="net.sf.taverna.t2.workbench.file.FileManager" />
+
+ <reference id="editManager" interface="net.sf.taverna.t2.workbench.edits.EditManager" />
+ <reference id="applicationConfiguration" interface="uk.org.taverna.configuration.app.ApplicationConfiguration" />
+ <reference id="workflowBundleIO" interface="uk.org.taverna.scufl2.api.io.WorkflowBundleIO" />
+
+ <list id="dataflowPersistenceHandlers" interface="net.sf.taverna.t2.workbench.file.DataflowPersistenceHandler" cardinality="0..N">
+ <listener ref="DataflowPersistenceHandlerRegistry" bind-method="update" unbind-method="update" />
+ </list>
+</beans:beans>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/main/resources/META-INF/spring/file-impl-context.xml
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/main/resources/META-INF/spring/file-impl-context.xml b/taverna-file-impl/src/main/resources/META-INF/spring/file-impl-context.xml
new file mode 100644
index 0000000..493df5f
--- /dev/null
+++ b/taverna-file-impl/src/main/resources/META-INF/spring/file-impl-context.xml
@@ -0,0 +1,123 @@
+<?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="FileCloseMenuAction" class="net.sf.taverna.t2.workbench.file.impl.menu.FileCloseMenuAction">
+ <constructor-arg ref="editManager" />
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ </bean>
+ <bean id="FileNewMenuAction" class="net.sf.taverna.t2.workbench.file.impl.menu.FileNewMenuAction">
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ </bean>
+ <bean id="FileOpenMenuAction" class="net.sf.taverna.t2.workbench.file.impl.menu.FileOpenMenuAction">
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ </bean>
+ <bean id="FileOpenFromURLMenuAction" class="net.sf.taverna.t2.workbench.file.impl.menu.FileOpenFromURLMenuAction">
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ </bean>
+ <bean id="FileOpenMenuSection" class="net.sf.taverna.t2.workbench.file.impl.menu.FileOpenMenuSection" />
+ <bean id="FileOpenRecentMenuAction" class="net.sf.taverna.t2.workbench.file.impl.menu.FileOpenRecentMenuAction">
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ <property name="applicationConfiguration" ref="applicationConfiguration"/>
+ </bean>
+ <bean id="FileSaveMenuSection" class="net.sf.taverna.t2.workbench.file.impl.menu.FileSaveMenuSection" />
+ <bean id="FileSaveMenuAction" class="net.sf.taverna.t2.workbench.file.impl.menu.FileSaveMenuAction">
+ <constructor-arg ref="editManager" />
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ </bean>
+ <bean id="FileSaveAllMenuAction" class="net.sf.taverna.t2.workbench.file.impl.menu.FileSaveAllMenuAction">
+ <constructor-arg ref="editManager" />
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ </bean>
+ <bean id="FileSaveAsMenuAction" class="net.sf.taverna.t2.workbench.file.impl.menu.FileSaveAsMenuAction">
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ </bean>
+ <bean id="WorkflowsMenu" class="net.sf.taverna.t2.workbench.file.impl.menu.WorkflowsMenu">
+ <constructor-arg ref="editManager" />
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ </bean>
+ <bean id="FileCloseAllMenuAction" class="net.sf.taverna.t2.workbench.file.impl.menu.FileCloseAllMenuAction">
+ <constructor-arg ref="editManager" />
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ </bean>
+ <bean id="FileToolbarMenuSection" class="net.sf.taverna.t2.workbench.file.impl.toolbar.FileToolbarMenuSection" />
+ <bean id="NewToolbarAction" class="net.sf.taverna.t2.workbench.file.impl.toolbar.NewToolbarAction">
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ </bean>
+ <bean id="OpenToolbarAction" class="net.sf.taverna.t2.workbench.file.impl.toolbar.OpenToolbarAction">
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ </bean>
+ <bean id="OpenWorkflowFromURLToolbarAction" class="net.sf.taverna.t2.workbench.file.impl.toolbar.OpenWorkflowFromURLToolbarAction">
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ </bean>
+ <bean id="SaveToolbarAction" class="net.sf.taverna.t2.workbench.file.impl.toolbar.SaveToolbarAction">
+ <constructor-arg ref="editManager" />
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ </bean>
+ <bean id="CloseToolbarAction" class="net.sf.taverna.t2.workbench.file.impl.toolbar.CloseToolbarAction">
+ <constructor-arg ref="editManager" />
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ </bean>
+
+ <bean id="T2DataflowOpener" class="net.sf.taverna.t2.workbench.file.impl.T2DataflowOpener">
+ <property name="workflowBundleIO" ref="workflowBundleIO"/>
+ </bean>
+
+ <bean id="WorkflowBundleOpener" class="net.sf.taverna.t2.workbench.file.impl.WorkflowBundleOpener">
+ <property name="workflowBundleIO" ref="workflowBundleIO"/>
+ </bean>
+ <bean id="WorkflowBundleSaver" class="net.sf.taverna.t2.workbench.file.impl.WorkflowBundleSaver">
+ <property name="workflowBundleIO" ref="workflowBundleIO"/>
+ </bean>
+
+ <bean id="CloseWorkflowsOnShutdown" class="net.sf.taverna.t2.workbench.file.impl.hooks.CloseWorkflowsOnShutdown">
+ <constructor-arg ref="editManager" />
+ <constructor-arg>
+ <ref local="FileManagerImpl" />
+ </constructor-arg>
+ </bean>
+
+ <bean id="FileManagerImpl" class="net.sf.taverna.t2.workbench.file.impl.FileManagerImpl">
+ <constructor-arg name="editManager" ref="editManager" />
+ <property name="dataflowPersistenceHandlerRegistry">
+ <ref local="DataflowPersistenceHandlerRegistry"/>
+ </property>
+ </bean>
+
+ <bean id="DataflowPersistenceHandlerRegistry" class="net.sf.taverna.t2.workbench.file.impl.DataflowPersistenceHandlerRegistry">
+ <property name="dataflowPersistenceHandlers" ref="dataflowPersistenceHandlers" />
+ </bean>
+
+
+</beans>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/test/java/net/sf/taverna/t2/workbench/file/impl/FileManagerTest.java
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/test/java/net/sf/taverna/t2/workbench/file/impl/FileManagerTest.java b/taverna-file-impl/src/test/java/net/sf/taverna/t2/workbench/file/impl/FileManagerTest.java
new file mode 100644
index 0000000..691b278
--- /dev/null
+++ b/taverna-file-impl/src/test/java/net/sf/taverna/t2/workbench/file/impl/FileManagerTest.java
@@ -0,0 +1,385 @@
+/*******************************************************************************
+ * 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.file.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import net.sf.taverna.t2.lang.observer.Observable;
+import net.sf.taverna.t2.lang.observer.Observer;
+import net.sf.taverna.t2.workbench.edits.Edit;
+import net.sf.taverna.t2.workbench.edits.EditManager;
+import net.sf.taverna.t2.workbench.edits.impl.EditManagerImpl;
+import net.sf.taverna.t2.workbench.file.DataflowInfo;
+import net.sf.taverna.t2.workbench.file.DataflowPersistenceHandler;
+import net.sf.taverna.t2.workbench.file.FileManager;
+import net.sf.taverna.t2.workbench.file.events.FileManagerEvent;
+import net.sf.taverna.t2.workbench.file.events.SetCurrentDataflowEvent;
+import net.sf.taverna.t2.workbench.file.exceptions.OpenException;
+import net.sf.taverna.t2.workbench.file.exceptions.OverwriteException;
+import net.sf.taverna.t2.workflow.edits.AddProcessorEdit;
+import net.sf.taverna.t2.workflow.edits.RenameEdit;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+import uk.org.taverna.scufl2.api.core.Processor;
+import uk.org.taverna.scufl2.api.core.Workflow;
+import uk.org.taverna.scufl2.api.io.WorkflowBundleIO;
+import uk.org.taverna.scufl2.api.io.WorkflowBundleReader;
+import uk.org.taverna.scufl2.api.io.WorkflowBundleWriter;
+import uk.org.taverna.scufl2.rdfxml.RDFXMLReader;
+import uk.org.taverna.scufl2.rdfxml.RDFXMLWriter;
+import uk.org.taverna.scufl2.translator.t2flow.T2FlowReader;
+
+public class FileManagerTest {
+
+ private static final WorkflowBundleFileType WF_BUNDLE_FILE_TYPE = new WorkflowBundleFileType();
+ private static final T2FlowFileType T2_FLOW_FILE_TYPE = new T2FlowFileType();
+
+ private static final String DUMMY_WORKFLOW_T2FLOW = "dummy-workflow.t2flow";
+
+ private FileManagerImpl fileManager;
+ private EditManager editManager;
+
+ private FileManagerObserver fileManagerObserver= new FileManagerObserver();;
+
+ @Test
+ public void close() throws Exception {
+ assertTrue("Non-empty set of open dataflows", fileManager
+ .getOpenDataflows().isEmpty());
+ WorkflowBundle dataflow = openDataflow();
+ assertEquals("Unexpected list of open dataflows", Arrays
+ .asList(dataflow), fileManager.getOpenDataflows());
+ fileManager.closeDataflow(dataflow, true);
+ assertNotSame(dataflow, fileManager.getOpenDataflows().get(0));
+ assertTrue("Did not insert empty dataflow after close", fileManager
+ .getOpenDataflows().get(0).getMainWorkflow().getProcessors().isEmpty());
+ }
+
+ @Test
+ public void openRemovesEmptyDataflow() throws Exception {
+ WorkflowBundle newDataflow = fileManager.newDataflow();
+ assertEquals("Unexpected list of open dataflows", Arrays
+ .asList(newDataflow), fileManager.getOpenDataflows());
+ WorkflowBundle dataflow = openDataflow();
+ // Should have removed newDataflow
+ assertEquals("Unexpected list of open dataflows", Arrays
+ .asList(dataflow), fileManager.getOpenDataflows());
+ }
+
+ @Test
+ public void isChanged() throws Exception {
+ WorkflowBundle dataflow = openDataflow();
+ assertFalse("Dataflow should not have changed", fileManager
+ .isDataflowChanged(dataflow));
+
+ // Do a change
+ Processor emptyProcessor = new Processor();
+ Edit<Workflow> addProcessorEdit = new AddProcessorEdit(dataflow.getMainWorkflow(),
+ emptyProcessor);
+ editManager.doDataflowEdit(dataflow, addProcessorEdit);
+ assertTrue("Dataflow should have changed", fileManager
+ .isDataflowChanged(dataflow));
+
+ // Save it with the change
+ File dataflowFile = File.createTempFile("test", ".t2flow");
+ dataflowFile.deleteOnExit();
+ dataflowFile.delete();
+
+ fileManager.saveDataflow(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, false);
+ assertFalse("Dataflow should no longer be marked as changed",
+ fileManager.isDataflowChanged(dataflow));
+ }
+
+ @Ignore("Undo support for ischanged not yet implemented")
+ @Test
+ public void isChangedWithUndo() throws Exception {
+ WorkflowBundle dataflow = openDataflow();
+ // Do a change
+ Processor emptyProcessor = new Processor();
+ Edit<Workflow> addProcessorEdit = new AddProcessorEdit(dataflow.getMainWorkflow(),
+ emptyProcessor);
+ editManager.doDataflowEdit(dataflow, addProcessorEdit);
+ assertTrue("Dataflow should have changed", fileManager
+ .isDataflowChanged(dataflow));
+ editManager.undoDataflowEdit(dataflow);
+ assertFalse(
+ "Dataflow should no longer be marked as changed after undo",
+ fileManager.isDataflowChanged(dataflow));
+ editManager.redoDataflowEdit(dataflow);
+ assertTrue("Dataflow should have changed after redo before save",
+ fileManager.isDataflowChanged(dataflow));
+
+ // Save it with the change
+ File dataflowFile = File.createTempFile("test", ".t2flow");
+ dataflowFile.deleteOnExit();
+ dataflowFile.delete();
+ fileManager.saveDataflow(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, false);
+ assertFalse("Dataflow should no longer be marked as changed",
+ fileManager.isDataflowChanged(dataflow));
+
+ editManager.undoDataflowEdit(dataflow);
+ assertTrue("Dataflow should have changed after undo", fileManager
+ .isDataflowChanged(dataflow));
+ fileManager.saveDataflow(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, false);
+ editManager.redoDataflowEdit(dataflow);
+ assertTrue("Dataflow should have changed after redo after save",
+ fileManager.isDataflowChanged(dataflow));
+ }
+
+ @Test
+ public void isListed() throws Exception {
+ assertTrue("Non-empty set of open data flows", fileManager
+ .getOpenDataflows().isEmpty());
+ WorkflowBundle dataflow = openDataflow();
+ assertEquals("Unexpected list of open dataflows", Arrays
+ .asList(dataflow), fileManager.getOpenDataflows());
+ }
+
+ /**
+ * Always uses a <strong>new</strong> file manager instead of the instance
+ * one from {@link FileManager#getInstance()}.
+ *
+ * @see #getFileManagerInstance()
+ *
+ */
+ @Before
+ public void makeFileManager() {
+ System.setProperty("java.awt.headless", "true");
+ editManager = new EditManagerImpl();
+ fileManager = new FileManagerImpl(editManager);
+ fileManagerObserver = new FileManagerObserver();
+ fileManager.addObserver(fileManagerObserver);
+ WorkflowBundleIO workflowBundleIO = new WorkflowBundleIO();
+ workflowBundleIO.setReaders(Arrays.<WorkflowBundleReader>asList(new RDFXMLReader(), new T2FlowReader()));
+ workflowBundleIO.setWriters(Arrays.<WorkflowBundleWriter>asList(new RDFXMLWriter()));
+ T2DataflowOpener t2DataflowOpener = new T2DataflowOpener();
+ t2DataflowOpener.setWorkflowBundleIO(workflowBundleIO);
+ WorkflowBundleOpener workflowBundleOpener = new WorkflowBundleOpener();
+ workflowBundleOpener.setWorkflowBundleIO(workflowBundleIO);
+ WorkflowBundleSaver workflowBundleSaver = new WorkflowBundleSaver();
+ workflowBundleSaver.setWorkflowBundleIO(workflowBundleIO);
+ DataflowPersistenceHandlerRegistry dataflowPersistenceHandlerRegistry = new DataflowPersistenceHandlerRegistry();
+ dataflowPersistenceHandlerRegistry.setDataflowPersistenceHandlers(Arrays.asList(
+ new DataflowPersistenceHandler[] {t2DataflowOpener, workflowBundleOpener, workflowBundleSaver}));
+ dataflowPersistenceHandlerRegistry.updateColletions();
+ fileManager.setDataflowPersistenceHandlerRegistry(dataflowPersistenceHandlerRegistry);
+ }
+
+ @Test
+ public void open() throws Exception {
+ assertTrue("ModelMapObserver already contained messages",
+ fileManagerObserver.messages.isEmpty());
+ WorkflowBundle dataflow = openDataflow();
+ assertNotNull("Dataflow was not loaded", dataflow);
+ assertEquals("Loaded dataflow was not set as current dataflow",
+ dataflow, fileManager.getCurrentDataflow());
+ assertFalse("ModelMapObserver did not contain message",
+ fileManagerObserver.messages.isEmpty());
+ assertEquals("ModelMapObserver contained unexpected messages", 2,
+ fileManagerObserver.messages.size());
+ FileManagerEvent event = fileManagerObserver.messages.get(0);
+ assertTrue(event instanceof SetCurrentDataflowEvent);
+ assertEquals(dataflow, ((SetCurrentDataflowEvent) event).getDataflow());
+ }
+
+ @Test
+ public void openSilently() throws Exception {
+ assertTrue("ModelMapObserver already contained messages",
+ fileManagerObserver.messages.isEmpty());
+ URL url = getClass().getResource(DUMMY_WORKFLOW_T2FLOW);
+ DataflowInfo info = fileManager.openDataflowSilently(T2_FLOW_FILE_TYPE, url);
+
+ WorkflowBundle dataflow = info.getDataflow();
+ assertNotNull("Dataflow was not loaded", dataflow);
+
+ assertNotSame("Loaded dataflow was set as current dataflow",
+ dataflow, fileManager.getCurrentDataflow());
+ assertTrue("ModelMapObserver contained unexpected messages",
+ fileManagerObserver.messages.isEmpty());
+ }
+
+ @Test
+ public void canSaveDataflow() throws Exception {
+ WorkflowBundle savedDataflow = openDataflow();
+ File dataflowFile = File.createTempFile("test", ".t2flow");
+ dataflowFile.deleteOnExit();
+ dataflowFile.delete();
+ fileManager.saveDataflow(savedDataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, true);
+ assertTrue(fileManager.canSaveWithoutDestination(savedDataflow));
+ fileManager.saveDataflow(savedDataflow, true);
+ fileManager.closeDataflow(savedDataflow, true);
+
+ WorkflowBundle otherFlow = fileManager.openDataflow(WF_BUNDLE_FILE_TYPE, dataflowFile.toURI()
+ .toURL());
+ assertTrue(fileManager.canSaveWithoutDestination(otherFlow));
+ }
+
+ @Test
+ public void save() throws Exception {
+ WorkflowBundle savedDataflow = openDataflow();
+ File dataflowFile = File.createTempFile("test", ".t2flow");
+ dataflowFile.deleteOnExit();
+ dataflowFile.delete();
+ assertFalse("File should not exist", dataflowFile.isFile());
+ fileManager.saveDataflow(savedDataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, false);
+ assertTrue("File should exist", dataflowFile.isFile());
+ WorkflowBundle loadedDataflow = fileManager.openDataflow(WF_BUNDLE_FILE_TYPE, dataflowFile.toURI()
+ .toURL());
+ assertNotSame("Dataflow was not reopened", savedDataflow,
+ loadedDataflow);
+ assertEquals("Unexpected number of processors in saved dataflow", 1,
+ savedDataflow.getMainWorkflow().getProcessors().size());
+ assertEquals("Unexpected number of processors in loaded dataflow", 1,
+ loadedDataflow.getMainWorkflow().getProcessors().size());
+
+ Processor savedProcessor = savedDataflow.getMainWorkflow().getProcessors().first();
+ Processor loadedProcessor = loadedDataflow.getMainWorkflow().getProcessors().first();
+ assertEquals("Loaded processor had wrong name", savedProcessor
+ .getName(), loadedProcessor.getName());
+
+ // TODO convert to scufl2
+// BeanshellActivity savedActivity = (BeanshellActivity) savedProcessor
+// .getActivityList().get(0);
+// BeanshellActivity loadedActivity = (BeanshellActivity) loadedProcessor
+// .getActivityList().get(0);
+// String savedScript = savedActivity.getConfiguration().getScript();
+// String loadedScript = loadedActivity.getConfiguration().getScript();
+// assertEquals("Unexpected saved script",
+// "String output = input + \"XXX\";", savedScript);
+// assertEquals("Loaded script did not matched saved script", savedScript,
+// loadedScript);
+ }
+
+ @Test
+ public void saveSilent() throws Exception {
+ assertTrue("ModelMapObserver contained unexpected messages",
+ fileManagerObserver.messages.isEmpty());
+
+ URL url = getClass().getResource(DUMMY_WORKFLOW_T2FLOW);
+ DataflowInfo info = fileManager.openDataflowSilently(T2_FLOW_FILE_TYPE, url);
+ WorkflowBundle dataflow = info.getDataflow();
+ assertTrue("ModelMapObserver contained unexpected messages",
+ fileManagerObserver.messages.isEmpty());
+
+ File dataflowFile = File.createTempFile("test", ".t2flow");
+ dataflowFile.deleteOnExit();
+ dataflowFile.delete();
+ assertFalse("File should not exist", dataflowFile.isFile());
+
+ fileManager.saveDataflowSilently(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, false);
+ assertTrue("File should exist", dataflowFile.isFile());
+
+ assertTrue("ModelMapObserver contained unexpected messages",
+ fileManagerObserver.messages.isEmpty());
+
+ }
+
+ @Test
+ public void saveOverwriteAgain() throws Exception {
+ WorkflowBundle dataflow = openDataflow();
+ File dataflowFile = File.createTempFile("test", ".t2flow");
+ dataflowFile.delete();
+ dataflowFile.deleteOnExit();
+ // File did NOT exist, should not fail
+ fileManager.saveDataflow(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, true);
+
+ Processor processor = dataflow.getMainWorkflow().getProcessors().first();
+ Edit<Processor> renameEdit = new RenameEdit<Processor>(processor,
+ processor.getName() + "-changed");
+ editManager.doDataflowEdit(dataflow, renameEdit);
+
+ // Last save was OURs, so should *not* fail - even if we now use
+ // the specific saveDataflow() method
+ fileManager.saveDataflow(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, true);
+
+ //Thread.sleep(1500);
+ WorkflowBundle otherFlow = openDataflow();
+ // Saving another flow to same file should still fail
+ try {
+ fileManager.saveDataflow(otherFlow,WF_BUNDLE_FILE_TYPE, dataflowFile, true);
+ fail("Should have thrown OverwriteException");
+ } catch (OverwriteException ex) {
+ // Expected
+ }
+ }
+
+ @Test(expected = OverwriteException.class)
+ public void saveOverwriteWarningFails() throws Exception {
+ WorkflowBundle dataflow = openDataflow();
+ File dataflowFile = File.createTempFile("test", ".t2flow");
+ dataflowFile.deleteOnExit();
+ // Should fail as file already exists
+ fileManager.saveDataflow(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, true);
+ }
+
+ @Test
+ public void saveOverwriteWarningWorks() throws Exception {
+ WorkflowBundle dataflow = openDataflow();
+ File dataflowFile = File.createTempFile("test", ".t2flow");
+ dataflowFile.delete();
+ dataflowFile.deleteOnExit();
+ // File did NOT exist, should not fail
+ fileManager.saveDataflow(dataflow, WF_BUNDLE_FILE_TYPE, dataflowFile, true);
+ }
+
+ @After
+ public void stopListeningToModelMap() {
+ fileManager.removeObserver(fileManagerObserver);
+ }
+
+ protected WorkflowBundle openDataflow() throws OpenException {
+ URL url = getClass().getResource(DUMMY_WORKFLOW_T2FLOW);
+ assertNotNull(url);
+ WorkflowBundle dataflow = fileManager.openDataflow(T2_FLOW_FILE_TYPE, url);
+ assertNotNull(dataflow);
+ return dataflow;
+ }
+
+ private final class FileManagerObserver implements Observer<FileManagerEvent> {
+ protected List<FileManagerEvent> messages = new ArrayList<FileManagerEvent>();
+
+ @Override
+ public void notify(Observable<FileManagerEvent> sender, FileManagerEvent message) throws Exception {
+ messages.add(message);
+ if (message instanceof SetCurrentDataflowEvent) {
+ assertTrue("Dataflow was not listed as open when set current",
+ fileManager.getOpenDataflows().contains(
+ ((SetCurrentDataflowEvent) message).getDataflow()));
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-file-impl/src/test/resources/net/sf/taverna/t2/workbench/file/impl/dummy-workflow.t2flow
----------------------------------------------------------------------
diff --git a/taverna-file-impl/src/test/resources/net/sf/taverna/t2/workbench/file/impl/dummy-workflow.t2flow b/taverna-file-impl/src/test/resources/net/sf/taverna/t2/workbench/file/impl/dummy-workflow.t2flow
new file mode 100644
index 0000000..b9a1075
--- /dev/null
+++ b/taverna-file-impl/src/test/resources/net/sf/taverna/t2/workbench/file/impl/dummy-workflow.t2flow
@@ -0,0 +1,157 @@
+<workflow xmlns="http://taverna.sf.net/2008/xml/t2flow" version="1" producedBy="test">
+ <dataflow id="ec0991ba-275c-49ed-b1d6-38534180fb7c" role="top">
+ <name>simple_workflow_with_input</name>
+ <inputPorts>
+ <port>
+ <name>input</name>
+ <depth>0</depth>
+ <granularDepth>0</granularDepth>
+ </port>
+ </inputPorts>
+ <outputPorts>
+ <port>
+ <name>output</name>
+ </port>
+ </outputPorts>
+ <processors>
+ <processor>
+ <name>Concat_XXX</name>
+ <inputPorts>
+ <port>
+ <name>input</name>
+ <depth>0</depth>
+ </port>
+ </inputPorts>
+ <outputPorts>
+ <port>
+ <name>output</name>
+ <depth>0</depth>
+ <granularDepth>0</granularDepth>
+ </port>
+ </outputPorts>
+ <annotations />
+ <activities>
+ <activity>
+ <class>
+ net.sf.taverna.t2.activities.beanshell.BeanshellActivity
+ </class>
+ <inputMap>
+ <map from="input" to="input" />
+ </inputMap>
+ <outputMap>
+ <map from="output" to="output" />
+ </outputMap>
+ <configBean encoding="xstream">
+ <net.sf.taverna.t2.activities.beanshell.BeanshellActivityConfigurationBean
+ xmlns="">
+ <script>String output = input + "XXX";</script>
+ <dependencies />
+ <inputs>
+ <net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean>
+ <handledReferenceSchemes />
+ <translatedElementType>java.lang.String</translatedElementType>
+ <allowsLiteralValues>true</allowsLiteralValues>
+ <name>input</name>
+ <depth>0</depth>
+ <mimeTypes>
+ <string>'text/plain'</string>
+ </mimeTypes>
+ </net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean>
+ </inputs>
+ <outputs>
+ <net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityOutputPortDefinitionBean>
+ <granularDepth>0</granularDepth>
+ <name>output</name>
+ <depth>0</depth>
+ <mimeTypes>
+ <string>'text/plain'</string>
+ </mimeTypes>
+ </net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityOutputPortDefinitionBean>
+ </outputs>
+ </net.sf.taverna.t2.activities.beanshell.BeanshellActivityConfigurationBean>
+ </configBean>
+ </activity>
+ </activities>
+ <dispatchStack>
+ <dispatchLayer>
+ <class>
+ net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Parallelize
+ </class>
+ <configBean encoding="xstream">
+ <net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.ParallelizeConfig
+ xmlns="">
+ <maxJobs>1</maxJobs>
+ </net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.ParallelizeConfig>
+ </configBean>
+ </dispatchLayer>
+ <dispatchLayer>
+ <class>
+ net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.ErrorBounce
+ </class>
+ <configBean encoding="xstream">
+ <null xmlns="" />
+ </configBean>
+ </dispatchLayer>
+ <dispatchLayer>
+ <class>
+ net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Failover
+ </class>
+ <configBean encoding="xstream">
+ <null xmlns="" />
+ </configBean>
+ </dispatchLayer>
+ <dispatchLayer>
+ <class>
+ net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Retry
+ </class>
+ <configBean encoding="xstream">
+ <net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.RetryConfig
+ xmlns="">
+ <backoffFactor>1.0</backoffFactor>
+ <initialDelay>0</initialDelay>
+ <maxDelay>0</maxDelay>
+ <maxRetries>0</maxRetries>
+ </net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.RetryConfig>
+ </configBean>
+ </dispatchLayer>
+ <dispatchLayer>
+ <class>
+ net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Invoke
+ </class>
+ <configBean encoding="xstream">
+ <null xmlns="" />
+ </configBean>
+ </dispatchLayer>
+ </dispatchStack>
+ <iterationStrategyStack>
+ <iteration>
+ <strategy>
+ <port name="input" depth="0" />
+ </strategy>
+ </iteration>
+ </iterationStrategyStack>
+ </processor>
+ </processors>
+ <conditions />
+ <datalinks>
+ <datalink>
+ <sink type="processor">
+ <processor>Concat_XXX</processor>
+ <port>input</port>
+ </sink>
+ <source type="dataflow">
+ <port>input</port>
+ </source>
+ </datalink>
+ <datalink>
+ <sink type="dataflow">
+ <port>output</port>
+ </sink>
+ <source type="processor">
+ <processor>Concat_XXX</processor>
+ <port>output</port>
+ </source>
+ </datalink>
+ </datalinks>
+ </dataflow>
+</workflow>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/52fd79dd/taverna-graph-model/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-graph-model/pom.xml b/taverna-graph-model/pom.xml
new file mode 100644
index 0000000..c608f3a
--- /dev/null
+++ b/taverna-graph-model/pom.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.taverna.workbench</groupId>
+ <artifactId>taverna-workbench</artifactId>
+ <version>3.1.0-incubating-SNAPSHOT</version>
+ </parent>
+ <artifactId>taverna-graph-model</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Taverna Graph Model</name>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>javacc-maven-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <execution>
+ <id>javacc</id>
+ <goals>
+ <goal>jjtree-javacc</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+ <plugin>
+ <groupId>org.eclipse.m2e</groupId>
+ <artifactId>lifecycle-mapping</artifactId>
+ <version>1.0.0</version>
+ <configuration>
+ <lifecycleMappingMetadata>
+ <pluginExecutions>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>
+ org.codehaus.mojo
+ </groupId>
+ <artifactId>
+ javacc-maven-plugin
+ </artifactId>
+ <versionRange>
+ [2.6,)
+ </versionRange>
+ <goals>
+ <goal>jjtree-javacc</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <execute>
+ <runOnIncremental>false</runOnIncremental>
+ </execute>
+ </action>
+ </pluginExecution>
+ </pluginExecutions>
+ </lifecycleMappingMetadata>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>${project.parent.groupId}</groupId>
+ <artifactId>taverna-configuration-api</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.parent.groupId}</groupId>
+ <artifactId>taverna-edits-api</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.parent.groupId}</groupId>
+ <artifactId>taverna-menu-api</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.parent.groupId}</groupId>
+ <artifactId>taverna-selection-api</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.parent.groupId}</groupId>
+ <artifactId>taverna-onfiguration-impl</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.taverna.engine</groupId>
+ <artifactId>taverna-observer</artifactId>
+ <version>${taverna.engine.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.parent.groupId}</groupId>
+ <artifactId>taverna.io</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.taverna.language</groupId>
+ <artifactId>taverna-scufl2-api</artifactId>
+ <version>${taverna.language.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.batik</groupId>
+ <artifactId>batik-osgi</artifactId>
+ <version>${batik.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-beanutils</groupId>
+ <artifactId>commons-beanutils</artifactId>
+ <version>${commons.beanutils.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>${log4j.version}</version>
+ </dependency>
+
+ </dependencies>
+</project>