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