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.commandline.*; 41 import com.jeantessier.dependency.*; 42 import com.jeantessier.dependencyfinder.*; 43 44 public class DependencyReporter { 45 public static final String DEFAULT_INCLUDES = "//"; 46 public static final String DEFAULT_SCOPE_INCLUDES = "//"; 47 public static final String DEFAULT_FILTER_INCLUDES = "//"; 48 public static final String DEFAULT_LOGFILE = "System.out"; 49 50 public static void showError(CommandLineUsage clu, String msg) { 51 System.err.println(msg); 52 showError(clu); 53 } 54 55 public static void showError(CommandLineUsage clu) { 56 System.err.println(clu); 57 System.err.println(); 58 System.err.println("-all shorthand for the combination:"); 59 System.err.println(" -package-scope"); 60 System.err.println(" -class-scope"); 61 System.err.println(" -feature-scope"); 62 System.err.println(" -package-filter"); 63 System.err.println(" -class-filter"); 64 System.err.println(" -feature-filter"); 65 System.err.println(); 66 System.err.println("-p2p shorthand for the combination:"); 67 System.err.println(" -package-scope"); 68 System.err.println(" -package-filter"); 69 System.err.println(); 70 System.err.println("-c2p shorthand for the combination:"); 71 System.err.println(" -class-scope"); 72 System.err.println(" -package-filter"); 73 System.err.println(); 74 System.err.println("-c2c shorthand for the combination:"); 75 System.err.println(" -class-scope"); 76 System.err.println(" -class-filter"); 77 System.err.println(); 78 System.err.println("-f2f shorthand for the combination:"); 79 System.err.println(" -feature-scope"); 80 System.err.println(" -feature-filter"); 81 System.err.println(); 82 System.err.println("-includes \"str\" shorthand for the combination:"); 83 System.err.println(" -scope-includes \"str\""); 84 System.err.println(" -filter-includes \"str\""); 85 System.err.println(); 86 System.err.println("-excludes \"str\" shorthand for the combination:"); 87 System.err.println(" -scope-excludes \"str\""); 88 System.err.println(" -filter-excludes \"str\""); 89 System.err.println(); 90 System.err.println("-show-all shorthand for the combination:"); 91 System.err.println(" -show-inbounds"); 92 System.err.println(" -show-outbounds"); 93 System.err.println(" -show-empty-nodes"); 94 System.err.println(); 95 System.err.println("Defaults is text output to the console."); 96 System.err.println(); 97 } 98 99 public static void showVersion() throws IOException { 100 Version version = new Version(); 101 102 System.err.print(version.getImplementationTitle()); 103 System.err.print(" "); 104 System.err.print(version.getImplementationVersion()); 105 System.err.print(" (c) "); 106 System.err.print(version.getCopyrightDate()); 107 System.err.print(" "); 108 System.err.print(version.getCopyrightHolder()); 109 System.err.println(); 110 111 System.err.print(version.getImplementationURL()); 112 System.err.println(); 113 114 System.err.print("Compiled on "); 115 System.err.print(version.getImplementationDate()); 116 System.err.println(); 117 } 118 119 public static void main(String [] args) throws Exception { 120 CommandLine commandLine = new CommandLine(new AtLeastParameterStrategy(1)); 122 commandLine.addMultipleValuesSwitch("scope-includes", DEFAULT_SCOPE_INCLUDES); 123 commandLine.addMultipleValuesSwitch("scope-excludes"); 124 commandLine.addToggleSwitch("package-scope"); 125 commandLine.addMultipleValuesSwitch("package-scope-includes"); 126 commandLine.addMultipleValuesSwitch("package-scope-excludes"); 127 commandLine.addToggleSwitch("class-scope"); 128 commandLine.addMultipleValuesSwitch("class-scope-includes"); 129 commandLine.addMultipleValuesSwitch("class-scope-excludes"); 130 commandLine.addToggleSwitch("feature-scope"); 131 commandLine.addMultipleValuesSwitch("feature-scope-includes"); 132 commandLine.addMultipleValuesSwitch("feature-scope-excludes"); 133 commandLine.addMultipleValuesSwitch("filter-includes", DEFAULT_FILTER_INCLUDES); 134 commandLine.addMultipleValuesSwitch("filter-excludes"); 135 commandLine.addToggleSwitch("package-filter"); 136 commandLine.addMultipleValuesSwitch("package-filter-includes"); 137 commandLine.addMultipleValuesSwitch("package-filter-excludes"); 138 commandLine.addToggleSwitch("class-filter"); 139 commandLine.addMultipleValuesSwitch("class-filter-includes"); 140 commandLine.addMultipleValuesSwitch("class-filter-excludes"); 141 commandLine.addToggleSwitch("feature-filter"); 142 commandLine.addMultipleValuesSwitch("feature-filter-includes"); 143 commandLine.addMultipleValuesSwitch("feature-filter-excludes"); 144 145 commandLine.addToggleSwitch("all"); 146 commandLine.addToggleSwitch("p2p"); 147 commandLine.addToggleSwitch("c2p"); 148 commandLine.addToggleSwitch("c2c"); 149 commandLine.addToggleSwitch("f2f"); 150 commandLine.addMultipleValuesSwitch("includes", DEFAULT_INCLUDES); 151 commandLine.addMultipleValuesSwitch("excludes"); 152 153 commandLine.addMultipleValuesSwitch("scope-includes-list"); 154 commandLine.addMultipleValuesSwitch("scope-excludes-list"); 155 commandLine.addMultipleValuesSwitch("filter-includes-list"); 156 commandLine.addMultipleValuesSwitch("filter-excludes-list"); 157 158 commandLine.addToggleSwitch("show-all"); 159 commandLine.addToggleSwitch("show-inbounds"); 160 commandLine.addToggleSwitch("show-outbounds"); 161 commandLine.addToggleSwitch("show-empty-nodes"); 162 163 commandLine.addToggleSwitch("xml"); 164 commandLine.addToggleSwitch("validate"); 165 commandLine.addSingleValueSwitch("encoding", XMLPrinter.DEFAULT_ENCODING); 166 commandLine.addSingleValueSwitch("dtd-prefix", XMLPrinter.DEFAULT_DTD_PREFIX); 167 commandLine.addSingleValueSwitch("indent-text"); 168 commandLine.addToggleSwitch("minimize"); 169 commandLine.addToggleSwitch("maximize"); 170 commandLine.addToggleSwitch("copy-only"); 171 commandLine.addToggleSwitch("time"); 172 commandLine.addSingleValueSwitch("out"); 173 commandLine.addToggleSwitch("help"); 174 commandLine.addOptionalValueSwitch("verbose", DEFAULT_LOGFILE); 175 commandLine.addToggleSwitch("version"); 176 177 CommandLineUsage usage = new CommandLineUsage("DependencyReporter"); 178 commandLine.accept(usage); 179 180 try { 181 commandLine.parse(args); 182 } catch (IllegalArgumentException ex) { 183 showError(usage, ex.toString()); 184 System.exit(1); 185 } catch (CommandLineException ex) { 186 showError(usage, ex.toString()); 187 System.exit(1); 188 } 189 190 if (commandLine.getToggleSwitch("help")) { 191 showError(usage); 192 } 193 194 if (commandLine.getToggleSwitch("version")) { 195 showVersion(); 196 } 197 198 if (commandLine.getToggleSwitch("help") || commandLine.getToggleSwitch("version")) { 199 System.exit(1); 200 } 201 202 VerboseListener verboseListener = new VerboseListener(); 203 if (commandLine.isPresent("verbose")) { 204 if ("System.out".equals(commandLine.getOptionalSwitch("verbose"))) { 205 verboseListener.setWriter(System.out); 206 } else { 207 verboseListener.setWriter(new FileWriter(commandLine.getOptionalSwitch("verbose"))); 208 } 209 } 210 211 if (commandLine.getToggleSwitch("maximize") && commandLine.getToggleSwitch("minimize")) { 212 showError(usage, "Only one of -maximize or -minimize allowed"); 213 } 214 215 if (hasScopeRegularExpressionSwitches(commandLine) && hasScopeListSwitches(commandLine)) { 216 showError(usage, "You can use switches for regular expressions or lists for scope, but not at the same time"); 217 } 218 219 if (hasFilterRegularExpressionSwitches(commandLine) && hasFilterListSwitches(commandLine)) { 220 showError(usage, "You can use switches for regular expressions or lists for filter, but not at the same time"); 221 } 222 223 226 227 Date start = new Date(); 228 229 SelectionCriteria scopeCriteria = new ComprehensiveSelectionCriteria(); 230 231 if (hasScopeRegularExpressionSwitches(commandLine)) { 232 RegularExpressionSelectionCriteria regularExpressionScopeCriteria = new RegularExpressionSelectionCriteria(); 233 234 regularExpressionScopeCriteria.setMatchingPackages(commandLine.getToggleSwitch("package-scope")); 235 regularExpressionScopeCriteria.setMatchingClasses(commandLine.getToggleSwitch("class-scope")); 236 regularExpressionScopeCriteria.setMatchingFeatures(commandLine.getToggleSwitch("feature-scope")); 237 238 if (commandLine.isPresent("scope-includes") || (!commandLine.isPresent("package-scope-includes") && !commandLine.isPresent("class-scope-includes") && !commandLine.isPresent("feature-scope-includes"))) { 239 regularExpressionScopeCriteria.setGlobalIncludes(commandLine.getMultipleSwitch("scope-includes")); 241 } 242 regularExpressionScopeCriteria.setGlobalExcludes(commandLine.getMultipleSwitch("scope-excludes")); 243 regularExpressionScopeCriteria.setPackageIncludes(commandLine.getMultipleSwitch("package-scope-includes")); 244 regularExpressionScopeCriteria.setPackageExcludes(commandLine.getMultipleSwitch("package-scope-excludes")); 245 regularExpressionScopeCriteria.setClassIncludes(commandLine.getMultipleSwitch("class-scope-includes")); 246 regularExpressionScopeCriteria.setClassExcludes(commandLine.getMultipleSwitch("class-scope-excludes")); 247 regularExpressionScopeCriteria.setFeatureIncludes(commandLine.getMultipleSwitch("feature-scope-includes")); 248 regularExpressionScopeCriteria.setFeatureExcludes(commandLine.getMultipleSwitch("feature-scope-excludes")); 249 250 if (commandLine.getToggleSwitch("all")) { 251 regularExpressionScopeCriteria.setMatchingPackages(true); 252 regularExpressionScopeCriteria.setMatchingClasses(true); 253 regularExpressionScopeCriteria.setMatchingFeatures(true); 254 } 255 256 if (commandLine.getToggleSwitch("p2p")) { 257 regularExpressionScopeCriteria.setMatchingPackages(true); 258 } 259 260 if (commandLine.getToggleSwitch("c2p")) { 261 regularExpressionScopeCriteria.setMatchingClasses(true); 262 } 263 264 if (commandLine.getToggleSwitch("c2c")) { 265 regularExpressionScopeCriteria.setMatchingClasses(true); 266 } 267 268 if (commandLine.getToggleSwitch("f2f")) { 269 regularExpressionScopeCriteria.setMatchingFeatures(true); 270 } 271 272 if (commandLine.isPresent("includes")) { 273 regularExpressionScopeCriteria.setGlobalIncludes(commandLine.getMultipleSwitch("includes")); 274 } 275 276 if (commandLine.isPresent("excludes")) { 277 regularExpressionScopeCriteria.setGlobalExcludes(commandLine.getMultipleSwitch("excludes")); 278 } 279 280 scopeCriteria = regularExpressionScopeCriteria; 281 } else if (hasScopeListSwitches(commandLine)) { 282 scopeCriteria = createCollectionSelectionCriteria(commandLine.getMultipleSwitch("scope-includes-list"), commandLine.getMultipleSwitch("scope-excludes-list")); 283 } 284 285 SelectionCriteria filterCriteria = new ComprehensiveSelectionCriteria(); 286 287 if (hasFilterRegularExpressionSwitches(commandLine)) { 288 RegularExpressionSelectionCriteria regularExpressionFilterCriteria = new RegularExpressionSelectionCriteria(); 289 290 regularExpressionFilterCriteria.setMatchingPackages(commandLine.getToggleSwitch("package-filter")); 291 regularExpressionFilterCriteria.setMatchingClasses(commandLine.getToggleSwitch("class-filter")); 292 regularExpressionFilterCriteria.setMatchingFeatures(commandLine.getToggleSwitch("feature-filter")); 293 294 if (commandLine.isPresent("filter-includes") || (!commandLine.isPresent("package-filter-includes") && !commandLine.isPresent("class-filter-includes") && !commandLine.isPresent("feature-filter-includes"))) { 295 regularExpressionFilterCriteria.setGlobalIncludes(commandLine.getMultipleSwitch("filter-includes")); 297 } 298 regularExpressionFilterCriteria.setGlobalExcludes(commandLine.getMultipleSwitch("filter-excludes")); 299 regularExpressionFilterCriteria.setPackageIncludes(commandLine.getMultipleSwitch("package-filter-includes")); 300 regularExpressionFilterCriteria.setPackageExcludes(commandLine.getMultipleSwitch("package-filter-excludes")); 301 regularExpressionFilterCriteria.setClassIncludes(commandLine.getMultipleSwitch("class-filter-includes")); 302 regularExpressionFilterCriteria.setClassExcludes(commandLine.getMultipleSwitch("class-filter-excludes")); 303 regularExpressionFilterCriteria.setFeatureIncludes(commandLine.getMultipleSwitch("feature-filter-includes")); 304 regularExpressionFilterCriteria.setFeatureExcludes(commandLine.getMultipleSwitch("feature-filter-excludes")); 305 306 if (commandLine.getToggleSwitch("all")) { 307 regularExpressionFilterCriteria.setMatchingPackages(true); 308 regularExpressionFilterCriteria.setMatchingClasses(true); 309 regularExpressionFilterCriteria.setMatchingFeatures(true); 310 } 311 312 if (commandLine.getToggleSwitch("p2p")) { 313 regularExpressionFilterCriteria.setMatchingPackages(true); 314 } 315 316 if (commandLine.getToggleSwitch("c2p")) { 317 regularExpressionFilterCriteria.setMatchingPackages(true); 318 } 319 320 if (commandLine.getToggleSwitch("c2c")) { 321 regularExpressionFilterCriteria.setMatchingClasses(true); 322 } 323 324 if (commandLine.getToggleSwitch("f2f")) { 325 regularExpressionFilterCriteria.setMatchingFeatures(true); 326 } 327 328 if (commandLine.isPresent("includes")) { 329 regularExpressionFilterCriteria.setGlobalIncludes(commandLine.getMultipleSwitch("includes")); 330 } 331 332 if (commandLine.isPresent("excludes")) { 333 regularExpressionFilterCriteria.setGlobalExcludes(commandLine.getMultipleSwitch("excludes")); 334 } 335 336 filterCriteria = regularExpressionFilterCriteria; 337 } else if (hasFilterListSwitches(commandLine)) { 338 filterCriteria = createCollectionSelectionCriteria(commandLine.getMultipleSwitch("filter-includes-list"), commandLine.getMultipleSwitch("filter-excludes-list")); 339 } 340 341 GraphCopier copier; 342 if (commandLine.getToggleSwitch("copy-only") || commandLine.getToggleSwitch("maximize")) { 343 copier = new GraphCopier(new SelectiveTraversalStrategy(scopeCriteria, filterCriteria)); 344 } else { 345 copier = new GraphSummarizer(scopeCriteria, filterCriteria); 346 } 347 348 Iterator i = commandLine.getParameters().iterator(); 349 while (i.hasNext()) { 350 String filename = (String ) i.next(); 351 Logger.getLogger(DependencyReporter.class).info("Reading " + filename); 352 verboseListener.print("Reading " + filename); 353 354 Collection packages = Collections.EMPTY_LIST; 355 356 if (filename.endsWith(".xml")) { 357 NodeLoader loader = new NodeLoader(commandLine.getToggleSwitch("validate")); 358 loader.addDependencyListener(verboseListener); 359 packages = loader.load(filename).getPackages().values(); 360 } 361 362 Logger.getLogger(DependencyReporter.class).info("Read in " + packages.size() + " package(s) from \"" + filename + "\"."); 363 364 if (commandLine.getToggleSwitch("maximize")) { 365 new LinkMaximizer().traverseNodes(packages); 366 } else if (commandLine.getToggleSwitch("minimize")) { 367 new LinkMinimizer().traverseNodes(packages); 368 } 369 370 copier.traverseNodes(packages); 371 } 372 373 Logger.getLogger(DependencyReporter.class).info("Reporting " + copier.getScopeFactory().getPackages().values().size() + " package(s) ..."); 374 375 verboseListener.print("Printing the graph ..."); 376 377 PrintWriter out; 378 if (commandLine.isPresent("out")) { 379 out = new PrintWriter(new FileWriter(commandLine.getSingleSwitch("out"))); 380 } else { 381 out = new PrintWriter(System.out); 382 } 383 384 Printer printer; 385 if (commandLine.isPresent("xml")) { 386 printer = new XMLPrinter(out, commandLine.getSingleSwitch("encoding"), commandLine.getSingleSwitch("dtd-prefix")); 387 } else { 388 printer = new TextPrinter(out); 389 } 390 391 if (commandLine.isPresent("indent-text")) { 392 printer.setIndentText(commandLine.getSingleSwitch("indent-text")); 393 } 394 395 printer.setShowInbounds(commandLine.isPresent("show-all") || commandLine.isPresent("show-inbounds")); 396 printer.setShowOutbounds(commandLine.isPresent("show-all") || commandLine.isPresent("show-outbounds")); 397 printer.setShowEmptyNodes(commandLine.isPresent("show-all") || commandLine.isPresent("show-empty-nodes")); 398 399 printer.traverseNodes(copier.getScopeFactory().getPackages().values()); 400 401 out.close(); 402 403 Date end = new Date(); 404 405 if (commandLine.getToggleSwitch("time")) { 406 System.err.println(DependencyReporter.class.getName() + ": " + ((end.getTime() - (double) start.getTime()) / 1000) + " secs."); 407 } 408 409 verboseListener.close(); 410 } 411 412 private static boolean hasScopeRegularExpressionSwitches(CommandLine commandLine) { 413 Collection switches = commandLine.getPresentSwitches(); 414 415 return 416 switches.contains("scope-includes") || 417 switches.contains("scope-excludes") || 418 switches.contains("package-scope") || 419 switches.contains("package-scope-includes") || 420 switches.contains("package-scope-excludes") || 421 switches.contains("class-scope") || 422 switches.contains("class-scope-includes") || 423 switches.contains("class-scope-excludes") || 424 switches.contains("feature-scope") || 425 switches.contains("feature-scope-includes") || 426 switches.contains("feature-scope-excludes") || 427 switches.contains("all") || 428 switches.contains("p2p") || 429 switches.contains("c2p") || 430 switches.contains("c2c") || 431 switches.contains("f2f") || 432 switches.contains("includes") || 433 switches.contains("excludes"); 434 } 435 436 private static boolean hasScopeListSwitches(CommandLine commandLine) { 437 Collection switches = commandLine.getPresentSwitches(); 438 439 return 440 switches.contains("scope-includes-list") || 441 switches.contains("scope-excludes-list"); 442 } 443 444 private static boolean hasFilterRegularExpressionSwitches(CommandLine commandLine) { 445 Collection switches = commandLine.getPresentSwitches(); 446 447 return 448 switches.contains("filter-includes") || 449 switches.contains("filter-excludes") || 450 switches.contains("package-filter") || 451 switches.contains("package-filter-includes") || 452 switches.contains("package-filter-excludes") || 453 switches.contains("class-filter") || 454 switches.contains("class-filter-includes") || 455 switches.contains("class-filter-excludes") || 456 switches.contains("feature-filter") || 457 switches.contains("feature-filter-includes") || 458 switches.contains("feature-filter-excludes") || 459 switches.contains("all") || 460 switches.contains("p2p") || 461 switches.contains("c2p") || 462 switches.contains("c2c") || 463 switches.contains("f2f") || 464 switches.contains("includes") || 465 switches.contains("excludes"); 466 } 467 468 private static boolean hasFilterListSwitches(CommandLine commandLine) { 469 Collection switches = commandLine.getPresentSwitches(); 470 471 return 472 switches.contains("filter-includes-list") || 473 switches.contains("filter-excludes-list"); 474 } 475 476 private static CollectionSelectionCriteria createCollectionSelectionCriteria(Collection includes, Collection excludes) throws IOException { 477 return new CollectionSelectionCriteria(loadCollection(includes), loadCollection(excludes)); 478 } 479 480 private static Collection loadCollection(Collection filenames) { 481 Collection result = null; 482 483 if (!filenames.isEmpty()) { 484 result = new HashSet(); 485 486 Iterator i = filenames.iterator(); 487 while (i.hasNext()) { 488 String filename = i.next().toString(); 489 490 BufferedReader reader = null; 491 String line; 492 493 try { 494 reader = new BufferedReader(new FileReader(filename)); 495 while ((line = reader.readLine()) != null) { 496 result.add(line); 497 } 498 } catch (IOException ex) { 499 Logger.getLogger(DependencyReporter.class).error("Couldn't read file " + filename, ex); 500 } finally { 501 try { 502 if (reader != null) { 503 reader.close(); 504 } 505 } catch (IOException ex) { 506 Logger.getLogger(DependencyReporter.class).error("Couldn't close file " + filename, ex); 507 } 508 } 509 } 510 } 511 512 return result; 513 } 514 } 515 | Popular Tags |