/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.test.failurehandler;
import java.io.FilterWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class HtmlSection {
protected final HtmlSection rootSection;
protected final String id;
protected final String name;
public PrintWriter getWriter() {
return textWriter;
}
protected final PrintWriter pw;
protected final PrintWriter textWriter;
protected boolean closed;
private HtmlSection child;
public HtmlSection(PrintWriter pw) {
this(pw, "", null, null);
}
private HtmlSection(PrintWriter pw, String id, String name, HtmlSection rootSection) {
this.pw = pw;
textWriter = new PrintWriter(new HtmlFilterWriter(pw), true);
this.id = id;
this.name = name;
child = null;
// main
if (rootSection == null) {
this.rootSection = this;
this.pw.println("<html>");
this.pw.println("<style>\n"
+ "div { display:none;}\n"
+ "</style>\n"
+ "\n"
+ "<script>\n"
+ "function show(e) {\n"
+ " while (e != null) {\n"
+ " if (e.tagName == 'DIV') {\n"
+ " e.style.display = 'block';\n"
+ " }\n"
+ " e = e.parentNode;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ "function toggle(id) {\n"
+ " e = document.getElementById(id);\n"
+ " d = e.style.display;\n"
+ " if (d == 'block') {\n"
+ " e.style.display = 'none';\n"
+ " } else {\n"
+ " show(e);\n"
+ " }\n"
+ "}\n"
+ "\n"
+ "function main() {\n"
+ " index = location.href.indexOf(\"#\");"
+ " if (index != -1) {\n"
+ " show(document.getElementById(location.href.substring(index + 1)));\n"
+ " }\n"
+ "}\n"
+ "\n"
+ "</script>\n"
+ "</head>");
this.pw.println("<body onload='main()'>");
} else {
this.rootSection = rootSection;
this.pw.print("<ul>");
}
}
public HtmlSection createChildren(String section) {
if (child != null) {
if (child.name.equals(section)) {
return child;
}
child.close();
}
child = new SubSection(this, section, rootSection);
return child;
}
protected final void removeChild(HtmlSection child) {
if (this.child == child) {
this.child = null;
}
}
public void close() {
closeChild();
if (closed) {
return;
}
closed = true;
if (rootSection == this) {
pw.println("</body>");
pw.println("</html>");
pw.close();
} else {
pw.println("</ul>");
}
}
protected final void closeChild() {
if (child != null) {
child.close();
child = null;
}
}
public void link(HtmlSection section, String child, String name) {
String path = section.id;
if (path.isEmpty()) {
path = child;
} else if (child != null) {
path = String.format("%s.%s", path, child);
}
pw.printf("<a href=\"#%1$s\" onclick=\"show(document.getElementById('%1$s')); return true;\">%2$s</a>%n",
path, name);
}
public HtmlSection createChildren(String[] sections) {
int i = 0;
int n = sections.length;
HtmlSection current = rootSection;
if (current != null) {
for (; i < n && current.child != null;
++i, current = current.child) {
if (!sections[i].equals(current.child.name)) {
break;
}
}
}
for (; i < n; ++i) {
current = current.createChildren(sections[i]);
}
return current;
}
private static class SubSection extends HtmlSection {
private final HtmlSection parent;
public SubSection(HtmlSection parent, String name,
HtmlSection rootSection) {
super(parent.pw,
parent.id.isEmpty()
? name
: String.format("%s.%s", parent.id, name),
name, rootSection);
this.parent = parent;
pw.printf("<li><a name='%1$s'/><a href='#%1$s' onclick=\"toggle('%1$s'); return false;\">%2$s</a><div id='%1$s'><code><pre>",
id, name);
}
@Override
public void close() {
closeChild();
if (closed) {
return;
}
pw.print("</pre></code></div></li><!-- " + id + "-->");
parent.removeChild(this);
super.close();
}
}
private static class HtmlFilterWriter extends FilterWriter {
public HtmlFilterWriter(PrintWriter pw) {
super(pw);
}
@Override
public void write(int c) throws IOException {
switch (c) {
case '<':
super.write("<", 0, 4);
break;
case '>':
super.write(">", 0, 4);
break;
case '"':
super.write(""", 0, 5);
break;
case '&':
super.write("&", 0, 4);
break;
default:
super.write(c);
}
}
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
for (int i = off; i < len; ++i){
write(cbuf[i]);
}
}
@Override
public void write(String str, int off, int len) throws IOException {
for (int i = off; i < len; ++i){
write(str.charAt(i));
}
}
}
}