1 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 DEFAULT_LOGFILE = "System.out"; 46 47 public static void showError(CommandLineUsage clu, String 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 [] args) throws Exception { 85 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 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 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 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 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 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 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 |