(JAL-976) refactored common code for JABAWS v2 service clients
[jalview.git] / src / jalview / ws / jws2 / MsaWSClient.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3  * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, 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.dm.JabaWsParamSet;
35 import jalview.ws.jws2.jabaws2.Jws2Instance;
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   public MsaWSClient(Jws2Instance sh, String altitle,
52           jalview.datamodel.AlignmentView msa, boolean submitGaps,
53           boolean preserveOrder, Alignment seqdataset,
54           AlignFrame _alignFrame)
55   {
56     this(sh, null, null, false, altitle, msa, submitGaps, preserveOrder,
57             seqdataset, _alignFrame);
58     // TODO Auto-generated constructor stub
59   }
60
61   public MsaWSClient(Jws2Instance sh, WsParamSetI preset,
62           String altitle, jalview.datamodel.AlignmentView msa,
63           boolean submitGaps, boolean preserveOrder, Alignment seqdataset,
64           AlignFrame _alignFrame)
65   {
66     this(sh, preset, null, false, altitle, msa, submitGaps, preserveOrder,
67             seqdataset, _alignFrame);
68     // TODO Auto-generated constructor stub
69   }
70
71   /**
72    * Creates a new MsaWSClient object that uses a service given by an externally
73    * retrieved ServiceHandle
74    * 
75    * @param sh
76    *          service handle of type AbstractName(MsaWS)
77    * @param altitle
78    *          DOCUMENT ME!
79    * @param msa
80    *          DOCUMENT ME!
81    * @param submitGaps
82    *          DOCUMENT ME!
83    * @param preserveOrder
84    *          DOCUMENT ME!
85    */
86
87   public MsaWSClient(Jws2Instance sh, WsParamSetI preset,
88           List<Argument> arguments, boolean editParams, String altitle,
89           jalview.datamodel.AlignmentView msa, boolean submitGaps,
90           boolean preserveOrder, Alignment seqdataset,
91           AlignFrame _alignFrame)
92   {
93     super(_alignFrame, preset, arguments);
94     if (!processParams(sh, editParams))
95     {
96       return;
97     }
98
99     if (!(sh.service instanceof MsaWS))
100     {
101       // redundant at mo - but may change
102       JOptionPane
103               .showMessageDialog(
104                       Desktop.desktop,
105                       "The Service called \n"
106                               + sh.serviceType
107                               + "\nis not a \nMultiple Sequence Alignment Service !",
108                       "Internal Jalview Error", JOptionPane.WARNING_MESSAGE);
109
110       return;
111     }
112     server = (MsaWS) sh.service;
113     if ((wsInfo = setWebService(sh, false)) == null)
114     {
115       JOptionPane.showMessageDialog(Desktop.desktop,
116               "The Multiple Sequence Alignment Service named "
117                       + sh.serviceType + " is unknown",
118               "Internal Jalview Error", JOptionPane.WARNING_MESSAGE);
119
120       return;
121     }
122     startMsaWSClient(altitle, msa, submitGaps, preserveOrder, seqdataset);
123
124   }
125
126   public MsaWSClient()
127   {
128     super();
129     // add a class reference to the list
130   }
131
132   private void startMsaWSClient(String altitle, AlignmentView msa,
133           boolean submitGaps, boolean preserveOrder, Alignment seqdataset)
134   {
135     // if (!locateWebService())
136     // {
137     // return;
138     // }
139
140     wsInfo.setProgressText(((submitGaps) ? "Re-alignment" : "Alignment")
141             + " of " + altitle + "\nJob details\n");
142     String jobtitle = WebServiceName.toLowerCase();
143     if (jobtitle.endsWith("alignment"))
144     {
145       if (submitGaps
146               && (!jobtitle.endsWith("realignment") || jobtitle
147                       .indexOf("profile") == -1))
148       {
149         int pos = jobtitle.indexOf("alignment");
150         jobtitle = WebServiceName.substring(0, pos) + "re-alignment of "
151                 + altitle;
152       }
153       else
154       {
155         jobtitle = WebServiceName + " of " + altitle;
156       }
157     }
158     else
159     {
160       jobtitle = WebServiceName + (submitGaps ? " re" : " ")
161               + "alignment of " + altitle;
162     }
163
164     MsaWSThread msathread = new MsaWSThread(server, preset, paramset,
165             WsURL, wsInfo, alignFrame, WebServiceName, jobtitle, msa,
166             submitGaps, preserveOrder, seqdataset);
167     wsInfo.setthisService(msathread);
168     msathread.start();
169   }
170
171   protected String getServiceActionKey()
172   {
173     return "MsaWS";
174   }
175
176   protected String getServiceActionDescription()
177   {
178     return "Multiple Sequence Alignment";
179   }
180
181   /**
182    * look at ourselves and work out if we are a service that can take a profile
183    * and align to it
184    * 
185    * @return true if we can send gapped sequences to the alignment service
186    */
187   private boolean canSubmitGaps()
188   {
189     // TODO: query service or extract service handle props to check if we can
190     // realign
191     return (WebServiceName.indexOf("lustal") > -1); // cheat!
192   }
193
194   
195   public void attachWSMenuEntry(JMenu rmsawsmenu,
196           final Jws2Instance service, final AlignFrame alignFrame)
197   {
198     setWebService(service, true); // headless
199     boolean finished = true, submitGaps = false;
200     JMenu msawsmenu = rmsawsmenu;
201     String svcname = WebServiceName;
202     if (svcname.endsWith("WS"))
203     {
204       svcname = svcname.substring(0, svcname.length() - 2);
205     }
206     String calcName = svcname + " ";
207     if (canSubmitGaps())
208     {
209       msawsmenu = new JMenu(svcname);
210       rmsawsmenu.add(msawsmenu);
211       calcName = "";
212     }
213     boolean hasparams = service.hasParameters();
214     do
215     {
216       String action = "Align ";
217       if (submitGaps == true)
218       {
219         action = "Realign ";
220         msawsmenu = new JMenu("Realign with " + svcname);
221         msawsmenu
222                 .setToolTipText("Align sequences to an existing alignment");
223         rmsawsmenu.add(msawsmenu);
224       }
225       final boolean withGaps = submitGaps;
226
227       JMenuItem method = new JMenuItem(calcName + "with Defaults");
228       method.setToolTipText(action + "with default settings");
229
230       method.addActionListener(new ActionListener()
231       {
232         public void actionPerformed(ActionEvent e)
233         {
234           AlignmentView msa = alignFrame.gatherSequencesForAlignment();
235           new MsaWSClient(service, alignFrame.getTitle(), msa, withGaps,
236                   true, alignFrame.getViewport().getAlignment()
237                           .getDataset(), alignFrame);
238
239         }
240       });
241       msawsmenu.add(method);
242       if (hasparams)
243       {
244         // only add these menu options if the service has user-modifiable
245         // arguments
246         method = new JMenuItem("Edit settings and run ...");
247         method.setToolTipText("View and change the parameters before alignment.");
248
249         method.addActionListener(new ActionListener()
250         {
251           public void actionPerformed(ActionEvent e)
252           {
253             AlignmentView msa = alignFrame.gatherSequencesForAlignment();
254             new MsaWSClient(service, null, null, true, alignFrame
255                     .getTitle(), msa, withGaps, true, alignFrame
256                     .getViewport().getAlignment().getDataset(), alignFrame);
257
258           }
259         });
260         msawsmenu.add(method);
261         List<WsParamSetI> presets = service.getParamStore().getPresets();
262         if (presets != null && presets.size() > 0)
263         {
264           JMenu presetlist = new JMenu("Run "+calcName + "with preset");
265
266           for (final WsParamSetI preset : presets)
267           {
268             final JMenuItem methodR = new JMenuItem(preset.getName());
269             methodR.setToolTipText("<html><p>"
270                     + JvSwingUtils.wrapTooltip("<strong>"
271                             + (preset.isModifiable() ? "User Preset"
272                                     : "Service Preset") + "</strong><br/>"
273                             + preset.getDescription() + "</p>") + "</html>");
274             methodR.addActionListener(new ActionListener()
275             {
276               public void actionPerformed(ActionEvent e)
277               {
278                 AlignmentView msa = alignFrame
279                         .gatherSequencesForAlignment();
280                 new MsaWSClient(service, preset, alignFrame.getTitle(),
281                         msa, false, true, alignFrame.getViewport()
282                                 .getAlignment().getDataset(), alignFrame);
283
284               }
285
286             });
287             presetlist.add(methodR);
288           }
289           msawsmenu.add(presetlist);
290         }
291       }
292       if (!submitGaps && canSubmitGaps())
293       {
294         submitGaps = true;
295         finished = false;
296       }
297       else
298       {
299         finished = true;
300       }
301     } while (!finished);
302   }
303 }