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