JAL-1320 sort options and parameters according to their name
[jalview.git] / src / jalview / ws / jws2 / JabaParamStore.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3  * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, 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.io.IOException;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Hashtable;
24 import java.util.List;
25 import java.util.StringTokenizer;
26
27 import org.jmol.util.ArrayUtil;
28 import compbio.metadata.Argument;
29 import compbio.metadata.Option;
30 import compbio.metadata.Parameter;
31 import compbio.metadata.Preset;
32 import compbio.metadata.PresetManager;
33 import compbio.metadata.RunnerConfig;
34
35 import jalview.ws.jws2.dm.JabaOption;
36 import jalview.ws.jws2.dm.JabaParameter;
37 import jalview.ws.jws2.dm.JabaWsParamSet;
38 import jalview.ws.jws2.jabaws2.Jws2Instance;
39 import jalview.ws.params.ArgumentI;
40 import jalview.ws.params.ParamDatastoreI;
41 import jalview.ws.params.ParamManager;
42 import jalview.ws.params.WsParamSetI;
43
44 public class JabaParamStore implements ParamDatastoreI
45 {
46
47   Hashtable<String, JabaWsParamSet> editedParams = new Hashtable<String, JabaWsParamSet>();
48
49   private Jws2Instance service;
50
51   private RunnerConfig serviceOptions;
52
53   private Hashtable<String, JabaPreset> servicePresets;
54
55   public JabaParamStore(Jws2Instance service)
56   {
57     this(service, null);
58   }
59
60   ParamManager manager;
61
62   public JabaParamStore(Jws2Instance service, ParamManager manager)
63   {
64     this.service = service;
65     serviceOptions = service.getRunnerConfig();
66     this.manager = manager;
67     // discover all the user's locally stored presets for this service and
68     // populate the hash table
69     if (manager != null)
70     {
71       manager.registerParser(service.getUri(), this);
72       WsParamSetI[] prams = manager.getParameterSet(null, service.getUri(),
73               true, false);
74       if (prams != null)
75       {
76         for (WsParamSetI paramset : prams)
77         {
78           if (paramset instanceof JabaWsParamSet)
79           {
80             editedParams.put(paramset.getName(), (JabaWsParamSet) paramset);
81           }
82           else
83           {
84             System.err
85                     .println("Warning: Ignoring parameter set instance of type "
86                             + paramset.getClass()
87                             + " : Bound but not applicable for service at "
88                             + service.getUri());
89           }
90         }
91       }
92     }
93   }
94
95   @Override
96   public List<WsParamSetI> getPresets()
97   {
98     List<WsParamSetI> prefs = new ArrayList();
99     if (servicePresets == null)
100     {
101       servicePresets = new Hashtable<String, JabaPreset>();
102       PresetManager prman;
103       if ((prman = service.getPresets()) != null)
104       {
105         List pset = prman.getPresets();
106         if (pset != null)
107         {
108           for (Object pr : pset)
109           {
110             JabaPreset prset = new JabaPreset(service, (Preset) pr);
111             servicePresets.put(prset.getName(), prset);
112           }
113         }
114       }
115     }
116     for (JabaPreset pr : servicePresets.values())
117     {
118       prefs.add(pr);
119     }
120     for (WsParamSetI wspset : editedParams.values())
121     {
122       prefs.add(wspset);
123     }
124     return prefs;
125   }
126
127   @Override
128   public WsParamSetI getPreset(String name)
129   {
130     for (WsParamSetI pr : getPresets())
131     {
132       if (pr.getName().equals(name))
133       {
134         return pr;
135       }
136     }
137     return null;
138   }
139
140   public static List<ArgumentI> getJwsArgsfromJaba(List jabargs)
141   {
142     return getJwsArgsfromJaba(jabargs, true);
143   }
144
145   public static List<ArgumentI> getJwsArgsfromJaba(List jabargs,
146           boolean sortByOpt)
147   {
148     List<ArgumentI> rgs = new ArrayList<ArgumentI>();
149     List<String> rgnames = new ArrayList<String>();
150     for (Object rg : jabargs)
151     {
152       ArgumentI narg = null;
153       String nargstring = null;
154       if (rg instanceof Parameter)
155       {
156         narg = new JabaParameter((Parameter) rg);
157         nargstring = narg.getName(); // just sort by name for this
158       }
159       else if (rg instanceof Option)
160       {
161         narg = new JabaOption((Option) rg);
162         nargstring = (String) ((Option) rg).getOptionNames().get(0);
163       }
164       if (narg == null)
165       {
166         throw new Error(
167                 "Implementation Error: Cannot handle Jaba parameter object "
168                         + rg.getClass());
169       }
170       else
171       {
172         rgs.add(narg);
173         rgnames.add(nargstring);
174       }
175     }
176     if (!sortByOpt)
177     {
178       return rgs;
179     }
180     ArgumentI[] rgssort = rgs.toArray(new ArgumentI[rgs.size()]);
181     String[] rgssorton = rgnames.toArray(new String[rgs.size()]);
182     jalview.util.QuickSort.sort(rgssorton, rgssort);
183     return Arrays.asList(rgssort);
184   }
185
186   public static List getJabafromJwsArgs(List<ArgumentI> jwsargs)
187   {
188     List rgs = new ArrayList();
189     for (ArgumentI rg : jwsargs)
190     {
191       Argument narg = (rg instanceof JabaOption) ? ((JabaOption) rg)
192               .getOption() : null;
193       if (narg == null)
194       {
195         throw new Error(
196                 "Implementation Error: Cannot handle Jaba parameter object "
197                         + rg.getClass());
198       }
199       else
200       {
201         rgs.add(narg);
202       }
203     }
204     return rgs;
205   }
206
207   @Override
208   public List<ArgumentI> getServiceParameters()
209   {
210     return getJwsArgsfromJaba(serviceOptions.getArguments());
211   }
212
213   @Override
214   public boolean presetExists(String name)
215   {
216     return (editedParams.containsKey(name) || servicePresets
217             .containsKey(name));
218   }
219
220   @Override
221   public void deletePreset(String name)
222   {
223     if (editedParams.containsKey(name))
224     {
225       WsParamSetI parameterSet = editedParams.get(name);
226       editedParams.remove(name);
227       if (manager != null)
228       {
229         manager.deleteParameterSet(parameterSet);
230       }
231       return;
232     }
233     if (servicePresets.containsKey(name))
234     {
235       throw new Error(
236               "Implementation error: Attempt to delete a service preset!");
237     }
238   }
239
240   @Override
241   public void storePreset(String presetName, String text,
242           List<ArgumentI> jobParams)
243   {
244     JabaWsParamSet jps = new JabaWsParamSet(presetName, text, jobParams);
245     jps.setApplicableUrls(new String[]
246     { service.getUri() });
247     editedParams.put(jps.getName(), jps);
248     if (manager != null)
249     {
250       manager.storeParameterSet(jps);
251     }
252   }
253
254   @Override
255   public void updatePreset(String oldName, String presetName, String text,
256           List<ArgumentI> jobParams)
257   {
258     JabaWsParamSet jps = (JabaWsParamSet) ((oldName != null) ? getPreset(oldName)
259             : getPreset(presetName));
260     if (jps == null)
261     {
262       throw new Error("Implementation error: Can't locate either oldname ("
263               + oldName + ") or presetName (" + presetName
264               + "in the datastore!");
265     }
266     jps.setName(presetName);
267     jps.setDescription(text);
268     jps.setArguments(jobParams);
269     jps.setApplicableUrls(new String[]
270     { service.getUri() });
271     if (oldName != null && !oldName.equals(jps.getName()))
272     {
273       editedParams.remove(oldName);
274     }
275     editedParams.put(jps.getName(), jps);
276
277     if (manager != null)
278     {
279       manager.storeParameterSet(jps);
280     }
281   }
282
283   /**
284    * create a new, empty parameter set for this service
285    * 
286    * @return
287    */
288   WsParamSetI newWsParamSet()
289   {
290     return new JabaWsParamSet();
291   };
292
293   private boolean involves(String[] urls)
294   {
295     boolean found = false;
296     for (String url : urls)
297     {
298       if (service.getServiceTypeURI().equals(url)
299               || service.getUri().equalsIgnoreCase(url))
300       {
301         found = true;
302         break;
303       }
304     }
305     return found;
306   }
307
308   @Override
309   public WsParamSetI parseServiceParameterFile(String name, String descr,
310           String[] urls, String parameterfile) throws IOException
311   {
312     if (!involves(urls))
313     {
314       throw new IOException(
315               "Implementation error: Cannot find service url in the given url set!");
316
317     }
318     JabaWsParamSet wsp = new JabaWsParamSet();
319     wsp.setName(name);
320     wsp.setDescription(descr);
321     wsp.setApplicableUrls(urls.clone());
322
323     List<String> lines = new ArrayList<String>();
324     StringTokenizer st = new StringTokenizer(parameterfile, "\n");
325     while (st.hasMoreTokens())
326     {
327       lines.add(st.nextToken());
328     }
329     wsp.setjabaArguments(ParameterUtils.processParameters(lines,
330             serviceOptions, " "));
331     return wsp;
332   }
333
334   @Override
335   public String generateServiceParameterFile(WsParamSetI pset)
336           throws IOException
337   {
338     if (!involves(pset.getApplicableUrls()))
339     {
340       throw new IOException(
341               "Implementation error: Cannot find service url in the given url set for this service parameter store ("
342                       + service.getUri() + ") !");
343
344     }
345     if (!(pset instanceof JabaWsParamSet))
346     {
347       throw new Error(
348               "Implementation error: JabaWsParamSets can only be handled by JabaParamStore");
349     }
350
351     StringBuffer rslt = new StringBuffer();
352     for (String ln : ParameterUtils.writeParameterSet(
353             ((JabaWsParamSet) pset).getjabaArguments(), " "))
354     {
355       rslt.append(ln);
356       rslt.append("\n");
357     }
358     ;
359     return rslt.toString();
360   }
361
362 }