KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > dom > Counter


1 /*
2  * Copyright 1999-2002,2004,2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package dom;
18
19 import java.io.PrintWriter JavaDoc;
20
21 import org.w3c.dom.Document JavaDoc;
22 import org.w3c.dom.NamedNodeMap JavaDoc;
23 import org.w3c.dom.Node JavaDoc;
24 import org.w3c.dom.Text JavaDoc;
25 import org.xml.sax.SAXException JavaDoc;
26 import org.xml.sax.SAXParseException JavaDoc;
27
28 /**
29  * A sample DOM counter. This sample program illustrates how to
30  * traverse a DOM tree in order to get information about the document.
31  * The output of this program shows the time and count of elements,
32  * attributes, ignorable whitespaces, and characters appearing in
33  * the document. Three times are shown: the parse time, the first
34  * traversal of the document, and the second traversal of the tree.
35  * <p>
36  * This class is useful as a "poor-man's" performance tester to
37  * compare the speed and accuracy of various DOM parsers. However,
38  * it is important to note that the first parse time of a parser
39  * will include both VM class load time and parser initialization
40  * that would not be present in subsequent parses with the same
41  * file.
42  * <p>
43  * <strong>Note:</strong> The results produced by this program
44  * should never be accepted as true performance measurements.
45  *
46  * @author Andy Clark, IBM
47  *
48  * @version $Id: Counter.java,v 1.13 2005/05/09 01:01:40 mrglavas Exp $
49  */

