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