Jalview 2.6 source licence
[jalview.git] / src / jalview / ws / jws2 / MsaWSClient.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
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     {
117       if (preset instanceof JabaPreset)
118       {
119         this.preset = ((JabaPreset) preset).p;
120       }
121       else if (preset instanceof JabaWsParamSet)
122       {
123         List<Argument> newargs = new ArrayList<Argument>();
124         JabaWsParamSet pset = ((JabaWsParamSet) preset);
125         for (Option opt : pset.getjabaArguments())
126         {
127           newargs.add(opt);
128         }
129         if (arguments != null && arguments.size() > 0)
130         {
131           // merge arguments with preset's own arguments.
132           for (Argument opt : arguments)
133           {
134             newargs.add(opt);
135           }
136         }
137         paramset = newargs;
138       }
139       else
140       {
141         throw new Error(
142                 "Implementation error: Can only instantiate Jaba parameter sets.");
143       }
144     }
145     else
146     {
147       // just provided with a bunch of arguments
148       this.paramset = arguments;
149     }
150     if (editParams)
151     {
152       if (sh.paramStore == null)
153       {
154         sh.paramStore = new JabaParamStore(sh,
155                 Desktop.getUserParameterStore());
156       }
157       WsJobParameters jobParams = new WsJobParameters(sh, preset);
158       if (!jobParams.showRunDialog())
159       {
160         return;
161       }
162       WsParamSetI prset = jobParams.getPreset();
163       if (prset == null)
164       {
165         paramset = JabaParamStore.getJabafromJwsArgs(jobParams
166                 .getJobParams());
167       }
168       else
169       {
170         this.preset = ((JabaPreset) prset).p;
171         paramset = null; // no user supplied parameters.
172       }
173     }
174
175     if ((wsInfo = setWebService(sh, false)) == null)
176     {
177       JOptionPane.showMessageDialog(Desktop.desktop,
178               "The Multiple Sequence Alignment Service named "
179                       + sh.serviceType + " is unknown",
180               "Internal Jalview Error", JOptionPane.WARNING_MESSAGE);
181
182       return;
183     }
184     startMsaWSClient(altitle, msa, submitGaps, preserveOrder, seqdataset);
185
186   }
187
188   public MsaWSClient()
189   {
190     super();
191     // add a class reference to the list
192   }
193
194   private void startMsaWSClient(String altitle, AlignmentView msa,
195           boolean submitGaps, boolean preserveOrder, Alignment seqdataset)
196   {
197     // if (!locateWebService())
198     // {
199     // return;
200     // }
201
202     wsInfo.setProgressText(((submitGaps) ? "Re-alignment" : "Alignment")
203             + " of " + altitle + "\nJob details\n");
204     String jobtitle = WebServiceName.toLowerCase();
205     if (jobtitle.endsWith("alignment"))
206     {
207       if (submitGaps
208               && (!jobtitle.endsWith("realignment") || jobtitle
209                       .indexOf("profile") == -1))
210       {
211         int pos = jobtitle.indexOf("alignment");
212         jobtitle = WebServiceName.substring(0, pos) + "re-alignment of "
213                 + altitle;
214       }
215       else
216       {
217         jobtitle = WebServiceName + " of " + altitle;
218       }
219     }
220     else
221     {
222       jobtitle = WebServiceName + (submitGaps ? " re" : " ")
223               + "alignment of " + altitle;
224     }
225
226     MsaWSThread msathread = new MsaWSThread(server, preset, paramset,
227             WsURL, wsInfo, alignFrame, WebServiceName, jobtitle, msa,
228             submitGaps, preserveOrder, seqdataset);
229     wsInfo.setthisService(msathread);
230     msathread.start();
231   }
232
233   protected String getServiceActionKey()
234   {
235     return "MsaWS";
236   }
237
238   protected String getServiceActionDescription()
239   {
240     return "Multiple Sequence Alignment";
241   }
242
243   /**
244    * look at ourselves and work out if we are a service that can take a profile
245    * and align to it
246    * 
247    * @return true if we can send gapped sequences to the alignment service
248    */
249   private boolean canSubmitGaps()
250   {
251     // TODO: query service or extract service handle props to check if we can
252     // realign
253     return (WebServiceName.indexOf("lustal") > -1); // cheat!
254   }
255
256   public void attachWSMenuEntry(JMenu rmsawsmenu,
257           final Jws2Instance service, final AlignFrame alignFrame)
258   {
259     setWebService(service, true); // headless
260     boolean finished = true, submitGaps = false;
261     JMenu msawsmenu = rmsawsmenu;
262     String svcname = WebServiceName;
263     if (svcname.endsWith("WS"))
264     {
265       svcname = svcname.substring(0, svcname.length() - 2);
266     }
267     String calcName = svcname + " ";
268     if (canSubmitGaps())
269     {
270       msawsmenu = new JMenu(svcname);
271       rmsawsmenu.add(msawsmenu);
272       calcName = "";
273     }
274     boolean hasparams = service.hasParameters();
275     do
276     {
277       String action="Align ";
278       if (submitGaps == true)
279       {
280         action="Realign ";
281         msawsmenu = new JMenu("Realign with " + svcname);
282         msawsmenu.setToolTipText("Align sequences to an existing alignment");
283         rmsawsmenu.add(msawsmenu);
284       }
285       final boolean withGaps = submitGaps;
286
287       JMenuItem method = new JMenuItem(calcName + "Defaults");
288       method.setToolTipText(action+"with default settings");
289
290       method.addActionListener(new ActionListener()
291       {
292         public void actionPerformed(ActionEvent e)
293         {
294           AlignmentView msa = alignFrame.gatherSequencesForAlignment();
295           new MsaWSClient(service, alignFrame.getTitle(), msa, withGaps,
296                   true, alignFrame.getViewport().getAlignment()
297                           .getDataset(), alignFrame);
298
299         }
300       });
301       msawsmenu.add(method);
302       if (hasparams)
303       {
304         // only add these menu options if the service has user-modifiable arguments
305         method = new JMenuItem(calcName + "Edit and run ...");
306         method.setToolTipText("View and change the parameters before alignment.");
307
308         method.addActionListener(new ActionListener()
309         {
310           public void actionPerformed(ActionEvent e)
311           {
312             AlignmentView msa = alignFrame.gatherSequencesForAlignment();
313             new MsaWSClient(service, null, null, true, alignFrame
314                     .getTitle(), msa, withGaps, true, alignFrame
315                     .getViewport().getAlignment().getDataset(), alignFrame);
316
317           }
318         });
319         msawsmenu.add(method);
320         List<WsParamSetI> presets = service.getParamStore().getPresets();
321         if (presets != null && presets.size() > 0)
322         {
323           JMenu presetlist = new JMenu(calcName + "Presets");
324
325           for (final WsParamSetI preset : presets)
326           {
327             final JMenuItem methodR = new JMenuItem(preset.getName());
328             methodR.setToolTipText("<html><p>"
329                     + JvSwingUtils.wrapTooltip("<strong>"
330                             + (preset.isModifiable() ? "User Preset"
331                                     : "Service Preset") + "</strong><br/>"
332                             + preset.getDescription() + "</p>") + "</html>");
333             methodR.addActionListener(new ActionListener()
334             {
335               public void actionPerformed(ActionEvent e)
336               {
337                 AlignmentView msa = alignFrame
338                         .gatherSequencesForAlignment();
339                 new MsaWSClient(service, preset, alignFrame.getTitle(),
340                         msa, false, true, alignFrame.getViewport()
341                                 .getAlignment().getDataset(), alignFrame);
342
343               }
344
345             });
346             presetlist.add(methodR);
347           }
348           msawsmenu.add(presetlist);
349         }
350       }
351       if (!submitGaps && canSubmitGaps())
352       {
353         submitGaps = true;
354         finished = false;
355       }
356       else
357       {
358         finished = true;
359       }
360     } while (!finished);
361   }
362 }