You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2015/02/17 12:45:30 UTC

[06/52] [abbrv] incubator-taverna-workbench git commit: taverna-ui-impl/

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/plugins/ui/PluginSiteFrame.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/plugins/ui/PluginSiteFrame.java b/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/plugins/ui/PluginSiteFrame.java
new file mode 100644
index 0000000..ecdb06e
--- /dev/null
+++ b/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/plugins/ui/PluginSiteFrame.java
@@ -0,0 +1,542 @@
+/*******************************************************************************
+ * Copyright (C) 2007-2010 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
+ ******************************************************************************/
+/*
+ * Copyright (C) 2003 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.  Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * 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
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename           $RCSfile: PluginSiteFrame.java,v $
+ * Revision           $Revision: 1.3 $
+ * Release status     $State: Exp $
+ * Last modified on   $Date: 2008/10/27 13:39:56 $
+ *               by   $Author: stain $
+ * Created on 29 Nov 2006
+ *****************************************************************/
+package net.sf.taverna.raven.plugins.ui;
+
+import java.awt.Color;
+import java.awt.Font;
+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.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JProgressBar;
+import javax.swing.JScrollPane;
+import javax.swing.border.EtchedBorder;
+
+import uk.org.taverna.commons.plugin.PluginManager;
+
+import net.sf.taverna.t2.workbench.helper.HelpEnabledDialog;
+
+
+/**
+ *
+ * @author David Withers
+ */
+public class PluginSiteFrame extends HelpEnabledDialog {
+
+	private static final long serialVersionUID = 1L;
+
+	private PluginManager pluginManager;
+
+	private List<PluginSite> pluginSites;
+
+	private List<Plugin> installationScheduled = new ArrayList<Plugin>(); // @jve:decl-index=0:
+
+	private JButton installButton = null; // @jve:decl-index=0:visual-constraint="446,247"
+
+	private JButton cancelButton = null;
+
+	private JButton addSiteButton = null;
+
+	private Map<Plugin, PluginRepositoryListener> listeners = new HashMap<Plugin, PluginRepositoryListener>();
+
+	private AddPluginSiteFrame addSiteFrame = null;
+
+	private JScrollPane scrollPane = null;
+
+	/**
+	 * This is the default constructor
+	 */
+	public PluginSiteFrame(Frame owner) {
+		super(owner, "Update sites", true);
+		initialize();
+	}
+
+	/**
+	 * This is the default constructor
+	 */
+	public PluginSiteFrame(JDialog owner) {
+		super(owner, "Update sites", true);
+		initialize();
+	}
+
+	/**
+	 * This method initializes this
+	 *
+	 * @return void
+	 */
+	private void initialize() {
+		this.pluginManager = PluginManager.getInstance();
+		this.pluginSites = this.pluginManager.getPluginSites();
+		this.setSize(600, 450);
+		this.setContentPane(getJContentPane());
+	}
+
+	/**
+	 * This method initializes jContentPane
+	 *
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getJContentPane() {
+		GridBagConstraints gridBagConstraints14 = new GridBagConstraints();
+		gridBagConstraints14.gridx = 1;
+		gridBagConstraints14.anchor = GridBagConstraints.SOUTHWEST;
+		gridBagConstraints14.gridy = GridBagConstraints.RELATIVE;
+		gridBagConstraints14.insets = new Insets(5, 5, 5, 5);
+		GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
+		gridBagConstraints12.fill = GridBagConstraints.BOTH;
+		gridBagConstraints12.gridx = 0;
+		gridBagConstraints12.gridy = 0;
+		gridBagConstraints12.weightx = 1.0;
+		gridBagConstraints12.weighty = 1.0;
+		gridBagConstraints12.gridwidth = 3;
+		gridBagConstraints12.anchor = GridBagConstraints.NORTHWEST;
+		GridBagConstraints gridBagConstraints = new GridBagConstraints();
+		gridBagConstraints.gridx = 0;
+		gridBagConstraints.gridy = GridBagConstraints.RELATIVE;
+		gridBagConstraints.anchor = GridBagConstraints.SOUTHWEST;
+		gridBagConstraints.insets = new Insets(5, 5, 5, 5);
+		GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
+		gridBagConstraints1.gridx = 2;
+		gridBagConstraints1.gridy = GridBagConstraints.RELATIVE;
+		gridBagConstraints1.anchor = GridBagConstraints.SOUTHEAST;
+		gridBagConstraints1.insets = new Insets(5, 5, 5, 5);
+		JPanel jContentPane = new JPanel();
+		jContentPane.setLayout(new GridBagLayout());
+		jContentPane.add(getJScrollPane(), gridBagConstraints12);
+		jContentPane.add(getInstallButton(), gridBagConstraints);
+		jContentPane.add(getCloseButton(), gridBagConstraints1);
+		jContentPane.add(getAddPluginSiteButton(), gridBagConstraints14);
+		return jContentPane;
+	}
+
+	/**
+	 * This method initializes jScrollPane
+	 *
+	 * @return javax.swing.JScrollPane
+	 */
+	private JScrollPane getJScrollPane() {
+		scrollPane = new JScrollPane();
+		scrollPane.setViewportView(getJPanel());
+		return scrollPane;
+	}
+
+	/**
+	 * This method initializes jPanel
+	 *
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getJPanel() {
+		JPanel jPanel = new JPanel();
+		jPanel.setLayout(new GridBagLayout());
+		for (PluginSite pluginSite : pluginSites) {
+			GridBagConstraints gridBagConstraints = new GridBagConstraints();
+			gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
+			gridBagConstraints.gridx = 0;
+			gridBagConstraints.gridy = GridBagConstraints.RELATIVE;
+			gridBagConstraints.weightx = 1.0;
+			gridBagConstraints.weighty = 0.0;
+			gridBagConstraints.anchor = GridBagConstraints.NORTHWEST;
+			gridBagConstraints.insets = new Insets(5, 5, 0, 5);
+			jPanel.add(getJPanel1(pluginSite), gridBagConstraints);
+		}
+		GridBagConstraints gridBagConstraints = new GridBagConstraints();
+		gridBagConstraints.fill = GridBagConstraints.BOTH;
+		gridBagConstraints.gridx = 0;
+		gridBagConstraints.gridy = GridBagConstraints.RELATIVE;
+		gridBagConstraints.weighty = 1.0;
+		jPanel.add(new JPanel(), gridBagConstraints);
+		return jPanel;
+	}
+
+	private JPanel getJPanel1(final PluginSite pluginSite) {
+		final JPanel pluginSitePanel = new JPanel();
+		pluginSitePanel.setBackground(Color.WHITE);
+		pluginSitePanel.setLayout(new GridBagLayout());
+		GridBagConstraints gridBagConstraints = new GridBagConstraints();
+		gridBagConstraints.gridx = 0;
+		gridBagConstraints.gridy = 0;
+		gridBagConstraints.anchor = GridBagConstraints.WEST;
+		gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
+		gridBagConstraints.gridwidth = 2;
+		gridBagConstraints.insets = new Insets(5, 5, 5, 5);
+		gridBagConstraints.ipadx = 5;
+		gridBagConstraints.ipady = 5;
+		gridBagConstraints.weightx = 1.0;
+		//ShadedLabel siteNameLabel = getSiteLabel(pluginSite);
+		JLabel siteNameLabel = getSiteLabel(pluginSite);
+
+		pluginSitePanel.add(siteNameLabel, gridBagConstraints);
+
+		final GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
+		gridBagConstraints1.gridx = 0;
+		gridBagConstraints1.gridy = 1;
+		gridBagConstraints1.anchor = GridBagConstraints.WEST;
+		gridBagConstraints1.fill = GridBagConstraints.HORIZONTAL;
+		gridBagConstraints1.gridwidth = 2;
+		gridBagConstraints1.insets = new Insets(5, 5, 5, 5);
+		gridBagConstraints1.weightx = 1.0;
+		final JProgressBar progressBar = new JProgressBar();
+		progressBar.setIndeterminate(true);
+		progressBar.setStringPainted(true);
+		progressBar.setString("Checking for new plugins");
+		pluginSitePanel.add(progressBar, gridBagConstraints1);
+
+		new Thread("Checking update site " + pluginSite) {
+			public void run() {
+				try {
+					List<Plugin> plugins = pluginManager
+							.getUninstalledPluginsFromSite(pluginSite);
+					if (plugins.size() > 0) {
+						Collections.sort(plugins, new Comparator<Plugin>() {
+
+							public int compare(Plugin o1, Plugin o2) {
+								return o1.getName().compareTo(o2.getName());
+							}
+
+						});
+
+						pluginSitePanel.remove(progressBar);
+						int gridY = 0;
+						for (Plugin plugin : plugins) {
+							gridY++;
+							GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
+							gridBagConstraints1.gridx = 0;
+							gridBagConstraints1.gridy = gridY;
+							gridBagConstraints1.anchor = GridBagConstraints.WEST;
+							gridBagConstraints1.insets = new Insets(5, 20, 0, 0);
+							pluginSitePanel.add(getJCheckBox(plugin),
+									gridBagConstraints1);
+
+							gridY++;
+
+							GridBagConstraints gridBagConstraintsDescription = new GridBagConstraints();
+							gridBagConstraintsDescription.gridx = 0;
+							gridBagConstraintsDescription.ipadx = 50;
+							gridBagConstraintsDescription.gridy = gridY;
+							gridBagConstraintsDescription.anchor = GridBagConstraints.WEST;
+							gridBagConstraintsDescription.insets = new Insets(5, 25, 10, 5);
+
+							gridY++;
+
+							GridBagConstraints gridBagConstraintsProgress = new GridBagConstraints();
+							gridBagConstraintsProgress.gridx = 0;
+							gridBagConstraintsProgress.gridy = gridY;
+							gridBagConstraintsProgress.fill = GridBagConstraints.HORIZONTAL;
+							gridBagConstraintsProgress.anchor = GridBagConstraints.WEST;
+							gridBagConstraintsProgress.insets = new Insets(5, 5, 0, 0);
+
+							JLabel description = new JLabel();
+							description.setText("<html>"+plugin.getDescription());
+							description.setFont(getFont().deriveFont(Font.PLAIN));
+							pluginSitePanel.add(description,gridBagConstraintsDescription);
+
+							PluginRepositoryListener progress = new PluginRepositoryListener();
+							listeners.put(plugin, progress);
+							progress.setVisible(false);
+
+							pluginSitePanel.add(progress.getProgressBar(),
+									gridBagConstraintsProgress);
+						}
+					} else {
+						pluginSitePanel.remove(progressBar);
+						pluginSitePanel.add(new JLabel(
+								"This update site contains no new plugins"),
+								gridBagConstraints1);
+					}
+				} catch (Exception e) {
+					pluginSitePanel.remove(progressBar);
+					pluginSitePanel.add(new JLabel(
+							"Unable to contact the update site"),
+							gridBagConstraints1);
+				} finally {
+					pluginSitePanel.revalidate();
+					pluginSitePanel.repaint();
+				}
+			}
+		}.start();
+
+		pluginSitePanel.setBorder(new EtchedBorder());
+		return pluginSitePanel;
+	}
+
+	private JLabel getSiteLabel(final PluginSite pluginSite) {
+		//ShadedLabel result = new ShadedLabel(pluginSite.getName(),Color.LIGHT_GRAY);
+		JLabel result = new JLabel(pluginSite.getName());
+
+
+		//add popup remove option, except on the Taverna main plugin site.
+		if (!(pluginSite instanceof TavernaPluginSite)) {
+			result.addMouseListener(new MouseAdapter() {
+				@Override
+				public void mouseClicked(MouseEvent e) {
+					popup(e);
+				}
+
+				@Override
+				public void mousePressed(MouseEvent e) {
+					popup(e);
+				}
+
+				private void popup(MouseEvent e) {
+					if (e.isPopupTrigger()) {
+						JPopupMenu menu=new JPopupMenu();
+						//JMenuItem item = new JMenuItem("Remove site",TavernaIcons.deleteIcon);
+						JMenuItem item = new JMenuItem("Remove site");
+
+						menu.add(item);
+						menu.show(e.getComponent(), e.getX(), e.getY());
+						item.addActionListener(new ActionListener() {
+
+							public void actionPerformed(ActionEvent e) {
+								int response=JOptionPane.showConfirmDialog(PluginSiteFrame.this, "Are you sure you want to remove the update site:"+pluginSite.getName(),"Remove update site",JOptionPane.YES_NO_OPTION);
+								if (response==JOptionPane.YES_OPTION) {
+									pluginManager.removePluginSite(pluginSite);
+									pluginManager.savePluginSites();
+									scrollPane.setViewportView(getJPanel());
+								}
+							}
+						});
+					}
+				}
+			});
+		}
+		return result;
+	}
+
+	/**
+	 * This method initializes jButton
+	 *
+	 * @return javax.swing.JButton
+	 */
+	private JCheckBox getJCheckBox(Plugin plugin) {
+		PluginCheckBox checkBox = new PluginCheckBox();
+		checkBox.plugin = plugin;
+		checkBox.setText(plugin.getName() + " " + plugin.getVersion());
+		checkBox.setOpaque(false);
+		checkBox.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				if (e.getSource() instanceof PluginCheckBox) {
+					PluginCheckBox checkBox = (PluginCheckBox) e.getSource();
+					if (checkBox.isSelected()) {
+						installationScheduled.add(checkBox.plugin);
+
+
+
+						getInstallButton().setEnabled(true);
+					} else {
+						installationScheduled.remove(checkBox.plugin);
+						if (installationScheduled.size() == 0) {
+							getInstallButton().setEnabled(false);
+						}
+					}
+				}
+			}
+
+		});
+		return checkBox;
+	}
+
+	private final Thread getUpdateRepositoryThread() {
+		return new Thread("Update Repository Progress") {
+
+			public void run() {
+				cancelButton.setEnabled(false);
+				for (int i = 0; i < installationScheduled.size(); i++) {
+					final Plugin plugin = installationScheduled.get(i);
+					PluginRepositoryListener listener = listeners.get(plugin);
+					if (listener != null) {
+						pluginManager.getRepository().addRepositoryListener(
+								listener);
+						listener.getProgressBar().setVisible(true);
+					}
+
+					pluginManager.addPlugin(plugin);
+
+					if (listener != null) {
+						pluginManager.getRepository().removeRepositoryListener(
+								listener);
+						listener.getProgressBar().setVisible(false);
+					}
+					plugin.setEnabled(true);
+
+				}
+				pluginManager.savePlugins();
+				installationScheduled.clear();
+				setVisible(false);
+				dispose();
+			}
+
+		};
+	}
+
+	/**
+	 * This method initializes jButton
+	 *
+	 * @return javax.swing.JButton
+	 */
+	private JButton getInstallButton() {
+		if (installButton == null) {
+			installButton = new JButton();
+			installButton.setText("Install");
+			installButton.setEnabled(false);
+			installButton
+					.addActionListener(new java.awt.event.ActionListener() {
+						public void actionPerformed(java.awt.event.ActionEvent e) {
+							installButton.setEnabled(false);
+							getUpdateRepositoryThread().start();
+						}
+
+					});
+		}
+		return installButton;
+	}
+
+	/**
+	 * This method initializes jButton
+	 *
+	 * @return javax.swing.JButton
+	 */
+	private JButton getCloseButton() {
+		if (cancelButton == null) {
+			cancelButton = new JButton();
+			cancelButton.setText("Close");
+			cancelButton.addActionListener(new ActionListener() {
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					setVisible(false);
+					dispose();
+				}
+			});
+		}
+		return cancelButton;
+	}
+
+	@SuppressWarnings("serial")
+	class PluginCheckBox extends JCheckBox {
+		public Plugin plugin;
+	}
+
+	private final void addPluginSite() {
+
+		addSiteFrame=new AddPluginSiteFrame(this);
+
+		addSiteFrame.setLocationRelativeTo(this);
+		addSiteFrame.setVisible(true);
+
+		if (addSiteFrame.getName()!=null) {
+			if (addSiteFrame.getName().length()==0) {
+				JOptionPane.showMessageDialog(this, "You must provide a name for your site.","Error adding update site",JOptionPane.ERROR_MESSAGE);
+				addPluginSite();
+			}
+			else {
+				if (addSiteFrame.getUrl()!=null) {
+					try {
+						PluginSite site = new PluginSite(addSiteFrame.getName(), new URL(addSiteFrame.getUrl()));
+						pluginManager.addPluginSite(site);
+						pluginManager.savePluginSites();
+
+						//refresh
+						scrollPane.setViewportView(getJPanel());
+						addSiteFrame=null; //so that the name and url are reset.
+					}
+					catch(Exception e) {
+						JOptionPane.showMessageDialog(this, "There was a problem adding the site you provided: "+e.getMessage(),"Error adding update site",JOptionPane.ERROR_MESSAGE);
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * This method initializes jButton
+	 *
+	 * @return javax.swing.JButton
+	 */
+	private JButton getAddPluginSiteButton() {
+		if (addSiteButton == null) {
+			addSiteButton = new JButton();
+			addSiteButton.setText("Add update site");
+			addSiteButton.setEnabled(true);
+			addSiteButton.addActionListener(new ActionListener() {
+				public void actionPerformed(ActionEvent e) {
+					addSiteButton.setEnabled(false);
+					addPluginSite();
+					addSiteButton.setEnabled(true);
+				}
+			});
+
+		}
+		return addSiteButton;
+	}
+
+} // @jve:decl-index=0:visual-constraint="10,10"

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/plugins/ui/UpdatesAvailableIcon.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/plugins/ui/UpdatesAvailableIcon.java b/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/plugins/ui/UpdatesAvailableIcon.java
new file mode 100644
index 0000000..a0b15bf
--- /dev/null
+++ b/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/plugins/ui/UpdatesAvailableIcon.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * 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
+ ******************************************************************************/
+/*
+ * Copyright (C) 2003 The University of Manchester
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.  Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * 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
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename           $RCSfile: UpdatesAvailableIcon.java,v $
+ * Revision           $Revision: 1.5 $
+ * Release status     $State: Exp $
+ * Last modified on   $Date: 2008/12/01 12:32:40 $
+ *               by   $Author: alaninmcr $
+ * Created on 12 Dec 2006
+ *****************************************************************/
+package net.sf.taverna.raven.plugins.ui;
+
+import java.awt.Component;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JLabel;
+import javax.swing.SwingUtilities;
+
+
+import org.apache.log4j.Logger;
+
+/**
+ * A JLabel that periodically checks for updates, running on a daemon thread. If
+ * updates are available it makes itself visible and responds to click events to
+ * display the appropriate update response.
+ *
+ * Also acts as a pluginmanager listener to refresh itself whenever a new plugin
+ * is added.
+ *
+ * @author Stuart Owen
+ *
+ */
+
+@SuppressWarnings("serial")
+public class UpdatesAvailableIcon extends JLabel implements PluginManagerListener {
+
+	private UpdatePluginsMouseAdaptor updatePluginMouseAdaptor = new UpdatePluginsMouseAdaptor();
+	private static Logger logger = Logger.getLogger(UpdatesAvailableIcon.class);
+
+	private final int CHECK_INTERVAL = 1800000; // every 30 minutes
+
+	public static final Icon updateIcon = new ImageIcon(
+			UpdatesAvailableIcon.class.getResource("update.png"));
+	public static final Icon updateRecommendedIcon = new ImageIcon(
+			UpdatesAvailableIcon.class.getResource("updateRecommended.png"));
+
+	public UpdatesAvailableIcon() {
+		super();
+		setVisible(false);
+
+		startCheckThread();
+		PluginManager.addPluginManagerListener(this);
+	}
+
+	public void pluginAdded(PluginManagerEvent event) {
+		logger.info("Plugin Added");
+		if (!isVisible())
+			checkForUpdates();
+	}
+
+	public void pluginStateChanged(PluginManagerEvent event) {
+
+	}
+
+	public void pluginUpdated(PluginManagerEvent event) {
+		logger.info("Plugin Updated");
+	}
+
+	public void pluginRemoved(PluginManagerEvent event) {
+		logger.info("Plugin Removed");
+		if (isVisible())
+			checkForUpdates();
+	}
+
+	public void pluginIncompatible(PluginManagerEvent event) {
+		logger
+				.warn("Plugin found to be incompatible with the current version of Taverna: "
+						+ event.getPlugin());
+	}
+
+	private void startCheckThread() {
+		Thread checkThread = new Thread("Check for updates thread") {
+
+			@Override
+			public void run() {
+				while (true) {
+					try {
+						checkForUpdates();
+						Thread.sleep(CHECK_INTERVAL);
+					} catch (InterruptedException e) {
+						logger.warn("Interruption exception in checking for updates thread",
+										e);
+					}
+				}
+			}
+		};
+		checkThread.setDaemon(true); // daemon so that taverna will stop the
+										// thread and close on exit.
+		checkThread.start();
+	}
+
+	private Object updateLock = new Object();
+
+	private void checkForUpdates() {
+		synchronized (updateLock) {
+			if (pluginUpdateAvailable()) {
+				logger.info("Plugin update available");
+				try {
+					SwingUtilities.invokeAndWait(new Runnable() {
+						public void run() {
+							// TODO Auto-generated method stub
+							setToolTipText("Plugin updates are available");
+
+							setVisible(true);
+							setIcon(updateIcon);
+							if (!Arrays.asList(getMouseListeners()).contains(
+									updatePluginMouseAdaptor)) {
+								addMouseListener(updatePluginMouseAdaptor);
+							}
+
+						}
+					});
+				} catch (InterruptedException e) {
+					logger.error("Could not check for updates", e);
+				} catch (InvocationTargetException e) {
+					logger.error("Could not check for updates", e);
+				}
+			} else {
+				setToolTipText("");
+				setVisible(false);
+
+			}
+		}
+
+	}
+
+	private boolean pluginUpdateAvailable() {
+		return PluginManager.getInstance().checkForUpdates();
+	}
+
+	private final class UpdatePluginsMouseAdaptor extends MouseAdapter {
+
+		@Override
+		public void mouseClicked(MouseEvent e) {
+			// FIXME: this assumes the button is on the toolbar.
+			Component parent = UpdatesAvailableIcon.this.getParent()
+					.getParent();
+
+			final PluginManagerFrame pluginManagerUI = new PluginManagerFrame(
+					PluginManager.getInstance());
+			pluginManagerUI.setLocationRelativeTo(parent);
+			pluginManagerUI.setVisible(true);
+		}
+
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/profile/ui/ProfileVersionCellRenderer.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/profile/ui/ProfileVersionCellRenderer.java b/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/profile/ui/ProfileVersionCellRenderer.java
new file mode 100644
index 0000000..b0c036c
--- /dev/null
+++ b/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/profile/ui/ProfileVersionCellRenderer.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * 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
+ ******************************************************************************/
+/*
+ * Copyright (C) 2003 The University of Manchester 
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.  Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * 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
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename           $RCSfile: ProfileVersionCellRenderer.java,v $
+ * Revision           $Revision: 1.2 $
+ * Release status     $State: Exp $
+ * Last modified on   $Date: 2008/09/04 14:52:06 $
+ *               by   $Author: sowen70 $
+ * Created on 16 Jan 2007
+ *****************************************************************/
+package net.sf.taverna.raven.profile.ui;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.ListCellRenderer;
+import javax.swing.border.AbstractBorder;
+
+import net.sf.taverna.raven.profile.ProfileHandler;
+import net.sf.taverna.raven.profile.ProfileVersion;
+import net.sf.taverna.raven.spi.Profile;
+import net.sf.taverna.raven.spi.ProfileFactory;
+
+public class ProfileVersionCellRenderer extends JPanel implements
+		ListCellRenderer {
+
+	private JLabel name;
+	private JLabel version;
+	private JLabel description;
+	private String currentVersion;
+	
+	public ProfileVersionCellRenderer() {
+		super();
+		initialise();
+	}
+	
+	private void initialise() {
+		Profile currentProfile = ProfileFactory.getInstance().getProfile();
+		if (currentProfile!=null) {
+			currentVersion=currentProfile.getVersion();
+		}
+		else {
+			currentVersion="UNKNOWN";
+		}
+		GridBagConstraints gridBagVersion = new GridBagConstraints();
+		gridBagVersion.gridx = 1;
+		gridBagVersion.insets = new Insets(3, 8, 3, 3);
+		gridBagVersion.anchor = GridBagConstraints.NORTHWEST;
+		gridBagVersion.fill = GridBagConstraints.NONE;
+		gridBagVersion.gridy = 0;		
+		version = new JLabel();
+		version.setFont(getFont().deriveFont(Font.BOLD));
+		version.setText("Version");
+		
+		GridBagConstraints gridBagDescription = new GridBagConstraints();
+		gridBagDescription.gridx = 0;
+		gridBagDescription.anchor = GridBagConstraints.NORTHWEST;
+		gridBagDescription.fill = GridBagConstraints.HORIZONTAL;
+		gridBagDescription.weightx = 1.0;
+		gridBagDescription.insets = new Insets(3, 3, 3, 3);
+		gridBagDescription.gridwidth = 2;
+		gridBagDescription.gridy = 1;
+		description = new JLabel();
+		description.setFont(getFont().deriveFont(Font.PLAIN));
+		description.setText("Plugin description");
+		
+		GridBagConstraints gridBagName = new GridBagConstraints();
+		gridBagName.gridx = 0;
+		gridBagName.anchor = GridBagConstraints.NORTHWEST;
+		gridBagName.fill = GridBagConstraints.NONE;
+		gridBagName.weightx = 0.0;
+		gridBagName.ipadx = 0;
+		gridBagName.insets = new Insets(3, 3, 3, 3);
+		gridBagName.gridwidth = 1;
+		gridBagName.gridy = 0;
+		name = new JLabel();
+		name.setFont(getFont().deriveFont(Font.PLAIN));
+		name.setText("Plugin name");
+		
+		this.setSize(297, 97);
+		this.setLayout(new GridBagLayout());
+		this.setBorder(new AbstractBorder() {
+			public void paintBorder(Component c, Graphics g, int x, int y,
+					int width, int height) {
+				Color oldColor = g.getColor();
+				g.setColor(Color.LIGHT_GRAY);
+				g.drawLine(x, y + height - 1, x + width - 1, y + height - 1);
+				g.setColor(oldColor);
+			}
+		});
+		this.add(name, gridBagName);
+		this.add(description, gridBagDescription);
+		this.add(version, gridBagVersion);		
+	}
+	
+	public Component getListCellRendererComponent(JList list, Object value,
+			int index, boolean isSelected, boolean cellHasFocus) {
+		if (isSelected) {
+			setBackground(list.getSelectionBackground());
+			setForeground(list.getSelectionForeground());
+		} else {
+			setBackground(list.getBackground());
+			setForeground(list.getForeground());
+		}
+		
+		if (value instanceof ProfileVersion) {
+			ProfileVersion version = (ProfileVersion) value;			
+			this.name.setText(version.getName());
+			if (version.getVersion().equalsIgnoreCase(currentVersion)) {
+				this.name.setText(version.getName()+" (Current)");
+				this.name.setForeground(Color.BLUE);
+			}
+			else {
+				this.name.setText(version.getName());
+				this.name.setForeground(Color.BLACK);
+			}
+			this.version.setText(version.getVersion());
+			this.description.setText("<html>"+version.getDescription());
+		}
+		
+		
+		return this;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/profile/ui/ProfileVersionListFrame.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/profile/ui/ProfileVersionListFrame.java b/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/profile/ui/ProfileVersionListFrame.java
new file mode 100644
index 0000000..861ed9a
--- /dev/null
+++ b/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/profile/ui/ProfileVersionListFrame.java
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * 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
+ ******************************************************************************/
+/*
+ * Copyright (C) 2003 The University of Manchester 
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.  Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * 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
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename           $RCSfile: ProfileVersionListFrame.java,v $
+ * Revision           $Revision: 1.3 $
+ * Release status     $State: Exp $
+ * Last modified on   $Date: 2008/09/04 14:52:06 $
+ *               by   $Author: sowen70 $
+ * Created on 16 Jan 2007
+ *****************************************************************/
+package net.sf.taverna.raven.profile.ui;
+
+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.io.File;
+import java.net.URL;
+import java.util.List;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import net.sf.taverna.raven.appconfig.bootstrap.RavenProperties;
+import net.sf.taverna.raven.plugins.Plugin;
+import net.sf.taverna.raven.plugins.PluginManager;
+import net.sf.taverna.raven.profile.ProfileHandler;
+import net.sf.taverna.raven.profile.ProfileUpdateHandler;
+import net.sf.taverna.raven.profile.ProfileVersion;
+import net.sf.taverna.raven.spi.ProfileFactory;
+import net.sf.taverna.t2.workbench.helper.HelpEnabledDialog;
+
+import org.apache.log4j.Logger;
+
+@SuppressWarnings("serial")
+public class ProfileVersionListFrame extends HelpEnabledDialog {
+	
+	private JPanel contentPane = null;
+	private JScrollPane scrollPane = null;
+	private JList list = null;
+	private JButton switchButton = null;
+	private JButton closeButton = null;
+	private String currentVersion = null;
+	
+	private static Logger logger = Logger
+			.getLogger(ProfileVersionListFrame.class);
+
+	public ProfileVersionListFrame() {
+		this(null);
+	}
+	
+	public ProfileVersionListFrame(Frame parent) {
+		super(parent,"Taverna versions", true);
+		initialise();
+	}
+	
+	protected JPanel getJContentPane() {
+		if (contentPane==null) {
+			GridBagConstraints scrollPaneConstraints = new GridBagConstraints();
+			scrollPaneConstraints.fill = GridBagConstraints.BOTH;
+			scrollPaneConstraints.gridy = 0;
+			scrollPaneConstraints.weightx = 1.0;
+			scrollPaneConstraints.weighty = 1.0;
+			scrollPaneConstraints.gridwidth = 2;
+			scrollPaneConstraints.insets = new Insets(5, 5, 5, 5);
+			scrollPaneConstraints.gridx = 0;
+			scrollPaneConstraints.gridheight = 3;
+			
+			GridBagConstraints switchButtonConstraints = new GridBagConstraints();			
+			switchButtonConstraints.gridy=0;			
+			switchButtonConstraints.gridx=2;
+			switchButtonConstraints.insets = new Insets(5,5,5,5);
+			switchButtonConstraints.fill=GridBagConstraints.HORIZONTAL;
+			
+			GridBagConstraints closeButtonConstraints = new GridBagConstraints();
+			closeButtonConstraints.gridy=2;			
+			closeButtonConstraints.gridx=2;
+			closeButtonConstraints.insets = new Insets(5,5,5,5);
+			closeButtonConstraints.anchor=GridBagConstraints.SOUTH;
+			closeButtonConstraints.fill=GridBagConstraints.HORIZONTAL;
+			
+			contentPane = new JPanel();
+			contentPane.setLayout(new GridBagLayout());
+			contentPane.add(getScrollPane(),scrollPaneConstraints);
+			contentPane.add(getSwitchButton(),switchButtonConstraints);
+			contentPane.add(getCloseButton(),closeButtonConstraints);
+			
+		}
+		return contentPane;
+	}
+	
+	protected JScrollPane getScrollPane() {
+		if (scrollPane==null) {
+			scrollPane=new JScrollPane();
+			scrollPane.setViewportView(getJList());
+		}
+		return scrollPane;
+	}
+	
+	protected JList getJList() {
+		if (list==null) {
+			list=new JList();
+			list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+			list.setModel(new ProfileVersionListModel());	
+			list.setCellRenderer(new ProfileVersionCellRenderer());
+			list.addListSelectionListener(new ListSelectionListener() {
+
+				public void valueChanged(ListSelectionEvent e) {
+					if (!e.getValueIsAdjusting()) {
+						respondToSelection();
+					}
+				}
+
+			});
+			if (list.getComponentCount() > 0) {
+				list.setSelectedIndex(0);
+				respondToSelection();
+				
+			}
+		}
+		return list;
+	}
+	
+	protected void respondToSelection() {
+		Object selected=list.getSelectedValue();
+		if (selected!=null && selected instanceof ProfileVersion) {
+			ProfileVersion version = (ProfileVersion)selected;
+			if (currentVersion==null || version.getVersion().equals(currentVersion)) {
+				getSwitchButton().setEnabled(false);
+			}
+			else {
+				getSwitchButton().setEnabled(true);
+			}
+		}
+	}
+	
+	protected JButton getSwitchButton() {
+		if (switchButton==null) {
+			switchButton=new JButton("Switch");
+			switchButton.setEnabled(true);
+			switchButton.addActionListener(new ActionListener() {
+
+				public void actionPerformed(ActionEvent e) {					
+					Object selected = getJList().getSelectedValue();
+					if (selected!=null && selected instanceof ProfileVersion) {
+						performSwitch((ProfileVersion)selected);
+					}
+				}
+				
+			});
+		}
+		return switchButton;
+	}
+	
+	protected JButton getCloseButton() {
+		if (closeButton==null) {
+			closeButton=new JButton("Close");
+			closeButton.setEnabled(true);
+			closeButton.addActionListener(new ActionListener() {
+				public void actionPerformed(ActionEvent e) {					
+					setVisible(false);
+					dispose();
+				}				
+			});			
+		}
+		return closeButton;		
+	}
+	
+	protected void performSwitch(ProfileVersion newVersion) {
+		List<Plugin> incompatiblePlugins = PluginManager.getInstance().getIncompatiblePlugins(newVersion.getVersion(),true);
+		if (incompatiblePlugins.size()>0) {
+			int response=JOptionPane.showConfirmDialog(this, "Some plugins will be incompatible with the new version and will be disabled. Do you wish to continue?","Confirm version switch",JOptionPane.YES_OPTION);
+			if (response!=JOptionPane.YES_OPTION) {
+				return;
+			}			
+		}
+		try {		
+			URL localProfile = new URL(RavenProperties.getInstance().getRavenProfileLocation());
+			URL profileList = new URL(RavenProperties.getInstance().getRavenProfileListLocation());
+			
+			ProfileUpdateHandler handler=new ProfileUpdateHandler(profileList,localProfile);
+			handler.updateLocalProfile(newVersion,new File(localProfile.toURI()));			
+			
+			//disable plugins after everything else has been acheived
+			for (Plugin plugin : incompatiblePlugins) {
+				plugin.setEnabled(false);
+			}			
+			JOptionPane.showMessageDialog(this, "You must restart taverna for the version switch to be activated");
+		}
+		catch(Exception e) {
+			logger.error("Error occurred switching to a new profile",e);
+			JOptionPane.showMessageDialog(this, "An error occurred switching to your new profile, try again later.");
+		}				
+	}
+	
+	
+	protected void initialise() {
+		try {
+			currentVersion = ProfileFactory.getInstance().getProfile().getVersion();
+		} catch (Exception e) {
+			logger.error("Unable to determine current taverna version",e);
+			currentVersion=null;
+		}
+		setSize(600,400);		
+		setContentPane(getJContentPane());
+	}	
+	
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/profile/ui/ProfileVersionListModel.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/profile/ui/ProfileVersionListModel.java b/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/profile/ui/ProfileVersionListModel.java
new file mode 100644
index 0000000..c952413
--- /dev/null
+++ b/taverna-workbench-plugins-gui/src/main/java/net/sf/taverna/raven/profile/ui/ProfileVersionListModel.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * 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
+ ******************************************************************************/
+/*
+ * Copyright (C) 2003 The University of Manchester 
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.  Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * 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
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename           $RCSfile: ProfileVersionListModel.java,v $
+ * Revision           $Revision: 1.3 $
+ * Release status     $State: Exp $
+ * Last modified on   $Date: 2008/09/04 14:52:06 $
+ *               by   $Author: sowen70 $
+ * Created on 16 Jan 2007
+ *****************************************************************/
+package net.sf.taverna.raven.profile.ui;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.AbstractListModel;
+
+import net.sf.taverna.raven.appconfig.bootstrap.RavenProperties;
+import net.sf.taverna.raven.profile.ProfileVersion;
+import net.sf.taverna.raven.profile.ProfileVersions;
+
+import org.apache.log4j.Logger;
+
+@SuppressWarnings("serial")
+public class ProfileVersionListModel extends AbstractListModel {
+	
+	private static Logger logger = Logger
+			.getLogger(ProfileVersionListModel.class);
+	
+	private List<ProfileVersion> versions;
+	
+	
+	public ProfileVersionListModel() {		
+		try {
+			URL url = getProfileListLocation();
+			versions = ProfileVersions.getProfileVersions(url);			
+		}
+		catch(MalformedURLException e) {
+			logger.error("Error with profile list URL",e);
+			versions = new ArrayList<ProfileVersion>();
+		}
+	}
+
+	public Object getElementAt(int index) {
+		return versions.get(index);
+	}
+
+	public int getSize() {
+		return versions.size();
+	}
+	
+	private URL getProfileListLocation() throws MalformedURLException{		
+		return new URL(RavenProperties.getInstance().getRavenProfileListLocation());
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-plugins-gui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.StartupSPI
----------------------------------------------------------------------
diff --git a/taverna-workbench-plugins-gui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.StartupSPI b/taverna-workbench-plugins-gui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.StartupSPI
new file mode 100644
index 0000000..a58f87a
--- /dev/null
+++ b/taverna-workbench-plugins-gui/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.StartupSPI
@@ -0,0 +1,2 @@
+net.sf.taverna.raven.plugins.ui.CheckForUpdatesStartupHook
+net.sf.taverna.raven.plugins.ui.CheckForNoticeStartupHook
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-plugins-gui/src/main/resources/META-INF/spring/plugins-gui-context-osgi.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-plugins-gui/src/main/resources/META-INF/spring/plugins-gui-context-osgi.xml b/taverna-workbench-plugins-gui/src/main/resources/META-INF/spring/plugins-gui-context-osgi.xml
new file mode 100644
index 0000000..38c21e5
--- /dev/null
+++ b/taverna-workbench-plugins-gui/src/main/resources/META-INF/spring/plugins-gui-context-osgi.xml
@@ -0,0 +1,11 @@
+<?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="CheckForUpdatesStartupHook" interface="net.sf.taverna.t2.workbench.StartupSPI" />
+
+</beans:beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-plugins-gui/src/main/resources/META-INF/spring/plugins-gui-context.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-plugins-gui/src/main/resources/META-INF/spring/plugins-gui-context.xml b/taverna-workbench-plugins-gui/src/main/resources/META-INF/spring/plugins-gui-context.xml
new file mode 100644
index 0000000..33e2207
--- /dev/null
+++ b/taverna-workbench-plugins-gui/src/main/resources/META-INF/spring/plugins-gui-context.xml
@@ -0,0 +1,8 @@
+<?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="CheckForUpdatesStartupHook" class="net.sf.taverna.raven.plugins.ui.CheckForUpdatesStartupHook" />
+
+</beans>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-plugins-gui/src/main/resources/net/sf/taverna/raven/plugins/ui/update.png
----------------------------------------------------------------------
diff --git a/taverna-workbench-plugins-gui/src/main/resources/net/sf/taverna/raven/plugins/ui/update.png b/taverna-workbench-plugins-gui/src/main/resources/net/sf/taverna/raven/plugins/ui/update.png
new file mode 100644
index 0000000..e3695cb
Binary files /dev/null and b/taverna-workbench-plugins-gui/src/main/resources/net/sf/taverna/raven/plugins/ui/update.png differ

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-plugins-gui/src/main/resources/net/sf/taverna/raven/plugins/ui/updateRecommended.png
----------------------------------------------------------------------
diff --git a/taverna-workbench-plugins-gui/src/main/resources/net/sf/taverna/raven/plugins/ui/updateRecommended.png b/taverna-workbench-plugins-gui/src/main/resources/net/sf/taverna/raven/plugins/ui/updateRecommended.png
new file mode 100644
index 0000000..5adc4b1
Binary files /dev/null and b/taverna-workbench-plugins-gui/src/main/resources/net/sf/taverna/raven/plugins/ui/updateRecommended.png differ

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-renderers-impl/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-workbench-renderers-impl/pom.xml b/taverna-workbench-renderers-impl/pom.xml
new file mode 100644
index 0000000..24e06c0
--- /dev/null
+++ b/taverna-workbench-renderers-impl/pom.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>net.sf.taverna.t2</groupId>
+		<artifactId>ui-impl</artifactId>
+		<version>2.0-SNAPSHOT</version>
+	</parent>
+	<groupId>net.sf.taverna.t2.ui-impl</groupId>
+	<artifactId>renderers-impl</artifactId>
+	<packaging>bundle</packaging>
+	<name>Renderers Implementation</name>
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-bundle-plugin</artifactId>
+				<extensions>true</extensions>
+				<configuration>
+					<instructions>
+						<Private-Package>org.fife.ui.hex.*,net.sf.taverna.t2.renderers.impl</Private-Package>
+					</instructions>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+	<dependencies>
+		<dependency>
+			<groupId>net.sf.taverna.t2.ui-api</groupId>
+			<artifactId>renderers-api</artifactId>
+			<version>${t2.ui.api.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.taverna.t2.lang</groupId>
+			<artifactId>ui</artifactId>
+			<version>${t2.lang.version}</version>
+		</dependency>
+		<dependency>
+    		<groupId>uk.org.taverna.databundle</groupId>
+    		<artifactId>databundle</artifactId>
+    		<version>${taverna.databundle.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>log4j</groupId>
+			<artifactId>log4j</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.jdom</groupId>
+			<artifactId>com.springsource.org.jdom</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.fife.ui.hex</groupId>
+			<artifactId>hexeditor</artifactId>
+			<version>1.1-SNAPSHOT</version>
+		</dependency>
+
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/AbstractRenderer.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/AbstractRenderer.java b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/AbstractRenderer.java
new file mode 100644
index 0000000..14ef62f
--- /dev/null
+++ b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/AbstractRenderer.java
@@ -0,0 +1,124 @@
+package net.sf.taverna.t2.renderers.impl;
+
+import static java.lang.String.format;
+import static javax.swing.JOptionPane.YES_NO_OPTION;
+import static javax.swing.JOptionPane.YES_OPTION;
+import static javax.swing.JOptionPane.showConfirmDialog;
+import static net.sf.taverna.t2.renderers.RendererUtils.getSizeInBytes;
+import static net.sf.taverna.t2.renderers.impl.RendererConstants.BIG_DATA_MSG;
+import static net.sf.taverna.t2.renderers.impl.RendererConstants.CANCELLED_MSG;
+import static net.sf.taverna.t2.renderers.impl.RendererConstants.NO_DATA_MSG;
+import static net.sf.taverna.t2.renderers.impl.RendererConstants.NO_SIZE_MSG;
+import static uk.org.taverna.databundle.DataBundles.isValue;
+import static uk.org.taverna.databundle.DataBundles.isReference;
+
+import java.nio.file.Path;
+
+import javax.swing.JComponent;
+import javax.swing.JTextArea;
+
+import net.sf.taverna.t2.renderers.Renderer;
+import net.sf.taverna.t2.renderers.RendererException;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Implements some of the common code across the renderers.
+ * 
+ * @author Donal Fellows
+ */
+abstract class AbstractRenderer implements Renderer {
+	protected Logger logger = Logger.getLogger(AbstractRenderer.class);
+	/** Size of a <s>mibibyte</s> megabyte. */
+	private int MEGABYTE = 1024 * 1024;
+
+	/**
+	 * Work out size of file in megabytes
+	 * 
+	 * @param bytes
+	 *            Number of bytes
+	 * @return Number of megabytes
+	 */
+	private int bytesToMeg(long bytes) {
+		float f = bytes / MEGABYTE;
+		return Math.round(f);
+	}
+
+	/**
+	 * Implements basic checks on the entity to render before delegating to
+	 * subclasses to actually do the rendering.
+	 * 
+	 * @see #getRendererComponent(Path)
+	 */
+	@Override
+	public JComponent getComponent(Path path) throws RendererException {
+		if (!isValue(path) && !isReference(path)) {
+			logger.error("unrenderable: data is not a value or reference");
+			return new JTextArea(NO_DATA_MSG);
+		}
+
+		// Get the size
+		long sizeInBytes;
+		try {
+			sizeInBytes = getSizeInBytes(path);
+		} catch (Exception ex) {
+			logger.error("unrenderable: failed to get data size", ex);
+			return new JTextArea(NO_SIZE_MSG + ex.getMessage());
+		}
+
+		// over the limit for this renderer?
+		if (sizeInBytes > MEGABYTE * getSizeLimit()) {
+			JComponent alternative = sizeCheck(path, bytesToMeg(sizeInBytes));
+			if (alternative != null)
+				return alternative;
+		}
+
+		return getRendererComponent(path);
+	}
+
+	/**
+	 * Implements the user-visible part of the size check. Default version just
+	 * does a simple yes/no proceed.
+	 * 
+	 * @return <tt>null</tt> if the normal flow is to continue, or a component
+	 *         to show to the user if it is to be used instead (e.g., to show a
+	 *         message that the entity was too large).
+	 */
+	protected JComponent sizeCheck(Path path, int approximateSizeInMB) {
+		int response = showConfirmDialog(null,
+				format(BIG_DATA_MSG, getResultType(), approximateSizeInMB),
+				getSizeQueryTitle(), YES_NO_OPTION);
+		if (response != YES_OPTION) // NO_OPTION or ESCAPE key
+			return new JTextArea(CANCELLED_MSG);
+		return null;
+	}
+
+	/**
+	 * How should we describe the data to the user? Should be capitalised.
+	 */
+	protected String getResultType() {
+		return "Result";
+	}
+
+	/**
+	 * At what size (in megabytes) do we query the user?
+	 * 
+	 * @see #sizeCheck(Path,log)
+	 */
+	protected int getSizeLimit() {
+		return 1;
+	}
+
+	/**
+	 * What title do we use on the dialog used to query the user?
+	 * 
+	 * @see #sizeCheck(Path,log)
+	 */
+	protected String getSizeQueryTitle() {
+		return "Render this image?";
+	}
+
+	/** Actually get the renderer; the basic checks have passed. */
+	protected abstract JComponent getRendererComponent(Path path)
+			throws RendererException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/AdvancedImageRenderer.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/AdvancedImageRenderer.java b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/AdvancedImageRenderer.java
new file mode 100644
index 0000000..6c15834
--- /dev/null
+++ b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/AdvancedImageRenderer.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * 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.renderers.impl;
+
+import static javax.imageio.ImageIO.getReaderMIMETypes;
+import static javax.imageio.ImageIO.getWriterFormatNames;
+import static net.sf.taverna.t2.renderers.RendererUtils.getInputStream;
+import static net.sf.taverna.t2.renderers.impl.RendererConstants.SEE_LOG_MSG;
+
+import java.awt.Image;
+import java.io.InputStream;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.imageio.ImageIO;
+import javax.swing.ImageIcon;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JTextArea;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Advanced renderer for mime type image/* that can render tiff files. Uses Java
+ * Advanced Imaging (JAI) ImageIO from https://jai-imageio.dev.java.net/.
+ * 
+ * @author Alex Nenadic
+ * @author David Withers
+ */
+public class AdvancedImageRenderer extends AbstractRenderer {
+	private static final String BAD_FORMAT_MSG = "Data does not seem to contain an image in any of the recognised formats:\n";
+	private static final String UNRENDERABLE_MSG = "Failed to create image renderer " + SEE_LOG_MSG;
+
+	private Logger logger = Logger.getLogger(AdvancedImageRenderer.class);
+	private List<String> mimeTypesList;
+
+	public AdvancedImageRenderer() {
+		mimeTypesList = Arrays.asList(getReaderMIMETypes());
+	}
+
+	@Override
+	public boolean canHandle(String mimeType) {
+		return mimeTypesList.contains(mimeType);
+	}
+
+	@Override
+	public String getType() {
+		return "Image";
+	}
+
+	@Override
+	public JComponent getRendererComponent(Path path) {
+		// Render into a label
+		try (InputStream inputStream = getInputStream(path)) {
+			Image image = ImageIO.read(inputStream);
+			if (image == null)
+				return new JTextArea(BAD_FORMAT_MSG
+						+ Arrays.asList(getWriterFormatNames()));
+			return new JLabel(new ImageIcon(image));
+		} catch (Exception e) {
+			logger.error("unrenderable: failed to create image renderer", e);
+			return new JTextArea(UNRENDERABLE_MSG + e.getMessage());
+		}
+	}
+
+	@Override
+	protected int getSizeLimit() {
+		return 4;
+	}
+
+	@Override
+	protected String getResultType() {
+		return "Image";
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/ExtensionFileFilter.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/ExtensionFileFilter.java b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/ExtensionFileFilter.java
new file mode 100644
index 0000000..2d90764
--- /dev/null
+++ b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/ExtensionFileFilter.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester   
+ * 
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ * 
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *    
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *    
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+/**
+ * This file is a component of the Taverna project,
+ * and is licensed under the GNU LGPL.
+ * Copyright Tom Oinn, EMBL-EBI
+ */
+package net.sf.taverna.t2.renderers.impl;
+
+import java.io.File;
+
+import javax.swing.filechooser.FileFilter;
+
+/**
+ * A FileFilter implementation that can be configured to show only specific file
+ * suffixes.
+ * 
+ * @author Tom Oinn
+ */
+public class ExtensionFileFilter extends FileFilter {
+	String[] allowedExtensions;
+
+	public ExtensionFileFilter(String[] allowedExtensions) {
+		this.allowedExtensions = allowedExtensions;
+	}
+
+	@Override
+	public boolean accept(File f) {
+		if (f.isDirectory())
+			return true;
+		String extension = getExtension(f);
+		if (extension != null)
+			for (int i = 0; i < allowedExtensions.length; i++)
+				if (extension.equalsIgnoreCase(allowedExtensions[i]))
+					return true;
+		return false;
+	}
+
+	String getExtension(File f) {
+		String ext = null;
+		String s = f.getName();
+		int i = s.lastIndexOf('.');
+		if (i > 0 && i < s.length() - 1)
+			ext = s.substring(i + 1).toLowerCase();
+		return ext;
+	}
+
+	@Override
+	public String getDescription() {
+		StringBuilder sb = new StringBuilder();
+		sb.append("Filter for extensions : ");
+		String sep = "";
+		for (String ext : allowedExtensions) {
+			sb.append(sep).append(ext);
+			sep = ", ";
+		}
+		return sb.toString();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/HexBinaryRenderer.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/HexBinaryRenderer.java b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/HexBinaryRenderer.java
new file mode 100644
index 0000000..f1d8f29
--- /dev/null
+++ b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/HexBinaryRenderer.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * 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.renderers.impl;
+
+import static net.sf.taverna.t2.renderers.RendererUtils.getInputStream;
+import static net.sf.taverna.t2.renderers.impl.RendererConstants.SEE_LOG_MSG;
+
+import java.io.InputStream;
+import java.nio.file.Path;
+
+import javax.swing.JComponent;
+import javax.swing.JTextArea;
+
+import net.sf.taverna.t2.renderers.RendererException;
+
+import org.fife.ui.hex.swing.HexEditor;
+
+/**
+ * Renderer for binary data. Uses HexEditor from
+ * http://www.fifesoft.com/hexeditor/.
+ * 
+ * @author Alex Nenadic
+ * @author David Withers
+ */
+public class HexBinaryRenderer extends AbstractRenderer {
+	private static final String RENDER_FAILED_MSG = "Failed to create binary hexadecimal renderer "
+			+ SEE_LOG_MSG;
+
+	@Override
+	public boolean canHandle(String mimeType) {
+		return false;
+		/*
+		 * can handle any data but return false here as we do not want this to
+		 * be default renderer
+		 */
+	}
+
+	@Override
+	protected String getSizeQueryTitle() {
+		return "Render binary data (in hexadecimal viewer)?";
+	}
+
+	@Override
+	public JComponent getRendererComponent(Path path) throws RendererException {
+		try (InputStream inputStream = getInputStream(path)) {
+			HexEditor editor = new HexEditor();
+			editor.open(inputStream);
+			return editor;
+		} catch (Exception e) {
+			logger.error("unrenderable: failed to create binhex renderer", e);
+			return new JTextArea(RENDER_FAILED_MSG + e.getMessage());
+		}
+	}
+
+	@Override
+	public String getType() {
+		return "Binary (HexDec)";
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/RendererConstants.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/RendererConstants.java b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/RendererConstants.java
new file mode 100644
index 0000000..d51c94c
--- /dev/null
+++ b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/RendererConstants.java
@@ -0,0 +1,13 @@
+package net.sf.taverna.t2.renderers.impl;
+
+interface RendererConstants {
+	String SEE_LOG_MSG = "(see error log for more details):\n";
+	String NO_DATA_MSG = "Failed to obtain the data to render: "
+			+ "data is not a value or reference";
+	String NO_SIZE_MSG = "Failed to get the size of the data " + SEE_LOG_MSG;
+	String BIG_DATA_MSG = "%s is approximately %d MB in size, "
+			+ "there could be issues with rendering this inside Taverna\n"
+			+ "Do you want to continue?";
+	String CANCELLED_MSG = "Rendering cancelled due to size of image. "
+			+ "Try saving and viewing in an external application.";
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/RendererRegistryImpl.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/RendererRegistryImpl.java b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/RendererRegistryImpl.java
new file mode 100644
index 0000000..eb41292
--- /dev/null
+++ b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/RendererRegistryImpl.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (C) 2007 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package net.sf.taverna.t2.renderers.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sf.taverna.t2.renderers.Renderer;
+import net.sf.taverna.t2.renderers.RendererRegistry;
+
+/**
+ * Implementation of a RendererRegistry.
+ *
+ * @author David Withers
+ */
+public class RendererRegistryImpl implements RendererRegistry {
+	private List<Renderer> renderers;
+
+	@Override
+	public List<Renderer> getRenderersForMimeType(String mimeType) {
+		ArrayList<Renderer> list = new ArrayList<>();
+		for (Renderer renderer : renderers)
+			if (renderer.canHandle(mimeType))
+				list.add(renderer);
+		return list;
+	}
+
+	@Override
+	public List<Renderer> getRenderers() {
+		return renderers;
+	}
+
+	public void setRenderers(List<Renderer> renderers) {
+		this.renderers = renderers;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/TextRenderer.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/TextRenderer.java b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/TextRenderer.java
new file mode 100644
index 0000000..87fa364
--- /dev/null
+++ b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/TextRenderer.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * 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.renderers.impl;
+
+import static java.awt.Font.PLAIN;
+import static java.lang.String.format;
+import static javax.swing.JOptionPane.NO_OPTION;
+import static javax.swing.JOptionPane.QUESTION_MESSAGE;
+import static javax.swing.JOptionPane.YES_NO_CANCEL_OPTION;
+import static javax.swing.JOptionPane.YES_OPTION;
+import static javax.swing.JOptionPane.showOptionDialog;
+import static net.sf.taverna.t2.renderers.RendererUtils.getInputStream;
+import static net.sf.taverna.t2.renderers.RendererUtils.getString;
+import static net.sf.taverna.t2.renderers.impl.RendererConstants.CANCELLED_MSG;
+import static net.sf.taverna.t2.renderers.impl.RendererConstants.SEE_LOG_MSG;
+
+import java.awt.Font;
+import java.io.InputStream;
+import java.nio.file.Path;
+import java.util.regex.Pattern;
+
+import javax.swing.JComponent;
+import javax.swing.JTextArea;
+
+import net.sf.taverna.t2.lang.ui.DialogTextArea;
+import net.sf.taverna.t2.renderers.RendererException;
+
+/**
+ * Renderer for mime type text/*
+ * 
+ * @author Ian Dunlop
+ * @author Alex Nenadic
+ * @author David Withers
+ */
+public class TextRenderer extends AbstractRenderer {
+	private static final String UNREADABLE_MSG = "Reference Service failed to render data "
+			+ SEE_LOG_MSG;
+	private static final String RENDERER_FAILED_MSG = "Failed to create text renderer "
+			+ SEE_LOG_MSG;
+	private static final String QUERY_MSG = "Result is approximately %d MB "
+			+ "in size, there could be issues with rendering this inside "
+			+ "Taverna\nDo you want to cancel, render all of the result, "
+			+ "or only the first part?";
+	private static final Pattern pattern = Pattern.compile(".*text/.*");
+
+	@Override
+	public boolean canHandle(String mimeType) {
+		return pattern.matcher(mimeType).matches();
+	}
+
+	@Override
+	public String getType() {
+		return "Text";
+	}
+
+	private JComponent textRender(String text) {
+		DialogTextArea theTextArea = new DialogTextArea();
+		theTextArea.setWrapStyleWord(true);
+		theTextArea.setEditable(false);
+		theTextArea.setText(text);
+		theTextArea.setFont(new Font("Monospaced", PLAIN, 12));
+		theTextArea.setCaretPosition(0);
+		return theTextArea;
+	}
+
+	private static final Object[] SIZE_OPTIONS = { "Continue rendering",
+			"Render partial", "Cancel" };
+
+	@Override
+	protected JComponent sizeCheck(Path path, int approximateSizeInMB) {
+		// allow partial rendering of text files
+		int response = showOptionDialog(null,
+				format(QUERY_MSG, approximateSizeInMB),
+				"Rendering large result", YES_NO_CANCEL_OPTION,
+				QUESTION_MESSAGE, null, SIZE_OPTIONS, SIZE_OPTIONS[2]);
+		if (response == YES_OPTION)
+			return null;
+		else if (response != NO_OPTION)
+			// if (response == CANCEL_OPTION) or ESCAPE key pressed
+			return new JTextArea(CANCELLED_MSG);
+
+		// Construct a partial result.
+		byte[] smallStringBytes = new byte[1048576];
+		try (InputStream inputStream = getInputStream(path)) {
+			// just copy the first MEGABYTE
+			inputStream.read(smallStringBytes);
+		} catch (Exception ex) {
+			logger.error("unrenderable: Reference Service failed "
+					+ "to render data as byte array", ex);
+			return new JTextArea(UNREADABLE_MSG + ex.getMessage());
+		}
+		try {
+			// TODO beware of encoding problems!
+			return textRender(new String(smallStringBytes));
+		} catch (Exception e1) {
+			logger.error("Failed to create text renderer", e1);
+			return new JTextArea(RENDERER_FAILED_MSG + e1.getMessage());
+		}
+	}
+
+	@Override
+	public JComponent getRendererComponent(Path path) throws RendererException {
+		String resolve;
+		try {
+			// Resolve it as a string
+			resolve = getString(path);
+		} catch (Exception e) {
+			logger.error("unrenderable: Reference Service failed "
+					+ "to render data as string", e);
+			return new JTextArea(UNREADABLE_MSG + e.getMessage());
+		}
+		try {
+			return textRender(resolve);
+		} catch (Exception e1) {
+			logger.error("Failed to create text renderer", e1);
+			return new JTextArea(RENDERER_FAILED_MSG + e1.getMessage());
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/TextRtfRenderer.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/TextRtfRenderer.java b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/TextRtfRenderer.java
new file mode 100644
index 0000000..6c3bf7f
--- /dev/null
+++ b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/TextRtfRenderer.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * 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.renderers.impl;
+
+import static net.sf.taverna.t2.renderers.impl.RendererConstants.SEE_LOG_MSG;
+
+import java.nio.file.Path;
+import java.util.regex.Pattern;
+
+import javax.swing.JComponent;
+import javax.swing.JEditorPane;
+import javax.swing.JTextArea;
+
+import net.sf.taverna.t2.renderers.RendererException;
+import net.sf.taverna.t2.renderers.RendererUtils;
+
+/**
+ * Renderer for mime type text/rtf
+ *
+ * @author Ian Dunlop
+ * @author Alex Nenadic
+ * @author David Withers
+ */
+public class TextRtfRenderer extends AbstractRenderer {
+	private static final String UNREADABLE_MSG = "Reference Service failed to render data "
+			+ SEE_LOG_MSG;
+	private static final String RENDERER_FAILED_MSG = "Failed to create RTF renderer "
+			+ SEE_LOG_MSG;
+	private static final Pattern pattern = Pattern.compile(".*text/rtf.*");
+
+	public boolean isTerminal() {
+		return true;
+	}
+
+	@Override
+	public boolean canHandle(String mimeType) {
+		return pattern.matcher(mimeType).matches();
+	}
+
+	@Override
+	public String getType() {
+		return "Text/RTF";
+	}
+
+	@Override
+	protected String getSizeQueryTitle() {
+		return "Render as RTF?";
+	}
+
+	@Override
+	public JComponent getRendererComponent(Path path) throws RendererException {
+		String resolve;
+		try {
+			// Resolve it as a string
+			resolve = RendererUtils.getString(path);
+		} catch (Exception e) {
+			logger.error("Reference Service failed to render data as string", e);
+			return new JTextArea(UNREADABLE_MSG + e.getMessage());
+		}
+		try {
+			return new JEditorPane("text/rtf", resolve);
+		} catch (Exception e) {
+			logger.error("Failed to create RTF renderer", e);
+			return new JTextArea(RENDERER_FAILED_MSG + e.getMessage());
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/TextXMLRenderer.java
----------------------------------------------------------------------
diff --git a/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/TextXMLRenderer.java b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/TextXMLRenderer.java
new file mode 100644
index 0000000..eaad9c6
--- /dev/null
+++ b/taverna-workbench-renderers-impl/src/main/java/net/sf/taverna/t2/renderers/impl/TextXMLRenderer.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * 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.renderers.impl;
+
+import static net.sf.taverna.t2.renderers.impl.RendererConstants.SEE_LOG_MSG;
+
+import java.nio.file.Path;
+import java.util.regex.Pattern;
+
+import javax.swing.JComponent;
+import javax.swing.JTextArea;
+
+import net.sf.taverna.t2.renderers.RendererUtils;
+
+/**
+ * Viewer to display XML as a tree.
+ * 
+ * @author Matthew Pocock
+ * @auhor Ian Dunlop
+ * @author David Withers
+ */
+public class TextXMLRenderer extends AbstractRenderer {
+	private static final String UNREADABLE_MSG = "Reference Service failed to render data as string " + SEE_LOG_MSG;
+	private static final String RENDERER_FAILED_MSG = "Failed to create XML renderer " + SEE_LOG_MSG;
+	private Pattern pattern;
+
+	public TextXMLRenderer() {
+		pattern = Pattern.compile(".*text/xml.*");
+	}
+
+	public boolean isTerminal() {
+		return true;
+	}
+
+	@Override
+	public boolean canHandle(String mimeType) {
+		return pattern.matcher(mimeType).matches();
+	}
+
+	@Override
+	public String getType() {
+		return "XML tree";
+	}
+
+	@Override
+	protected String getSizeQueryTitle() {
+		return "Render this as XML?";
+	}
+
+	@Override
+	public JComponent getRendererComponent(Path path) {
+		String resolve = null;
+		try {
+			// Resolve it as a string
+			resolve = RendererUtils.getString(path);
+		} catch (Exception ex) {
+			logger.error("unrenderable: Reference Service failed to render data as string",
+					ex);
+			return new JTextArea(UNREADABLE_MSG + ex.getMessage());
+		}
+		try {
+			return new XMLTree(resolve);
+		} catch (Exception e) {
+			logger.error("unrenderable: failed to create XML renderer", e);
+			return new JTextArea(RENDERER_FAILED_MSG + e.getMessage());
+		}
+	}
+}