test/tools/javac/diags/RunExamples.java

Thu, 28 Mar 2013 10:58:45 -0700

author
jjg
date
Thu, 28 Mar 2013 10:58:45 -0700
changeset 1669
d3648557391b
parent 1409
33abf479f202
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8010511: Tests are creating files in /tmp
Reviewed-by: darcy

jjg@610 1 /*
jjg@1669 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
jjg@610 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jjg@610 4 *
jjg@610 5 * This code is free software; you can redistribute it and/or modify it
jjg@610 6 * under the terms of the GNU General Public License version 2 only, as
jjg@610 7 * published by the Free Software Foundation.
jjg@610 8 *
jjg@610 9 * This code is distributed in the hope that it will be useful, but WITHOUT
jjg@610 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jjg@610 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jjg@610 12 * version 2 for more details (a copy is included in the LICENSE file that
jjg@610 13 * accompanied this code).
jjg@610 14 *
jjg@610 15 * You should have received a copy of the GNU General Public License version
jjg@610 16 * 2 along with this work; if not, write to the Free Software Foundation,
jjg@610 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jjg@610 18 *
jjg@610 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jjg@610 20 * or visit www.oracle.com if you need additional information or have any
jjg@610 21 * questions.
jjg@610 22 */
jjg@610 23
jjg@610 24 /**
jjg@610 25 * @test
jjh@1182 26 * @bug 6968063 7127924
jjg@610 27 * @summary provide examples of code that generate diagnostics
jjg@1409 28 * @build ArgTypeCompilerFactory Example HTMLWriter RunExamples DocCommentProcessor
jjh@1179 29 * @run main/othervm RunExamples
jjh@1179 30 */
jjh@1179 31 /*
jjh@1179 32 * See CR 7127924 for info on why othervm is used.
jjg@610 33 */
jjg@610 34
jjg@610 35 import java.io.*;
jjg@1669 36 import java.nio.file.*;
jjg@1669 37 import java.nio.file.attribute.BasicFileAttributes;
jjg@610 38 import java.util.*;
jjg@610 39 import java.util.regex.Matcher;
jjg@610 40 import java.util.regex.Pattern;
jjg@610 41
jjg@610 42 /**
jjg@610 43 * Utility to run selected or all examples, writing results to
jjg@610 44 * stdout, a plain text file or an HTML file. This program can be
jjg@610 45 * run standalone, or as a jtreg test.
jjg@610 46 *
jjg@610 47 * Options:
jjg@610 48 * -examples dir directory of examples. Defaults to ${test.src}/examples
jjg@610 49 * -raw run examples with -XDrawDiagnostics
jjg@610 50 * -showFiles include text of source files in the output
jjg@610 51 * -verbose verbose output
jjg@610 52 * -o file write output to file: format will be HTML if
jjg@610 53 * file has .html extension; otherwise it will be plain text.
jjg@610 54 * default is to stdout
jjg@610 55 * -title string specify a title, only applies to HTML output
jjg@610 56 */
jjg@610 57 public class RunExamples {
jjg@610 58 public static void main(String... args) throws Exception {
mcimadamore@795 59 jtreg = (System.getProperty("test.src") != null);
jjg@1669 60 Path tmpDir;
jjg@1669 61 boolean deleteOnExit;
jjg@610 62 if (jtreg) {
jjg@610 63 // use standard jtreg scratch directory: the current directory
jjg@1669 64 tmpDir = Paths.get(System.getProperty("user.dir"));
jjg@1669 65 deleteOnExit = false;
jjg@610 66 } else {
jjg@1669 67 tmpDir = Files.createTempDirectory(Paths.get(System.getProperty("java.io.tmpdir")),
jjg@1669 68 RunExamples.class.getName());
jjg@1669 69 deleteOnExit = true;
jjg@610 70 }
jjg@1669 71 Example.setTempDir(tmpDir.toFile());
jjg@610 72
jjg@610 73 RunExamples r = new RunExamples();
jjg@610 74
jjg@610 75 try {
jjg@610 76 if (r.run(args))
jjg@610 77 return;
jjg@610 78 } finally {
jjg@1669 79 if (deleteOnExit) {
jjg@1669 80 clean(tmpDir);
jjg@610 81 }
jjg@610 82 }
jjg@610 83
jjg@610 84 if (jtreg)
jjg@610 85 throw new Exception(r.errors + " errors occurred");
jjg@610 86 else
jjg@610 87 System.exit(1);
jjg@610 88 }
jjg@610 89
jjg@610 90 boolean run(String... args) {
jjg@610 91 Set<String> selectedKeys = new TreeSet<String>();
jjg@610 92 Set<Example> selectedExamples = new TreeSet<Example>();
jjg@610 93 File testSrc = new File(System.getProperty("test.src", "."));
jjg@610 94 File examplesDir = new File(testSrc, "examples");
jjg@610 95 File outFile = null;
jjg@610 96 boolean raw = false;
jjg@610 97 boolean showFiles = false;
jjg@610 98 boolean verbose = false;
jjg@842 99 boolean argTypes = false;
jjg@610 100 String title = null;
jjg@610 101
jjg@610 102 for (int i = 0; i < args.length; i++) {
jjg@610 103 String arg = args[i];
jjg@610 104 if (arg.equals("-k") && (i + 1) < args.length)
jjg@610 105 selectedKeys.add(args[++i]);
jjg@610 106 else if (arg.equals("-examples") && (i + 1) < args.length)
jjg@610 107 examplesDir = new File(args[++i]);
jjg@610 108 else if (arg.equals("-raw"))
jjg@610 109 raw = true;
jjg@610 110 else if (arg.equals("-showFiles"))
jjg@610 111 showFiles = true;
jjg@610 112 else if (arg.equals("-verbose"))
jjg@610 113 verbose = true;
jjg@610 114 else if (arg.equals("-o") && (i + 1) < args.length)
jjg@610 115 outFile = new File(args[++i]);
jjg@610 116 else if (arg.equals("-title") && (i + 1) < args.length)
jjg@610 117 title = args[++i];
jjg@842 118 else if (arg.equals("-argtypes"))
jjg@842 119 argTypes = true;
jjg@610 120 else if (arg.startsWith("-")) {
jjg@610 121 error("unknown option: " + arg);
jjg@610 122 return false;
jjg@610 123 } else {
jjg@610 124 while (i < args.length) {
jjg@610 125 File f = new File(examplesDir, args[i]);
jjg@610 126 selectedExamples.add(new Example(f));
jjg@610 127 i++;
jjg@610 128 }
jjg@610 129 }
jjg@610 130 }
jjg@610 131
jjg@842 132 // special mode to show message keys and the types of the args that
jjg@842 133 // are used.
jjg@842 134 if (argTypes)
jjg@842 135 Example.Compiler.factory = new ArgTypeCompilerFactory();
jjg@842 136
jjg@610 137 if (selectedKeys.size() > 0) {
jjg@610 138 Set<Example> examples = getExamples(examplesDir);
jjg@610 139 nextKey:
jjg@610 140 for (String k: selectedKeys) {
jjg@610 141 for (Example e: examples) {
jjg@610 142 if (e.getDeclaredKeys().contains(k))
jjg@610 143 continue nextKey;
jjg@610 144 }
jjg@610 145 error("Key " + k + ": no examples found");
jjg@610 146 }
jjg@610 147 } else {
jjg@842 148 if (selectedExamples.isEmpty())
jjg@610 149 selectedExamples = getExamples(examplesDir);
jjg@610 150 }
jjg@610 151
jjg@610 152 try {
jjg@610 153 Runner r;
jjg@610 154 if (outFile == null) {
jjg@610 155 PrintWriter out = new PrintWriter(System.out);
jjg@610 156 r = new TextRunner(out, showFiles, raw, verbose);
jjg@610 157 } else if (outFile.getName().endsWith(".html"))
jjg@610 158 r = new HTMLRunner(outFile, showFiles, raw, verbose, title);
jjg@610 159 else
jjg@610 160 r = new TextRunner(outFile, showFiles, raw, verbose);
jjg@610 161 r.run(selectedExamples);
jjg@610 162 r.close();
jjg@610 163 } catch (IOException e) {
jjg@610 164 error("Error writing output: " + e);
jjg@610 165 }
jjg@610 166
jjg@610 167 return (errors == 0);
jjg@610 168 }
jjg@610 169
jjg@610 170 /**
jjg@610 171 * Get the complete set of examples to be checked.
jjg@610 172 */
jjg@610 173 Set<Example> getExamples(File examplesDir) {
jjg@610 174 Set<Example> results = new TreeSet<Example>();
jjg@610 175 for (File f: examplesDir.listFiles()) {
mcimadamore@795 176 if (isValidExample(f))
jjg@610 177 results.add(new Example(f));
jjg@610 178 }
jjg@610 179 return results;
jjg@610 180 }
jjg@610 181
mcimadamore@795 182 boolean isValidExample(File f) {
mcimadamore@795 183 return (f.isDirectory() && (!jtreg || f.list().length > 0)) ||
mcimadamore@795 184 (f.isFile() && f.getName().endsWith(".java"));
mcimadamore@795 185 }
mcimadamore@795 186
jjg@610 187 /**
jjg@610 188 * Report an error.
jjg@610 189 */
jjg@610 190 void error(String msg) {
jjg@610 191 System.err.println("Error: " + msg);
jjg@610 192 errors++;
jjg@610 193 }
jjg@610 194
mcimadamore@795 195 static boolean jtreg;
mcimadamore@795 196
jjg@610 197 int errors;
jjg@610 198
jjg@610 199 /**
jjg@610 200 * Clean the contents of a directory.
jjg@610 201 */
jjg@1669 202 static void clean(Path dir) throws IOException {
jjg@1669 203 Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
jjg@1669 204 @Override
jjg@1669 205 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
jjg@1669 206 Files.delete(file);
jjg@1669 207 return super.visitFile(file, attrs);
jjg@1669 208 }
jjg@1669 209
jjg@1669 210 @Override
jjg@1669 211 public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
jjg@1669 212 if (exc == null) Files.delete(dir);
jjg@1669 213 return super.postVisitDirectory(dir, exc);
jjg@1669 214 }
jjg@1669 215 });
jjg@610 216 }
jjg@610 217
jjg@610 218 static abstract class Runner {
jjg@610 219 Runner(boolean showFiles, boolean raw, boolean verbose) {
jjg@610 220 this.showFiles = showFiles;
jjg@610 221 this.raw = raw;
jjg@610 222 this.verbose = verbose;
jjg@610 223 }
jjg@610 224
jjg@610 225 void close() throws IOException { }
jjg@610 226
jjg@610 227 void run(Collection<Example> examples) throws IOException {
jjg@610 228 for (Example e: examples) {
jjg@610 229 startExample(e);
jjg@610 230 if (showFiles) {
jjg@610 231 showFile(e, e.infoFile);
jjg@610 232 Set<File> srcFiles = new TreeSet<File>(e.srcFiles);
jjg@610 233 srcFiles.remove(e.infoFile);
jjg@610 234 showFiles(e, srcFiles);
jjg@610 235 showFiles(e, e.srcPathFiles);
jjg@610 236 showFiles(e, e.procFiles);
jjg@610 237 showFiles(e, e.supportFiles);
jjg@610 238 }
jjg@610 239 run(e);
jjg@610 240 }
jjg@610 241 }
jjg@610 242
jjg@610 243 void showFiles(Example e, Collection<File> files) throws IOException {
jjg@610 244 for (File f: files)
jjg@610 245 showFile(e, f);
jjg@610 246 }
jjg@610 247
jjg@610 248 abstract void startExample(Example e) throws IOException;
jjg@610 249
jjg@610 250 abstract void showFile(Example e, File f) throws IOException;
jjg@610 251
jjg@610 252 abstract void run(Example e) throws IOException;
jjg@610 253
jjg@610 254 protected String read(File f) throws IOException {
jjg@610 255 byte[] bytes = new byte[(int) f.length()];
jjg@610 256 DataInputStream in = new DataInputStream(new FileInputStream(f));
jjg@610 257 try {
jjg@610 258 in.readFully(bytes);
jjg@610 259 } finally {
jjg@610 260 in.close();
jjg@610 261 }
jjg@610 262 return new String(bytes);
jjg@610 263 }
jjg@610 264
jjg@610 265 protected Pattern copyrightHeaderPat =
jjg@610 266 Pattern.compile("(?s)(/\\*.*?Copyright.*?\\*/\n)\\s*(.*)");
jjg@610 267 protected Pattern infoHeaderPat =
jjg@610 268 Pattern.compile("(?s)((?://\\s*[a-z]+:[^\n]*\n)+)\\s*(.*)");
jjg@610 269
jjg@610 270 protected boolean showFiles;
jjg@610 271 protected boolean raw;
jjg@610 272 protected boolean verbose;
jjg@610 273 }
jjg@610 274
jjg@610 275 static class TextRunner extends Runner {
jjg@610 276 TextRunner(File file, boolean showFiles, boolean raw, boolean verbose)
jjg@610 277 throws IOException {
jjg@610 278 super(showFiles, raw, verbose);
jjg@610 279 this.file = file;
jjg@610 280 out = new PrintWriter(new FileWriter(file));
jjg@610 281 }
jjg@610 282
jjg@610 283 TextRunner(PrintWriter out, boolean showFiles, boolean raw, boolean verbose)
jjg@610 284 throws IOException {
jjg@610 285 super(showFiles, raw, verbose);
jjg@610 286 this.out = out;
jjg@610 287 }
jjg@610 288
jjg@610 289 @Override
jjg@610 290 void close() {
jjg@610 291 if (file != null)
jjg@610 292 out.close();
jjg@610 293 }
jjg@610 294
jjg@610 295 @Override
jjg@610 296 void startExample(Example e) {
jjg@610 297 out.println("----- " + e.getName() + " --------------------");
jjg@610 298 out.println();
jjg@610 299 }
jjg@610 300
jjg@610 301 @Override
jjg@610 302 void showFile(Example e, File f) {
jjg@610 303 out.println("--- " + f);
jjg@610 304 String text;
jjg@610 305 try {
jjg@610 306 text = read(f);
jjg@610 307 } catch (IOException ex) {
jjg@610 308 text = "Error reading " + f + "; " + ex;
jjg@610 309 }
jjg@610 310 Matcher m = copyrightHeaderPat.matcher(text);
jjg@610 311 if (m.matches()) {
jjg@610 312 out.println("(Copyright)");
jjg@610 313 writeLines(m.group(2));
jjg@610 314 } else {
jjg@610 315 writeLines(text);
jjg@610 316 }
jjg@610 317 out.println();
jjg@610 318 }
jjg@610 319
jjg@610 320 @Override
jjg@610 321 void run(Example e) {
jjg@610 322 // only show Output: header if also showing files
jjg@610 323 if (showFiles)
jjg@610 324 out.println("--- Output:");
jjg@610 325 e.run(out, raw, verbose);
jjg@610 326 out.println();
jjg@610 327 }
jjg@610 328
jjg@610 329 void writeLines(String text) {
jjg@610 330 for (String line: text.split("\n"))
jjg@610 331 out.println(line);
jjg@610 332 }
jjg@610 333
jjg@610 334 File file;
jjg@610 335 PrintWriter out;
jjg@610 336 }
jjg@610 337
jjg@610 338 static class HTMLRunner extends Runner {
jjg@610 339 HTMLRunner(File file, boolean showFiles, boolean raw, boolean verbose, String title)
jjg@610 340 throws IOException {
jjg@610 341 super(showFiles, raw, verbose);
jjg@610 342 this.file = file;
jjg@610 343 PrintWriter out = new PrintWriter(new FileWriter(file));
jjg@610 344 html = new HTMLWriter(out);
jjg@610 345 html.startTag(HTMLWriter.HEAD);
jjg@610 346 if (title != null) {
jjg@610 347 html.startTag(HTMLWriter.TITLE);
jjg@610 348 html.write(title);
jjg@610 349 html.endTag(HTMLWriter.TITLE);
jjg@610 350 }
jjg@610 351 html.startTag(HTMLWriter.STYLE);
jjg@610 352 html.newLine();
jjg@610 353 html.writeLine("div.file { background-color:#e0ffe0; margin-left:30px; margin-right:30px;\n"
jjg@610 354 + " padding: 3px; border: thin solid silver; }");
jjg@610 355 html.writeLine("p.file { white-space: pre-wrap; font-family:monospace; margin: 0; }");
jjg@610 356 html.writeLine("div.output { background-color:#e0e0ff; margin-left:30px; margin-right:30px;\n"
jjg@610 357 + " padding: 3px; border: thin solid silver; }");
jjg@610 358 html.writeLine("p.output { white-space: pre-wrap; font-family:monospace; margin: 0; }");
jjg@610 359 html.writeLine("table.index { border: thin solid silver; }");
jjg@610 360 html.writeLine(".copyright { font-size: x-small }");
jjg@610 361 html.writeLine(".hidden { display:none }");
jjg@610 362 html.writeLine(".unhidden { display:block }");
jjg@610 363 html.writeLine(".odd { background-color: #e0e0e0 }");
jjg@610 364 html.writeLine(".even { background-color: white }");
jjg@610 365 html.endTag(HTMLWriter.STYLE);
jjg@610 366 html.startTag(HTMLWriter.SCRIPT);
jjg@610 367 html.writeAttr(HTMLWriter.TYPE, HTMLWriter.TEXT_JAVASCRIPT);
jjg@610 368 html.writeLine("\nfunction unhide(id) {\n"
jjg@610 369 + " var item = document.getElementById(id);\n"
jjg@610 370 + " if (item) {\n"
jjg@610 371 + " item.className=(item.className=='hidden')?'unhidden':'hidden';\n"
jjg@610 372 + " }\n"
jjg@610 373 + "}");
jjg@610 374 html.endTag(HTMLWriter.SCRIPT);
jjg@610 375 html.endTag(HTMLWriter.HEAD);
jjg@610 376 html.startTag(HTMLWriter.BODY);
jjg@610 377 if (title != null) {
jjg@610 378 html.startTag(TITLE_HEADER);
jjg@610 379 html.write(title);
jjg@610 380 html.endTag(TITLE_HEADER);
jjg@610 381 }
jjg@610 382 }
jjg@610 383
jjg@610 384 @Override
jjg@610 385 void close() throws IOException {
jjg@610 386 html.endTag(HTMLWriter.BODY);
jjg@610 387 html.newLine();
jjg@610 388 html.flush();
jjg@610 389 }
jjg@610 390
jjg@610 391 @Override
jjg@610 392 void run(Collection<Example> examples) throws IOException {
jjg@610 393 if (examples.size() > 1)
jjg@610 394 writeIndex(examples);
jjg@610 395 super.run(examples);
jjg@610 396 }
jjg@610 397
jjg@610 398 void writeIndex(Collection<Example> examples) throws IOException {
jjg@610 399 Map<String, Set<Example>> index = new TreeMap<String, Set<Example>>();
jjg@610 400 Set<String> initials = new HashSet<String>();
jjg@610 401 for (Example e: examples) {
jjg@610 402 for (String k: e.getDeclaredKeys()) {
jjg@610 403 Set<Example> s = index.get(k);
jjg@610 404 if (s == null)
jjg@610 405 index.put(k, s = new TreeSet<Example>());
jjg@610 406 s.add(e);
jjg@610 407 }
jjg@610 408 initials.add(e.getName().substring(0, 1).toUpperCase());
jjg@610 409 }
jjg@610 410
jjg@610 411
jjg@610 412 if (INDEX_HEADER != null) {
jjg@610 413 html.startTag(INDEX_HEADER);
jjg@610 414 html.write("Index");
jjg@610 415 html.endTag(INDEX_HEADER);
jjg@610 416 }
jjg@610 417
jjg@610 418 html.startTag(HTMLWriter.P);
jjg@610 419 html.writeLine("Examples: ");
jjg@610 420 for (char initial = 'A'; initial <= 'Z'; initial++) {
jjg@610 421 String s = String.valueOf(initial);
jjg@610 422 if (initials.contains(s)) {
jjg@610 423 html.writeLink("#" + s, s);
jjg@610 424 } else {
jjg@610 425 html.write(s);
jjg@610 426 }
jjg@610 427 html.newLine();
jjg@610 428 }
jjg@610 429 html.endTag(HTMLWriter.P);
jjg@610 430
jjg@610 431 html.startTag(HTMLWriter.TABLE);
jjg@610 432 html.writeAttr(HTMLWriter.CLASS, "index");
jjg@610 433 html.newLine();
jjg@610 434 int row = 0;
jjg@610 435 for (Map.Entry<String, Set<Example>> entry: index.entrySet()) {
jjg@610 436 html.startTag(HTMLWriter.TR);
jjg@610 437 html.writeAttr(HTMLWriter.CLASS,
jjg@610 438 (row++ % 2 == 0 ? "even" : "odd"));
jjg@610 439 html.startTag(HTMLWriter.TD);
jjg@610 440 html.writeAttr("valign", "top");
jjg@610 441 html.write(entry.getKey());
jjg@610 442 html.endTag(HTMLWriter.TD);
jjg@610 443 html.newLine();
jjg@610 444 html.startTag(HTMLWriter.TD);
jjg@610 445 html.writeAttr(HTMLWriter.ALIGN, "top");
jjg@610 446 String sep = "";
jjg@610 447 for (Example e: entry.getValue()) {
jjg@610 448 html.write(sep);
jjg@610 449 html.writeLink('#' + e.getName(), e.getName());
jjg@610 450 sep = ", ";
jjg@610 451 }
jjg@610 452 html.endTag(HTMLWriter.TD);
jjg@610 453 html.endTag(HTMLWriter.TR);
jjg@610 454 html.newLine();
jjg@610 455 }
jjg@610 456 html.endTag(HTMLWriter.TABLE);
jjg@610 457 }
jjg@610 458
jjg@610 459 @Override
jjg@610 460 void startExample(Example e) throws IOException {
jjg@610 461 String name = e.getName();
jjg@610 462 String initial = name.substring(0, 1).toUpperCase();
jjg@610 463 if (!initial.equals(currInitial)) {
jjg@610 464 html.writeLinkDestination(initial, "");
jjg@610 465 currInitial = initial;
jjg@610 466 }
jjg@610 467 html.writeLinkDestination(name, "");
jjg@610 468 html.startTag(EXAMPLE_HEADER);
jjg@610 469 html.write(e.getName());
jjg@610 470 html.endTag(EXAMPLE_HEADER);
jjg@610 471 }
jjg@610 472
jjg@610 473 @Override
jjg@610 474 void showFile(Example e, File f) throws IOException {
jjg@610 475 String text;
jjg@610 476 try {
jjg@610 477 text = read(f);
jjg@610 478 } catch (IOException ex) {
jjg@610 479 text = "Error reading " + f + ": " + ex;
jjg@610 480 }
jjg@610 481 if (!f.equals(e.file)) {
jjg@610 482 html.startTag(FILE_HEADER);
jjg@610 483 html.write(e.file.toURI().relativize(f.toURI()).toString());
jjg@610 484 html.endTag(FILE_HEADER);
jjg@610 485 }
jjg@610 486 html.startTag(HTMLWriter.DIV);
jjg@610 487 html.writeAttr(CLASS, FILE);
jjg@610 488
jjg@610 489 String legalHeader;
jjg@610 490 Matcher m1 = copyrightHeaderPat.matcher(text);
jjg@610 491 if (m1.matches()) {
jjg@610 492 legalHeader = m1.group(1);
jjg@610 493 text = m1.group(2);
jjg@610 494 } else
jjg@610 495 legalHeader = null;
jjg@610 496
jjg@610 497 String infoHeader;
jjg@610 498 Matcher m2 = infoHeaderPat.matcher(text);
jjg@610 499 if (m2.matches()) {
jjg@610 500 infoHeader = m2.group(1);
jjg@610 501 text = m2.group(2);
jjg@610 502 } else
jjg@610 503 infoHeader = null;
jjg@610 504
jjg@610 505 String legalId = null, infoId = null;
jjg@610 506 if (legalHeader != null || infoHeader != null) {
jjg@610 507 String sep = "";
jjg@610 508 html.startTag(HTMLWriter.SPAN);
jjg@610 509 html.writeStyleAttr("float: right");
jjg@610 510 if (legalHeader != null) {
jjg@610 511 legalId = nextId();
jjg@610 512 html.startTag(HTMLWriter.A);
jjg@610 513 html.writeAttr(HTMLWriter.HREF, "javascript:unhide('" + legalId + "');");
jjg@610 514 //html.writeEntity("&copy;");
jjg@610 515 html.write("Copyright");
jjg@610 516 html.endTag(HTMLWriter.A);
jjg@610 517 sep = ", ";
jjg@610 518 }
jjg@610 519 if (infoHeader != null) {
jjg@610 520 html.write(sep);
jjg@610 521 infoId = nextId();
jjg@610 522 html.startTag(HTMLWriter.A);
jjg@610 523 html.writeAttr(HTMLWriter.HREF, "javascript:unhide('" + infoId + "');");
jjg@610 524 html.write("Info");
jjg@610 525 html.endTag(HTMLWriter.A);
jjg@610 526 sep = ", ";
jjg@610 527 }
jjg@610 528 html.endTag(HTMLWriter.SPAN);
jjg@610 529 }
jjg@610 530
jjg@610 531 html.startTag(HTMLWriter.P);
jjg@610 532 html.writeAttr(CLASS, FILE);
jjg@610 533 if (legalHeader != null) {
jjg@610 534 html.startTag(HTMLWriter.SPAN);
jjg@610 535 html.writeAttr(HTMLWriter.CLASS, "hidden");
jjg@610 536 html.writeAttr(HTMLWriter.ID, legalId);
jjg@610 537 html.write(legalHeader);
jjg@610 538 html.newLine();
jjg@610 539 html.endTag(HTMLWriter.SPAN);
jjg@610 540 }
jjg@610 541 if (infoHeader != null) {
jjg@610 542 html.startTag(HTMLWriter.SPAN);
jjg@610 543 html.writeAttr(HTMLWriter.CLASS, "hidden");
jjg@610 544 html.writeAttr(HTMLWriter.ID, infoId);
jjg@610 545 html.write(infoHeader);
jjg@610 546 html.newLine();
jjg@610 547 html.endTag(HTMLWriter.SPAN);
jjg@610 548 }
jjg@610 549 html.write(text);
jjg@610 550 html.endTag(HTMLWriter.P);
jjg@610 551
jjg@610 552 html.endTag(HTMLWriter.DIV);
jjg@610 553 }
jjg@610 554
jjg@610 555 @Override
jjg@610 556 void run(Example e) throws IOException {
jjg@610 557 StringWriter sw = new StringWriter();
jjg@610 558 PrintWriter pw = new PrintWriter(sw);
jjg@610 559 e.run(pw, raw, verbose);
jjg@610 560 pw.flush();
jjg@610 561
jjg@610 562 // only show Output: header if also showing files
jjg@610 563 if (showFiles) {
jjg@610 564 html.startTag(OUTPUT_HEADER);
jjg@610 565 html.write("Output:");
jjg@610 566 html.endTag(OUTPUT_HEADER);
jjg@610 567 }
jjg@610 568
jjg@610 569 html.startTag(HTMLWriter.DIV);
jjg@610 570 html.writeAttr(CLASS, OUTPUT);
jjg@610 571 html.startTag(HTMLWriter.P);
jjg@610 572 html.writeAttr(CLASS, OUTPUT);
jjg@610 573 String[] lines = sw.toString().split("\n");
jjg@610 574 for (String line: lines) {
jjg@610 575 html.write(line);
jjg@610 576 html.newLine();
jjg@610 577 }
jjg@610 578 html.endTag(HTMLWriter.P);
jjg@610 579 html.endTag(HTMLWriter.DIV);
jjg@610 580 }
jjg@610 581
jjg@610 582 String nextId() {
jjg@610 583 return "id" + (nextId++);
jjg@610 584 }
jjg@610 585
jjg@610 586 File file;
jjg@610 587 HTMLWriter html;
jjg@610 588 int nextId;
jjg@610 589 String currInitial = "";
jjg@610 590
jjg@610 591 static final String TITLE_HEADER = HTMLWriter.H3;
jjg@610 592 static final String INDEX_HEADER = HTMLWriter.H4;
jjg@610 593 static final String EXAMPLE_HEADER = HTMLWriter.H4;
jjg@610 594 static final String FILE_HEADER = HTMLWriter.H5;
jjg@610 595 static final String OUTPUT_HEADER = HTMLWriter.H5;
jjg@610 596 static final String CLASS = "class";
jjg@610 597 static final String FILE = "file";
jjg@610 598 static final String OUTPUT = "output";
jjg@610 599 }
jjg@610 600 }
jjg@610 601
jjg@610 602

mercurial