more robust jws2 service discovery
[jalview.git] / src / jalview / ws / jws2 / Jws2Discoverer.java
1 package jalview.ws.jws2;
2
3 import java.awt.event.ActionEvent;
4 import java.awt.event.ActionListener;
5 import java.net.ConnectException;
6 import java.util.HashSet;
7 import java.util.Vector;
8
9 import javax.swing.JMenu;
10 import javax.swing.JMenuItem;
11
12 import org.apache.log4j.Level;
13
14 import jalview.bin.Cache;
15 import jalview.datamodel.AlignmentView;
16 import jalview.gui.AlignFrame;
17 import jalview.ws.WSMenuEntryProviderI;
18 import compbio.data.msa.MsaWS;
19 import compbio.ws.client.Jws2Base;
20 import compbio.ws.client.Jws2Base.Services;
21
22 /**
23  * discoverer for jws2 services. Follows the lightweight service discoverer
24  * pattern (archetyped by EnfinEnvision2OneWay)
25  * 
26  * @author JimP
27  * 
28  */
29 public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
30 {
31   private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(this);
32
33   /**
34    * change listeners are notified of "services" property changes
35    * 
36    * @param listener
37    *          to be added that consumes new services Hashtable object.
38    */
39   public void addPropertyChangeListener(
40           java.beans.PropertyChangeListener listener)
41   {
42     changeSupport.addPropertyChangeListener(listener);
43   }
44
45   /**
46    * 
47    * 
48    * @param listener
49    *          to be removed
50    */
51   public void removePropertyChangeListener(
52           java.beans.PropertyChangeListener listener)
53   {
54     changeSupport.removePropertyChangeListener(listener);
55   }
56
57   boolean running=false;
58   @Override
59   public void run()
60   {
61     if (running)
62     {
63       return;
64     }
65     running=true;
66 //    Cache.initLogger();
67 //    Cache.log.setLevel(Level.DEBUG);
68     // TODO: Document and PACK JWS2
69     String jwsservers = Cache.getDefault("JWS2HOSTURLS",
70             "http://webservices.compbio.dundee.ac.uk:8084/jws2");
71     try
72     {
73       if (Jws2Base.validURL(jwsservers))
74       {
75         // look for services
76         for (Services srv : Jws2Base.Services.values())
77         {
78           MsaWS service = null;
79           try
80           {
81             service = Jws2Base.connect(jwsservers, srv);
82           } 
83           catch (Exception e)
84           {
85             System.err.println("Jws2 Discoverer: Problem with "+jwsservers+" with service "+srv+":\n"+e.getMessage());
86             if (!(e instanceof javax.xml.ws.WebServiceException)) {
87               e.printStackTrace();
88             }
89           }
90           ;
91           if (service != null)
92           {
93             addService(jwsservers, srv, service);
94           }
95         }
96
97       }
98       else
99       {
100         Cache.log.info("Ignoring invalid Jws2 service url " + jwsservers);
101       }
102     } catch (Exception e)
103     {
104       e.printStackTrace();
105       Cache.log.warn("Exception when discovering Jws2 services.", e);
106     } catch (Error e)
107     {
108       Cache.log.error("Exception when discovering Jws2 services.", e);
109     }
110     running=false;
111     changeSupport.firePropertyChange("services", new Vector(), services);
112   }
113
114   /**
115    * record this service endpoint so we can use it
116    * 
117    * @param jwsservers
118    * @param srv
119    * @param service2
120    */
121   private void addService(String jwsservers, Services srv, MsaWS service2)
122   {
123     if (services==null) {
124       services = new Vector<Jws2Instance>();
125     }
126     System.out.println("Discovered service: " + jwsservers + " "
127             + srv.toString());
128     services.add(new Jws2Instance(jwsservers, "Align with "
129             + srv.toString(), service2));
130   }
131
132   public class Jws2Instance
133   {
134     String hosturl;
135
136     String serviceType;
137
138     MsaWS service;
139
140     public Jws2Instance(String hosturl, String serviceType, MsaWS service)
141     {
142       super();
143       this.hosturl = hosturl;
144       this.serviceType = serviceType;
145       this.service = service;
146     }
147
148   };
149
150   /**
151    * holds list of services.
152    */
153   Vector<Jws2Instance> services;
154
155   @Override
156   public void attachWSMenuEntry(JMenu wsmenu, final AlignFrame alignFrame)
157   {
158     if (running || services==null || services.size() == 0)
159     {
160       return;
161     }
162     /**
163      * eventually, JWS2 services will appear under the same align/etc submenus.
164      * for moment we keep them separate.
165      */
166     JMenu jws2 = new JMenu("JWS2 Alignment");
167     MsaWSClient msacl = new MsaWSClient();
168     for (final Jws2Instance service : services)
169     {
170       msacl.attachWSMenuEntry(jws2, service, alignFrame);
171       /*JMenuItem sitem = new JMenuItem(service.serviceType);
172       sitem.setToolTipText("Hosted at " + service.hosturl);
173       sitem.addActionListener(new ActionListener()
174       {
175
176         @Override
177         public void actionPerformed(ActionEvent e)
178         {
179           AlignmentView msa = alignFrame.gatherSequencesForAlignment();
180           MsaWSClient client = new MsaWSClient(service,
181                   "JWS2 Alignment of " + alignFrame.getTitle(), msa, false,
182                   true, alignFrame.getViewport().getAlignment().getDataset(),
183                   alignFrame);
184         }
185       });*/
186     }
187     if (services.size()>0)
188     {
189       wsmenu.add(jws2);
190     }
191     
192   }
193   public static void main(String[] args)
194   {
195     Thread runner = new Thread(getDiscoverer());
196     runner.start();
197     while (runner.isAlive())
198     {
199       try
200       {
201         Thread.sleep(50);
202       } catch (InterruptedException e)
203       {
204       }
205       ;
206     }
207   }
208   private static Jws2Discoverer discoverer;
209   public static Jws2Discoverer getDiscoverer()
210   {
211     if (discoverer==null)
212     {
213       discoverer = new Jws2Discoverer();
214     }
215     return discoverer;
216   }
217
218   public boolean hasServices()
219   {
220     // TODO Auto-generated method stub
221     return !running && services!=null && services.size()>0;
222   }
223
224   public boolean isRunning()
225   {
226     return running;
227   }
228   
229 }