formatting
[jalview.git] / src / jalview / ws / jws2 / Jws2Discoverer.java
index b6e7493..c0addfe 100644 (file)
@@ -32,9 +32,11 @@ import java.beans.PropertyChangeListener;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
@@ -266,7 +268,9 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
     // dynamically regenerate service list.
     populateWSMenuEntry(wsmenu, alignFrame, null);
   }
-
+  private boolean isRecalculable(String action) {
+    return (action!=null && action.equalsIgnoreCase("conservation"));
+  }
   private void populateWSMenuEntry(JMenu jws2al, final AlignFrame alignFrame, String typeFilter)
   {
     if (running || services == null || services.size() == 0)
@@ -280,13 +284,130 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
      * for moment we keep them separate.
      */
     JMenu atpoint;
+    List<Jws2Instance> enumerableServices=new ArrayList<Jws2Instance>();
+    //jws2al.removeAll();
+    Map<String, Jws2Instance> preferredHosts=new HashMap<String,Jws2Instance>();
+    Map<String, List<Jws2Instance>> alternates = new HashMap<String, List<Jws2Instance>>();
+    for (Jws2Instance service : services.toArray(new Jws2Instance[0]))
+    {
+      if (!isRecalculable(service.action)) {
+        // add 'one shot' services to be displayed using the classic menu structure
+        enumerableServices.add(service);
+      } else {
+        if (!preferredHosts.containsKey(service.serviceType))
+        {
+          Jws2Instance preferredInstance = getPreferredServiceFor(alignFrame,
+                  service.serviceType);
+          if (preferredInstance != null)
+          {
+            preferredHosts.put(service.serviceType, preferredInstance);
+          }
+          else
+          {
+            preferredHosts.put(service.serviceType, service);
+          }
+        }
+        List<Jws2Instance> ph=alternates.get(service.serviceType);
+        if (preferredHosts.get(service.serviceType)!=service)
+        {
+          if (ph==null)
+          {
+            ph=new ArrayList<Jws2Instance>();
+          }
+          ph.add(service);
+          alternates.put(service.serviceType, ph);
+        }
+      }
+
+    }
+
+    // create GUI element for classic services
+    addEnumeratedServices(jws2al, alignFrame, enumerableServices);
+    // and the instantaneous services
+    for (final Jws2Instance service : preferredHosts.values())
+    {
+      atpoint = JvSwingUtils.findOrCreateMenu(jws2al,service.action);
+      JMenuItem hitm;
+      if (atpoint.getItemCount()>1) {
+        // previous service of this type already present
+        atpoint.addSeparator();
+      }
+      atpoint.add(hitm = new JMenuItem(service.getHost()));
+      hitm.setForeground(Color.blue);
+      hitm.addActionListener(new ActionListener()
+      {
+
+        @Override
+        public void actionPerformed(ActionEvent e)
+        {
+          Desktop.showUrl(service.getHost());
+        }
+      });
+      hitm.setToolTipText(JvSwingUtils
+              .wrapTooltip("Opens the JABAWS server's homepage in web browser"));
+
+      service.attachWSMenuEntry(atpoint, alignFrame);
+      if (alternates.containsKey(service.serviceType))
+      {
+        atpoint.add(hitm=new JMenu("Switch server"));
+        hitm.setToolTipText(JvSwingUtils.wrapTooltip("Choose a server for running this service"));
+        for (final Jws2Instance sv:alternates.get(service.serviceType))
+        {
+          JMenuItem itm;
+          hitm.add(itm=new JMenuItem(sv.getHost()));
+          itm.setForeground(Color.blue);
+          itm.addActionListener(new ActionListener()
+          {
+
+            @Override
+            public void actionPerformed(ActionEvent arg0)
+            {
+              new Thread(new Runnable() { 
+                public void run() {
+                  setPreferredServiceFor(alignFrame, sv.serviceType, sv.action, sv);
+                  changeSupport.firePropertyChange("services", new Vector(), services);
+                };
+              }).start();
+
+            }
+          });
+        }
+        /*hitm.addActionListener(new ActionListener()
+              {
+
+                @Override
+                public void actionPerformed(ActionEvent arg0)
+                {
+                  new Thread(new Runnable() {
+                    @Override
+                    public void run()
+                    {
+                      new SetPreferredServer(alignFrame, service.serviceType, service.action);
+                    }
+                  }).start();
+                }
+              });*/
+      }
+    }
+  }
+  /**
+   * add services using the Java 2.5/2.6/2.7 system which optionally creates submenus to index by host and service program type
+   */
+  private void addEnumeratedServices(final JMenu jws2al, final AlignFrame alignFrame, List<Jws2Instance> enumerableServices)
+  {
+    boolean byhost = Cache.getDefault("WSMENU_BYHOST", false), bytype = Cache
+            .getDefault("WSMENU_BYTYPE", false);
+    /**
+     * eventually, JWS2 services will appear under the same align/etc submenus.
+     * for moment we keep them separate.
+     */
+    JMenu atpoint;
     MsaWSClient msacl = new MsaWSClient();
-    Vector hostLabels = new Vector();
-    jws2al.removeAll();
-    Hashtable<String,String> lasthostFor = new Hashtable<String,String>();
+    List<String> hostLabels = new ArrayList<String>();
+    Hashtable<String, String> lasthostFor = new Hashtable<String, String>();
     Hashtable<String, ArrayList<Jws2Instance>> hosts = new Hashtable<String, ArrayList<Jws2Instance>>();
     ArrayList<String> hostlist=new ArrayList<String>();
-    for (Jws2Instance service : services)
+    for (Jws2Instance service : enumerableServices)
     {
       ArrayList<Jws2Instance> hostservices = hosts.get(service.getHost());
       if (hostservices == null)
@@ -339,7 +460,11 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
           // contiguous
           // group
           JMenuItem hitm;
-          atpoint.addSeparator();
+          if (hostLabels.contains(host)) {
+            atpoint.addSeparator();
+          } else {
+            hostLabels.add(host);
+          }
           if (lasthostFor.get(service.action) == null || !lasthostFor.get(service.action).equals(host))
           {
             atpoint.add(hitm = new JMenuItem(host));
@@ -357,30 +482,14 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
                     .wrapTooltip("Opens the JABAWS server's homepage in web browser"));
             lasthostFor.put(service.action,host);
           }
-          hostLabels.addElement(host + service.serviceType
+          hostLabels.add(host + service.serviceType
                   + service.getActionText());
-          // hostLabels.addElement(host + (bytype ?
-          // service.serviceType+service.getActionText() : ""));
         }
         
         service.attachWSMenuEntry(atpoint, alignFrame);
-        /*
-         * JMenuItem sitem = new JMenuItem(service.serviceType);
-         * sitem.setToolTipText("Hosted at " + service.hosturl);
-         * sitem.addActionListener(new ActionListener() {
-         * 
-         * @Override public void actionPerformed(ActionEvent e) { AlignmentView
-         * msa = alignFrame.gatherSequencesForAlignment(); MsaWSClient client =
-         * new MsaWSClient(service, "JWS2 Alignment of " +
-         * alignFrame.getTitle(), msa, false, true,
-         * alignFrame.getViewport().getAlignment().getDataset(), alignFrame); }
-         * });
-         */
       }
     }
