Clover coverage report - PMD - 3.7
Coverage timestamp: Wed May 31 2006 09:25:59 EDT

file stats: | LOC: | 423 |  | Methods: | 17
| NCLOC: | 255 |  | Classes: | 1

Source file | Conditionals | Statements | Methods | TOTAL

PMD.java

8.7%

19.2%

35.3%

18.1%

1 |  | /**
2 |  | * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 |  | */
4 |  | package net.sourceforge.pmd;
5 |  |
6 |  | import net.sourceforge.pmd.ast.ParseException;
7 |  | import net.sourceforge.pmd.cpd.FileFinder;
8 |  | import net.sourceforge.pmd.cpd.SourceFileOrDirectoryFilter;
9 |  | import net.sourceforge.pmd.parsers.Parser;
10 |  | import net.sourceforge.pmd.renderers.Renderer;
11 |  | import net.sourceforge.pmd.sourcetypehandlers.SourceTypeHandler;
12 |  | import net.sourceforge.pmd.sourcetypehandlers.SourceTypeHandlerBroker;
13 |  |
14 |  | import java.io.BufferedInputStream;
15 |  | import java.io.File;
16 |  | import java.io.FileNotFoundException;
17 |  | import java.io.IOException;
18 |  | import java.io.InputStream;
19 |  | import java.io.InputStreamReader;
20 |  | import java.io.Reader;
21 |  | import java.io.UnsupportedEncodingException;
22 |  | import java.util.ArrayList;
23 |  | import java.util.Enumeration;
24 |  | import java.util.Iterator;
25 |  | import java.util.List;
26 |  | import java.util.StringTokenizer;
27 |  | import java.util.zip.ZipEntry;
28 |  | import java.util.zip.ZipFile;
29 |  |
30 |  | public class PMD {
31 |  | public static final String EOL = System.getProperty("line.separator", "\n");
32 |  | public static final String VERSION = "3.7";
33 |  |
34 |  | private String excludeMarker = ExcludeLines.EXCLUDE_MARKER;
35 |  | private SourceTypeDiscoverer sourceTypeDiscoverer = new SourceTypeDiscoverer();
36 |  | private SourceTypeHandlerBroker sourceTypeHandlerBroker = new SourceTypeHandlerBroker();
37 |  |
38 | 1054 | public PMD() {
39 |  | }
40 |  |
41 |  | /**
42 |  | * @param targetJDKVersion
43 |  | * @deprecated Use the no-args constructor and the setJavaVersion method instead
44 |  | */
45 | 1 | public PMD(TargetJDKVersion targetJDKVersion) {
46 | 1 | if (targetJDKVersion instanceof TargetJDK1_3) {
47 | 0 | setJavaVersion(SourceType.JAVA_13);
48 | 1 | } else if (targetJDKVersion instanceof TargetJDK1_5) {
49 | 0 | setJavaVersion(SourceType.JAVA_15);
50 |  | }
51 |  | }
52 |  |
53 |  | /**
54 |  | * Processes the file read by the reader agains the rule set.
55 |  | *
56 |  | * @param reader input stream reader
57 |  | * @param ruleSets set of rules to process against the file
58 |  | * @param ctx context in which PMD is operating. This contains the Renderer and
59 |  | * whatnot
60 |  | * @throws PMDException if the input could not be parsed or processed
61 |  | */
62 | 3 | public void processFile(Reader reader, RuleSets ruleSets, RuleContext ctx)
63 |  | throws PMDException {
64 | 3 | SourceType sourceType = getSourceTypeOfFile(ctx.getSourceCodeFilename());
65 |  |
66 | 3 | processFile(reader, ruleSets, ctx, sourceType);
67 |  | }
68 |  |
69 |  | /**
70 |  | * Processes the file read by the reader agains the rule set.
71 |  | *
72 |  | * @param reader input stream reader
73 |  | * @param ruleSets set of rules to process against the file
74 |  | * @param ctx context in which PMD is operating. This contains the Renderer and
75 |  | * whatnot
76 |  | * @param sourceType the SourceType of the source
77 |  | * @throws PMDException if the input could not be parsed or processed
78 |  | */
79 | 1055 | public void processFile(Reader reader, RuleSets ruleSets, RuleContext ctx,
80 |  | SourceType sourceType) throws PMDException {
81 | 1055 | try {
82 | 1055 | SourceTypeHandler sourceTypeHandler = sourceTypeHandlerBroker
83 |  | .getVisitorsFactoryForSourceType(sourceType);
84 |  |
85 | 1055 | ExcludeLines excluder = new ExcludeLines(reader, excludeMarker);
86 | 1055 | ctx.excludeLines(excluder.getLinesToExclude());
87 |  |
88 | 1055 | Parser parser = sourceTypeHandler.getParser();
89 | 1055 | Object rootNode = parser.parse(excluder.getCopyReader());
90 | 1055 | Thread.yield();
91 |  |
92 |  | // TODO - move SymbolFacade traversal inside JavaParser.CompilationUnit()
93 | 1055 | sourceTypeHandler.getSymbolFacade().start(rootNode);
94 |  |
95 | 1055 | Language language = SourceTypeToRuleLanguageMapper.getMappedLanguage(sourceType);
96 |  |
97 | 1055 | if (ruleSets.usesDFA(language)) {
98 | 0 | sourceTypeHandler.getDataFlowFacade().start(rootNode);
99 |  | }
100 |  |
101 | 1055 | List acus = new ArrayList();
102 | 1055 | acus.add(rootNode);
103 |  |
104 | 1055 | ruleSets.apply(acus, ctx, language);
105 |  | } catch (ParseException pe) {
106 | 0 | throw new PMDException("Error while parsing "
107 |  | + ctx.getSourceCodeFilename(), pe);
108 |  | } catch (Exception e) {
109 | 0 | throw new PMDException("Error while processing "
110 |  | + ctx.getSourceCodeFilename(), e);
111 |  | } finally {
112 | 1055 | try {
113 | 1055 | reader.close();
114 |  | } catch (IOException e) {
115 | 0 | throw new PMDException("Error while closing "
116 |  | + ctx.getSourceCodeFilename(), e);
117 |  | }
118 |  | }
119 |  | }
120 |  |
121 |  | /**
122 |  | * Get the SourceType of the source file with given name. This depends on the fileName
123 |  | * extension, and the java version.
124 |  | * <p/>
125 |  | * For compatibility with older code that does not always pass in a correct filename,
126 |  | * unrecognized files are assumed to be java files.
127 |  | *
128 |  | * @param fileName Name of the file, can be absolute, or simple.
129 |  | * @return the SourceType
130 |  | */
131 | 3 | private SourceType getSourceTypeOfFile(String fileName) {
132 | 3 | SourceType sourceType = sourceTypeDiscoverer.getSourceTypeOfFile(fileName);
133 | 3 | if (sourceType == null) {
134 |  | // For compatibility with older code that does not always pass in
135 |  | // a correct filename.
136 | 3 | sourceType = sourceTypeDiscoverer.getSourceTypeOfJavaFiles();
137 |  | }
138 | 3 | return sourceType;
139 |  | }
140 |  |
141 |  | /**
142 |  | * Processes the file read by the reader agains the rule set.
143 |  | *
144 |  | * @param reader input stream reader
145 |  | * @param ruleSet set of rules to process against the file
146 |  | * @param ctx context in which PMD is operating. This contains the Renderer and
147 |  | * whatnot
148 |  | * @throws PMDException if the input could not be parsed or processed
149 |  | */
150 | 3 | public void processFile(Reader reader, RuleSet ruleSet, RuleContext ctx)
151 |  | throws PMDException {
152 | 3 | processFile(reader, new RuleSets(ruleSet), ctx);
153 |  | }
154 |  |
155 |  | /**
156 |  | * Processes the input stream agains a rule set using the given input encoding.
157 |  | *
158 |  | * @param fileContents an input stream to analyze
159 |  | * @param encoding input stream's encoding
160 |  | * @param ruleSet set of rules to process against the file
161 |  | * @param ctx context in which PMD is operating. This contains the Report and whatnot
162 |  | * @throws PMDException if the input encoding is unsupported or the input stream could
163 |  | * not be parsed
164 |  | * @see #processFile(Reader, RuleSet, RuleContext)
165 |  | */
166 | 0 | public void processFile(InputStream fileContents, String encoding,
167 |  | RuleSet ruleSet, RuleContext ctx) throws PMDException {
168 | 0 | try {
169 | 0 | processFile(new InputStreamReader(fileContents, encoding), ruleSet, ctx);
170 |  | } catch (UnsupportedEncodingException uee) {
171 | 0 | throw new PMDException("Unsupported encoding exception: "
172 |  | + uee.getMessage());
173 |  | }
174 |  | }
175 |  |
176 |  | /**
177 |  | * Processes the input stream agains a rule set using the given input encoding.
178 |  | *
179 |  | * @param fileContents an input stream to analyze
180 |  | * @param encoding input stream's encoding
181 |  | * @param ruleSets set of rules to process against the file
182 |  | * @param ctx context in which PMD is operating. This contains the Report and whatnot
183 |  | * @throws PMDException if the input encoding is unsupported or the input stream could
184 |  | * not be parsed
185 |  | * @see #processFile(Reader, RuleSet, RuleContext)
186 |  | */
187 | 0 | public void processFile(InputStream fileContents, String encoding,
188 |  | RuleSets ruleSets, RuleContext ctx) throws PMDException {
189 | 0 | try {
190 | 0 | processFile(new InputStreamReader(fileContents, encoding), ruleSets, ctx);
191 |  | } catch (UnsupportedEncodingException uee) {
192 | 0 | throw new PMDException("Unsupported encoding exception: "
193 |  | + uee.getMessage());
194 |  | }
195 |  | }
196 |  |
197 |  | /**
198 |  | * Processes the input stream against a rule set assuming the platform character set.
199 |  | *
200 |  | * @param fileContents input stream to check
201 |  | * @param ruleSet the set of rules to process against the source code
202 |  | * @param ctx the context in which PMD is operating. This contains the Report and
203 |  | * whatnot
204 |  | * @throws PMDException if the input encoding is unsupported or the input input stream
205 |  | * could not be parsed
206 |  | * @see #processFile(InputStream, String, RuleSet, RuleContext)
207 |  | */
208 | 0 | public void processFile(InputStream fileContents, RuleSet ruleSet,
209 |  | RuleContext ctx) throws PMDException {
210 | 0 | processFile(fileContents, System.getProperty("file.encoding"), ruleSet, ctx);
211 |  | }
212 |  |
213 | 0 | public void setExcludeMarker(String marker) {
214 | 0 | this.excludeMarker = marker;
215 |  | }
216 |  |
217 |  | /**
218 |  | * Set the SourceType to be used for ".java" files.
219 |  | *
220 |  | * @param javaVersion the SourceType that indicates the java version
221 |  | */
222 | 0 | public void setJavaVersion(SourceType javaVersion) {
223 | 0 | sourceTypeDiscoverer.setSourceTypeOfJavaFiles(javaVersion);
224 |  | }
225 |  |
226 | 0 | public static void main(String[] args) {
227 | 0 | CommandLineOptions opts = new CommandLineOptions(args);
228 |  |
229 | 0 | SourceFileSelector fileSelector = new SourceFileSelector();
230 |  |
231 | 0 | fileSelector.setSelectJavaFiles(opts.isCheckJavaFiles());
232 | 0 | fileSelector.setSelectJspFiles(opts.isCheckJspFiles());
233 |  |
234 | 0 | List files;
235 | 0 | if (opts.containsCommaSeparatedFileList()) {
236 | 0 | files = collectFromCommaDelimitedString(opts.getInputPath(),
237 |  | fileSelector);
238 |  | } else {
239 | 0 | files = collectFilesFromOneName(opts.getInputPath(), fileSelector);
240 |  | }
241 |  |
242 | 0 | PMD pmd = new PMD();
243 | 0 | if (opts.getTargetJDK().equals("1.3")) {
244 | 0 | if (opts.debugEnabled())
245 | 0 | System.out.println("In JDK 1.3 mode");
246 | 0 | pmd.setJavaVersion(SourceType.JAVA_13);
247 | 0 | } else if (opts.getTargetJDK().equals("1.5")) {
248 | 0 | if (opts.debugEnabled())
249 | 0 | System.out.println("In JDK 1.5 mode");
250 | 0 | pmd.setJavaVersion(SourceType.JAVA_15);
251 |  | } else {
252 | 0 | if (opts.debugEnabled())
253 | 0 | System.out.println("In JDK 1.4 mode");
254 | 0 | pmd.setJavaVersion(SourceType.JAVA_14);
255 |  | }
256 | 0 | pmd.setExcludeMarker(opts.getExcludeMarker());
257 |  |
258 | 0 | RuleContext ctx = new RuleContext();
259 | 0 | Report report = new Report();
260 | 0 | ctx.setReport(report);
261 | 0 | report.start();
262 |  |
263 | 0 | try {
264 | 0 | RuleSetFactory ruleSetFactory = new RuleSetFactory();
265 | 0 | RuleSets rulesets = ruleSetFactory.createRuleSets(opts.getRulesets());
266 | 0 | printRuleNamesInDebug(opts.debugEnabled(), rulesets);
267 |  |
268 | 0 | pmd.processFiles(files, ctx, rulesets, opts.debugEnabled(), opts
269 |  | .shortNamesEnabled(), opts.getInputPath(), opts.getEncoding());
270 |  | } catch (FileNotFoundException fnfe) {
271 | 0 | System.out.println(opts.usage());
272 | 0 | fnfe.printStackTrace();
273 |  | } catch (RuleSetNotFoundException rsnfe) {
274 | 0 | System.out.println(opts.usage());
275 | 0 | rsnfe.printStackTrace();
276 |  | } catch (IOException ioe) {
277 | 0 | System.out.println(opts.usage());
278 | 0 | ioe.printStackTrace();
279 |  | }
280 | 0 | report.end();
281 |  |
282 | 0 | try {
283 | 0 | Renderer r = opts.createRenderer();
284 | 0 | System.out.println(r.render(ctx.getReport()));
285 |  | } catch (Exception e) {
286 | 0 | System.out.println(e.getMessage());
287 | 0 | System.out.println(opts.usage());
288 | 0 | if (opts.debugEnabled()) {
289 | 0 | e.printStackTrace();
290 |  | }
291 |  | }
292 |  | }
293 |  |
294 |  | /**
295 |  | * Run PMD on a list of files.
296 |  | *
297 |  | * @param files the List of DataSource instances.
298 |  | * @param ctx the context in which PMD is operating. This contains the Report and
299 |  | * whatnot
300 |  | * @param rulesets the RuleSets
301 |  | * @param debugEnabled
302 |  | * @param shortNamesEnabled
303 |  | * @param inputPath
304 |  | * @param encoding
305 |  | * @throws IOException If one of the files could not be read
306 |  | */
307 | 0 | public void processFiles(List files, RuleContext ctx, RuleSets rulesets,
308 |  | boolean debugEnabled, boolean shortNamesEnabled, String inputPath,
309 |  | String encoding) throws IOException {
310 | 0 | for (Iterator i = files.iterator(); i.hasNext();) {
311 | 0 | DataSource dataSource = (DataSource) i.next();
312 |  |
313 | 0 | String niceFileName = dataSource.getNiceFileName(shortNamesEnabled,
314 |  | inputPath);
315 | 0 | ctx.setSourceCodeFilename(niceFileName);
316 | 0 | if (debugEnabled) {
317 | 0 | System.out.println("Processing " + ctx.getSourceCodeFilename());
318 |  | }
319 |  |
320 | 0 | try {
321 | 0 | InputStream stream = new BufferedInputStream(dataSource
322 |  | .getInputStream());
323 | 0 | processFile(stream, encoding, rulesets, ctx);
324 |  | } catch (PMDException pmde) {
325 | 0 | if (debugEnabled) {
326 | 0 | pmde.getReason().printStackTrace();
327 |  | }
328 | 0 | ctx.getReport().addError(new Report.ProcessingError(pmde.getMessage(), niceFileName));
329 |  | }
330 |  | }
331 |  | }
332 |  |
333 |  | /**
334 |  | * If in debug modus, print the names of the rules.
335 |  | *
336 |  | * @param debugEnabled the boolean indicating if debug is enabled
337 |  | * @param rulesets the RuleSets to print
338 |  | */
339 | 0 | private static void printRuleNamesInDebug(boolean debugEnabled, RuleSets rulesets) {
340 | 0 | if (debugEnabled) {
341 | 0 | for (Iterator i = rulesets.getAllRules().iterator(); i.hasNext();) {
342 | 0 | Rule r = (Rule) i.next();
343 | 0 | System.out.println("Loaded rule " + r.getName());
344 |  | }
345 |  | }
346 |  | }
347 |  |
348 |  | /**
349 |  | * Collects the given file into a list.
350 |  | *
351 |  | * @param inputFileName a file name
352 |  | * @param fileSelector Filtering of wanted source files
353 |  | * @return the list of files collected from the <code>inputFileName</code>
354 |  | * @see #collect(String)
355 |  | */
356 | 0 | private static List collectFilesFromOneName(String inputFileName,
357 |  | SourceFileSelector fileSelector) {
358 | 0 | return collect(inputFileName, fileSelector);
359 |  | }
360 |  |
361 |  | /**
362 |  | * Collects the files from the given comma-separated list.
363 |  | *
364 |  | * @param fileList comma-separated list of filenames
365 |  | * @param fileSelector Filtering of wanted source files
366 |  | * @return list of files collected from the <code>fileList</code>
367 |  | */
368 | 0 | private static List collectFromCommaDelimitedString(String fileList,
369 |  | SourceFileSelector fileSelector) {
370 | 0 | List files = new ArrayList();
371 | 0 | for (StringTokenizer st = new StringTokenizer(fileList, ","); st
372 |  | .hasMoreTokens();) {
373 | 0 | files.addAll(collect(st.nextToken(), fileSelector));
374 |  | }
375 | 0 | return files;
376 |  | }
377 |  |
378 |  | /**
379 |  | * Collects the files from the given <code>filename</code>.
380 |  | *
381 |  | * @param filename the source from which to collect files
382 |  | * @param fileSelector Filtering of wanted source files
383 |  | * @return a list of files found at the given <code>filename</code>
384 |  | * @throws RuntimeException if <code>filename</code> is not found
385 |  | */
386 | 0 | private static List collect(String filename, SourceFileSelector fileSelector) {
387 | 0 | File inputFile = new File(filename);
388 | 0 | if (!inputFile.exists()) {
389 | 0 | throw new RuntimeException("File " + inputFile.getName()
390 |  | + " doesn't exist");
391 |  | }
392 | 0 | List dataSources = new ArrayList();
393 | 0 | if (!inputFile.isDirectory()) {
394 | 0 | if (filename.endsWith(".zip") || filename.endsWith(".jar")) {
395 | 0 | ZipFile zipFile;
396 | 0 | try {
397 | 0 | zipFile = new ZipFile(inputFile);
398 | 0 | Enumeration e = zipFile.entries();
399 | 0 | while (e.hasMoreElements()) {
400 | 0 | ZipEntry zipEntry = (ZipEntry) e.nextElement();
401 | 0 | if (fileSelector.isWantedFile(zipEntry.getName())) {
402 | 0 | dataSources.add(new ZipDataSource(zipFile, zipEntry));
403 |  | }
404 |  | }
405 |  | } catch (IOException ze) {
406 | 0 | throw new RuntimeException("Zip file " + inputFile.getName()
407 |  | + " can't be opened");
408 |  | }
409 |  | } else {
410 | 0 | dataSources.add(new FileDataSource(inputFile));
411 |  | }
412 |  | } else {
413 | 0 | FileFinder finder = new FileFinder();
414 | 0 | List files = finder.findFilesFrom(inputFile.getAbsolutePath(),
415 |  | new SourceFileOrDirectoryFilter(fileSelector), true);
416 | 0 | for (Iterator i = files.iterator(); i.hasNext();) {
417 | 0 | dataSources.add(new FileDataSource((File) i.next()));
418 |  | }
419 |  | }
420 | 0 | return dataSources;
421 |  | }
422 |  |
423 |  | }