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