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