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