Clover coverage report - PMD - 3.9 Coverage timestamp: Tue Dec 19 2006 09:38:44 EST FRAMES NO FRAMES |
file stats: | LOC: | 592 |  | Methods: | 25
| NCLOC: | 393 |  | Classes: | 4
Source file | Conditionals | Statements | Methods | TOTAL
PMD.java | 7.6% | 14.6% | 28% | 14.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.BufferedWriter;
16 |  | import java.io.File;
17 |  | import java.io.FileWriter;
18 |  | import java.io.IOException;
19 |  | import java.io.InputStream;
20 |  | import java.io.InputStreamReader;
21 |  | import java.io.OutputStreamWriter;
22 |  | import java.io.Reader;
23 |  | import java.io.UnsupportedEncodingException;
24 |  | import java.io.Writer;
25 |  | import java.util.ArrayList;
26 |  | import java.util.Enumeration;
27 |  | import java.util.Iterator;
28 |  | import java.util.LinkedList;
29 |  | import java.util.List;
30 |  | import java.util.StringTokenizer;
31 |  | import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService;
32 |  | import edu.emory.mathcs.backport.java.util.concurrent.Executors;
33 |  | import edu.emory.mathcs.backport.java.util.concurrent.ThreadFactory;
34 |  | import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
35 |  | import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicInteger;
36 |  | import edu.emory.mathcs.backport.java.util.Collections;
37 |  | import java.util.zip.ZipEntry;
38 |  | import java.util.zip.ZipFile;
39 |  |
40 |  | public class PMD {
41 |  | public static final String EOL = System.getProperty("line.separator", "\n");
42 |  | public static final String VERSION = "3.9";
43 |  | public static final String EXCLUDE_MARKER = "NOPMD";
44 |  |
45 |  |
46 |  | private String excludeMarker = EXCLUDE_MARKER;
47 |  | private SourceTypeDiscoverer sourceTypeDiscoverer = new SourceTypeDiscoverer();
48 |  |
49 | 1260 | public PMD() {}
50 |  |
51 |  | /**
52 |  | * Processes the file read by the reader agains the rule set.
53 |  | *
54 |  | * @param reader input stream reader
55 |  | * @param ruleSets set of rules to process against the file
56 |  | * @param ctx context in which PMD is operating. This contains the Renderer and
57 |  | * whatnot
58 |  | * @throws PMDException if the input could not be parsed or processed
59 |  | */
60 | 3 | public void processFile(Reader reader, RuleSets ruleSets, RuleContext ctx)
61 |  | throws PMDException {
62 | 3 | SourceType sourceType = getSourceTypeOfFile(ctx.getSourceCodeFilename());
63 |  |
64 | 3 | processFile(reader, ruleSets, ctx, sourceType);
65 |  | }
66 |  |
67 |  | /**
68 |  | * Processes the file read by the reader against the rule set.
69 |  | *
70 |  | * @param reader input stream reader
71 |  | * @param ruleSets set of rules to process against the file
72 |  | * @param ctx context in which PMD is operating. This contains the Renderer and
73 |  | * whatnot
74 |  | * @param sourceType the SourceType of the source
75 |  | * @throws PMDException if the input could not be parsed or processed
76 |  | */
77 | 1260 | public void processFile(Reader reader, RuleSets ruleSets, RuleContext ctx,
78 |  | SourceType sourceType) throws PMDException {
79 | 1260 | try {
80 | 1260 | SourceTypeHandler sourceTypeHandler = SourceTypeHandlerBroker.getVisitorsFactoryForSourceType(sourceType);
81 | 1260 | ctx.setSourceType(sourceType);
82 | 1260 | Parser parser = sourceTypeHandler.getParser();
83 | 1260 | parser.setExcludeMarker(excludeMarker);
84 | 1260 | Object rootNode = parser.parse(reader);
85 | 1260 | ctx.excludeLines(parser.getExcludeMap());
86 | 1260 | Thread.yield();
87 | 1260 | sourceTypeHandler.getSymbolFacade().start(rootNode);
88 |  |
89 | 1260 | Language language = SourceTypeToRuleLanguageMapper.getMappedLanguage(sourceType);
90 |  |
91 | 1260 | if (ruleSets.usesDFA(language)) {
92 | 5 | sourceTypeHandler.getDataFlowFacade().start(rootNode);
93 |  | }
94 |  |
95 | 1260 | if (ruleSets.usesTypeResolution(language)) {
96 | 18 | sourceTypeHandler.getTypeResolutionFacade().start(rootNode);
97 |  | }
98 |  |
99 | 1260 | List acus = new ArrayList();
100 | 1260 | acus.add(rootNode);
101 |  |
102 | 1260 | ruleSets.apply(acus, ctx, language);
103 |  | } catch (ParseException pe) {
104 | 0 | throw new PMDException("Error while parsing "
105 |  | + ctx.getSourceCodeFilename(), pe);
106 |  | } catch (Exception e) {
107 | 0 | throw new PMDException("Error while processing "
108 |  | + ctx.getSourceCodeFilename(), e);
109 |  | } finally {
110 | 1260 | try {
111 | 1260 | reader.close();
112 |  | } catch (IOException e) {
113 | 0 | throw new PMDException("Error while closing "
114 |  | + ctx.getSourceCodeFilename(), e);
115 |  | }
116 |  | }
117 |  | }
118 |  |
119 |  | /**
120 |  | * Get the SourceType of the source file with given name. This depends on the fileName
121 |  | * extension, and the java version.
122 |  | * <p/>
123 |  | * For compatibility with older code that does not always pass in a correct filename,
124 |  | * unrecognized files are assumed to be java files.
125 |  | *
126 |  | * @param fileName Name of the file, can be absolute, or simple.
127 |  | * @return the SourceType
128 |  | */
129 | 3 | private SourceType getSourceTypeOfFile(String fileName) {
130 | 3 | SourceType sourceType = sourceTypeDiscoverer.getSourceTypeOfFile(fileName);
131 | 3 | if (sourceType == null) {
132 |  | // For compatibility with older code that does not always pass in
133 |  | // a correct filename.
134 | 3 | sourceType = sourceTypeDiscoverer.getSourceTypeOfJavaFiles();
135 |  | }
136 | 3 | return sourceType;
137 |  | }
138 |  |
139 |  | /**
140 |  | * Processes the file read by the reader agains the rule set.
141 |  | *
142 |  | * @param reader input stream reader
143 |  | * @param ruleSet set of rules to process against the file
144 |  | * @param ctx context in which PMD is operating. This contains the Renderer and
145 |  | * whatnot
146 |  | * @throws PMDException if the input could not be parsed or processed
147 |  | */
148 | 3 | public void processFile(Reader reader, RuleSet ruleSet, RuleContext ctx)
149 |  | throws PMDException {
150 | 3 | processFile(reader, new RuleSets(ruleSet), ctx);
151 |  | }
152 |  |
153 |  | /**
154 |  | * Processes the input stream agains a rule set using the given input encoding.
155 |  | *
156 |  | * @param fileContents an input stream to analyze
157 |  | * @param encoding input stream's encoding
158 |  | * @param ruleSet set of rules to process against the file
159 |  | * @param ctx context in which PMD is operating. This contains the Report and whatnot
160 |  | * @throws PMDException if the input encoding is unsupported or the input stream could
161 |  | * not be parsed
162 |  | * @see #processFile(Reader, RuleSet, RuleContext)
163 |  | */
164 | 0 | public void processFile(InputStream fileContents, String encoding,
165 |  | RuleSet ruleSet, RuleContext ctx) throws PMDException {
166 | 0 | try {
167 | 0 | processFile(new InputStreamReader(fileContents, encoding), ruleSet, ctx);
168 |  | } catch (UnsupportedEncodingException uee) {
169 | 0 | throw new PMDException("Unsupported encoding exception: "
170 |  | + uee.getMessage());
171 |  | }
172 |  | }
173 |  |
174 |  | /**
175 |  | * Processes the input stream agains a rule set using the given input encoding.
176 |  | *
177 |  | * @param fileContents an input stream to analyze
178 |  | * @param encoding input stream's encoding
179 |  | * @param ruleSets set of rules to process against the file
180 |  | * @param ctx context in which PMD is operating. This contains the Report and whatnot
181 |  | * @throws PMDException if the input encoding is unsupported or the input stream could
182 |  | * not be parsed
183 |  | * @see #processFile(Reader, RuleSet, RuleContext)
184 |  | */
185 | 0 | public void processFile(InputStream fileContents, String encoding,
186 |  | RuleSets ruleSets, RuleContext ctx) throws PMDException {
187 | 0 | try {
188 | 0 | processFile(new InputStreamReader(fileContents, encoding), ruleSets, ctx);
189 |  | } catch (UnsupportedEncodingException uee) {
190 | 0 | throw new PMDException("Unsupported encoding exception: "
191 |  | + uee.getMessage());
192 |  | }
193 |  | }
194 |  |
195 |  | /**
196 |  | * Processes the input stream against a rule set assuming the platform character set.
197 |  | *
198 |  | * @param fileContents input stream to check
199 |  | * @param ruleSet the set of rules to process against the source code
200 |  | * @param ctx the context in which PMD is operating. This contains the Report and
201 |  | * whatnot
202 |  | * @throws PMDException if the input encoding is unsupported or the input input stream
203 |  | * could not be parsed
204 |  | * @see #processFile(InputStream, String, RuleSet, RuleContext)
205 |  | */
206 | 0 | public void processFile(InputStream fileContents, RuleSet ruleSet,
207 |  | RuleContext ctx) throws PMDException {
208 | 0 | processFile(fileContents, System.getProperty("file.encoding"), ruleSet, ctx);
209 |  | }
210 |  |
211 | 1 | public void setExcludeMarker(String marker) {
212 | 1 | this.excludeMarker = marker;
213 |  | }
214 |  |
215 |  | /**
216 |  | * Set the SourceType to be used for ".java" files.
217 |  | *
218 |  | * @param javaVersion the SourceType that indicates the java version
219 |  | */
220 | 1256 | public void setJavaVersion(SourceType javaVersion) {
221 | 1256 | sourceTypeDiscoverer.setSourceTypeOfJavaFiles(javaVersion);
222 |  | }
223 |  |
224 | 0 | public static void main(String[] args) {
225 | 0 | CommandLineOptions opts = new CommandLineOptions(args);
226 |  |
227 | 0 | SourceFileSelector fileSelector = new SourceFileSelector();
228 |  |
229 | 0 | fileSelector.setSelectJavaFiles(opts.isCheckJavaFiles());
230 | 0 | fileSelector.setSelectJspFiles(opts.isCheckJspFiles());
231 |  |
232 | 0 | List files;
233 | 0 | if (opts.containsCommaSeparatedFileList()) {
234 | 0 | files = collectFromCommaDelimitedString(opts.getInputPath(),
235 |  | fileSelector);
236 |  | } else {
237 | 0 | files = collectFilesFromOneName(opts.getInputPath(), fileSelector);
238 |  | }
239 |  |
240 | 0 | SourceType sourceType;
241 | 0 | if (opts.getTargetJDK().equals("1.3")) {
242 | 0 | if (opts.debugEnabled())
243 | 0 | System.out.println("In JDK 1.3 mode");
244 | 0 | sourceType = SourceType.JAVA_13;
245 | 0 | } else if (opts.getTargetJDK().equals("1.5")) {
246 | 0 | if (opts.debugEnabled())
247 | 0 | System.out.println("In JDK 1.5 mode");
248 | 0 | sourceType = SourceType.JAVA_15;
249 | 0 | } else if (opts.getTargetJDK().equals("1.6")) {
250 | 0 | if (opts.debugEnabled())
251 | 0 | System.out.println("In JDK 1.6 mode");
252 | 0 | sourceType = SourceType.JAVA_16;
253 |  | } else {
254 | 0 | if (opts.debugEnabled())
255 | 0 | System.out.println("In JDK 1.4 mode");
256 | 0 | sourceType = SourceType.JAVA_14;
257 |  | }
258 |  |
259 | 0 | RuleContext ctx = new RuleContext();
260 | 0 | Report report = new Report();
261 | 0 | ctx.setReport(report);
262 | 0 | report.start();
263 |  |
264 | 0 | try {
265 | 0 | RuleSetFactory ruleSetFactory = new RuleSetFactory();
266 | 0 | ruleSetFactory.setMinimumPriority(opts.getMinPriority());
267 |  |
268 | 0 | RuleSets rulesets = ruleSetFactory.createRuleSets(opts.getRulesets());
269 | 0 | printRuleNamesInDebug(opts.debugEnabled(), rulesets);
270 |  |
271 | 0 | processFiles(opts.getCpus(), ruleSetFactory, sourceType, files, ctx,
272 |  | opts.getRulesets(), opts.debugEnabled(), opts.shortNamesEnabled(),
273 |  | opts.getInputPath(), opts.getEncoding(), opts.getExcludeMarker());
274 |  | } catch (RuleSetNotFoundException rsnfe) {
275 | 0 | System.out.println(opts.usage());
276 | 0 | rsnfe.printStackTrace();
277 |  | }
278 | 0 | report.end();
279 |  |
280 | 0 | Writer w = null;
281 | 0 | try {
282 | 0 | Renderer r = opts.createRenderer();
283 | 0 | if (opts.getReportFile() != null) {
284 | 0 | w = new BufferedWriter(new FileWriter(opts.getReportFile()));
285 |  | } else {
286 | 0 | w = new OutputStreamWriter(System.out);
287 |  | }
288 | 0 | r.render(w, ctx.getReport());
289 | 0 | w.write(EOL);
290 | 0 | w.flush();
291 | 0 | if (opts.getReportFile() != null) {
292 | 0 | w.close();
293 |  | }
294 |  | } catch (Exception e) {
295 | 0 | System.out.println(e.getMessage());
296 | 0 | System.out.println(opts.usage());
297 | 0 | if (opts.debugEnabled()) {
298 | 0 | e.printStackTrace();
299 |  | }
300 |  | } finally {
301 | 0 | if (opts.getReportFile() != null && w != null) {
302 | 0 | try {
303 | 0 | w.close();
304 |  | } catch (Exception e) {
305 | 0 | System.out.println(e.getMessage());
306 |  | }
307 |  | }
308 |  | }
309 |  | }
310 |  |
311 |  | private static class PmdRunnable extends PMD implements Runnable {
312 |  | private final ExecutorService executor;
313 |  | private final DataSource dataSource;
314 |  | private final String fileName;
315 |  | private final boolean debugEnabled;
316 |  | private final String encoding;
317 |  | private final String rulesets;
318 |  |
319 | 0 | public PmdRunnable(ExecutorService executor, DataSource dataSource, String fileName, SourceType sourceType,
320 |  | boolean debugEnabled, String encoding, String rulesets, String excludeMarker) {
321 | 0 | this.executor = executor;
322 | 0 | this.dataSource = dataSource;
323 | 0 | this.fileName = fileName;
324 | 0 | this.debugEnabled = debugEnabled;
325 | 0 | this.encoding = encoding;
326 | 0 | this.rulesets = rulesets;
327 |  |
328 | 0 | setJavaVersion(sourceType);
329 | 0 | setExcludeMarker(excludeMarker);
330 |  | }
331 |  |
332 | 0 | public void run() {
333 | 0 | PmdThread thread = (PmdThread) Thread.currentThread();
334 |  |
335 | 0 | RuleContext ctx = thread.getRuleContext();
336 | 0 | RuleSets rs = thread.getRuleSets(rulesets);
337 |  |
338 | 0 | ctx.setSourceCodeFilename(fileName);
339 | 0 | if (debugEnabled) {
340 | 0 | System.out.println("Processing " + ctx.getSourceCodeFilename());
341 |  | }
342 |  |
343 | 0 | try {
344 | 0 | InputStream stream = new BufferedInputStream(dataSource.getInputStream());
345 | 0 | processFile(stream, encoding, rs, ctx);
346 |  | } catch (PMDException pmde) {
347 | 0 | if (debugEnabled) {
348 | 0 | pmde.getReason().printStackTrace();
349 |  | }
350 | 0 | ctx.getReport().addError(
351 |  | new Report.ProcessingError(pmde.getMessage(),
352 |  | fileName));
353 |  | } catch (Throwable t) {
354 |  | // unexepected exception: log and stop executor service
355 | 0 | if (debugEnabled) {
356 | 0 | t.printStackTrace();
357 |  | }
358 | 0 | ctx.getReport().addError(
359 |  | new Report.ProcessingError(t.getMessage(),
360 |  | fileName));
361 |  |
362 | 0 | executor.shutdownNow();
363 |  | }
364 |  | }
365 |  |
366 |  | }
367 |  |
368 |  | private static class PmdThreadFactory implements ThreadFactory {
369 |  |
370 | 0 | public PmdThreadFactory(RuleSetFactory ruleSetFactory) {
371 | 0 | this.ruleSetFactory = ruleSetFactory;
372 |  | }
373 |  |
374 |  | private final RuleSetFactory ruleSetFactory;
375 |  | private final AtomicInteger counter = new AtomicInteger();
376 |  |
377 | 0 | public Thread newThread(Runnable r) {
378 | 0 | PmdThread t = new PmdThread(counter.incrementAndGet(), r, ruleSetFactory);
379 | 0 | threadList.add(t);
380 | 0 | return t;
381 |  | }
382 |  |
383 |  | public List threadList = Collections.synchronizedList(new LinkedList());
384 |  |
385 |  | }
386 |  |
387 |  | private static class PmdThread extends Thread {
388 |  |
389 | 0 | public PmdThread(int id, Runnable r, RuleSetFactory ruleSetFactory) {
390 | 0 | super(r, "PmdThread " + id);
391 | 0 | this.id = id;
392 | 0 | context = new RuleContext();
393 | 0 | context.setReport(new Report());
394 | 0 | this.ruleSetFactory = ruleSetFactory;
395 |  | }
396 |  |
397 |  | private int id;
398 |  | private RuleContext context;
399 |  | private RuleSets rulesets;
400 |  | private RuleSetFactory ruleSetFactory;
401 |  |
402 | 0 | public RuleContext getRuleContext() {
403 | 0 | return context;
404 |  | }
405 |  |
406 | 0 | public RuleSets getRuleSets(String rsList) {
407 | 0 | if (rulesets == null) {
408 | 0 | try {
409 | 0 | rulesets = ruleSetFactory.createRuleSets(rsList);
410 |  | } catch (Exception e) {
411 | 0 | e.printStackTrace();
412 |  | }
413 |  | }
414 | 0 | return rulesets;
415 |  | }
416 |  |
417 | 0 | public String toString() {
418 | 0 | return "PmdThread " + id;
419 |  | }
420 |  |
421 |  | }
422 |  |
423 |  | /**
424 |  | * Run PMD on a list of files using multiple threads.
425 |  | *
426 |  | * @throws IOException If one of the files could not be read
427 |  | */
428 | 0 | public static void processFiles(int threadCount, RuleSetFactory ruleSetFactory, SourceType sourceType, List files, RuleContext ctx, String rulesets,
429 |  | boolean debugEnabled, boolean shortNamesEnabled, String inputPath,
430 |  | String encoding, String excludeMarker) {
431 |  |
432 | 0 | PmdThreadFactory factory = new PmdThreadFactory(ruleSetFactory);
433 | 0 | ExecutorService executor = Executors.newFixedThreadPool(threadCount, factory);
434 |  |
435 | 0 | for (Iterator i = files.iterator(); i.hasNext();) {
436 | 0 | DataSource dataSource = (DataSource) i.next();
437 | 0 | String niceFileName = dataSource.getNiceFileName(shortNamesEnabled,
438 |  | inputPath);
439 |  |
440 | 0 | Runnable r = new PmdRunnable(executor, dataSource, niceFileName, sourceType, debugEnabled,
441 |  | encoding, rulesets, excludeMarker);
442 |  |
443 | 0 | executor.execute(r);
444 |  | }
445 | 0 | executor.shutdown();
446 |  |
447 | 0 | try {
448 | 0 | executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
449 |  | } catch (InterruptedException e) {
450 |  | }
451 |  |
452 | 0 | Report mainReport = ctx.getReport();
453 | 0 | Iterator i = factory.threadList.iterator();
454 | 0 | while (i.hasNext()) {
455 | 0 | PmdThread thread = (PmdThread) i.next();
456 | 0 | Report r = thread.context.getReport();
457 | 0 | mainReport.merge(r);
458 |  | }
459 |  | }
460 |  |
461 |  | /**
462 |  | * Run PMD on a list of files.
463 |  | *
464 |  | * @param files the List of DataSource instances.
465 |  | * @param ctx the context in which PMD is operating. This contains the Report and
466 |  | * whatnot
467 |  | * @param rulesets the RuleSets
468 |  | * @param debugEnabled
469 |  | * @param shortNamesEnabled
470 |  | * @param inputPath
471 |  | * @param encoding
472 |  | * @throws IOException If one of the files could not be read
473 |  | */
474 | 0 | public void processFiles(List files, RuleContext ctx, RuleSets rulesets,
475 |  | boolean debugEnabled, boolean shortNamesEnabled, String inputPath,
476 |  | String encoding) throws IOException {
477 | 0 | for (Iterator i = files.iterator(); i.hasNext();) {
478 | 0 | DataSource dataSource = (DataSource) i.next();
479 |  |
480 | 0 | String niceFileName = dataSource.getNiceFileName(shortNamesEnabled,
481 |  | inputPath);
482 | 0 | ctx.setSourceCodeFilename(niceFileName);
483 | 0 | if (debugEnabled) {
484 | 0 | System.out.println("Processing " + ctx.getSourceCodeFilename());
485 |  | }
486 |  |
487 | 0 | try {
488 | 0 | InputStream stream = new BufferedInputStream(dataSource
489 |  | .getInputStream());
490 | 0 | processFile(stream, encoding, rulesets, ctx);
491 |  | } catch (PMDException pmde) {
492 | 0 | if (debugEnabled) {
493 | 0 | pmde.getReason().printStackTrace();
494 |  | }
495 | 0 | ctx.getReport().addError(new Report.ProcessingError(pmde.getMessage(), niceFileName));
496 |  | }
497 |  | }
498 |  | }
499 |  |
500 |  | /**
501 |  | * If in debug modus, print the names of the rules.
502 |  | *
503 |  | * @param debugEnabled the boolean indicating if debug is enabled
504 |  | * @param rulesets the RuleSets to print
505 |  | */
506 | 0 | private static void printRuleNamesInDebug(boolean debugEnabled, RuleSets rulesets) {
507 | 0 | if (debugEnabled) {
508 | 0 | for (Iterator i = rulesets.getAllRules().iterator(); i.hasNext();) {
509 | 0 | Rule r = (Rule) i.next();
510 | 0 | System.out.println("Loaded rule " + r.getName());
511 |  | }
512 |  | }
513 |  | }
514 |  |
515 |  | /**
516 |  | * Collects the given file into a list.
517 |  | *
518 |  | * @param inputFileName a file name
519 |  | * @param fileSelector Filtering of wanted source files
520 |  | * @return the list of files collected from the <code>inputFileName</code>
521 |  | * @see #collect(String, SourceFileSelector)
522 |  | */
523 | 0 | private static List collectFilesFromOneName(String inputFileName,
524 |  | SourceFileSelector fileSelector) {
525 | 0 | return collect(inputFileName, fileSelector);
526 |  | }
527 |  |
528 |  | /**
529 |  | * Collects the files from the given comma-separated list.
530 |  | *
531 |  | * @param fileList comma-separated list of filenames
532 |  | * @param fileSelector Filtering of wanted source files
533 |  | * @return list of files collected from the <code>fileList</code>
534 |  | */
535 | 0 | private static List collectFromCommaDelimitedString(String fileList,
536 |  | SourceFileSelector fileSelector) {
537 | 0 | List files = new ArrayList();
538 | 0 | for (StringTokenizer st = new StringTokenizer(fileList, ","); st
539 |  | .hasMoreTokens();) {
540 | 0 | files.addAll(collect(st.nextToken(), fileSelector));
541 |  | }
542 | 0 | return files;
543 |  | }
544 |  |
545 |  | /**
546 |  | * Collects the files from the given <code>filename</code>.
547 |  | *
548 |  | * @param filename the source from which to collect files
549 |  | * @param fileSelector Filtering of wanted source files
550 |  | * @return a list of files found at the given <code>filename</code>
551 |  | * @throws RuntimeException if <code>filename</code> is not found
552 |  | */
553 | 0 | private static List collect(String filename, SourceFileSelector fileSelector) {
554 | 0 | File inputFile = new File(filename);
555 | 0 | if (!inputFile.exists()) {
556 | 0 | throw new RuntimeException("File " + inputFile.getName()
557 |  | + " doesn't exist");
558 |  | }
559 | 0 | List dataSources = new ArrayList();
560 | 0 | if (!inputFile.isDirectory()) {
561 | 0 | if (filename.endsWith(".zip") || filename.endsWith(".jar")) {
562 | 0 | ZipFile zipFile;
563 | 0 | try {
564 | 0 | zipFile = new ZipFile(inputFile);
565 | 0 | Enumeration e = zipFile.entries();
566 | 0 | while (e.hasMoreElements()) {
567 | 0 | ZipEntry zipEntry = (ZipEntry) e.nextElement();
568 | 0 | if (fileSelector.isWantedFile(zipEntry.getName())) {
569 | 0 | dataSources.add(new ZipDataSource(zipFile, zipEntry));
570 |  | }
571 |  | }
572 |  | } catch (IOException ze) {
573 | 0 | throw new RuntimeException("Zip file " + inputFile.getName()
574 |  | + " can't be opened");
575 |  | }
576 |  | } else {
577 | 0 | dataSources.add(new FileDataSource(inputFile));
578 |  | }
579 |  | } else {
580 | 0 | FileFinder finder = new FileFinder();
581 | 0 | List files = finder.findFilesFrom(inputFile.getAbsolutePath(),
582 |  | new SourceFileOrDirectoryFilter(fileSelector), true);
583 | 0 | for (Iterator i = files.iterator(); i.hasNext();) {
584 | 0 | dataSources.add(new FileDataSource((File) i.next()));
585 |  | }
586 |  | }
587 | 0 | return dataSources;
588 |  | }
589 |  |
590 |  | }
591 |  |
592 |  |