50 public class Counter {
51
52     //
53
// Constants
54
//
55

56     // feature ids
57

58     /** Namespaces feature id (http://xml.org/sax/features/namespaces). */
59     protected static final String JavaDoc NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces";
60
61     /** Validation feature id (http://xml.org/sax/features/validation). */
62     protected static final String JavaDoc VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation";
63
64     /** Schema validation feature id (http://apache.org/xml/features/validation/schema). */
65     protected static final String JavaDoc SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema";
66
67     /** Schema full checking feature id (http://apache.org/xml/features/validation/schema-full-checking). */
68     protected static final String JavaDoc SCHEMA_FULL_CHECKING_FEATURE_ID = "http://apache.org/xml/features/validation/schema-full-checking";
69     
70     /** Validate schema annotations feature id (http://apache.org/xml/features/validate-annotations). */
71     protected static final String JavaDoc VALIDATE_ANNOTATIONS_ID = "http://apache.org/xml/features/validate-annotations";
72     
73     /** Dynamic validation feature id (http://apache.org/xml/features/validation/dynamic). */
74     protected static final String JavaDoc DYNAMIC_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/dynamic";
75     
76     /** XInclude feature id (http://apache.org/xml/features/xinclude). */
77     protected static final String JavaDoc XINCLUDE_FEATURE_ID = "http://apache.org/xml/features/xinclude";
78     
79     /** XInclude fixup base URIs feature id (http://apache.org/xml/features/xinclude/fixup-base-uris). */
80     protected static final String JavaDoc XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID = "http://apache.org/xml/features/xinclude/fixup-base-uris";
81     
82     /** XInclude fixup language feature id (http://apache.org/xml/features/xinclude/fixup-language). */
83     protected static final String JavaDoc XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID = "http://apache.org/xml/features/xinclude/fixup-language";
84
85     // default settings
86

87     /** Default parser name (dom.wrappers.Xerces). */
88     protected static final String JavaDoc DEFAULT_PARSER_NAME = "dom.wrappers.Xerces";
89
90     /** Default repetition (1). */
91     protected static final int DEFAULT_REPETITION = 1;
92
93     /** Default namespaces support (true). */
94     protected static final boolean DEFAULT_NAMESPACES = true;
95
96     /** Default validation support (false). */
97     protected static final boolean DEFAULT_VALIDATION = false;
98
99     /** Default Schema validation support (false). */
100     protected static final boolean DEFAULT_SCHEMA_VALIDATION = false;
101
102     /** Default Schema full checking support (false). */
103     protected static final boolean DEFAULT_SCHEMA_FULL_CHECKING = false;
104     
105     /** Default validate schema annotations (false). */
106     protected static final boolean DEFAULT_VALIDATE_ANNOTATIONS = false;
107
108     /** Default dynamic validation support (false). */
109     protected static final boolean DEFAULT_DYNAMIC_VALIDATION = false;
110     
111     /** Default XInclude processing support (false). */
112     protected static final boolean DEFAULT_XINCLUDE = false;
113     
114     /** Default XInclude fixup base URIs support (true). */
115     protected static final boolean DEFAULT_XINCLUDE_FIXUP_BASE_URIS = true;
116     
117     /** Default XInclude fixup language support (true). */
118     protected static final boolean DEFAULT_XINCLUDE_FIXUP_LANGUAGE = true;
119
120     //
121
// Data
122
//
123

124     /** Number of elements. */
125     protected long fElements;
126
127     /** Number of attributes. */
128     protected long fAttributes;
129
130     /** Number of characters. */
131     protected long fCharacters;
132
133     /** Number of ignorable whitespace characters. */
134     protected long fIgnorableWhitespace;
135
136     /** Document information. */
137     protected ParserWrapper.DocumentInfo fDocumentInfo;
138
139     //
140
// Public methods
141
//
142

143     /** Sets the parser wrapper. */
144     public void setDocumentInfo(ParserWrapper.DocumentInfo documentInfo) {
145         fDocumentInfo = documentInfo;
146     } // setDocumentInfo(ParserWrapper.DocumentInfo)
147

148     /** Traverses the specified node, recursively. */
149     public void count(Node JavaDoc node) {
150
151         // is there anything to do?
152
if (node == null) {
153             return;
154         }
155
156         int type = node.getNodeType();
157         switch (type) {
158             case Node.DOCUMENT_NODE: {
159                 fElements = 0;
160                 fAttributes = 0;
161                 fCharacters = 0;
162                 fIgnorableWhitespace = 0;
163                 Document JavaDoc document = (Document JavaDoc)node;
164                 count(document.getDocumentElement());
165                 break;
166             }
167
168             case Node.ELEMENT_NODE: {
169                 fElements++;
170                 NamedNodeMap JavaDoc attrs = node.getAttributes();
171                 if (attrs != null) {
172                     fAttributes += attrs.getLength();
173                 }
174                 // drop through to entity reference
175
}
176
177             case Node.ENTITY_REFERENCE_NODE: {
178                 Node JavaDoc child = node.getFirstChild();
179                 while (child != null) {
180                     count(child);
181                     child = child.getNextSibling();
182                 }
183                 break;
184             }
185
186             case Node.CDATA_SECTION_NODE: {
187                 fCharacters += ((Text JavaDoc)node).getLength();
188                 break;
189             }
190
191             case Node.TEXT_NODE: {
192                 if (fDocumentInfo != null) {
193                     Text JavaDoc text = (Text JavaDoc)node;
194                     int length = text.getLength();
195                     if (fDocumentInfo.isIgnorableWhitespace(text)) {
196                         fIgnorableWhitespace += length;
197                     }
198                     else {
199                         fCharacters += length;
200                     }
201                 }
202                 break;
203             }
204         }
205
206     } // count(Node)
207

208     /** Prints the results. */
209     public void printResults(PrintWriter JavaDoc out, String JavaDoc uri,
210                              long parse, long traverse1, long traverse2,
211                              int repetition) {
212
213         // filename.xml: 631/200/100 ms (4 elems, 0 attrs, 78 spaces, 0 chars)
214
out.print(uri);
215         out.print(": ");
216         if (repetition == 1) {
217             out.print(parse);
218         }
219         else {
220             out.print(parse);
221             out.print('/');
222             out.print(repetition);
223             out.print('=');
224             out.print(parse/repetition);
225         }
226         out.print(';');
227         out.print(traverse1);
228         out.print(';');
229         out.print(traverse2);
230         out.print(" ms (");
231         out.print(fElements);
232         out.print(" elems, ");
233         out.print(fAttributes);
234         out.print(" attrs, ");
235         out.print(fIgnorableWhitespace);
236         out.print(" spaces, ");
237         out.print(fCharacters);
238         out.print(" chars)");
239         out.println();
240         out.flush();
241
242     } // printResults(PrintWriter,String,long,long,long)
243

244     //
245
// MAIN
246
//
247

248     /** Main program entry point. */
249     public static void main(String JavaDoc argv[]) {
250
251         // is there anything to do?
252
if (argv.length == 0) {
253             printUsage();
254             System.exit(1);
255         }
256
257         // variables
258
Counter counter = new Counter();
259         PrintWriter JavaDoc out = new PrintWriter JavaDoc(System.out);
260         ParserWrapper parser = null;
261         int repetition = DEFAULT_REPETITION;
262         boolean namespaces = DEFAULT_NAMESPACES;
263         boolean validation = DEFAULT_VALIDATION;
264         boolean schemaValidation = DEFAULT_SCHEMA_VALIDATION;
265         boolean schemaFullChecking = DEFAULT_SCHEMA_FULL_CHECKING;
266         boolean validateAnnotations = DEFAULT_VALIDATE_ANNOTATIONS;
267         boolean dynamicValidation = DEFAULT_DYNAMIC_VALIDATION;
268         boolean xincludeProcessing = DEFAULT_XINCLUDE;
269         boolean xincludeFixupBaseURIs = DEFAULT_XINCLUDE_FIXUP_BASE_URIS;
270         boolean xincludeFixupLanguage = DEFAULT_XINCLUDE_FIXUP_LANGUAGE;
271
272         // process arguments
273
for (int i = 0; i < argv.length; i++) {
274             String JavaDoc arg = argv[i];
275             if (arg.startsWith("-")) {
276                 String JavaDoc option = arg.substring(1);
277                 if (option.equals("p")) {
278                     // get parser name
279
if (++i == argv.length) {
280                         System.err.println("error: Missing argument to -p option.");
281                     }
282                     String JavaDoc parserName = argv[i];
283
284                     // create parser
285
try {
286                         parser = (ParserWrapper)Class.forName(parserName).newInstance();
287                     }
288                     catch (Exception JavaDoc e) {
289                         parser = null;
290                         System.err.println("error: Unable to instantiate parser ("+parserName+")");
291                     }
292                     continue;
293                 }
294                 if (option.equals("x")) {
295                     if (++i == argv.length) {
296                         System.err.println("error: Missing argument to -x option.");
297                         continue;
298                     }
299                     String JavaDoc number = argv[i];
300                     try {
301                         int value = Integer.parseInt(number);
302                         if (value < 1) {
303                             System.err.println("error: Repetition must be at least 1.");
304                             continue;
305                         }
306                         repetition = value;
307                     }
308                     catch (NumberFormatException JavaDoc e) {
309                         System.err.println("error: invalid number ("+number+").");
310                     }
311                     continue;
312                 }
313                 if (option.equalsIgnoreCase("n")) {
314                     namespaces = option.equals("n");
315                     continue;
316                 }
317                 if (option.equalsIgnoreCase("v")) {
318                     validation = option.equals("v");
319                     continue;
320                 }
321                 if (option.equalsIgnoreCase("s")) {
322                     schemaValidation = option.equals("s");
323                     continue;
324                 }
325                 if (option.equalsIgnoreCase("f")) {
326                     schemaFullChecking = option.equals("f");
327                     continue;
328                 }
329                 if (option.equalsIgnoreCase("va")) {
330                     validateAnnotations = option.equals("va");
331                     continue;
332                 }
333                 if (option.equalsIgnoreCase("dv")) {
334                     dynamicValidation = option.equals("dv");
335                     continue;
336                 }
337                 if (option.equalsIgnoreCase("xi")) {
338                     xincludeProcessing = option.equals("xi");
339                     continue;
340                 }
341                 if (option.equalsIgnoreCase("xb")) {
342                     xincludeFixupBaseURIs = option.equals("xb");
343                     continue;
344                 }
345                 if (option.equalsIgnoreCase("xl")) {
346                     xincludeFixupLanguage = option.equals("xl");
347                     continue;
348                 }
349                 if (option.equals("h")) {
350                     printUsage();
351                     continue;
352                 }
353             }
354
355             // use default parser?
356
if (parser == null) {
357
358                 // create parser
359
try {
360                     parser = (ParserWrapper)Class.forName(DEFAULT_PARSER_NAME).newInstance();
361                 }
362                 catch (Exception JavaDoc e) {
363                     System.err.println("error: Unable to instantiate parser ("+DEFAULT_PARSER_NAME+")");
364                     continue;
365                 }
366             }
367
368             // set parser features
369
try {
370                 parser.setFeature(NAMESPACES_FEATURE_ID, namespaces);
371             }
372             catch (SAXException JavaDoc e) {
373                 System.err.println("warning: Parser does not support feature ("+NAMESPACES_FEATURE_ID+")");
374             }
375             try {
376                 parser.setFeature(VALIDATION_FEATURE_ID, validation);
377             }
378             catch (SAXException JavaDoc e) {
379                 System.err.println("warning: Parser does not support feature ("+VALIDATION_FEATURE_ID+")");
380             }
381             try {
382                 parser.setFeature(SCHEMA_VALIDATION_FEATURE_ID, schemaValidation);
383             }
384             catch (SAXException JavaDoc e) {
385                 System.err.println("warning: Parser does not support feature ("+SCHEMA_VALIDATION_FEATURE_ID+")");
386             }
387             try {
388                 parser.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, schemaFullChecking);
389             }
390             catch (SAXException JavaDoc e) {
391                 System.err.println("warning: Parser does not support feature ("+SCHEMA_FULL_CHECKING_FEATURE_ID+")");
392             }
393             try {
394                 parser.setFeature(VALIDATE_ANNOTATIONS_ID, validateAnnotations);
395             }
396             catch (SAXException JavaDoc e) {
397                 System.err.println("warning: Parser does not support feature ("+VALIDATE_ANNOTATIONS_ID+")");
398             }
399             try {
400                 parser.setFeature(DYNAMIC_VALIDATION_FEATURE_ID, dynamicValidation);
401             }
402             catch (SAXException JavaDoc e) {
403                 System.err.println("warning: Parser does not support feature ("+DYNAMIC_VALIDATION_FEATURE_ID+")");
404             }
405             try {
406                 parser.setFeature(XINCLUDE_FEATURE_ID, xincludeProcessing);
407             }
408             catch (SAXException JavaDoc e) {
409                 System.err.println("warning: Parser does not support feature ("+XINCLUDE_FEATURE_ID+")");
410             }
411             try {
412                 parser.setFeature(XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID, xincludeFixupBaseURIs);
413             }
414             catch (SAXException JavaDoc e) {
415                 System.err.println("warning: Parser does not support feature ("+XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID+")");
416             }
417             try {
418                 parser.setFeature(XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID, xincludeFixupLanguage);
419             }
420             catch (SAXException JavaDoc e) {
421                 System.err.println("warning: Parser does not support feature ("+XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID+")");
422             }
423
424             // parse file
425
try {
426                 long beforeParse = System.currentTimeMillis();
427                 Document JavaDoc document = null;
428                 for (int j = 0; j < repetition; j++) {
429                     document = parser.parse(arg);
430                 }
431                 long afterParse = System.currentTimeMillis();
432                 long parse = afterParse - beforeParse;
433
434                 ParserWrapper.DocumentInfo documentInfo = parser.getDocumentInfo();
435                 counter.setDocumentInfo(documentInfo);
436
437                 long beforeTraverse1 = System.currentTimeMillis();
438                 counter.count(document);
439                 long afterTraverse1 = System.currentTimeMillis();
440                 long traverse1 = afterTraverse1 - beforeTraverse1;
441
442                 long beforeTraverse2 = System.currentTimeMillis();
443                 counter.count(document);
444                 long afterTraverse2 = System.currentTimeMillis();
445                 long traverse2 = afterTraverse2 - beforeTraverse2;
446                 counter.printResults(out, arg, parse, traverse1, traverse2,
447                                      repetition);
448             }
449             catch (SAXParseException JavaDoc e) {
450                 // ignore
451
}
452             catch (Exception JavaDoc e) {
453                 System.err.println("error: Parse error occurred - "+e.getMessage());
454                 Exception JavaDoc se = e;
455                 if (e instanceof SAXException JavaDoc) {
456                     se = ((SAXException JavaDoc)e).getException();
457                 }
458                 if (se != null)
459                   se.printStackTrace(System.err);
460                 else
461                   e.printStackTrace(System.err);
462             }
463         }
464
465     } // main(String[])
466