-
   }
-
   public static void main(String[] args)
   {
     if (args.length>0)
@@ -732,4 +841,71 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
     }
     return match;
   }
+  
+  Map<String, Map<String, String>> preferredServiceMap = new HashMap<String, Map<String, String>>();
+;
+
+  /**
+   * get current preferred service of the given type, or global default
+   * @param af null or a specific alignFrame 
+   * @param serviceType Jws2Instance.serviceType for service
+   * @return null if no service of this type is available, the preferred service for the serviceType and af if specified and if defined. 
+   */
+  public Jws2Instance getPreferredServiceFor(AlignFrame af,
+          String serviceType)
+  {
+    String serviceurl = null;
+    synchronized (preferredServiceMap)
+    {
+      String afid = (af == null) ? "" : af.getViewport().getSequenceSetId();
+      Map<String, String> prefmap = preferredServiceMap.get(afid);
+      if (afid.length() > 0 && prefmap == null)
+      {
+        // recover global setting, if any
+        prefmap = preferredServiceMap.get("");
+      }
+        if (prefmap != null)
+        {
+          serviceurl = prefmap.get(serviceType);
+        }
+      
+    }
+    Jws2Instance response = null;
+    for (Jws2Instance svc : services)
+    {
+      if (svc.serviceType.equals(serviceType))
+      {
+        if (serviceurl == null || serviceurl.equals(svc.getHost()))
+        {
+          response = svc;
+          break;
+        }
+      }
+    }
+    return response;
+  }
+
+  public void setPreferredServiceFor(AlignFrame af, String serviceType,
+          String serviceAction, Jws2Instance selectedServer)
+  {
+    String afid = (af == null) ? "" : af.getViewport().getSequenceSetId();
+    if (preferredServiceMap == null)
+    {
+      preferredServiceMap = new HashMap<String, Map<String, String>>();
+    }
+    Map<String, String> prefmap = preferredServiceMap.get(afid);
+    if (prefmap == null)
+    {
+      prefmap = new HashMap<String, String>();
+      preferredServiceMap.put(afid, prefmap);
+    }
+    prefmap.put(serviceType, selectedServer.getHost());
+    prefmap.put(serviceAction, selectedServer.getHost());
+  }
+
+  public void setPreferredServiceFor(String serviceType,
+          String serviceAction, Jws2Instance selectedServer)
+  {
+    setPreferredServiceFor(null, serviceType, serviceAction, selectedServer);
+  }
 }