1 /**
2 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 */
4 package net.sourceforge.pmd;
5
6 import net.sourceforge.pmd.renderers.CSVRenderer;
7 import net.sourceforge.pmd.renderers.EmacsRenderer;
8 import net.sourceforge.pmd.renderers.HTMLRenderer;
9 import net.sourceforge.pmd.renderers.IDEAJRenderer;
10 import net.sourceforge.pmd.renderers.PapariTextRenderer;
11 import net.sourceforge.pmd.renderers.Renderer;
12 import net.sourceforge.pmd.renderers.SummaryHTMLRenderer;
13 import net.sourceforge.pmd.renderers.TextRenderer;
14 import net.sourceforge.pmd.renderers.VBHTMLRenderer;
15 import net.sourceforge.pmd.renderers.XMLRenderer;
16 import net.sourceforge.pmd.renderers.XSLTRenderer;
17 import net.sourceforge.pmd.renderers.YAHTMLRenderer;
18
19 import java.io.InputStreamReader;
20 import java.text.MessageFormat;
21
22 public class CommandLineOptions {
23
24 private boolean debugEnabled;
25 private boolean stressTestEnabled;
26 private String targetJDK = "1.5";
27 private boolean shortNamesEnabled;
28 private int cpus = Runtime.getRuntime().availableProcessors();
29
30 private String excludeMarker = PMD.EXCLUDE_MARKER;
31 private String inputPath;
32 private String reportFormat;
33 private String reportFile;
34 private String ruleSets;
35 private String encoding = new InputStreamReader(System.in).getEncoding();
36 private String linePrefix;
37 private String linkPrefix;
38 private int minPriority = Rule.LOWEST_PRIORITY;
39 private boolean benchmark;
40 private String xsltFilename;
41 private String auxClasspath;
42
43 private boolean checkJavaFiles = true;
44 private boolean checkJspFiles;
45
46 private String[] args;
47
48 public CommandLineOptions(String[] args) {
49
50 this.args = args;
51
52 if (args == null || args.length < 3) {
53 throw new IllegalArgumentException(usage());
54 }
55 int optIndex = 0;
56 if (args[0].charAt(0) == '-') {
57 optIndex = args.length - 3;
58 }
59
60 inputPath = args[optIndex];
61 reportFormat = args[optIndex+1];
62 ruleSets = new SimpleRuleSetNameMapper(args[optIndex+2]).getRuleSets();
63
64 for (int i = 0; i < args.length; i++) {
65 if (args[i].equals("-debug")) {
66 debugEnabled = true;
67 } else if (args[i].equals("-stress")) {
68 stressTestEnabled = true;
69 } else if (args[i].equals("-shortnames")) {
70 shortNamesEnabled = true;
71 } else if (args[i].equals("-encoding")) {
72 encoding = args[++i];
73 } else if (args[i].equals("-cpus")) {
74 try {
75 cpus = Integer.parseInt(args[++i]);
76 } catch (NumberFormatException e) {
77 throw new IllegalArgumentException(MessageFormat.format(
78 "cpus parameter must be a whole number, {0} received", args[i]));
79 }
80 } else if (args[i].equals("-targetjdk")) {
81 targetJDK = args[++i];
82 } else if (args[i].equals("-excludemarker")) {
83 excludeMarker = args[++i];
84 } else if (args[i].equals("-jsp")) {
85 checkJspFiles = true;
86 } else if (args[i].equals("-nojava")) {
87 checkJavaFiles = false;
88 } else if (args[i].equals("-lineprefix")) {
89 linePrefix = args[++i];
90 } else if (args[i].equals("-linkprefix")) {
91 linkPrefix = args[++i];
92 } else if (args[i].equals("-minimumpriority")) {
93 try {
94 minPriority = Integer.parseInt(args[++i]);
95 } catch (NumberFormatException e) {
96 throw new IllegalArgumentException(MessageFormat.format(
97 "minimumpriority parameter must be a whole number, {0} received", args[i]));
98 }
99 } else if (args[i].equals("-reportfile")) {
100 reportFile = args[++i];
101 } else if (args[i].equals("-benchmark")) {
102 benchmark = true;
103 } else if ( args[i].equals("-xslt") ) {
104 i++;
105 if ( i >= args.length ) {
106 throw new IllegalArgumentException(usage());
107 }
108 this.xsltFilename = args[i];
109 } else if (args[i].equals("-auxclasspath")) {
110 i++;
111 if ( i >= args.length ) {
112 throw new IllegalArgumentException(usage());
113 }
114 this.auxClasspath = args[i];
115 }
116 }
117 }
118
119 public Renderer createRenderer() {
120 if (reportFormat.equals("xml")) {
121 return new XMLRenderer();
122 } else if (reportFormat.equals("ideaj")) {
123 return new IDEAJRenderer(args);
124 } else if (reportFormat.equals("papari")) {
125 return new PapariTextRenderer();
126 } else if (reportFormat.equals("text")) {
127 return new TextRenderer();
128 } else if (reportFormat.equals("emacs")) {
129 return new EmacsRenderer();
130 } else if (reportFormat.equals("csv")) {
131 return new CSVRenderer();
132 } else if (reportFormat.equals("html")) {
133 return new HTMLRenderer();
134 } else if (reportFormat.equals("nicehtml")) {
135 return new XSLTRenderer(this.xsltFilename);
136 } else if (reportFormat.equals("yahtml")) {
137 return new YAHTMLRenderer();
138 } else if (reportFormat.equals("summaryhtml")) {
139 return new SummaryHTMLRenderer(linkPrefix, linePrefix);
140 } else if (reportFormat.equals("vbhtml")) {
141 return new VBHTMLRenderer();
142 }
143 if (!reportFormat.equals("")) {
144 try {
145 return (Renderer) Class.forName(reportFormat).newInstance();
146 } catch (Exception e) {
147 throw new IllegalArgumentException("Can't find the custom format " + reportFormat + ": " + e.getClass().getName());
148 }
149 }
150
151 throw new IllegalArgumentException("Can't create report with format of " + reportFormat);
152 }
153
154 public boolean containsCommaSeparatedFileList() {
155 return inputPath.indexOf(',') != -1;
156 }
157
158 public String getInputPath() {
159 return this.inputPath;
160 }
161
162 public String getEncoding() {
163 return this.encoding;
164 }
165
166 public String getReportFormat() {
167 return this.reportFormat;
168 }
169
170 public String getReportFile() {
171 return this.reportFile;
172 }
173
174 public String getRulesets() {
175 return this.ruleSets;
176 }
177
178 public String getExcludeMarker() {
179 return this.excludeMarker;
180 }
181
182 public boolean debugEnabled() {
183 return debugEnabled;
184 }
185
186 public boolean stressTestEnabled() {
187 return stressTestEnabled;
188 }
189
190 public int getCpus() {
191 return cpus;
192 }
193
194 public String getTargetJDK() {
195 return targetJDK;
196 }
197
198 public boolean shortNamesEnabled() {
199 return shortNamesEnabled;
200 }
201
202 public int getMinPriority() {
203 return minPriority;
204 }
205
206 public boolean benchmark() {
207 return benchmark;
208 }
209
210 public String getAuxClasspath() {
211 return auxClasspath;
212 }
213
214 public String usage() {
215 return PMD.EOL + PMD.EOL +
216 "Mandatory arguments:" + PMD.EOL +
217 "1) A java source code filename or directory" + PMD.EOL +
218 "2) A report format " + PMD.EOL +
219 "3) A ruleset filename or a comma-delimited string of ruleset filenames" + PMD.EOL +
220 PMD.EOL +
221 "For example: " + PMD.EOL +
222 "c:\\> java -jar pmd-" + PMD.VERSION + ".jar c:\\my\\source\\code html unusedcode" + PMD.EOL +
223 PMD.EOL +
224 "Optional arguments that may be put before or after the mandatory arguments: " + PMD.EOL +
225 "-debug: prints debugging information" + PMD.EOL +
226 "-targetjdk: specifies a language version to target - 1.3, 1.4, 1.5, 1.6 or 1.7; default is 1.5" + PMD.EOL +
227 "-cpus: specifies the number of threads to create" + PMD.EOL +
228 "-encoding: specifies the character set encoding of the source code files PMD is reading (i.e., UTF-8)" + PMD.EOL +
229 "-excludemarker: specifies the String that marks the a line which PMD should ignore; default is NOPMD" + PMD.EOL +
230 "-shortnames: prints shortened filenames in the report" + PMD.EOL +
231 "-linkprefix: path to HTML source, for summary html renderer only" + PMD.EOL +
232 "-lineprefix: custom anchor to affected line in the source file, for summary html renderer only" + PMD.EOL +
233 "-minimumpriority: rule priority threshold; rules with lower priority than they will not be used" + PMD.EOL +
234 "-nojava: do not check Java files; default to check Java files" + PMD.EOL +
235 "-jsp: check JSP/JSF files; default to do not check JSP/JSF files" + PMD.EOL +
236 "-reportfile: send report output to a file; default to System.out" + PMD.EOL +
237 "-benchmark: output a benchmark report upon completion; default to System.err" + PMD.EOL +
238 "-xslt: override default xslt for 'nicehtml' output." + PMD.EOL +
239 "-auxclasspath: specifies the classpath for libraries used by the source code (used by type resolution)" + PMD.EOL +
240 " (alternatively, a 'file://' URL to a text file containing path elements on consecutive lines)" + PMD.EOL +
241 PMD.EOL +
242 "For example on windows: " + PMD.EOL +
243 "c:\\> java -jar pmd-" + PMD.VERSION + ".jar c:\\my\\source\\code text unusedcode,imports -targetjdk 1.5 -debug" + PMD.EOL +
244 "c:\\> java -jar pmd-" + PMD.VERSION + ".jar c:\\my\\source\\code xml basic,design -encoding UTF-8" + PMD.EOL +
245 "c:\\> java -jar pmd-" + PMD.VERSION + ".jar c:\\my\\source\\code html typeresolution -auxclasspath commons-collections.jar;derby.jar" + PMD.EOL +
246 "c:\\> java -jar pmd-" + PMD.VERSION + ".jar c:\\my\\source\\code html typeresolution -auxclasspath file:///C:/my/classpathfile" + PMD.EOL +
247 PMD.EOL +
248 "For example on *nix: " + PMD.EOL +
249 "$ java -jar pmd-" + PMD.VERSION + ".jar /home/workspace/src/main/java/code nicehtml basic,design" + PMD.EOL +
250 "$ java -jar pmd-" + PMD.VERSION + ".jar /home/workspace/src/main/java/code nicehtml basic,design -xslt my-own.xsl" + PMD.EOL +
251 "$ java -jar pmd-" + PMD.VERSION + ".jar /home/workspace/src/main/java/code nicehtml typeresolution -auxclasspath commons-collections.jar:derby.jar" + PMD.EOL +
252 PMD.EOL;
253 }
254
255 public boolean isCheckJavaFiles() {
256 return checkJavaFiles;
257 }
258
259 public boolean isCheckJspFiles() {
260 return checkJspFiles;
261 }
262 }
263
264
265
266