c0b701b33f729ceb3f292eaf887e397d839c350b
[jalview.git] / src / jalview / ws / jws2 / Jws2Client.java
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.jws2;
22
23 import jalview.api.AlignCalcWorkerI;
24 import jalview.bin.Cache;
25 import jalview.gui.AlignFrame;
26 import jalview.gui.Desktop;
27 import jalview.gui.JvSwingUtils;
28 import jalview.gui.WebserviceInfo;
29 import jalview.gui.WsJobParameters;
30 import jalview.util.MessageManager;
31 import jalview.ws.jws2.dm.AAConSettings;
32 import jalview.ws.jws2.dm.JabaWsParamSet;
33 import jalview.ws.jws2.jabaws2.Jws2Instance;
34 import jalview.ws.params.WsParamSetI;
35 import jalview.ws.uimodel.AlignAnalysisUIText;
36
37 import java.awt.event.ActionEvent;
38 import java.awt.event.ActionListener;
39 import java.util.List;
40
41 import javax.swing.JCheckBoxMenuItem;
42 import javax.swing.JMenu;
43 import javax.swing.JMenuItem;
44 import javax.swing.event.MenuEvent;
45 import javax.swing.event.MenuListener;
46
47 import compbio.metadata.Argument;
48
49 /**
50  * provides metadata for a jabaws2 service instance - resolves names, etc.
51  * 
52  * @author JimP
53  * 
54  */
55 public abstract class Jws2Client extends jalview.ws.WSClient
56 {
57   protected AlignFrame alignFrame;
58
59   protected WsParamSetI preset;
60
61   protected List<Argument> paramset;
62
63   public Jws2Client(AlignFrame _alignFrame, WsParamSetI preset,
64           List<Argument> arguments)
65   {
66     alignFrame = _alignFrame;
67     this.preset = preset;
68     if (preset != null)
69     {
70       if (!((preset instanceof JabaPreset) || preset instanceof JabaWsParamSet))
71       {
72         /*
73          * { this.preset = ((JabaPreset) preset).p; } else if (preset instanceof
74          * JabaWsParamSet) { List<Argument> newargs = new ArrayList<Argument>();
75          * JabaWsParamSet pset = ((JabaWsParamSet) preset); for (Option opt :
76          * pset.getjabaArguments()) { newargs.add(opt); } if (arguments != null
77          * && arguments.size() > 0) { // merge arguments with preset's own
78          * arguments. for (Argument opt : arguments) { newargs.add(opt); } }
79          * paramset = newargs; } else {
80          */
81         throw new Error(
82                 MessageManager
83                         .getString("error.implementation_error_can_only_instantiate_jaba_param_sets"));
84       }
85     }
86     else
87     {
88       // just provided with a bunch of arguments
89       this.paramset = arguments;
90     }
91   }
92
93   boolean processParams(Jws2Instance sh, boolean editParams)
94   {
95     return processParams(sh, editParams, false);
96   }
97
98   protected boolean processParams(Jws2Instance sh, boolean editParams,
99           boolean adjustingExisting)
100   {
101
102     if (editParams)
103     {
104       if (sh.paramStore == null)
105       {
106         sh.paramStore = new JabaParamStore(sh,
107                 Desktop.getUserParameterStore());
108       }
109       WsJobParameters jobParams = (preset == null && paramset != null && paramset
110               .size() > 0) ? new WsJobParameters(null, sh, null, paramset)
111               : new WsJobParameters(sh, preset);
112       if (adjustingExisting)
113       {
114         jobParams.setName(MessageManager
115                 .getString("label.adjusting_parameters_for_calculation"));
116       }
117       if (!jobParams.showRunDialog())
118       {
119         return false;
120       }
121       WsParamSetI prset = jobParams.getPreset();
122       if (prset == null)
123       {
124         paramset = jobParams.isServiceDefaults() ? null : JabaParamStore
125                 .getJabafromJwsArgs(jobParams.getJobParams());
126         this.preset = null;
127       }
128       else
129       {
130         this.preset = prset; // ((JabaPreset) prset).p;
131         paramset = null; // no user supplied parameters.
132       }
133     }
134     return true;
135
136   }
137
138   public Jws2Client()
139   {
140     // anonymous constructor - used for headless method calls only
141   }
142
143   protected WebserviceInfo setWebService(Jws2Instance serv, boolean b)
144   {
145     // serviceHandle = serv;
146     String serviceInstance = serv.action; // serv.service.getClass().getName();
147     WebServiceName = serv.serviceType;
148     WebServiceJobTitle = serv.getActionText();
149     WsURL = serv.hosturl;
150     if (!b)
151     {
152       return new WebserviceInfo(WebServiceJobTitle, WebServiceJobTitle
153               + " using service hosted at " + serv.hosturl + "\n"
154               + (serv.description != null ? serv.description : ""), false);
155     }
156     return null;
157   }
158
159   /*
160    * Jws2Instance serviceHandle; (non-Javadoc)
161    * 
162    * @see jalview.ws.WSMenuEntryProviderI#attachWSMenuEntry(javax.swing.JMenu,
163    * jalview.gui.AlignFrame)
164    * 
165    * @Override public void attachWSMenuEntry(JMenu wsmenu, AlignFrame
166    * alignFrame) { if (serviceHandle==null) { throw new
167    * Error("Implementation error: No service handle for this Jws2 service."); }
168    * attachWSMenuEntry(wsmenu, serviceHandle, alignFrame); }
169    */
170   /**
171    * add the menu item for a particular jws2 service instance
172    * 
173    * @param wsmenu
174    * @param service
175    * @param alignFrame
176    */
177   abstract void attachWSMenuEntry(JMenu wsmenu, final Jws2Instance service,
178           final AlignFrame alignFrame);
179
180   protected boolean registerAAConWSInstance(final JMenu wsmenu,
181           final Jws2Instance service, final AlignFrame alignFrame)
182   {
183     final AlignAnalysisUIText aaui = service.getAlignAnalysisUI(); // null ; //
184                                                                    // AlignAnalysisUIText.aaConGUI.get(service.serviceType.toString());
185     if (aaui == null)
186     {
187       // not an instantaneous calculation GUI type service
188       return false;
189     }
190     // create the instaneous calculation GUI bits and update state if existing
191     // GUI elements already present
192
193     JCheckBoxMenuItem _aaConEnabled = null;
194     for (int i = 0; i < wsmenu.getItemCount(); i++)
195     {
196       JMenuItem item = wsmenu.getItem(i);
197       if (item instanceof JCheckBoxMenuItem
198               && item.getText().equals(aaui.getAAconToggle()))
199       {
200         _aaConEnabled = (JCheckBoxMenuItem) item;
201       }
202     }
203     // is there an aaCon worker already present - if so, set it to use the
204     // given service handle
205     {
206       List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
207               .getCalcManager()
208               .getRegisteredWorkersOfClass(aaui.getClient());
209       if (aaconClient != null && aaconClient.size() > 0)
210       {
211         AbstractJabaCalcWorker worker = (AbstractJabaCalcWorker) aaconClient
212                 .get(0);
213         if (!worker.service.hosturl.equals(service.hosturl))
214         {
215           // javax.swing.SwingUtilities.invokeLater(new Runnable()
216           {
217             // @Override
218             // public void run()
219             {
220               removeCurrentAAConWorkerFor(aaui, alignFrame);
221               buildCurrentAAConWorkerFor(aaui, alignFrame, service);
222             }
223           }// );
224         }
225       }
226     }
227
228     // is there a service already registered ? there shouldn't be if we are
229     // being called correctly
230     if (_aaConEnabled == null)
231     {
232       final JCheckBoxMenuItem aaConEnabled = new JCheckBoxMenuItem(
233               aaui.getAAconToggle());
234
235       aaConEnabled.setToolTipText(JvSwingUtils.wrapTooltip(true,
236               aaui.getAAconToggleTooltip()));
237       aaConEnabled.addActionListener(new ActionListener()
238       {
239         @Override
240         public void actionPerformed(ActionEvent arg0)
241         {
242           List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
243                   .getCalcManager()
244                   .getRegisteredWorkersOfClass(aaui.getClient());
245           if (aaconClient != null && aaconClient.size() > 0)
246           {
247             removeCurrentAAConWorkerFor(aaui, alignFrame);
248           }
249           else
250           {
251             buildCurrentAAConWorkerFor(aaui, alignFrame);
252
253           }
254         }
255
256       });
257       wsmenu.add(aaConEnabled);
258       final JMenuItem modifyParams = new JMenuItem(aaui.getAAeditSettings());
259       modifyParams
260               .setToolTipText("<html><p>"
261                       + JvSwingUtils.wrapTooltip(false,
262                               aaui.getAAeditSettingsTooltip() + "</p>")
263                       + "</html>");
264       modifyParams.addActionListener(new ActionListener()
265       {
266
267         @Override
268         public void actionPerformed(ActionEvent arg0)
269         {
270           showAAConAnnotationSettingsFor(aaui, alignFrame);
271         }
272       });
273       wsmenu.add(modifyParams);
274       wsmenu.addMenuListener(new MenuListener()
275       {
276
277         @Override
278         public void menuSelected(MenuEvent arg0)
279         {
280           // TODO: refactor to the implementing class.
281           if (alignFrame.getViewport().getAlignment().isNucleotide() ? aaui
282                   .isNa() : aaui.isPr())
283           {
284             aaConEnabled.setEnabled(true);
285             modifyParams.setEnabled(true);
286           }
287           else
288           {
289             aaConEnabled.setEnabled(false);
290             modifyParams.setEnabled(false);
291           }
292           List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
293                   .getCalcManager()
294                   .getRegisteredWorkersOfClass(aaui.getClient());
295           if (aaconClient != null && aaconClient.size() > 0)
296           {
297             aaConEnabled.setSelected(true);
298           }
299           else
300           {
301             aaConEnabled.setSelected(false);
302           }
303         }
304
305         @Override
306         public void menuDeselected(MenuEvent arg0)
307         {
308           // TODO Auto-generated method stub
309
310         }
311
312         @Override
313         public void menuCanceled(MenuEvent arg0)
314         {
315           // TODO Auto-generated method stub
316
317         }
318       });
319
320     }
321     return true;
322   }
323
324   private static void showAAConAnnotationSettingsFor(
325           final AlignAnalysisUIText aaui, AlignFrame alignFrame)
326   {
327     /*
328      * preferred settings Whether AACon is automatically recalculated Which
329      * AACon server to use What parameters to use
330      */
331     // could actually do a class search for this too
332     AAConSettings fave = (AAConSettings) alignFrame.getViewport()
333             .getCalcIdSettingsFor(aaui.getCalcId());
334     if (fave == null)
335     {
336       fave = createDefaultAAConSettings(aaui);
337     }
338     new SequenceAnnotationWSClient(fave, alignFrame, true);
339
340   }
341
342   private static void buildCurrentAAConWorkerFor(
343           final AlignAnalysisUIText aaui, AlignFrame alignFrame)
344   {
345     buildCurrentAAConWorkerFor(aaui, alignFrame, null);
346   }
347
348   private static void buildCurrentAAConWorkerFor(
349           final AlignAnalysisUIText aaui, AlignFrame alignFrame,
350           Jws2Instance service)
351   {
352     /*
353      * preferred settings Whether AACon is automatically recalculated Which
354      * AACon server to use What parameters to use
355      */
356     AAConSettings fave = (AAConSettings) alignFrame.getViewport()
357             .getCalcIdSettingsFor(aaui.getCalcId());
358     if (fave == null)
359     {
360       fave = createDefaultAAConSettings(aaui, service);
361     }
362     else
363     {
364       if (service != null
365               && !fave.getService().hosturl.equals(service.hosturl))
366       {
367         Cache.log.debug("Changing AACon service to " + service.hosturl
368                 + " from " + fave.getService().hosturl);
369         fave.setService(service);
370       }
371     }
372     new SequenceAnnotationWSClient(fave, alignFrame, false);
373   }
374
375   private static AAConSettings createDefaultAAConSettings(
376           AlignAnalysisUIText aaui)
377   {
378     return createDefaultAAConSettings(aaui, null);
379   }
380
381   private static AAConSettings createDefaultAAConSettings(
382           AlignAnalysisUIText aaui, Jws2Instance service)
383   {
384     if (service != null)
385     {
386       if (!service.serviceType.toString().equals(
387               compbio.ws.client.Services.AAConWS.toString()))
388       {
389         Cache.log
390                 .warn("Ignoring invalid preferred service for AACon calculations (service type was "
391                         + service.serviceType + ")");
392         service = null;
393       }
394       else
395       {
396         // check service is actually in the list of currently avaialable
397         // services
398         if (!Jws2Discoverer.getDiscoverer().getServices().contains(service))
399         {
400           // it isn't ..
401           service = null;
402         }
403       }
404     }
405     if (service == null)
406     {
407       // get the default service for AACon
408       service = Jws2Discoverer.getDiscoverer().getPreferredServiceFor(null,
409               aaui.getServiceType());
410     }
411     if (service == null)
412     {
413       // TODO raise dialog box explaining error, and/or open the JABA
414       // preferences menu.
415       throw new Error(
416               MessageManager.getString("error.no_aacon_service_found"));
417     }
418     return new AAConSettings(true, service, null, null);
419   }
420
421   private static void removeCurrentAAConWorkerFor(AlignAnalysisUIText aaui,
422           AlignFrame alignFrame)
423   {
424     alignFrame.getViewport().getCalcManager()
425             .removeRegisteredWorkersOfClass(aaui.getClient());
426   }
427
428 }