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