1be97f507c6004abdcb36cb395c880baff5c9e53
[jalview.git] / src / jalview / io / BioJsHTMLOutput.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.io;
22
23 import jalview.exceptions.NoFileSelectedException;
24 import jalview.gui.AlignmentPanel;
25 import jalview.gui.OOMWarning;
26 import jalview.json.binding.biojs.BioJSReleasePojo;
27 import jalview.json.binding.biojs.BioJSRepositoryPojo;
28 import jalview.util.MessageManager;
29
30 import java.io.BufferedInputStream;
31 import java.io.BufferedReader;
32 import java.io.File;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.io.InputStreamReader;
36 import java.io.PrintWriter;
37 import java.net.URISyntaxException;
38 import java.net.URL;
39 import java.util.Objects;
40 import java.util.TreeMap;
41
42 public class BioJsHTMLOutput extends HTMLOutput
43 {
44
45   private static File currentBJSTemplateFile;
46
47   private static TreeMap<String, File> bioJsMSAVersions;
48
49   public static final String DEFAULT_DIR = System.getProperty("user.home")
50           + File.separatorChar + ".biojs_templates" + File.separatorChar;
51
52   public static final String BJS_TEMPLATES_LOCAL_DIRECTORY = jalview.bin.Cache
53           .getDefault("biojs_template_directory", DEFAULT_DIR);
54
55   public static final String BJS_TEMPLATE_GIT_REPO = jalview.bin.Cache
56           .getDefault(
57                   "biojs_template_git_repo",
58                   "https://raw.githubusercontent.com/jalview/exporter-templates/master/biojs/package.json");
59
60   public BioJsHTMLOutput(AlignmentPanel ap)
61   {
62     super(ap);
63   }
64
65   @Override
66   public void exportHTML(String outputFile)
67   {
68     exportStarted();
69     try
70     {
71
72       if (outputFile == null)
73       {
74         outputFile = getOutputFile();
75       }
76       generatedFile = new File(outputFile);
77
78       String bioJSON = getBioJSONData();
79       String bioJSTemplateString = HTMLOutput.readFileAsString(getCurrentBJSTemplateFile());
80       String generatedBioJsWithJalviewAlignmentAsJson = bioJSTemplateString
81               .replaceAll("#sequenceData#", bioJSON).toString();
82
83       PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(
84               generatedFile));
85       out.print(generatedBioJsWithJalviewAlignmentAsJson);
86       out.flush();
87       out.close();
88       exportCompleted();
89       setProgressMessage(MessageManager.formatMessage(
90               "status.export_complete", "BioJS"));
91
92     } catch (NoFileSelectedException ex)
93     {
94       // do noting if no file was selected
95     } catch (OutOfMemoryError err)
96     {
97       System.out.println("########################\n" + "OUT OF MEMORY "
98               + outputFile + "\n" + "########################");
99       new OOMWarning("Creating Image for " + outputFile, err);
100     } catch (Exception e)
101     {
102       setProgressMessage(MessageManager.formatMessage(
103               "info.error_creating_file", "HTML"));
104       e.printStackTrace();
105     }
106   }
107
108
109
110   public static void refreshVersionInfo(String dirName)
111           throws URISyntaxException
112   {
113     File directory = new File(BJS_TEMPLATES_LOCAL_DIRECTORY);
114     Objects.requireNonNull(dirName, "dirName MUST not be null!");
115     Objects.requireNonNull(directory, "directory MUST not be null!");
116     TreeMap<String, File> versionFileMap = new TreeMap<String, File>();
117
118     for (File file : directory.listFiles())
119     {
120       if (file.isFile())
121       {
122         String fileName = file.getName().substring(0,
123                 file.getName().lastIndexOf("."));
124         String fileMeta[] = fileName.split("_");
125         if (fileMeta.length > 2)
126         {
127           setCurrentBJSTemplateFile(file);
128           versionFileMap.put(fileMeta[2], file);
129         }
130         else if (fileMeta.length > 1)
131         {
132           versionFileMap.put(fileMeta[1], file);
133         }
134       }
135     }
136     if (getCurrentBJSTemplateFile() == null && versionFileMap.size() > 0)
137     {
138       setCurrentBJSTemplateFile(versionFileMap.lastEntry().getValue());
139     }
140     setBioJsMSAVersions(versionFileMap);
141   }
142
143   public static void updateBioJS()
144   {
145     Thread updateThread = new Thread()
146     {
147       @Override
148       public void run()
149       {
150         try
151         {
152           String gitRepoPkgJson = getURLContentAsString(BJS_TEMPLATE_GIT_REPO);
153           if (gitRepoPkgJson != null)
154           {
155             BioJSRepositoryPojo release = new BioJSRepositoryPojo(
156                     gitRepoPkgJson);
157             syncUpdates(BJS_TEMPLATES_LOCAL_DIRECTORY, release);
158             refreshVersionInfo(BJS_TEMPLATES_LOCAL_DIRECTORY);
159           }
160         } catch (URISyntaxException e)
161         {
162           e.printStackTrace();
163         }
164       }
165     };
166     updateThread.start();
167
168   }
169
170   public static void syncUpdates(String localDir, BioJSRepositoryPojo repo)
171   {
172     for (BioJSReleasePojo bjsRelease : repo.getReleases())
173     {
174       String releaseUrl = bjsRelease.getUrl();
175       String releaseVersion = bjsRelease.getVersion();
176       String releaseFile = "BioJsMSA_" + releaseVersion + ".txt";
177       if (releaseVersion.equals(repo.getLatestReleaseVersion()))
178       {
179         releaseFile = "Latest_BioJsMSA_" + releaseVersion + ".txt";
180       }
181
182       File biojsDirectory = new File(BJS_TEMPLATES_LOCAL_DIRECTORY);
183       if (!biojsDirectory.exists())
184       {
185         if (!biojsDirectory.mkdirs())
186         {
187           System.out.println("Couldn't create local directory : "
188                   + BJS_TEMPLATES_LOCAL_DIRECTORY);
189           return;
190         }
191       }
192
193       File file = new File(BJS_TEMPLATES_LOCAL_DIRECTORY + releaseFile);
194       if (!file.exists())
195       {
196
197         PrintWriter out = null;
198         try
199         {
200           out = new java.io.PrintWriter(new java.io.FileWriter(file));
201           out.print(getURLContentAsString(releaseUrl));
202         } catch (IOException e)
203         {
204           e.printStackTrace();
205         } finally
206         {
207           if (out != null)
208           {
209             out.flush();
210             out.close();
211           }
212         }
213       }
214     }
215
216   }
217
218   public static String getURLContentAsString(String url)
219           throws OutOfMemoryError
220   {
221     StringBuilder responseStrBuilder = null;
222     InputStream is = null;
223     try
224     {
225       URL resourceUrl = new URL(url);
226       is = new BufferedInputStream(resourceUrl.openStream());
227       BufferedReader br = new BufferedReader(new InputStreamReader(is));
228       responseStrBuilder = new StringBuilder();
229       String lineContent;
230
231       while ((lineContent = br.readLine()) != null)
232       {
233         responseStrBuilder.append(lineContent).append("\n");
234       }
235     } catch (OutOfMemoryError er)
236     {
237       er.printStackTrace();
238     } catch (Exception ex)
239     {
240       ex.printStackTrace();
241     } finally
242     {
243       if (is != null)
244       {
245         try
246         {
247           is.close();
248         } catch (IOException e)
249         {
250           e.printStackTrace();
251         }
252       }
253     }
254     return responseStrBuilder == null ? null : responseStrBuilder
255             .toString();
256   }
257
258   public static File getCurrentBJSTemplateFile()
259   {
260     return currentBJSTemplateFile;
261   }
262
263   public static void setCurrentBJSTemplateFile(File currentBJSTemplateFile)
264   {
265     BioJsHTMLOutput.currentBJSTemplateFile = currentBJSTemplateFile;
266   }
267
268   public static TreeMap<String, File> getBioJsMSAVersions()
269   {
270     return bioJsMSAVersions;
271   }
272
273   public static void setBioJsMSAVersions(
274           TreeMap<String, File> bioJsMSAVersions)
275   {
276     BioJsHTMLOutput.bioJsMSAVersions = bioJsMSAVersions;
277   }
278
279   @Override
280   public boolean isEmbedData()
281   {
282     return true;
283   }
284
285   @Override
286   public boolean isLaunchInBrowserAfterExport()
287   {
288     return true;
289   }
290
291   @Override
292   public File getExportedFile()
293   {
294     return generatedFile;
295   }
296
297 }