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