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