467     //
468
// Private static methods
469
//
470

471     /** Prints the usage. */
472     private static void printUsage() {
473
474         System.err.println("usage: java dom.Counter (options) uri ...");
475         System.err.println();
476
477         System.err.println("options:");
478         System.err.println(" -p name Select parser by name.");
479         System.err.println(" -x number Select number of repetitions.");
480         System.err.println(" -n | -N Turn on/off namespace processing.");
481         System.err.println(" -v | -V Turn on/off validation.");
482         System.err.println(" -s | -S Turn on/off Schema validation support.");
483         System.err.println(" NOTE: Not supported by all parsers.");
484         System.err.println(" -f | -F Turn on/off Schema full checking.");
485         System.err.println(" NOTE: Requires use of -s and not supported by all parsers.");
486         System.err.println(" -va | -VA Turn on/off validation of schema annotations.");
487         System.err.println(" NOTE: Requires use of -s and not supported by all parsers.");
488         System.err.println(" -dv | -DV Turn on/off dynamic validation.");
489         System.err.println(" NOTE: Not supported by all parsers.");
490         System.err.println(" -xi | -XI Turn on/off XInclude processing.");
491         System.err.println(" NOTE: Not supported by all parsers.");
492         System.err.println(" -xb | -XB Turn on/off base URI fixup during XInclude processing.");
493         System.err.println(" NOTE: Requires use of -xi and not supported by all parsers.");
494         System.err.println(" -xl | -XL Turn on/off language fixup during XInclude processing.");
495         System.err.println(" NOTE: Requires use of -xi and not supported by all parsers.");
496         System.err.println(" -h This help screen.");
497         System.err.println();
498
499         System.err.println("defaults:");
500         System.err.println(" Parser: "+DEFAULT_PARSER_NAME);
501         System.err.println(" Repetition: "+DEFAULT_REPETITION);
502         System.err.print(" Namespaces: ");
503         System.err.println(DEFAULT_NAMESPACES ? "on" : "off");
504         System.err.print(" Validation: ");
505         System.err.println(DEFAULT_VALIDATION ? "on" : "off");
506         System.err.print(" Schema: ");
507         System.err.println(DEFAULT_SCHEMA_VALIDATION ? "on" : "off");
508         System.err.print(" Schema full checking: ");
509         System.err.println(DEFAULT_SCHEMA_FULL_CHECKING ? "on" : "off");
510         System.err.print(" Dynamic: ");
511         System.err.println(DEFAULT_DYNAMIC_VALIDATION ? "on" : "off");
512         System.err.print(" XInclude: ");
513         System.err.println(DEFAULT_XINCLUDE ? "on" : "off");
514         System.err.print(" XInclude base URI fixup: ");
515         System.err.println(DEFAULT_XINCLUDE_FIXUP_BASE_URIS ? "on" : "off");
516         System.err.print(" XInclude language fixup: ");
517         System.err.println(DEFAULT_XINCLUDE_FIXUP_LANGUAGE ? "on" : "off");
518
519     } // printUsage()
520

521 } // class DOMCount
522
Popular Tags