JAL-3063 service param files read/saved using JAXB not Castor binding
[jalview.git] / src / jalview / gui / WsParamSetManager.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
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
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.gui;
22
23 import jalview.bin.Cache;
24 import jalview.io.JalviewFileChooser;
25 import jalview.io.JalviewFileView;
26 import jalview.util.MessageManager;
27 import jalview.ws.params.ParamDatastoreI;
28 import jalview.ws.params.ParamManager;
29 import jalview.ws.params.WsParamSetI;
30 import jalview.xml.binding.jalview.ObjectFactory;
31 import jalview.xml.binding.jalview.WebServiceParameterSet;
32
33 import java.io.File;
34 import java.io.FileInputStream;
35 import java.io.FileOutputStream;
36 import java.io.IOException;
37 import java.io.InputStreamReader;
38 import java.io.OutputStreamWriter;
39 import java.io.PrintWriter;
40 import java.util.ArrayList;
41 import java.util.Hashtable;
42 import java.util.List;
43 import java.util.StringTokenizer;
44
45 import javax.xml.bind.JAXBContext;
46 import javax.xml.bind.JAXBElement;
47 import javax.xml.bind.Marshaller;
48 import javax.xml.stream.XMLInputFactory;
49 import javax.xml.stream.XMLStreamReader;
50
51 /**
52  * store and retrieve web service parameter sets.
53  * 
54  * @author JimP
55  * 
56  */
57 public class WsParamSetManager implements ParamManager
58 {
59   Hashtable<String, ParamDatastoreI> paramparsers = new Hashtable<>();
60
61   @Override
62   public WsParamSetI[] getParameterSet(String name, String serviceUrl,
63           boolean modifiable, boolean unmodifiable)
64   {
65     String files = Cache.getProperty("WS_PARAM_FILES");
66     if (files == null)
67     {
68       return null;
69     }
70     StringTokenizer st = new StringTokenizer(files, "|");
71     String pfile = null;
72     List<WsParamSetI> params = new ArrayList<>();
73     while (st.hasMoreTokens())
74     {
75       pfile = st.nextToken();
76       try
77       {
78         WsParamSetI[] pset = parseParamFile(pfile);
79         for (WsParamSetI p : pset)
80         {
81           boolean add = false;
82           if (serviceUrl != null)
83           {
84             for (String url : p.getApplicableUrls())
85             {
86               if (url.equals(serviceUrl))
87               {
88                 add = true;
89               }
90             }
91           }
92           else
93           {
94             add = true;
95           }
96           add &= (modifiable == p.isModifiable()
97                   || unmodifiable == !p.isModifiable());
98           add &= name == null || p.getName().equals(name);
99
100           if (add)
101           {
102
103             params.add(p);
104           }
105
106         }
107       } catch (IOException e)
108       {
109         Cache.log.info("Failed to parse parameter file " + pfile
110                 + " (Check that all JALVIEW_WSPARAMFILES entries are valid!)",
111                 e);
112       }
113     }
114     return params.toArray(new WsParamSetI[0]);
115   }
116
117   private WsParamSetI[] parseParamFile(String filename) throws IOException
118   {
119     List<WsParamSetI> psets = new ArrayList<>();
120     InputStreamReader is = new InputStreamReader(
121             new FileInputStream(new File(filename)), "UTF-8");
122
123     WebServiceParameterSet wspset = null;
124     try
125     {
126       JAXBContext jc = JAXBContext
127               .newInstance("jalview.xml.binding.jalview");
128       javax.xml.bind.Unmarshaller um = jc.createUnmarshaller();
129       XMLStreamReader streamReader = XMLInputFactory.newInstance()
130               .createXMLStreamReader(is);
131       JAXBElement<WebServiceParameterSet> jbe = um.unmarshal(streamReader,
132               WebServiceParameterSet.class);
133       wspset = jbe.getValue();
134     } catch (Exception ex)
135     {
136       throw new IOException(ex);
137     }
138
139     if (wspset != null && wspset.getParameters().length() > 0)
140     {
141       List<String> urls = wspset.getServiceURL();
142       final String[] urlArray = urls.toArray(new String[urls.size()]);
143
144       for (String url : urls)
145       {
146         ParamDatastoreI parser = paramparsers.get(url);
147         if (parser != null)
148         {
149           WsParamSetI pset = parser.parseServiceParameterFile(
150                   wspset.getName(), wspset.getDescription(),
151                   urlArray, wspset.getParameters());
152           if (pset != null)
153           {
154             pset.setSourceFile(filename);
155             psets.add(pset);
156             break;
157           }
158         }
159       }
160     }
161
162     return psets.toArray(new WsParamSetI[0]);
163   }
164
165   @Override
166   public void storeParameterSet(WsParamSetI parameterSet)
167   {
168     String filename = parameterSet.getSourceFile();
169     File outfile = null;
170     try
171     {
172       if (filename != null && !((outfile = new File(filename)).canWrite()))
173       {
174         Cache.log.warn("Can't write to " + filename
175                 + " - Prompting for new file to write to.");
176         filename = null;
177       }
178     } catch (Exception e)
179     {
180       filename = null;
181     }
182
183     ParamDatastoreI parser = null;
184     for (String urls : parameterSet.getApplicableUrls())
185     {
186       if (parser == null)
187       {
188         parser = paramparsers.get(urls);
189       }
190     }
191     if (parser == null)
192     {
193       throw new Error(MessageManager.getString(
194               "error.implementation_error_cannot_find_marshaller_for_param_set"));
195     }
196     if (filename == null)
197     {
198       JalviewFileChooser chooser = new JalviewFileChooser("wsparams",
199               "Web Service Parameter File");
200       chooser.setFileView(new JalviewFileView());
201       chooser.setDialogTitle(MessageManager
202               .getString("label.choose_filename_for_param_file"));
203       chooser.setToolTipText(MessageManager.getString("action.save"));
204       int value = chooser.showSaveDialog(Desktop.instance);
205       if (value == JalviewFileChooser.APPROVE_OPTION)
206       {
207         outfile = chooser.getSelectedFile();
208         Cache.setProperty("LAST_DIRECTORY", outfile.getParent());
209         filename = outfile.getAbsolutePath();
210         if (!filename.endsWith(".wsparams"))
211         {
212           filename = filename.concat(".wsparams");
213           outfile = new File(filename);
214         }
215       }
216     }
217     if (outfile != null)
218     {
219       String paramFiles = jalview.bin.Cache.getDefault("WS_PARAM_FILES",
220               filename);
221       if (paramFiles.indexOf(filename) == -1)
222       {
223         if (paramFiles.length() > 0)
224         {
225           paramFiles = paramFiles.concat("|");
226         }
227         paramFiles = paramFiles.concat(filename);
228       }
229       Cache.setProperty("WS_PARAM_FILES", paramFiles);
230
231       WebServiceParameterSet paramxml = new WebServiceParameterSet();
232
233       paramxml.setName(parameterSet.getName());
234       paramxml.setDescription(parameterSet.getDescription());
235       for (String url : parameterSet.getApplicableUrls())
236       {
237         paramxml.getServiceURL().add(url);
238       }
239       paramxml.setVersion("1.0");
240       try
241       {
242         paramxml.setParameters(
243                 parser.generateServiceParameterFile(parameterSet));
244         PrintWriter out = new PrintWriter(new OutputStreamWriter(
245                 new FileOutputStream(outfile), "UTF-8"));
246         JAXBContext jaxbContext = JAXBContext
247                 .newInstance(WebServiceParameterSet.class);
248         Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
249         jaxbMarshaller.marshal(
250                 new ObjectFactory().createWebServiceParameterSet(paramxml),
251                 out);
252         out.close();
253         parameterSet.setSourceFile(filename);
254       } catch (Exception e)
255       {
256         Cache.log.error("Couldn't write parameter file to " + outfile, e);
257       }
258     }
259   }
260
261   /*
262    * 
263    * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
264    * .getProperty("LAST_DIRECTORY"), new String[] { "jc" }, new String[] {
265    * "Jalview User Colours" }, "Jalview User Colours"); chooser.setFileView(new
266    * jalview.io.JalviewFileView());
267    * chooser.setDialogTitle("Load colour scheme");
268    * chooser.setToolTipText("Load");
269    * 
270    * int value = chooser.showOpenDialog(this);
271    * 
272    * if (value == JalviewFileChooser.APPROVE_OPTION) { File choice =
273    * chooser.getSelectedFile(); jalview.bin.Cache.setProperty("LAST_DIRECTORY",
274    * choice.getParent()); String defaultColours = jalview.bin.Cache.getDefault(
275    * "USER_DEFINED_COLOURS", choice.getPath()); if
276    * (defaultColours.indexOf(choice.getPath()) == -1) { defaultColours =
277    * defaultColours.concat("|") .concat(choice.getPath()); } (non-Javadoc)
278    * 
279    * @see
280    * jalview.ws.params.ParamManager#deleteParameterSet(jalview.ws.params.WsParamSetI
281    * )
282    */
283   @Override
284   public void deleteParameterSet(WsParamSetI parameterSet)
285   {
286     String filename = parameterSet.getSourceFile();
287     if (filename == null || filename.trim().length() < 1)
288     {
289       return;
290     }
291     String paramFiles = jalview.bin.Cache.getDefault("WS_PARAM_FILES", "");
292     if (paramFiles.indexOf(filename) > -1)
293     {
294       String nparamFiles = new String();
295       StringTokenizer st = new StringTokenizer(paramFiles, "|");
296       while (st.hasMoreElements())
297       {
298         String fl = st.nextToken();
299         if (!fl.equals(filename))
300         {
301           nparamFiles = nparamFiles.concat("|").concat(fl);
302         }
303       }
304       jalview.bin.Cache.setProperty("WS_PARAM_FILES", nparamFiles);
305     }
306
307     try
308     {
309       File pfile = new File(filename);
310       if (pfile.exists() && pfile.canWrite())
311       {
312         if (JvOptionPane.showConfirmDialog(Desktop.instance,
313                 "Delete the preset's file, too ?", "Delete User Preset ?",
314                 JvOptionPane.OK_CANCEL_OPTION) == JvOptionPane.OK_OPTION)
315         {
316           pfile.delete();
317         }
318       }
319     } catch (Exception e)
320     {
321       Cache.log.error(
322               "Exception when trying to delete webservice user preset: ",
323               e);
324     }
325   }
326
327   @Override
328   public void registerParser(String hosturl, ParamDatastoreI paramdataStore)
329   {
330     paramparsers.put(hosturl, paramdataStore);
331   }
332
333 }