1 package org.codehaus.mojo.macker;
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 public class HelpMojo
19 extends AbstractMojo
20 {
21
22
23
24
25
26 private boolean detail;
27
28
29
30
31
32
33 private java.lang.String goal;
34
35
36
37
38
39
40 private int lineLength;
41
42
43
44
45
46
47 private int indentSize;
48
49
50
51 public void execute()
52 throws MojoExecutionException
53 {
54 if ( lineLength <= 0 )
55 {
56 getLog().warn( "The parameter 'lineLength' should be positive, using '80' as default." );
57 lineLength = 80;
58 }
59 if ( indentSize <= 0 )
60 {
61 getLog().warn( "The parameter 'indentSize' should be positive, using '2' as default." );
62 indentSize = 2;
63 }
64
65 StringBuffer sb = new StringBuffer();
66
67 append( sb, "org.codehaus.mojo:macker-maven-plugin:1.0.0-SNAPSHOT", 0 );
68 append( sb, "", 0 );
69
70 append( sb, "Macker Maven Plugin", 0 );
71 append( sb, "This plugin executes the Macker architectural rule checking utility against a project\'s compiled Java code.", 1 );
72 append( sb, "", 0 );
73
74 if ( goal == null || goal.length() <= 0 )
75 {
76 append( sb, "This plugin has 2 goals:", 0 );
77 append( sb, "", 0 );
78 }
79
80 if ( goal == null || goal.length() <= 0 || "help".equals( goal ) )
81 {
82 append( sb, "macker:help", 0 );
83 append( sb, "Display help information on macker-maven-plugin.\nCall\n\u00a0\u00a0mvn\u00a0macker:help\u00a0-Ddetail=true\u00a0-Dgoal=<goal-name>\nto display parameter details.", 1 );
84 append( sb, "", 0 );
85 if ( detail )
86 {
87 append( sb, "Available parameters:", 1 );
88 append( sb, "", 0 );
89
90 append( sb, "detail (Default: false)", 2 );
91 append( sb, "If true, display all settable properties for each goal.", 3 );
92 append( sb, "", 0 );
93
94 append( sb, "goal", 2 );
95 append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 );
96 append( sb, "", 0 );
97
98 append( sb, "indentSize (Default: 2)", 2 );
99 append( sb, "The number of spaces per indentation level, should be positive.", 3 );
100 append( sb, "", 0 );
101
102 append( sb, "lineLength (Default: 80)", 2 );
103 append( sb, "The maximum length of a display line, should be positive.", 3 );
104 append( sb, "", 0 );
105 }
106 }
107
108 if ( goal == null || goal.length() <= 0 || "macker".equals( goal ) )
109 {
110 append( sb, "macker:macker", 0 );
111 append( sb, "Runs Macker against the compiled classes of the project.", 1 );
112 append( sb, "", 0 );
113 if ( detail )
114 {
115 append( sb, "Available parameters:", 1 );
116 append( sb, "", 0 );
117
118 append( sb, "anger", 2 );
119 append( sb, "Anger threshold. Valid options are error, warning, info, and debug.", 3 );
120 append( sb, "", 0 );
121
122 append( sb, "classesDirectory", 2 );
123 append( sb, "Directory containing the class files for Macker to analyze.", 3 );
124 append( sb, "", 0 );
125
126 append( sb, "excludes", 2 );
127 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 root directories, use the parameter excludeRoots instead.", 3 );
128 append( sb, "", 0 );
129
130 append( sb, "failOnError (Default: true)", 2 );
131 append( sb, "Fail the build on an error.", 3 );
132 append( sb, "", 0 );
133
134 append( sb, "includes", 2 );
135 append( sb, "A list of files to include from checking. Can contain Ant-style wildcards and double wildcards. Defaults to **\\/*.class.", 3 );
136 append( sb, "", 0 );
137
138 append( sb, "includeTests (Default: false)", 2 );
139 append( sb, "Run Macker on the tests.", 3 );
140 append( sb, "", 0 );
141
142 append( sb, "maxmem (Default: 64m)", 2 );
143 append( sb, "Maximum memory to pass JVM of Macker processes.", 3 );
144 append( sb, "", 0 );
145
146 append( sb, "maxmsg (Default: 0)", 2 );
147 append( sb, "Print max messages.", 3 );
148 append( sb, "", 0 );
149
150 append( sb, "outputDirectory (Default: ${project.build.directory})", 2 );
151 append( sb, "Directory where the Macker output file will be generated.", 3 );
152 append( sb, "", 0 );
153
154 append( sb, "outputName (Default: macker-out.xml)", 2 );
155 append( sb, "Name of the Macker output file.", 3 );
156 append( sb, "", 0 );
157
158 append( sb, "print", 2 );
159 append( sb, "Print threshold. Valid options are error, warning, info, and debug.", 3 );
160 append( sb, "", 0 );
161
162 append( sb, "quiet (Default: false)", 2 );
163 append( sb, "Only output Macker errors, avoid info messages.", 3 );
164 append( sb, "", 0 );
165
166 append( sb, "rule (Default: macker-rules.xml)", 2 );
167 append( sb, "Name of the Macker rules file.", 3 );
168 append( sb, "", 0 );
169
170 append( sb, "rules", 2 );
171 append( sb, "Name of the Macker rules files.", 3 );
172 append( sb, "", 0 );
173
174 append( sb, "rulesDirectory", 2 );
175 append( sb, "Directory containing the rules files for Macker.", 3 );
176 append( sb, "", 0 );
177
178 append( sb, "skip (Default: false)", 2 );
179 append( sb, "Skip the checks. Most useful on the command line via \'-Dmacker.skip=true\'.", 3 );
180 append( sb, "", 0 );
181
182 append( sb, "testClassesDirectory", 2 );
183 append( sb, "The directories containing the test-classes to be analyzed.", 3 );
184 append( sb, "", 0 );
185
186 append( sb, "variables", 2 );
187 append( sb, "Variables map that will be passed to Macker.", 3 );
188 append( sb, "", 0 );
189
190 append( sb, "verbose (Default: false)", 2 );
191 append( sb, "Verbose setting for Macker tool execution.", 3 );
192 append( sb, "", 0 );
193 }
194 }
195
196 if ( getLog().isInfoEnabled() )
197 {
198 getLog().info( sb.toString() );
199 }
200 }
201
202
203
204
205
206
207
208
209
210
211 private static String repeat( String str, int repeat )
212 {
213 StringBuffer buffer = new StringBuffer( repeat * str.length() );
214
215 for ( int i = 0; i < repeat; i++ )
216 {
217 buffer.append( str );
218 }
219
220 return buffer.toString();
221 }
222
223
224
225
226
227
228
229
230
231 private void append( StringBuffer sb, String description, int indent )
232 {
233 for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
234 {
235 sb.append( it.next().toString() ).append( '\n' );
236 }
237 }
238
239
240
241
242
243
244
245
246
247
248
249 private static List toLines( String text, int indent, int indentSize, int lineLength )
250 {
251 List lines = new ArrayList();
252
253 String ind = repeat( "\t", indent );
254 String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
255 for ( int i = 0; i < plainLines.length; i++ )
256 {
257 toLines( lines, ind + plainLines[i], indentSize, lineLength );
258 }
259
260 return lines;
261 }
262
263
264
265
266
267
268
269
270
271 private static void toLines( List lines, String line, int indentSize, int lineLength )
272 {
273 int lineIndent = getIndentLevel( line );
274 StringBuffer buf = new StringBuffer( 256 );
275 String[] tokens = line.split( " +" );
276 for ( int i = 0; i < tokens.length; i++ )
277 {
278 String token = tokens[i];
279 if ( i > 0 )
280 {
281 if ( buf.length() + token.length() >= lineLength )
282 {
283 lines.add( buf.toString() );
284 buf.setLength( 0 );
285 buf.append( repeat( " ", lineIndent * indentSize ) );
286 }
287 else
288 {
289 buf.append( ' ' );
290 }
291 }
292 for ( int j = 0; j < token.length(); j++ )
293 {
294 char c = token.charAt( j );
295 if ( c == '\t' )
296 {
297 buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
298 }
299 else if ( c == '\u00A0' )
300 {
301 buf.append( ' ' );
302 }
303 else
304 {
305 buf.append( c );
306 }
307 }
308 }
309 lines.add( buf.toString() );
310 }
311
312
313
314
315
316
317
318 private static int getIndentLevel( String line )
319 {
320 int level = 0;
321 for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
322 {
323 level++;
324 }
325 for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
326 {
327 if ( line.charAt( i ) == '\t' )
328 {
329 level++;
330 break;
331 }
332 }
333 return level;
334 }
335 }