1 /* 2 * $Id$ 3 * 4 * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. 5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6 * 7 * This code is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 only, as 9 * published by the Free Software Foundation. Oracle designates this 10 * particular file as subject to the "Classpath" exception as provided 11 * by Oracle in the LICENSE file that accompanied this code. 12 * 13 * This code is distributed in the hope that it will be useful, but WITHOUT 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 * version 2 for more details (a copy is included in the LICENSE file that 17 * accompanied this code). 18 * 19 * You should have received a copy of the GNU General Public License version 20 * 2 along with this work; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22 * 23 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 24 * or visit www.oracle.com if you need additional information or have any 25 * questions. 26 */ 27 package com.sun.javatest; 28 29 import java.io.File; 30 import java.io.IOException; 31 import java.io.PrintWriter; 32 import java.util.Iterator; 33 34 import com.sun.interview.WizPrint; 35 import com.sun.javatest.httpd.JThttpProvider; 36 import com.sun.javatest.httpd.PageGenerator; 37 import com.sun.javatest.httpd.RootRegistry; 38 import com.sun.javatest.httpd.httpURL; 39 import com.sun.javatest.util.I18NResourceBundle; 40 import com.sun.javatest.util.PropertyArray; 41 import com.sun.javatest.util.StringArray; 42 43 class HarnessHttpHandler extends JThttpProvider 44 implements Harness.Observer 45 { 46 HarnessHttpHandler(Harness harness) { 47 this.harness = harness; 48 harness.addObserver(this); 49 } 50 51 public void serviceRequest(httpURL requestURL, PrintWriter out) { 52 String nf = requestURL.getNextFile(); 53 if (nf == null) { // request for root 54 beginGood(out); 55 printHtml(out); 56 } 57 else if (nf.equals("env")) { // environment dump 58 beginGood(out); 59 printEnv(out); 60 } 61 else if (nf.equals("interview")) { // interview dump 62 beginGood(out); 63 printInterview(out); 64 } 65 else if (nf.equals("text")) // get text only data 66 printText(requestURL, out); 67 else if (nf.equals("stop")) { // stop the harness 68 if (!harness.isRunning()) { 69 println(out, i18n.getString("harnessHttp.noStop")); 70 } 71 else { 72 // generate the token if it hasn't already been 73 beginGood(out); 74 if (magicToken == null) { 75 long num = Math.round(Math.floor(Math.random() * 30000.0 )); 76 magicToken = Integer.toString((int)num); 77 } 78 79 PageGenerator.writeHeader(out, i18n.getString("harnessHttp.stop.hdr")); 80 PageGenerator.startBody(out); 81 82 String token = requestURL.getValue("token"); 83 if (token == null) 84 printStopConfirm(out); 85 else if (token.equals(magicToken)) { 86 harness.stop(); 87 println(out, i18n.getString("harnessHttp.stopped")); 88 } 89 else { 90 printStopErr(out); 91 } 92 93 out.println("<hr>"); 94 PageGenerator.writeFooter(out); 95 PageGenerator.endBody(out); 96 PageGenerator.writeEndDoc(out); 97 } 98 } 99 else { // bad url 100 if (debug) 101 System.out.println("TRT.HH-remainder of URL unknown (" + nf + ")"); 102 103 beginBad(out); 104 printHtml(out); 105 } 106 107 out.close(); 108 } 109 110 private void beginGood(PrintWriter out) { 111 PageGenerator.generateOkHttp(out); 112 PageGenerator.generateDocType(out, PageGenerator.HTML32); 113 } 114 115 private void beginBad(PrintWriter out) { 116 PageGenerator.generateBadHttp(out); 117 PageGenerator.generateDocType(out, PageGenerator.HTML32); 118 } 119 120 /** 121 * Print the basic HTML page for Harness. 122 */ 123 private void printHtml(PrintWriter out) { 124 PageGenerator.writeBeginDoc(out); 125 126 printIndex(out); 127 128 out.println("<hr>"); 129 PageGenerator.writeFooter(out); 130 PageGenerator.endBody(out); 131 PageGenerator.writeEndDoc(out); 132 } 133 134 /** 135 * Print the environment settings in formatted HTML. 136 */ 137 private void printEnv(PrintWriter out) { 138 PageGenerator.writeBeginDoc(out); 139 PageGenerator.writeHeader(out, i18n.getString("harnessHttp.env.title")); 140 141 out.print("<h3>"); 142 print(out, i18n.getString("harnessHttp.env.hdr")); 143 out.println("</h3>"); 144 145 Parameters params = harness.getParameters(); 146 if (params != null) 147 printEnv(out, params.getEnv()); 148 else 149 out.println(i18n.getString("harnessHttp.env.none")); 150 151 out.println("<hr>"); 152 PageGenerator.writeFooter(out); 153 PageGenerator.endBody(out); 154 PageGenerator.writeEndDoc(out); 155 } 156 157 /** 158 * Print the interview settings in formatted HTML. 159 */ 160 private void printInterview(PrintWriter out) { 161 PageGenerator.writeBeginDoc(out); 162 PageGenerator.writeHeader(out, i18n.getString("harnessHttp.interview.title")); 163 164 out.print("<h3>"); 165 print(out, i18n.getString("harnessHttp.interview.hdr")); 166 out.println("</h3>"); 167 168 try { 169 Parameters params = harness.getParameters(); 170 if (params == null || 171 !(harness.getParameters() instanceof InterviewParameters)) { 172 println(out, i18n.getString("harnessHttp.interview.none")); 173 } 174 else { 175 InterviewParameters interview = (InterviewParameters)(harness.getParameters()); 176 WizPrint wp = new WizPrint(interview); 177 wp.setShowResponses(true); 178 wp.setShowResponseTypes(true); 179 wp.setShowTags(true); 180 wp.write(out); 181 } // else 182 183 out.println("<hr>"); 184 PageGenerator.writeFooter(out); 185 PageGenerator.endBody(out); 186 PageGenerator.writeEndDoc(out); 187 } // try 188 catch (IOException e) { 189 println(out, i18n.getString("harnessHttp.ioProblem")); 190 } // catch 191 } 192 193 /** 194 * Access to raw text output pages. 195 * We choose to not including the standard HTTP response header when 196 * returning plain text. This makes it easier to process on the client side. 197 */ 198 private void printText(httpURL requestURL, PrintWriter out) { 199 // write directly to out in this method, we are not 200 // transmitting HTML encoded data 201 Parameters params = harness.getParameters(); 202 String nf = requestURL.getNextFile(); 203 if (nf == null) { 204 beginGood(out); 205 printIndex(out); 206 } 207 else if (nf.equals("env")) { 208 // special case for incomplete interview? 209 210 TestEnvironment env = params.getEnv(); 211 212 if (env == null) { 213 print(out, i18n.getString("harnessHttp.env.none")); 214 return; 215 } 216 217 /* does not fit in the properties style output 218 out.print(i18n.getString("harnessHttp.env.name")); 219 out.println(env.getName()); 220 */ 221 222 String[] pa = new String[0]; 223 224 for (Iterator<TestEnvironment.Element> i = env.elements().iterator(); i.hasNext(); ) { 225 TestEnvironment.Element elem = i.next(); 226 // this is stunningly inefficient and should be fixed 227 pa = PropertyArray.put(pa, elem.getKey(), elem.getValue()); 228 } 229 230 try { 231 PropertyArray.save(pa, out); 232 } 233 catch (IOException e) { 234 // this is probably useless since problems with out 235 // probably caused this 236 out.println(i18n.getString("harnessHttp.ioProblem")); 237 } 238 } 239 else if (nf.equals("config")) { 240 if (params == null) { 241 out.print(i18n.getString("harnessHttp.text.unavail")); 242 return; 243 } 244 245 // test suite info 246 TestSuite ts = params.getTestSuite(); 247 out.print(i18n.getString("harnessHttp.text.ts.path")); 248 out.print("="); 249 if (ts != null) { 250 out.println(ts.getPath()); 251 } 252 else 253 out.println(i18n.getString("harnessHttp.text.empty")); 254 255 out.print(i18n.getString("harnessHttp.text.ts.name")); 256 out.print("="); 257 if (ts != null) { 258 out.println(ts.getName()); 259 } 260 else 261 out.println(i18n.getString("harnessHttp.text.empty")); 262 263 out.print(i18n.getString("harnessHttp.text.wd.val")); 264 out.print("="); 265 WorkDirectory wd = params.getWorkDirectory(); 266 if (wd != null) 267 out.println(wd.getPath()); 268 else 269 out.println(i18n.getString("harnessHttp.text.empty")); 270 } 271 else if (nf.equals("tests")) { 272 if (params == null) { 273 out.print(i18n.getString("harnessHttp.text.unavail")); 274 return; 275 } 276 277 String[] tests = params.getTests(); 278 if (tests != null && tests.length != 0) { 279 for (int i = 0; i < tests.length; i++) { 280 out.print("url"); 281 out.print(Integer.toString(i)); 282 out.print("="); 283 out.println(tests[i]); 284 } // for 285 } 286 } 287 else if (nf.equals("stats")) { 288 if (!harness.isRunning()) { 289 out.println(""); 290 return; 291 } 292 293 stats[Status.NOT_RUN] = harness.getTestsFoundCount() - stats[Status.PASSED] - 294 stats[Status.FAILED] - stats[Status.ERROR]; 295 296 for (int i = 0; i < Status.NUM_STATES; i++) { 297 out.print((Status.typeToString(i)).replace(' ', '_')); 298 out.print("="); 299 out.println(stats[i]); 300 } // for 301 } 302 else if (nf.equals("state")) { 303 // provide information about the Harness' state 304 print(out, i18n.getString("harnessHttp.state.run.val")); 305 out.println(harness.isRunning()); 306 } 307 else if (nf.equals("results")) { 308 // test dump 309 TestResultTable trt = harness.getResultTable(); 310 TestFilter[] filters = params.getFilters(); 311 String[] tests = params.getTests(); 312 313 Iterator<TestResult> it = null; 314 if (tests == null || tests.length == 0) 315 it = trt.getIterator(filters); 316 else 317 it = trt.getIterator(params.getTests(), filters); 318 319 while (it.hasNext()) { 320 TestResult tr = it.next(); 321 out.println(tr.getTestName()); 322 out.println(tr.getStatus().toString()); 323 } // while 324 } 325 else { 326 if (debug) 327 System.out.println("TRT.HH-remainder of URL unknown (" + nf + ")"); 328 329 println(out, i18n.getString("harnessHttp.badRequest", requestURL.getFullPath())); 330 } 331 } 332 333 private void printStopConfirm(PrintWriter out) { 334 out.print("<h2>"); 335 print(out, i18n.getString("harnessHttp.stopConfirm.hdr")); 336 out.println("</h2>"); 337 out.print("<h4>"); 338 print(out, i18n.getString("harnessHttp.stopConfirm.txt")); 339 out.println("</h4>"); 340 out.print("<Form method=get enctype=application/x-www-form-urlencoded>"); 341 342 out.print("<p><Input align=center type=submit value="); 343 out.print(i18n.getString("harnessHttp.stopConfirm.btn")); 344 out.println(">"); 345 out.print("<Input type=hidden name=token value="); 346 out.print(magicToken); 347 out.println("></Form>"); 348 } 349 350 private void printStopErr(PrintWriter out) { 351 out.println("<h2>"); 352 println(out, i18n.getString("harnessHttp.stopErr.hdr")); 353 out.println("</h2>"); 354 out.println("<b>"); 355 println(out, i18n.getString("harnessHttp.stopErr.text1")); 356 println(out, i18n.getString("harnessHttp.stopErr.text2")); 357 out.println("</b>"); 358 out.println("<p>"); 359 println(out, i18n.getString("harnessHttp.stopErr.text3")); 360 out.println("<a href=\"/harness/stop\">"); 361 println(out, i18n.getString("harnessHttp.stopErr.text4")); 362 out.println("</a>"); 363 println(out, i18n.getString("harnessHttp.stopErr.text5")); 364 } 365 366 private void printIndex(PrintWriter out) { 367 PageGenerator.writeHeader(out, i18n.getString("harnessHttp.index.title")); 368 PageGenerator.startBody(out); 369 out.println("<h2>"); 370 out.print("JT Harness ™ "); 371 println(out, i18n.getString("harnessHttp.index.hdr")); 372 out.println("</h2>"); 373 374 Parameters params = harness.getParameters(); 375 if (params == null) { 376 out.println(i18n.getString("harnessHttp.parameters.noParams")); 377 return; 378 } 379 380 // print test suite 381 print(out, i18n.getString("harnessHttp.parameters.tsName")); 382 String name = params.getTestSuite().getName(); 383 println(out, (name == null ? 384 i18n.getString("harnessHttp.parameters.noTs") : 385 name)); 386 387 out.println("<br>"); 388 print(out, i18n.getString("harnessHttp.parameters.tsPath")); 389 File tsr = params.getTestSuite().getRoot(); 390 println(out, (tsr == null ? 391 i18n.getString("harnessHttp.parameters.noTs") : 392 tsr.getPath())); 393 394 out.println("<br>"); 395 396 // print workdir 397 print(out, i18n.getString("harnessHttp.parameters.wd")); 398 399 WorkDirectory wd = params.getWorkDirectory(); 400 if (wd != null) 401 println(out, wd.getPath()); 402 else 403 print(out, i18n.getString("harnessHttp.parameters.noWd")); 404 405 out.println("<p>"); 406 407 // print parameters 408 printParameters(out, params); 409 410 // print results link 411 TestResultTable currentResults = harness.getResultTable(); 412 out.println("<h3>"); 413 println(out, i18n.getString("harnessHttp.results.hdr")); 414 out.println("</h3>"); 415 if (currentResults != null) { 416 JThttpProvider trtProv = RootRegistry.getObjectHandler(currentResults); 417 if (trtProv != null && trtProv.getRootURL() != null) { 418 out.print("<a href=\""); 419 out.print(trtProv.getRootURL()); 420 out.print("\">"); 421 print(out, i18n.getString("harnessHttp.trt.link")); 422 out.println("</a>"); 423 } 424 } 425 else { 426 out.print(i18n.getString("harnessHttp.trt.none")); 427 } 428 } 429 430 private void printParameters(PrintWriter out, Parameters params) { 431 out.println("<h3>"); 432 println(out, i18n.getString("harnessHttp.parameters.hdr")); 433 out.println("</h3>"); 434 435 print(out, i18n.getString("harnessHttp.parameters.env")); 436 TestEnvironment tev = params.getEnv(); 437 if (tev != null) { 438 out.print("<a href=\""); 439 out.print(getRootURL()); 440 out.print("/env\">"); 441 442 print(out, tev.getName()); 443 out.println("</a>"); 444 } 445 else { 446 println(out, i18n.getString("harnessHttp.parameters.noEnv")); 447 } 448 449 out.println("<br>"); 450 451 print(out, i18n.getString("harnessHttp.parameters.interview")); 452 if (params instanceof InterviewParameters) { 453 InterviewParameters ip = (InterviewParameters)params; 454 File ipf = ip.getFile(); 455 456 out.print("<a href=\""); 457 out.print(getRootURL()); 458 out.print("/interview\">"); 459 print(out, (ipf == null ? 460 i18n.getString("harnessHttp.parameters.noInterviewFile") : 461 ipf.getPath())); 462 out.println("</a>"); 463 } 464 else { 465 println(out, i18n.getString("harnessHttp.parameters.noInterview")); 466 } 467 468 out.println("<p>"); 469 470 // initial files info 471 out.println("<ul>"); 472 out.print("<li>"); 473 print(out, i18n.getString("harnessHttp.parameters.urls")); 474 printTests(out); 475 476 // jtx info 477 out.print("<li>"); 478 print(out, i18n.getString("harnessHttp.parameters.jtx")); 479 Parameters.ExcludeListParameters exclParams = params.getExcludeListParameters(); 480 481 if (exclParams instanceof Parameters.MutableExcludeListParameters) { 482 Parameters.MutableExcludeListParameters e = 483 (Parameters.MutableExcludeListParameters) (exclParams); 484 File[] jtx = e.getExcludeFiles(); 485 if (jtx == null || jtx.length == 0) 486 println(out, i18n.getString("harnessHttp.parameters.emptyJtx")); 487 else { 488 out.println("<ul>"); 489 for (int i = 0; i < jtx.length; i++) 490 out.println("<li>" + jtx[i].getPath()); 491 492 out.println("</ul>"); 493 } 494 } 495 else { 496 println(out, i18n.getString("harnessHttp.parameters.noJtx")); 497 } 498 499 // keyword info 500 /* removed until output can be improved 501 out.print("<li>"); 502 print(out, i18n.getString("harnessHttp.parameters.keyw")); 503 out.println(params.getKeywords()); 504 */ 505 506 out.println("</ul>"); 507 508 // status 509 } 510 511 private void printTests(PrintWriter out) { 512 String[] tests = harness.getParameters().getTests(); 513 if (tests == null || tests.length == 0) { 514 print(out, i18n.getString("harnessHttp.parameters.noTests")); 515 } 516 else { 517 out.println("<ul>"); 518 519 for (int i = 0; i < tests.length; i++) { 520 out.println("<li>"); 521 println(out, tests[i]); 522 } 523 524 out.println("</ul>"); 525 } 526 } // printTests() 527 528 private void printEnv(PrintWriter out, TestEnvironment env) { 529 out.print(i18n.getString("harnessHttp.env.name")); 530 println(out, env.getName()); 531 532 String keyHeader = "Key"; 533 String valHeader = "Value"; 534 535 out.println("<Table Border>"); 536 537 StringBuffer buf = new StringBuffer(50); 538 539 // write the table header 540 buf.append("<tr><th>"); 541 buf.append(filterTags(keyHeader)); 542 buf.append("<th>"); 543 buf.append(filterTags(valHeader)); 544 buf.append("</tr>"); 545 out.println(buf.toString()); 546 547 for (Iterator<String> keys = env.keys().iterator(); keys.hasNext(); ) { 548 String key = keys.next(); 549 out.println("<tr>"); 550 buf.setLength(0); 551 buf.append("<td>"); 552 buf.append(key.toString()); 553 buf.append("<td>"); 554 try { 555 buf.append(filterTags(StringArray.join((env.lookup(key))))); 556 } 557 catch (TestEnvironment.Fault f) { 558 buf.append(i18n.getString("harnessHttp.env.error")); 559 } 560 561 out.println(buf.toString()); 562 out.println("</tr>"); 563 } // while 564 565 out.println("</Table>"); 566 } 567 568 // ------------ instance vars ------------ 569 private Harness harness; 570 private boolean debug = false; 571 private String magicToken; 572 private int[] stats = new int[Status.NUM_STATES]; 573 private TestFinderQueue tfq; 574 private static I18NResourceBundle i18n = I18NResourceBundle.getBundleForClass(HarnessHttpHandler.class); 575 576 // ------------ Harness.Observer ------------ 577 public void startingTestRun(Parameters params) { } 578 579 public void startingTest(TestResult tr) { } 580 581 public void finishedTest(TestResult tr) { 582 stats[tr.getStatus().getType()]++; 583 } 584 585 public void stoppingTestRun() { } 586 public void finishedTesting() { } 587 public void finishedTestRun(boolean allOK) { } 588 589 public void error(String msg) { } 590 }