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