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