Source Code Cross Referenced for PMD.java in  » Code-Analyzer » pmd-4.2rc1 » net » sourceforge » pmd » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Code Analyzer » pmd 4.2rc1 » net.sourceforge.pmd 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
003:         */package net.sourceforge.pmd;
004:
005:        import java.io.BufferedInputStream;
006:        import java.io.BufferedWriter;
007:        import java.io.File;
008:        import java.io.FileWriter;
009:        import java.io.IOException;
010:        import java.io.InputStream;
011:        import java.io.InputStreamReader;
012:        import java.io.OutputStreamWriter;
013:        import java.io.Reader;
014:        import java.io.UnsupportedEncodingException;
015:        import java.io.Writer;
016:        import java.util.ArrayList;
017:        import java.util.Collections;
018:        import java.util.Comparator;
019:        import java.util.Enumeration;
020:        import java.util.LinkedList;
021:        import java.util.List;
022:        import java.util.StringTokenizer;
023:        import java.util.concurrent.Callable;
024:        import java.util.concurrent.ExecutionException;
025:        import java.util.concurrent.ExecutorService;
026:        import java.util.concurrent.Executors;
027:        import java.util.concurrent.Future;
028:        import java.util.concurrent.ThreadFactory;
029:        import java.util.concurrent.atomic.AtomicInteger;
030:        import java.util.logging.Handler;
031:        import java.util.logging.Level;
032:        import java.util.logging.Logger;
033:        import java.util.zip.ZipEntry;
034:        import java.util.zip.ZipFile;
035:
036:        import net.sourceforge.pmd.ast.CompilationUnit;
037:        import net.sourceforge.pmd.ast.ParseException;
038:        import net.sourceforge.pmd.cpd.SourceFileOrDirectoryFilter;
039:        import net.sourceforge.pmd.parsers.Parser;
040:        import net.sourceforge.pmd.renderers.Renderer;
041:        import net.sourceforge.pmd.sourcetypehandlers.SourceTypeHandler;
042:        import net.sourceforge.pmd.sourcetypehandlers.SourceTypeHandlerBroker;
043:        import net.sourceforge.pmd.util.Benchmark;
044:        import net.sourceforge.pmd.util.ConsoleLogHandler;
045:        import net.sourceforge.pmd.util.FileFinder;
046:
047:        public class PMD {
048:            public static final String EOL = System.getProperty(
049:                    "line.separator", "\n");
050:            public static final String VERSION = "4.2rc1";
051:            public static final String EXCLUDE_MARKER = "NOPMD";
052:
053:            private static final Logger LOG = Logger.getLogger(PMD.class
054:                    .getName());
055:
056:            private String excludeMarker = EXCLUDE_MARKER;
057:            private SourceTypeDiscoverer sourceTypeDiscoverer = new SourceTypeDiscoverer();
058:            private ClassLoader classLoader = getClass().getClassLoader();
059:
060:            public PMD() {
061:            }
062:
063:            /**
064:             * Processes the file read by the reader against the rule set.
065:             *
066:             * @param reader   input stream reader
067:             * @param ruleSets set of rules to process against the file
068:             * @param ctx      context in which PMD is operating. This contains the Renderer and
069:             *                 whatnot
070:             * @throws PMDException if the input could not be parsed or processed
071:             */
072:            public void processFile(Reader reader, RuleSets ruleSets,
073:                    RuleContext ctx) throws PMDException {
074:                SourceType sourceType = getSourceTypeOfFile(ctx
075:                        .getSourceCodeFilename());
076:
077:                processFile(reader, ruleSets, ctx, sourceType);
078:            }
079:
080:            /**
081:             * Processes the file read by the reader against the rule set.
082:             *
083:             * @param reader     input stream reader
084:             * @param ruleSets   set of rules to process against the file
085:             * @param ctx        context in which PMD is operating. This contains the Renderer and
086:             *                   whatnot
087:             * @param sourceType the SourceType of the source
088:             * @throws PMDException if the input could not be parsed or processed
089:             */
090:            public void processFile(Reader reader, RuleSets ruleSets,
091:                    RuleContext ctx, SourceType sourceType) throws PMDException {
092:                try {
093:                    if (ruleSets.applies(ctx.getSourceCodeFile())) {
094:                        SourceTypeHandler sourceTypeHandler = SourceTypeHandlerBroker
095:                                .getVisitorsFactoryForSourceType(sourceType);
096:                        ctx.setSourceType(sourceType);
097:                        Parser parser = sourceTypeHandler.getParser();
098:                        parser.setExcludeMarker(excludeMarker);
099:                        long start = System.nanoTime();
100:                        CompilationUnit rootNode = (CompilationUnit) parser
101:                                .parse(reader);
102:                        ctx.excludeLines(parser.getExcludeMap());
103:                        long end = System.nanoTime();
104:                        Benchmark.mark(Benchmark.TYPE_PARSER, end - start, 0);
105:                        start = System.nanoTime();
106:                        sourceTypeHandler.getSymbolFacade().start(rootNode);
107:                        end = System.nanoTime();
108:                        Benchmark.mark(Benchmark.TYPE_SYMBOL_TABLE,
109:                                end - start, 0);
110:
111:                        Language language = SourceTypeToRuleLanguageMapper
112:                                .getMappedLanguage(sourceType);
113:
114:                        if (ruleSets.usesDFA(language)) {
115:                            start = System.nanoTime();
116:                            sourceTypeHandler.getDataFlowFacade().start(
117:                                    rootNode);
118:                            end = System.nanoTime();
119:                            Benchmark.mark(Benchmark.TYPE_DFA, end - start, 0);
120:                        }
121:
122:                        if (ruleSets.usesTypeResolution(language)) {
123:                            start = System.nanoTime();
124:                            sourceTypeHandler.getTypeResolutionFacade(
125:                                    classLoader).start(rootNode);
126:                            end = System.nanoTime();
127:                            Benchmark.mark(Benchmark.TYPE_TYPE_RESOLUTION, end
128:                                    - start, 0);
129:                        }
130:
131:                        List<CompilationUnit> acus = new ArrayList<CompilationUnit>();
132:                        acus.add(rootNode);
133:
134:                        ruleSets.apply(acus, ctx, language);
135:                    }
136:                } catch (ParseException pe) {
137:                    throw new PMDException("Error while parsing "
138:                            + ctx.getSourceCodeFilename(), pe);
139:                } catch (Exception e) {
140:                    throw new PMDException("Error while processing "
141:                            + ctx.getSourceCodeFilename(), e);
142:                } finally {
143:                    try {
144:                        reader.close();
145:                    } catch (IOException e) {
146:                    }
147:                }
148:            }
149:
150:            /**
151:             * Get the SourceType of the source file with given name. This depends on the fileName
152:             * extension, and the java version.
153:             * <p/>
154:             * For compatibility with older code that does not always pass in a correct filename,
155:             * unrecognized files are assumed to be java files.
156:             *
157:             * @param fileName Name of the file, can be absolute, or simple.
158:             * @return the SourceType
159:             */
160:            private SourceType getSourceTypeOfFile(String fileName) {
161:                SourceType sourceType = sourceTypeDiscoverer
162:                        .getSourceTypeOfFile(fileName);
163:                if (sourceType == null) {
164:                    // For compatibility with older code that does not always pass in
165:                    // a correct filename.
166:                    sourceType = sourceTypeDiscoverer
167:                            .getSourceTypeOfJavaFiles();
168:                }
169:                return sourceType;
170:            }
171:
172:            /**
173:             * Processes the file read by the reader against the rule set.
174:             *
175:             * @param reader  input stream reader
176:             * @param ruleSet set of rules to process against the file
177:             * @param ctx     context in which PMD is operating. This contains the Renderer and
178:             *                whatnot
179:             * @throws PMDException if the input could not be parsed or processed
180:             */
181:            public void processFile(Reader reader, RuleSet ruleSet,
182:                    RuleContext ctx) throws PMDException {
183:                processFile(reader, new RuleSets(ruleSet), ctx);
184:            }
185:
186:            /**
187:             * Processes the input stream against a rule set using the given input encoding.
188:             *
189:             * @param fileContents an input stream to analyze
190:             * @param encoding     input stream's encoding
191:             * @param ruleSet      set of rules to process against the file
192:             * @param ctx          context in which PMD is operating. This contains the Report and whatnot
193:             * @throws PMDException if the input encoding is unsupported or the input stream could
194:             *                      not be parsed
195:             * @see #processFile(Reader, RuleSet, RuleContext)
196:             */
197:            public void processFile(InputStream fileContents, String encoding,
198:                    RuleSet ruleSet, RuleContext ctx) throws PMDException {
199:                try {
200:                    processFile(new InputStreamReader(fileContents, encoding),
201:                            ruleSet, ctx);
202:                } catch (UnsupportedEncodingException uee) {
203:                    throw new PMDException("Unsupported encoding exception: "
204:                            + uee.getMessage());
205:                }
206:            }
207:
208:            /**
209:             * Processes the input stream against a rule set using the given input encoding.
210:             *
211:             * @param fileContents an input stream to analyze
212:             * @param encoding     input stream's encoding
213:             * @param ruleSets     set of rules to process against the file
214:             * @param ctx          context in which PMD is operating. This contains the Report and whatnot
215:             * @throws PMDException if the input encoding is unsupported or the input stream could
216:             *                      not be parsed
217:             * @see #processFile(Reader, RuleSet, RuleContext)
218:             */
219:            public void processFile(InputStream fileContents, String encoding,
220:                    RuleSets ruleSets, RuleContext ctx) throws PMDException {
221:                try {
222:                    processFile(new InputStreamReader(fileContents, encoding),
223:                            ruleSets, ctx);
224:                } catch (UnsupportedEncodingException uee) {
225:                    throw new PMDException("Unsupported encoding exception: "
226:                            + uee.getMessage());
227:                }
228:            }
229:
230:            /**
231:             * Processes the input stream against a rule set assuming the platform character set.
232:             *
233:             * @param fileContents input stream to check
234:             * @param ruleSet      the set of rules to process against the source code
235:             * @param ctx          the context in which PMD is operating. This contains the Report and
236:             *                     whatnot
237:             * @throws PMDException if the input encoding is unsupported or the input input stream
238:             *                      could not be parsed
239:             * @see #processFile(InputStream, String, RuleSet, RuleContext)
240:             */
241:            public void processFile(InputStream fileContents, RuleSet ruleSet,
242:                    RuleContext ctx) throws PMDException {
243:                processFile(fileContents, System.getProperty("file.encoding"),
244:                        ruleSet, ctx);
245:            }
246:
247:            public void setExcludeMarker(String marker) {
248:                this .excludeMarker = marker;
249:            }
250:
251:            /**
252:             * Set the SourceType to be used for ".java" files.
253:             *
254:             * @param javaVersion the SourceType that indicates the java version
255:             */
256:            public void setJavaVersion(SourceType javaVersion) {
257:                sourceTypeDiscoverer.setSourceTypeOfJavaFiles(javaVersion);
258:            }
259:
260:            /**
261:             * Get the ClassLoader being used by PMD when processing Rules.
262:             * @return The ClassLoader being used
263:             */
264:            public ClassLoader getClassLoader() {
265:                return classLoader;
266:            }
267:
268:            /**
269:             * Set the ClassLoader being used by PMD when processing Rules.
270:             * Setting a value of <code>null</code> will cause the default
271:             * ClassLoader to be used.
272:             * @param classLoader The ClassLoader to use
273:             */
274:            public void setClassLoader(ClassLoader classLoader) {
275:                if (classLoader == null) {
276:                    classLoader = getClass().getClassLoader();
277:                }
278:                this .classLoader = classLoader;
279:            }
280:
281:            private static void doPMD(CommandLineOptions opts) {
282:                long startFiles = System.nanoTime();
283:                SourceFileSelector fileSelector = new SourceFileSelector();
284:
285:                fileSelector.setSelectJavaFiles(opts.isCheckJavaFiles());
286:                fileSelector.setSelectJspFiles(opts.isCheckJspFiles());
287:
288:                List<DataSource> files;
289:                if (opts.containsCommaSeparatedFileList()) {
290:                    files = collectFromCommaDelimitedString(
291:                            opts.getInputPath(), fileSelector);
292:                } else {
293:                    files = collectFilesFromOneName(opts.getInputPath(),
294:                            fileSelector);
295:                }
296:                long endFiles = System.nanoTime();
297:                Benchmark.mark(Benchmark.TYPE_COLLECT_FILES, endFiles
298:                        - startFiles, 0);
299:
300:                SourceType sourceType;
301:                if (opts.getTargetJDK().equals("1.3")) {
302:                    LOG.fine("In JDK 1.3 mode");
303:                    sourceType = SourceType.JAVA_13;
304:                } else if (opts.getTargetJDK().equals("1.5")) {
305:                    LOG.fine("In JDK 1.5 mode");
306:                    sourceType = SourceType.JAVA_15;
307:                } else if (opts.getTargetJDK().equals("1.6")) {
308:                    LOG.fine("In JDK 1.6 mode");
309:                    sourceType = SourceType.JAVA_16;
310:                } else if (opts.getTargetJDK().equals("1.7")) {
311:                    LOG.fine("In JDK 1.7 mode");
312:                    sourceType = SourceType.JAVA_17;
313:                } else {
314:                    LOG.fine("In JDK 1.4 mode");
315:                    sourceType = SourceType.JAVA_14;
316:                }
317:
318:                long reportStart, reportEnd;
319:                Renderer renderer;
320:                Writer w = null;
321:
322:                reportStart = System.nanoTime();
323:                try {
324:                    renderer = opts.createRenderer();
325:                    List<Renderer> renderers = new LinkedList<Renderer>();
326:                    renderers.add(renderer);
327:                    if (opts.getReportFile() != null) {
328:                        w = new BufferedWriter(new FileWriter(opts
329:                                .getReportFile()));
330:                    } else {
331:                        w = new OutputStreamWriter(System.out);
332:                    }
333:                    renderer.setWriter(w);
334:                    renderer.start();
335:
336:                    reportEnd = System.nanoTime();
337:                    Benchmark.mark(Benchmark.TYPE_REPORTING, reportEnd
338:                            - reportStart, 0);
339:
340:                    RuleContext ctx = new RuleContext();
341:
342:                    try {
343:                        long startLoadRules = System.nanoTime();
344:                        RuleSetFactory ruleSetFactory = new RuleSetFactory();
345:                        ruleSetFactory
346:                                .setMinimumPriority(opts.getMinPriority());
347:
348:                        RuleSets rulesets = ruleSetFactory.createRuleSets(opts
349:                                .getRulesets());
350:                        printRuleNamesInDebug(rulesets);
351:                        long endLoadRules = System.nanoTime();
352:                        Benchmark.mark(Benchmark.TYPE_LOAD_RULES, endLoadRules
353:                                - startLoadRules, 0);
354:
355:                        processFiles(opts.getCpus(), ruleSetFactory,
356:                                sourceType, files, ctx, renderers, opts
357:                                        .stressTestEnabled(), opts
358:                                        .getRulesets(), opts
359:                                        .shortNamesEnabled(), opts
360:                                        .getInputPath(), opts.getEncoding(),
361:                                opts.getExcludeMarker(), PMD.class
362:                                        .getClassLoader());
363:                    } catch (RuleSetNotFoundException rsnfe) {
364:                        LOG.log(Level.SEVERE, "Ruleset not found", rsnfe);
365:                        System.out.println(opts.usage());
366:                    }
367:
368:                    reportStart = System.nanoTime();
369:                    renderer.end();
370:                    w.write(EOL);
371:                    w.flush();
372:                    if (opts.getReportFile() != null) {
373:                        w.close();
374:                        w = null;
375:                    }
376:                } catch (Exception e) {
377:                    String message = e.getMessage();
378:                    if (message != null) {
379:                        LOG.severe(message);
380:                    } else {
381:                        LOG.log(Level.SEVERE, "Exception during processing", e);
382:                    }
383:
384:                    LOG.log(Level.FINE, "Exception during processing", e); //Only displayed when debug logging is on
385:
386:                    LOG.info(opts.usage());
387:                } finally {
388:                    if (opts.getReportFile() != null && w != null) {
389:                        try {
390:                            w.close();
391:                        } catch (Exception e) {
392:                            System.out.println(e.getMessage());
393:                        }
394:                    }
395:                    reportEnd = System.nanoTime();
396:                    Benchmark.mark(Benchmark.TYPE_REPORTING, reportEnd
397:                            - reportStart, 0);
398:                }
399:            }
400:
401:            public static void main(String[] args) {
402:                long start = System.nanoTime();
403:                final CommandLineOptions opts = new CommandLineOptions(args);
404:
405:                final Level logLevel = opts.debugEnabled() ? Level.FINER
406:                        : Level.INFO;
407:                final Handler logHandler = new ConsoleLogHandler();
408:                final ScopedLogHandlersManager logHandlerManager = new ScopedLogHandlersManager(
409:                        logLevel, logHandler);
410:                final Level oldLogLevel = LOG.getLevel();
411:                LOG.setLevel(logLevel); //Need to do this, since the static logger has already been initialized at this point
412:                try {
413:                    doPMD(opts);
414:                } finally {
415:                    logHandlerManager.close();
416:                    LOG.setLevel(oldLogLevel);
417:                    if (opts.benchmark()) {
418:                        long end = System.nanoTime();
419:                        Benchmark
420:                                .mark(Benchmark.TYPE_TOTAL_PMD, end - start, 0);
421:                        System.err.println(Benchmark.report());
422:                    }
423:                }
424:            }
425:
426:            private static class PmdRunnable extends PMD implements 
427:                    Callable<Report> {
428:                private final ExecutorService executor;
429:                private final DataSource dataSource;
430:                private final String fileName;
431:                private final String encoding;
432:                private final String rulesets;
433:                private final List<Renderer> renderers;
434:
435:                public PmdRunnable(ExecutorService executor,
436:                        DataSource dataSource, String fileName,
437:                        SourceType sourceType, List<Renderer> renderers,
438:                        String encoding, String rulesets, String excludeMarker,
439:                        ClassLoader classLoader) {
440:                    this .executor = executor;
441:                    this .dataSource = dataSource;
442:                    this .fileName = fileName;
443:                    this .encoding = encoding;
444:                    this .rulesets = rulesets;
445:                    this .renderers = renderers;
446:
447:                    setJavaVersion(sourceType);
448:                    setExcludeMarker(excludeMarker);
449:                    setClassLoader(classLoader);
450:                }
451:
452:                public Report call() {
453:                    PmdThread thread = (PmdThread) Thread.currentThread();
454:
455:                    RuleContext ctx = thread.getRuleContext();
456:                    RuleSets rs = thread.getRuleSets(rulesets);
457:
458:                    Report report = new Report();
459:                    ctx.setReport(report);
460:
461:                    ctx.setSourceCodeFilename(fileName);
462:                    if (LOG.isLoggable(Level.FINE)) {
463:                        LOG.fine("Processing " + ctx.getSourceCodeFilename());
464:                    }
465:                    for (Renderer r : renderers) {
466:                        r.startFileAnalysis(dataSource);
467:                    }
468:
469:                    try {
470:                        InputStream stream = new BufferedInputStream(dataSource
471:                                .getInputStream());
472:                        processFile(stream, encoding, rs, ctx);
473:                    } catch (PMDException pmde) {
474:                        LOG.log(Level.FINE, "Error while processing file", pmde
475:                                .getCause());
476:
477:                        report.addError(new Report.ProcessingError(pmde
478:                                .getMessage(), fileName));
479:                    } catch (IOException ioe) {
480:                        // unexpected exception: log and stop executor service
481:                        LOG.log(Level.FINE, "IOException during processing",
482:                                ioe);
483:
484:                        report.addError(new Report.ProcessingError(ioe
485:                                .getMessage(), fileName));
486:
487:                        executor.shutdownNow();
488:                    } catch (RuntimeException re) {
489:                        // unexpected exception: log and stop executor service
490:                        LOG.log(Level.FINE,
491:                                "RuntimeException during processing", re);
492:
493:                        report.addError(new Report.ProcessingError(re
494:                                .getMessage(), fileName));
495:
496:                        executor.shutdownNow();
497:                    }
498:                    return report;
499:                }
500:
501:            }
502:
503:            private static class PmdThreadFactory implements  ThreadFactory {
504:
505:                private final RuleSetFactory ruleSetFactory;
506:                private final RuleContext ctx;
507:                private final AtomicInteger counter = new AtomicInteger();
508:
509:                public PmdThreadFactory(RuleSetFactory ruleSetFactory,
510:                        RuleContext ctx) {
511:                    this .ruleSetFactory = ruleSetFactory;
512:                    this .ctx = ctx;
513:                }
514:
515:                public Thread newThread(Runnable r) {
516:                    PmdThread t = new PmdThread(counter.incrementAndGet(), r,
517:                            ruleSetFactory, ctx);
518:                    threadList.add(t);
519:                    return t;
520:                }
521:
522:                public List<PmdThread> threadList = Collections
523:                        .synchronizedList(new LinkedList<PmdThread>());
524:
525:            }
526:
527:            private static class PmdThread extends Thread {
528:
529:                public PmdThread(int id, Runnable r,
530:                        RuleSetFactory ruleSetFactory, RuleContext ctx) {
531:                    super (r, "PmdThread " + id);
532:                    this .id = id;
533:                    context = new RuleContext(ctx);
534:                    this .ruleSetFactory = ruleSetFactory;
535:                }
536:
537:                private int id;
538:                private RuleContext context;
539:                private RuleSets rulesets;
540:                private RuleSetFactory ruleSetFactory;
541:
542:                public RuleContext getRuleContext() {
543:                    return context;
544:                }
545:
546:                public RuleSets getRuleSets(String rsList) {
547:                    if (rulesets == null) {
548:                        try {
549:                            rulesets = ruleSetFactory.createRuleSets(rsList);
550:                        } catch (Exception e) {
551:                            e.printStackTrace();
552:                        }
553:                    }
554:                    return rulesets;
555:                }
556:
557:                public String toString() {
558:                    return "PmdThread " + id;
559:                }
560:
561:            }
562:
563:            /**
564:             * Do we have proper permissions to use multithreading?
565:             */
566:            private static final boolean mtSupported;
567:
568:            static {
569:                boolean error = false;
570:                try {
571:                    /*
572:                     * ant task ran from Eclipse with jdk 1.5.0 raises an AccessControlException
573:                     * when shutdown is called. Standalone pmd or ant from command line are fine.
574:                     * 
575:                     * With jdk 1.6.0, ant task from Eclipse also works.
576:                     */
577:                    ExecutorService executor = Executors.newFixedThreadPool(1);
578:                    executor.shutdown();
579:                } catch (RuntimeException e) {
580:                    error = true;
581:                }
582:                mtSupported = !error;
583:            }
584:
585:            /**
586:             * Run PMD on a list of files using multiple threads.
587:             *
588:             * @throws IOException If one of the files could not be read
589:             */
590:            public static void processFiles(int threadCount,
591:                    RuleSetFactory ruleSetFactory, SourceType sourceType,
592:                    List<DataSource> files, RuleContext ctx,
593:                    List<Renderer> renderers, String rulesets,
594:                    final boolean shortNamesEnabled, final String inputPath,
595:                    String encoding, String excludeMarker,
596:                    ClassLoader classLoader) {
597:                processFiles(threadCount, ruleSetFactory, sourceType, files,
598:                        ctx, renderers, false, rulesets, shortNamesEnabled,
599:                        inputPath, encoding, excludeMarker, classLoader);
600:            }
601:
602:            /**
603:             * Run PMD on a list of files using multiple threads.
604:             *
605:             * @throws IOException If one of the files could not be read
606:             */
607:            public static void processFiles(int threadCount,
608:                    RuleSetFactory ruleSetFactory, SourceType sourceType,
609:                    List<DataSource> files, RuleContext ctx,
610:                    List<Renderer> renderers, boolean stressTestEnabled,
611:                    String rulesets, final boolean shortNamesEnabled,
612:                    final String inputPath, String encoding,
613:                    String excludeMarker, ClassLoader classLoader) {
614:
615:                /*
616:                 * Check if multithreaded is supported. 
617:                 * ExecutorService can also be disabled if threadCount is not positive, e.g. using the
618:                 * "-cpus 0" command line option.
619:                 */
620:                boolean useMT = mtSupported && (threadCount > 0);
621:
622:                if (stressTestEnabled) {
623:                    // randomize processing order
624:                    Collections.shuffle(files);
625:                } else {
626:                    Collections.sort(files, new Comparator<DataSource>() {
627:                        public int compare(DataSource d1, DataSource d2) {
628:                            String s1 = d1.getNiceFileName(shortNamesEnabled,
629:                                    inputPath);
630:                            String s2 = d2.getNiceFileName(shortNamesEnabled,
631:                                    inputPath);
632:                            return s1.compareTo(s2);
633:                        }
634:                    });
635:                }
636:
637:                if (useMT) {
638:                    RuleSets rs = null;
639:                    try {
640:                        rs = ruleSetFactory.createRuleSets(rulesets);
641:                    } catch (RuleSetNotFoundException rsnfe) {
642:                        // should not happen: parent already created a ruleset
643:                    }
644:                    rs.start(ctx);
645:
646:                    PmdThreadFactory factory = new PmdThreadFactory(
647:                            ruleSetFactory, ctx);
648:                    ExecutorService executor = Executors.newFixedThreadPool(
649:                            threadCount, factory);
650:                    List<Future<Report>> tasks = new LinkedList<Future<Report>>();
651:
652:                    for (DataSource dataSource : files) {
653:                        String niceFileName = dataSource.getNiceFileName(
654:                                shortNamesEnabled, inputPath);
655:
656:                        PmdRunnable r = new PmdRunnable(executor, dataSource,
657:                                niceFileName, sourceType, renderers, encoding,
658:                                rulesets, excludeMarker, classLoader);
659:
660:                        Future<Report> future = executor.submit(r);
661:                        tasks.add(future);
662:                    }
663:                    executor.shutdown();
664:
665:                    while (!tasks.isEmpty()) {
666:                        Future<Report> future = tasks.remove(0);
667:                        Report report = null;
668:                        try {
669:                            report = future.get();
670:                        } catch (InterruptedException ie) {
671:                            Thread.currentThread().interrupt();
672:                            future.cancel(true);
673:                        } catch (ExecutionException ee) {
674:                            Throwable t = ee.getCause();
675:                            if (t instanceof  RuntimeException) {
676:                                throw (RuntimeException) t;
677:                            } else if (t instanceof  Error) {
678:                                throw (Error) t;
679:                            } else {
680:                                throw new IllegalStateException(
681:                                        "PmdRunnable exception", t);
682:                            }
683:                        }
684:
685:                        try {
686:                            long start = System.nanoTime();
687:                            for (Renderer r : renderers) {
688:                                r.renderFileReport(report);
689:                            }
690:                            long end = System.nanoTime();
691:                            Benchmark.mark(Benchmark.TYPE_REPORTING, end
692:                                    - start, 1);
693:                        } catch (IOException ioe) {
694:                        }
695:                    }
696:
697:                    try {
698:                        rs.end(ctx);
699:                        long start = System.nanoTime();
700:                        for (Renderer r : renderers) {
701:                            r.renderFileReport(ctx.getReport());
702:                        }
703:                        long end = System.nanoTime();
704:                        Benchmark
705:                                .mark(Benchmark.TYPE_REPORTING, end - start, 1);
706:                    } catch (IOException ioe) {
707:                    }
708:
709:                } else {
710:                    // single threaded execution
711:
712:                    PMD pmd = new PMD();
713:                    pmd.setJavaVersion(sourceType);
714:                    pmd.setExcludeMarker(excludeMarker);
715:
716:                    RuleSets rs = null;
717:                    try {
718:                        rs = ruleSetFactory.createRuleSets(rulesets);
719:                    } catch (RuleSetNotFoundException rsnfe) {
720:                        // should not happen: parent already created a ruleset
721:                    }
722:                    for (DataSource dataSource : files) {
723:                        String niceFileName = dataSource.getNiceFileName(
724:                                shortNamesEnabled, inputPath);
725:
726:                        Report report = new Report();
727:                        ctx.setReport(report);
728:
729:                        ctx.setSourceCodeFilename(niceFileName);
730:                        if (LOG.isLoggable(Level.FINE)) {
731:                            LOG.fine("Processing "
732:                                    + ctx.getSourceCodeFilename());
733:                        }
734:                        rs.start(ctx);
735:
736:                        for (Renderer r : renderers) {
737:                            r.startFileAnalysis(dataSource);
738:                        }
739:
740:                        try {
741:                            InputStream stream = new BufferedInputStream(
742:                                    dataSource.getInputStream());
743:                            pmd.processFile(stream, encoding, rs, ctx);
744:                        } catch (PMDException pmde) {
745:                            LOG.log(Level.FINE, "Error while processing file",
746:                                    pmde.getCause());
747:
748:                            report.addError(new Report.ProcessingError(pmde
749:                                    .getMessage(), niceFileName));
750:                        } catch (IOException ioe) {
751:                            // unexpected exception: log and stop executor service
752:                            LOG.log(Level.FINE, "Unable to read source file",
753:                                    ioe);
754:
755:                            report.addError(new Report.ProcessingError(ioe
756:                                    .getMessage(), niceFileName));
757:                        } catch (RuntimeException re) {
758:                            // unexpected exception: log and stop executor service
759:                            LOG.log(Level.FINE,
760:                                    "RuntimeException while processing file",
761:                                    re);
762:
763:                            report.addError(new Report.ProcessingError(re
764:                                    .getMessage(), niceFileName));
765:                        }
766:
767:                        rs.end(ctx);
768:
769:                        try {
770:                            long start = System.nanoTime();
771:                            for (Renderer r : renderers) {
772:                                r.renderFileReport(report);
773:                            }
774:                            long end = System.nanoTime();
775:                            Benchmark.mark(Benchmark.TYPE_REPORTING, end
776:                                    - start, 1);
777:                        } catch (IOException ioe) {
778:                        }
779:                    }
780:                }
781:            }
782:
783:            /**
784:             * Run PMD on a list of files.
785:             *
786:             * @param files             the List of DataSource instances.
787:             * @param ctx               the context in which PMD is operating. This contains the Report and
788:             *                          whatnot
789:             * @param rulesets          the RuleSets
790:             * @param debugEnabled
791:             * @param shortNamesEnabled
792:             * @param inputPath
793:             * @param encoding
794:             * @throws IOException If one of the files could not be read
795:             */
796:            public void processFiles(List<DataSource> files, RuleContext ctx,
797:                    RuleSets rulesets, boolean debugEnabled,
798:                    boolean shortNamesEnabled, String inputPath, String encoding)
799:                    throws IOException {
800:                for (DataSource dataSource : files) {
801:                    String niceFileName = dataSource.getNiceFileName(
802:                            shortNamesEnabled, inputPath);
803:                    ctx.setSourceCodeFilename(niceFileName);
804:                    LOG.fine("Processing " + ctx.getSourceCodeFilename());
805:
806:                    try {
807:                        InputStream stream = new BufferedInputStream(dataSource
808:                                .getInputStream());
809:                        processFile(stream, encoding, rulesets, ctx);
810:                    } catch (PMDException pmde) {
811:                        LOG.log(Level.FINE, "Error while processing files",
812:                                pmde.getCause());
813:
814:                        ctx.getReport().addError(
815:                                new Report.ProcessingError(pmde.getMessage(),
816:                                        niceFileName));
817:                    }
818:                }
819:            }
820:
821:            /**
822:             * If in debug modus, print the names of the rules.
823:             *
824:             * @param rulesets     the RuleSets to print
825:             */
826:            private static void printRuleNamesInDebug(RuleSets rulesets) {
827:                if (LOG.isLoggable(Level.FINER)) {
828:                    for (Rule r : rulesets.getAllRules()) {
829:                        LOG.finer("Loaded rule " + r.getName());
830:                    }
831:                }
832:            }
833:
834:            /**
835:             * Collects the given file into a list.
836:             *
837:             * @param inputFileName a file name
838:             * @param fileSelector  Filtering of wanted source files
839:             * @return the list of files collected from the <code>inputFileName</code>
840:             * @see #collect(String, SourceFileSelector)
841:             */
842:            private static List<DataSource> collectFilesFromOneName(
843:                    String inputFileName, SourceFileSelector fileSelector) {
844:                return collect(inputFileName, fileSelector);
845:            }
846:
847:            /**
848:             * Collects the files from the given comma-separated list.
849:             *
850:             * @param fileList     comma-separated list of filenames
851:             * @param fileSelector Filtering of wanted source files
852:             * @return list of files collected from the <code>fileList</code>
853:             */
854:            private static List<DataSource> collectFromCommaDelimitedString(
855:                    String fileList, SourceFileSelector fileSelector) {
856:                List<DataSource> files = new ArrayList<DataSource>();
857:                for (StringTokenizer st = new StringTokenizer(fileList, ","); st
858:                        .hasMoreTokens();) {
859:                    files.addAll(collect(st.nextToken(), fileSelector));
860:                }
861:                return files;
862:            }
863:
864:            /**
865:             * Collects the files from the given <code>filename</code>.
866:             *
867:             * @param filename     the source from which to collect files
868:             * @param fileSelector Filtering of wanted source files
869:             * @return a list of files found at the given <code>filename</code>
870:             * @throws RuntimeException if <code>filename</code> is not found
871:             */
872:            private static List<DataSource> collect(String filename,
873:                    SourceFileSelector fileSelector) {
874:                File inputFile = new File(filename);
875:                if (!inputFile.exists()) {
876:                    throw new RuntimeException("File " + inputFile.getName()
877:                            + " doesn't exist");
878:                }
879:                List<DataSource> dataSources = new ArrayList<DataSource>();
880:                if (!inputFile.isDirectory()) {
881:                    if (filename.endsWith(".zip") || filename.endsWith(".jar")) {
882:                        ZipFile zipFile;
883:                        try {
884:                            zipFile = new ZipFile(inputFile);
885:                            Enumeration e = zipFile.entries();
886:                            while (e.hasMoreElements()) {
887:                                ZipEntry zipEntry = (ZipEntry) e.nextElement();
888:                                if (fileSelector.isWantedFile(zipEntry
889:                                        .getName())) {
890:                                    dataSources.add(new ZipDataSource(zipFile,
891:                                            zipEntry));
892:                                }
893:                            }
894:                        } catch (IOException ze) {
895:                            throw new RuntimeException("Zip file "
896:                                    + inputFile.getName() + " can't be opened");
897:                        }
898:                    } else {
899:                        dataSources.add(new FileDataSource(inputFile));
900:                    }
901:                } else {
902:                    FileFinder finder = new FileFinder();
903:                    List<File> files = finder
904:                            .findFilesFrom(inputFile.getAbsolutePath(),
905:                                    new SourceFileOrDirectoryFilter(
906:                                            fileSelector), true);
907:                    for (File f : files) {
908:                        dataSources.add(new FileDataSource(f));
909:                    }
910:                }
911:                return dataSources;
912:            }
913:
914:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.