1 16 17 package xni; 18 19 import java.io.PrintWriter ; 20 21 import org.apache.xerces.parsers.XMLDocumentParser; 22 import org.apache.xerces.xni.Augmentations; 23 import org.apache.xerces.xni.QName; 24 import org.apache.xerces.xni.XMLAttributes; 25 import org.apache.xerces.xni.XMLLocator; 26 import org.apache.xerces.xni.XMLString; 27 import org.apache.xerces.xni.XNIException; 28 import org.apache.xerces.xni.NamespaceContext; 29 import org.apache.xerces.xni.parser.XMLConfigurationException; 30 import org.apache.xerces.xni.parser.XMLErrorHandler; 31 import org.apache.xerces.xni.parser.XMLInputSource; 32 import org.apache.xerces.xni.parser.XMLParseException; 33 import org.apache.xerces.xni.parser.XMLParserConfiguration; 34 35 54 public class Counter 55 extends XMLDocumentParser 56 implements XMLErrorHandler { 57 58 62 64 65 protected static final String NAMESPACES_FEATURE_ID = 66 "http://xml.org/sax/features/namespaces"; 67 68 69 protected static final String NAMESPACE_PREFIXES_FEATURE_ID = 70 "http://xml.org/sax/features/namespace-prefixes"; 71 72 73 protected static final String VALIDATION_FEATURE_ID = 74 "http://xml.org/sax/features/validation"; 75 76 77 protected static final String SCHEMA_VALIDATION_FEATURE_ID = 78 "http://apache.org/xml/features/validation/schema"; 79 80 81 protected static final String SCHEMA_FULL_CHECKING_FEATURE_ID = 82 "http://apache.org/xml/features/validation/schema-full-checking"; 83 84 86 87 protected static final String DEFAULT_PARSER_CONFIG = 88 "org.apache.xerces.parsers.XIncludeAwareParserConfiguration"; 89 90 91 protected static final int DEFAULT_REPETITION = 1; 92 93 94 protected static final boolean DEFAULT_NAMESPACES = true; 95 96 97 protected static final boolean DEFAULT_NAMESPACE_PREFIXES = false; 98 99 100 protected static final boolean DEFAULT_VALIDATION = false; 101 102 103 protected static final boolean DEFAULT_SCHEMA_VALIDATION = false; 104 105 106 protected static final boolean DEFAULT_SCHEMA_FULL_CHECKING = false; 107 108 109 protected static final boolean DEFAULT_MEMORY_USAGE = false; 110 111 112 protected static final boolean DEFAULT_TAGGINESS = false; 113 114 118 119 protected long fElements; 120 121 122 protected long fAttributes; 123 124 125 protected long fCharacters; 126 127 128 protected long fIgnorableWhitespace; 129 130 131 protected long fTagCharacters; 132 133 134 protected long fOtherCharacters; 135 136 140 141 public Counter(XMLParserConfiguration configuration) { 142 super(configuration); 143 fConfiguration.setErrorHandler(this); 144 } 146 150 151 public void printResults(PrintWriter out, String uri, long time, 152 long memory, boolean tagginess, 153 int repetition) { 154 155 out.print(uri); 157 out.print(": "); 158 if (repetition == 1) { 159 out.print(time); 160 } 161 else { 162 out.print(time); 163 out.print('/'); 164 out.print(repetition); 165 out.print('='); 166 out.print(time/repetition); 167 } 168 out.print(" ms"); 169 if (memory != Long.MIN_VALUE) { 170 out.print(", "); 171 out.print(memory); 172 out.print(" bytes"); 173 } 174 out.print(" ("); 175 out.print(fElements); 176 out.print(" elems, "); 177 out.print(fAttributes); 178 out.print(" attrs, "); 179 out.print(fIgnorableWhitespace); 180 out.print(" spaces, "); 181 out.print(fCharacters); 182 out.print(" chars)"); 183 if (tagginess) { 184 out.print(' '); 185 long totalCharacters = fTagCharacters + fOtherCharacters 186 + fCharacters + fIgnorableWhitespace; 187 long tagValue = fTagCharacters * 100 / totalCharacters; 188 out.print(tagValue); 189 out.print("% tagginess"); 190 } 191 out.println(); 192 out.flush(); 193 194 } 196 200 201 public void startDocument(XMLLocator locator, String encoding, NamespaceContext namespaceContext, Augmentations augs) 202 throws XNIException { 203 204 fElements = 0; 205 fAttributes = 0; 206 fCharacters = 0; 207 fIgnorableWhitespace = 0; 208 fTagCharacters = 0; 209 fOtherCharacters = 0; 210 211 } 213 214 public void startElement(QName element, XMLAttributes attrs, Augmentations augs) 215 throws XNIException { 216 217 fElements++; 218 fTagCharacters++; fTagCharacters += element.rawname.length(); 220 if (attrs != null) { 221 int attrCount = attrs.getLength(); 222 fAttributes += attrCount; 223 for (int i = 0; i < attrCount; i++) { 224 fTagCharacters++; fTagCharacters += attrs.getQName(i).length(); 226 fTagCharacters++; fTagCharacters++; fOtherCharacters += attrs.getValue(i).length(); 229 fTagCharacters++; } 231 } 232 fTagCharacters++; 234 } 236 237 public void emptyElement(QName element, XMLAttributes attrs, Augmentations augs) 238 throws XNIException { 239 240 fElements++; 241 fTagCharacters++; fTagCharacters += element.rawname.length(); 243 if (attrs != null) { 244 int attrCount = attrs.getLength(); 245 fAttributes += attrCount; 246 for (int i = 0; i < attrCount; i++) { 247 fTagCharacters++; fTagCharacters += attrs.getQName(i).length(); 249 fTagCharacters++; fTagCharacters++; fOtherCharacters += attrs.getValue(i).length(); 252 fTagCharacters++; } 254 } 255 fTagCharacters++; fTagCharacters++; 258 } 260 261 public void characters(XMLString text, Augmentations augs) throws XNIException { 262 263 fCharacters += text.length; 264 265 } 267 268 public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException { 269 270 fIgnorableWhitespace += text.length; 271 272 } 274 275 public void processingInstruction(String target, XMLString data, Augmentations augs) 276 throws XNIException { 277 fTagCharacters += 2; fTagCharacters += target.length(); 279 if (data.length > 0) { 280 fTagCharacters++; fOtherCharacters += data.length; 282 } 283 fTagCharacters += 2; } 286 290 291 public void warning(String domain, String key, XMLParseException ex) 292 throws XNIException { 293 printError("Warning", ex); 294 } 296 297 public void error(String domain, String key, XMLParseException ex) 298 throws XNIException { 299 printError("Error", ex); 300 } 302 303 public void fatalError(String domain, String key, XMLParseException ex) 304 throws XNIException { 305 printError("Fatal Error", ex); 306 throw ex; 307 } 309 313 314 protected void printError(String type, XMLParseException ex) { 315 316 System.err.print("["); 317 System.err.print(type); 318 System.err.print("] "); 319 String systemId = ex.getExpandedSystemId(); 320 if (systemId != null) { 321 int index = systemId.lastIndexOf('/'); 322 if (index != -1) 323 systemId = systemId.substring(index + 1); 324 System.err.print(systemId); 325 } 326 System.err.print(':'); 327 System.err.print(ex.getLineNumber()); 328 System.err.print(':'); 329 System.err.print(ex.getColumnNumber()); 330 System.err.print(": "); 331 System.err.print(ex.getMessage()); 332 System.err.println(); 333 System.err.flush(); 334 335 } 337 341 342 public static void main(String argv[]) { 343 344 if (argv.length == 0) { 346 printUsage(); 347 System.exit(1); 348 } 349 350 PrintWriter out = new PrintWriter (System.out); 352 XMLDocumentParser parser = null; 353 XMLParserConfiguration parserConfig = null; 354 int repetition = DEFAULT_REPETITION; 355 boolean namespaces = DEFAULT_NAMESPACES; 356 boolean namespacePrefixes = DEFAULT_NAMESPACE_PREFIXES; 357 boolean validation = DEFAULT_VALIDATION; 358 boolean schemaValidation = DEFAULT_SCHEMA_VALIDATION; 359 boolean schemaFullChecking = DEFAULT_SCHEMA_FULL_CHECKING; 360 boolean memoryUsage = DEFAULT_MEMORY_USAGE; 361 boolean tagginess = DEFAULT_TAGGINESS; 362 363 for (int i = 0; i < argv.length; i++) { 365 String arg = argv[i]; 366 if (arg.startsWith("-")) { 367 String option = arg.substring(1); 368 if (option.equals("p")) { 369 if (++i == argv.length) { 371 System.err.println("error: Missing argument to -p option."); 372 continue; 373 } 374 String parserName = argv[i]; 375 376 try { 378 parserConfig = (XMLParserConfiguration)ObjectFactory.newInstance(parserName, 379 ObjectFactory.findClassLoader(), true); 380 parserConfig.addRecognizedFeatures(new String [] { 381 NAMESPACE_PREFIXES_FEATURE_ID, 382 }); 383 parser = null; 384 } 385 catch (Exception e) { 386 parserConfig = null; 387 System.err.println("error: Unable to instantiate parser configuration ("+parserName+")"); 388 } 389 continue; 390 } 391 if (option.equals("x")) { 392 if (++i == argv.length) { 393 System.err.println("error: Missing argument to -x option."); 394 continue; 395 } 396 String number = argv[i]; 397 try { 398 int value = Integer.parseInt(number); 399 if (value < 1) { 400 System.err.println("error: Repetition must be at least 1."); 401 continue; 402 } 403 repetition = value; 404 } 405 catch (NumberFormatException e) { 406 System.err.println("error: invalid number ("+number+")."); 407 } 408 continue; 409 } 410 if (option.equalsIgnoreCase("n")) { 411 namespaces = option.equals("n"); 412 continue; 413 } 414 if (option.equalsIgnoreCase("np")) { 415 namespacePrefixes = option.equals("np"); 416 continue; 417 } 418 if (option.equalsIgnoreCase("v")) { 419 validation = option.equals("v"); 420 continue; 421 } 422 if (option.equalsIgnoreCase("s")) { 423 schemaValidation = option.equals("s"); 424 continue; 425 } 426 if (option.equalsIgnoreCase("f")) { 427 schemaFullChecking = option.equals("f"); 428 continue; 429 } 430 if (option.equalsIgnoreCase("m")) { 431 memoryUsage = option.equals("m"); 432 continue; 433 } 434 if (option.equalsIgnoreCase("t")) { 435 tagginess = option.equals("t"); 436 continue; 437 } 438 if (option.equals("-rem")) { 439 if (++i == argv.length) { 440 System.err.println("error: Missing argument to -# option."); 441 continue; 442 } 443 System.out.print("# "); 444 System.out.println(argv[i]); 445 continue; 446 } 447 if (option.equals("h")) { 448 printUsage(); 449 continue; 450 } 451 System.err.println("error: unknown option ("+option+")."); 452 continue; 453 } 454 455 if (parserConfig == null) { 457 458 try { 460 parserConfig = (XMLParserConfiguration)ObjectFactory.newInstance(DEFAULT_PARSER_CONFIG, 461 ObjectFactory.findClassLoader(), true); 462 parserConfig.addRecognizedFeatures(new String [] { 463 NAMESPACE_PREFIXES_FEATURE_ID, 464 }); 465 } 466 catch (Exception e) { 467 System.err.println("error: Unable to instantiate parser configuration ("+DEFAULT_PARSER_CONFIG+")"); 468 continue; 469 } 470 } 471 472 if (parser == null) { 474 parser = new Counter(parserConfig); 475 } 476 try { 477 parserConfig.setFeature(NAMESPACES_FEATURE_ID, namespaces); 478 } 479 catch (XMLConfigurationException e) { 480 System.err.println("warning: Parser does not support feature ("+NAMESPACES_FEATURE_ID+")"); 481 } 482 try { 483 parserConfig.setFeature(VALIDATION_FEATURE_ID, validation); 484 } 485 catch (XMLConfigurationException e) { 486 System.err.println("warning: Parser does not support feature ("+VALIDATION_FEATURE_ID+")"); 487 } 488 try { 489 parserConfig.setFeature(SCHEMA_VALIDATION_FEATURE_ID, schemaValidation); 490 } 491 catch (XMLConfigurationException e) { 492 if (e.getType() == XMLConfigurationException.NOT_SUPPORTED) { 493 System.err.println("warning: Parser does not support feature ("+SCHEMA_VALIDATION_FEATURE_ID+")"); 494 } 495 } 496 try { 497 parserConfig.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, schemaFullChecking); 498 } 499 catch (XMLConfigurationException e) { 500 if (e.getType() == XMLConfigurationException.NOT_SUPPORTED) { 501 System.err.println("warning: Parser does not support feature ("+SCHEMA_FULL_CHECKING_FEATURE_ID+")"); 502 } 503 } 504 505 try { 507 long timeBefore = System.currentTimeMillis(); 508 long memoryBefore = 0; 509 if(memoryUsage) { 510 System.gc(); 511 memoryBefore = Runtime.getRuntime().freeMemory(); 512 } 513 for (int j = 0; j < repetition; j++) { 514 parser.parse(new XMLInputSource(null, arg, null)); 515 } 516 long memory = Long.MIN_VALUE; 517 if(memoryUsage) { 518 long memoryAfter = Runtime.getRuntime().freeMemory(); 519 memory = memoryBefore - memoryAfter; 520 } 521 522 long timeAfter = System.currentTimeMillis(); 523 long time = timeAfter - timeBefore; 524 ((Counter)parser).printResults(out, arg, time, 525 memory, tagginess, 526 repetition); 527 } 528 catch (XMLParseException e) { 529 } 531 catch (Exception e) { 532 System.err.println("error: Parse error occurred - "+e.getMessage()); 533 if (e instanceof XNIException) { 534 e = ((XNIException)e).getException(); 535 } 536 e.printStackTrace(System.err); 537 } 538 } 539 540 } 542 546 547 private static void printUsage() { 548 549 System.err.println("usage: java xni.Counter (options) uri ..."); 550 System.err.println(); 551 552 System.err.println("options:"); 553 System.err.println(" -p name Select parser configuration by name."); 554 System.err.println(" -x number Select number of repetitions."); 555 System.err.println(" -n | -N Turn on/off namespace processing."); 556 System.err.println(" -np | -NP Turn on/off namespace prefixes."); 557 System.err.println(" NOTE: Requires use of -n."); 558 System.err.println(" -v | -V Turn on/off validation."); 559 System.err.println(" -s | -S Turn on/off Schema validation support."); 560 System.err.println(" NOTE: Not supported by all parser configurations."); 561 System.err.println(" -f | -F Turn on/off Schema full checking."); 562 System.err.println(" NOTE: Requires use of -s and not supported by all parsers."); 563 System.err.println(" -m | -M Turn on/off memory usage report."); 564 System.err.println(" -t | -T Turn on/off \"tagginess\" report."); 565 System.err.println(" --rem text Output user defined comment before next parse."); 566 System.err.println(" -h This help screen."); 567 568 System.err.println(); 569 System.err.println("defaults:"); 570 System.err.println(" Config: "+DEFAULT_PARSER_CONFIG); 571 System.err.println(" Repetition: "+DEFAULT_REPETITION); 572 System.err.print(" Namespaces: "); 573 System.err.println(DEFAULT_NAMESPACES ? "on" : "off"); 574 System.err.print(" Prefixes: "); 575 System.err.println(DEFAULT_NAMESPACE_PREFIXES ? "on" : "off"); 576 System.err.print(" Validation: "); 577 System.err.println(DEFAULT_VALIDATION ? "on" : "off"); 578 System.err.print(" Schema: "); 579 System.err.println(DEFAULT_SCHEMA_VALIDATION ? "on" : "off"); 580 System.err.print(" Schema full checking: "); 581 System.err.println(DEFAULT_SCHEMA_FULL_CHECKING ? "on" : "off"); 582 System.err.print(" Memory: "); 583 System.err.println(DEFAULT_MEMORY_USAGE ? "on" : "off"); 584 System.err.print(" Tagginess: "); 585 System.err.println(DEFAULT_TAGGINESS ? "on" : "off"); 586 587 System.err.println(); 588 System.err.println("notes:"); 589 System.err.println(" The speed and memory results from this program should NOT be used as the"); 590 System.err.println(" basis of parser performance comparison! Real analytical methods should be"); 591 System.err.println(" used. For better results, perform multiple document parses within the same"); 592 System.err.println(" virtual machine to remove class loading from parse time and memory usage."); 593 System.err.println(); 594 System.err.println(" The \"tagginess\" measurement gives a rough estimate of the percentage of"); 595 System.err.println(" markup versus content in the XML document. The percent tagginess of a "); 596 System.err.println(" document is equal to the minimum amount of tag characters required for "); 597 System.err.println(" elements, attributes, and processing instructions divided by the total"); 598 System.err.println(" amount of characters (characters, ignorable whitespace, and tag characters)"); 599 System.err.println(" in the document."); 600 System.err.println(); 601 System.err.println(" Not all features are supported by different parser configurations."); 602 603 } 605 } | Popular Tags |