Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.ws.rest

File RestClient.java

 

Coverage histogram

../../../img/srcFileCovDistChart6.png
35% of files have more coverage

Code metrics

34
99
23
1
476
326
44
0.44
4.3
23
1.91

Classes

Class Line # Actions
RestClient 51 99 44 75
0.519230851.9%
 

Contributing tests

This file is covered by 102 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.rest;
22   
23    import jalview.bin.Cache;
24    import jalview.datamodel.AlignmentView;
25    import jalview.gui.AlignFrame;
26    import jalview.gui.AlignViewport;
27    import jalview.gui.AlignmentPanel;
28    import jalview.gui.Desktop;
29    import jalview.gui.JvOptionPane;
30    import jalview.gui.WebserviceInfo;
31    import jalview.io.packed.DataProvider.JvDataType;
32    import jalview.util.MessageManager;
33    import jalview.ws.WSClient;
34    import jalview.ws.WSClientI;
35    import jalview.ws.WSMenuEntryProviderI;
36   
37    import java.awt.event.ActionEvent;
38    import java.awt.event.ActionListener;
39    import java.util.Hashtable;
40    import java.util.Vector;
41   
42    import javax.swing.JMenu;
43    import javax.swing.JMenuItem;
44    import javax.swing.event.MenuEvent;
45    import javax.swing.event.MenuListener;
46   
47    /**
48    * @author JimP
49    *
50    */
 
