1 package jalview.ws.jws2;
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;
9 import java.util.HashSet;
10 import java.util.Hashtable;
11 import java.util.StringTokenizer;
12 import java.util.Vector;
14 import javax.swing.JMenu;
15 import javax.swing.JMenuItem;
17 import org.apache.log4j.Level;
19 import jalview.bin.Cache;
20 import jalview.datamodel.AlignmentView;
21 import jalview.gui.AlignFrame;
22 import jalview.ws.WSMenuEntryProviderI;
23 import compbio.data.msa.MsaWS;
24 import compbio.metadata.Option;
25 import compbio.metadata.Preset;
26 import compbio.metadata.PresetManager;
27 import compbio.metadata.RunnerConfig;
28 import compbio.ws.client.Jws2Base;
29 import compbio.ws.client.Jws2Base.Services;
32 * discoverer for jws2 services. Follows the lightweight service discoverer
33 * pattern (archetyped by EnfinEnvision2OneWay)
38 public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
40 private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(
44 * change listeners are notified of "services" property changes
47 * to be added that consumes new services Hashtable object.
49 public void addPropertyChangeListener(
50 java.beans.PropertyChangeListener listener)
52 changeSupport.addPropertyChangeListener(listener);
61 public void removePropertyChangeListener(
62 java.beans.PropertyChangeListener listener)
64 changeSupport.removePropertyChangeListener(listener);
67 boolean running = false;
69 Thread oldthread = null;
74 if (running && oldthread != null && oldthread.isAlive())
79 oldthread = Thread.currentThread();
82 Class foo = getClass().getClassLoader().loadClass(
83 "compbio.ws.client.Jws2Base");
84 } catch (ClassNotFoundException e)
87 .println("Not enabling Jalview Webservices version 2: client jar is not available."
88 + "\nPlease check that your webstart JNLP file is up to date!");
94 services.removeAllElements();
96 for (String jwsservers : getServiceUrls())
100 if (Jws2Base.validURL(jwsservers))
103 for (Services srv : Jws2Base.Services.values())
105 MsaWS service = null;
108 service = Jws2Base.connect(jwsservers, srv);
109 } catch (Exception e)
111 System.err.println("Jws2 Discoverer: Problem on "
112 + jwsservers + " with service " + srv + ":\n"
114 if (!(e instanceof javax.xml.ws.WebServiceException))
122 addService(jwsservers, srv, service);
129 Cache.log.info("Ignoring invalid Jws2 service url " + jwsservers);
131 } catch (Exception e)
134 Cache.log.warn("Exception when discovering Jws2 services.", e);
137 Cache.log.error("Exception when discovering Jws2 services.", e);
142 changeSupport.firePropertyChange("services", new Vector(), services);
146 * record this service endpoint so we can use it
152 private void addService(String jwsservers, Services srv, MsaWS service2)
154 if (services == null)
156 services = new Vector<Jws2Instance>();
158 System.out.println("Discovered service: " + jwsservers + " "
160 services.add(new Jws2Instance(jwsservers, srv.toString(), service2));
163 public class Jws2Instance
165 public String hosturl;
167 public String serviceType;
169 public MsaWS service;
171 public Jws2Instance(String hosturl, String serviceType, MsaWS service)
174 this.hosturl = hosturl;
175 this.serviceType = serviceType;
176 this.service = service;
179 PresetManager presets = null;
182 * non thread safe - gets the presets for this service (blocks whilst it
183 * calls the service to get the preset set)
185 * @return service presets or null if exceptions were raised.
187 public PresetManager getPresets()
193 presets = service.getPresets();
194 } catch (Exception ex)
197 .println("Exception when retrieving presets for service "
198 + serviceType + " at " + hosturl);
204 public String getHost()
209 URL serviceurl = new URL(hosturl);
210 if (serviceurl.getPort()!=80)
212 return serviceurl.getHost()+":"+serviceurl.getPort();
214 return serviceurl.getHost();
215 } catch (Exception e)
217 System.err.println("Failed to parse service URL '" + hosturl
218 + "' as a valid URL!");
223 * @return short description of what the service will do
225 public String getActionText() {
231 * non-thread safe - blocks whilst accessing service to get complete set of available options and parameters
234 public RunnerConfig getRunnerConfig()
236 return service.getRunnerOptions();
241 * holds list of services.
243 protected Vector<Jws2Instance> services;
246 * find or add a submenu with the given title in the given menu
249 * @return the new or existing submenu
251 private JMenu findOrCreateMenu(JMenu menu, String submenu)
253 JMenu submenuinstance = null;
254 for (int i=0,iSize=menu.getMenuComponentCount(); i<iSize; i++)
256 if (menu.getMenuComponent(i) instanceof JMenu &&
257 ((JMenu)menu.getMenuComponent(i)).getText().equals(submenu))
259 submenuinstance = (JMenu) menu.getMenuComponent(i);
262 if (submenuinstance==null)
264 submenuinstance = new JMenu(submenu);
265 menu.add(submenuinstance);
267 return submenuinstance;
271 public void attachWSMenuEntry(JMenu wsmenu, final AlignFrame alignFrame)
273 if (running || services == null || services.size() == 0)
277 boolean byhost = Cache.getDefault("WSMENU_BYHOST", true), bytype = Cache
278 .getDefault("WSMENU_BYTYPE", true);
280 * eventually, JWS2 services will appear under the same align/etc submenus.
281 * for moment we keep them separate.
283 JMenu atpoint, jws2al = new JMenu("JWS2 Alignment");
284 MsaWSClient msacl = new MsaWSClient();
285 for (final Jws2Instance service : services)
288 String host = service.getHost();
289 String type = service.serviceType;
292 atpoint = findOrCreateMenu(atpoint, host);
293 if (atpoint.getToolTipText()==null) {
294 atpoint.setToolTipText("Services at "+host);
299 atpoint = findOrCreateMenu(atpoint,type);
300 if (atpoint.getToolTipText()==null) {
301 atpoint.setToolTipText(service.getActionText());
304 msacl.attachWSMenuEntry(atpoint, service, alignFrame);
306 * JMenuItem sitem = new JMenuItem(service.serviceType);
307 * sitem.setToolTipText("Hosted at " + service.hosturl);
308 * sitem.addActionListener(new ActionListener() {
310 * @Override public void actionPerformed(ActionEvent e) { AlignmentView
311 * msa = alignFrame.gatherSequencesForAlignment(); MsaWSClient client =
312 * new MsaWSClient(service, "JWS2 Alignment of " + alignFrame.getTitle(),
313 * msa, false, true, alignFrame.getViewport().getAlignment().getDataset(),
317 if (services.size() > 0)
324 public static void main(String[] args)
326 Thread runner = new Thread(getDiscoverer());
327 getDiscoverer().addPropertyChangeListener(new PropertyChangeListener()
331 public void propertyChange(PropertyChangeEvent evt)
333 System.out.println("Changesupport: There are now "
334 + getDiscoverer().services.size() + " services");
338 while (runner.isAlive())
343 } catch (InterruptedException e)
350 private static Jws2Discoverer discoverer;
352 public static Jws2Discoverer getDiscoverer()
354 if (discoverer == null)
356 discoverer = new Jws2Discoverer();
361 public boolean hasServices()
363 // TODO Auto-generated method stub
364 return !running && services != null && services.size() > 0;
367 public boolean isRunning()
373 * the jalview .properties entry for JWS2 URLS
375 final static String JWS2HOSTURLS = "JWS2HOSTURLS";
377 public static void setServiceUrls(Vector<String> urls)
381 StringBuffer urlbuffer = new StringBuffer();
383 for (String url : urls)
385 urlbuffer.append(sep);
386 urlbuffer.append(url);
389 Cache.setProperty(JWS2HOSTURLS, urlbuffer.toString());
393 Cache.removeProperty(JWS2HOSTURLS);
397 public static Vector<String> getServiceUrls()
399 String surls = Cache.getDefault(JWS2HOSTURLS,
400 "http://webservices.compbio.dundee.ac.uk:8084/jws2");
401 Vector<String> urls = new Vector<String>();
404 StringTokenizer st = new StringTokenizer(surls, ",");
405 while (st.hasMoreElements())
410 java.net.URL u = new java.net.URL(url = st.nextToken());
411 if (!urls.contains(url))
417 jalview.bin.Cache.log.info("Ignoring duplicate url in "
418 + JWS2HOSTURLS + " list");
420 } catch (Exception ex)
422 jalview.bin.Cache.log
423 .warn("Problem whilst trying to make a URL from '"
424 + ((url != null) ? url : "<null>") + "'");
425 jalview.bin.Cache.log
426 .warn("This was probably due to a malformed comma separated list"
429 + " entry of $(HOME)/.jalview_properties)");
430 jalview.bin.Cache.log.debug("Exception was ", ex);
433 } catch (Exception ex)
435 jalview.bin.Cache.log.warn(
436 "Error parsing comma separated list of urls in "
437 + JWS2HOSTURLS + " preference.", ex);
439 if (urls.size() >= 0)
446 public Vector<Jws2Instance> getServices()
448 return (services==null) ? new Vector<Jws2Instance>(): new Vector<Jws2Instance>(services);