JAL-1756 bug-fix
[jalview.git] / src / jalview / io / BioJsHTMLOutput.java
1 package jalview.io;
2
3 import jalview.exceptions.NoFileSelectedException;
4 import jalview.gui.AlignViewport;
5 import jalview.gui.AlignmentPanel;
6 import jalview.gui.FeatureRenderer;
7 import jalview.json.binding.v1.BioJSReleasePojo;
8 import jalview.json.binding.v1.BioJSRepositoryPojo;
9 import jalview.util.MessageManager;
10
11 import java.io.BufferedInputStream;
12 import java.io.BufferedReader;
13 import java.io.File;
14 import java.io.IOException;
15 import java.io.InputStream;
16 import java.io.InputStreamReader;
17 import java.io.PrintWriter;
18 import java.net.URISyntaxException;
19 import java.net.URL;
20 import java.util.Objects;
21 import java.util.TreeMap;
22
23
24 public class BioJsHTMLOutput
25 {
26   private AlignViewport av;
27
28   private static File currentBJSTemplateFile;
29
30   private static TreeMap<String, File> bioJsMSAVersions;
31
32   public static final String DEFAULT_DIR = System.getProperty("user.home")
33           + File.separatorChar + ".biojs_templates" + File.separatorChar;
34
35   public static final String BJS_TEMPLATES_LOCAL_DIRECTORY = jalview.bin.Cache
36           .getDefault("biojs_template_directory", DEFAULT_DIR);
37
38   public static final String BJS_TEMPLATE_GIT_REPO = jalview.bin.Cache
39           .getDefault(
40                   "biojs_template_git_repo",
41                   "https://raw.githubusercontent.com/tcofoegbu/bjs-template/master/package.json");
42
43   public BioJsHTMLOutput(AlignmentPanel ap, FeatureRenderer fr1)
44   {
45     if (ap != null)
46     {
47       this.av = ap.av;
48       av.setFeatureRenderer(new FeatureRenderer(ap));
49     }
50   }
51
52   public void exportJalviewAlignmentAsBioJsHtmlFile()
53   {
54     try
55     {
56       String outputFile = getOutputFile();
57       String jalviewAlignmentJson = JSONFile.getJSONData(av);
58       String bioJSTemplateString = getBioJsTemplateAsString();
59       String generatedBioJsWithJalviewAlignmentAsJson = bioJSTemplateString
60               .replaceAll(
61 "#sequenceData#", jalviewAlignmentJson)
62               .toString();
63
64       PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(
65               outputFile));
66       out.print(generatedBioJsWithJalviewAlignmentAsJson);
67       out.flush();
68       out.close();
69       jalview.util.BrowserLauncher.openURL("file:///" + outputFile);
70     } catch (NoFileSelectedException ex)
71     {
72       // do noting if no file was selected
73     } catch (Exception e)
74     {
75       e.printStackTrace();
76     }
77   }
78
79   public String getOutputFile() throws NoFileSelectedException
80   {
81     String selectedFile = null;
82     JalviewFileChooser jvFileChooser = new JalviewFileChooser(
83             jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
84             { "html" }, new String[]
85             { "HTML files" }, "HTML files");
86     jvFileChooser.setFileView(new JalviewFileView());
87
88     // TODO uncomment when supported by MassageManager
89     jvFileChooser.setDialogTitle(MessageManager
90             .getString("label.save_as_biojs_html"));
91     jvFileChooser.setDialogTitle("save as BioJs HTML");
92     jvFileChooser.setToolTipText(MessageManager.getString("action.save"));
93
94     int fileChooserOpt = jvFileChooser.showSaveDialog(null);
95     if (fileChooserOpt == JalviewFileChooser.APPROVE_OPTION)
96     {
97       jalview.bin.Cache.setProperty("LAST_DIRECTORY", jvFileChooser
98               .getSelectedFile().getParent());
99       selectedFile = jvFileChooser.getSelectedFile().getPath();
100     }
101     else
102     {
103       throw new NoFileSelectedException("No file was selected.");
104     }
105     return selectedFile;
106   }
107
108
109   public static String getBioJsTemplateAsString()
110           throws IOException
111   {
112     InputStreamReader isReader = null;
113     BufferedReader buffReader = null;
114     StringBuilder sb = new StringBuilder();
115     Objects.requireNonNull(getCurrentBJSTemplateFile(),
116             "BioJsTemplate File not initialized!");
117     @SuppressWarnings("deprecation")
118     URL url = getCurrentBJSTemplateFile().toURL();
119     if (url != null)
120     {
121       try
122       {
123         isReader = new InputStreamReader(url.openStream());
124         buffReader = new BufferedReader(isReader);
125         String line;
126         String lineSeparator = System.getProperty("line.separator");
127         while ((line = buffReader.readLine()) != null)
128         {
129           sb.append(line).append(lineSeparator);
130         }
131
132       } catch (Exception ex)
133       {
134         ex.printStackTrace();
135       } finally
136       {
137         if (isReader != null)
138         {
139           isReader.close();
140         }
141
142         if (buffReader != null)
143         {
144           buffReader.close();
145         }
146       }
147     }
148     return sb.toString();
149   }
150
151   public void refreshBioJSVersionsInfo(String dirName)
152           throws URISyntaxException
153   {
154     File directory = new File(BJS_TEMPLATES_LOCAL_DIRECTORY);
155     Objects.requireNonNull(dirName, "dirName MUST not be null!");
156     Objects.requireNonNull(directory, "directory MUST not be null!");
157     TreeMap<String, File> versionFileMap = new TreeMap<String, File>();
158
159     for (File file : directory.listFiles())
160     {
161       if (file.isFile())
162       {
163         String fileName = file.getName().substring(0,
164                 file.getName().lastIndexOf("."));
165         String fileMeta[] = fileName.split("_");
166         if (fileMeta.length > 2)
167         {
168           setCurrentBJSTemplateFile(file);
169           versionFileMap.put(fileMeta[2], file);
170         }
171         else if (fileMeta.length > 1)
172         {
173           versionFileMap.put(fileMeta[1], file);
174         }
175       }
176     }
177     if (getCurrentBJSTemplateFile() == null && versionFileMap.size() > 0)
178     {
179       setCurrentBJSTemplateFile(versionFileMap.lastEntry().getValue());
180     }
181     setBioJsMSAVersions(versionFileMap);
182   }
183
184   public void updateBioJS()
185   {
186     Thread updateThread = new Thread()
187     {
188       public void run()
189       {
190         try
191         {
192           String gitRepoPkgJson = getURLContentAsString(BJS_TEMPLATE_GIT_REPO);
193           BioJSRepositoryPojo release = new BioJSRepositoryPojo(
194                   gitRepoPkgJson);
195           syncUpdates(BJS_TEMPLATES_LOCAL_DIRECTORY, release);
196           refreshBioJSVersionsInfo(BJS_TEMPLATES_LOCAL_DIRECTORY);
197         } catch (URISyntaxException e)
198         {
199           e.printStackTrace();
200         }
201       }
202     };
203     updateThread.start();
204
205   }
206
207
208   public void syncUpdates(String localDir, BioJSRepositoryPojo repo)
209   {
210     for (BioJSReleasePojo bjsRelease : repo.getReleases())
211     {
212       String releaseUrl = bjsRelease.getUrl();
213       String releaseVersion = bjsRelease.getVersion();
214       String releaseFile = "BioJsMSA_" + releaseVersion + ".txt";
215       if (releaseVersion.equals(repo.getLatestReleaseVersion()))
216       {
217         releaseFile = "Latest_BioJsMSA_" + releaseVersion + ".txt";
218       }
219
220       File biojsDirectory = new File(BJS_TEMPLATES_LOCAL_DIRECTORY);
221       if (!biojsDirectory.exists())
222       {
223         if (!biojsDirectory.mkdirs())
224         {
225           System.out.println("Couldn't create local directory : "
226                   + BJS_TEMPLATES_LOCAL_DIRECTORY);
227           return;
228         }
229       }
230
231       File file = new File(BJS_TEMPLATES_LOCAL_DIRECTORY + releaseFile);
232       if (!file.exists())
233       {
234
235         PrintWriter out = null;
236         try
237         {
238           out = new java.io.PrintWriter(new java.io.FileWriter(file));
239           out.print(getURLContentAsString(releaseUrl));
240         } catch (IOException e)
241         {
242           e.printStackTrace();
243         } finally
244         {
245           if (out != null)
246           {
247             out.flush();
248             out.close();
249           }
250         }
251       }
252     }
253
254   }
255
256   public static String getURLContentAsString(String url)
257           throws OutOfMemoryError
258   {
259     StringBuilder responseStrBuilder = null;
260     InputStream is = null;
261     try
262     {
263       URL resourceUrl = new URL(url);
264       is = new BufferedInputStream(resourceUrl.openStream());
265       BufferedReader br = new BufferedReader(new InputStreamReader(is));
266       responseStrBuilder = new StringBuilder();
267       String lineContent;
268
269       while ((lineContent = br.readLine()) != null)
270       {
271         responseStrBuilder.append(lineContent).append("\n");
272       }
273     } catch (OutOfMemoryError er)
274     {
275       er.printStackTrace();
276     } catch (Exception ex)
277     {
278       ex.printStackTrace();
279     } finally
280     {
281       if (is != null)
282       {
283         try
284         {
285           is.close();
286         } catch (IOException e)
287         {
288           e.printStackTrace();
289         }
290       }
291     }
292     return responseStrBuilder == null ? null : responseStrBuilder
293             .toString();
294   }
295
296   public static File getCurrentBJSTemplateFile()
297   {
298     return currentBJSTemplateFile;
299   }
300
301   public static void setCurrentBJSTemplateFile(File currentBJSTemplateFile)
302   {
303     BioJsHTMLOutput.currentBJSTemplateFile = currentBJSTemplateFile;
304   }
305
306   public static TreeMap<String, File> getBioJsMSAVersions()
307   {
308     return bioJsMSAVersions;
309   }
310
311   public static void setBioJsMSAVersions(
312           TreeMap<String, File> bioJsMSAVersions)
313   {
314     BioJsHTMLOutput.bioJsMSAVersions = bioJsMSAVersions;
315   }
316
317 }