1 package jdepend.textui; 2 3 import java.io.*; 4 import java.util.*; 5 import java.text.NumberFormat ; 6 7 import jdepend.framework.JavaClass; 8 import jdepend.framework.JavaPackage; 9 import jdepend.framework.PackageComparator; 10 import jdepend.framework.PackageFilter; 11 12 20 21 public class JDepend { 22 23 private jdepend.framework.JDepend analyzer; 24 25 private PrintWriter writer; 26 27 protected NumberFormat formatter; 28 29 32 public JDepend() { 33 this(new PrintWriter(System.out)); 34 } 35 36 41 public JDepend(PrintWriter writer) { 42 analyzer = new jdepend.framework.JDepend(); 43 44 formatter = NumberFormat.getInstance(); 45 formatter.setMaximumFractionDigits(2); 46 47 setWriter(writer); 48 } 49 50 55 public void setWriter(PrintWriter writer) { 56 this.writer = writer; 57 } 58 59 protected PrintWriter getWriter() { 60 return writer; 61 } 62 63 68 public void setFilter(PackageFilter filter) { 69 analyzer.setFilter(filter); 70 } 71 72 75 public void setComponents(String components) { 76 analyzer.setComponents(components); 77 } 78 79 86 public void addDirectory(String name) throws IOException { 87 analyzer.addDirectory(name); 88 } 89 90 96 public void analyzeInnerClasses(boolean b) { 97 analyzer.analyzeInnerClasses(b); 98 } 99 100 104 public void analyze() { 105 106 printHeader(); 107 108 Collection packages = analyzer.analyze(); 109 110 ArrayList packageList = new ArrayList(packages); 111 112 Collections.sort(packageList, new PackageComparator(PackageComparator 113 .byName())); 114 115 printPackages(packageList); 116 117 printCycles(packageList); 118 119 printSummary(packageList); 120 121 printFooter(); 122 123 getWriter().flush(); 124 } 125 126 protected void printPackages(Collection packages) { 127 printPackagesHeader(); 128 129 Iterator i = packages.iterator(); 130 while (i.hasNext()) { 131 printPackage((JavaPackage) i.next()); 132 } 133 134 printPackagesFooter(); 135 } 136 137 protected void printPackage(JavaPackage jPackage) { 138 139 printPackageHeader(jPackage); 140 141 if (jPackage.getClasses().size() == 0) { 142 printNoStats(); 143 printPackageFooter(jPackage); 144 return; 145 } 146 147 printStatistics(jPackage); 148 149 printSectionBreak(); 150 151 printAbstractClasses(jPackage); 152 153 printSectionBreak(); 154 155 printConcreteClasses(jPackage); 156 157 printSectionBreak(); 158 159 printEfferents(jPackage); 160 161 printSectionBreak(); 162 163 printAfferents(jPackage); 164 165 printPackageFooter(jPackage); 166 } 167 168 protected void printAbstractClasses(JavaPackage jPackage) { 169 printAbstractClassesHeader(); 170 171 ArrayList members = new ArrayList(jPackage.getClasses()); 172 Collections.sort(members, new JavaClass.ClassComparator()); 173 Iterator memberIter = members.iterator(); 174 while (memberIter.hasNext()) { 175 JavaClass jClass = (JavaClass) memberIter.next(); 176 if (jClass.isAbstract()) { 177 printClassName(jClass); 178 } 179 } 180 181 printAbstractClassesFooter(); 182 } 183 184 protected void printConcreteClasses(JavaPackage jPackage) { 185 printConcreteClassesHeader(); 186 187 ArrayList members = new ArrayList(jPackage.getClasses()); 188 Collections.sort(members, new JavaClass.ClassComparator()); 189 Iterator memberIter = members.iterator(); 190 while (memberIter.hasNext()) { 191 JavaClass concrete = (JavaClass) memberIter.next(); 192 if (!concrete.isAbstract()) { 193 printClassName(concrete); 194 } 195 } 196 197 printConcreteClassesFooter(); 198 } 199 200 protected void printEfferents(JavaPackage jPackage) { 201 printEfferentsHeader(); 202 203 ArrayList efferents = new ArrayList(jPackage.getEfferents()); 204 Collections.sort(efferents, new PackageComparator(PackageComparator 205 .byName())); 206 Iterator efferentIter = efferents.iterator(); 207 while (efferentIter.hasNext()) { 208 JavaPackage efferent = (JavaPackage) efferentIter.next(); 209 printPackageName(efferent); 210 } 211 if (efferents.size() == 0) { 212 printEfferentsError(); 213 } 214 215 printEfferentsFooter(); 216 } 217 218 protected void printAfferents(JavaPackage jPackage) { 219 printAfferentsHeader(); 220 221 ArrayList afferents = new ArrayList(jPackage.getAfferents()); 222 Collections.sort(afferents, new PackageComparator(PackageComparator 223 .byName())); 224 Iterator afferentIter = afferents.iterator(); 225 while (afferentIter.hasNext()) { 226 JavaPackage afferent = (JavaPackage) afferentIter.next(); 227 printPackageName(afferent); 228 } 229 if (afferents.size() == 0) { 230 printAfferentsError(); 231 } 232 233 printAfferentsFooter(); 234 } 235 236 protected void printCycles(Collection packages) { 237 printCyclesHeader(); 238 239 Iterator i = packages.iterator(); 240 while (i.hasNext()) { 241 printCycle((JavaPackage) i.next()); 242 } 243 244 printCyclesFooter(); 245 } 246 247 protected void printCycle(JavaPackage jPackage) { 248 249 List list = new ArrayList(); 250 jPackage.collectCycle(list); 251 252 if (!jPackage.containsCycle()) { 253 return; 254 } 255 256 JavaPackage cyclePackage = (JavaPackage) list.get(list.size() - 1); 257 String cyclePackageName = cyclePackage.getName(); 258 259 int i = 0; 260 Iterator pkgIter = list.iterator(); 261 while (pkgIter.hasNext()) { 262 i++; 263 264 JavaPackage pkg = (JavaPackage) pkgIter.next(); 265 266 if (i == 1) { 267 printCycleHeader(pkg); 268 } else { 269 if (pkg.getName().equals(cyclePackageName)) { 270 printCycleTarget(pkg); 271 } else { 272 printCycleContributor(pkg); 273 } 274 } 275 } 276 277 printCycleFooter(); 278 } 279 280 protected void printHeader() { 281 } 283 284 protected void printFooter() { 285 } 287 288 protected void printPackagesHeader() { 289 } 291 292 protected void printPackagesFooter() { 293 } 295 296 protected void printNoStats() { 297 getWriter().println( 298 "No stats available: package referenced, but not analyzed."); 299 } 300 301 protected void printPackageHeader(JavaPackage jPackage) { 302 getWriter().println( 303 "\n--------------------------------------------------"); 304 getWriter().println("- Package: " + jPackage.getName()); 305 getWriter().println( 306 "--------------------------------------------------"); 307 } 308 309 protected void printPackageFooter(JavaPackage jPackage) { 310 } 312 313 protected void printStatistics(JavaPackage jPackage) { 314 getWriter().println("\nStats:"); 315 getWriter().println( 316 tab() + "Total Classes: " + jPackage.getClassCount()); 317 getWriter() 318 .println( 319 tab() + "Concrete Classes: " 320 + jPackage.getConcreteClassCount()); 321 getWriter() 322 .println( 323 tab() + "Abstract Classes: " 324 + jPackage.getAbstractClassCount()); 325 getWriter().println(""); 326 getWriter().println(tab() + "Ca: " + jPackage.afferentCoupling()); 327 getWriter().println(tab() + "Ce: " + jPackage.efferentCoupling()); 328 getWriter().println(""); 329 getWriter().println( 330 tab() + "A: " + toFormattedString(jPackage.abstractness())); 331 getWriter().println( 332 tab() + "I: " + toFormattedString(jPackage.instability())); 333 getWriter().println( 334 tab() + "D: " + toFormattedString(jPackage.distance())); 335 } 336 337 protected void printClassName(JavaClass jClass) { 338 getWriter().println(tab() + jClass.getName()); 339 } 340 341 protected void printPackageName(JavaPackage jPackage) { 342 getWriter().println(tab() + jPackage.getName()); 343 } 344 345 protected void printAbstractClassesHeader() { 346 getWriter().println("Abstract Classes:"); 347 } 348 349 protected void printAbstractClassesFooter() { 350 } 352 353 protected void printConcreteClassesHeader() { 354 getWriter().println("Concrete Classes:"); 355 } 356 357 protected void printConcreteClassesFooter() { 358 } 360 361 protected void printEfferentsHeader() { 362 getWriter().println("Depends Upon:"); 363 } 364 365 protected void printEfferentsFooter() { 366 } 368 369 protected void printEfferentsError() { 370 getWriter().println(tab() + "Not dependent on any packages."); 371 } 372 373 protected void printAfferentsHeader() { 374 getWriter().println("Used By:"); 375 } 376 377 protected void printAfferentsFooter() { 378 } 380 381 protected void printAfferentsError() { 382 getWriter().println(tab() + "Not used by any packages."); 383 } 384 385 protected void printCyclesHeader() { 386 printSectionBreak(); 387 getWriter().println( 388 "\n--------------------------------------------------"); 389 getWriter().println("- Package Dependency Cycles:"); 390 getWriter().println( 391 "--------------------------------------------------\n"); 392 } 393 394 protected void printCyclesFooter() { 395 } 397 398 protected void printCycleHeader(JavaPackage jPackage) { 399 getWriter().println(jPackage.getName()); 400 getWriter().println(tab() + "|"); 401 } 402 403 protected void printCycleTarget(JavaPackage jPackage) { 404 getWriter().println(tab() + "|-> " + jPackage.getName()); 405 } 406 407 protected void printCycleContributor(JavaPackage jPackage) { 408 getWriter().println(tab() + "| " + jPackage.getName()); 409 } 410 411 protected void printCycleFooter() { 412 printSectionBreak(); 413 } 414 415 protected void printSummary(Collection packages) { 416 getWriter().println( 417 "\n--------------------------------------------------"); 418 getWriter().println("- Summary:"); 419 getWriter().println( 420 "--------------------------------------------------\n"); 421 422 getWriter() 423 .println( 424 "Name, Class Count, Abstract Class Count, Ca, Ce, A, I, D, V:\n"); 425 426 Iterator i = packages.iterator(); 427 while (i.hasNext()) { 428 JavaPackage jPackage = (JavaPackage) i.next(); 429 getWriter().print(jPackage.getName() + ","); 430 getWriter().print(jPackage.getClassCount() + ","); 431 getWriter().print(jPackage.getAbstractClassCount() + ","); 432 getWriter().print(jPackage.afferentCoupling() + ","); 433 getWriter().print(jPackage.efferentCoupling() + ","); 434 getWriter().print(toFormattedString(jPackage.abstractness()) + ","); 435 getWriter().print(toFormattedString(jPackage.instability()) + ","); 436 getWriter().print(toFormattedString(jPackage.distance()) + ","); 437 getWriter().println(jPackage.getVolatility()); 438 } 439 } 440 441 protected void printSectionBreak() { 442 getWriter().println(""); 443 } 444 445 protected String toFormattedString(float f) { 446 return formatter.format(f); 447 } 448 449 protected String tab() { 450 return " "; 451 } 452 453 protected String tab(int n) { 454 StringBuffer s = new StringBuffer (); 455 for (int i = 0; i < n; i++) { 456 s.append(tab()); 457 } 458 459 return s.toString(); 460 } 461 462 protected void usage(String message) { 463 if (message != null) { 464 System.err.println("\n" + message); 465 } 466 String baseUsage = "\nJDepend "; 467 468 System.err.println(""); 469 System.err.println("usage: "); 470 System.err.println(baseUsage + "[-components <components>]" + 471 " [-file <output file>] <directory> " + 472 "[directory2 [directory 3] ...]"); 473 System.exit(1); 474 } 475 476 protected void instanceMain(String [] args) { 477 478 if (args.length < 1) { 479 usage("Must specify at least one directory."); 480 } 481 482 int directoryCount = 0; 483 484 for (int i = 0; i < args.length; i++) { 485 if (args[i].startsWith("-")) { 486 if (args[i].equalsIgnoreCase("-file")) { 487 488 if (args.length <= i + 1) { 489 usage("Output file name not specified."); 490 } 491 492 try { 493 setWriter(new PrintWriter(new OutputStreamWriter( 494 new FileOutputStream(args[++i]), "UTF8"))); 495 } catch (IOException ioe) { 496 usage(ioe.getMessage()); 497 } 498 499 } else if (args[i].equalsIgnoreCase("-components")) { 500 if (args.length <= i + 1) { 501 usage("Components not specified."); 502 } 503 setComponents(args[++i]); 504 } else { 505 usage("Invalid argument: " + args[i]); 506 } 507 } else { 508 try { 509 addDirectory(args[i]); 510 directoryCount++; 511 } catch (IOException ioe) { 512 usage("Directory does not exist: " + args[i]); 513 } 514 } 515 } 516 517 if (directoryCount == 0) { 518 usage("Must specify at least one directory."); 519 } 520 521 analyze(); 522 } 523 524 public static void main(String args[]) { 525 new JDepend().instanceMain(args); 526 } 527 } 528 | Popular Tags |