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