JAL-3066 Working custom parameters for clustalo
[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.api.ServiceWithParameters;
29 import jalview.ws.jws2.dm.AAConSettings;
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,
106           final ServiceWithParameters service,
107           final AlignFrame alignFrame);
108
109   static boolean registerAAConWSInstance(final JMenu wsmenu,
110           final ServiceWithParameters service, final AlignFrame alignFrame)
111   {
112     Jws2Instance jaba_service = (Jws2Instance) service;
113     final AlignAnalysisUIText aaui = jaba_service.getAlignAnalysisUI(); // null ; //
114                                                                    // AlignAnalysisUIText.aaConGUI.get(service.serviceType.toString());
115     if (aaui == null)
116     {
117       // not an instantaneous calculation GUI type service
118       return false;
119     }
120     // create the instaneous calculation GUI bits and update state if existing
121     // GUI elements already present
122
123     JCheckBoxMenuItem _aaConEnabled = null;
124     for (int i = 0; i < wsmenu.getItemCount(); i++)
125     {
126       JMenuItem item = wsmenu.getItem(i);
127       if (item instanceof JCheckBoxMenuItem
128               && item.getText().equals(aaui.getAAconToggle()))
129       {
130         _aaConEnabled = (JCheckBoxMenuItem) item;
131       }
132     }
133     // is there an aaCon worker already present - if so, set it to use the
134     // given service handle
135     {
136       List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
137               .getCalcManager()
138               .getRegisteredWorkersOfClass(aaui.getClient());
139       if (aaconClient != null && aaconClient.size() > 0)
140       {
141         AbstractJabaCalcWorker worker = (AbstractJabaCalcWorker) aaconClient
142                 .get(0);
143         if (!worker.service.getHostURL().equals(service.getHostURL()))
144         {
145           // javax.swing.SwingUtilities.invokeLater(new Runnable()
146           {
147             // @Override
148             // public void run()
149             {
150               removeCurrentAAConWorkerFor(aaui, alignFrame);
151               buildCurrentAAConWorkerFor(aaui, alignFrame, jaba_service);
152             }
153           } // );
154         }
155       }
156     }
157
158     // is there a service already registered ? there shouldn't be if we are
159     // being called correctly
160     if (_aaConEnabled == null)
161     {
162       final JCheckBoxMenuItem aaConEnabled = new JCheckBoxMenuItem(
163               aaui.getAAconToggle());
164
165       aaConEnabled.setToolTipText(
166               JvSwingUtils.wrapTooltip(true, aaui.getAAconToggleTooltip()));
167       aaConEnabled.addActionListener(new ActionListener()
168       {
169         @Override
170         public void actionPerformed(ActionEvent arg0)
171         {
172           List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
173                   .getCalcManager()
174                   .getRegisteredWorkersOfClass(aaui.getClient());
175           if (aaconClient != null && aaconClient.size() > 0)
176           {
177             removeCurrentAAConWorkerFor(aaui, alignFrame);
178           }
179           else
180           {
181             buildCurrentAAConWorkerFor(aaui, alignFrame);
182
183           }
184         }
185
186       });
187       wsmenu.add(aaConEnabled);
188       final JMenuItem modifyParams = new JMenuItem(
189               aaui.getAAeditSettings());
190       modifyParams.setToolTipText(JvSwingUtils.wrapTooltip(true,
191               aaui.getAAeditSettingsTooltip()));
192       modifyParams.addActionListener(new ActionListener()
193       {
194
195         @Override
196         public void actionPerformed(ActionEvent arg0)
197         {
198           showAAConAnnotationSettingsFor(aaui, alignFrame);
199         }
200       });
201       wsmenu.add(modifyParams);
202       wsmenu.addMenuListener(new MenuListener()
203       {
204
205         @Override
206         public void menuSelected(MenuEvent arg0)
207         {
208           // TODO: refactor to the implementing class.
209           if (alignFrame.getViewport().getAlignment().isNucleotide()
210                   ? aaui.isNa()
211                   : aaui.isPr())
212           {
213             aaConEnabled.setEnabled(true);
214             modifyParams.setEnabled(true);
215           }
216           else
217           {
218             aaConEnabled.setEnabled(false);
219             modifyParams.setEnabled(false);
220           }
221           List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
222                   .getCalcManager()
223                   .getRegisteredWorkersOfClass(aaui.getClient());
224           if (aaconClient != null && aaconClient.size() > 0)
225           {
226             aaConEnabled.setSelected(true);
227           }
228           else
229           {
230             aaConEnabled.setSelected(false);
231           }
232         }
233
234         @Override
235         public void menuDeselected(MenuEvent arg0)
236         {
237           // TODO Auto-generated method stub
238
239         }
240
241         @Override
242         public void menuCanceled(MenuEvent arg0)
243         {
244           // TODO Auto-generated method stub
245
246         }
247       });
248
249     }
250     return true;
251   }
252
253   private static void showAAConAnnotationSettingsFor(
254           final AlignAnalysisUIText aaui, AlignFrame alignFrame)
255   {
256     /*
257      * preferred settings Whether AACon is automatically recalculated Which
258      * AACon server to use What parameters to use
259      */
260     // could actually do a class search for this too
261     AAConSettings fave = (AAConSettings) alignFrame.getViewport()
262             .getCalcIdSettingsFor(aaui.getCalcId());
263     if (fave == null)
264     {
265       fave = createDefaultAAConSettings(aaui);
266     }
267     new SequenceAnnotationWSClient(fave, alignFrame, true);
268
269   }
270
271   private static void buildCurrentAAConWorkerFor(
272           final AlignAnalysisUIText aaui, AlignFrame alignFrame)
273   {
274     buildCurrentAAConWorkerFor(aaui, alignFrame, null);
275   }
276
277   private static void buildCurrentAAConWorkerFor(
278           final AlignAnalysisUIText aaui, AlignFrame alignFrame,
279           Jws2Instance service)
280   {
281     /*
282      * preferred settings Whether AACon is automatically recalculated Which
283      * AACon server to use What parameters to use
284      */
285     AAConSettings fave = (AAConSettings) alignFrame.getViewport()
286             .getCalcIdSettingsFor(aaui.getCalcId());
287     if (fave == null)
288     {
289       fave = createDefaultAAConSettings(aaui, service);
290     }
291     else
292     {
293       if (service != null
294               && !fave.getService().getHostURL()
295                       .equals(service.getHostURL()))
296       {
297         Cache.log.debug("Changing AACon service to " + service.getHostURL()
298                 + " from " + fave.getService().getHostURL());
299         fave.setService(service);
300       }
301     }
302     new SequenceAnnotationWSClient(fave, alignFrame, false);
303   }
304
305   private static AAConSettings createDefaultAAConSettings(
306           AlignAnalysisUIText aaui)
307   {
308     return createDefaultAAConSettings(aaui, null);
309   }
310
311   private static AAConSettings createDefaultAAConSettings(
312           AlignAnalysisUIText aaui, Jws2Instance service)
313   {
314     if (service != null)
315     {
316       if (!service.getServiceType()
317               .equals(compbio.ws.client.Services.AAConWS.toString()))
318       {
319         Cache.log.warn(
320                 "Ignoring invalid preferred service for AACon calculations (service type was "
321                         + service.getServiceType() + ")");
322         service = null;
323       }
324       else
325       {
326         // check service is actually in the list of currently avaialable
327         // services
328         if (!Jws2Discoverer.getDiscoverer().getServices().contains(service))
329         {
330           // it isn't ..
331           service = null;
332         }
333       }
334     }
335     if (service == null)
336     {
337       // get the default service for AACon
338       service = Jws2Discoverer.getDiscoverer().getPreferredServiceFor(null,
339               aaui.getServiceType());
340     }
341     if (service == null)
342     {
343       // TODO raise dialog box explaining error, and/or open the JABA
344       // preferences menu.
345       throw new Error(
346               MessageManager.getString("error.no_aacon_service_found"));
347     }
348     return new AAConSettings(true, service, null, null);
349   }
350
351   private static void removeCurrentAAConWorkerFor(AlignAnalysisUIText aaui,
352           AlignFrame alignFrame)
353   {
354     alignFrame.getViewport().getCalcManager()
355             .removeRegisteredWorkersOfClass(aaui.getClient());
356   }
357
358 }