KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > xni > Counter


1 /*
2  * Copyright 2001-2004 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 xni;
18
19 import java.io.PrintWriter JavaDoc;
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 /**
36  * A sample XNI counter. The output of this program shows the time
37  * and count of elements, attributes, ignorable whitespaces, and
38  * characters appearing in the document.
39  * <p>
40  * This class is useful as a "poor-man's" performance tester to
41  * compare the speed and accuracy of various parser configurations.
42  * However, it is important to note that the first parse time of a
43  * parser will include both VM class load time and parser
44  * initialization that would not be present in subsequent parses
45  * with the same file.
46  * <p>
47  * <strong>Note:</strong> The results produced by this program
48  * should never be accepted as true performance measurements.
49  *
50  * @author Andy Clark, IBM
51  *
52  * @version $Id: Counter.java,v 1.17 2005/06/14 20:51:13 mrglavas Exp $
53  */

54 public class Counter
55     extends XMLDocumentParser
56     implements XMLErrorHandler {
57
58     //
59
// Constants
60
//
61

62     // feature ids
63

64     /** Namespaces feature id (http://xml.org/sax/features/namespaces). */
65     protected static final String JavaDoc NAMESPACES_FEATURE_ID =
66         "http://xml.org/sax/features/namespaces";
67
68     /** Namespace prefixes feature id (http://xml.org/sax/features/namespace-prefixes). */
69     protected static final String JavaDoc NAMESPACE_PREFIXES_FEATURE_ID =
70         "http://xml.org/sax/features/namespace-prefixes";
71
72     /** Validation feature id (http://xml.org/sax/features/validation). */
73     protected static final String JavaDoc VALIDATION_FEATURE_ID =
74         "http://xml.org/sax/features/validation";
75
76     /** Schema validation feature id (http://apache.org/xml/features/validation/schema). */
77     protected static final String JavaDoc SCHEMA_VALIDATION_FEATURE_ID =
78         "http://apache.org/xml/features/validation/schema";
79
80     /** Schema full checking feature id (http://apache.org/xml/features/validation/schema-full-checking). */
81     protected static final String JavaDoc SCHEMA_FULL_CHECKING_FEATURE_ID =
82         "http://apache.org/xml/features/validation/schema-full-checking";
83
84     // default settings
85

86     /** Default parser configuration (org.apache.xerces.parsers.XIncludeAwareParserConfiguration). */
87     protected static final String JavaDoc DEFAULT_PARSER_CONFIG =
88         "org.apache.xerces.parsers.XIncludeAwareParserConfiguration";
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 namespace prefixes (false). */
97     protected static final boolean DEFAULT_NAMESPACE_PREFIXES = false;
98
99     /** Default validation support (false). */
100     protected static final boolean DEFAULT_VALIDATION = false;
101
102     /** Default Schema validation support (false). */
103     protected static final boolean DEFAULT_SCHEMA_VALIDATION = false;
104
105     /** Default Schema full checking support (false). */
106     protected static final boolean DEFAULT_SCHEMA_FULL_CHECKING = false;
107
108     /** Default memory usage report (false). */
109     protected static final boolean DEFAULT_MEMORY_USAGE = false;
110
111     /** Default "tagginess" report (false). */
112     protected static final boolean DEFAULT_TAGGINESS = false;
113
114     //
115
// Data
116
//
117

118     /** Number of elements. */
119     protected long fElements;
120
121     /** Number of attributes. */
122     protected long fAttributes;
123
124     /** Number of characters. */
125     protected long fCharacters;
126
127     /** Number of ignorable whitespace characters. */
128     protected long fIgnorableWhitespace;
129
130     /** Number of characters of tags. */
131     protected long fTagCharacters;
132
133     /** Number of other content characters for the "tagginess" calculation. */
134     protected long fOtherCharacters;
135
136     //
137
// Constructors
138
//
139

140     /** Default constructor. */
141     public Counter(XMLParserConfiguration configuration) {
142         super(configuration);
143         fConfiguration.setErrorHandler(this);
144     } // <init>(XMLParserConfiguration)
145

146     //
147
// Public methods
148
//
149

150     /** Prints the results. */
151     public void printResults(PrintWriter JavaDoc out, String JavaDoc uri, long time,
152                              long memory, boolean tagginess,
153                              int repetition) {
154
155         // filename.xml: 631 ms (4 elems, 0 attrs, 78 spaces, 0 chars)
156
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     } // printResults(PrintWriter,String,long)
195

196     //
197
// ContentHandler methods
198
//
199

200     /** Start document. */
201     public void startDocument(XMLLocator locator, String JavaDoc 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     } // startDocument(XMLLocator,String, NamespaceContext, Augmentations)
212

213     /** Start element. */
214     public void startElement(QName element, XMLAttributes attrs, Augmentations augs)
215         throws XNIException {
216
217         fElements++;
218         fTagCharacters++; // open angle bracket
219
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++; // space
225
fTagCharacters += attrs.getQName(i).length();
226                 fTagCharacters++; // '='
227
fTagCharacters++; // open quote
228
fOtherCharacters += attrs.getValue(i).length();
229                 fTagCharacters++; // close quote
230
}
231         }
232         fTagCharacters++; // close angle bracket
233

