--- /dev/null
+package org.simantics.document.linking.report.html;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.io.PrintStream;\r
+import java.net.URL;\r
+import java.net.URLDecoder;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.eclipse.core.runtime.FileLocator;\r
+import org.eclipse.core.runtime.Path;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.osgi.framework.Bundle;\r
+import org.simantics.document.linking.Activator;\r
+import org.simantics.document.linking.report.Document;\r
+import org.simantics.document.linking.report.DocumentElement;\r
+import org.simantics.document.linking.report.DocumentItem;\r
+import org.simantics.document.linking.report.DocumentTitlePage;\r
+import org.simantics.document.linking.report.Table;\r
+import org.simantics.document.linking.report.TableOfContents;\r
+import org.simantics.document.linking.report.TextItem;\r
+import org.simantics.document.linking.report.URLItem;\r
+import org.simantics.document.linking.report.base.TextItemImpl;\r
+import org.simantics.utils.datastructures.Arrays;\r
+\r
+\r
+/**\r
+ * HTML format reporter.\r
+ * \r
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
+ *\r
+ */\r
+public class HTMLDocument extends HTMLStreamElement implements Document {\r
+ \r
+ \r
+ boolean referCSS = false; // if true, generated report refers to bas css in the plug-in. Otherwise the base css's contents are copied to report file.\r
+ \r
+ int currentPage = 0;\r
+ int currentLine = 1;\r
+\r
+ HTMLStreamElement content;\r
+ \r
+ private Map<Class<? extends HTMLElement>, Integer> uniqueIndex = new HashMap<Class<? extends HTMLElement>, Integer>();\r
+ \r
+ \r
+ @Override\r
+ public String getId() {\r
+ return null;\r
+ }\r
+ \r
+ public HTMLDocument(File file) throws Exception {\r
+ super(file);\r
+ content = new HTMLStreamElement(this);\r
+ }\r
+ \r
+ String getUniqueId(Class<? extends HTMLElement> cls) {\r
+ Integer index = uniqueIndex.get(cls);\r
+ if (index == null)\r
+ index = 1;\r
+ else\r
+ index = index + 1;\r
+ uniqueIndex.put(cls,index);\r
+ \r
+ return cls.getSimpleName() +"_"+index;\r
+ }\r
+ String getUniqueId(HTMLElement element) {\r
+ Class<? extends HTMLElement> cls = element.getClass();\r
+ return getUniqueId(cls);\r
+ }\r
+ \r
+ private static String getDataUrl() throws IOException {\r
+ Bundle b = Platform.getBundle(Activator.PLUGIN_ID);\r
+ URL dataUrl = FileLocator.find(b, new Path("report"), null);\r
+ URL fileUrl = FileLocator.toFileURL(dataUrl);\r
+ return URLDecoder.decode(fileUrl.getPath(), "UTF-8"); \r
+ }\r
+ \r
+ private void copyBaseCSS(String cssUrl) throws Exception {\r
+ File f = new File(URLDecoder.decode(cssUrl, "UTF-8")).getAbsoluteFile();\r
+ copyData(f, os);\r
+ }\r
+\r
+ \r
+ private void header() throws Exception {\r
+ PrintStream resultOs = os;\r
+ String cssUrl = getDataUrl() +"/report.css";\r
+ resultOs.println("<!DOCTYPE html>");\r
+ resultOs.println("<html lang=\"en\">");\r
+ resultOs.println("<head>");\r
+ resultOs.println(" <meta charset=\"utf-8\">");\r
+ resultOs.println(" <title>Report</title>");\r
+ if (referCSS)\r
+ resultOs.println(" <link rel=\"stylesheet\" href=\"" + cssUrl + "\" type=\"text/css\">");\r
+ resultOs.println(" <style>");\r
+ if (!referCSS) {\r
+ copyBaseCSS(cssUrl);\r
+ }\r
+ \r
+ resultOs.println(" </style>");\r
+ resultOs.println("</head>");\r
+ resultOs.println("<body>");\r
+ }\r
+\r
+ private void footer() throws Exception{\r
+ if (currentTable != null)\r
+ currentTable.endTable();\r
+ if (toc != null)\r
+ toc.close();\r
+ content.close();\r
+ PrintStream resultOs = os;\r
+ resultOs.println("</body>");\r
+ resultOs.println("</html>");\r
+ }\r
+ \r
+ @Override\r
+ public void close() throws Exception {\r
+ footer();\r
+ super.close();\r
+ }\r
+ \r
+\r
+ @Override\r
+ public int getCurrentLine() {\r
+ return currentLine;\r
+ }\r
+ \r
+ @Override\r
+ public int getAvailableLines() {\r
+ return Integer.MAX_VALUE;\r
+ }\r
+ \r
+ @Override\r
+ public void nextPage() throws Exception {\r
+ if (currentPage == 0)\r
+ header(); \r
+ currentPage++;\r
+ currentLine = 1;\r
+ }\r
+ \r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public <T extends DocumentElement> T newElement(Class<T> cls,String...options) throws Exception {\r
+ if (cls == Table.class) {\r
+ return (T)newTable(Arrays.contains(options, Document.TOC));\r
+ } else if (cls == TableOfContents.class) {\r
+ return (T)getOrCreateToc();\r
+ } else if (cls == DocumentTitlePage.class) {\r
+ if (titlePage != null)\r
+ throw new Exception("Document many have only one title page");\r
+ titlePage = new HTMLTitlePage(this);\r
+ return (T)titlePage;\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public <T extends DocumentElement> T nextElement(Class<T> cls,String...options) throws Exception {\r
+ if (cls == Table.class) {\r
+ return (T)nextTable(Arrays.contains(options, Document.TOC));\r
+ } else if (cls == TableOfContents.class) {\r
+ return (T)getOrCreateToc();\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public <T extends DocumentElement> T getCurrentElement(Class<T> cls) {\r
+ if (cls == Table.class) {\r
+ return (T)getCurrentTable();\r
+ } else if (cls == TableOfContents.class) {\r
+ return (T)toc;\r
+ } else if (cls == DocumentTitlePage.class) {\r
+ return (T)titlePage;\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public <T extends DocumentItem> T newItem(Class<T> cls, String... options)\r
+ throws Exception {\r
+ if (cls == TextItem.class)\r
+ return (T)new TextItemImpl();\r
+ if (cls == URLItem.class)\r
+ return (T)new HTMLURLItemImpl();\r
+ return null;\r
+ }\r
+ \r
+ private HTMLTable currentTable;\r
+ \r
+ \r
+ public Table nextTable(boolean id) throws Exception {\r
+ if (currentTable != null) {\r
+ currentTable.endTable();\r
+ currentTable = new HTMLTable(currentTable,id);\r
+ return currentTable;\r
+ } else {\r
+ return currentTable;\r
+ }\r
+ \r
+ }\r
+ \r
+ \r
+ public Table newTable(boolean id) throws Exception {\r
+ if (currentTable != null) {\r
+ currentTable.endTable();\r
+ }\r
+ currentTable = new HTMLTable(this,content.os,id);\r
+ return currentTable;\r
+ }\r
+ \r
+ \r
+ public Table getCurrentTable() {\r
+ return currentTable;\r
+ }\r
+ \r
+ HTMLTocElement toc;\r
+ \r
+ public TableOfContents getOrCreateToc() throws Exception{\r
+ if (toc == null) {\r
+ toc = new HTMLTocElement(this);\r
+ }\r
+ return toc;\r
+ }\r
+ \r
+ HTMLTitlePage titlePage;\r
+\r
+}\r