1 package net.sourceforge.pmd.ant;
2
3 import net.sourceforge.pmd.PMD;
4 import net.sourceforge.pmd.PMDException;
5 import net.sourceforge.pmd.Report;
6 import net.sourceforge.pmd.Rule;
7 import net.sourceforge.pmd.RuleContext;
8 import net.sourceforge.pmd.RuleSet;
9 import net.sourceforge.pmd.RuleSetFactory;
10 import net.sourceforge.pmd.RuleSetNotFoundException;
11 import net.sourceforge.pmd.renderers.Renderer;
12 import net.sourceforge.pmd.renderers.TextRenderer;
13 import org.apache.tools.ant.AntClassLoader;
14 import org.apache.tools.ant.BuildException;
15 import org.apache.tools.ant.DirectoryScanner;
16 import org.apache.tools.ant.Project;
17 import org.apache.tools.ant.Task;
18 import org.apache.tools.ant.types.FileSet;
19 import org.apache.tools.ant.types.Path;
20 import org.apache.tools.ant.types.Reference;
21
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileNotFoundException;
25 import java.io.IOException;
26 import java.io.Writer;
27 import java.util.ArrayList;
28 import java.util.Iterator;
29 import java.util.List;
30
31 public class PMDTask extends Task {
32
33 private Path classpath;
34 private List formatters = new ArrayList();
35 private List filesets = new ArrayList();
36 private boolean shortFilenames;
37 private boolean printToConsole;
38 private String ruleSetFiles;
39 private boolean failOnError;
40 private boolean failOnRuleViolation;
41
42 /***
43 * The end of line string for this machine.
44 */
45 protected String EOL = System.getProperty("line.separator", "\n");
46
47 public void setShortFilenames(boolean value) {
48 this.shortFilenames = value;
49 }
50
51 public void setFailOnError(boolean fail) {
52 this.failOnError = fail;
53 }
54
55 public void setFailOnRuleViolation(boolean fail) {
56 this.failOnRuleViolation = fail;
57 }
58
59 public void setPrintToConsole(boolean printToConsole) {
60 this.printToConsole = printToConsole;
61 }
62
63 public void setRuleSetFiles(String ruleSetFiles) {
64 this.ruleSetFiles = ruleSetFiles;
65 }
66
67 public void addFileset(FileSet set) {
68 filesets.add(set);
69 }
70
71 public void addFormatter(Formatter f) {
72 formatters.add(f);
73 }
74
75 public void setClasspath(Path classpath) {
76 this.classpath = classpath;
77 }
78
79 public Path getClasspath() {
80 return classpath;
81 }
82
83 public Path createClasspath() {
84 if (classpath == null) {
85 classpath = new Path(getProject());
86 }
87 return classpath.createPath();
88 }
89
90 public void setClasspathRef(Reference r) {
91 createLongClasspath().setRefid(r);
92 }
93
94 public void execute() throws BuildException {
95 validate();
96
97 RuleSet rules;
98 try {
99 RuleSetFactory ruleSetFactory = new RuleSetFactory();
100 if (classpath == null) {
101 log("Using the normal ClassLoader", Project.MSG_VERBOSE);
102 rules = ruleSetFactory.createRuleSet(ruleSetFiles);
103 } else {
104 log("Using the AntClassLoader", Project.MSG_VERBOSE);
105 rules = ruleSetFactory.createRuleSet(ruleSetFiles, new AntClassLoader(project, classpath));
106 }
107 } catch (RuleSetNotFoundException e) {
108 throw new BuildException(e.getMessage());
109 }
110
111 logRulesUsed(rules);
112
113 PMD pmd = new PMD();
114 RuleContext ctx = new RuleContext();
115 ctx.setReport(new Report());
116 for (Iterator i = filesets.iterator(); i.hasNext();) {
117 FileSet fs = (FileSet) i.next();
118 DirectoryScanner ds = fs.getDirectoryScanner(project);
119 String[] srcFiles = ds.getIncludedFiles();
120 for (int j = 0; j < srcFiles.length; j++) {
121 File file = new File(ds.getBasedir() + System.getProperty("file.separator") + srcFiles[j]);
122 log("Processing file " + file.getAbsoluteFile().toString(), Project.MSG_VERBOSE);
123 ctx.setSourceCodeFilename(shortFilenames ? srcFiles[j] : file.getAbsolutePath());
124 try {
125 pmd.processFile(new FileInputStream(file), rules, ctx);
126 } catch (FileNotFoundException fnfe) {
127 if (failOnError) {
128 throw new BuildException(fnfe);
129 }
130 } catch (PMDException pmde) {
131 log(pmde.toString(), Project.MSG_VERBOSE);
132 if (failOnError) {
133 throw new BuildException(pmde);
134 }
135 ctx.getReport().addError(new Report.ProcessingError(pmde.getMessage(), ctx.getSourceCodeFilename()));
136 }
137 }
138 }
139
140 log(ctx.getReport().size() + " problems found", Project.MSG_VERBOSE);
141
142 if (!ctx.getReport().isEmpty()) {
143 for (Iterator i = formatters.iterator(); i.hasNext();) {
144 Formatter formatter = (Formatter) i.next();
145 log("Sending a report to " + formatter, Project.MSG_VERBOSE);
146 String buffer = formatter.getRenderer().render(ctx.getReport()) + EOL;
147 try {
148 Writer writer = formatter.getToFileWriter(project.getBaseDir().toString());
149 writer.write(buffer, 0, buffer.length());
150 writer.close();
151 } catch (IOException ioe) {
152 throw new BuildException(ioe.getMessage());
153 }
154 }
155
156 if (printToConsole) {
157 Renderer r = new TextRenderer();
158 log(r.render(ctx.getReport()), Project.MSG_INFO);
159 }
160
161 if (failOnRuleViolation) {
162 throw new BuildException("Stopping build since PMD found " + ctx.getReport().size() + " rule violations in the code");
163 }
164 }
165 }
166
167 private void logRulesUsed(RuleSet rules) {
168 log("Using these rulesets: " + ruleSetFiles, Project.MSG_VERBOSE);
169 for (Iterator i = rules.getRules().iterator();i.hasNext();) {
170 Rule rule = (Rule)i.next();
171 log("Using rule " + rule.getName(), Project.MSG_VERBOSE);
172 }
173 }
174
175 private void validate() throws BuildException {
176 if (formatters.isEmpty() && !printToConsole) {
177 throw new BuildException("No formatter specified; and printToConsole was false");
178 }
179
180 for (Iterator i = formatters.iterator(); i.hasNext();) {
181 Formatter f = (Formatter) i.next();
182 if (f.isToFileNull()) {
183 throw new BuildException("Formatter toFile attribute is required");
184 }
185 }
186
187 if (ruleSetFiles == null) {
188 throw new BuildException("No rulesets specified");
189 }
190 }
191
192 private Path createLongClasspath() {
193 if (classpath == null) {
194 classpath = new Path(project);
195 }
196 return classpath.createPath();
197 }
198
199 }
This page was automatically generated by Maven