From d25930a1576379cd45940caa9c1f0e4cf01fbc2c Mon Sep 17 00:00:00 2001 From: jprocter Date: Sat, 19 Jun 2010 16:43:39 +0000 Subject: [PATCH] rejigged change support to make it (more) reliable --- src/jalview/gui/AlignFrame.java | 49 ++--- src/jalview/gui/Desktop.java | 363 +++++++++++++++++++++++-------- src/jalview/ws/jws1/Discoverer.java | 5 +- src/jalview/ws/jws2/Jws2Discoverer.java | 155 +++++++++---- 4 files changed, 407 insertions(+), 165 deletions(-) diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 87776d3..6ee243e 100755 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -30,6 +30,7 @@ import javax.swing.*; import javax.swing.event.MenuEvent; import jalview.analysis.*; +import jalview.bin.Cache; import jalview.commands.*; import jalview.datamodel.*; import jalview.io.*; @@ -514,16 +515,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, /* Set up intrinsic listeners for dynamically generated GUI bits. */ private void addServiceListeners() { - final java.beans.PropertyChangeListener thisListener, thatListener; + final java.beans.PropertyChangeListener thisListener; // Do this once to get current state BuildWebServiceMenu(); - Desktop.discoverer - .addPropertyChangeListener(thisListener = new java.beans.PropertyChangeListener() + Desktop.instance.addJalviewPropertyChangeListener("services", + thisListener=new java.beans.PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { - // System.out.println("Discoverer property change."); - if (evt.getPropertyName().equals("services")) + // // System.out.println("Discoverer property change."); + // if (evt.getPropertyName().equals("services")) { SwingUtilities.invokeLater(new Runnable() { @@ -532,7 +533,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void run() { System.err - .println("Change support JWS1: build services again."); + .println("Rebuild WS Menu for service change"); BuildWebServiceMenu(); } @@ -540,26 +541,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } } }); - jalview.ws.jws2.Jws2Discoverer.getDiscoverer() - .addPropertyChangeListener( - thatListener = new java.beans.PropertyChangeListener() - { - public void propertyChange(PropertyChangeEvent evt) - { - System.err - .println("Change support JWS2: build services again."); - BuildWebServiceMenu(); - } - }); addInternalFrameListener(new javax.swing.event.InternalFrameAdapter() { public void internalFrameClosed( javax.swing.event.InternalFrameEvent evt) { - // System.out.println("deregistering discoverer listener"); - Desktop.discoverer.removePropertyChangeListener(thisListener); - jalview.ws.jws2.Jws2Discoverer.getDiscoverer() - .removePropertyChangeListener(thatListener); + System.out.println("deregistering discoverer listener"); + Desktop.instance.removeJalviewPropertyChangeListener("services",thisListener); closeMenuItem_actionPerformed(true); }; }); @@ -3843,7 +3831,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, // object broker mechanism. Vector wsmenu = new Vector(); final IProgressIndicator af = this; - if ((Discoverer.services != null) && (Discoverer.services.size() > 0)) + if (Cache.getDefault("SHOW_JWS1_SERVICES", true) + && Discoverer.services != null + && (Discoverer.services.size() > 0)) { // TODO: refactor to allow list of AbstractName/Handler bindings to be // stored or retrieved from elsewhere @@ -3901,6 +3891,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } // TODO: move into separate menu builder class. + if (Cache.getDefault("SHOW_JWS2_SERVICES", true)) { Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer(); if (jws2servs != null) @@ -3911,13 +3902,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, jws2servs.attachWSMenuEntry(jws2men, this); wsmenu.add(jws2men); } - else - { - if (!jws2servs.isRunning()) - { - new Thread(jws2servs).start(); - } - } } } resetWebServiceMenu(); @@ -3959,8 +3943,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, */ private void build_urlServiceMenu(JMenu webService) { - jalview.ws.EnfinEnvision2OneWay.getInstance().attachWSMenuEntry( - webService, this); + if (Cache.getDefault("SHOW_ENFIN_SERVICES", true)) + { + jalview.ws.EnfinEnvision2OneWay.getInstance().attachWSMenuEntry( + webService, this); + } } /* diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index 3ba50c5..23b18b0 100755 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -24,6 +24,8 @@ import java.awt.*; import java.awt.datatransfer.*; import java.awt.dnd.*; import java.awt.event.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; @@ -40,7 +42,8 @@ import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; /** - * DOCUMENT ME! + * Jalview Desktop + * * * @author $author$ * @version $Revision$ @@ -48,15 +51,117 @@ import javax.swing.event.MenuListener; public class Desktop extends jalview.jbgui.GDesktop implements DropTargetListener, ClipboardOwner, IProgressIndicator { - /** DOCUMENT ME!! */ + + private class JalviewChangeSupport implements PropertyChangeListener + { + @Override + public void propertyChange(PropertyChangeEvent evt) + { + // Handle change events - most are simply routed to other sources + changeSupport.firePropertyChange(evt); + } + + /** + * change listeners are notified of changes to resources so they can update + * their state. E.g. - the 'services' property notifies when the available + * set of web service endpoints have changed. + */ + private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport( + this); + + /** + * @param propertyName + * @param listener + * @see java.beans.PropertyChangeSupport#addPropertyChangeListener(java.lang.String, + * java.beans.PropertyChangeListener) + */ + public void addJalviewPropertyChangeListener(String propertyName, + PropertyChangeListener listener) + { + changeSupport.addPropertyChangeListener(propertyName, listener); + } + + /** + * @param listener + * @see java.beans.PropertyChangeSupport#addPropertyChangeListener( + * java.beans.PropertyChangeListener) + */ + public void addJalviewPropertyChangeListener( + PropertyChangeListener listener) + { + changeSupport.addPropertyChangeListener(listener); + } + + /* + * @param propertyName + * + * @param oldValue + * + * @param newValue + * + * @see + * java.beans.PropertyChangeSupport#firePropertyChange(java.lang.String, + * java.lang.Object, java.lang.Object) public void firePropertyChange(String + * propertyName, Object oldValue, Object newValue) { + * changeSupport.firePropertyChange(propertyName, oldValue, newValue); } + */ + + /** + * @param propertyName + * @param listener + * @see java.beans.PropertyChangeSupport#removePropertyChangeListener(java.lang.String, + * java.beans.PropertyChangeListener) + */ + public void removeJalviewPropertyChangeListener(String propertyName, + PropertyChangeListener listener) + { + changeSupport.removePropertyChangeListener(propertyName, listener); + } + + } + + private JalviewChangeSupport changeSupport = new JalviewChangeSupport(); + + /** + * @param listener + * @see jalview.gui.Desktop.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener) + */ + public void addJalviewPropertyChangeListener( + PropertyChangeListener listener) + { + changeSupport.addJalviewPropertyChangeListener(listener); + } + + /** + * @param propertyName + * @param listener + * @see jalview.gui.Desktop.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String, + * java.beans.PropertyChangeListener) + */ + public void addJalviewPropertyChangeListener(String propertyName, + PropertyChangeListener listener) + { + changeSupport.addJalviewPropertyChangeListener(propertyName, listener); + } + + /** + * @param propertyName + * @param listener + * @see jalview.gui.Desktop.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String, + * java.beans.PropertyChangeListener) + */ + public void removeJalviewPropertyChangeListener(String propertyName, + PropertyChangeListener listener) + { + changeSupport.removeJalviewPropertyChangeListener(propertyName, + listener); + } + + /** Singleton Desktop instance */ public static Desktop instance; - // Need to decide if the Memory Usage is to be included in - // Next release or not. public static MyDesktopPane desktop; - // public static JDesktopPane desktop; - static int openFrameCount = 0; static final int xOffset = 30; @@ -70,84 +175,105 @@ public class Desktop extends jalview.jbgui.GDesktop implements public static boolean internalCopy = false; static int fileLoadingCount = 0; - class MyDesktopManager implements DesktopManager { - - private DesktopManager delegate; - - public MyDesktopManager(DesktopManager delegate) { - this.delegate = delegate; - } - - public void activateFrame(JInternalFrame f) { - try { - delegate.activateFrame(f); - } catch (NullPointerException npe) { - Point p = getMousePosition(); - instance.showPasteMenu(p.x,p.y); - } - } - - public void beginDraggingFrame(JComponent f) { - delegate.beginDraggingFrame(f); - } - - public void beginResizingFrame(JComponent f, int direction) { - delegate.beginResizingFrame(f, direction); - } - - public void closeFrame(JInternalFrame f) { - delegate.closeFrame(f); - } - - public void deactivateFrame(JInternalFrame f) { - delegate.deactivateFrame(f); - } - - public void deiconifyFrame(JInternalFrame f) { - delegate.deiconifyFrame(f); - } - - public void dragFrame(JComponent f, int newX, int newY) { - delegate.dragFrame(f, newX, newY); - } - - public void endDraggingFrame(JComponent f) { - delegate.endDraggingFrame(f); - } - - public void endResizingFrame(JComponent f) { - delegate.endResizingFrame(f); - } - - public void iconifyFrame(JInternalFrame f) { - delegate.iconifyFrame(f); - } - - public void maximizeFrame(JInternalFrame f) { - delegate.maximizeFrame(f); - } - - public void minimizeFrame(JInternalFrame f) { - delegate.minimizeFrame(f); - } - - public void openFrame(JInternalFrame f) { - delegate.openFrame(f); - } - - public void resizeFrame(JComponent f, int newX, int newY, int newWidth, - int newHeight) { - delegate.resizeFrame(f, newX, newY, newWidth, newHeight); - } - - public void setBoundsForFrame(JComponent f, int newX, int newY, - int newWidth, int newHeight) { - delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight); - } - - // All other methods, simply delegate - - } + + class MyDesktopManager implements DesktopManager + { + + private DesktopManager delegate; + + public MyDesktopManager(DesktopManager delegate) + { + this.delegate = delegate; + } + + public void activateFrame(JInternalFrame f) + { + try + { + delegate.activateFrame(f); + } catch (NullPointerException npe) + { + Point p = getMousePosition(); + instance.showPasteMenu(p.x, p.y); + } + } + + public void beginDraggingFrame(JComponent f) + { + delegate.beginDraggingFrame(f); + } + + public void beginResizingFrame(JComponent f, int direction) + { + delegate.beginResizingFrame(f, direction); + } + + public void closeFrame(JInternalFrame f) + { + delegate.closeFrame(f); + } + + public void deactivateFrame(JInternalFrame f) + { + delegate.deactivateFrame(f); + } + + public void deiconifyFrame(JInternalFrame f) + { + delegate.deiconifyFrame(f); + } + + public void dragFrame(JComponent f, int newX, int newY) + { + delegate.dragFrame(f, newX, newY); + } + + public void endDraggingFrame(JComponent f) + { + delegate.endDraggingFrame(f); + } + + public void endResizingFrame(JComponent f) + { + delegate.endResizingFrame(f); + } + + public void iconifyFrame(JInternalFrame f) + { + delegate.iconifyFrame(f); + } + + public void maximizeFrame(JInternalFrame f) + { + delegate.maximizeFrame(f); + } + + public void minimizeFrame(JInternalFrame f) + { + delegate.minimizeFrame(f); + } + + public void openFrame(JInternalFrame f) + { + delegate.openFrame(f); + } + + public void resizeFrame(JComponent f, int newX, int newY, int newWidth, + int newHeight) + { + delegate.resizeFrame(f, newX, newY, newWidth, newHeight); + } + + public void setBoundsForFrame(JComponent f, int newX, int newY, + int newWidth, int newHeight) + { + delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight); + } + + // All other methods, simply delegate + + } + /** * Creates a new Desktop object. */ @@ -177,7 +303,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements // This line prevents Windows Look&Feel resizing all new windows to maximum // if previous window was maximised - desktop.setDesktopManager(new MyDesktopManager(new DefaultDesktopManager())); + desktop.setDesktopManager(new MyDesktopManager( + new DefaultDesktopManager())); Rectangle dims = getLastKnownDimensions(""); if (dims != null) { @@ -231,7 +358,6 @@ public class Desktop extends jalview.jbgui.GDesktop implements } }); - discoverer = new jalview.ws.jws1.Discoverer(); // Only gets started if gui is // displayed. // Thread off a new instance of the file chooser - this reduces the time it // takes to open it later on. @@ -1752,7 +1878,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements public void paintComponent(Graphics g) { - if (showMemoryUsage && g != null) + if (showMemoryUsage && g != null && df != null) { if (percentUsage < 20) g.setColor(Color.red); @@ -1965,15 +2091,66 @@ public class Desktop extends jalview.jbgui.GDesktop implements public void startServiceDiscovery() { - discoverer.start(); - - try { - new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()).start(); + startServiceDiscovery(false); + } + + public void startServiceDiscovery(boolean blocking) + { + boolean alive = true; + Thread t0 = null, t1 = null, t2 = null; + + // todo: changesupport handlers need to be transferred + if (discoverer == null) + { + discoverer = new jalview.ws.jws1.Discoverer(); + // register PCS handler for desktop. + discoverer.addPropertyChangeListener(changeSupport); + } + if (Cache.getDefault("SHOW_JWS1_SERVICES", true)) + { + (t0 = new Thread(discoverer)).start(); + } + + try + { + if (Cache.getDefault("SHOW_ENVISION2_SERVICES", true)) + { + // EnfinEnvision web service menu entries are rebuild every time the + // menu is shown, so no changeSupport events are needed. + jalview.ws.EnfinEnvision2OneWay.getInstance(); + (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance())) + .start(); + } } catch (Exception e) { - Cache.log.info("Exception when trying to launch Envision2 workflow discovery.",e); + Cache.log + .info( + "Exception when trying to launch Envision2 workflow discovery.", + e); Cache.log.info(e.getStackTrace()); } - new Thread(jalview.ws.jws2.Jws2Discoverer.getDiscoverer()).start(); + if (Cache.getDefault("SHOW_JWS2_SERVICES", true)) + { + jalview.ws.jws2.Jws2Discoverer.getDiscoverer() + .addPropertyChangeListener(changeSupport); + (t2 = new Thread(jalview.ws.jws2.Jws2Discoverer.getDiscoverer())) + .start(); + } + if (blocking) + { + while (alive) + { + try + { + Thread.sleep(15); + } catch (Exception e) + { + } + alive = (t1 != null && t1.isAlive()) + || (t2 != null && t2.isAlive()) + || (t0 != null && t0.isAlive()); + } + } } + } diff --git a/src/jalview/ws/jws1/Discoverer.java b/src/jalview/ws/jws1/Discoverer.java index 90581dc..0638b69 100644 --- a/src/jalview/ws/jws1/Discoverer.java +++ b/src/jalview/ws/jws1/Discoverer.java @@ -44,13 +44,12 @@ import javax.swing.*; import ext.vamsas.*; -public class Discoverer extends Thread implements Runnable +public class Discoverer implements Runnable { ext.vamsas.IRegistry registry; // the root registry service. private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport( this); - /** * change listeners are notified of "services" property changes * @@ -387,7 +386,7 @@ public class Discoverer extends Thread implements Runnable // Vector oldServicelist = serviceList; services = sscat; serviceList = cat; - firePropertyChange("services", oldServices, services); + changeSupport.firePropertyChange("services", oldServices, services); } /** diff --git a/src/jalview/ws/jws2/Jws2Discoverer.java b/src/jalview/ws/jws2/Jws2Discoverer.java index 6aa4607..784ff49 100644 --- a/src/jalview/ws/jws2/Jws2Discoverer.java +++ b/src/jalview/ws/jws2/Jws2Discoverer.java @@ -6,6 +6,7 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.net.ConnectException; import java.util.HashSet; +import java.util.StringTokenizer; import java.util.Vector; import javax.swing.JMenu; @@ -60,15 +61,16 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI } boolean running = false; - + Thread oldthread=null; @Override public void run() { - if (running) + if (running && oldthread!=null && oldthread.isAlive()) { return; } running = true; + oldthread = Thread.currentThread(); try { Class foo = getClass().getClassLoader().loadClass( @@ -77,56 +79,59 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI { System.err .println("Not enabling Jalview Webservices version 2: client jar is not available." - +"\nPlease check that your webstart JNLP file is up to date!"); + + "\nPlease check that your webstart JNLP file is up to date!"); running = false; return; } - // Cache.initLogger(); - // Cache.log.setLevel(Level.DEBUG); - // TODO: Document and PACK JWS2 - String jwsservers = Cache.getDefault("JWS2HOSTURLS", - "http://webservices.compbio.dundee.ac.uk:8084/jws2"); - try + if (services != null) { - if (Jws2Base.validURL(jwsservers)) + services.removeAllElements(); + } + for (String jwsservers : getServiceUrls()) + { + try { - // look for services - for (Services srv : Jws2Base.Services.values()) + if (Jws2Base.validURL(jwsservers)) { - MsaWS service = null; - try - { - service = Jws2Base.connect(jwsservers, srv); - } catch (Exception e) + // look for services + for (Services srv : Jws2Base.Services.values()) { - System.err.println("Jws2 Discoverer: Problem with " - + jwsservers + " with service " + srv + ":\n" - + e.getMessage()); - if (!(e instanceof javax.xml.ws.WebServiceException)) + MsaWS service = null; + try { - e.printStackTrace(); + service = Jws2Base.connect(jwsservers, srv); + } catch (Exception e) + { + System.err.println("Jws2 Discoverer: Problem on " + + jwsservers + " with service " + srv + ":\n" + + e.getMessage()); + if (!(e instanceof javax.xml.ws.WebServiceException)) + { + e.printStackTrace(); + } + } + ; + if (service != null) + { + addService(jwsservers, srv, service); } } - ; - if (service != null) - { - addService(jwsservers, srv, service); - } - } - } - else + } + else + { + Cache.log.info("Ignoring invalid Jws2 service url " + jwsservers); + } + } catch (Exception e) + { + e.printStackTrace(); + Cache.log.warn("Exception when discovering Jws2 services.", e); + } catch (Error e) { - Cache.log.info("Ignoring invalid Jws2 service url " + jwsservers); + Cache.log.error("Exception when discovering Jws2 services.", e); } - } catch (Exception e) - { - e.printStackTrace(); - Cache.log.warn("Exception when discovering Jws2 services.", e); - } catch (Error e) - { - Cache.log.error("Exception when discovering Jws2 services.", e); } + oldthread = null; running = false; changeSupport.firePropertyChange("services", new Vector(), services); } @@ -280,4 +285,78 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI return running; } + /** + * the jalview .properties entry for JWS2 URLS + */ + final static String JWS2HOSTURLS = "JWS2HOSTURLS"; + + public static void setServiceUrls(Vector urls) + { + if (urls != null) + { + StringBuffer urlbuffer = new StringBuffer(); + String sep = ""; + for (String url : urls) + { + urlbuffer.append(sep); + urlbuffer.append(url); + sep = ","; + } + Cache.setProperty(JWS2HOSTURLS, urlbuffer.toString()); + } + else + { + Cache.removeProperty(JWS2HOSTURLS); + } + } + + public static Vector getServiceUrls() + { + String surls = Cache.getDefault(JWS2HOSTURLS, + "http://webservices.compbio.dundee.ac.uk:8084/jws2"); + Vector urls = new Vector(); + try + { + StringTokenizer st = new StringTokenizer(surls, ","); + while (st.hasMoreElements()) + { + String url = null; + try + { + java.net.URL u = new java.net.URL(url = st.nextToken()); + if (!urls.contains(url)) + { + urls.add(url); + } + else + { + jalview.bin.Cache.log.info("Ignoring duplicate url in " + + JWS2HOSTURLS + " list"); + } + } catch (Exception ex) + { + jalview.bin.Cache.log + .warn("Problem whilst trying to make a URL from '" + + ((url != null) ? url : "") + "'"); + jalview.bin.Cache.log + .warn("This was probably due to a malformed comma separated list" + + " in the " + + JWS2HOSTURLS + + " entry of $(HOME)/.jalview_properties)"); + jalview.bin.Cache.log.debug("Exception was ", ex); + } + } + } catch (Exception ex) + { + jalview.bin.Cache.log.warn( + "Error parsing comma separated list of urls in " + + JWS2HOSTURLS + " preference.", ex); + } + if (urls.size() >= 0) + { + return urls; + } + return null; + } + } -- 1.7.10.2