Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 BST
  2. Package jalview.ws.jws1

File Discoverer.java

 

Coverage histogram

../../../img/srcFileCovDistChart4.png
44% of files have more coverage

Code metrics

38
106
12
1
440
310
39
0.37
8.83
12
3.25

Classes

Class Line # Actions
Discoverer 37 106 39
0.384615438.5%
 

Contributing tests

This file is covered by 80 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.ws.jws1;
22   
23    import jalview.gui.JvOptionPane;
24    import jalview.util.MessageManager;
25   
26    import java.net.URL;
27    import java.util.Hashtable;
28    import java.util.StringTokenizer;
29    import java.util.Vector;
30   
31    import ext.vamsas.IRegistry;
32    import ext.vamsas.IRegistryServiceLocator;
33    import ext.vamsas.RegistryServiceSoapBindingStub;
34    import ext.vamsas.ServiceHandle;
35    import ext.vamsas.ServiceHandles;
36   
 
37    public class Discoverer implements Runnable
38    {
39    ext.vamsas.IRegistry registry; // the root registry service.
40   
41    private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(
42    this);
43   
44    /**
45    * change listeners are notified of "services" property changes
46    *
47    * @param listener
48    * to be added that consumes new services Hashtable object.
49    */
 
50  2 toggle public void addPropertyChangeListener(
51    java.beans.PropertyChangeListener listener)
52    {
53  2 changeSupport.addPropertyChangeListener(listener);
54    }
55   
56    /**
57    *
58    *
59    * @param listener
60    * to be removed
61    */
 
62  0 toggle public void removePropertyChangeListener(
63    java.beans.PropertyChangeListener listener)
64    {
65  0 changeSupport.removePropertyChangeListener(listener);
66    }
67   
68    /**
69    * Property change listener firing routine
70    *
71    * @param prop
72    * services
73    * @param oldvalue
74    * old services hash
75    * @param newvalue
76    * new services hash
77    */
 
78  0 toggle public void firePropertyChange(String prop, Object oldvalue,
79    Object newvalue)
80    {
81  0 changeSupport.firePropertyChange(prop, oldvalue, newvalue);
82    }
83   
84    /**
85    * Initializes the server field with a valid service implementation.
86    *
87    * @return true if service was located.
88    */
 
89  0 toggle private IRegistry locateWebService(java.net.URL WsURL)
90    {
91  0 IRegistryServiceLocator loc = new IRegistryServiceLocator(); // Default
92  0 IRegistry server = null;
93  0 try
94    {
95  0 server = loc.getRegistryService(WsURL);
96  0 ((RegistryServiceSoapBindingStub) server).setTimeout(60000); // One
97    // minute
98    // timeout
99    } catch (Exception ex)
100    {
101  0 jalview.bin.Cache.log.error(
102    "Serious! Service location failed\nfor URL :" + WsURL + "\n",
103    ex);
104   
105  0 return null;
106    }
107   
108  0 loc.getEngine().setOption("axis", "1");
109   
110  0 return server;
111    }
112   
113    static private java.net.URL RootServiceURL = null;
114   
115    static public Vector<URL> ServiceURLList = null;
116   
117    static private boolean reallyDiscoverServices = true;
118   
119    public static java.util.Hashtable<String, Vector<ServiceHandle>> services = null;
120    // stored by
121    // abstractServiceType
122    // string
123   
124    public static java.util.Vector<ServiceHandle> serviceList = null;
125   
 
126  0 toggle static private Vector<URL> getDiscoveryURLS()
127    {
128  0 Vector<URL> urls = new Vector<>();
129  0 String RootServiceURLs = jalview.bin.Cache.getDefault("DISCOVERY_URLS",
130    "http://www.compbio.dundee.ac.uk/JalviewWS/services/ServiceRegistry");
131   
132  0 try
133    {
134  0 StringTokenizer st = new StringTokenizer(RootServiceURLs, ",");
135  0 while (st.hasMoreElements())
136    {
137  0 String url = null;
138  0 try
139    {
140  0 java.net.URL u = new java.net.URL(url = st.nextToken());
141  0 if (!urls.contains(u))
142    {
143  0 urls.add(u);
144    }
145    else
146    {
147  0 jalview.bin.Cache.log
148    .info("Ignoring duplicate url in DISCOVERY_URLS list");
149    }
150    } catch (Exception ex)
151    {
152  0 jalview.bin.Cache.log
153    .warn("Problem whilst trying to make a URL from '"
154  0 + ((url != null) ? url : "<null>") + "'");
155  0 jalview.bin.Cache.log.warn(
156    "This was probably due to a malformed comma separated list"
157    + " in the DISCOVERY_URLS entry of $(HOME)/.jalview_properties)");
158  0 jalview.bin.Cache.log.debug("Exception was ", ex);
159    }
160    }
161    } catch (Exception ex)
162    {
163  0 jalview.bin.Cache.log.warn(
164    "Error parsing comma separated list of urls in DISCOVERY_URLS.",
165    ex);
166    }
167  0 if (urls.size() > 0)
168    {
169  0 return urls;
170    }
171  0 return null;
172    }
173   
174    /**
175    * fetch new services or reset to hardwired defaults depending on preferences.
176    */
 
177  18 toggle static public void doDiscovery()
178    {
179  18 jalview.bin.Cache.log
180    .debug("(Re)-Initialising the discovery URL list.");
181  18 try
182    {
183  18 reallyDiscoverServices = jalview.bin.Cache
184    .getDefault("DISCOVERY_START", false);
185  18 if (reallyDiscoverServices)
186    {
187  0 ServiceURLList = getDiscoveryURLS();
188    }
189    else
190    {
191  18 jalview.bin.Cache.log.debug("Setting default services");
192  18 services = new Hashtable<>();
193    // Muscle, Clustal and JPred.
194  18 ServiceHandle[] defServices = { new ServiceHandle("MsaWS",
195    "Edgar, Robert C. (2004), MUSCLE: multiple sequence alignment "
196    + "with high accuracy and high throughput, Nucleic Acids Research 32(5), 1792-97.",
197    "http://www.compbio.dundee.ac.uk/JalviewWS/services/MuscleWS",
198    MessageManager.getString(
199    "label.muscle_multiple_protein_sequence_alignment")),
200    new ServiceHandle("MsaWS",
201    "Katoh, K., K. Kuma, K., Toh, H., and Miyata, T. (2005) "
202    + "\"MAFFT version 5: improvement in accuracy of multiple sequence alignment.\""
203    + " Nucleic Acids Research, 33 511-518",
204    "http://www.compbio.dundee.ac.uk/JalviewWS/services/MafftWS",
205    MessageManager.getString(
206    "label.mafft_multiple_sequence_alignment")),
207    new ServiceHandle("MsaWS",
208    "Thompson, J.D., Higgins, D.G. and Gibson, T.J. (1994) CLUSTAL W: improving the sensitivity of progressive multiple"
209    + " sequence alignment through sequence weighting, position specific gap penalties and weight matrix choice."
210    + " Nucleic Acids Research, 22 4673-4680",
211    "http://www.compbio.dundee.ac.uk/JalviewWS/services/ClustalWS",
212    MessageManager.getString(
213    "label.clustalw_multiple_sequence_alignment")),
214    new ServiceHandle("SecStrPred",
215    "Drozdetskiy A, Cole C, Procter J & Barton GJ. (2015)\nJPred4: a protein secondary structure prediction server"
216    + "\nNucleic Acids Research, Web Server issue (first published 15th April 2015)"
217    + "\ndoi://10.1093/nar/gkv332",
218    "http://www.compbio.dundee.ac.uk/JalviewWS/services/jpred",
219    "JPred Secondary Structure Prediction") };
220  18 services = new Hashtable<>();
221  18 serviceList = new Vector<>();
222  18 buildServiceLists(defServices, serviceList, services);
223    }
224   
225    } catch (Exception e)
226    {
227  0 System.err.println(
228    "jalview.rootRegistry is not a proper url!\nWas set to "
229    + RootServiceURL + "\n" + e);
230    }
231   
232    }
233   
234    // TODO: JBPNote : make this discover more services based on list of
235    // discovery service urls, break cyclic references to the same url and
236    // duplicate service entries (same endpoint *and* same interface)
 
237  0 toggle private ServiceHandle[] getServices(java.net.URL location)
238    {
239  0 ServiceHandles shs = null;
240  0 try
241    {
242  0 jalview.bin.Cache.log.debug("Discovering services using " + location);
243  0 shs = locateWebService(location).getServices();
244    } catch (org.apache.axis.AxisFault f)
245    {
246    // JBPNote - should do this a better way!
247  0 if (f.getFaultReason().indexOf("(407)") > -1)
248    {
249  0 if (jalview.gui.Desktop.desktop != null)
250    {
251  0 JvOptionPane.showMessageDialog(jalview.gui.Desktop.desktop,
252    MessageManager.getString("label.set_proxy_settings"),
253    MessageManager
254    .getString("label.proxy_authorization_failed"),
255    JvOptionPane.WARNING_MESSAGE);
256    }
257    }
258    else
259    {
260  0 jalview.bin.Cache.log.warn("No Discovery service at " + location);
261  0 jalview.bin.Cache.log.debug("Axis Fault", f);
262    }
263    } catch (Exception e)
264    {
265  0 jalview.bin.Cache.log.warn("No Discovery service at " + location);
266  0 jalview.bin.Cache.log.debug("Discovery Service General Exception", e);
267    }
268  0 if ((shs != null) && shs.getServices().length > 0)
269    {
270  0 return shs.getServices();
271    }
272  0 return null;
273    }
274   
275    /**
276    * Adds a list of services to the service catalog and categorised catalog
277    * returns true if ServiceURLList was modified with a new DiscoveryService URL
278    *
279    * @param sh
280    * ServiceHandle[]
281    * @param cat
282    * Vector
283    * @param sscat
284    * Hashtable
285    * @return boolean
286    */
 
287  18 toggle static private boolean buildServiceLists(ServiceHandle[] sh,
288    Vector<ServiceHandle> cat,
289    Hashtable<String, Vector<ServiceHandle>> sscat)
290    {
291  18 boolean seenNewDiscovery = false;
292  90 for (int i = 0, j = sh.length; i < j; i++)
293    {
294  72 if (!cat.contains(sh[i]))
295    {
296  72 jalview.bin.Cache.log.debug("A " + sh[i].getAbstractName()
297    + " service called " + sh[i].getName() + " exists at "
298    + sh[i].getEndpointURL() + "\n");
299  72 if (!sscat.containsKey(sh[i].getAbstractName()))
300    {
301  36 sscat.put(sh[i].getAbstractName(), cat = new Vector<>());
302    }
303    else
304    {
305  36 cat = sscat.get(sh[i].getAbstractName());
306    }
307  72 cat.add(sh[i]);
308  72 if (sh[i].getAbstractName().equals("Registry"))
309    {
310  0 for (int s = 0, sUrls = ServiceURLList.size(); s < sUrls; s++)
311    {
312  0 java.net.URL disc_serv = null;
313  0 try
314    {
315  0 disc_serv = new java.net.URL(sh[i].getEndpointURL());
316  0 if (!ServiceURLList.contains(disc_serv))
317    {
318  0 jalview.bin.Cache.log.debug(
319    "Adding new discovery service at " + disc_serv);
320  0 ServiceURLList.add(disc_serv);
321  0 seenNewDiscovery = true;
322    }
323    } catch (Exception e)
324    {
325  0 jalview.bin.Cache.log
326    .debug("Ignoring bad discovery service URL "
327    + sh[i].getEndpointURL(), e);
328    }
329    }
330    }
331    }
332    }
333  18 return seenNewDiscovery;
334    }
335   
 
336  18 toggle public void discoverServices()
337    {
338  18 Hashtable<String, Vector<ServiceHandle>> sscat = new Hashtable<>();
339  18 Vector<ServiceHandle> cat = new Vector<>();
340  18 ServiceHandle sh[] = null;
341  18 int s_url = 0;
342  18 if (ServiceURLList == null)
343    {
344  18 jalview.bin.Cache.log
345    .debug("No service endpoints to use for service discovery.");
346  18 return;
347    }
348  0 while (s_url < ServiceURLList.size())
349    {
350  0 if ((sh = getServices(
351    ServiceURLList.get(s_url))) != null)
352    {
353   
354  0 buildServiceLists(sh, cat, sscat);
355    }
356    else
357    {
358  0 jalview.bin.Cache.log.warn("No services at "
359    + (ServiceURLList.get(s_url))
360    + " - check DISCOVERY_URLS property in .jalview_properties");
361    }
362  0 s_url++;
363    }
364    // TODO: decide on correct semantics for services list - PropertyChange
365    // provides a way of passing the new object around
366    // so no need to access original discovery thread.
367    // Curent decision is to change properties then notify listeners with old
368    // and new values.
369  0 Hashtable<String, Vector<ServiceHandle>> oldServices = services;
370    // Vector oldServicelist = serviceList;
371  0 services = sscat;
372  0 serviceList = cat;
373  0 changeSupport.firePropertyChange("services", oldServices, services);
374    }
375   
376    /**
377    * creates a new thread to call discoverServices()
378    */
 
379  18 toggle @Override
380    public void run()
381    {
382  18 final Discoverer discoverer = this;
383  18 Thread discoverThread = new Thread()
384    {
 
385  18 toggle @Override
386    public void run()
387    {
388  18 Discoverer.doDiscovery();
389  18 discoverer.discoverServices();
390    }
391    };
392  18 discoverThread.start();
393    }
394   
395    /**
396    * binding service abstract name to handler class
397    */
398    private static Hashtable<String, WS1Client> serviceClientBindings;
399   
 
400  1750 toggle public static WS1Client getServiceClient(ServiceHandle sh)
401    {
402  1750 if (serviceClientBindings == null)
403    {
404    // get a list from Config or create below
405  1 serviceClientBindings = new Hashtable<>();
406  1 serviceClientBindings.put("MsaWS", new MsaWSClient());
407  1 serviceClientBindings.put("SecStrPred", new JPredClient());
408  1 serviceClientBindings.put("SeqSearch", new SeqSearchWSClient());
409    }
410  1750 WS1Client instance = serviceClientBindings
411    .get(sh.getAbstractName());
412  1750 if (instance == null)
413    {
414  0 System.err.println(
415    "WARNING - POSSIBLE IMPLEMENTATION ERROR - cannot find WSClient implementation for "
416    + sh.getAbstractName());
417    }
418    else
419    {
420  1750 instance.serviceHandle = sh;
421    }
422  1750 return instance;
423    }
424    /**
425    * notes on discovery service 1. need to allow multiple discovery source urls.
426    * 2. user interface to add/control list of urls in preferences notes on
427    * wsclient discovery 1. need a classpath property with list of additional
428    * plugin directories 2. optional config to cite specific bindings between
429    * class name and Abstract service name. 3. precedence for automatic discovery
430    * by using getAbstractName for WSClient - user added plugins override default
431    * plugins ? notes on wsclient gui code for gui attachment now moved to
432    * wsclient implementation. Needs more abstraction but approach seems to work.
433    * is it possible to 'generalise' the data retrieval calls further ? current
434    * methods are very specific (gatherForMSA or gatherForSeqOrMsaSecStrPred),
435    * new methods for conservation (group or alignment), treecalc (aligned
436    * profile), seqannot (sequences selected from dataset, annotation back to
437    * dataset).
438    *
439    */
440    }