JAL-1233 JAL-1576 copy constructor to propagate helix colours and applyTo implementat...
[jalview.git] / src / jalview / io / BioJsHTMLOutput.java
1 package jalview.io;
2
3 import jalview.api.AlignExportSettingI;
4 import jalview.api.AlignmentViewPanel;
5 import jalview.datamodel.AlignmentExportData;
6 import jalview.exceptions.NoFileSelectedException;
7 import jalview.json.binding.biojs.BioJSReleasePojo;
8 import jalview.json.binding.biojs.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 AlignmentViewPanel ap;
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/jalview/exporter-templates/master/biojs/package.json");
42
43   public BioJsHTMLOutput(AlignmentViewPanel ap)
44   {
45     if (ap != null)
46     {
47       this.ap = ap;
48     }
49   }
50
51   public void exportJalviewAlignmentAsBioJsHtmlFile()
52   {
53     try
54     {
55       String outputFile = getOutputFile();
56       // String jalviewAlignmentJson = JSONFile.getJSONData(ap);
57       AlignExportSettingI exportSettings = new AlignExportSettingI()
58       {
59         @Override
60         public boolean isExportHiddenSequences()
61         {
62           return true;
63         }
64
65         @Override
66         public boolean isExportHiddenColumns()
67         {
68           return true;
69         }
70
71         @Override
72         public boolean isExportAnnotations()
73         {
74           return true;
75         }
76
77         @Override
78         public boolean isExportFeatures()
79         {
80           return true;
81         }
82
83         @Override
84         public boolean isExportGroups()
85         {
86           return true;
87         }
88
89         @Override
90         public boolean isCancelled()
91         {
92           return false;
93         }
94
95       };
96       AlignmentExportData exportData = jalview.gui.AlignFrame
97               .getAlignmentForExport(
98 JSONFile.FILE_DESC,
99                       ap.getAlignViewport(), exportSettings);
100       if (exportData.getSettings().isCancelled())
101       {
102         return;
103       }
104       String jalviewAlignmentJson = new FormatAdapter(ap,
105               exportData.getSettings()).formatSequences(JSONFile.FILE_DESC,
106               exportData.getAlignment(), exportData.getOmitHidden(),
107               exportData.getStartEndPostions(), ap.getAlignViewport()
108                       .getColumnSelection());
109
110       String bioJSTemplateString = getBioJsTemplateAsString();
111       String generatedBioJsWithJalviewAlignmentAsJson = bioJSTemplateString
112               .replaceAll(
113 "#sequenceData#", jalviewAlignmentJson)
114               .toString();
115
116       PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(
117               outputFile));
118       out.print(generatedBioJsWithJalviewAlignmentAsJson);
119       out.flush();
120       out.close();
121       jalview.util.BrowserLauncher.openURL("file:///" + outputFile);
122     } catch (NoFileSelectedException ex)
123     {
124       // do noting if no file was selected
125     } catch (Exception e)
126     {
127       e.printStackTrace();
128     }
129   }
130
131   public String getOutputFile() throws NoFileSelectedException
132   {
133     String selectedFile = null;
134     JalviewFileChooser jvFileChooser = new JalviewFileChooser(
135             jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
136             { "html" }, new String[]
137             { "HTML files" }, "HTML files");
138     jvFileChooser.setFileView(new JalviewFileView());
139
140     jvFileChooser.setDialogTitle(MessageManager
141             .getString("label.save_as_biojs_html"));
142     jvFileChooser.setToolTipText(MessageManager.getString("action.save"));
143
144     int fileChooserOpt = jvFileChooser.showSaveDialog(null);
145     if (fileChooserOpt == JalviewFileChooser.APPROVE_OPTION)
146     {
147       jalview.bin.Cache.setProperty("LAST_DIRECTORY", jvFileChooser
148               .getSelectedFile().getParent());
149       selectedFile = jvFileChooser.getSelectedFile().getPath();
150     }
151     else
152     {
153       throw new NoFileSelectedException("No file was selected.");
154     }
155     return selectedFile;
156   }
157
158
159   public static String getBioJsTemplateAsString()
160           throws IOException
161   {
162     InputStreamReader isReader = null;
163     BufferedReader buffReader = null;
164     StringBuilder sb = new StringBuilder();
165     Objects.requireNonNull(getCurrentBJSTemplateFile(),
166             "BioJsTemplate File not initialized!");
167     @SuppressWarnings("deprecation")
168     URL url = getCurrentBJSTemplateFile().toURL();
169     if (url != null)
170     {
171       try
172       {
173         isReader = new InputStreamReader(url.openStream());
174         buffReader = new BufferedReader(isReader);
175         String line;
176         String lineSeparator = System.getProperty("line.separator");
177         while ((line = buffReader.readLine()) != null)
178         {
179           sb.append(line).append(lineSeparator);
180         }
181
182       } catch (Exception ex)
183       {
184         ex.printStackTrace();
185       } finally
186       {
187         if (isReader != null)
188         {
189           isReader.close();
190         }
191
192         if (buffReader != null)
193         {
194           buffReader.close();
195         }
196       }
197     }
198     return sb.toString();
199   }
200
201   public static void refreshBioJSVersionsInfo(String dirName)
202           throws URISyntaxException
203   {
204     File directory = new File(BJS_TEMPLATES_LOCAL_DIRECTORY);
205     Objects.requireNonNull(dirName, "dirName MUST not be null!");
206     Objects.requireNonNull(directory, "directory MUST not be null!");
207     TreeMap<String, File> versionFileMap = new TreeMap<String, File>();
208
209     for (File file : directory.listFiles())
210     {
211       if (file.isFile())
212       {
213         String fileName = file.getName().substring(0,
214                 file.getName().lastIndexOf("."));
215         String fileMeta[] = fileName.split("_");
216         if (fileMeta.length > 2)
217         {
218           setCurrentBJSTemplateFile(file);
219           versionFileMap.put(fileMeta[2], file);
220         }
221         else if (fileMeta.length > 1)
222         {
223           versionFileMap.put(fileMeta[1], file);
224         }
225       }
226     }
227     if (getCurrentBJSTemplateFile() == null && versionFileMap.size() > 0)
228     {
229       setCurrentBJSTemplateFile(versionFileMap.lastEntry().getValue());
230     }
231     setBioJsMSAVersions(versionFileMap);
232   }
233
234   public static void updateBioJS()
235   {
236     Thread updateThread = new Thread()
237     {
238       public void run()
239       {
240         try
241         {
242           String gitRepoPkgJson = getURLContentAsString(BJS_TEMPLATE_GIT_REPO);
243           if (gitRepoPkgJson != null)
244           {
245             BioJSRepositoryPojo release = new BioJSRepositoryPojo(
246                     gitRepoPkgJson);
247             syncUpdates(BJS_TEMPLATES_LOCAL_DIRECTORY, release);
248             refreshBioJSVersionsInfo(BJS_TEMPLATES_LOCAL_DIRECTORY);
249           }
250         } catch (URISyntaxException e)
251         {
252           e.printStackTrace();
253         }
254       }
255     };
256     updateThread.start();
257
258   }
259
260
261   public static void syncUpdates(String localDir, BioJSRepositoryPojo repo)
262   {
263     for (BioJSReleasePojo bjsRelease : repo.getReleases())
264     {
265       String releaseUrl = bjsRelease.getUrl();
266       String releaseVersion = bjsRelease.getVersion();
267       String releaseFile = "BioJsMSA_" + releaseVersion + ".txt";
268       if (releaseVersion.equals(repo.getLatestReleaseVersion()))
269       {
270         releaseFile = "Latest_BioJsMSA_" + releaseVersion + ".txt";
271       }
272
273       File biojsDirectory = new File(BJS_TEMPLATES_LOCAL_DIRECTORY);
274       if (!biojsDirectory.exists())
275       {
276         if (!biojsDirectory.mkdirs())
277         {
278           System.out.println("Couldn't create local directory : "
279                   + BJS_TEMPLATES_LOCAL_DIRECTORY);
280           return;
281         }
282       }
283
284       File file = new File(BJS_TEMPLATES_LOCAL_DIRECTORY + releaseFile);
285       if (!file.exists())
286       {
287
288         PrintWriter out = null;
289         try
290         {
291           out = new java.io.PrintWriter(new java.io.FileWriter(file));
292           out.print(getURLContentAsString(releaseUrl));
293         } catch (IOException e)
294         {
295           e.printStackTrace();
296         } finally
297         {
298           if (out != null)
299           {
300             out.flush();
301             out.close();
302           }
303         }
304       }
305     }
306
307   }
308
309   public static String getURLContentAsString(String url)
310           throws OutOfMemoryError
311   {
312     StringBuilder responseStrBuilder = null;
313     InputStream is = null;
314     try
315     {
316       URL resourceUrl = new URL(url);
317       is = new BufferedInputStream(resourceUrl.openStream());
318       BufferedReader br = new BufferedReader(new InputStreamReader(is));
319       responseStrBuilder = new StringBuilder();
320       String lineContent;
321
322       while ((lineContent = br.readLine()) != null)
323       {
324         responseStrBuilder.append(lineContent).append("\n");
325       }
326     } catch (OutOfMemoryError er)
327     {
328       er.printStackTrace();
329     } catch (Exception ex)
330     {
331       ex.printStackTrace();
332     } finally
333     {
334       if (is != null)
335       {
336         try
337         {
338           is.close();
339         } catch (IOException e)
340         {
341           e.printStackTrace();
342         }
343       }
344     }
345     return responseStrBuilder == null ? null : responseStrBuilder
346             .toString();
347   }
348
349   public static File getCurrentBJSTemplateFile()
350   {
351     return currentBJSTemplateFile;
352   }
353
354   public static void setCurrentBJSTemplateFile(File currentBJSTemplateFile)
355   {
356     BioJsHTMLOutput.currentBJSTemplateFile = currentBJSTemplateFile;
357   }
358
359   public static TreeMap<String, File> getBioJsMSAVersions()
360   {
361     return bioJsMSAVersions;
362   }
363
364   public static void setBioJsMSAVersions(
365           TreeMap<String, File> bioJsMSAVersions)
366   {
367     BioJsHTMLOutput.bioJsMSAVersions = bioJsMSAVersions;
368   }
369
370 }