Clover icon

Coverage Report

  1. Project Clover database Mon Nov 18 2024 09:56:54 GMT
  2. Package jalview.ws.jws1

File Discoverer.java

 

Coverage histogram

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

Code metrics

38
106
12
1
433
303
39
0.37
8.83
12
3.25

Classes

Class Line # Actions
Discoverer 39 106 39
0.384615438.5%
 

Contributing tests

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