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