a422a38f0d48d96c98a16fabf1699b0376963643
[jalview.git] / src / jalview / io / HTMLOutput.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.api.AlignExportSettingI;
24 import jalview.datamodel.AlignmentExportData;
25 import jalview.exceptions.NoFileSelectedException;
26 import jalview.gui.AlignmentPanel;
27 import jalview.gui.IProgressIndicator;
28 import jalview.util.MessageManager;
29
30 import java.io.BufferedReader;
31 import java.io.File;
32 import java.io.IOException;
33 import java.io.InputStreamReader;
34 import java.net.URL;
35 import java.util.Objects;
36
37
38 public abstract class HTMLOutput
39 {
40   protected AlignmentPanel ap;
41
42   protected long pSessionId;
43
44   protected IProgressIndicator pIndicator;
45
46   protected File generatedFile;
47
48   public HTMLOutput(AlignmentPanel ap)
49   {
50     if (ap != null)
51     {
52       this.ap = ap;
53       this.pIndicator = ap.alignFrame;
54     }
55   }
56
57
58   public String getBioJSONData()
59   {
60     if (!isEmbedData())
61     {
62       return null;
63     }
64     AlignExportSettingI exportSettings = new AlignExportSettingI()
65     {
66       @Override
67       public boolean isExportHiddenSequences()
68       {
69         return true;
70       }
71
72       @Override
73       public boolean isExportHiddenColumns()
74       {
75         return true;
76       }
77
78       @Override
79       public boolean isExportAnnotations()
80       {
81         return true;
82       }
83
84       @Override
85       public boolean isExportFeatures()
86       {
87         return true;
88       }
89
90       @Override
91       public boolean isExportGroups()
92       {
93         return true;
94       }
95
96       @Override
97       public boolean isCancelled()
98       {
99         return false;
100       }
101
102     };
103     AlignmentExportData exportData = jalview.gui.AlignFrame
104             .getAlignmentForExport(JSONFile.FILE_DESC,
105                     ap.getAlignViewport(), exportSettings);
106     String bioJSON = new FormatAdapter(ap, exportData.getSettings())
107             .formatSequences(JSONFile.FILE_DESC, exportData.getAlignment(),
108                     exportData.getOmitHidden(), exportData
109                             .getStartEndPostions(), ap.getAlignViewport()
110                             .getColumnSelection());
111     return bioJSON;
112   }
113
114   /**
115    * Read a template file content as string
116    * 
117    * @param file
118    *          - the file to be read
119    * @return File content as String
120    * @throws IOException
121    */
122   public static String readFileAsString(File file) throws IOException
123   {
124     InputStreamReader isReader = null;
125     BufferedReader buffReader = null;
126     StringBuilder sb = new StringBuilder();
127     Objects.requireNonNull(file, "File must not be null!");
128     @SuppressWarnings("deprecation")
129     URL url = file.toURL();
130     if (url != null)
131     {
132       try
133       {
134         isReader = new InputStreamReader(url.openStream());
135         buffReader = new BufferedReader(isReader);
136         String line;
137         String lineSeparator = System.getProperty("line.separator");
138         while ((line = buffReader.readLine()) != null)
139         {
140           sb.append(line).append(lineSeparator);
141         }
142   
143       } catch (Exception ex)
144       {
145         ex.printStackTrace();
146       } finally
147       {
148         if (isReader != null)
149         {
150           isReader.close();
151         }
152   
153         if (buffReader != null)
154         {
155           buffReader.close();
156         }
157       }
158     }
159     return sb.toString();
160   }
161
162   public static String getImageMapHTML()
163   {
164     return new String(
165             "<html>\n"
166                     + "<head>\n"
167                     + "<script language=\"JavaScript\">\n"
168                     + "var ns4 = document.layers;\n"
169                     + "var ns6 = document.getElementById && !document.all;\n"
170                     + "var ie4 = document.all;\n"
171                     + "offsetX = 0;\n"
172                     + "offsetY = 20;\n"
173                     + "var toolTipSTYLE=\"\";\n"
174                     + "function initToolTips()\n"
175                     + "{\n"
176                     + "  if(ns4||ns6||ie4)\n"
177                     + "  {\n"
178                     + "    if(ns4) toolTipSTYLE = document.toolTipLayer;\n"
179                     + "    else if(ns6) toolTipSTYLE = document.getElementById(\"toolTipLayer\").style;\n"
180                     + "    else if(ie4) toolTipSTYLE = document.all.toolTipLayer.style;\n"
181                     + "    if(ns4) document.captureEvents(Event.MOUSEMOVE);\n"
182                     + "    else\n"
183                     + "    {\n"
184                     + "      toolTipSTYLE.visibility = \"visible\";\n"
185                     + "      toolTipSTYLE.display = \"none\";\n"
186                     + "    }\n"
187                     + "    document.onmousemove = moveToMouseLoc;\n"
188                     + "  }\n"
189                     + "}\n"
190                     + "function toolTip(msg, fg, bg)\n"
191                     + "{\n"
192                     + "  if(toolTip.arguments.length < 1) // hide\n"
193                     + "  {\n"
194                     + "    if(ns4) toolTipSTYLE.visibility = \"hidden\";\n"
195                     + "    else toolTipSTYLE.display = \"none\";\n"
196                     + "  }\n"
197                     + "  else // show\n"
198                     + "  {\n"
199                     + "    if(!fg) fg = \"#555555\";\n"
200                     + "    if(!bg) bg = \"#FFFFFF\";\n"
201                     + "    var content =\n"
202                     + "    '<table border=\"0\" cellspacing=\"0\" cellpadding=\"1\" bgcolor=\"' + fg + '\"><td>' +\n"
203                     + "    '<table border=\"0\" cellspacing=\"0\" cellpadding=\"1\" bgcolor=\"' + bg + \n"
204                     + "    '\"><td align=\"center\"><font face=\"sans-serif\" color=\"' + fg +\n"
205                     + "    '\" size=\"-2\">&nbsp;' + msg +\n"
206                     + "    '&nbsp;</font></td></table></td></table>';\n"
207                     + "    if(ns4)\n"
208                     + "    {\n"
209                     + "      toolTipSTYLE.document.write(content);\n"
210                     + "      toolTipSTYLE.document.close();\n"
211                     + "      toolTipSTYLE.visibility = \"visible\";\n"
212                     + "    }\n"
213                     + "    if(ns6)\n"
214                     + "    {\n"
215                     + "      document.getElementById(\"toolTipLayer\").innerHTML = content;\n"
216                     + "      toolTipSTYLE.display='block'\n"
217                     + "    }\n"
218                     + "    if(ie4)\n"
219                     + "    {\n"
220                     + "      document.all(\"toolTipLayer\").innerHTML=content;\n"
221                     + "      toolTipSTYLE.display='block'\n"
222                     + "    }\n"
223                     + "  }\n"
224                     + "}\n"
225                     + "function moveToMouseLoc(e)\n"
226                     + "{\n"
227                     + "  if(ns4||ns6)\n"
228                     + "  {\n"
229                     + "    x = e.pageX;\n"
230                     + "    y = e.pageY;\n"
231                     + "  }\n"
232                     + "  else\n"
233                     + "  {\n"
234                     + "    x = event.x + document.body.scrollLeft;\n"
235                     + "    y = event.y + document.body.scrollTop;\n"
236                     + "  }\n"
237                     + "  toolTipSTYLE.left = x + offsetX;\n"
238                     + "  toolTipSTYLE.top = y + offsetY;\n"
239                     + "  return true;\n"
240                     + "}\n"
241                     + "</script>\n"
242                     + "</head>\n"
243                     + "<body>\n"
244                     + "<div id=\"toolTipLayer\" style=\"position:absolute; visibility: hidden\"></div>\n"
245                     + "<script language=\"JavaScript\"><!--\n"
246                     + "initToolTips(); //--></script>\n");
247
248   }
249
250   public String getOutputFile() throws NoFileSelectedException
251   {
252     String selectedFile = null;
253     if (pIndicator != null && !isHeadless())
254     {
255       pIndicator.setProgressBar(MessageManager.formatMessage(
256               "status.waiting_for_user_to_select_output_file", "HTML"),
257               pSessionId);
258     }
259
260     JalviewFileChooser jvFileChooser = new JalviewFileChooser(
261             jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
262             new String[] { "html" }, new String[] { "HTML files" },
263             "HTML files");
264     jvFileChooser.setFileView(new JalviewFileView());
265
266     jvFileChooser.setDialogTitle(MessageManager
267             .getString("label.save_as_biojs_html"));
268     jvFileChooser.setToolTipText(MessageManager.getString("action.save"));
269
270     int fileChooserOpt = jvFileChooser.showSaveDialog(null);
271     if (fileChooserOpt == JalviewFileChooser.APPROVE_OPTION)
272     {
273       jalview.bin.Cache.setProperty("LAST_DIRECTORY", jvFileChooser
274               .getSelectedFile().getParent());
275       selectedFile = jvFileChooser.getSelectedFile().getPath();
276     }
277     else
278     {
279       pIndicator.setProgressBar(MessageManager.formatMessage(
280               "status.cancelled_image_export_operation", "BioJS"),
281               pSessionId);
282       throw new NoFileSelectedException("No file was selected.");
283     }
284     return selectedFile;
285   }
286
287   protected void setProgressMessage(String message)
288   {
289     if (pIndicator != null && !isHeadless())
290     {
291       pIndicator.setProgressBar(message, pSessionId);
292     }
293     else
294     {
295       System.out.println(message);
296     }
297   }
298
299   /**
300    * Answers true if HTML export is invoke in headless mode or false otherwise
301    * 
302    * @return
303    */
304   protected boolean isHeadless()
305   {
306     return System.getProperty("java.awt.headless") != null
307             && System.getProperty("java.awt.headless").equals("true");
308   }
309
310   /**
311    * This method provides implementation of consistent behaviour which should
312    * occur before a HTML file export. It MUST be called at the start of the
313    * exportHTML() method implementation.
314    */
315   protected void exportStarted()
316   {
317     pSessionId = System.currentTimeMillis();
318   }
319
320   /**
321    * This method provides implementation of consistent behaviour which should
322    * occur after a HTML file export. It MUST be called at the end of the
323    * exportHTML() method implementation.
324    */
325   protected void exportCompleted()
326   {
327     if (isLaunchInBrowserAfterExport() && !isHeadless())
328     {
329       try
330       {
331         jalview.util.BrowserLauncher
332                 .openURL("file:///" + getExportedFile());
333       } catch (IOException e)
334       {
335         e.printStackTrace();
336       }
337     }
338   }
339
340   /**
341    * if this answers true then BioJSON data will be embedded to the exported
342    * HTML file otherwise it won't be embedded.
343    * 
344    * @return
345    */
346   public abstract boolean isEmbedData();
347
348   /**
349    * if this answers true then the generated HTML file is opened for viewing in
350    * a browser after its generation otherwise it won't be opened in a browser
351    * 
352    * @return
353    */
354   public abstract boolean isLaunchInBrowserAfterExport();
355
356   /**
357    * handle to the generated HTML file
358    * 
359    * @return
360    */
361   public abstract File getExportedFile();
362
363   /**
364    * This is the main method to handle the HTML generation.
365    * 
366    * @param outputFile
367    *          the file path of the generated HTML
368    */
369   public abstract void exportHTML(String outputFile);
370 }