KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > xml > dom > DOMStats


1 /*
2  * Enhydra Java Application Server Project
3  *
4  * The contents of this file are subject to the Enhydra Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License on
7  * the Enhydra web site ( http://www.enhydra.org/ ).
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11  * the License for the specific terms governing rights and limitations
12  * under the License.
13  *
14  * The Initial Developer of the Enhydra Application Server is Lutris
15  * Technologies, Inc. The Enhydra Application Server and portions created
16  * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
17  * All Rights Reserved.
18  *
19  * Contributor(s):
20  *
21  * $Id: DOMStats.java,v 1.2 2005/01/26 08:29:24 jkjome Exp $
22  */

23
24 package org.enhydra.xml.dom;
25
26 import java.io.OutputStream JavaDoc;
27 import java.io.PrintWriter JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.TreeMap JavaDoc;
30
31 import org.enhydra.xml.lazydom.LazyNode;
32 import org.enhydra.xml.xmlc.codegen.JavaLang;
33 import org.w3c.dom.Node JavaDoc;
34
35 /*
36  * NB: This has special handling for LazyDOM nodes. It would have been better
37  * from an OOD perspective to derive a LazyDOMStats class.
38  */

39
40 /**
41  * Collect and print statistics on a DOM.
42  */

43 public class DOMStats {
44     /**
45      * Option flag to print simple class names instead of fully qualified
46      * names.
47      */

48     public static final int SIMPLE_CLASS_NAMES = 0x01;
49
50     /**
51      * Field width used for node types.
52      */

53     private static final int NODE_TYPE_WIDTH = 22;
54
55     /**
56      * Field width used for counts.
57      */

58     private static final int COUNT_WIDTH = 10;
59
60     /**
61      * Max Node type number.
62      */

63     private static final short MAX_NODE_TYPE = Node.NOTATION_NODE;
64
65     /**
66      * Indentation padding.
67      */

68     private static final String JavaDoc INDENT2 = " ";
69     private static final String JavaDoc INDENT4 = " ";
70
71     /**
72      * Statitics collected on a node.
73      */

74     private class NodeStats {
75         public int fNodeCount; // New nodes for lazy DOM..
76
public int fTemplateCount;
77         public int fExpandedCount;
78
79         /** Sum a NodeStats with this object. */
80         public void sum(NodeStats stats) {
81             fNodeCount += stats.fNodeCount;
82             fTemplateCount += stats.fTemplateCount;
83             fExpandedCount += stats.fExpandedCount;
84         }
85     }
86
87     /**
88      * Class used to collect a count Nodes by class
89      */

90     private class NodeClassCount {
91         public final String JavaDoc fClass;
92         public NodeStats fStats = new NodeStats();
93
94         /** Constructor */
95         public NodeClassCount(String JavaDoc nodeClass) {
96             fClass = nodeClass;
97         }
98     }
99
100     /*
101      * Is this a LazyDOM?
102      */

103     private final boolean fIsLazyDOM;
104
105     /**
106      * Options sets.
107      */

108     private final int fOptions;
109
110     /**
111      * Table of counts, indexed by node class name.
112      */

113     private final TreeMap JavaDoc fNodeClassCounts = new TreeMap JavaDoc();
114
115     /**
116      * Maximum length of a node class name.
117      */

118     private int fMaxNodeClassName;
119
120     /**
121      * Count of nodes, indexed by type.
122      */

123     private NodeStats[] fTypeStats = new NodeStats[MAX_NODE_TYPE+1];
124
125     /**
126      * Constructor, collect stats.
127      */

128     private DOMStats(Node root,
129                      int options) {
130         fOptions = options;
131         fIsLazyDOM = (DOMOps.getActualNode(root) instanceof LazyNode);
132         for (int i = 0; i < fTypeStats.length; i++) {
133             fTypeStats[i] = new NodeStats();
134         }
135         collectStats(root);
136     }
137
138     /**
139      * Get the class name to print based on the options.
140      */

141     private String JavaDoc getPrintClassName(String JavaDoc className) {
142         if ((fOptions & SIMPLE_CLASS_NAMES) != 0) {
143             return JavaLang.simpleClassName(className);
144         } else {
145             return className;
146         }
147     }
148
149     /**
150      * Get a node class stats.
151      */

152     private NodeStats getNodeClassStats(Node node) {
153         String JavaDoc nodeClass = node.getClass().getName();
154         NodeClassCount counts = (NodeClassCount)fNodeClassCounts.get(nodeClass);
155         if (counts == null) {
156             counts = new NodeClassCount(nodeClass);
157             fNodeClassCounts.put(nodeClass, counts);
158             int nameLen = getPrintClassName(nodeClass).length();
159             if (nameLen > fMaxNodeClassName) {
160                 fMaxNodeClassName = nameLen;
161             }
162         }
163         return counts.fStats;
164     }
165
166     /**
167      * Count a node by type.
168      */

169     private void countNode(Node node) {
170         NodeStats classStats = getNodeClassStats(node);
171         boolean isLazyNode = (node instanceof LazyNode);
172         if (isLazyNode && ((LazyNode)node).isTemplateNode()) {
173             fTypeStats[node.getNodeType()].fTemplateCount++;
174             classStats.fTemplateCount++;
175         } else if (isLazyNode && (((LazyNode)node).getNodeId() >= 0)) {
176             fTypeStats[node.getNodeType()].fExpandedCount++;
177             classStats.fExpandedCount++;
178         } else {
179             fTypeStats[node.getNodeType()].fNodeCount++;
180             classStats.fNodeCount++;
181         }
182     }
183
184     /**
185      * Collect statistics.
186      */

187     private void collectStats(Node root) {
188         SimpleDOMTraversal.Handler handler
189             = new SimpleDOMTraversal.Handler() {
190                     public void handleNode(Node node) {
191                         countNode(node);
192                     }
193                 };
194         SimpleDOMTraversal traverser = SimpleDOMTraversal.getTraverser(handler, root);
195         traverser.traverse(root);
196     }
197
198     //FIXME: need to collect these somewhere..
199
/**
200      * Right pad a string.
201      */

202     private String JavaDoc padRight(String JavaDoc src,
203                             int len) {
204         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(len);
205         int curLen = src.length();
206         buf.append(src);
207         while (curLen < len) {
208             buf.append(' ');
209             curLen++;
210         }
211         return buf.toString();
212     }
213
214     /**
215      * Left pad a string.
216      */

217     private String JavaDoc padLeft(String JavaDoc src,
218                            int len) {
219         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(len);
220         int curLen = src.length();
221         while (curLen < len) {
222             buf.append(' ');
223             curLen++;
224         }
225         buf.append(src);
226         return buf.toString();
227     }
228
229     /**
230      * Output a label plus a NodeStats.
231      */

232     private void printNodeStats(PrintWriter JavaDoc out,
233                                 String JavaDoc label,
234                                 int labelWidth,
235                                 NodeStats stats) {
236         out.print(INDENT4);
237         out.print(padRight(label, labelWidth));
238         if (fIsLazyDOM) {
239             out.print(padLeft(Integer.toString(stats.fTemplateCount), COUNT_WIDTH));
240             out.print(padLeft(Integer.toString(stats.fExpandedCount), COUNT_WIDTH));
241         }
242         out.print(padLeft(Integer.toString(stats.fNodeCount), COUNT_WIDTH));
243         out.println();
244     }
245
246     /**
247      * Print nodes by type.
248      */

249     private void printByType(PrintWriter JavaDoc out) {
250         out.print(INDENT2);
251         out.print(padRight("Node Type", NODE_TYPE_WIDTH));
252         out.print(INDENT2);
253         if (fIsLazyDOM) {
254             out.print(padLeft("Template", COUNT_WIDTH));
255             out.print(padLeft("Expanded", COUNT_WIDTH));
256             out.print(padLeft("New", COUNT_WIDTH));
257         } else {
258             out.print(padLeft("Nodes", COUNT_WIDTH));
259         }
260         out.println();
261         NodeStats sum = new NodeStats();
262         for (short type = 1; type <= MAX_NODE_TYPE; type++) {
263             printNodeStats(out, DOMInfo.nodeTypeToName(type), NODE_TYPE_WIDTH,
264                            fTypeStats[type]);
265             sum.sum(fTypeStats[type]);
266         }
267         printNodeStats(out, "Total", NODE_TYPE_WIDTH, sum);
268     }
269
270     /**
271      * Print nodes by class.
272      */

273     private void printByClass(PrintWriter JavaDoc out) {
274         int labelWidth = fMaxNodeClassName + 2;
275         out.print(INDENT2);
276         out.print(padRight("Node Class", labelWidth));
277         out.print(INDENT2);
278         if (fIsLazyDOM) {
279             out.print(padLeft("Template", COUNT_WIDTH));
280             out.print(padLeft("Expanded", COUNT_WIDTH));
281             out.print(padLeft("New", COUNT_WIDTH));
282         } else {
283             out.print(padLeft("Nodes", COUNT_WIDTH));
284         }
285         out.println();
286         Iterator JavaDoc values = fNodeClassCounts.values().iterator();
287         NodeStats sum = new NodeStats();
288         while (values.hasNext()) {
289             NodeClassCount count = (NodeClassCount)values.next();
290             printNodeStats(out, getPrintClassName(count.fClass),
291                            labelWidth, count.fStats);
292             sum.sum(count.fStats);
293         }
294         printNodeStats(out, "Total", labelWidth, sum);
295     }
296
297     /**
298      * Output statistics.
299      */

300     private void outputStats(String JavaDoc msg,
301                              PrintWriter JavaDoc out) {
302         if (out == null) {
303             out = new PrintWriter JavaDoc(System.err, true);
304         }
305         if ((msg != null) && (msg.length() > 0)) {
306             out.println(msg + ":");
307         }
308         printByType(out);
309         printByClass(out);
310         out.flush();
311     }
312
313     /**
314      * Collect and print statistics about a DOM tree or subtree.
315      * @param msg A message to print at the start. If null or empty,
316      * don't print a message.
317      * @param root Top of the tree.
318      * @param options Option flags controlling printing.
319      * @param out Output writer. If null, stderr will be used.
320      */

321     public static void printStats(String JavaDoc msg,
322                                   Node root,
323                                   int options,
324                                   PrintWriter JavaDoc out) {
325         new DOMStats(root, options).outputStats(msg, out);
326     }
327
328     /**
329      * Collect and print statistics about a DOM tree or subtree.
330      * @param msg A message to print at the start. If null or empty,
331      * don't print a message.
332      * @param root Top of the tree.
333      * @param options Option flags controlling printing.
334      * @param out Output writer. If null, stderr will be used.
335      */

336     public static void printStats(String JavaDoc msg,
337                                   Node root,
338                                   int options,
339                                   OutputStream JavaDoc out) {
340         PrintWriter JavaDoc writer = new PrintWriter JavaDoc((out != null) ? out : System.err, true);
341         printStats(msg, root, options, writer);
342     }
343 }
344
Popular Tags