abstracted GUI to use jalview.ws.params objects (JAL-591, JAL-633). User defined...
[jalview.git] / src / jalview / ws / jws2 / MsaWSClient.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
3  * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
10  * 
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package jalview.ws.jws2;
19
20 import java.awt.event.ActionEvent;
21 import java.awt.event.ActionListener;
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import javax.swing.*;
26
27 import jalview.datamodel.*;
28 import jalview.gui.*;
29 import compbio.data.msa.MsaWS;
30 import compbio.metadata.Argument;
31 import compbio.metadata.Option;
32 import compbio.metadata.Preset;
33 import compbio.metadata.PresetManager;
34 import jalview.ws.jws2.Jws2Discoverer.Jws2Instance;
35 import jalview.ws.jws2.dm.JabaWsParamSet;
36 import jalview.ws.params.WsParamSetI;
37
38 /**
39  * DOCUMENT ME!
40  * 
41  * @author $author$
42  * @version $Revision$
43  */
44 public class MsaWSClient extends Jws2Client
45 {
46   /**
47    * server is a WSDL2Java generated stub for an archetypal MsaWSI service.
48    */
49   MsaWS server;
50
51   AlignFrame alignFrame;
52
53   private Preset preset;
54
55   private List<Argument> paramset;
56
57   public MsaWSClient(Jws2Discoverer.Jws2Instance sh, String altitle,
58           jalview.datamodel.AlignmentView msa, boolean submitGaps,
59           boolean preserveOrder, Alignment seqdataset,
60           AlignFrame _alignFrame)
61   {
62     this(sh, null, null, false, altitle, msa, submitGaps, preserveOrder,
63             seqdataset, _alignFrame);
64     // TODO Auto-generated constructor stub
65   }
66
67   public MsaWSClient(Jws2Discoverer.Jws2Instance sh, WsParamSetI preset,
68           String altitle, jalview.datamodel.AlignmentView msa,
69           boolean submitGaps, boolean preserveOrder, Alignment seqdataset,
70           AlignFrame _alignFrame)
71   {
72     this(sh, preset, null, false, altitle, msa, submitGaps, preserveOrder,
73             seqdataset, _alignFrame);
74     // TODO Auto-generated constructor stub
75   }
76
77   /**
78    * Creates a new MsaWSClient object that uses a service given by an externally
79    * retrieved ServiceHandle
80    * 
81    * @param sh
82    *          service handle of type AbstractName(MsaWS)
83    * @param altitle
84    *          DOCUMENT ME!
85    * @param msa
86    *          DOCUMENT ME!
87    * @param submitGaps
88    *          DOCUMENT ME!
89    * @param preserveOrder
90    *          DOCUMENT ME!
91    */
92
93   public MsaWSClient(Jws2Discoverer.Jws2Instance sh, WsParamSetI preset,
94           List<Argument> arguments, boolean editParams, String altitle,
95           jalview.datamodel.AlignmentView msa, boolean submitGaps,
96           boolean preserveOrder, Alignment seqdataset,
97           AlignFrame _alignFrame)
98   {
99     super();
100     alignFrame = _alignFrame;
101     if (!(sh.service instanceof MsaWS))
102     {
103       // redundant at mo - but may change
104       JOptionPane
105               .showMessageDialog(
106                       Desktop.desktop,
107                       "The Service called \n"
108                               + sh.serviceType
109                               + "\nis not a \nMultiple Sequence Alignment Service !",
110                       "Internal Jalview Error", JOptionPane.WARNING_MESSAGE);
111
112       return;
113     }
114     server = sh.service;
115     if (preset!=null) {
116       if (preset instanceof JabaPreset){
117         this.preset = ((JabaPreset)preset).p;
118       }  else
119         if (preset instanceof JabaWsParamSet) {
120           JabaWsParamSet pset = ((JabaWsParamSet)preset);
121           if (arguments!=null && arguments.size()>0)
122           {
123             // merge arguments with preset's own arguments.
124             List<Argument> oldargs = arguments;
125             arguments = new ArrayList<Argument>();
126             for (Option opt : pset.getjabaArguments()) {
127               arguments.add(opt);
128             }
129             for (Argument opt: oldargs)
130             {
131               arguments.add(opt);
132             }
133           }
134         
135       }else{
136         throw new Error("Implementation error: Can only instantiate Jaba parameter sets.");
137       }
138     }
139     this.paramset = arguments;
140     if (editParams)
141     {
142       if (sh.paramStore==null)
143       {
144         sh.paramStore = new JabaParamStore(sh);
145       }
146       WsJobParameters jobParams = new WsJobParameters(sh, preset);
147       if (!jobParams.showRunDialog())
148       {
149         return;
150       }
151       WsParamSetI prset = jobParams.getPreset();
152       if (prset==null)
153       {
154         paramset = JabaParamStore.getJabafromJwsArgs(jobParams.getJobParams());
155       } else {
156         this.preset = ((JabaPreset)prset).p;
157         paramset = null; // no user supplied parameters.
158       }
159     }
160
161     if ((wsInfo = setWebService(sh, false)) == null)
162     {
163       JOptionPane.showMessageDialog(Desktop.desktop,
164               "The Multiple Sequence Alignment Service named "
165                       + sh.serviceType + " is unknown",
166               "Internal Jalview Error", JOptionPane.WARNING_MESSAGE);
167
168       return;
169     }
170     startMsaWSClient(altitle, msa, submitGaps, preserveOrder, seqdataset);
171
172   }
173
174   public MsaWSClient()
175   {
176     super();
177     // add a class reference to the list
178   }
179
180   private void startMsaWSClient(String altitle, AlignmentView msa,
181           boolean submitGaps, boolean preserveOrder, Alignment seqdataset)
182   {
183     // if (!locateWebService())
184     // {
185     // return;
186     // }
187
188     wsInfo.setProgressText(((submitGaps) ? "Re-alignment" : "Alignment")
189             + " of " + altitle + "\nJob details\n");
190     String jobtitle = WebServiceName.toLowerCase();
191     if (jobtitle.endsWith("alignment"))
192     {
193       if (submitGaps
194               && (!jobtitle.endsWith("realignment") || jobtitle
195                       .indexOf("profile") == -1))
196       {
197         int pos = jobtitle.indexOf("alignment");
198         jobtitle = WebServiceName.substring(0, pos) + "re-alignment of "
199                 + altitle;
200       }
201       else
202       {
203         jobtitle = WebServiceName + " of " + altitle;
204       }
205     }
206     else
207     {
208       jobtitle = WebServiceName + (submitGaps ? " re" : " ")
209               + "alignment of " + altitle;
210     }
211
212     MsaWSThread msathread = new MsaWSThread(server, preset, paramset,
213             WsURL, wsInfo, alignFrame, WebServiceName, jobtitle, msa,
214             submitGaps, preserveOrder, seqdataset);
215     wsInfo.setthisService(msathread);
216     msathread.start();
217   }
218
219   protected String getServiceActionKey()
220   {
221     return "MsaWS";
222   }
223
224   protected String getServiceActionDescription()
225   {
226     return "Multiple Sequence Alignment";
227   }
228
229   /**
230    * look at ourselves and work out if we are a service that can take a profile
231    * and align to it
232    * 
233    * @return true if we can send gapped sequences to the alignment service
234    */
235   private boolean canSubmitGaps()
236   {
237     // TODO: query service or extract service handle props to check if we can
238     // realign
239     return (WebServiceName.indexOf("lustal") > -1); // cheat!
240   }
241
242   public void attachWSMenuEntry(JMenu rmsawsmenu,
243           final Jws2Instance service, final AlignFrame alignFrame)
244   {
245     setWebService(service, true); // headless
246     boolean finished = true, submitGaps = false;
247     JMenu msawsmenu = rmsawsmenu;
248     String svcname = WebServiceName;
249     if (svcname.endsWith("WS"))
250     {
251       svcname = svcname.substring(0, svcname.length() - 2);
252     }
253     String calcName = svcname + " ";
254     if (canSubmitGaps())
255     {
256       msawsmenu = new JMenu(svcname);
257       rmsawsmenu.add(msawsmenu);
258       calcName = "";
259     }
260
261     do
262     {
263       if (submitGaps == true)
264       {
265         msawsmenu = new JMenu("profile " + svcname);
266         rmsawsmenu.add(msawsmenu);
267       }
268       final boolean withGaps = submitGaps;
269       JMenuItem method = new JMenuItem(calcName + "Defaults");
270       method.setToolTipText("Align with default settings");
271
272       method.addActionListener(new ActionListener()
273       {
274         public void actionPerformed(ActionEvent e)
275         {
276           AlignmentView msa = alignFrame.gatherSequencesForAlignment();
277           new MsaWSClient(service, alignFrame.getTitle(), msa, withGaps,
278                   true, alignFrame.getViewport().getAlignment()
279                           .getDataset(), alignFrame);
280
281         }
282       });
283       msawsmenu.add(method);
284       method = new JMenuItem(calcName + "Edit and run ...");
285       method.setToolTipText("View and change the parameters before alignment.");
286
287       method.addActionListener(new ActionListener()
288       {
289         public void actionPerformed(ActionEvent e)
290         {
291           AlignmentView msa = alignFrame.gatherSequencesForAlignment();
292           new MsaWSClient(service, null, null, true, alignFrame.getTitle(),
293                   msa, withGaps, true, alignFrame.getViewport()
294                           .getAlignment().getDataset(), alignFrame);
295
296         }
297       });
298       msawsmenu.add(method);
299       List<WsParamSetI> presets = service.getParamStore().getPresets();
300       if (presets != null && presets.size() > 0)
301       {
302         JMenu presetlist = new JMenu(calcName + "Presets");
303
304         for (final WsParamSetI preset : presets)
305         {
306           final JMenuItem methodR = new JMenuItem(preset.getName());
307           methodR.setToolTipText("<html><p><strong>"
308                   + (preset.isModifiable() ? "User Preset"
309                           : "Service Preset") + "</strong><br/>"
310                   + preset.getDescription() + "</p></html>");
311           methodR.addActionListener(new ActionListener()
312           {
313             public void actionPerformed(ActionEvent e)
314             {
315               AlignmentView msa = alignFrame.gatherSequencesForAlignment();
316               new MsaWSClient(service, preset, alignFrame.getTitle(), msa,
317                       false, true, alignFrame.getViewport().getAlignment()
318                               .getDataset(), alignFrame);
319
320             }
321
322           });
323           presetlist.add(methodR);
324         }
325         msawsmenu.add(presetlist);
326       }
327       if (!submitGaps && canSubmitGaps())
328       {
329         submitGaps = true;
330         finished = false;
331       }
332       else
333       {
334         finished = true;
335       }
336     } while (!finished);
337   }
338 }