1
2
3
4
5 package com.qulice.pmd;
6
7 import com.jcabi.log.Logger;
8 import com.qulice.spi.Environment;
9 import java.io.File;
10 import java.nio.charset.Charset;
11 import java.util.Collection;
12 import java.util.Collections;
13 import java.util.LinkedList;
14 import net.sourceforge.pmd.PMDConfiguration;
15 import net.sourceforge.pmd.Report;
16 import net.sourceforge.pmd.RuleContext;
17 import net.sourceforge.pmd.RulePriority;
18 import net.sourceforge.pmd.util.datasource.DataSource;
19
20
21
22
23
24
25 @SuppressWarnings("deprecation")
26 final class SourceValidator {
27
28
29
30 private final RuleContext context;
31
32
33
34
35 private final PmdListener listener;
36
37
38
39
40
41 private final PmdRenderer renderer;
42
43
44
45
46 private final PMDConfiguration config;
47
48
49
50
51 private final Charset encoding;
52
53
54
55
56
57 SourceValidator(final Environment env) {
58 this.context = new RuleContext();
59 this.listener = new PmdListener(env);
60 this.renderer = new PmdRenderer();
61 this.config = new PMDConfiguration();
62 this.encoding = env.encoding();
63 }
64
65
66
67
68
69
70
71 @SuppressWarnings({"PMD.AvoidInstantiatingObjectsInLoops", "PMD.CloseResource"})
72 public Collection<PmdError> validate(
73 final Collection<DataSource> sources, final String path) {
74 this.config.setRuleSets("com/qulice/pmd/ruleset.xml");
75 this.config.setThreads(0);
76 this.config.setMinimumPriority(RulePriority.LOW);
77 this.config.setIgnoreIncrementalAnalysis(true);
78 this.config.setShowSuppressedViolations(true);
79 this.config.setSourceEncoding(this.encoding.name());
80 final Report report = new Report();
81 report.addListener(this.listener);
82 this.context.setReport(report);
83 for (final DataSource source : sources) {
84 final String name = source.getNiceFileName(false, path);
85 final long start = System.currentTimeMillis();
86 Logger.debug(this, "PMD processing file: %s", name);
87 this.context.setSourceCodeFile(new File(name));
88 this.validateOne(source);
89 Logger.debug(
90 this,
91 "PMD processed file: %[file]s in %[ms]s",
92 name,
93 System.currentTimeMillis() - start
94 );
95 }
96 this.renderer.exportTo(report);
97 report.errors().forEachRemaining(this.listener::onProcessingError);
98 report.configErrors().forEachRemaining(this.listener::onConfigError);
99 Logger.debug(
100 this,
101 "got %d errors",
102 this.listener.errors().size()
103 );
104 return this.listener.errors();
105 }
106
107
108
109
110
111 private void validateOne(final DataSource source) {
112 final net.sourceforge.pmd.RuleSetFactory factory =
113 new net.sourceforge.pmd.RuleSetFactory(
114 new net.sourceforge.pmd.util.ResourceLoader(),
115 RulePriority.LOW,
116 false,
117 true
118 );
119 net.sourceforge.pmd.PMD.processFiles(
120 this.config,
121 factory,
122 new LinkedList<>(Collections.singleton(source)),
123 this.context,
124 Collections.singletonList(this.renderer)
125 );
126 }
127 }