1 4 package net.sourceforge.pmd.ant; 5 6 import net.sourceforge.pmd.PMD; 7 import net.sourceforge.pmd.PMDException; 8 import net.sourceforge.pmd.Report; 9 import net.sourceforge.pmd.Rule; 10 import net.sourceforge.pmd.RuleContext; 11 import net.sourceforge.pmd.RuleSet; 12 import net.sourceforge.pmd.RuleSetFactory; 13 import net.sourceforge.pmd.RuleSetNotFoundException; 14 import net.sourceforge.pmd.RuleSets; 15 import net.sourceforge.pmd.SimpleRuleSetNameMapper; 16 import net.sourceforge.pmd.SourceType; 17 import org.apache.tools.ant.AntClassLoader; 18 import org.apache.tools.ant.BuildException; 19 import org.apache.tools.ant.DirectoryScanner; 20 import org.apache.tools.ant.Project; 21 import org.apache.tools.ant.Task; 22 import org.apache.tools.ant.types.FileSet; 23 import org.apache.tools.ant.types.Path; 24 import org.apache.tools.ant.types.Reference; 25 26 import java.io.BufferedInputStream ; 27 import java.io.File ; 28 import java.io.FileInputStream ; 29 import java.io.FileNotFoundException ; 30 import java.io.PrintWriter ; 31 import java.io.StringWriter ; 32 import java.util.ArrayList ; 33 import java.util.Collection ; 34 import java.util.Iterator ; 35 import java.util.List ; 36 37 public class PMDTask extends Task { 38 39 private Path classpath; 40 private List formatters = new ArrayList (); 41 private List filesets = new ArrayList (); 42 private int minPriority = Rule.LOWEST_PRIORITY; 43 private boolean shortFilenames; 44 private String ruleSetFiles; 45 private String encoding = System.getProperty("file.encoding"); 46 private boolean failOnError; 47 private boolean failOnRuleViolation; 48 private String targetJDK = "1.4"; 49 private String failuresPropertyName; 50 private String excludeMarker; 51 private final Collection nestedRules = new ArrayList (); 52 53 public void setShortFilenames(boolean value) { 54 this.shortFilenames = value; 55 } 56 57 public void setTargetJDK(String value) { 58 this.targetJDK = value; 59 } 60 61 public void setExcludeMarker(String value) { 62 this.excludeMarker = value; 63 } 64 65 public void setFailOnError(boolean fail) { 66 this.failOnError = fail; 67 } 68 69 public void setFailOnRuleViolation(boolean fail) { 70 this.failOnRuleViolation = fail; 71 } 72 73 public void setRuleSetFiles(String ruleSetFiles) { 74 this.ruleSetFiles = ruleSetFiles; 75 } 76 77 public void setEncoding(String encoding) { 78 this.encoding = encoding; 79 } 80 81 public void setFailuresPropertyName(String failuresPropertyName) { 82 this.failuresPropertyName = failuresPropertyName; 83 } 84 85 public void setMinimumPriority(int minPriority) { 86 this.minPriority = minPriority; 87 } 88 89 public void addFileset(FileSet set) { 90 filesets.add(set); 91 } 92 93 public void addFormatter(Formatter f) { 94 formatters.add(f); 95 } 96 97 public void setClasspath(Path classpath) { 98 this.classpath = classpath; 99 } 100 101 public Path getClasspath() { 102 return classpath; 103 } 104 105 public Path createClasspath() { 106 if (classpath == null) { 107 classpath = new Path(getProject()); 108 } 109 return classpath.createPath(); 110 } 111 112 public void setClasspathRef(Reference r) { 113 createLongClasspath().setRefid(r); 114 } 115 116 public void execute() throws BuildException { 117 validate(); 118 119 ruleSetFiles = new SimpleRuleSetNameMapper(ruleSetFiles).getRuleSets(); 120 RuleSets rules; 121 try { 122 RuleSetFactory ruleSetFactory = new RuleSetFactory(); 123 ruleSetFactory.setMinimumPriority(minPriority); 124 if (classpath == null) { 125 log("Using the normal ClassLoader", Project.MSG_VERBOSE); 126 rules = ruleSetFactory.createRuleSets(ruleSetFiles); 127 } else { 128 log("Using the AntClassLoader", Project.MSG_VERBOSE); 129 rules = ruleSetFactory.createRuleSets(ruleSetFiles, new AntClassLoader(getProject(), classpath)); 130 } 131 } catch (RuleSetNotFoundException e) { 132 throw new BuildException(e.getMessage()); 133 } 134 logRulesUsed(rules); 135 136 PMD pmd; 137 if (targetJDK.equals("1.3")) { 138 log("Targeting Java language version 1.3", Project.MSG_VERBOSE); 139 pmd = new PMD(); 140 pmd.setJavaVersion(SourceType.JAVA_13); 141 } else if (targetJDK.equals("1.5")) { 142 log("Targeting Java language version 1.5", Project.MSG_VERBOSE); 143 pmd = new PMD(); 144 pmd.setJavaVersion(SourceType.JAVA_15); 145 } else if (targetJDK.equals("1.6")) { 146 log("Targeting Java language version 1.6", Project.MSG_VERBOSE); 147 pmd = new PMD(); 148 pmd.setJavaVersion(SourceType.JAVA_16); 149 } else if(targetJDK.equals("jsp")){ 150 log("Targeting JSP", Project.MSG_VERBOSE); 151 pmd = new PMD(); 152 pmd.setJavaVersion(SourceType.JSP); 153 } else { 154 log("Targeting Java language version 1.4", Project.MSG_VERBOSE); 155 pmd = new PMD(); 156 } 157 158 if (excludeMarker != null) { 159 log("Setting exclude marker to be " + excludeMarker, Project.MSG_VERBOSE); 160 pmd.setExcludeMarker(excludeMarker); 161 } 162 163 RuleContext ctx = new RuleContext(); 164 Report report = new Report(); 165 ctx.setReport(report); 166 report.start(); 167 for (Iterator i = filesets.iterator(); i.hasNext();) { 168 FileSet fs = (FileSet) i.next(); 169 DirectoryScanner ds = fs.getDirectoryScanner(getProject()); 170 String [] srcFiles = ds.getIncludedFiles(); 171 for (int j = 0; j < srcFiles.length; j++) { 172 File file = new File (ds.getBasedir() + System.getProperty("file.separator") + srcFiles[j]); 173 log("Processing file " + file.getAbsoluteFile().toString(), Project.MSG_VERBOSE); 174 ctx.setSourceCodeFilename(shortFilenames ? srcFiles[j] : file.getAbsolutePath()); 175 try { 176 pmd.processFile(new BufferedInputStream (new FileInputStream (file)), encoding, rules, ctx); 177 } catch (FileNotFoundException fnfe) { 178 if (failOnError) { 179 throw new BuildException(fnfe); 180 } 181 } catch (PMDException pmde) { 182 log(pmde.toString(), Project.MSG_VERBOSE); 183 if (pmde.getReason() != null) { 184 StringWriter strWriter = new StringWriter (); 185 PrintWriter printWriter = new PrintWriter (strWriter); 186 pmde.getReason().printStackTrace(printWriter); 187 log(strWriter.toString(), Project.MSG_VERBOSE); 188 } 189 if (pmde.getReason() != null && pmde.getReason().getMessage() != null) { 190 log(pmde.getReason().getMessage(), Project.MSG_VERBOSE); 191 } 192 if (failOnError) { 193 throw new BuildException(pmde); 194 } 195 ctx.getReport().addError(new Report.ProcessingError(pmde.getMessage(), ctx.getSourceCodeFilename())); 196 } 197 } 198 } 199 report.end(); 200 201 log(ctx.getReport().size() + " problems found", Project.MSG_VERBOSE); 202 203 for (Iterator i = formatters.iterator(); i.hasNext();) { 204 Formatter formatter = (Formatter) i.next(); 205 log("Sending a report to " + formatter, Project.MSG_VERBOSE); 206 formatter.outputReport(ctx.getReport(), getProject().getBaseDir().toString()); 207 } 208 209 if (failuresPropertyName != null && ctx.getReport().size() > 0) { 210 getProject().setProperty(failuresPropertyName, String.valueOf(ctx.getReport().size())); 211 log("Setting property " + failuresPropertyName + " to " + ctx.getReport().size(), Project.MSG_VERBOSE); 212 } 213 214 if (failOnRuleViolation && ctx.getReport().size() > 0) { 215 throw new BuildException("Stopping build since PMD found " + ctx.getReport().size() + " rule violations in the code"); 216 } 217 } 218 219 private void logRulesUsed(net.sourceforge.pmd.RuleSets rules) { 220 log("Using these rulesets: " + ruleSetFiles, Project.MSG_VERBOSE); 221 222 RuleSet[] ruleSets = rules.getAllRuleSets(); 223 for (int j = 0; j < ruleSets.length; j++) { 224 RuleSet ruleSet = ruleSets[j]; 225 226 for (Iterator i = ruleSet.getRules().iterator(); i.hasNext();) { 227 Rule rule = (Rule) i.next(); 228 log("Using rule " + rule.getName(), Project.MSG_VERBOSE); 229 } 230 } 231 } 232 233 private void validate() throws BuildException { 234 for (Iterator i = formatters.iterator(); i.hasNext();) { 236 Formatter f = (Formatter) i.next(); 237 if (f.isNoOutputSupplied()) { 238 throw new BuildException("toFile or toConsole needs to be specified in Formatter"); 239 } 240 } 241 242 if (ruleSetFiles == null) { 243 if (nestedRules.isEmpty()) { 244 throw new BuildException("No rulesets specified"); 245 } 246 ruleSetFiles = getNestedRuleSetFiles(); 247 } 248 249 if (!targetJDK.equals("1.3") && !targetJDK.equals("1.4") && !targetJDK.equals("1.5") && !targetJDK.equals("1.6") && !targetJDK.equals("jsp")) { 250 throw new BuildException("The targetjdk attribute, if used, must be set to either '1.3', '1.4', '1.5', '1.6' or 'jsp'"); 251 } 252 } 253 254 private String getNestedRuleSetFiles() { 255 final StringBuffer sb = new StringBuffer (); 256 for (Iterator it = nestedRules.iterator(); it.hasNext();) { 257 RuleSetWrapper rs = (RuleSetWrapper) it.next(); 258 sb.append(rs.getFile()); 259 if (it.hasNext()) { 260 sb.append(','); 261 } 262 } 263 return sb.toString(); 264 } 265 266 private Path createLongClasspath() { 267 if (classpath == null) { 268 classpath = new Path(getProject()); 269 } 270 return classpath.createPath(); 271 } 272 273 public void addRuleset(RuleSetWrapper r) { 274 nestedRules.add(r); 275 } 276 277 } 278 279 | Popular Tags |