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