KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jeantessier > dependencyfinder > cli > ClassMetrics


1 /*
2  * Copyright (c) 2001-2005, Jean Tessier
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of Jean Tessier nor the names of his contributors
17  * may be used to endorse or promote products derived from this software
18  * without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */

32
33 package com.jeantessier.dependencyfinder.cli;
34
35 import java.io.*;
36 import java.util.*;
37
38 import org.apache.log4j.*;
39
40 import com.jeantessier.classreader.*;
41 import com.jeantessier.commandline.*;
42 import com.jeantessier.dependencyfinder.*;
43
44 public class ClassMetrics {
45     public static final String JavaDoc DEFAULT_LOGFILE = "System.out";
46
47     public static void showError(CommandLineUsage clu, String JavaDoc msg) {
48         System.err.println(msg);
49         showError(clu);
50     }
51
52     public static void showError(CommandLineUsage clu) {
53         System.err.println(clu);
54         System.err.println();
55         System.err.println("If no files are specified, it processes the current directory.");
56         System.err.println();
57         System.err.println("If file is a directory, it is recusively scanned for files");
58         System.err.println("ending in \".class\".");
59         System.err.println();
60         System.err.println("Defaults is text output to the console.");
61         System.err.println();
62     }
63
64     public static void showVersion() throws IOException {
65         Version version = new Version();
66         
67         System.err.print(version.getImplementationTitle());
68         System.err.print(" ");
69         System.err.print(version.getImplementationVersion());
70         System.err.print(" (c) ");
71         System.err.print(version.getCopyrightDate());
72         System.err.print(" ");
73         System.err.print(version.getCopyrightHolder());
74         System.err.println();
75         
76         System.err.print(version.getImplementationURL());
77         System.err.println();
78         
79         System.err.print("Compiled on ");
80         System.err.print(version.getImplementationDate());
81         System.err.println();
82     }
83
84     public static void main(String JavaDoc[] args) throws Exception JavaDoc {
85         // Parsing the command line
86
CommandLine commandLine = new CommandLine();
87         commandLine.addToggleSwitch("list");
88         commandLine.addToggleSwitch("instruction-counts");
89         commandLine.addToggleSwitch("time");
90         commandLine.addSingleValueSwitch("out");
91         commandLine.addToggleSwitch("help");
92         commandLine.addOptionalValueSwitch("verbose", DEFAULT_LOGFILE);
93         commandLine.addToggleSwitch("version");
94
95         CommandLineUsage usage = new CommandLineUsage("ClassMetrics");
96         commandLine.accept(usage);
97
98         try {
99             commandLine.parse(args);
100         } catch (IllegalArgumentException JavaDoc ex) {
101             showError(usage, ex.toString());
102             System.exit(1);
103         } catch (CommandLineException ex) {
104             showError(usage, ex.toString());
105             System.exit(1);
106         }
107
108         if (commandLine.getToggleSwitch("help")) {
109             showError(usage);
110         }
111         
112         if (commandLine.getToggleSwitch("version")) {
113             showVersion();
114         }
115
116         if (commandLine.getToggleSwitch("help") || commandLine.getToggleSwitch("version")) {
117             System.exit(1);
118         }
119
120         VerboseListener verboseListener = new VerboseListener();
121         if (commandLine.isPresent("verbose")) {
122             if ("System.out".equals(commandLine.getOptionalSwitch("verbose"))) {
123                 verboseListener.setWriter(System.out);
124             } else {
125                 verboseListener.setWriter(new FileWriter(commandLine.getOptionalSwitch("verbose")));
126             }
127         }
128
129         /*
130          * Beginning of main processing
131          */

132
133         Date start = new Date();
134
135         boolean list = commandLine.getToggleSwitch("list");
136         boolean instructionCounts = commandLine.getToggleSwitch("instruction-counts");
137
138         List parameters = commandLine.getParameters();
139         if (parameters.size() == 0) {
140             parameters.add(".");
141         }
142
143         ClassfileLoader loader = new AggregatingClassfileLoader();
144         loader.addLoadListener(verboseListener);
145         loader.load(parameters);
146
147         MetricsGatherer metrics = new MetricsGatherer();
148         metrics.visitClassfiles(loader.getAllClassfiles());
149
150         verboseListener.print("Printing report ...");
151         
152         PrintWriter out;
153         if (commandLine.isPresent("out")) {
154             out = new PrintWriter(new FileWriter(commandLine.getSingleSwitch("out")));
155         } else {
156             out = new PrintWriter(new OutputStreamWriter(System.out));
157         }
158
159         out.println(metrics.getClasses().size() + " class(es)");
160         if (list) {
161             Iterator j = metrics.getClasses().iterator();
162             while (j.hasNext()) {
163                 out.println(" " + j.next());
164             }
165         }
166
167         out.println(metrics.getInterfaces().size() + " interface(s)");
168         if (list) {
169             Iterator j = metrics.getInterfaces().iterator();
170             while (j.hasNext()) {
171                 out.println(" " + j.next());
172             }
173         }
174
175         out.println();
176         out.println(metrics.getMethods().size() + " method(s) (average " + (metrics.getMethods().size() / (metrics.getClasses().size() + (double) metrics.getInterfaces().size())) + " per class/interface)");
177         out.println(metrics.getFields().size() + " field(s) (average " + (metrics.getFields().size() / (metrics.getClasses().size() + (double) metrics.getInterfaces().size())) + " per class/interface)");
178         out.println();
179
180         printCFM(out, " synthetic element(s)", metrics.getSyntheticClasses(), metrics.getSyntheticFields(), metrics.getSyntheticMethods(), list);
181         printCFM(out, " deprecated element(s)", metrics.getDeprecatedClasses(), metrics.getDeprecatedFields(), metrics.getDeprecatedMethods(), list);
182         printCFMIC(out, " public element(s)", metrics.getPublicClasses(), metrics.getPublicFields(), metrics.getPublicMethods(), metrics.getPublicInnerClasses(), list);
183         printFMIC(out, " protected element(s)", metrics.getProtectedFields(), metrics.getProtectedMethods(), metrics.getProtectedInnerClasses(), list);
184         printFMIC(out, " private element(s)", metrics.getPrivateFields(), metrics.getPrivateMethods(), metrics.getPrivateInnerClasses(), list);
185         printCFMIC(out, " package element(s)", metrics.getPackageClasses(), metrics.getPackageFields(), metrics.getPackageMethods(), metrics.getPackageInnerClasses(), list);
186         printCMIC(out, " abstract element(s)", metrics.getAbstractClasses(), metrics.getAbstractMethods(), metrics.getAbstractInnerClasses(), list);
187
188         printFMIC(out, " static element(s)", metrics.getStaticFields(), metrics.getStaticMethods(), metrics.getStaticInnerClasses(), list);
189         printCFMIC(out, " final element(s)", metrics.getFinalClasses(), metrics.getFinalFields(), metrics.getFinalMethods(), metrics.getFinalInnerClasses(), list);
190
191         out.println(metrics.getSynchronizedMethods().size() + " synchronized method(s)");
192         if (list) {
193             Iterator j = metrics.getSynchronizedMethods().iterator();
194             while (j.hasNext()) {
195                 out.println(" " + j.next());
196             }
197         }
198
199         out.println(metrics.getNativeMethods().size() + " native method(s)");
200         if (list) {
201             Iterator j = metrics.getNativeMethods().iterator();
202             while (j.hasNext()) {
203                 out.println(" " + j.next());
204             }
205         }
206
207         out.println(metrics.getVolatileFields().size() + " volatile field(s)");
208         if (list) {
209             Iterator j = metrics.getVolatileFields().iterator();
210             while (j.hasNext()) {
211                 out.println(" " + j.next());
212             }
213         }
214
215         out.println(metrics.getTransientFields().size() + " transient field(s)");
216         if (list) {
217             Iterator j = metrics.getTransientFields().iterator();
218             while (j.hasNext()) {
219                 out.println(" " + j.next());
220             }
221         }
222
223         out.println(metrics.getCustomAttributes().size() + " custom attribute(s)");
224         if (list) {
225             Iterator j = metrics.getCustomAttributes().iterator();
226             while (j.hasNext()) {
227                 out.println(" " + j.next());
228             }
229         }
230
231         if (instructionCounts) {
232             out.println();
233             out.println("Instruction counts:");
234             for (int opcode=0; opcode<256; opcode++) {
235                 out.print(" 0x");
236                 Hex.print(out, (byte) opcode);
237                 out.println(" " + Instruction.getMnemonic(opcode) + ": " + metrics.getInstructionCounts()[opcode]);
238             }
239         }
240
241         out.close();
242         
243         Date end = new Date();
244
245         if (commandLine.getToggleSwitch("time")) {
246             System.err.println(ClassMetrics.class.getName() + ": " + ((end.getTime() - (double) start.getTime()) / 1000) + " secs.");
247         }
248
249         verboseListener.close();
250     }
251
252     private static void printCMIC(PrintWriter out, String JavaDoc label, Collection classes, Collection methods, Collection innerClasses, boolean list) {
253         out.println((classes.size() +
254                      methods.size() +
255                      innerClasses.size()) + label);
256         if (list) {
257             Iterator j;
258
259             out.println(" " + classes.size() + " class(es)");
260             j = classes.iterator();
261             while (j.hasNext()) {
262                 out.println(" " + j.next());
263             }
264
265             out.println(" " + methods.size() + " method(s)");
266             j = methods.iterator();
267             while (j.hasNext()) {
268                 out.println(" " + j.next());
269             }
270
271             out.println(" " + innerClasses.size() + " inner class(es)");
272             j = innerClasses.iterator();
273             while (j.hasNext()) {
274                 out.println(" " + j.next());
275             }
276         } else {
277             out.println(" " + classes.size() + " class(es)");
278             out.println(" " + methods.size() + " method(s)");
279             out.println(" " + innerClasses.size() + " inner class(es)");
280         }
281     }
282
283     private static void printCFMIC(PrintWriter out, String JavaDoc label, Collection classes, Collection fields, Collection methods, Collection innerClasses, boolean list) {
284         out.println((classes.size() +
285                      fields.size() +
286                      methods.size() +
287                      innerClasses.size()) + label);
288         if (list) {
289             Iterator j;
290
291             out.println(" " + classes.size() + " class(es)");
292             j = classes.iterator();
293             while (j.hasNext()) {
294                 out.println(" " + j.next());
295             }
296
297             out.println(" " + fields.size() + " field(s)");
298             j = fields.iterator();
299             while (j.hasNext()) {
300                 out.println(" " + j.next());
301             }
302
303             out.println(" " + methods.size() + " method(s)");
304             j = methods.iterator();
305             while (j.hasNext()) {
306                 out.println(" " + j.next());
307             }
308
309             out.println(" " + innerClasses.size() + " inner class(es)");
310             j = innerClasses.iterator();
311             while (j.hasNext()) {
312                 out.println(" " + j.next());
313             }
314         } else {
315             out.println(" " + classes.size() + " class(es)");
316             out.println(" " + fields.size() + " fields(s)");
317             out.println(" " + methods.size() + " method(s)");
318             out.println(" " + innerClasses.size() + " inner class(es)");
319         }
320     }
321
322     private static void printCFM(PrintWriter out, String JavaDoc label, Collection classes, Collection fields, Collection methods, boolean list) {
323         out.println((classes.size() +
324                      fields.size() +
325                      methods.size()) + label);
326         if (list) {
327             Iterator j;
328
329             out.println(" " + classes.size() + " class(es)");
330             j = classes.iterator();
331             while (j.hasNext()) {
332                 out.println(" " + j.next());
333             }
334
335             out.println(" " + fields.size() + " field(s)");
336             j = fields.iterator();
337             while (j.hasNext()) {
338                 out.println(" " + j.next());
339             }
340
341             out.println(" " + methods.size() + " method(s)");
342             j = methods.iterator();
343             while (j.hasNext()) {
344                 out.println(" " + j.next());
345             }
346         } else {
347             out.println(" " + classes.size() + " class(es)");
348             out.println(" " + fields.size() + " fields(s)");
349             out.println(" " + methods.size() + " method(s)");
350         }
351     }
352
353     private static void printFMIC(PrintWriter out, String JavaDoc label, Collection fields, Collection methods, Collection innerClasses, boolean list) {
354         out.println((fields.size() +
355                      methods.size() +
356                      innerClasses.size()) + label);
357         if (list) {
358             Iterator j;
359
360             out.println(" " + fields.size() + " field(s)");
361             j = fields.iterator();
362             while (j.hasNext()) {
363                 out.println(" " + j.next());
364             }
365
366             out.println(" " + methods.size() + " method(s)");
367             j = methods.iterator();
368             while (j.hasNext()) {
369                 out.println(" " + j.next());
370             }
371
372             out.println(" " + innerClasses.size() + " inner class(es)");
373             j = innerClasses.iterator();
374             while (j.hasNext()) {
375                 out.println(" " + j.next());
376             }
377         } else {
378             out.println(" " + fields.size() + " fields(s)");
379             out.println(" " + methods.size() + " method(s)");
380             out.println(" " + innerClasses.size() + " inner class(es)");
381         }
382     }
383 }
384
Popular Tags