1
2
3
4 package net.sourceforge.pmd.cli;
5
6 import java.io.IOException;
7 import java.util.Properties;
8
9 import net.sourceforge.pmd.PMDConfiguration;
10 import net.sourceforge.pmd.RulePriority;
11 import net.sourceforge.pmd.lang.Language;
12 import net.sourceforge.pmd.lang.LanguageVersion;
13
14 import com.beust.jcommander.IStringConverter;
15 import com.beust.jcommander.Parameter;
16 import com.beust.jcommander.ParameterException;
17 import com.beust.jcommander.validators.PositiveInteger;
18
19 public class PMDParameters {
20
21 @Parameter(names = { "-rulesets", "-R" }, description = "comma separated list of rulesets name to use", required = true)
22 private String rulesets;
23
24 @Parameter(names = { "-uri", "-u" }, description = "Database URI for sources", required = false)
25 private String uri;
26
27 @Parameter(names = { "-dir", "-d" }, description = "root directory for sources", required = false)
28 private String sourceDir;
29
30 @Parameter(names = { "-format", "-f" }, description = "report format type")
31 private String format = "text";
32
33 @Parameter(names = { "-debug", "-verbose", "-D", "-V" }, description = "Debug mode")
34 private boolean debug = false;
35
36 @Parameter(names = { "-help", "-h", "-H" }, description = "Display help on usage", help = true)
37 private boolean help = false;
38
39 @Parameter(names = { "-encoding", "-e" }, description = "specifies the character set encoding of the source code files PMD is reading (i.e., UTF-8)")
40 private String encoding = "UTF-8";
41
42 @Parameter(names = { "-threads", "-t" }, description = "set the number of threads used by PMD", validateWith = PositiveInteger.class)
43 private Integer threads = 1;
44
45 @Parameter(names = { "-benchmark", "-b" }, description = "Benchmark mode - output a benchmark report upon completion; default to System.err")
46 private boolean benchmark = false;
47
48 @Parameter(names = { "-stress", "-S" }, description = "performs a stress test")
49 private boolean stress = false;
50
51 @Parameter(names = "-shortnames", description = "prints shortened filenames in the report")
52 private boolean shortnames = false;
53
54 @Parameter(names = "-showsuppressed", description = "report should show suppressed rule violations")
55 private boolean showsuppressed = false;
56
57 @Parameter(names = "-suppressmarker", description = "specifies the String that marks the a line which PMD should ignore; default is NOPMD")
58 private String suppressmarker = "NOPMD";
59
60 @Parameter(names = { "-minimumpriority", "-min" }, description = "rule priority threshold; rules with lower priority than they will not be used", converter = RulePriorityConverter.class)
61 private RulePriority minimumPriority = RulePriority.LOW;
62
63 @Parameter(names = { "-property", "-P" }, description = "{name}={value}: define a property for the report", converter = PropertyConverter.class)
64 private Properties properties = new Properties();
65
66 @Parameter(names = { "-reportfile", "-r" }, description = "send report output to a file; default to System.out")
67 private String reportfile = null;
68
69 @Parameter(names = { "-version", "-v" }, description = "specify version of a language PMD should use")
70 private String version = Language.getDefaultLanguage().getDefaultVersion().getVersion();
71
72 @Parameter(names = { "-language", "-l" }, description = "specify a language PMD should use")
73 private String language = Language.getDefaultLanguage().getTerseName();
74
75 @Parameter(names = "-auxclasspath", description = "specifies the classpath for libraries used by the source code. This is used by the type resolution. Alternatively, a 'file://' URL to a text file containing path elements on consecutive lines can be specified.")
76 private String auxclasspath;
77
78
79 public static class PropertyConverter implements IStringConverter<Properties> {
80
81 private static final char separator = '=';
82
83 public Properties convert(String value) {
84 Properties properties = new Properties();
85 int indexOfSeparator = value.indexOf(separator);
86 if (indexOfSeparator < 0)
87 throw new ParameterException(
88 "Property name must be separated with an = sign from it value: name=value.");
89 String propertyName = value.substring(0, indexOfSeparator);
90 String propertyValue = value.substring(indexOfSeparator + 1);
91 properties.put(propertyName, propertyValue);
92 return properties;
93 }
94 }
95
96
97 public static class RulePriorityConverter implements IStringConverter<RulePriority> {
98
99 public int validate(String value) throws ParameterException {
100 int minPriorityValue = Integer.parseInt(value);
101 if (minPriorityValue < 0 || minPriorityValue > 5)
102 throw new ParameterException("Priority values can only be integer value, between 0 and 5," + value
103 + " is not valid");
104 return minPriorityValue;
105 }
106
107 public RulePriority convert(String value) {
108 return RulePriority.valueOf(validate(value));
109 }
110 }
111
112 public static PMDConfiguration transformParametersIntoConfiguration(PMDParameters params) {
113 if (null == params.getSourceDir() && null == params.getUri()) {
114 throw new IllegalArgumentException(
115 "Please provide either source root directory (-dir or -d) or database URI (-uri or -u) parameter");
116 }
117 PMDConfiguration configuration = new PMDConfiguration();
118 configuration.setInputPaths(params.getSourceDir());
119 configuration.setInputUri(params.getUri());
120 configuration.setReportFormat(params.getFormat());
121 configuration.setBenchmark(params.isBenchmark());
122 configuration.setDebug(params.isDebug());
123 configuration.setMinimumPriority(params.getMinimumPriority());
124 configuration.setReportFile(params.getReportfile());
125 configuration.setReportProperties(params.getProperties());
126 configuration.setReportShortNames(params.isShortnames());
127 configuration.setRuleSets(params.getRulesets());
128 configuration.setShowSuppressedViolations(params.isShowsuppressed());
129 configuration.setSourceEncoding(params.getEncoding());
130 configuration.setStressTest(params.isStress());
131 configuration.setSuppressMarker(params.getSuppressmarker());
132 configuration.setThreads(params.getThreads());
133 for (LanguageVersion language : LanguageVersion.findVersionsForLanguageTerseName(params.getLanguage())) {
134
135 LanguageVersion languageVersion = language.getLanguage().getVersion(params.getVersion());
136 if (languageVersion == null) {
137 languageVersion = language.getLanguage().getDefaultVersion();
138 }
139 configuration.getLanguageVersionDiscoverer().setDefaultLanguageVersion(languageVersion);
140
141 }
142 try {
143 configuration.prependClasspath(params.getAuxclasspath());
144 } catch (IOException e) {
145 throw new IllegalArgumentException("Invalid auxiliary classpath: " + e.getMessage(), e);
146 }
147 return configuration;
148 }
149
150 public boolean isDebug() {
151 return debug;
152 }
153
154 public boolean isHelp() {
155 return help;
156 }
157
158 public String getEncoding() {
159 return encoding;
160 }
161
162 public Integer getThreads() {
163 return threads;
164 }
165
166 public boolean isBenchmark() {
167 return benchmark;
168 }
169
170 public boolean isStress() {
171 return stress;
172 }
173
174 public boolean isShortnames() {
175 return shortnames;
176 }
177
178 public boolean isShowsuppressed() {
179 return showsuppressed;
180 }
181
182 public String getSuppressmarker() {
183 return suppressmarker;
184 }
185
186 public RulePriority getMinimumPriority() {
187 return minimumPriority;
188 }
189
190 public Properties getProperties() {
191 return properties;
192 }
193
194 public String getReportfile() {
195 return reportfile;
196 }
197
198 public String getVersion() {
199 return version;
200 }
201
202 public String getLanguage() {
203 return language;
204 }
205
206 public String getAuxclasspath() {
207 return auxclasspath;
208 }
209
210 public String getRulesets() {
211 return rulesets;
212 }
213
214 public String getSourceDir() {
215 return sourceDir;
216 }
217
218 public String getFormat() {
219 return format;
220 }
221
222
223
224
225 public String getUri() {
226 return uri;
227 }
228
229
230
231
232 public void setUri(String uri) {
233 this.uri = uri;
234 }
235
236 }