JAL-3690 refactoring web-services discovery
[jalview.git] / src / jalview / ws / jws2 / Jws2Discoverer.java
index 30c1cb7..73d3700 100644 (file)
@@ -23,6 +23,7 @@ package jalview.ws.jws2;
 import jalview.bin.Cache;
 import jalview.gui.AlignFrame;
 import jalview.util.MessageManager;
+import jalview.ws.ServiceChangeListener;
 import jalview.ws.WSDiscovererI;
 import jalview.ws.api.ServiceWithParameters;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
@@ -34,11 +35,16 @@ import java.beans.PropertyChangeSupport;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.Vector;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
 
 import javax.swing.JMenu;
 
@@ -72,9 +78,8 @@ public class Jws2Discoverer implements WSDiscovererI, Runnable
 
   // preferred url has precedence over others
   private String preferredUrl;
-
-  private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
-          this);
+  
+  private Set<ServiceChangeListener> serviceListeners = new CopyOnWriteArraySet<>();
 
   private Vector<String> invalidServiceUrls = null;
 
@@ -85,8 +90,8 @@ public class Jws2Discoverer implements WSDiscovererI, Runnable
   private volatile boolean running = false;
 
   private volatile boolean aborted = false;
-
-  private Thread oldthread = null;
+  
+  private volatile Thread oldthread = null;
 
   /**
    * holds list of services.
@@ -100,28 +105,25 @@ public class Jws2Discoverer implements WSDiscovererI, Runnable
   {
   }
 
-  /**
-   * change listeners are notified of "services" property changes
-   * 
-   * @param listener
-   *          to be added that consumes new services Hashtable object.
-   */
-  public void addPropertyChangeListener(
-          java.beans.PropertyChangeListener listener)
+
+  @Override
+  public void addServiceChangeListener(ServiceChangeListener listener)
   {
-    changeSupport.addPropertyChangeListener(listener);
+    serviceListeners.add(listener);
   }
 
-  /**
-   * 
-   * 
-   * @param listener
-   *          to be removed
-   */
-  public void removePropertyChangeListener(
-          java.beans.PropertyChangeListener listener)
+  @Override
+  public void removeServiceChangeListener(ServiceChangeListener listener)
   {
-    changeSupport.removePropertyChangeListener(listener);
+    serviceListeners.remove(listener);
+  }
+
+  private void notifyServiceListeners(List<? extends ServiceWithParameters> services) 
+  {
+    if (services == null) services = this.services;
+    for (var listener : serviceListeners) {
+      listener.servicesChanged(this, services);
+    }
   }
 
   /**
@@ -176,13 +178,11 @@ public class Jws2Discoverer implements WSDiscovererI, Runnable
       ignoredServices.add(ignored);
     }
 
-    changeSupport.firePropertyChange("services", services,
-            new Vector<Jws2Instance>());
+    notifyServiceListeners(Collections.emptyList());
     oldthread = Thread.currentThread();
     try
     {
-      Class foo = getClass().getClassLoader()
-              .loadClass("compbio.ws.client.Jws2Client");
+      getClass().getClassLoader().loadClass("compbio.ws.client.Jws2Client");
     } catch (ClassNotFoundException e)
     {
       System.err.println(
@@ -287,8 +287,7 @@ public class Jws2Discoverer implements WSDiscovererI, Runnable
     }
     oldthread = null;
     running = false;
-    changeSupport.firePropertyChange("services", new Vector<Jws2Instance>(),
-            services);
+    notifyServiceListeners(services);
   }
 
   /**
@@ -325,30 +324,6 @@ public class Jws2Discoverer implements WSDiscovererI, Runnable
   }
 
   /**
-   * attach all available web services to the appropriate submenu in the given
-   * JMenu
-   */
-  @Override
-  public void attachWSMenuEntry(JMenu wsmenu, final AlignFrame alignFrame)
-  {
-    if (running || services == null || services.size() == 0)
-    {
-      return;
-    }
-    // dynamically regenerate service list.
-    populateWSMenuEntry(wsmenu, alignFrame, null);
-  }
-
-  private void populateWSMenuEntry(JMenu jws2al,
-          final AlignFrame alignFrame, String typeFilter)
-  {
-    PreferredServiceRegistry.getRegistry().populateWSMenuEntry(
-            getServices(),
-            changeSupport, jws2al,
-            alignFrame, typeFilter);
-  }
-
-  /**
    * 
    * @param args
    * @j2sIgnore
@@ -363,37 +338,28 @@ public class Jws2Discoverer implements WSDiscovererI, Runnable
         testUrls.add(url);
       }
     }
-    Thread runner = getDiscoverer()
-            .startDiscoverer(new PropertyChangeListener()
-            {
-
-              @Override
-              public void propertyChange(PropertyChangeEvent evt)
-              {
-                if (getDiscoverer().services != null)
-                {
-                  System.out.println("Changesupport: There are now "
-                          + getDiscoverer().services.size() + " services");
-                  int i = 1;
-                  for (ServiceWithParameters instance : getDiscoverer().services)
-                  {
-                    System.out.println("Service " + i++ + " "
-                            + instance.getClass() + "@"
-                            + instance.getHostURL()
-                            + ": " + instance.getActionText());
-                  }
-
-                }
-              }
-            });
-    while (runner.isAlive())
-    {
-      try
-      {
-        Thread.sleep(50);
-      } catch (InterruptedException e)
+    var discoverer = getDiscoverer();
+    discoverer.addServiceChangeListener((_discoverer, _services) -> {
+      if (discoverer.services != null)
       {
+        System.out.println("Changesupport: There are now "
+                + discoverer.services.size() + " services");
+        int i = 1;
+        for (ServiceWithParameters instance : discoverer.services)
+        {
+          System.out.println(
+                  "Service " + i++ + " " + instance.getClass()
+                          + "@" + instance.getHostURL() + ": "
+                          + instance.getActionText());
+        }
+
       }
+    });
+    try
+    {
+      discoverer.startDiscoverer().get();
+    } catch (InterruptedException | ExecutionException e)
+    {
     }
     try
     {
@@ -513,8 +479,7 @@ public class Jws2Discoverer implements WSDiscovererI, Runnable
   @Override
   public Vector<ServiceWithParameters> getServices()
   {
-    return (services == null) ? new Vector<>()
-            : new Vector<>(services);
+    return (services == null) ? new Vector<>() : new Vector<>(services);
   }
 
   /**
@@ -573,7 +538,7 @@ public class Jws2Discoverer implements WSDiscovererI, Runnable
    * @return new thread
    */
   @Override
-  public Thread startDiscoverer(PropertyChangeListener changeSupport2)
+  public FutureTask<WSDiscovererI> startDiscoverer()
   {
     /*    if (restart())
         {
@@ -589,10 +554,9 @@ public class Jws2Discoverer implements WSDiscovererI, Runnable
     {
       setAborted(true);
     }
-    addPropertyChangeListener(changeSupport2);
-    Thread thr = new Thread(this);
-    thr.start();
-    return thr;
+    FutureTask<WSDiscovererI> task = new FutureTask<>(this, this);
+    new Thread(task).start();
+    return task;
   }
 
   /**