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