c88d8ebe4252a9a8079f5f2137adb0e8178f1491
[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.bin.Cache;
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   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           System.out.println("Couldn't create local directory : "
142                   + BJS_TEMPLATES_LOCAL_DIRECTORY);
143           return;
144         }
145       }
146
147       File file = new File(BJS_TEMPLATES_LOCAL_DIRECTORY + releaseFile);
148       if (!file.exists())
149       {
150
151         PrintWriter out = null;
152         try
153         {
154           out = new java.io.PrintWriter(new java.io.FileWriter(file));
155           out.print(getURLContentAsString(releaseUrl));
156         } catch (IOException e)
157         {
158           e.printStackTrace();
159         } finally
160         {
161           if (out != null)
162           {
163             out.flush();
164             out.close();
165           }
166         }
167       }
168     }
169
170   }
171
172   public static String getURLContentAsString(String url)
173           throws OutOfMemoryError
174   {
175     StringBuilder responseStrBuilder = null;
176     InputStream is = null;
177     try
178     {
179       URL resourceUrl = new URL(url);
180       is = new BufferedInputStream(resourceUrl.openStream());
181       BufferedReader br = new BufferedReader(new InputStreamReader(is));
182       responseStrBuilder = new StringBuilder();
183       String lineContent;
184
185       while ((lineContent = br.readLine()) != null)
186       {
187         responseStrBuilder.append(lineContent).append("\n");
188       }
189     } catch (OutOfMemoryError er)
190     {
191       er.printStackTrace();
192     } catch (Exception ex)
193     {
194       ex.printStackTrace();
195     } finally
196     {
197       if (is != null)
198       {
199         try
200         {
201           is.close();
202         } catch (IOException e)
203         {
204           e.printStackTrace();
205         }
206       }
207     }
208     return responseStrBuilder == null ? null
209             : responseStrBuilder.toString();
210   }
211
212   public static File getCurrentBJSTemplateFile()
213   {
214     return currentBJSTemplateFile;
215   }
216
217   public static void setCurrentBJSTemplateFile(File currentBJSTemplateFile)
218   {
219     BioJsHTMLOutput.currentBJSTemplateFile = currentBJSTemplateFile;
220   }
221
222   public static TreeMap<String, File> getBioJsMSAVersions()
223   {
224     return bioJsMSAVersions;
225   }
226
227   public static void setBioJsMSAVersions(
228           TreeMap<String, File> bioJsMSAVersions)
229   {
230     BioJsHTMLOutput.bioJsMSAVersions = bioJsMSAVersions;
231   }
232
233   @Override
234   public boolean isEmbedData()
235   {
236     return true;
237   }
238
239   @Override
240   public boolean isLaunchInBrowserAfterExport()
241   {
242     return true;
243   }
244
245   @Override
246   public void run()
247   {
248     try
249     {
250       String bioJSON = getBioJSONData();
251       String bioJSTemplateString = HTMLOutput
252               .readFileAsString(getCurrentBJSTemplateFile());
253       String generatedBioJsWithJalviewAlignmentAsJson = bioJSTemplateString
254               .replaceAll("#sequenceData#", bioJSON).toString();
255
256       PrintWriter out = new java.io.PrintWriter(
257               new java.io.FileWriter(generatedFile));
258       out.print(generatedBioJsWithJalviewAlignmentAsJson);
259       out.flush();
260       out.close();
261       setProgressMessage(MessageManager
262               .formatMessage("status.export_complete", getDescription()));
263       exportCompleted();
264
265     } catch (OutOfMemoryError err)
266     {
267       System.out.println("########################\n" + "OUT OF MEMORY "
268               + generatedFile + "\n" + "########################");
269       new OOMWarning("Creating Image for " + generatedFile, err);
270     } catch (Exception e)
271     {
272       setProgressMessage(MessageManager
273               .formatMessage("info.error_creating_file", getDescription()));
274       e.printStackTrace();
275     }
276
277   }
278
279 }