1 54 55 package edu.umd.cs.findbugs.anttask; 56 57 import java.io.File ; 58 import java.util.ArrayList ; 59 import java.util.List ; 60 import java.util.Properties ; 61 62 import org.apache.tools.ant.BuildException; 63 import org.apache.tools.ant.Task; 64 import org.apache.tools.ant.taskdefs.Java; 65 import org.apache.tools.ant.types.Path; 66 import org.apache.tools.ant.types.Reference; 67 68 import edu.umd.cs.findbugs.ExitCodes; 69 70 71 119 120 public class FindBugsTask extends Task { 121 122 private static final String FINDBUGS_JAR = "findbugs.jar"; 123 private static final long DEFAULT_TIMEOUT = 600000; 125 private boolean debug = false; 126 private String effort; 127 private boolean conserveSpace = false; 128 private boolean sorted = true; 129 private boolean timestampNow = true; 130 private boolean quietErrors = false; 131 private boolean failOnError = false; 132 private String errorProperty = null; 133 private String warningsProperty = null; 134 private boolean workHard = false; 135 private boolean relaxed = false; 136 private boolean adjustExperimental = false; 137 private File homeDir = null; 138 private File projectFile = null; 139 private File excludeFile = null; 140 private File includeFile = null; 141 private Path auxClasspath = null; 142 private Path auxAnalyzepath = null; 143 private Path sourcePath = null; 144 private String outputFormat = "xml"; 145 private String reportLevel = null; 146 private String jvmargs = ""; 147 private String visitors = null; 148 private String omitVisitors = null; 149 private String outputFileName = null; 150 private String stylesheet = null; 151 private List <ClassLocation> classLocations = new ArrayList <ClassLocation>(); 152 private long timeout = DEFAULT_TIMEOUT; 153 private Path classpath = null; 154 private Path pluginList = null; 155 private List <SystemProperty> systemPropertyList = new ArrayList <SystemProperty>(); 156 157 private Java findbugsEngine = null; 158 159 public static class ClassLocation { 161 File classLocation = null; 162 163 public void setLocation( File location ) { 164 classLocation = location; 165 } 166 167 public File getLocation( ) { 168 return classLocation; 169 } 170 171 @Override 172 public String toString( ) { 173 return classLocation!=null?classLocation.toString():""; 174 } 175 176 } 177 178 public static class SystemProperty { 180 private String name; 181 private String value; 182 183 public SystemProperty() { 184 } 185 186 public void setName(String name) { this.name = name; } 187 public void setValue(String value) { this.value = value; } 188 189 public String getName() { return name; } 190 public String getValue() { return value; } 191 } 192 193 196 public void setJvmargs(String args) { 197 this.jvmargs = args; 198 } 199 200 205 public void setWorkHard(boolean workHard){ 206 this.workHard = workHard; 207 } 208 209 214 public void setRelaxed(boolean relaxed) { 215 this.relaxed = relaxed; 216 } 217 218 223 public void setAdjustExperimental(boolean adjustExperimental){ 224 this.adjustExperimental = adjustExperimental; 225 } 226 227 230 public void setVisitors(String commaSeperatedString) { 231 this.visitors = commaSeperatedString; 232 } 233 234 237 public void setOmitVisitors(String commaSeperatedString) { 238 this.omitVisitors = commaSeperatedString; 239 } 240 241 244 public void setHome(File homeDir) { 245 this.homeDir = homeDir; 246 } 247 248 251 public void setOutput(String format) { 252 this.outputFormat = format; 253 } 254 255 258 public void setStylesheet(String stylesheet) { 259 this.stylesheet = stylesheet; 260 } 261 262 265 public void setReportLevel(String level) { 266 this.reportLevel = level; 267 } 268 269 272 public void setSort(boolean flag) { 273 this.sorted = flag; 274 } 275 278 public void setTimestampNow(boolean flag) { 279 this.timestampNow = flag; 280 } 281 282 285 public void setQuietErrors(boolean flag) { 286 this.quietErrors = flag; 287 } 288 289 292 public void setFailOnError(boolean flag) { 293 this.failOnError = flag; 294 } 295 296 300 public void setErrorProperty(String name) { 301 this.errorProperty = name; 302 } 303 304 308 public void setWarningsProperty(String name) { 309 this.warningsProperty = name; 310 } 311 312 315 public void setDebug(boolean flag) { 316 this.debug = flag; 317 } 318 319 324 public void setEffort(String effort) { 325 this.effort = effort; 326 } 327 328 331 public void setConserveSpace(boolean flag) { 332 this.conserveSpace = flag; 333 } 334 335 338 public void setExcludeFilter(File filterFile) { 339 this.excludeFile = filterFile; 340 } 341 342 345 public void setIncludeFilter(File filterFile) { 346 this.includeFile = filterFile; 347 } 348 349 352 public void setProjectFile(File projectFile) { 353 this.projectFile = projectFile; 354 } 355 356 359 public void setAuxClasspath(Path src) { 360 boolean nonEmpty = false; 361 362 String [] elementList = src.list(); 363 for (String anElementList : elementList) { 364 if (!anElementList.equals("")) { 365 nonEmpty = true; 366 break; 367 } 368 } 369 370 if (nonEmpty) { 371 if (auxClasspath == null) { 372 auxClasspath = src; 373 } else { 374 auxClasspath.append(src); 375 } 376 } 377 } 378 379 382 public Path createAuxClasspath() { 383 if (auxClasspath == null) { 384 auxClasspath = new Path(getProject()); 385 } 386 return auxClasspath.createPath(); 387 } 388 389 392 public void setAuxClasspathRef(Reference r) { 393 createAuxClasspath().setRefid(r); 394 } 395 396 399 public void setAuxAnalyzepath(Path src) { 400 boolean nonEmpty = false; 401 402 String [] elementList = src.list(); 403 for (String anElementList : elementList) { 404 if (!anElementList.equals("")) { 405 nonEmpty = true; 406 break; 407 } 408 } 409 410 if (nonEmpty) { 411 if (auxAnalyzepath == null) { 412 auxAnalyzepath = src; 413 } else { 414 auxAnalyzepath.append(src); 415 } 416 } 417 } 418 419 422 public Path createAuxAnalyzepath() { 423 if (auxAnalyzepath == null) { 424 auxAnalyzepath = new Path(getProject()); 425 } 426 return auxAnalyzepath.createPath(); 427 } 428 429 432 public void setAuxAnalyzepathRef(Reference r) { 433 createAuxAnalyzepath().setRefid(r); 434 } 435 436 439 public void setSourcePath(Path src) { 440 if (sourcePath == null) { 441 sourcePath = src; 442 } else { 443 sourcePath.append(src); 444 } 445 } 446 447 450 public Path createSourcePath() { 451 if (sourcePath == null) { 452 sourcePath = new Path(getProject()); 453 } 454 return sourcePath.createPath(); 455 } 456 457 460 public void setSourcePathRef(Reference r) { 461 createSourcePath().setRefid(r); 462 } 463 464 467 public ClassLocation createClass() { 468 ClassLocation cl = new ClassLocation(); 469 classLocations.add( cl ); 470 return cl; 471 } 472 473 476 public void setOutputFile(String outputFileName) { 477 this.outputFileName = outputFileName; 478 } 479 480 484 public void setTimeout(long timeout) { 485 this.timeout = timeout; 486 } 487 488 @Override 489 public void execute() throws BuildException { 490 checkParameters(); 491 try { 492 execFindbugs(); 493 } catch (BuildException e) { 494 if (errorProperty != null) { 495 getProject().setProperty(errorProperty, "true"); 496 } 497 if (failOnError) { 498 throw e; 499 } 500 } 501 } 502 503 506 public void setClasspath(Path src) { 507 if (classpath == null) { 508 classpath = src; 509 } else { 510 classpath.append(src); 511 } 512 } 513 514 517 public Path createClasspath() { 518 if (classpath == null) { 519 classpath = new Path(getProject()); 520 } 521 return classpath.createPath(); 522 } 523 524 527 public void setClasspathRef(Reference r) { 528 createClasspath().setRefid(r); 529 } 530 531 534 public void setPluginList(Path src) { 535 if (pluginList == null) { 536 pluginList = src; 537 } else { 538 pluginList.append(src); 539 } 540 } 541 542 545 public Path createPluginList() { 546 if (pluginList == null) { 547 pluginList = new Path(getProject()); 548 } 549 return pluginList.createPath(); 550 } 551 552 555 public void setPluginListRef(Reference r) { 556 createPluginList().setRefid(r); 557 } 558 559 562 public SystemProperty createSystemProperty() { 563 SystemProperty systemProperty = new SystemProperty(); 564 systemPropertyList.add(systemProperty); 565 return systemProperty; 566 } 567 568 573 private void checkParameters() { 574 if ( homeDir == null && (classpath == null || pluginList == null) ) { 575 throw new BuildException( "either home attribute or " + 576 "classpath and pluginList attributes " + 577 " must be defined for task <" 578 + getTaskName() + "/>", 579 getLocation() ); 580 } 581 582 if (pluginList != null) { 583 String [] pluginFileList = pluginList.list(); 585 for (String pluginFile : pluginFileList) { 586 if (!pluginFile.endsWith(".jar")) { 587 throw new BuildException("plugin file " + pluginFile + " is not a Jar file " + 588 "in task <" + getTaskName() + "/>", 589 getLocation()); 590 } 591 } 592 } 593 594 if ( projectFile == null && classLocations.size() == 0 && auxAnalyzepath == null) { 595 throw new BuildException( "either projectfile, <class/> or <auxAnalyzepath/> child " + 596 "elements must be defined for task <" 597 + getTaskName() + "/>", 598 getLocation() ); 599 } 600 601 if ( outputFormat != null && 602 !( outputFormat.trim().equalsIgnoreCase("xml" ) || 603 outputFormat.trim().equalsIgnoreCase("xml:withMessages" ) || 604 outputFormat.trim().equalsIgnoreCase("html" ) || 605 outputFormat.trim().equalsIgnoreCase("text" ) || 606 outputFormat.trim().equalsIgnoreCase("xdocs" ) || 607 outputFormat.trim().equalsIgnoreCase("emacs") ) ) { 608 throw new BuildException( "output attribute must be either " + 609 "'text', 'xml', 'html', 'xdocs' or 'emacs' for task <" 610 + getTaskName() + "/>", 611 getLocation() ); 612 } 613 614 if ( reportLevel != null && 615 !( reportLevel.trim().equalsIgnoreCase("experimental" ) || 616 reportLevel.trim().equalsIgnoreCase("low" ) || 617 reportLevel.trim().equalsIgnoreCase("medium" ) || 618 reportLevel.trim().equalsIgnoreCase("high" ) ) ) { 619 throw new BuildException( "reportlevel attribute must be either " + 620 "'experimental' or 'low' or 'medium' or 'high' for task <" + 621 getTaskName() + "/>", 622 getLocation() ); 623 } 624 625 if ( excludeFile != null && includeFile != null ) { 626 throw new BuildException("only one of excludeFile and includeFile " + 627 " attributes may be used in task <" + getTaskName() + "/>", 628 getLocation()); 629 } 630 631 for (SystemProperty aSystemPropertyList : systemPropertyList) { 632 SystemProperty systemProperty = (SystemProperty) aSystemPropertyList; 633 if (systemProperty.getName() == null || systemProperty.getValue() == null) 634 throw new BuildException("systemProperty elements must have name and value attributes"); 635 } 636 637 if (effort != null && !effort.equals("min") && !effort.equals("default") && !effort.equals("max")) { 638 throw new BuildException("effort attribute must be one of 'min', 'default', or 'max'"); 639 } 640 } 641 642 646 private void addArg(String arg) { 647 findbugsEngine.createArg().setValue(arg); 648 } 649 650 655 private void execFindbugs() throws BuildException { 656 findbugsEngine = (Java) getProject().createTask("java"); 657 658 findbugsEngine.setTaskName( getTaskName() ); 659 findbugsEngine.setFork( true ); 660 findbugsEngine.setTimeout( timeout ); 661 662 if ( debug ) 663 jvmargs = jvmargs + " -Dfindbugs.debug=true"; 664 findbugsEngine.createJvmarg().setLine( jvmargs ); 665 666 for (SystemProperty aSystemPropertyList : systemPropertyList) { 668 SystemProperty systemProperty = (SystemProperty) aSystemPropertyList; 669 String jvmArg = "-D" + systemProperty.getName() + "=" + systemProperty.getValue(); 670 findbugsEngine.createJvmarg().setValue(jvmArg); 671 } 672 673 if (homeDir != null) { 674 677 findbugsEngine.setJar( new File ( homeDir + File.separator + "lib" + 678 File.separator + FINDBUGS_JAR ) ); 679 680 addArg("-home"); 681 addArg(homeDir.getPath()); 682 } else { 683 687 findbugsEngine.setClasspath(classpath); 688 findbugsEngine.setClassname("edu.umd.cs.findbugs.FindBugs2"); 689 690 addArg("-pluginList"); 691 addArg(pluginList.toString()); 692 } 693 694 if (adjustExperimental) { 695 addArg("-adjustExperimental"); 696 } 697 698 if ( conserveSpace ) { 699 addArg("-conserveSpace"); 700 } 701 if ( workHard ){ 702 addArg("-workHard"); 703 } 704 if ( effort != null ) { 705 addArg("-effort:" + effort); 706 } 707 708 if ( sorted ) addArg("-sortByClass"); 709 if ( timestampNow ) addArg("-timestampNow"); 710 711 if ( outputFormat != null && !outputFormat.trim().equalsIgnoreCase("text") ) { 712 outputFormat = outputFormat.trim(); 713 String outputArg = "-"; 714 int colon = outputFormat.indexOf(':'); 715 if (colon >= 0) { 716 outputArg += outputFormat.substring(0, colon).toLowerCase(); 717 outputArg += ":"; 718 outputArg += outputFormat.substring(colon + 1); 719 } else { 720 outputArg += outputFormat.toLowerCase(); 721 if (stylesheet != null) { 722 outputArg += ":"; 723 outputArg += stylesheet.trim(); 724 } 725 } 726 addArg(outputArg); 727 } 728 if ( quietErrors ) addArg("-quiet"); 729 if ( reportLevel != null ) addArg("-" + reportLevel.trim().toLowerCase()); 730 if ( projectFile != null ) { 731 addArg("-project"); 732 addArg(projectFile.getPath()); 733 } 734 if ( excludeFile != null ) { 735 addArg("-exclude"); 736 addArg(excludeFile.getPath()); 737 } 738 if ( includeFile != null) { 739 addArg("-include"); 740 addArg(includeFile.getPath()); 741 } 742 if ( visitors != null) { 743 addArg("-visitors"); 744 addArg(visitors); 745 } 746 if ( omitVisitors != null ) { 747 addArg("-omitVisitors"); 748 addArg(omitVisitors); 749 } 750 if ( auxClasspath != null ) { 751 addArg("-auxclasspath"); 752 addArg(auxClasspath.toString()); 753 } 754 if ( sourcePath != null) { 755 addArg("-sourcepath"); 756 addArg(sourcePath.toString()); 757 } 758 if ( outputFileName != null ) { 759 addArg("-outputFile"); 760 addArg(outputFileName); 761 } 762 if ( relaxed ) { 763 addArg("-relaxed"); 764 } 765 766 addArg("-exitcode"); 767 for (ClassLocation classLocation : classLocations) { 768 addArg(classLocation.toString()); 769 } 770 771 if (auxAnalyzepath != null) { 772 String [] result = auxAnalyzepath.toString().split(java.io.File.pathSeparator); 773 for (int x=0; x<result.length; x++) { 774 addArg(result[x]); 775 } 776 } 777 778 log("Running FindBugs..."); 779 780 int rc = findbugsEngine.executeJava(); 781 782 if ((rc & ExitCodes.ERROR_FLAG) != 0) { 783 throw new BuildException("Execution of findbugs failed."); 784 } 785 if ((rc & ExitCodes.MISSING_CLASS_FLAG) != 0) { 786 log("Classes needed for analysis were missing"); 787 } 788 if (warningsProperty != null && (rc & ExitCodes.BUGS_FOUND_FLAG) != 0) { 789 getProject().setProperty(warningsProperty, "true"); 790 } 791 792 if (outputFileName != null) { 793 log("Output saved to " + outputFileName); 794 } 795 } 796 797 } 798 799 | Popular Tags |