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