JAL-1807 explicit imports (jalview.ws.*)
[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.WSClient;
32 import jalview.ws.jws2.dm.AAConSettings;
33 import jalview.ws.jws2.dm.JabaWsParamSet;
34 import jalview.ws.jws2.jabaws2.Jws2Instance;
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 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) || preset instanceof JabaWsParamSet))
72       {
73         /*
74          * { this.preset = ((JabaPreset) preset).p; } else if (preset instanceof
75          * JabaWsParamSet) { List<Argument> newargs = new ArrayList<Argument>();
76          * JabaWsParamSet pset = ((JabaWsParamSet) preset); for (Option opt :
77          * pset.getjabaArguments()) { newargs.add(opt); } if (arguments != null
78          * && arguments.size() > 0) { // merge arguments with preset's own
79          * arguments. for (Argument opt : arguments) { newargs.add(opt); } }
80          * paramset = newargs; } else {
81          */
82         throw new Error(MessageManager.getString("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 && paramset
109               .size() > 0) ? new WsJobParameters(null, sh, null, paramset)
110               : new WsJobParameters(sh, preset);
111       if (adjustingExisting)
112       {
113         jobParams.setName(MessageManager
114                 .getString("label.adjusting_parameters_for_calculation"));
115       }
116       if (!jobParams.showRunDialog())
117       {
118         return false;
119       }
120       WsParamSetI prset = jobParams.getPreset();
121       if (prset == null)
122       {
123         paramset = jobParams.isServiceDefaults() ? null : JabaParamStore
124                 .getJabafromJwsArgs(jobParams.getJobParams());
125         this.preset = null;
126       }
127       else
128       {
129         this.preset = prset; // ((JabaPreset) prset).p;
130         paramset = null; // no user supplied parameters.
131       }
132     }
133     return true;
134
135   }
136
137   public Jws2Client()
138   {
139     // anonymous constructor - used for headless method calls only
140   }
141
142   protected WebserviceInfo setWebService(Jws2Instance serv, boolean b)
143   {
144     // serviceHandle = serv;
145     String serviceInstance = serv.action; // serv.service.getClass().getName();
146     WebServiceName = serv.serviceType;
147     WebServiceJobTitle = serv.getActionText();
148     WsURL = serv.hosturl;
149     if (!b)
150     {
151       return new WebserviceInfo(WebServiceJobTitle, WebServiceJobTitle
152               + " using service hosted at " + serv.hosturl + "\n"
153               + (serv.description != null ? serv.description : ""), false);
154     }
155     return null;
156   }
157
158   /*
159    * Jws2Instance serviceHandle; (non-Javadoc)
160    * 
161    * @see jalview.ws.WSMenuEntryProviderI#attachWSMenuEntry(javax.swing.JMenu,
162    * jalview.gui.AlignFrame)
163    * 
164    * @Override public void attachWSMenuEntry(JMenu wsmenu, AlignFrame
165    * alignFrame) { if (serviceHandle==null) { throw new
166    * Error("Implementation error: No service handle for this Jws2 service."); }
167    * attachWSMenuEntry(wsmenu, serviceHandle, alignFrame); }
168    */
169   /**
170    * add the menu item for a particular jws2 service instance
171    * 
172    * @param wsmenu
173    * @param service
174    * @param alignFrame
175    */
176   abstract void attachWSMenuEntry(JMenu wsmenu, final Jws2Instance service,
177           final AlignFrame alignFrame);
178   
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, aaui.getAAconToggleTooltip()));
236       aaConEnabled.addActionListener(new ActionListener()
237       {
238         @Override
239         public void actionPerformed(ActionEvent arg0)
240         {
241           List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
242                   .getCalcManager()
243                   .getRegisteredWorkersOfClass(aaui.getClient());
244           if (aaconClient != null && aaconClient.size() > 0)
245           {
246             removeCurrentAAConWorkerFor(aaui, alignFrame);
247           }
248           else
249           {
250             buildCurrentAAConWorkerFor(aaui, alignFrame);
251
252           }
253         }
254
255       });
256       wsmenu.add(aaConEnabled);
257       final JMenuItem modifyParams = new JMenuItem(aaui.getAAeditSettings());
258       modifyParams.setToolTipText("<html><p>"
259               + JvSwingUtils.wrapTooltip(false, aaui.getAAeditSettingsTooltip()
260                       + "</p>") + "</html>");
261       modifyParams.addActionListener(new ActionListener()
262       {
263
264         @Override
265         public void actionPerformed(ActionEvent arg0)
266         {
267           showAAConAnnotationSettingsFor(aaui, alignFrame);
268         }
269       });
270       wsmenu.add(modifyParams);
271       wsmenu.addMenuListener(new MenuListener()
272       {
273
274         @Override
275         public void menuSelected(MenuEvent arg0)
276         {
277           // TODO: refactor to the implementing class.
278           if (alignFrame.getViewport().getAlignment().isNucleotide() ? aaui
279                   .isNa() : aaui.isPr())
280           {
281             aaConEnabled.setEnabled(true);
282             modifyParams.setEnabled(true);
283           }
284           else
285           {
286             aaConEnabled.setEnabled(false);
287             modifyParams.setEnabled(false);
288           }
289           List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
290                   .getCalcManager()
291                   .getRegisteredWorkersOfClass(aaui.getClient());
292           if (aaconClient != null && aaconClient.size() > 0)
293           {
294             aaConEnabled.setSelected(true);
295           }
296           else
297           {
298             aaConEnabled.setSelected(false);
299           }
300         }
301
302         @Override
303         public void menuDeselected(MenuEvent arg0)
304         {
305           // TODO Auto-generated method stub
306
307         }
308
309         @Override
310         public void menuCanceled(MenuEvent arg0)
311         {
312           // TODO Auto-generated method stub
313
314         }
315       });
316
317     }
318     return true;
319   }
320
321   private static void showAAConAnnotationSettingsFor(
322           final AlignAnalysisUIText aaui, AlignFrame alignFrame)
323   {
324     /*
325      * preferred settings Whether AACon is automatically recalculated Which
326      * AACon server to use What parameters to use
327      */
328     // could actually do a class search for this too
329     AAConSettings fave = (AAConSettings) alignFrame.getViewport()
330             .getCalcIdSettingsFor(aaui.getCalcId());
331     if (fave == null)
332     {
333       fave = createDefaultAAConSettings(aaui);
334     }
335     new SequenceAnnotationWSClient(fave, alignFrame, true);
336
337   }
338
339   private static void buildCurrentAAConWorkerFor(
340           final AlignAnalysisUIText aaui, AlignFrame alignFrame)
341   {
342     buildCurrentAAConWorkerFor(aaui, alignFrame, null);
343   }
344
345   private static void buildCurrentAAConWorkerFor(
346           final AlignAnalysisUIText aaui, AlignFrame alignFrame,
347           Jws2Instance service)
348   {
349     /*
350      * preferred settings Whether AACon is automatically recalculated Which
351      * AACon server to use What parameters to use
352      */
353     AAConSettings fave = (AAConSettings) alignFrame.getViewport()
354             .getCalcIdSettingsFor(aaui.getCalcId());
355     if (fave == null)
356     {
357       fave = createDefaultAAConSettings(aaui, service);
358     }
359     else
360     {
361       if (service != null
362               && !fave.getService().hosturl.equals(service.hosturl))
363       {
364         Cache.log.debug("Changing AACon service to " + service.hosturl
365                 + " from " + fave.getService().hosturl);
366         fave.setService(service);
367       }
368     }
369     new SequenceAnnotationWSClient(fave, alignFrame, false);
370   }
371
372   private static AAConSettings createDefaultAAConSettings(
373           AlignAnalysisUIText aaui)
374   {
375     return createDefaultAAConSettings(aaui, null);
376   }
377
378   private static AAConSettings createDefaultAAConSettings(
379           AlignAnalysisUIText aaui, Jws2Instance service)
380   {
381     if (service != null)
382     {
383       if (!service.serviceType.toString().equals(
384               compbio.ws.client.Services.AAConWS.toString()))
385       {
386         Cache.log
387                 .warn("Ignoring invalid preferred service for AACon calculations (service type was "
388                         + service.serviceType + ")");
389         service = null;
390       }
391       else
392       {
393         // check service is actually in the list of currently avaialable
394         // services
395         if (!Jws2Discoverer.getDiscoverer().getServices().contains(service))
396         {
397           // it isn't ..
398           service = null;
399         }
400       }
401     }
402     if (service == null)
403     {
404       // get the default service for AACon
405       service = Jws2Discoverer.getDiscoverer().getPreferredServiceFor(null,
406               aaui.getServiceType());
407     }
408     if (service == null)
409     {
410       // TODO raise dialog box explaining error, and/or open the JABA
411       // preferences menu.
412       throw new Error(MessageManager.getString("error.no_aacon_service_found"));
413     }
414     return new AAConSettings(true, service, null, null);
415   }
416
417   private static void removeCurrentAAConWorkerFor(AlignAnalysisUIText aaui,
418           AlignFrame alignFrame)
419   {
420     alignFrame.getViewport().getCalcManager()
421             .removeRegisteredWorkersOfClass(aaui.getClient());
422   }
423
424 }