2
* The Apache Software License, Version 1.1
5
* Copyright (c) 1999-2002 The Apache Software Foundation. All rights
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in
17
* the documentation and/or other materials provided with the
20
* 3. The end-user documentation included with the redistribution,
21
* if any, must include the following acknowledgment:
22
* "This product includes software developed by the
23
* Apache Software Foundation (http://www.apache.org/)."
24
* Alternately, this acknowledgment may appear in the software itself,
25
* if and wherever such third-party acknowledgments normally appear.
27
* 4. The names "Xerces" and "Apache Software Foundation" must
28
* not be used to endorse or promote products derived from this
29
* software without prior written permission. For written
30
* permission, please contact apache@apache.org.
32
* 5. Products derived from this software may not be called "Apache",
33
* nor may "Apache" appear in their name, without prior written
34
* permission of the Apache Software Foundation.
36
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48
* ====================================================================
50
* This software consists of voluntary contributions made by many
51
* individuals on behalf of the Apache Software Foundation and was
52
* originally based on software copyright (c) 1999, International
53
* Business Machines, Inc., http://www.apache.org. For more
54
* information on the Apache Software Foundation, please see
55
* <http://www.apache.org/>.
60
import java.io.PrintWriter;
62
import org.w3c.dom.Document;
63
import org.w3c.dom.NamedNodeMap;
64
import org.w3c.dom.Node;
65
import org.w3c.dom.Text;
67
import org.xml.sax.SAXException;
68
import org.xml.sax.SAXParseException;
71
* A sample DOM counter. This sample program illustrates how to
72
* traverse a DOM tree in order to get information about the document.
73
* The output of this program shows the time and count of elements,
74
* attributes, ignorable whitespaces, and characters appearing in
75
* the document. Three times are shown: the parse time, the first
76
* traversal of the document, and the second traversal of the tree.
78
* This class is useful as a "poor-man's" performance tester to
79
* compare the speed and accuracy of various DOM parsers. However,
80
* it is important to note that the first parse time of a parser
81
* will include both VM class load time and parser initialization
82
* that would not be present in subsequent parses with the same
85
* <strong>Note:</strong> The results produced by this program
86
* should never be accepted as true performance measurements.
88
* @author Andy Clark, IBM
90
* @version $Id: Counter.java,v 1.9 2003/11/29 18:07:34 mrglavas Exp $
92
public class Counter {
100
/** Namespaces feature id (http://xml.org/sax/features/namespaces). */
101
protected static final String NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces";
103
/** Validation feature id (http://xml.org/sax/features/validation). */
104
protected static final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation";
106
/** Schema validation feature id (http://apache.org/xml/features/validation/schema). */
107
protected static final String SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema";
109
/** Schema full checking feature id (http://apache.org/xml/features/validation/schema-full-checking). */
110
protected static final String SCHEMA_FULL_CHECKING_FEATURE_ID = "http://apache.org/xml/features/validation/schema-full-checking";
112
/** Dynamic validation feature id (http://apache.org/xml/features/validation/dynamic). */
113
protected static final String DYNAMIC_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/dynamic";
117
/** Default parser name (dom.wrappers.Xerces). */
118
protected static final String DEFAULT_PARSER_NAME = "dom.wrappers.Xerces";
120
/** Default repetition (1). */
121
protected static final int DEFAULT_REPETITION = 1;
123
/** Default namespaces support (true). */
124
protected static final boolean DEFAULT_NAMESPACES = true;
126
/** Default validation support (false). */
127
protected static final boolean DEFAULT_VALIDATION = false;
129
/** Default Schema validation support (false). */
130
protected static final boolean DEFAULT_SCHEMA_VALIDATION = false;
132
/** Default Schema full checking support (false). */
133
protected static final boolean DEFAULT_SCHEMA_FULL_CHECKING = false;
135
/** Default dynamic validation support (false). */
136
protected static final boolean DEFAULT_DYNAMIC_VALIDATION = false;
142
/** Number of elements. */
143
protected long fElements;
145
/** Number of attributes. */
146
protected long fAttributes;
148
/** Number of characters. */
149
protected long fCharacters;
151
/** Number of ignorable whitespace characters. */
152
protected long fIgnorableWhitespace;
154
/** Document information. */
155
protected ParserWrapper.DocumentInfo fDocumentInfo;
161
/** Sets the parser wrapper. */
162
public void setDocumentInfo(ParserWrapper.DocumentInfo documentInfo) {
163
fDocumentInfo = documentInfo;
164
} // setDocumentInfo(ParserWrapper.DocumentInfo)
166
/** Traverses the specified node, recursively. */
167
public void count(Node node) {
169
// is there anything to do?
174
int type = node.getNodeType();
176
case Node.DOCUMENT_NODE: {
180
fIgnorableWhitespace = 0;
181
Document document = (Document)node;
182
count(document.getDocumentElement());
186
case Node.ELEMENT_NODE: {
188
NamedNodeMap attrs = node.getAttributes();
190
fAttributes += attrs.getLength();
192
// drop through to entity reference
195
case Node.ENTITY_REFERENCE_NODE: {
196
Node child = node.getFirstChild();
197
while (child != null) {
199
child = child.getNextSibling();
204
case Node.CDATA_SECTION_NODE: {
205
fCharacters += ((Text)node).getLength();
209
case Node.TEXT_NODE: {
210
if (fDocumentInfo != null) {
211
Text text = (Text)node;
212
int length = text.getLength();
213
if (fDocumentInfo.isIgnorableWhitespace(text)) {
214
fIgnorableWhitespace += length;
217
fCharacters += length;
226
/** Prints the results. */
227
public void printResults(PrintWriter out, String uri,
228
long parse, long traverse1, long traverse2,
231
// filename.xml: 631/200/100 ms (4 elems, 0 attrs, 78 spaces, 0 chars)
234
if (repetition == 1) {
240
out.print(repetition);
242
out.print(parse/repetition);
245
out.print(traverse1);
247
out.print(traverse2);
249
out.print(fElements);
250
out.print(" elems, ");
251
out.print(fAttributes);
252
out.print(" attrs, ");
253
out.print(fIgnorableWhitespace);
254
out.print(" spaces, ");
255
out.print(fCharacters);
256
out.print(" chars)");
260
} // printResults(PrintWriter,String,long,long,long)
266
/** Main program entry point. */
267
public static void main(String argv[]) {
269
// is there anything to do?
270
if (argv.length == 0) {
276
Counter counter = new Counter();
277
PrintWriter out = new PrintWriter(System.out);
278
ParserWrapper parser = null;
279
int repetition = DEFAULT_REPETITION;
280
boolean namespaces = DEFAULT_NAMESPACES;
281
boolean validation = DEFAULT_VALIDATION;
282
boolean schemaValidation = DEFAULT_SCHEMA_VALIDATION;
283
boolean schemaFullChecking = DEFAULT_SCHEMA_FULL_CHECKING;
284
boolean dynamicValidation = DEFAULT_DYNAMIC_VALIDATION;
287
for (int i = 0; i < argv.length; i++) {
288
String arg = argv[i];
289
if (arg.startsWith("-")) {
290
String option = arg.substring(1);
291
if (option.equals("p")) {
293
if (++i == argv.length) {
294
System.err.println("error: Missing argument to -p option.");
296
String parserName = argv[i];
300
parser = (ParserWrapper)Class.forName(parserName).newInstance();
302
catch (Exception e) {
304
System.err.println("error: Unable to instantiate parser ("+parserName+")");
308
if (option.equals("x")) {
309
if (++i == argv.length) {
310
System.err.println("error: Missing argument to -x option.");
313
String number = argv[i];
315
int value = Integer.parseInt(number);
317
System.err.println("error: Repetition must be at least 1.");
322
catch (NumberFormatException e) {
323
System.err.println("error: invalid number ("+number+").");
327
if (option.equalsIgnoreCase("n")) {
328
namespaces = option.equals("n");
331
if (option.equalsIgnoreCase("v")) {
332
validation = option.equals("v");
335
if (option.equalsIgnoreCase("s")) {
336
schemaValidation = option.equals("s");
339
if (option.equalsIgnoreCase("f")) {
340
schemaFullChecking = option.equals("f");
343
if (option.equalsIgnoreCase("dv")) {
344
dynamicValidation = option.equals("dv");
347
if (option.equals("h")) {
353
// use default parser?
354
if (parser == null) {
358
parser = (ParserWrapper)Class.forName(DEFAULT_PARSER_NAME).newInstance();
360
catch (Exception e) {
361
System.err.println("error: Unable to instantiate parser ("+DEFAULT_PARSER_NAME+")");
366
// set parser features
368
parser.setFeature(NAMESPACES_FEATURE_ID, namespaces);
370
catch (SAXException e) {
371
System.err.println("warning: Parser does not support feature ("+NAMESPACES_FEATURE_ID+")");
374
parser.setFeature(VALIDATION_FEATURE_ID, validation);
376
catch (SAXException e) {
377
System.err.println("warning: Parser does not support feature ("+VALIDATION_FEATURE_ID+")");
380
parser.setFeature(SCHEMA_VALIDATION_FEATURE_ID, schemaValidation);
382
catch (SAXException e) {
383
System.err.println("warning: Parser does not support feature ("+SCHEMA_VALIDATION_FEATURE_ID+")");
386
parser.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, schemaFullChecking);
388
catch (SAXException e) {
389
System.err.println("warning: Parser does not support feature ("+SCHEMA_FULL_CHECKING_FEATURE_ID+")");
392
parser.setFeature(DYNAMIC_VALIDATION_FEATURE_ID, dynamicValidation);
394
catch (SAXException e) {
395
System.err.println("warning: Parser does not support feature ("+DYNAMIC_VALIDATION_FEATURE_ID+")");
400
long beforeParse = System.currentTimeMillis();
401
Document document = null;
402
for (int j = 0; j < repetition; j++) {
403
document = parser.parse(arg);
405
long afterParse = System.currentTimeMillis();
406
long parse = afterParse - beforeParse;
408
ParserWrapper.DocumentInfo documentInfo = parser.getDocumentInfo();
409
counter.setDocumentInfo(documentInfo);
411
long beforeTraverse1 = System.currentTimeMillis();
412
counter.count(document);
413
long afterTraverse1 = System.currentTimeMillis();
414
long traverse1 = afterTraverse1 - beforeTraverse1;
416
long beforeTraverse2 = System.currentTimeMillis();
417
counter.count(document);
418
long afterTraverse2 = System.currentTimeMillis();
419
long traverse2 = afterTraverse2 - beforeTraverse2;
420
counter.printResults(out, arg, parse, traverse1, traverse2,
423
catch (SAXParseException e) {
426
catch (Exception e) {
427
System.err.println("error: Parse error occurred - "+e.getMessage());
429
if (e instanceof SAXException) {
430
se = ((SAXException)e).getException();
433
se.printStackTrace(System.err);
435
e.printStackTrace(System.err);
442
// Private static methods
445
/** Prints the usage. */
446
private static void printUsage() {
448
System.err.println("usage: java dom.Counter (options) uri ...");
449
System.err.println();
451
System.err.println("options:");
452
System.err.println(" -p name Select parser by name.");
453
System.err.println(" -x number Select number of repetitions.");
454
System.err.println(" -n | -N Turn on/off namespace processing.");
455
System.err.println(" -v | -V Turn on/off validation.");
456
System.err.println(" -s | -S Turn on/off Schema validation support.");
457
System.err.println(" NOTE: Not supported by all parsers.");
458
System.err.println(" -f | -F Turn on/off Schema full checking.");
459
System.err.println(" NOTE: Requires use of -s and not supported by all parsers.");
460
System.err.println(" -dv | -DV Turn on/off dynamic validation.");
461
System.err.println(" NOTE: Not supported by all parsers.");
462
System.err.println(" -h This help screen.");
463
System.err.println();
465
System.err.println("defaults:");
466
System.err.println(" Parser: "+DEFAULT_PARSER_NAME);
467
System.err.println(" Repetition: "+DEFAULT_REPETITION);
468
System.err.print(" Namespaces: ");
469
System.err.println(DEFAULT_NAMESPACES ? "on" : "off");
470
System.err.print(" Validation: ");
471
System.err.println(DEFAULT_VALIDATION ? "on" : "off");
472
System.err.print(" Schema: ");
473
System.err.println(DEFAULT_SCHEMA_VALIDATION ? "on" : "off");
474
System.err.print(" Schema full checking: ");
475
System.err.println(DEFAULT_SCHEMA_FULL_CHECKING ? "on" : "off");
476
System.err.print(" Dynamic: ");
477
System.err.println(DEFAULT_DYNAMIC_VALIDATION ? "on" : "off");