1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package jdk.test.failurehandler; 25 26 import java.io.FilterWriter; 27 import java.io.IOException; 28 import java.io.PrintWriter; 29 30 public class HtmlSection { 31 protected final HtmlSection rootSection; 32 protected final String id; 33 protected final String name; 34 35 public PrintWriter getWriter() { 36 return textWriter; 37 } 38 39 protected final PrintWriter pw; 40 protected final PrintWriter textWriter; 41 protected boolean closed; 42 43 private HtmlSection child; 44 45 46 public HtmlSection(PrintWriter pw) { 47 this(pw, "", null, null); 48 } 49 50 private HtmlSection(PrintWriter pw, String id, String name, HtmlSection rootSection) { 51 this.pw = pw; 52 textWriter = new PrintWriter(new HtmlFilterWriter(pw)); 53 this.id = id; 54 this.name = name; 55 child = null; 56 // main 57 if (rootSection == null) { 58 this.rootSection = this; 59 this.pw.println("<html>"); 60 this.pw.println("<style>\n" 61 + "div { display:none;}\n" 62 + "</style>\n" 63 + "\n" 64 + "<script>\n" 65 + "function show(e) {\n" 66 + " while (e != null) {\n" 67 + " if (e.tagName == 'DIV') {\n" 68 + " e.style.display = 'block';\n" 69 + " }\n" 70 + " e = e.parentNode;\n" 71 + " }\n" 72 + "}\n" 73 + "\n" 74 + "function toggle(id) {\n" 75 + " e = document.getElementById(id);\n" 76 + " d = e.style.display;\n" 77 + " if (d == 'block') {\n" 78 + " e.style.display = 'none';\n" 79 + " } else {\n" 80 + " show(e);\n" 81 + " }\n" 82 + "}\n" 83 + "\n" 84 + "function main() {\n" 85 + " index = location.href.indexOf(\"#\");" 86 + " if (index != -1) {\n" 87 + " show(document.getElementById(location.href.substring(index + 1)));\n" 88 + " }\n" 89 + "}\n" 90 + "\n" 91 + "</script>\n" 92 + "</head>"); 93 94 this.pw.println("<body onload='main()'>"); 95 } else { 96 this.rootSection = rootSection; 97 this.pw.print("<ul>"); 98 } 99 } 100 101 public HtmlSection createChildren(String section) { 102 if (child != null) { 103 if (child.name.equals(section)) { 104 return child; 105 } 106 child.close(); 107 } 108 child = new SubSection(this, section, rootSection); 109 return child; 110 } 111 112 protected final void removeChild(HtmlSection child) { 113 if (this.child == child) { 114 this.child = null; 115 } 116 } 117 118 public void close() { 119 closeChild(); 120 if (closed) { 121 return; 122 } 123 closed = true; 124 125 if (rootSection == this) { 126 pw.println("</body>"); 127 pw.println("</html>"); 128 pw.close(); 129 } else { 130 pw.println("</ul>"); 131 } 132 133 } 134 135 protected final void closeChild() { 136 if (child != null) { 137 child.close(); 138 child = null; 139 } 140 } 141 142 public void link(HtmlSection section, String child, String name) { 143 String path = section.id; 144 if (path.isEmpty()) { 145 path = child; 146 } else if (child != null) { 147 path = String.format("%s.%s", path, child); 148 } 149 pw.printf("<a href=\"#%1$s\" onclick=\"show(document.getElementById('%1$s')); return true;\">%2$s</a>%n", 150 path, name); 151 } 152 153 public HtmlSection createChildren(String[] sections) { 154 int i = 0; 155 int n = sections.length; 156 HtmlSection current = rootSection; 157 if (current != null) { 158 for (; i < n && current.child != null; 159 ++i, current = current.child) { 160 if (!sections[i].equals(current.child.name)) { 161 break; 162 } 163 } 164 } 165 for (; i < n; ++i) { 166 current = current.createChildren(sections[i]); 167 } 168 return current; 169 } 170 171 private static class SubSection extends HtmlSection { 172 private final HtmlSection parent; 173 174 public SubSection(HtmlSection parent, String name, 175 HtmlSection rootSection) { 176 super(parent.pw, 177 parent.id.isEmpty() 178 ? name 179 : String.format("%s.%s", parent.id, name), 180 name, rootSection); 181 this.parent = parent; 182 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>", 183 id, name); 184 } 185 186 @Override 187 public void close() { 188 closeChild(); 189 if (closed) { 190 return; 191 } 192 pw.print("</pre></code></div></li><!-- " + id + "-->"); 193 parent.removeChild(this); 194 super.close(); 195 } 196 } 197 198 private static class HtmlFilterWriter extends FilterWriter { 199 public HtmlFilterWriter(PrintWriter pw) { 200 super(pw); 201 } 202 203 @Override 204 public void write(int c) throws IOException { 205 switch (c) { 206 case '<': 207 super.write("<", 0, 4); 208 break; 209 case '>': 210 super.write(">", 0, 4); 211 break; 212 case '"': 213 super.write(""", 0, 5); 214 break; 215 case '&': 216 super.write("&", 0, 4); 217 break; 218 default: 219 super.write(c); 220 } 221 } 222 223 @Override 224 public void write(char[] cbuf, int off, int len) throws IOException { 225 for (int i = off; i < len; ++i){ 226 write(cbuf[i]); 227 } 228 } 229 230 @Override 231 public void write(String str, int off, int len) throws IOException { 232 for (int i = off; i < len; ++i){ 233 write(str.charAt(i)); 234 } 235 } 236 } 237 }