234     } // startElement(QName,XMLAttributes)
235

236     /** Empty element. */
237     public void emptyElement(QName element, XMLAttributes attrs, Augmentations augs)
238         throws XNIException {
239
240         fElements++;
241         fTagCharacters++; // open angle bracket
242
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++; // space
248
fTagCharacters += attrs.getQName(i).length();
249                 fTagCharacters++; // '='
250
fTagCharacters++; // open quote
251
fOtherCharacters += attrs.getValue(i).length();
252                 fTagCharacters++; // close quote
253
}
254         }
255         fTagCharacters++; // forward slash
256
fTagCharacters++; // close angle bracket
257

258     } // startElement(QName,XMLAttributes)
259

260     /** Characters. */
261     public void characters(XMLString text, Augmentations augs) throws XNIException {
262
263         fCharacters += text.length;
264
265     } // characters(XMLString);
266

267     /** Ignorable whitespace. */
268     public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException {
269
270         fIgnorableWhitespace += text.length;
271
272     } // ignorableWhitespace(XMLString);
273

274     /** Processing instruction. */
275     public void processingInstruction(String JavaDoc target, XMLString data, Augmentations augs)
276         throws XNIException {
277         fTagCharacters += 2; // "<?"
278
fTagCharacters += target.length();
279         if (data.length > 0) {
280             fTagCharacters++; // space
281
fOtherCharacters += data.length;
282         }
283         fTagCharacters += 2; // "?>"
284
} // processingInstruction(String,XMLString)
285

286     //
287
// XMLErrorHandler methods
288
//
289

290     /** Warning. */
291     public void warning(String JavaDoc domain, String JavaDoc key, XMLParseException ex)
292         throws XNIException {
293         printError("Warning", ex);
294     } // warning(String,String,XMLParseException)
295

296     /** Error. */
297     public void error(String JavaDoc domain, String JavaDoc key, XMLParseException ex)
298         throws XNIException {
299         printError("Error", ex);
300     } // error(String,String,XMLParseException)
301

302     /** Fatal error. */
303     public void fatalError(String JavaDoc domain, String JavaDoc key, XMLParseException ex)
304         throws XNIException {
305         printError("Fatal Error", ex);
306         throw ex;
307     } // fatalError(String,String,XMLParseException)
308

309     //
310
// Protected methods
311
//
312

313     /** Prints the error message. */
314     protected void printError(String JavaDoc type, XMLParseException ex) {
315
316         System.err.print("[");
317         System.err.print(type);
318         System.err.print("] ");
319         String JavaDoc 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     } // printError(String,XMLParseException)
336

337     //
338
// MAIN
339
//
340

341     /** Main program entry point. */
342     public static void main(String JavaDoc argv[]) {
343
344         // is there anything to do?
345
if (argv.length == 0) {
346             printUsage();
347             System.exit(1);
348         }
349
350         // variables
351
PrintWriter JavaDoc out = new PrintWriter JavaDoc(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         // process arguments
364
for (int i = 0; i < argv.length; i++) {
365             String JavaDoc arg = argv[i];
366             if (arg.startsWith("-")) {
367                 String JavaDoc option = arg.substring(1);
368                 if (option.equals("p")) {
369                     // get parser name
370
if (++i == argv.length) {
371                         System.err.println("error: Missing argument to -p option.");
372                         continue;
373                     }
374                     String JavaDoc parserName = argv[i];
375
376                     // create parser
377
try {
378                         parserConfig = (XMLParserConfiguration)ObjectFactory.newInstance(parserName,
379                             ObjectFactory.findClassLoader(), true);
380                         parserConfig.addRecognizedFeatures(new String JavaDoc[] {
381                             NAMESPACE_PREFIXES_FEATURE_ID,
382                         });
383                         parser = null;
384                     }
385                     catch (Exception JavaDoc 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 JavaDoc 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 JavaDoc 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             // use default parser?
456
if (parserConfig == null) {
457
458                 // create parser
459
try {
460                     parserConfig = (XMLParserConfiguration)ObjectFactory.newInstance(DEFAULT_PARSER_CONFIG,
461                         ObjectFactory.findClassLoader(), true);
462                     parserConfig.addRecognizedFeatures(new String JavaDoc[] {
463                         NAMESPACE_PREFIXES_FEATURE_ID,
464                     });
465                 }
466                 catch (Exception JavaDoc e) {
467                     System.err.println("error: Unable to instantiate parser configuration ("+DEFAULT_PARSER_CONFIG+")");
468                     continue;
469                 }
470             }
471
472             // set parser features
473
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             // parse file
506
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                 // ignore
530
}
531             catch (Exception JavaDoc 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     } // main(String[])
541

542     //
543
// Private static methods
544
//
545

546     /** Prints the usage. */
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     } // printUsage()
604

605 } // class Counter
606
Popular Tags