1 16 17 package sax; 18 19 import java.io.PrintWriter ; 20 21 import org.xml.sax.Attributes ; 22 import org.xml.sax.Parser ; 23 import org.xml.sax.SAXException ; 24 import org.xml.sax.SAXNotRecognizedException ; 25 import org.xml.sax.SAXNotSupportedException ; 26 import org.xml.sax.SAXParseException ; 27 import org.xml.sax.XMLReader ; 28 import org.xml.sax.helpers.DefaultHandler ; 29 import org.xml.sax.helpers.ParserAdapter ; 30 import org.xml.sax.helpers.ParserFactory ; 31 import org.xml.sax.helpers.XMLReaderFactory ; 32 33 54 public class Counter 55 extends DefaultHandler { 56 57 61 63 64 protected static final String NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces"; 65 66 67 protected static final String NAMESPACE_PREFIXES_FEATURE_ID = "http://xml.org/sax/features/namespace-prefixes"; 68 69 70 protected static final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation"; 71 72 73 protected static final String SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema"; 74 75 76 protected static final String SCHEMA_FULL_CHECKING_FEATURE_ID = "http://apache.org/xml/features/validation/schema-full-checking"; 77 78 79 protected static final String VALIDATE_ANNOTATIONS_ID = "http://apache.org/xml/features/validate-annotations"; 80 81 82 protected static final String DYNAMIC_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/dynamic"; 83 84 85 protected static final String XINCLUDE_FEATURE_ID = "http://apache.org/xml/features/xinclude"; 86 87 88 protected static final String XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID = "http://apache.org/xml/features/xinclude/fixup-base-uris"; 89 90 91 protected static final String XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID = "http://apache.org/xml/features/xinclude/fixup-language"; 92 93 95 96 protected static final String DEFAULT_PARSER_NAME = "org.apache.xerces.parsers.SAXParser"; 97 98 99 protected static final int DEFAULT_REPETITION = 1; 100 101 102 protected static final boolean DEFAULT_NAMESPACES = true; 103 104 105 protected static final boolean DEFAULT_NAMESPACE_PREFIXES = false; 106 107 108 protected static final boolean DEFAULT_VALIDATION = false; 109 110 111 protected static final boolean DEFAULT_SCHEMA_VALIDATION = false; 112 113 114 protected static final boolean DEFAULT_SCHEMA_FULL_CHECKING = false; 115 116 117 protected static final boolean DEFAULT_VALIDATE_ANNOTATIONS = false; 118 119 120 protected static final boolean DEFAULT_DYNAMIC_VALIDATION = false; 121 122 123 protected static final boolean DEFAULT_XINCLUDE = false; 124 125 126 protected static final boolean DEFAULT_XINCLUDE_FIXUP_BASE_URIS = true; 127 128 129 protected static final boolean DEFAULT_XINCLUDE_FIXUP_LANGUAGE = true; 130 131 132 protected static final boolean DEFAULT_MEMORY_USAGE = false; 133 134 135 protected static final boolean DEFAULT_TAGGINESS = false; 136 137 141 142 protected long fElements; 143 144 145 protected long fAttributes; 146 147 148 protected long fCharacters; 149 150 151 protected long fIgnorableWhitespace; 152 153 154 protected long fTagCharacters; 155 156 157 protected long fOtherCharacters; 158 159 163 164 public Counter() { 165 } 167 171 172 public void printResults(PrintWriter out, String uri, long time, 173 long memory, boolean tagginess, 174 int repetition) { 175 176 out.print(uri); 178 out.print(": "); 179 if (repetition == 1) { 180 out.print(time); 181 } 182 else { 183 out.print(time); 184 out.print('/'); 185 out.print(repetition); 186 out.print('='); 187 out.print(time/repetition); 188 } 189 out.print(" ms"); 190 if (memory != Long.MIN_VALUE) { 191 out.print(", "); 192 out.print(memory); 193 out.print(" bytes"); 194 } 195 out.print(" ("); 196 out.print(fElements); 197 out.print(" elems, "); 198 out.print(fAttributes); 199 out.print(" attrs, "); 200 out.print(fIgnorableWhitespace); 201 out.print(" spaces, "); 202 out.print(fCharacters); 203 out.print(" chars)"); 204 if (tagginess) { 205 out.print(' '); 206 long totalCharacters = fTagCharacters + fOtherCharacters 207 + fCharacters + fIgnorableWhitespace; 208 long tagValue = fTagCharacters * 100 / totalCharacters; 209 out.print(tagValue); 210 out.print("% tagginess"); 211 } 212 out.println(); 213 out.flush(); 214 215 } 217 221 222 public void startDocument() throws SAXException { 223 224 fElements = 0; 225 fAttributes = 0; 226 fCharacters = 0; 227 fIgnorableWhitespace = 0; 228 fTagCharacters = 0; 229 230 } 232 233 public void startElement(String uri, String local, String raw, 234 Attributes attrs) throws SAXException { 235 236 fElements++; 237 fTagCharacters++; fTagCharacters += raw.length(); 239 if (attrs != null) { 240 int attrCount = attrs.getLength(); 241 fAttributes += attrCount; 242 for (int i = 0; i < attrCount; i++) { 243 fTagCharacters++; fTagCharacters += attrs.getQName(i).length(); 245 fTagCharacters++; fTagCharacters++; fOtherCharacters += attrs.getValue(i).length(); 248 fTagCharacters++; } 250 } 251 fTagCharacters++; 253 } 255 256 public void characters(char ch[], int start, int length) 257 throws SAXException { 258 259 fCharacters += length; 260 261 } 263 264 public void ignorableWhitespace(char ch[], int start, int length) 265 throws SAXException { 266 267 fIgnorableWhitespace += length; 268 269 } 271 272 public void processingInstruction(String target, String data) 273 throws SAXException { 274 fTagCharacters += 2; fTagCharacters += target.length(); 276 if (data != null && data.length() > 0) { 277 fTagCharacters++; fOtherCharacters += data.length(); 279 } 280 fTagCharacters += 2; } 283 287 288 public void warning(SAXParseException ex) throws SAXException { 289 printError("Warning", ex); 290 } 292 293 public void error(SAXParseException ex) throws SAXException { 294 printError("Error", ex); 295 } 297 298 public void fatalError(SAXParseException ex) throws SAXException { 299 printError("Fatal Error", ex); 300 } 303 307 308 protected void printError(String type, SAXParseException ex) { 309 310 System.err.print("["); 311 System.err.print(type); 312 System.err.print("] "); 313 if (ex== null) { 314 System.out.println("!!!"); 315 } 316 String systemId = ex.getSystemId(); 317 if (systemId != null) { 318 int index = systemId.lastIndexOf('/'); 319 if (index != -1) 320 systemId = systemId.substring(index + 1); 321 System.err.print(systemId); 322 } 323 System.err.print(':'); 324 System.err.print(ex.getLineNumber()); 325 System.err.print(':'); 326 System.err.print(ex.getColumnNumber()); 327 System.err.print(": "); 328 System.err.print(ex.getMessage()); 329 System.err.println(); 330 System.err.flush(); 331 332 } 334 338 339 public static void main(String argv[]) { 340 341 if (argv.length == 0) { 343 printUsage(); 344 System.exit(1); 345 } 346 347 Counter counter = new Counter(); 349 PrintWriter out = new PrintWriter (System.out); 350 XMLReader parser = null; 351 int repetition = DEFAULT_REPETITION; 352 boolean namespaces = DEFAULT_NAMESPACES; 353 boolean namespacePrefixes = DEFAULT_NAMESPACE_PREFIXES; 354 boolean validation = DEFAULT_VALIDATION; 355 boolean schemaValidation = DEFAULT_SCHEMA_VALIDATION; 356 boolean schemaFullChecking = DEFAULT_SCHEMA_FULL_CHECKING; 357 boolean validateAnnotations = DEFAULT_VALIDATE_ANNOTATIONS; 358 boolean dynamicValidation = DEFAULT_DYNAMIC_VALIDATION; 359 boolean xincludeProcessing = DEFAULT_XINCLUDE; 360 boolean xincludeFixupBaseURIs = DEFAULT_XINCLUDE_FIXUP_BASE_URIS; 361 boolean xincludeFixupLanguage = DEFAULT_XINCLUDE_FIXUP_LANGUAGE; 362 boolean memoryUsage = DEFAULT_MEMORY_USAGE; 363 boolean tagginess = DEFAULT_TAGGINESS; 364 365 for (int i = 0; i < argv.length; i++) { 367 String arg = argv[i]; 368 if (arg.startsWith("-")) { 369 String option = arg.substring(1); 370 if (option.equals("p")) { 371 if (++i == argv.length) { 373 System.err.println("error: Missing argument to -p option."); 374 continue; 375 } 376 String parserName = argv[i]; 377 378 try { 380 parser = XMLReaderFactory.createXMLReader(parserName); 381 } 382 catch (Exception e) { 383 try { 384 Parser sax1Parser = ParserFactory.makeParser(parserName); 385 parser = new ParserAdapter (sax1Parser); 386 System.err.println("warning: Features and properties not supported on SAX1 parsers."); 387 } 388 catch (Exception ex) { 389 parser = null; 390 System.err.println("error: Unable to instantiate parser ("+parserName+")"); 391 } 392 } 393 continue; 394 } 395 if (option.equals("x")) { 396 if (++i == argv.length) { 397 System.err.println("error: Missing argument to -x option."); 398 continue; 399 } 400 String number = argv[i]; 401 try { 402 int value = Integer.parseInt(number); 403 if (value < 1) { 404 System.err.println("error: Repetition must be at least 1."); 405 continue; 406 } 407 repetition = value; 408 } 409 catch (NumberFormatException e) { 410 System.err.println("error: invalid number ("+number+")."); 411 } 412 continue; 413 } 414 if (option.equalsIgnoreCase("n")) { 415 namespaces = option.equals("n"); 416 continue; 417 } 418 if (option.equalsIgnoreCase("np")) { 419 namespacePrefixes = option.equals("np"); 420 continue; 421 } 422 if (option.equalsIgnoreCase("v")) { 423 validation = option.equals("v"); 424 continue; 425 } 426 if (option.equalsIgnoreCase("s")) { 427 schemaValidation = option.equals("s"); 428 continue; 429 } 430 if (option.equalsIgnoreCase("f")) { 431 schemaFullChecking = option.equals("f"); 432 continue; 433 } 434 if (option.equalsIgnoreCase("va")) { 435 validateAnnotations = option.equals("va"); 436 continue; 437 } 438 if (option.equalsIgnoreCase("dv")) { 439 dynamicValidation = option.equals("dv"); 440 continue; 441 } 442 if (option.equalsIgnoreCase("xi")) { 443 xincludeProcessing = option.equals("xi"); 444 continue; 445 } 446 if (option.equalsIgnoreCase("xb")) { 447 xincludeFixupBaseURIs = option.equals("xb"); 448 continue; 449 } 450 if (option.equalsIgnoreCase("xl")) { 451 xincludeFixupLanguage = option.equals("xl"); 452 continue; 453 } 454 if (option.equalsIgnoreCase("m")) { 455 memoryUsage = option.equals("m"); 456 continue; 457 } 458 if (option.equalsIgnoreCase("t")) { 459 tagginess = option.equals("t"); 460 continue; 461 } 462 if (option.equals("-rem")) { 463 if (++i == argv.length) { 464 System.err.println("error: Missing argument to -# option."); 465 continue; 466 } 467 System.out.print("# "); 468 System.out.println(argv[i]); 469 continue; 470 } 471 if (option.equals("h")) { 472 printUsage(); 473 continue; 474 } 475 System.err.println("error: unknown option ("+option+")."); 476 continue; 477 } 478 479 if (parser == null) { 481 482 try { 484 parser = XMLReaderFactory.createXMLReader(DEFAULT_PARSER_NAME); 485 } 486 catch (Exception e) { 487 System.err.println("error: Unable to instantiate parser ("+DEFAULT_PARSER_NAME+")"); 488 continue; 489 } 490 } 491 492 try { 494 parser.setFeature(NAMESPACES_FEATURE_ID, namespaces); 495 } 496 catch (SAXException e) { 497 System.err.println("warning: Parser does not support feature ("+NAMESPACES_FEATURE_ID+")"); 498 } 499 try { 500 parser.setFeature(NAMESPACE_PREFIXES_FEATURE_ID, namespacePrefixes); 501 } 502 catch (SAXException e) { 503 System.err.println("warning: Parser does not support feature ("+NAMESPACE_PREFIXES_FEATURE_ID+")"); 504 } 505 try { 506 parser.setFeature(VALIDATION_FEATURE_ID, validation); 507 } 508 catch (SAXException e) { 509 System.err.println("warning: Parser does not support feature ("+VALIDATION_FEATURE_ID+")"); 510 } 511 try { 512 parser.setFeature(SCHEMA_VALIDATION_FEATURE_ID, schemaValidation); 513 } 514 catch (SAXNotRecognizedException e) { 515 System.err.println("warning: Parser does not recognize feature ("+SCHEMA_VALIDATION_FEATURE_ID+")"); 516 517 } 518 catch (SAXNotSupportedException e) { 519 System.err.println("warning: Parser does not support feature ("+SCHEMA_VALIDATION_FEATURE_ID+")"); 520 } 521 try { 522 parser.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, schemaFullChecking); 523 } 524 catch (SAXNotRecognizedException e) { 525 System.err.println("warning: Parser does not recognize feature ("+SCHEMA_FULL_CHECKING_FEATURE_ID+")"); 526 527 } 528 catch (SAXNotSupportedException e) { 529 System.err.println("warning: Parser does not support feature ("+SCHEMA_FULL_CHECKING_FEATURE_ID+")"); 530 } 531 try { 532 parser.setFeature(VALIDATE_ANNOTATIONS_ID, validateAnnotations); 533 } 534 catch (SAXNotRecognizedException e) { 535 System.err.println("warning: Parser does not recognize feature ("+VALIDATE_ANNOTATIONS_ID+")"); 536 537 } 538 catch (SAXNotSupportedException e) { 539 System.err.println("warning: Parser does not support feature ("+VALIDATE_ANNOTATIONS_ID+")"); 540 } 541 try { 542 parser.setFeature(DYNAMIC_VALIDATION_FEATURE_ID, dynamicValidation); 543 } 544 catch (SAXNotRecognizedException e) { 545 System.err.println("warning: Parser does not recognize feature ("+DYNAMIC_VALIDATION_FEATURE_ID+")"); 546 547 } 548 catch (SAXNotSupportedException e) { 549 System.err.println("warning: Parser does not support feature ("+DYNAMIC_VALIDATION_FEATURE_ID+")"); 550 } 551 try { 552 parser.setFeature(XINCLUDE_FEATURE_ID, xincludeProcessing); 553 } 554 catch (SAXNotRecognizedException e) { 555 System.err.println("warning: Parser does not recognize feature ("+XINCLUDE_FEATURE_ID+")"); 556 557 } 558 catch (SAXNotSupportedException e) { 559 System.err.println("warning: Parser does not support feature ("+XINCLUDE_FEATURE_ID+")"); 560 } 561 try { 562 parser.setFeature(XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID, xincludeFixupBaseURIs); 563 } 564 catch (SAXNotRecognizedException e) { 565 System.err.println("warning: Parser does not recognize feature ("+XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID+")"); 566 567 } 568 catch (SAXNotSupportedException e) { 569 System.err.println("warning: Parser does not support feature ("+XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID+")"); 570 } 571 try { 572 parser.setFeature(XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID, xincludeFixupLanguage); 573 } 574 catch (SAXNotRecognizedException e) { 575 System.err.println("warning: Parser does not recognize feature ("+XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID+")"); 576 577 } 578 catch (SAXNotSupportedException e) { 579 System.err.println("warning: Parser does not support feature ("+XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID+")"); 580 } 581 582 parser.setContentHandler(counter); 584 parser.setErrorHandler(counter); 585 try { 586 long timeBefore = System.currentTimeMillis(); 587 long memoryBefore = Runtime.getRuntime().freeMemory(); 588 for (int j = 0; j < repetition; j++) { 589 parser.parse(arg); 590 } 591 long memoryAfter = Runtime.getRuntime().freeMemory(); 592 long timeAfter = System.currentTimeMillis(); 593 594 long time = timeAfter - timeBefore; 595 long memory = memoryUsage 596 ? memoryBefore - memoryAfter : Long.MIN_VALUE; 597 counter.printResults(out, arg, time, memory, tagginess, 598 repetition); 599 } 600 catch (SAXParseException e) { 601 } 603 catch (Exception e) { 604 System.err.println("error: Parse error occurred - "+e.getMessage()); 605 Exception se = e; 606 if (e instanceof SAXException ) { 607 se = ((SAXException )e).getException(); 608 } 609 if (se != null) 610 se.printStackTrace(System.err); 611 else 612 e.printStackTrace(System.err); 613 614 } 615 } 616 617 } 619 623 624 private static void printUsage() { 625 626 System.err.println("usage: java sax.Counter (options) uri ..."); 627 System.err.println(); 628 629 System.err.println("options:"); 630 System.err.println(" -p name Select parser by name."); 631 System.err.println(" -x number Select number of repetitions."); 632 System.err.println(" -n | -N Turn on/off namespace processing."); 633 System.err.println(" -np | -NP Turn on/off namespace prefixes."); 634 System.err.println(" NOTE: Requires use of -n."); 635 System.err.println(" -v | -V Turn on/off validation."); 636 System.err.println(" -s | -S Turn on/off Schema validation support."); 637 System.err.println(" NOTE: Not supported by all parsers."); 638 System.err.println(" -f | -F Turn on/off Schema full checking."); 639 System.err.println(" NOTE: Requires use of -s and not supported by all parsers."); 640 System.err.println(" -va | -VA Turn on/off validation of schema annotations."); 641 System.err.println(" NOTE: Requires use of -s and not supported by all parsers."); 642 System.err.println(" -dv | -DV Turn on/off dynamic validation."); 643 System.err.println(" NOTE: Not supported by all parsers."); 644 System.err.println(" -xi | -XI Turn on/off XInclude processing."); 645 System.err.println(" NOTE: Not supported by all parsers."); 646 System.err.println(" -xb | -XB Turn on/off base URI fixup during XInclude processing."); 647 System.err.println(" NOTE: Requires use of -xi and not supported by all parsers."); 648 System.err.println(" -xl | -XL Turn on/off language fixup during XInclude processing."); 649 System.err.println(" NOTE: Requires use of -xi and not supported by all parsers."); 650 System.err.println(" -m | -M Turn on/off memory usage report"); 651 System.err.println(" -t | -T Turn on/off \"tagginess\" report."); 652 System.err.println(" --rem text Output user defined comment before next parse."); 653 System.err.println(" -h This help screen."); 654 655 System.err.println(); 656 System.err.println("defaults:"); 657 System.err.println(" Parser: "+DEFAULT_PARSER_NAME); 658 System.err.println(" Repetition: "+DEFAULT_REPETITION); 659 System.err.print(" Namespaces: "); 660 System.err.println(DEFAULT_NAMESPACES ? "on" : "off"); 661 System.err.print(" Prefixes: "); 662 System.err.println(DEFAULT_NAMESPACE_PREFIXES ? "on" : "off"); 663 System.err.print(" Validation: "); 664 System.err.println(DEFAULT_VALIDATION ? "on" : "off"); 665 System.err.print(" Schema: "); 666 System.err.println(DEFAULT_SCHEMA_VALIDATION ? "on" : "off"); 667 System.err.print(" Schema full checking: "); 668 System.err.println(DEFAULT_SCHEMA_FULL_CHECKING ? "on" : "off"); 669 System.err.print(" Dynamic: "); 670 System.err.println(DEFAULT_DYNAMIC_VALIDATION ? "on" : "off"); 671 System.err.print(" XInclude: "); 672 System.err.println(DEFAULT_XINCLUDE ? "on" : "off"); 673 System.err.print(" XInclude base URI fixup: "); 674 System.err.println(DEFAULT_XINCLUDE_FIXUP_BASE_URIS ? "on" : "off"); 675 System.err.print(" XInclude language fixup: "); 676 System.err.println(DEFAULT_XINCLUDE_FIXUP_LANGUAGE ? "on" : "off"); 677 System.err.print(" Memory: "); 678 System.err.println(DEFAULT_MEMORY_USAGE ? "on" : "off"); 679 System.err.print(" Tagginess: "); 680 System.err.println(DEFAULT_TAGGINESS ? "on" : "off"); 681 682 System.err.println(); 683 System.err.println("notes:"); 684 System.err.println(" The speed and memory results from this program should NOT be used as the"); 685 System.err.println(" basis of parser performance comparison! Real analytical methods should be"); 686 System.err.println(" used. For better results, perform multiple document parses within the same"); 687 System.err.println(" virtual machine to remove class loading from parse time and memory usage."); 688 System.err.println(); 689 System.err.println(" The \"tagginess\" measurement gives a rough estimate of the percentage of"); 690 System.err.println(" markup versus content in the XML document. The percent tagginess of a "); 691 System.err.println(" document is equal to the minimum amount of tag characters required for "); 692 System.err.println(" elements, attributes, and processing instructions divided by the total"); 693 System.err.println(" amount of characters (characters, ignorable whitespace, and tag characters)"); 694 System.err.println(" in the document."); 695 System.err.println(); 696 System.err.println(" Not all features are supported by different parsers."); 697 698 } 700 } | Popular Tags |