View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
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"; // Enhance to support other usage
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      // this has to be a public static class, so that JCommander can use it!
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      // this has to be a public static class, so that JCommander can use it!
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      * @return the uri alternative to source directory.
224      */
225     public String getUri() {
226         return uri;
227     }
228 
229     /**
230      * @param uri the uri specifying the source directory.
231      */
232     public void setUri(String uri) {
233         this.uri = uri;
234     }
235 
236 }