1 | |
package org.apache.maven.plugin.pmd; |
2 | |
|
3 | |
import java.util.ArrayList; |
4 | |
import java.util.Iterator; |
5 | |
import java.util.List; |
6 | |
|
7 | |
import org.apache.maven.plugin.AbstractMojo; |
8 | |
import org.apache.maven.plugin.MojoExecutionException; |
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
@SuppressWarnings( "all" ) |
20 | 0 | public class HelpMojo |
21 | |
extends AbstractMojo |
22 | |
{ |
23 | |
|
24 | |
|
25 | |
|
26 | |
|
27 | |
|
28 | |
private boolean detail; |
29 | |
|
30 | |
|
31 | |
|
32 | |
|
33 | |
|
34 | |
|
35 | |
private java.lang.String goal; |
36 | |
|
37 | |
|
38 | |
|
39 | |
|
40 | |
|
41 | |
|
42 | |
private int lineLength; |
43 | |
|
44 | |
|
45 | |
|
46 | |
|
47 | |
|
48 | |
|
49 | |
private int indentSize; |
50 | |
|
51 | |
|
52 | |
|
53 | |
public void execute() |
54 | |
throws MojoExecutionException |
55 | |
{ |
56 | 0 | if ( lineLength <= 0 ) |
57 | |
{ |
58 | 0 | getLog().warn( "The parameter 'lineLength' should be positive, using '80' as default." ); |
59 | 0 | lineLength = 80; |
60 | |
} |
61 | 0 | if ( indentSize <= 0 ) |
62 | |
{ |
63 | 0 | getLog().warn( "The parameter 'indentSize' should be positive, using '2' as default." ); |
64 | 0 | indentSize = 2; |
65 | |
} |
66 | |
|
67 | 0 | StringBuffer sb = new StringBuffer(); |
68 | |
|
69 | 0 | append( sb, "org.apache.maven.plugins:maven-pmd-plugin:2.7.1", 0 ); |
70 | 0 | append( sb, "", 0 ); |
71 | |
|
72 | 0 | append( sb, "Maven PMD Plugin", 0 ); |
73 | 0 | append( sb, "A Maven plugin for the PMD toolkit, that produces a report on both code rule violations and detected copy and paste fragments, as well as being able to fail the build based on these metrics.", 1 ); |
74 | 0 | append( sb, "", 0 ); |
75 | |
|
76 | 0 | if ( goal == null || goal.length() <= 0 ) |
77 | |
{ |
78 | 0 | append( sb, "This plugin has 5 goals:", 0 ); |
79 | 0 | append( sb, "", 0 ); |
80 | |
} |
81 | |
|
82 | 0 | if ( goal == null || goal.length() <= 0 || "check".equals( goal ) ) |
83 | |
{ |
84 | 0 | append( sb, "pmd:check", 0 ); |
85 | 0 | append( sb, "Fail the build if there were any PMD violations in the source code.", 1 ); |
86 | 0 | append( sb, "", 0 ); |
87 | 0 | if ( detail ) |
88 | |
{ |
89 | 0 | append( sb, "Available parameters:", 1 ); |
90 | 0 | append( sb, "", 0 ); |
91 | |
|
92 | 0 | append( sb, "aggregate (Default: false)", 2 ); |
93 | 0 | append( sb, "Whether to build an aggregated report at the root, or build individual reports.", 3 ); |
94 | 0 | append( sb, "Expression: ${aggregate}", 3 ); |
95 | 0 | append( sb, "", 0 ); |
96 | |
|
97 | 0 | append( sb, "failOnViolation (Default: true)", 2 ); |
98 | 0 | append( sb, "Whether to fail the build if the validation check fails.", 3 ); |
99 | 0 | append( sb, "Required: Yes", 3 ); |
100 | 0 | append( sb, "Expression: ${pmd.failOnViolation}", 3 ); |
101 | 0 | append( sb, "", 0 ); |
102 | |
|
103 | 0 | append( sb, "failurePriority (Default: 5)", 2 ); |
104 | 0 | append( sb, "What priority level to fail the build on. Failures at or above this level will stop the build. Anything below will be warnings and will be displayed in the build output if verbose=true. Note: Minimum Priority = 5 Maximum Priority = 0", 3 ); |
105 | 0 | append( sb, "Required: Yes", 3 ); |
106 | 0 | append( sb, "Expression: ${pmd.failurePriority}", 3 ); |
107 | 0 | append( sb, "", 0 ); |
108 | |
|
109 | 0 | append( sb, "skip (Default: false)", 2 ); |
110 | 0 | append( sb, "Skip the PMD checks. Most useful on the command line via \'-Dpmd.skip=true\'.", 3 ); |
111 | 0 | append( sb, "Expression: ${pmd.skip}", 3 ); |
112 | 0 | append( sb, "", 0 ); |
113 | |
|
114 | 0 | append( sb, "targetDirectory", 2 ); |
115 | 0 | append( sb, "The location of the XML report to check, as generated by the PMD report.", 3 ); |
116 | 0 | append( sb, "Required: Yes", 3 ); |
117 | 0 | append( sb, "Expression: ${project.build.directory}", 3 ); |
118 | 0 | append( sb, "", 0 ); |
119 | |
|
120 | 0 | append( sb, "verbose (Default: false)", 2 ); |
121 | 0 | append( sb, "Print details of check failures to build output.", 3 ); |
122 | 0 | append( sb, "Expression: ${pmd.verbose}", 3 ); |
123 | 0 | append( sb, "", 0 ); |
124 | |
} |
125 | |
} |
126 | |
|
127 | 0 | if ( goal == null || goal.length() <= 0 || "cpd".equals( goal ) ) |
128 | |
{ |
129 | 0 | append( sb, "pmd:cpd", 0 ); |
130 | 0 | append( sb, "Creates a report for PMD\'s CPD tool. See http://pmd.sourceforge.net/cpd.html for more detail.", 1 ); |
131 | 0 | append( sb, "", 0 ); |
132 | 0 | if ( detail ) |
133 | |
{ |
134 | 0 | append( sb, "Available parameters:", 1 ); |
135 | 0 | append( sb, "", 0 ); |
136 | |
|
137 | 0 | append( sb, "aggregate (Default: false)", 2 ); |
138 | 0 | append( sb, "Whether to build an aggregated report at the root, or build individual reports.", 3 ); |
139 | 0 | append( sb, "Expression: ${aggregate}", 3 ); |
140 | 0 | append( sb, "", 0 ); |
141 | |
|
142 | 0 | append( sb, "excludeRoots", 2 ); |
143 | 0 | append( sb, "The project source directories that should be excluded.", 3 ); |
144 | 0 | append( sb, "", 0 ); |
145 | |
|
146 | 0 | append( sb, "excludes", 2 ); |
147 | 0 | append( sb, "A list of files to exclude from checking. Can contain Ant-style wildcards and double wildcards. Note that these exclusion patterns only operate on the path of a source file relative to its source root directory. In other words, files are excluded based on their package and/or class name. If you want to exclude entire source root directories, use the parameter excludeRoots instead.", 3 ); |
148 | 0 | append( sb, "", 0 ); |
149 | |
|
150 | 0 | append( sb, "format (Default: xml)", 2 ); |
151 | 0 | append( sb, "Set the output format type, in addition to the HTML report. Must be one of: \'none\', \'csv\', \'xml\', \'txt\' or the full class name of the PMD renderer to use. See the net.sourceforge.pmd.renderers package javadoc for available renderers. XML is required if the pmd:check goal is being used.", 3 ); |
152 | 0 | append( sb, "Expression: ${format}", 3 ); |
153 | 0 | append( sb, "", 0 ); |
154 | |
|
155 | 0 | append( sb, "ignoreIdentifiers (Default: false)", 2 ); |
156 | 0 | append( sb, "Similar to ignoreLiterals but for identifiers; i.e., variable names, methods names, and so forth.", 3 ); |
157 | 0 | append( sb, "Expression: ${cpd.ignoreIdentifiers}", 3 ); |
158 | 0 | append( sb, "", 0 ); |
159 | |
|
160 | 0 | append( sb, "ignoreLiterals (Default: false)", 2 ); |
161 | 0 | append( sb, "If true, CPD ignores literal value differences when evaluating a duplicate block. This means that foo=42; and foo=43; will be seen as equivalent. You may want to run PMD with this option off to start with and then switch it on to see what it turns up.", 3 ); |
162 | 0 | append( sb, "Expression: ${cpd.ignoreLiterals}", 3 ); |
163 | 0 | append( sb, "", 0 ); |
164 | |
|
165 | 0 | append( sb, "includes", 2 ); |
166 | 0 | append( sb, "A list of files to include from checking. Can contain Ant-style wildcards and double wildcards. Defaults to **\\/*.java.", 3 ); |
167 | 0 | append( sb, "", 0 ); |
168 | |
|
169 | 0 | append( sb, "includeTests (Default: false)", 2 ); |
170 | 0 | append( sb, "Run PMD on the tests.", 3 ); |
171 | 0 | append( sb, "", 0 ); |
172 | |
|
173 | 0 | append( sb, "linkXRef (Default: true)", 2 ); |
174 | 0 | append( sb, "Link the violation line numbers to the source xref. Links will be created automatically if the jxr plugin is being used.", 3 ); |
175 | 0 | append( sb, "Expression: ${linkXRef}", 3 ); |
176 | 0 | append( sb, "", 0 ); |
177 | |
|
178 | 0 | append( sb, "minimumTokens (Default: 100)", 2 ); |
179 | 0 | append( sb, "The minimum number of tokens that need to be duplicated before it causes a violation.", 3 ); |
180 | 0 | append( sb, "Expression: ${minimumTokens}", 3 ); |
181 | 0 | append( sb, "", 0 ); |
182 | |
|
183 | 0 | append( sb, "outputDirectory", 2 ); |
184 | 0 | append( sb, "The output directory for the final HTML report. Note that this parameter is only evaluated if the goal is run directly from the command line or during the default lifecycle. If the goal is run indirectly as part of a site generation, the output directory configured in the Maven Site Plugin is used instead.", 3 ); |
185 | 0 | append( sb, "Required: Yes", 3 ); |
186 | 0 | append( sb, "Expression: ${project.reporting.outputDirectory}", 3 ); |
187 | 0 | append( sb, "", 0 ); |
188 | |
|
189 | 0 | append( sb, "outputEncoding (Default: ${project.reporting.outputEncoding})", 2 ); |
190 | 0 | append( sb, "The file encoding when writing non-HTML reports.", 3 ); |
191 | 0 | append( sb, "Expression: ${outputEncoding}", 3 ); |
192 | 0 | append( sb, "", 0 ); |
193 | |
|
194 | 0 | append( sb, "skip (Default: false)", 2 ); |
195 | 0 | append( sb, "Skip the CPD report generation. Most useful on the command line via \'-Dcpd.skip=true\'.", 3 ); |
196 | 0 | append( sb, "Expression: ${cpd.skip}", 3 ); |
197 | 0 | append( sb, "", 0 ); |
198 | |
|
199 | 0 | append( sb, "sourceEncoding (Default: ${project.build.sourceEncoding})", 2 ); |
200 | 0 | append( sb, "The file encoding to use when reading the Java sources.", 3 ); |
201 | 0 | append( sb, "Expression: ${encoding}", 3 ); |
202 | 0 | append( sb, "", 0 ); |
203 | |
|
204 | 0 | append( sb, "targetDirectory", 2 ); |
205 | 0 | append( sb, "The output directory for the intermediate XML report.", 3 ); |
206 | 0 | append( sb, "Required: Yes", 3 ); |
207 | 0 | append( sb, "Expression: ${project.build.directory}", 3 ); |
208 | 0 | append( sb, "", 0 ); |
209 | |
|
210 | 0 | append( sb, "xrefLocation (Default: ${project.reporting.outputDirectory}/xref)", 2 ); |
211 | 0 | append( sb, "Location of the Xrefs to link to.", 3 ); |
212 | 0 | append( sb, "", 0 ); |
213 | |
|
214 | 0 | append( sb, "xrefTestLocation (Default: ${project.reporting.outputDirectory}/xref-test)", 2 ); |
215 | 0 | append( sb, "Location of the Test Xrefs to link to.", 3 ); |
216 | 0 | append( sb, "", 0 ); |
217 | |
} |
218 | |
} |
219 | |
|
220 | 0 | if ( goal == null || goal.length() <= 0 || "cpd-check".equals( goal ) ) |
221 | |
{ |
222 | 0 | append( sb, "pmd:cpd-check", 0 ); |
223 | 0 | append( sb, "Fail the build if there were any CPD violations in the source code.", 1 ); |
224 | 0 | append( sb, "", 0 ); |
225 | 0 | if ( detail ) |
226 | |
{ |
227 | 0 | append( sb, "Available parameters:", 1 ); |
228 | 0 | append( sb, "", 0 ); |
229 | |
|
230 | 0 | append( sb, "aggregate (Default: false)", 2 ); |
231 | 0 | append( sb, "Whether to build an aggregated report at the root, or build individual reports.", 3 ); |
232 | 0 | append( sb, "Expression: ${aggregate}", 3 ); |
233 | 0 | append( sb, "", 0 ); |
234 | |
|
235 | 0 | append( sb, "failOnViolation (Default: true)", 2 ); |
236 | 0 | append( sb, "Whether to fail the build if the validation check fails.", 3 ); |
237 | 0 | append( sb, "Required: Yes", 3 ); |
238 | 0 | append( sb, "Expression: ${pmd.failOnViolation}", 3 ); |
239 | 0 | append( sb, "", 0 ); |
240 | |
|
241 | 0 | append( sb, "skip (Default: false)", 2 ); |
242 | 0 | append( sb, "Skip the CPD violation checks. Most useful on the command line via \'-Dcpd.skip=true\'.", 3 ); |
243 | 0 | append( sb, "Expression: ${cpd.skip}", 3 ); |
244 | 0 | append( sb, "", 0 ); |
245 | |
|
246 | 0 | append( sb, "targetDirectory", 2 ); |
247 | 0 | append( sb, "The location of the XML report to check, as generated by the PMD report.", 3 ); |
248 | 0 | append( sb, "Required: Yes", 3 ); |
249 | 0 | append( sb, "Expression: ${project.build.directory}", 3 ); |
250 | 0 | append( sb, "", 0 ); |
251 | |
|
252 | 0 | append( sb, "verbose (Default: false)", 2 ); |
253 | 0 | append( sb, "Print details of check failures to build output.", 3 ); |
254 | 0 | append( sb, "Expression: ${pmd.verbose}", 3 ); |
255 | 0 | append( sb, "", 0 ); |
256 | |
} |
257 | |
} |
258 | |
|
259 | 0 | if ( goal == null || goal.length() <= 0 || "help".equals( goal ) ) |
260 | |
{ |
261 | 0 | append( sb, "pmd:help", 0 ); |
262 | 0 | append( sb, "Display help information on maven-pmd-plugin.\nCall\n\u00a0\u00a0mvn\u00a0pmd:help\u00a0-Ddetail=true\u00a0-Dgoal=<goal-name>\nto display parameter details.", 1 ); |
263 | 0 | append( sb, "", 0 ); |
264 | 0 | if ( detail ) |
265 | |
{ |
266 | 0 | append( sb, "Available parameters:", 1 ); |
267 | 0 | append( sb, "", 0 ); |
268 | |
|
269 | 0 | append( sb, "detail (Default: false)", 2 ); |
270 | 0 | append( sb, "If true, display all settable properties for each goal.", 3 ); |
271 | 0 | append( sb, "Expression: ${detail}", 3 ); |
272 | 0 | append( sb, "", 0 ); |
273 | |
|
274 | 0 | append( sb, "goal", 2 ); |
275 | 0 | append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 ); |
276 | 0 | append( sb, "Expression: ${goal}", 3 ); |
277 | 0 | append( sb, "", 0 ); |
278 | |
|
279 | 0 | append( sb, "indentSize (Default: 2)", 2 ); |
280 | 0 | append( sb, "The number of spaces per indentation level, should be positive.", 3 ); |
281 | 0 | append( sb, "Expression: ${indentSize}", 3 ); |
282 | 0 | append( sb, "", 0 ); |
283 | |
|
284 | 0 | append( sb, "lineLength (Default: 80)", 2 ); |
285 | 0 | append( sb, "The maximum length of a display line, should be positive.", 3 ); |
286 | 0 | append( sb, "Expression: ${lineLength}", 3 ); |
287 | 0 | append( sb, "", 0 ); |
288 | |
} |
289 | |
} |
290 | |
|
291 | 0 | if ( goal == null || goal.length() <= 0 || "pmd".equals( goal ) ) |
292 | |
{ |
293 | 0 | append( sb, "pmd:pmd", 0 ); |
294 | 0 | append( sb, "Creates a PMD report.", 1 ); |
295 | 0 | append( sb, "", 0 ); |
296 | 0 | if ( detail ) |
297 | |
{ |
298 | 0 | append( sb, "Available parameters:", 1 ); |
299 | 0 | append( sb, "", 0 ); |
300 | |
|
301 | 0 | append( sb, "aggregate (Default: false)", 2 ); |
302 | 0 | append( sb, "Whether to build an aggregated report at the root, or build individual reports.", 3 ); |
303 | 0 | append( sb, "Expression: ${aggregate}", 3 ); |
304 | 0 | append( sb, "", 0 ); |
305 | |
|
306 | 0 | append( sb, "excludeRoots", 2 ); |
307 | 0 | append( sb, "The project source directories that should be excluded.", 3 ); |
308 | 0 | append( sb, "", 0 ); |
309 | |
|
310 | 0 | append( sb, "excludes", 2 ); |
311 | 0 | append( sb, "A list of files to exclude from checking. Can contain Ant-style wildcards and double wildcards. Note that these exclusion patterns only operate on the path of a source file relative to its source root directory. In other words, files are excluded based on their package and/or class name. If you want to exclude entire source root directories, use the parameter excludeRoots instead.", 3 ); |
312 | 0 | append( sb, "", 0 ); |
313 | |
|
314 | 0 | append( sb, "format (Default: xml)", 2 ); |
315 | 0 | append( sb, "Set the output format type, in addition to the HTML report. Must be one of: \'none\', \'csv\', \'xml\', \'txt\' or the full class name of the PMD renderer to use. See the net.sourceforge.pmd.renderers package javadoc for available renderers. XML is required if the pmd:check goal is being used.", 3 ); |
316 | 0 | append( sb, "Expression: ${format}", 3 ); |
317 | 0 | append( sb, "", 0 ); |
318 | |
|
319 | 0 | append( sb, "includes", 2 ); |
320 | 0 | append( sb, "A list of files to include from checking. Can contain Ant-style wildcards and double wildcards. Defaults to **\\/*.java.", 3 ); |
321 | 0 | append( sb, "", 0 ); |
322 | |
|
323 | 0 | append( sb, "includeTests (Default: false)", 2 ); |
324 | 0 | append( sb, "Run PMD on the tests.", 3 ); |
325 | 0 | append( sb, "", 0 ); |
326 | |
|
327 | 0 | append( sb, "linkXRef (Default: true)", 2 ); |
328 | 0 | append( sb, "Link the violation line numbers to the source xref. Links will be created automatically if the jxr plugin is being used.", 3 ); |
329 | 0 | append( sb, "Expression: ${linkXRef}", 3 ); |
330 | 0 | append( sb, "", 0 ); |
331 | |
|
332 | 0 | append( sb, "minimumPriority (Default: 5)", 2 ); |
333 | 0 | append( sb, "The rule priority threshold; rules with lower priority than this will not be evaluated.", 3 ); |
334 | 0 | append( sb, "Expression: ${minimumPriority}", 3 ); |
335 | 0 | append( sb, "", 0 ); |
336 | |
|
337 | 0 | append( sb, "outputDirectory", 2 ); |
338 | 0 | append( sb, "The output directory for the final HTML report. Note that this parameter is only evaluated if the goal is run directly from the command line or during the default lifecycle. If the goal is run indirectly as part of a site generation, the output directory configured in the Maven Site Plugin is used instead.", 3 ); |
339 | 0 | append( sb, "Required: Yes", 3 ); |
340 | 0 | append( sb, "Expression: ${project.reporting.outputDirectory}", 3 ); |
341 | 0 | append( sb, "", 0 ); |
342 | |
|
343 | 0 | append( sb, "outputEncoding (Default: ${project.reporting.outputEncoding})", 2 ); |
344 | 0 | append( sb, "The file encoding when writing non-HTML reports.", 3 ); |
345 | 0 | append( sb, "Expression: ${outputEncoding}", 3 ); |
346 | 0 | append( sb, "", 0 ); |
347 | |
|
348 | 0 | append( sb, "rulesets", 2 ); |
349 | 0 | append( sb, "The PMD rulesets to use. See the Stock Rulesets for a list of some included. Since version 2.5, the ruleset \'rulesets/maven.xml\' is also available. Defaults to the basic, imports and unusedcode rulesets.", 3 ); |
350 | 0 | append( sb, "", 0 ); |
351 | |
|
352 | 0 | append( sb, "skip (Default: false)", 2 ); |
353 | 0 | append( sb, "Skip the PMD report generation. Most useful on the command line via \'-Dpmd.skip=true\'.", 3 ); |
354 | 0 | append( sb, "Expression: ${pmd.skip}", 3 ); |
355 | 0 | append( sb, "", 0 ); |
356 | |
|
357 | 0 | append( sb, "sourceEncoding (Default: ${project.build.sourceEncoding})", 2 ); |
358 | 0 | append( sb, "The file encoding to use when reading the Java sources.", 3 ); |
359 | 0 | append( sb, "Expression: ${encoding}", 3 ); |
360 | 0 | append( sb, "", 0 ); |
361 | |
|
362 | 0 | append( sb, "targetDirectory", 2 ); |
363 | 0 | append( sb, "The output directory for the intermediate XML report.", 3 ); |
364 | 0 | append( sb, "Required: Yes", 3 ); |
365 | 0 | append( sb, "Expression: ${project.build.directory}", 3 ); |
366 | 0 | append( sb, "", 0 ); |
367 | |
|
368 | 0 | append( sb, "targetJdk", 2 ); |
369 | 0 | append( sb, "The target JDK to analyze based on. Should match the target used in the compiler plugin. Valid values are currently 1.3, 1.4, 1.5 and 1.6.\nNote: support for 1.6 was added in version 2.3 of this plugin.\n", 3 ); |
370 | 0 | append( sb, "Expression: ${targetJdk}", 3 ); |
371 | 0 | append( sb, "", 0 ); |
372 | |
|
373 | 0 | append( sb, "xrefLocation (Default: ${project.reporting.outputDirectory}/xref)", 2 ); |
374 | 0 | append( sb, "Location of the Xrefs to link to.", 3 ); |
375 | 0 | append( sb, "", 0 ); |
376 | |
|
377 | 0 | append( sb, "xrefTestLocation (Default: ${project.reporting.outputDirectory}/xref-test)", 2 ); |
378 | 0 | append( sb, "Location of the Test Xrefs to link to.", 3 ); |
379 | 0 | append( sb, "", 0 ); |
380 | |
} |
381 | |
} |
382 | |
|
383 | 0 | if ( getLog().isInfoEnabled() ) |
384 | |
{ |
385 | 0 | getLog().info( sb.toString() ); |
386 | |
} |
387 | 0 | } |
388 | |
|
389 | |
|
390 | |
|
391 | |
|
392 | |
|
393 | |
|
394 | |
|
395 | |
|
396 | |
|
397 | |
|
398 | |
private static String repeat( String str, int repeat ) |
399 | |
{ |
400 | 0 | StringBuffer buffer = new StringBuffer( repeat * str.length() ); |
401 | |
|
402 | 0 | for ( int i = 0; i < repeat; i++ ) |
403 | |
{ |
404 | 0 | buffer.append( str ); |
405 | |
} |
406 | |
|
407 | 0 | return buffer.toString(); |
408 | |
} |
409 | |
|
410 | |
|
411 | |
|
412 | |
|
413 | |
|
414 | |
|
415 | |
|
416 | |
|
417 | |
|
418 | |
private void append( StringBuffer sb, String description, int indent ) |
419 | |
{ |
420 | 0 | for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); ) |
421 | |
{ |
422 | 0 | sb.append( it.next().toString() ).append( '\n' ); |
423 | |
} |
424 | 0 | } |
425 | |
|
426 | |
|
427 | |
|
428 | |
|
429 | |
|
430 | |
|
431 | |
|
432 | |
|
433 | |
|
434 | |
|
435 | |
|
436 | |
private static List toLines( String text, int indent, int indentSize, int lineLength ) |
437 | |
{ |
438 | 0 | List<String> lines = new ArrayList<String>(); |
439 | |
|
440 | 0 | String ind = repeat( "\t", indent ); |
441 | 0 | String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" ); |
442 | 0 | for ( int i = 0; i < plainLines.length; i++ ) |
443 | |
{ |
444 | 0 | toLines( lines, ind + plainLines[i], indentSize, lineLength ); |
445 | |
} |
446 | |
|
447 | 0 | return lines; |
448 | |
} |
449 | |
|
450 | |
|
451 | |
|
452 | |
|
453 | |
|
454 | |
|
455 | |
|
456 | |
|
457 | |
|
458 | |
private static void toLines( List<String> lines, String line, int indentSize, int lineLength ) |
459 | |
{ |
460 | 0 | int lineIndent = getIndentLevel( line ); |
461 | 0 | StringBuffer buf = new StringBuffer( 256 ); |
462 | 0 | String[] tokens = line.split( " +" ); |
463 | 0 | for ( int i = 0; i < tokens.length; i++ ) |
464 | |
{ |
465 | 0 | String token = tokens[i]; |
466 | 0 | if ( i > 0 ) |
467 | |
{ |
468 | 0 | if ( buf.length() + token.length() >= lineLength ) |
469 | |
{ |
470 | 0 | lines.add( buf.toString() ); |
471 | 0 | buf.setLength( 0 ); |
472 | 0 | buf.append( repeat( " ", lineIndent * indentSize ) ); |
473 | |
} |
474 | |
else |
475 | |
{ |
476 | 0 | buf.append( ' ' ); |
477 | |
} |
478 | |
} |
479 | 0 | for ( int j = 0; j < token.length(); j++ ) |
480 | |
{ |
481 | 0 | char c = token.charAt( j ); |
482 | 0 | if ( c == '\t' ) |
483 | |
{ |
484 | 0 | buf.append( repeat( " ", indentSize - buf.length() % indentSize ) ); |
485 | |
} |
486 | 0 | else if ( c == '\u00A0' ) |
487 | |
{ |
488 | 0 | buf.append( ' ' ); |
489 | |
} |
490 | |
else |
491 | |
{ |
492 | 0 | buf.append( c ); |
493 | |
} |
494 | |
} |
495 | |
} |
496 | 0 | lines.add( buf.toString() ); |
497 | 0 | } |
498 | |
|
499 | |
|
500 | |
|
501 | |
|
502 | |
|
503 | |
|
504 | |
|
505 | |
private static int getIndentLevel( String line ) |
506 | |
{ |
507 | 0 | int level = 0; |
508 | 0 | for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ ) |
509 | |
{ |
510 | 0 | level++; |
511 | |
} |
512 | 0 | for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ ) |
513 | |
{ |
514 | 0 | if ( line.charAt( i ) == '\t' ) |
515 | |
{ |
516 | 0 | level++; |
517 | 0 | break; |
518 | |
} |
519 | |
} |
520 | 0 | return level; |
521 | |
} |
522 | |
} |