bugfix - use currently held parameters
[jalview.git] / src / jalview / ws / jws2 / SequenceAnnotationWSClient.java
1 /**
2  * 
3  */
4 package jalview.ws.jws2;
5
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8 import java.util.List;
9
10 import javax.swing.JCheckBoxMenuItem;
11 import javax.swing.JMenu;
12 import javax.swing.JMenuItem;
13 import javax.swing.JOptionPane;
14 import javax.swing.event.AncestorEvent;
15 import javax.swing.event.AncestorListener;
16 import javax.swing.event.MenuEvent;
17 import javax.swing.event.MenuListener;
18
19 import compbio.metadata.Argument;
20
21 import jalview.api.AlignCalcWorkerI;
22 import jalview.datamodel.AlignmentView;
23 import jalview.gui.AlignFrame;
24 import jalview.gui.Desktop;
25 import jalview.gui.JalviewDialog;
26 import jalview.gui.JvSwingUtils;
27 import jalview.ws.jws2.dm.AAConsSettings;
28 import jalview.ws.jws2.jabaws2.Jws2Instance;
29 import jalview.ws.params.WsParamSetI;
30
31 /**
32  * @author jimp
33  * 
34  */
35 public class SequenceAnnotationWSClient extends Jws2Client
36 {
37
38   public static final String AAConsCalcId = "jabaws2.AACons";
39
40   /**
41    * initialise a client so its attachWSMenuEntry method can be called.
42    */
43   public SequenceAnnotationWSClient()
44   {
45     // TODO Auto-generated constructor stub
46   }
47
48   public SequenceAnnotationWSClient(final Jws2Instance sh,
49           AlignFrame alignFrame, WsParamSetI preset, boolean editParams)
50   {
51     super(alignFrame, preset, null);
52     initSequenceAnnotationWSClient(sh, alignFrame, preset, editParams);
53   }
54   
55   public void initSequenceAnnotationWSClient(final Jws2Instance sh,
56           AlignFrame alignFrame, WsParamSetI preset, boolean editParams)
57   {
58     if (alignFrame.getViewport().getAlignment().isNucleotide())
59     {
60       JOptionPane.showMessageDialog(Desktop.desktop, sh.serviceType
61               + " can only be used\nfor amino acid alignments.",
62               "Wrong type of sequences!", JOptionPane.WARNING_MESSAGE);
63       return;
64
65     }
66     if (sh.action.toLowerCase().contains("conservation"))
67     {
68       // Build an AACons style client - take alignment, return annotation for
69       // columns
70
71       List<AlignCalcWorkerI> clnts = alignFrame.getViewport()
72               .getCalcManager()
73               .getRegisteredWorkersOfClass(AAConsClient.class);
74       if (clnts == null || clnts.size() == 0)
75       {
76         if (!processParams(sh, editParams))
77         {
78           return;
79         }
80         AAConsClient worker;
81         alignFrame
82                 .getViewport()
83                 .getCalcManager()
84                 .registerWorker(
85                         worker = new AAConsClient(sh, alignFrame, this.preset,
86                                 paramset));
87         alignFrame.getViewport().getCalcManager().startWorker(worker);
88
89       }
90       else
91       {
92         AAConsClient worker = (AAConsClient) clnts.get(0);
93         if (editParams)
94         {
95           paramset = worker.getArguments();
96           preset = worker.getPreset();
97         }
98
99         if (!processParams(sh, editParams, true))
100         {
101           return;
102         }
103         // reinstate worker if it was blacklisted (might have happened due to
104         // invalid parameters)
105         alignFrame.getViewport().getCalcManager().workerMayRun(worker);
106         worker.updateParameters(this.preset, paramset);
107
108       }
109     }
110     if (sh.action.toLowerCase().contains("disorder"))
111     {
112       // build IUPred style client. take sequences, returns annotation per
113       // sequence.
114       if (!processParams(sh, editParams))
115       {
116         return;
117       }
118
119       alignFrame
120               .getViewport()
121               .getCalcManager()
122               .startWorker(
123                       new AADisorderClient(sh, alignFrame, preset, paramset));
124     }
125
126   }
127
128   public SequenceAnnotationWSClient(AAConsSettings fave,
129           AlignFrame alignFrame, boolean b)
130   {
131     super(alignFrame, fave.getPreset(), fave.getJobArgset());
132     initSequenceAnnotationWSClient(fave.getService(), alignFrame, fave.getPreset(), b);
133   }
134
135   /*
136    * (non-Javadoc)
137    * 
138    * @see jalview.ws.jws2.Jws2Client#attachWSMenuEntry(javax.swing.JMenu,
139    * jalview.ws.jws2.jabaws2.Jws2Instance, jalview.gui.AlignFrame)
140    */
141   public void attachWSMenuEntry(JMenu wsmenu, final Jws2Instance service,
142           final AlignFrame alignFrame)
143   {
144     if (service.serviceType.equals(compbio.ws.client.Services.AAConWS
145             .toString()))
146     {
147       registerAAConsWSInstance(wsmenu, service, alignFrame);
148       return;
149     }
150     boolean hasparams = service.hasParameters();
151     // Assume name ends in WS
152     String calcName = service.serviceType.substring(0,
153             service.serviceType.length() - 2);
154
155     JMenuItem aacons = new JMenuItem(calcName + " Defaults");
156     aacons.addActionListener(new ActionListener()
157     {
158
159       @Override
160       public void actionPerformed(ActionEvent e)
161       {
162         new SequenceAnnotationWSClient(service, alignFrame, null, false);
163       }
164     });
165     wsmenu.add(aacons);
166     if (hasparams)
167     {
168       // only add these menu options if the service has user-modifiable
169       // arguments
170       aacons = new JMenuItem("Edit settings and run ...");
171       aacons.setToolTipText("View and change parameters before running calculation");
172
173       aacons.addActionListener(new ActionListener()
174       {
175         public void actionPerformed(ActionEvent e)
176         {
177           new SequenceAnnotationWSClient(service, alignFrame, null, true);
178         }
179       });
180       wsmenu.add(aacons);
181       List<WsParamSetI> presets = service.getParamStore().getPresets();
182       if (presets != null && presets.size() > 0)
183       {
184         JMenu presetlist = new JMenu("Run " + calcName + "with preset");
185
186         for (final WsParamSetI preset : presets)
187         {
188           final JMenuItem methodR = new JMenuItem(preset.getName());
189           methodR.setToolTipText("<html><p>"
190                   + JvSwingUtils.wrapTooltip("<strong>"
191                           + (preset.isModifiable() ? "User Preset"
192                                   : "Service Preset") + "</strong><br/>"
193                           + preset.getDescription() + "</p>") + "</html>");
194           methodR.addActionListener(new ActionListener()
195           {
196             public void actionPerformed(ActionEvent e)
197             {
198               new SequenceAnnotationWSClient(service, alignFrame, preset,
199                       false);
200             }
201
202           });
203           presetlist.add(methodR);
204         }
205         wsmenu.add(presetlist);
206       }
207
208     }
209   }
210
211   private final String AAconsToggle = "AACons Calculations",
212           AAconsToggleTooltip = "When checked, AACons calculations are updated automatically.",
213           AAeditSettings = "Change AACons Settings...",
214           AAeditSettingsTooltip = "Modify settings for AACons calculations.";
215
216   private SequenceAnnotationWSClient preferredAAConsClient = null;
217
218   // private final enableAAConsCalculation(final AlignFrame alignFrame, )
219   private void registerAAConsWSInstance(final JMenu wsmenu,
220           final Jws2Instance service, final AlignFrame alignFrame)
221   {
222     // register this in the AACons settings set
223     JCheckBoxMenuItem _aaConsEnabled = null;
224     for (int i = 0; i < wsmenu.getItemCount(); i++)
225     {
226       JMenuItem item = wsmenu.getItem(i);
227       if (item instanceof JCheckBoxMenuItem
228               && item.getText().equals(AAconsToggle))
229       {
230         _aaConsEnabled = (JCheckBoxMenuItem) item;
231       }
232     }
233
234     // is there a service already registered ?
235     if (_aaConsEnabled == null)
236     {
237       final JCheckBoxMenuItem aaConsEnabled = new JCheckBoxMenuItem(
238               AAconsToggle);
239       wsmenu.addMenuListener(new MenuListener()
240       {
241
242         @Override
243         public void menuSelected(MenuEvent arg0)
244         {
245           wsmenu.setEnabled(!alignFrame.getViewport().getAlignment()
246                   .isNucleotide());
247           List<AlignCalcWorkerI> aaconsClient = alignFrame.getViewport()
248                   .getCalcManager()
249                   .getRegisteredWorkersOfClass(AAConsClient.class);
250           if (aaconsClient != null && aaconsClient.size() > 0)
251           {
252             aaConsEnabled.setSelected(true);
253           }
254           else
255           {
256             aaConsEnabled.setSelected(false);
257           }
258         }
259
260         @Override
261         public void menuDeselected(MenuEvent arg0)
262         {
263           // TODO Auto-generated method stub
264
265         }
266
267         @Override
268         public void menuCanceled(MenuEvent arg0)
269         {
270           // TODO Auto-generated method stub
271
272         }
273       });
274       aaConsEnabled.setToolTipText("<html><p>"
275               + JvSwingUtils.wrapTooltip(AAconsToggleTooltip + "</p>")
276               + "</html>");
277       aaConsEnabled.addActionListener(new ActionListener()
278       {
279         @Override
280         public void actionPerformed(ActionEvent arg0)
281         {
282           // aaConsEnabled.setSelected(!aaConsEnabled.isSelected());
283           List<AlignCalcWorkerI> aaconsClient = alignFrame.getViewport()
284                   .getCalcManager()
285                   .getRegisteredWorkersOfClass(AAConsClient.class);
286           if (aaconsClient != null && aaconsClient.size() > 0)
287           {
288             removeCurrentAAConsWorkerFor(alignFrame);
289           }
290           else
291           {
292             buildCurrentAAConsWorkerFor(alignFrame);
293
294           }
295         }
296
297       });
298       wsmenu.add(aaConsEnabled);
299       JMenuItem modifyParams = new JMenuItem(AAeditSettings);
300       modifyParams.setToolTipText("<html><p>"
301               + JvSwingUtils.wrapTooltip(AAeditSettingsTooltip + "</p>")
302               + "</html>");
303       modifyParams.addActionListener(new ActionListener()
304       {
305
306         @Override
307         public void actionPerformed(ActionEvent arg0)
308         {
309           showAAConsAnnotationSettingsFor(alignFrame);
310         }
311       });
312       wsmenu.add(modifyParams);
313
314     }
315
316   }
317
318   private static void showAAConsAnnotationSettingsFor(AlignFrame alignFrame)
319   {
320     /*
321      * preferred settings
322      * Whether AACons is automatically recalculated
323      * Which AACons server to use
324      * What parameters to use
325      */
326     // could actually do a class search for this too
327     AAConsSettings fave= (AAConsSettings) alignFrame.getViewport().getCalcIdSettingsFor(AAConsCalcId);
328     if (fave==null)
329     {
330       fave = createDefaultAAConsSettings();
331     }
332     new SequenceAnnotationWSClient(fave, alignFrame, true);
333
334   }
335   private static void buildCurrentAAConsWorkerFor(AlignFrame alignFrame)
336   {
337     /*
338      * preferred settings
339      * Whether AACons is automatically recalculated
340      * Which AACons server to use
341      * What parameters to use
342      */
343     AAConsSettings fave= (AAConsSettings) alignFrame.getViewport().getCalcIdSettingsFor(AAConsCalcId);
344     if (fave==null)
345     {
346       fave = createDefaultAAConsSettings();
347     }
348     new SequenceAnnotationWSClient(fave, alignFrame, false);
349   }
350
351   private static AAConsSettings createDefaultAAConsSettings()
352   {
353     Jws2Instance service=null;
354     // set sensible defaults
355     for (Jws2Instance sv: Jws2Discoverer.getDiscoverer().getServices()) {
356       if (sv.serviceType.toString().equals(compbio.ws.client.Services.AAConWS.toString()))
357       {
358         service = sv;
359         break;
360       }
361     }
362     if (service==null)
363     {
364       // TODO raise dialog box explaining error, and/or open the JABA preferences menu.
365       throw new Error("No AACons service found.");
366     }
367     return new AAConsSettings(true, service, null, null);
368   }
369
370   private static void removeCurrentAAConsWorkerFor(AlignFrame alignFrame)
371   {
372     alignFrame.getViewport().getCalcManager()
373             .removeRegisteredWorkersOfClass(AAConsClient.class);
374     // AAConsClient.removeAAConsAnnotation(alignFrame.alignPanel);
375
376   }
377 }