JAL-1645 Version-Rel Version 2.9 Year-Rel 2015 Licensing glob
[jalview.git] / src / jalview / io / BioJsHTMLOutput.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9)
3  * Copyright (C) 2015 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.io;
22
23 import jalview.api.AlignExportSettingI;
24 import jalview.api.AlignmentViewPanel;
25 import jalview.datamodel.AlignmentExportData;
26 import jalview.exceptions.NoFileSelectedException;
27 import jalview.json.binding.biojs.BioJSReleasePojo;
28 import jalview.json.binding.biojs.BioJSRepositoryPojo;
29 import jalview.util.MessageManager;
30
31 import java.io.BufferedInputStream;
32 import java.io.BufferedReader;
33 import java.io.File;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.io.InputStreamReader;
37 import java.io.PrintWriter;
38 import java.net.URISyntaxException;
39 import java.net.URL;
40 import java.util.Objects;
41 import java.util.TreeMap;
42
43 public class BioJsHTMLOutput
44 {
45   private AlignmentViewPanel ap;
46
47   private static File currentBJSTemplateFile;
48
49   private static TreeMap<String, File> bioJsMSAVersions;
50
51   public static final String DEFAULT_DIR = System.getProperty("user.home")
52           + File.separatorChar + ".biojs_templates" + File.separatorChar;
53
54   public static final String BJS_TEMPLATES_LOCAL_DIRECTORY = jalview.bin.Cache
55           .getDefault("biojs_template_directory", DEFAULT_DIR);
56
57   public static final String BJS_TEMPLATE_GIT_REPO = jalview.bin.Cache
58           .getDefault(
59                   "biojs_template_git_repo",
60                   "https://raw.githubusercontent.com/jalview/exporter-templates/master/biojs/package.json");
61
62   public BioJsHTMLOutput(AlignmentViewPanel ap)
63   {
64     if (ap != null)
65     {
66       this.ap = ap;
67     }
68   }
69
70   public void exportJalviewAlignmentAsBioJsHtmlFile()
71   {
72     try
73     {
74       String outputFile = getOutputFile();
75       // String jalviewAlignmentJson = JSONFile.getJSONData(ap);
76       AlignExportSettingI exportSettings = new AlignExportSettingI()
77       {
78         @Override
79         public boolean isExportHiddenSequences()
80         {
81           return true;
82         }
83
84         @Override
85         public boolean isExportHiddenColumns()
86         {
87           return true;
88         }
89
90         @Override
91         public boolean isExportAnnotations()
92         {
93           return true;
94         }
95
96         @Override
97         public boolean isExportFeatures()
98         {
99           return true;
100         }
101
102         @Override
103         public boolean isExportGroups()
104         {
105           return true;
106         }
107
108         @Override
109         public boolean isCancelled()
110         {
111           return false;
112         }
113
114       };
115       AlignmentExportData exportData = jalview.gui.AlignFrame
116               .getAlignmentForExport(JSONFile.FILE_DESC,
117                       ap.getAlignViewport(), exportSettings);
118       if (exportData.getSettings().isCancelled())
119       {
120         return;
121       }
122       String jalviewAlignmentJson = new FormatAdapter(ap,
123               exportData.getSettings()).formatSequences(JSONFile.FILE_DESC,
124               exportData.getAlignment(), exportData.getOmitHidden(),
125               exportData.getStartEndPostions(), ap.getAlignViewport()
126                       .getColumnSelection());
127
128       String bioJSTemplateString = getBioJsTemplateAsString();
129       String generatedBioJsWithJalviewAlignmentAsJson = bioJSTemplateString
130               .replaceAll("#sequenceData#", jalviewAlignmentJson)
131               .toString();
132
133       PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(
134               outputFile));
135       out.print(generatedBioJsWithJalviewAlignmentAsJson);
136       out.flush();
137       out.close();
138       jalview.util.BrowserLauncher.openURL("file:///" + outputFile);
139     } catch (NoFileSelectedException ex)
140     {
141       // do noting if no file was selected
142     } catch (Exception e)
143     {
144       e.printStackTrace();
145     }
146   }
147
148   public String getOutputFile() throws NoFileSelectedException
149   {
150     String selectedFile = null;
151     JalviewFileChooser jvFileChooser = new JalviewFileChooser(
152             jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
153             new String[] { "html" }, new String[] { "HTML files" },
154             "HTML files");
155     jvFileChooser.setFileView(new JalviewFileView());
156
157     jvFileChooser.setDialogTitle(MessageManager
158             .getString("label.save_as_biojs_html"));
159     jvFileChooser.setToolTipText(MessageManager.getString("action.save"));
160
161     int fileChooserOpt = jvFileChooser.showSaveDialog(null);
162     if (fileChooserOpt == JalviewFileChooser.APPROVE_OPTION)
163     {
164       jalview.bin.Cache.setProperty("LAST_DIRECTORY", jvFileChooser
165               .getSelectedFile().getParent());
166       selectedFile = jvFileChooser.getSelectedFile().getPath();
167     }
168     else
169     {
170       throw new NoFileSelectedException("No file was selected.");
171     }
172     return selectedFile;
173   }
174
175   public static String getBioJsTemplateAsString() throws IOException
176   {
177     InputStreamReader isReader = null;
178     BufferedReader buffReader = null;
179     StringBuilder sb = new StringBuilder();
180     Objects.requireNonNull(getCurrentBJSTemplateFile(),
181             "BioJsTemplate File not initialized!");
182     @SuppressWarnings("deprecation")
183     URL url = getCurrentBJSTemplateFile().toURL();
184     if (url != null)
185     {
186       try
187       {
188         isReader = new InputStreamReader(url.openStream());
189         buffReader = new BufferedReader(isReader);
190         String line;
191         String lineSeparator = System.getProperty("line.separator");
192         while ((line = buffReader.readLine()) != null)
193         {
194           sb.append(line).append(lineSeparator);
195         }
196
197       } catch (Exception ex)
198       {
199         ex.printStackTrace();
200       } finally
201       {
202         if (isReader != null)
203         {
204           isReader.close();
205         }
206
207         if (buffReader != null)
208         {
209           buffReader.close();
210         }
211       }
212     }
213     return sb.toString();
214   }
215
216   public static void refreshBioJSVersionsInfo(String dirName)
217           throws URISyntaxException
218   {
219     File directory = new File(BJS_TEMPLATES_LOCAL_DIRECTORY);
220     Objects.requireNonNull(dirName, "dirName MUST not be null!");
221     Objects.requireNonNull(directory, "directory MUST not be null!");
222     TreeMap<String, File> versionFileMap = new TreeMap<String, File>();
223
224     for (File file : directory.listFiles())
225     {
226       if (file.isFile())
227       {
228         String fileName = file.getName().substring(0,
229                 file.getName().lastIndexOf("."));
230         String fileMeta[] = fileName.split("_");
231         if (fileMeta.length > 2)
232         {
233           setCurrentBJSTemplateFile(file);
234           versionFileMap.put(fileMeta[2], file);
235         }
236         else if (fileMeta.length > 1)
237         {
238           versionFileMap.put(fileMeta[1], file);
239         }
240       }
241     }
242     if (getCurrentBJSTemplateFile() == null && versionFileMap.size() > 0)
243     {
244       setCurrentBJSTemplateFile(versionFileMap.lastEntry().getValue());
245     }
246     setBioJsMSAVersions(versionFileMap);
247   }
248
249   public static void updateBioJS()
250   {
251     Thread updateThread = new Thread()
252     {
253       public void run()
254       {
255         try
256         {
257           String gitRepoPkgJson = getURLContentAsString(BJS_TEMPLATE_GIT_REPO);
258           if (gitRepoPkgJson != null)
259           {
260             BioJSRepositoryPojo release = new BioJSRepositoryPojo(
261                     gitRepoPkgJson);
262             syncUpdates(BJS_TEMPLATES_LOCAL_DIRECTORY, release);
263             refreshBioJSVersionsInfo(BJS_TEMPLATES_LOCAL_DIRECTORY);
264           }
265         } catch (URISyntaxException e)
266         {
267           e.printStackTrace();
268         }
269       }
270     };
271     updateThread.start();
272
273   }
274
275   public static void syncUpdates(String localDir, BioJSRepositoryPojo repo)
276   {
277     for (BioJSReleasePojo bjsRelease : repo.getReleases())
278     {
279       String releaseUrl = bjsRelease.getUrl();
280       String releaseVersion = bjsRelease.getVersion();
281       String releaseFile = "BioJsMSA_" + releaseVersion + ".txt";
282       if (releaseVersion.equals(repo.getLatestReleaseVersion()))
283       {
284         releaseFile = "Latest_BioJsMSA_" + releaseVersion + ".txt";
285       }
286
287       File biojsDirectory = new File(BJS_TEMPLATES_LOCAL_DIRECTORY);
288       if (!biojsDirectory.exists())
289       {
290         if (!biojsDirectory.mkdirs())
291         {
292           System.out.println("Couldn't create local directory : "
293                   + BJS_TEMPLATES_LOCAL_DIRECTORY);
294           return;
295         }
296       }
297
298       File file = new File(BJS_TEMPLATES_LOCAL_DIRECTORY + releaseFile);
299       if (!file.exists())
300       {
301
302         PrintWriter out = null;
303         try
304         {
305           out = new java.io.PrintWriter(new java.io.FileWriter(file));
306           out.print(getURLContentAsString(releaseUrl));
307         } catch (IOException e)
308         {
309           e.printStackTrace();
310         } finally
311         {
312           if (out != null)
313           {
314             out.flush();
315             out.close();
316           }
317         }
318       }
319     }
320
321   }
322
323   public static String getURLContentAsString(String url)
324           throws OutOfMemoryError
325   {
326     StringBuilder responseStrBuilder = null;
327     InputStream is = null;
328     try
329     {
330       URL resourceUrl = new URL(url);
331       is = new BufferedInputStream(resourceUrl.openStream());
332       BufferedReader br = new BufferedReader(new InputStreamReader(is));
333       responseStrBuilder = new StringBuilder();
334       String lineContent;
335
336       while ((lineContent = br.readLine()) != null)
337       {
338         responseStrBuilder.append(lineContent).append("\n");
339       }
340     } catch (OutOfMemoryError er)
341     {
342       er.printStackTrace();
343     } catch (Exception ex)
344     {
345       ex.printStackTrace();
346     } finally
347     {
348       if (is != null)
349       {
350         try
351         {
352           is.close();
353         } catch (IOException e)
354         {
355           e.printStackTrace();
356         }
357       }
358     }
359     return responseStrBuilder == null ? null : responseStrBuilder
360             .toString();
361   }
362
363   public static File getCurrentBJSTemplateFile()
364   {
365     return currentBJSTemplateFile;
366   }
367
368   public static void setCurrentBJSTemplateFile(File currentBJSTemplateFile)
369   {
370     BioJsHTMLOutput.currentBJSTemplateFile = currentBJSTemplateFile;
371   }
372
373   public static TreeMap<String, File> getBioJsMSAVersions()
374   {
375     return bioJsMSAVersions;
376   }
377
378   public static void setBioJsMSAVersions(
379           TreeMap<String, File> bioJsMSAVersions)
380   {
381     BioJsHTMLOutput.bioJsMSAVersions = bioJsMSAVersions;
382   }
383
384 }