51    public class RestClient extends WSClient
52    implements WSClientI, WSMenuEntryProviderI
53    {
54    RestServiceDescription service;
55   
 
56  1107 toggle public RestClient(RestServiceDescription rsd)
57    {
58  1107 service = rsd;
59    }
60   
61    /**
62    * parent alignframe for this job
63    */
64    AlignFrame af;
65   
66    /**
67    * alignment view which provides data for job.
68    */
69    AlignViewport av;
70   
71    /**
72    * get the alignFrame for the associated input data if it exists.
73    *
74    * @return
75    */
 
76  0 toggle protected AlignFrame recoverAlignFrameForView()
77    {
78  0 return jalview.gui.Desktop.getAlignFrameFor(av);
79    }
80   
 
81  0 toggle public RestClient(RestServiceDescription service2, AlignFrame alignFrame)
82    {
83  0 this(service2, alignFrame, false);
84    }
85   
86    boolean headless = false;
87   
 
88  1 toggle public RestClient(RestServiceDescription service2, AlignFrame alignFrame,
89    boolean nogui)
90    {
91  1 service = service2;
92  1 af = alignFrame;
93  1 av = alignFrame.getViewport();
94  1 headless = nogui;
95  1 constructJob();
96    }
97   
 
98  1 toggle public void setWebserviceInfo(boolean headless)
99    {
100  1 WebServiceJobTitle = MessageManager
101    .formatMessage("label.webservice_job_title", new String[]
102    { service.details.Action, service.details.Name });
103  1 WebServiceName = service.details.Name;
104  1 WebServiceReference = "No reference - go to url for more info";
105  1 if (service.details.description != null)
106    {
107  1 WebServiceReference = service.details.description;
108    }
109  1 if (!headless)
110    {
111  0 wsInfo = new WebserviceInfo(WebServiceJobTitle,
112    WebServiceName + "\n" + WebServiceReference, true);
113  0 wsInfo.setRenderAsHtml(true);
114    }
115   
116    }
117   
 
118  0 toggle @Override
119    public boolean isCancellable()
120    {
121    // TODO define process for cancelling rsbws jobs
122  0 return false;
123    }
124   
 
125  0 toggle @Override
126    public boolean canMergeResults()
127    {
128    // TODO process service definition to identify if the results might be
129    // mergeable
130    // TODO: change comparison for annotation merge
131  0 return false;
132    }
133   
 
134  0 toggle @Override
135    public void cancelJob()
136    {
137  0 System.err.println("Cannot cancel this job type: " + service);
138    }
139   
 
140  1102 toggle @Override
141    public void attachWSMenuEntry(final JMenu wsmenu,
142    final AlignFrame alignFrame)
143    {
144  1102 JMenuItem submit = new JMenuItem(service.details.Name);
145  1102 submit.setToolTipText(MessageManager
146    .formatMessage("label.rest_client_submit", new String[]
147    { service.details.Action, service.details.Name }));
148  1102 submit.addActionListener(new ActionListener()
149    {
150   
 
151  0 toggle @Override
152    public void actionPerformed(ActionEvent e)
153    {
154  0 new RestClient(service, alignFrame);
155    }
156   
157    });
158  1102 wsmenu.add(submit);
159    // TODO: menu listener should enable/disable entry depending upon selection
160    // state of the alignment
161  1102 wsmenu.addMenuListener(new MenuListener()
162    {
163   
 
164  0 toggle @Override
165    public void menuSelected(MenuEvent e)
166    {
167    // TODO Auto-generated method stub
168   
169    }
170   
 
171  0 toggle @Override
172    public void menuDeselected(MenuEvent e)
173    {
174    // TODO Auto-generated method stub
175   
176    }
177   
 
178  0 toggle @Override
179    public void menuCanceled(MenuEvent e)
180    {
181    // TODO Auto-generated method stub
182   
183    }
184   
185    });
186   
187    }
188   
189    /**
190    * record of initial undoredo hash for the alignFrame providing data for this
191    * job.
192    */
193    long[] undoredo = null;
194   
195    /**
196    * Compare the original input data to the data currently presented to the
197    * user. // LOGIC: compare undo/redo - if same, merge regardless (coping with
198    * any changes in hidden columns as normal) // if different undo/redo then
199    * compare region that was submitted // if same, then merge as before, if
200    * different then prompt user to open a new window.
201    *
202    * @return
203    */
 
204  0 toggle protected boolean isAlignmentModified()
205    {
206  0 if (undoredo == null || av == null || av.getAlignment() == null)
207    {
208    // always return modified if we don't have access to live GUI elements
209    // anymore.
210  0 return true;
211    }
212  0 if (av.isUndoRedoHashModified(undoredo))
213    {
214    // alignment has been modified in some way.
215  0 return true;
216    }
217    // TODO: look deeper into modification of selection state, etc that may
218    // affect RestJobThread.realiseResults(boolean merge);
219  0 return false;
220   
221    }
222   
223    /**
224    * TODO: combine to form a dataset+alignment+annotation context
225    */
226    AlignmentView _input;
227   
228    /**
229    * input data context
230    */
231    jalview.io.packed.JalviewDataset jds;
232   
233    /**
234    * informative name for results
235    */
236    public String viewTitle;
237   
 
238  1 toggle protected void constructJob()
239    {
240  1 service.setInvolvesFlags();
241    // record all aspects of alignment view so we can merge back or recreate
242    // later
243  1 undoredo = av.getUndoRedoHash();
244    /**
245    * delete ? Vector sgs = av.getAlignment().getGroups(); if (sgs!=null) {
246    * _sgs = new SequenceGroup[sgs.size()]; sgs.copyInto(_sgs); } else { _sgs =
247    * new SequenceGroup[0]; }
248    */
249  1 boolean selExists = (av.getSelectionGroup() != null)
250    && (av.getSelectionGroup().getSize() > 1);
251    // TODO: JAL-715: refactor to alignViewport methods and revise to full
252    // focus+context+dataset input data staging model
253  1 if (selExists)
254    {
255  0 if (service.partitiondata)
256    {
257  0 if (av.getAlignment().getGroups() != null
258    && av.getAlignment().getGroups().size() > 0)
259    {
260    // intersect groups with selected region
261  0 _input = new AlignmentView(av.getAlignment(),
262    av.getAlignment().getHiddenColumns(),
263    av.getSelectionGroup(), av.hasHiddenColumns(), true,
264    true);
265  0 viewTitle = MessageManager.formatMessage(
266    "label.select_visible_region_of", new String[]
267  0 { (av.hasHiddenColumns()
268    ? MessageManager.getString("label.visible")
269    : ""),
270    af.getTitle() });
271    }
272    else
273    {
274    // use selected region to partition alignment
275  0 _input = new AlignmentView(av.getAlignment(),
276    av.getAlignment().getHiddenColumns(),
277    av.getSelectionGroup(), av.hasHiddenColumns(), false,
278    true);
279    }
280  0 viewTitle = MessageManager.formatMessage(
281    "label.select_unselect_visible_regions_from", new String[]
282  0 { (av.hasHiddenColumns()
283    ? MessageManager.getString("label.visible")
284    : ""),
285    af.getTitle() });
286    }
287    else
288    {
289    // just take selected region intersection
290  0 _input = new AlignmentView(av.getAlignment(),
291    av.getAlignment().getHiddenColumns(),
292    av.getSelectionGroup(), av.hasHiddenColumns(), true, true);
293  0 viewTitle = MessageManager.formatMessage(
294    "label.select_visible_region_of", new String[]
295  0 { (av.hasHiddenColumns()
296    ? MessageManager.getString("label.visible")
297    : ""),
298    af.getTitle() });
299    }
300    }
301    else
302    {
303    // standard alignment view without selection present
304  1 _input = new AlignmentView(av.getAlignment(),
305    av.getAlignment().getHiddenColumns(), null,
306    av.hasHiddenColumns(), false, true);
307  1 viewTitle = ""
308  1 + (av.hasHiddenColumns()
309    ? (new StringBuffer(" ")
310    .append(MessageManager
311    .getString("label.visible_region_of"))
312    .toString())
313    : "")
314    + af.getTitle();
315    }
316   
317  1 RestJobThread jobsthread = new RestJobThread(this);
318   
319  1 if (jobsthread.isValid())
320    {
321  1 setWebserviceInfo(headless);
322  1 if (!headless)
323    {
324  0 wsInfo.setthisService(this);
325  0 jobsthread.setWebServiceInfo(wsInfo);
326    }
327  1 jobsthread.start();
328    }
329    else
330    {
331    // TODO: try to tell the user why the job couldn't be started.
332  0 JvOptionPane.showMessageDialog(Desktop.desktop,
333  0 (jobsthread.hasWarnings() ? jobsthread.getWarnings()
334    : MessageManager.getString(
335    "label.job_couldnt_be_started_check_input")),
336    MessageManager
337    .getString("label.unable_start_web_service_analysis"),
338    JvOptionPane.WARNING_MESSAGE);
339    }
340    }
341   
 
342  3 toggle public static RestClient makeShmmrRestClient()
343    {
344  3 String action = "Analysis",
345    description = "Sequence Harmony and Multi-Relief (Brandt et al. 2010)",
346    name = MessageManager.getString("label.multiharmony");
347  3 Hashtable<String, InputType> iparams = new Hashtable<String, InputType>();
348  3 jalview.ws.rest.params.JobConstant toolp;
349    // toolp = new jalview.ws.rest.JobConstant("tool","jalview");
350    // iparams.put(toolp.token, toolp);
351    // toolp = new jalview.ws.rest.params.JobConstant("mbjob[method]","shmr");
352    // iparams.put(toolp.token, toolp);
353    // toolp = new
354    // jalview.ws.rest.params.JobConstant("mbjob[description]","step 1");
355    // iparams.put(toolp.token, toolp);
356    // toolp = new jalview.ws.rest.params.JobConstant("start_search","1");
357    // iparams.put(toolp.token, toolp);
358    // toolp = new jalview.ws.rest.params.JobConstant("blast","0");
359    // iparams.put(toolp.token, toolp);
360   
361  3 jalview.ws.rest.params.Alignment aliinput = new jalview.ws.rest.params.Alignment();
362    // SHMR server has a 65K limit for content pasted into the 'ali' parameter,
363    // so we always upload our files.
364  3 aliinput.token = "ali_file";
365  3 aliinput.writeAsFile = true;
366  3 iparams.put(aliinput.token, aliinput);
367  3 jalview.ws.rest.params.SeqGroupIndexVector sgroups = new jalview.ws.rest.params.SeqGroupIndexVector();
368  3 sgroups.setMinsize(2);
369  3 sgroups.min = 2;// need at least two group defined to make a partition
370  3 iparams.put("groups", sgroups);
371  3 sgroups.token = "groups";
372  3 sgroups.sep = " ";
373  3 RestServiceDescription shmrService = new RestServiceDescription(action,
374    description, name,
375    "http://zeus.few.vu.nl/programs/shmrwww/index.php?tool=jalview", // ?tool=jalview&mbjob[method]=shmr&mbjob[description]=step1",
376    "?tool=jalview", iparams, true, false, '-');
377    // a priori knowledge of the data returned from the service
378  3 shmrService.addResultDatatype(JvDataType.ANNOTATION);
379  3 return new RestClient(shmrService);
380    }
381   
 
382  0 toggle public AlignmentPanel recoverAlignPanelForView()
383    {
384  0 AlignmentPanel[] aps = Desktop
385    .getAlignmentPanels(av.getSequenceSetId());
386  0 for (AlignmentPanel alp : aps)
387    {
388  0 if (alp.av == av)
389    {
390  0 return alp;
391    }
392    }
393  0 return null;
394    }
395   
 
396  0 toggle public boolean isShowResultsInNewView()
397    {
398    // TODO make this a property of the service
399  0 return true;
400    }
401   
402    protected static Vector<String> services = null;
403   
404    public static final String RSBS_SERVICES = "RSBS_SERVICES";
405   
 
406  1104 toggle public static RestClient[] getRestClients()
407    {
408  1104 if (services == null)
409    {
410  1 services = new Vector<String>();
411  1 try
412    {
413  1 for (RestServiceDescription descr : RestServiceDescription
414    .parseDescriptions(
415    jalview.bin.Cache.getDefault(RSBS_SERVICES,
416    makeShmmrRestClient().service.toString())))
417    {
418  1 services.add(descr.toString());
419    }
420    } catch (Exception ex)
421    {
422  0 System.err.println(
423    "Serious - RSBS descriptions in user preferences are corrupt!");
424  0 ex.printStackTrace();
425    }
426   
427    }
428  1104 RestClient[] lst = new RestClient[services.size()];
429  1104 int i = 0;
430  1104 for (String svc : services)
431    {
432  1104 lst[i++] = new RestClient(new RestServiceDescription(svc));
433    }
434  1104 return lst;
435    }
436   
 
437  1102 toggle public String getAction()
438    {
439  1102 return service.details.Action;
440    }
441   
 
442  2 toggle public RestServiceDescription getRestDescription()
443    {
444  2 return service;
445    }
446   
 
447  0 toggle public static Vector<String> getRsbsDescriptions()
448    {
449  0 Vector<String> rsbsDescrs = new Vector<String>();
450  0 for (RestClient rsbs : getRestClients())
451    {
452  0 rsbsDescrs.add(rsbs.getRestDescription().toString());
453    }
454  0 return rsbsDescrs;
455    }
456   
 
457  1 toggle public static void setRsbsServices(Vector<String> rsbsUrls)
458    {
459  1 if (rsbsUrls != null)
460    {
461    // TODO: consider validating services ?
462  1 services = new Vector<String>(rsbsUrls);
463  1 StringBuffer sprop = new StringBuffer();
464  1 for (String s : services)
465    {
466  1 sprop.append(s);
467    }
468  1 Cache.setProperty(RSBS_SERVICES, sprop.toString());
469    }
470    else
471    {
472  0 Cache.removeProperty(RSBS_SERVICES);
473    }
474    }
475   
476    }