1 package org.andromda.maven.plugin.cartridge;
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 public class HelpMojo
20 extends AbstractMojo
21 {
22
23
24
25
26
27 private boolean detail;
28
29
30
31
32
33
34 private java.lang.String goal;
35
36
37
38
39
40
41 private int lineLength;
42
43
44
45
46
47
48 private int indentSize;
49
50
51
52 public void execute()
53 throws MojoExecutionException
54 {
55 if ( lineLength <= 0 )
56 {
57 getLog().warn( "The parameter 'lineLength' should be positive, using '80' as default." );
58 lineLength = 80;
59 }
60 if ( indentSize <= 0 )
61 {
62 getLog().warn( "The parameter 'indentSize' should be positive, using '2' as default." );
63 indentSize = 2;
64 }
65
66 StringBuffer sb = new StringBuffer();
67
68 append( sb, "org.andromda.maven.plugins:andromda-cartridge-plugin:3.5-SNAPSHOT", 0 );
69 append( sb, "", 0 );
70
71 append( sb, "AndroMDA Cartridge Maven Plugin", 0 );
72 append( sb, "A Maven plugin for performing AndroMDA cartridge related tasks (such as running cartridge tests).", 1 );
73 append( sb, "", 0 );
74
75 if ( goal == null || goal.length() <= 0 )
76 {
77 append( sb, "This plugin has 3 goals:", 0 );
78 append( sb, "", 0 );
79 }
80
81 if ( goal == null || goal.length() <= 0 || "help".equals( goal ) )
82 {
83 append( sb, "andromda-cartridge:help", 0 );
84 append( sb, "Display help information on andromda-cartridge-plugin.\nCall\n\u00a0\u00a0mvn\u00a0andromda-cartridge:help\u00a0-Ddetail=true\u00a0-Dgoal=<goal-name>\nto display parameter details.", 1 );
85 append( sb, "", 0 );
86 if ( detail )
87 {
88 append( sb, "Available parameters:", 1 );
89 append( sb, "", 0 );
90
91 append( sb, "detail (Default: false)", 2 );
92 append( sb, "If true, display all settable properties for each goal.", 3 );
93 append( sb, "Expression: ${detail}", 3 );
94 append( sb, "", 0 );
95
96 append( sb, "goal", 2 );
97 append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 );
98 append( sb, "Expression: ${goal}", 3 );
99 append( sb, "", 0 );
100
101 append( sb, "indentSize (Default: 2)", 2 );
102 append( sb, "The number of spaces per indentation level, should be positive.", 3 );
103 append( sb, "Expression: ${indentSize}", 3 );
104 append( sb, "", 0 );
105
106 append( sb, "lineLength (Default: 80)", 2 );
107 append( sb, "The maximum length of a display line, should be positive.", 3 );
108 append( sb, "Expression: ${lineLength}", 3 );
109 append( sb, "", 0 );
110 }
111 }
112
113 if ( goal == null || goal.length() <= 0 || "test".equals( goal ) )
114 {
115 append( sb, "andromda-cartridge:test", 0 );
116 append( sb, "Provides the ability to compare cartridge output with existing output.", 1 );
117 append( sb, "", 0 );
118 if ( detail )
119 {
120 append( sb, "Available parameters:", 1 );
121 append( sb, "", 0 );
122
123 append( sb, "actualDirectory", 2 );
124 append( sb, "Specifies the directory that contains the \'actual\' output (meaning the output that was currently generated)", 3 );
125 append( sb, "Required: Yes", 3 );
126 append( sb, "Expression: ${project.build.directory}/cartridge-test/actual", 3 );
127 append( sb, "", 0 );
128
129 append( sb, "binaryOutputSuffixes", 2 );
130 append( sb, "Defines the extensions of binary files, binary files are checked for presence and equality, however they aren\'t compared as strings, like every other file.", 3 );
131 append( sb, "Expression: jpg,jpeg,gif,png,jar,zip", 3 );
132 append( sb, "", 0 );
133
134 append( sb, "configurationUri", 2 );
135 append( sb, "This is the URI to the AndroMDA configuration file.", 3 );
136 append( sb, "Required: Yes", 3 );
137 append( sb, "Expression: file:${basedir}/conf/test/andromdaUML2.xml", 3 );
138 append( sb, "", 0 );
139
140 append( sb, "expectedDirectory", 2 );
141 append( sb, "Specifies the directory that contains the \'expected\' output.", 3 );
142 append( sb, "Required: Yes", 3 );
143 append( sb, "Expression: ${project.build.directory}/cartridge-test/expected", 3 );
144 append( sb, "", 0 );
145
146 append( sb, "expectedOutputArchive", 2 );
147 append( sb, "The location of the archive storing the expected output.", 3 );
148 append( sb, "Required: Yes", 3 );
149 append( sb, "Expression: ${basedir}/src/test/expected/cartridge-outputUML2.zip", 3 );
150 append( sb, "", 0 );
151
152 append( sb, "lastModifiedCheck", 2 );
153 append( sb, "Set this to \'true\' to skip code generation if code has not changed since the latest model date.", 3 );
154 append( sb, "Expression: ${lastModifiedCheck}", 3 );
155 append( sb, "", 0 );
156
157 append( sb, "propertyFiles", 2 );
158 append( sb, "(no description available)", 3 );
159 append( sb, "Expression: ${project.build.filters}", 3 );
160 append( sb, "", 0 );
161
162 append( sb, "reportDirectory", 2 );
163 append( sb, "Base directory to which the cartridge test report is written", 3 );
164 append( sb, "Expression: ${project.build.directory}/cartridge-test/reports", 3 );
165 append( sb, "", 0 );
166
167 append( sb, "skip", 2 );
168 append( sb, "Set this to \'true\' to bypass cartridge tests entirely. Its use is NOT RECOMMENDED, but quite convenient on occasion.", 3 );
169 append( sb, "Expression: ${maven.test.skip}", 3 );
170 append( sb, "", 0 );
171
172 append( sb, "skipTests", 2 );
173 append( sb, "Set this to \'true\' to skip running tests, but still compile them. Its use is NOT RECOMMENDED, but quite convenient on occasion.", 3 );
174 append( sb, "Expression: ${skipTests}", 3 );
175 append( sb, "", 0 );
176
177 append( sb, "testFailureIgnore (Default: false)", 2 );
178 append( sb, "Set this to true to ignore a failure during testing. Its use is NOT RECOMMENDED, but quite convenient on occasion.", 3 );
179 append( sb, "Expression: ${maven.test.failure.ignore}", 3 );
180 append( sb, "", 0 );
181 }
182 }
183
184 if ( goal == null || goal.length() <= 0 || "update".equals( goal ) )
185 {
186 append( sb, "andromda-cartridge:update", 0 );
187 append( sb, "Updates the cartridge expected output with the current cartridge output. Invoke it with mvn andromda-cartridge:update when you are inside the cartridge root directory.", 1 );
188 append( sb, "", 0 );
189 if ( detail )
190 {
191 append( sb, "Available parameters:", 1 );
192 append( sb, "", 0 );
193
194 append( sb, "actualDirectory", 2 );
195 append( sb, "Specifies the directory that contains the \'actual\' output (meaning the output that was currently generated)", 3 );
196 append( sb, "Required: Yes", 3 );
197 append( sb, "Expression: ${project.build.directory}/cartridge-test/actual", 3 );
198 append( sb, "", 0 );
199
200 append( sb, "binaryOutputSuffixes", 2 );
201 append( sb, "Defines the extensions of binary files, binary files are checked for presence and equality, however they aren\'t compared as strings, like every other file.", 3 );
202 append( sb, "Expression: jpg,jpeg,gif,png,jar,zip", 3 );
203 append( sb, "", 0 );
204
205 append( sb, "configurationUri", 2 );
206 append( sb, "This is the URI to the AndroMDA configuration file.", 3 );
207 append( sb, "Required: Yes", 3 );
208 append( sb, "Expression: file:${basedir}/conf/test/andromdaUML2.xml", 3 );
209 append( sb, "", 0 );
210
211 append( sb, "expectedDirectory", 2 );
212 append( sb, "Specifies the directory that contains the \'expected\' output.", 3 );
213 append( sb, "Required: Yes", 3 );
214 append( sb, "Expression: ${project.build.directory}/cartridge-test/expected", 3 );
215 append( sb, "", 0 );
216
217 append( sb, "expectedOutputArchive", 2 );
218 append( sb, "The location of the archive storing the expected output.", 3 );
219 append( sb, "Required: Yes", 3 );
220 append( sb, "Expression: ${basedir}/src/test/expected/cartridge-outputUML2.zip", 3 );
221 append( sb, "", 0 );
222
223 append( sb, "lastModifiedCheck", 2 );
224 append( sb, "Set this to \'true\' to skip code generation if code has not changed since the latest model date.", 3 );
225 append( sb, "Expression: ${lastModifiedCheck}", 3 );
226 append( sb, "", 0 );
227
228 append( sb, "propertyFiles", 2 );
229 append( sb, "(no description available)", 3 );
230 append( sb, "Expression: ${project.build.filters}", 3 );
231 append( sb, "", 0 );
232
233 append( sb, "reportDirectory", 2 );
234 append( sb, "Base directory to which the cartridge test report is written", 3 );
235 append( sb, "Expression: ${project.build.directory}/cartridge-test/reports", 3 );
236 append( sb, "", 0 );
237
238 append( sb, "skip", 2 );
239 append( sb, "Set this to \'true\' to bypass cartridge tests entirely. Its use is NOT RECOMMENDED, but quite convenient on occasion.", 3 );
240 append( sb, "Expression: ${maven.test.skip}", 3 );
241 append( sb, "", 0 );
242
243 append( sb, "skipTests", 2 );
244 append( sb, "Set this to \'true\' to skip running tests, but still compile them. Its use is NOT RECOMMENDED, but quite convenient on occasion.", 3 );
245 append( sb, "Expression: ${skipTests}", 3 );
246 append( sb, "", 0 );
247
248 append( sb, "testFailureIgnore (Default: false)", 2 );
249 append( sb, "Set this to true to ignore a failure during testing. Its use is NOT RECOMMENDED, but quite convenient on occasion.", 3 );
250 append( sb, "Expression: ${maven.test.failure.ignore}", 3 );
251 append( sb, "", 0 );
252 }
253 }
254
255 if ( getLog().isInfoEnabled() )
256 {
257 getLog().info( sb.toString() );
258 }
259 }
260
261
262
263
264
265
266
267
268
269
270 private static String repeat( String str, int repeat )
271 {
272 StringBuffer buffer = new StringBuffer( repeat * str.length() );
273
274 for ( int i = 0; i < repeat; i++ )
275 {
276 buffer.append( str );
277 }
278
279 return buffer.toString();
280 }
281
282
283
284
285
286
287
288
289
290 private void append( StringBuffer sb, String description, int indent )
291 {
292 for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
293 {
294 sb.append( it.next().toString() ).append( '\n' );
295 }
296 }
297
298
299
300
301
302
303
304
305
306
307
308 private static List toLines( String text, int indent, int indentSize, int lineLength )
309 {
310 List lines = new ArrayList();
311
312 String ind = repeat( "\t", indent );
313 String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
314 for ( int i = 0; i < plainLines.length; i++ )
315 {
316 toLines( lines, ind + plainLines[i], indentSize, lineLength );
317 }
318
319 return lines;
320 }
321
322
323
324
325
326
327
328
329
330 private static void toLines( List lines, String line, int indentSize, int lineLength )
331 {
332 int lineIndent = getIndentLevel( line );
333 StringBuffer buf = new StringBuffer( 256 );
334 String[] tokens = line.split( " +" );
335 for ( int i = 0; i < tokens.length; i++ )
336 {
337 String token = tokens[i];
338 if ( i > 0 )
339 {
340 if ( buf.length() + token.length() >= lineLength )
341 {
342 lines.add( buf.toString() );
343 buf.setLength( 0 );
344 buf.append( repeat( " ", lineIndent * indentSize ) );
345 }
346 else
347 {
348 buf.append( ' ' );
349 }
350 }
351 for ( int j = 0; j < token.length(); j++ )
352 {
353 char c = token.charAt( j );
354 if ( c == '\t' )
355 {
356 buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
357 }
358 else if ( c == '\u00A0' )
359 {
360 buf.append( ' ' );
361 }
362 else
363 {
364 buf.append( c );
365 }
366 }
367 }
368 lines.add( buf.toString() );
369 }
370
371
372
373
374
375
376
377 private static int getIndentLevel( String line )
378 {
379 int level = 0;
380 for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
381 {
382 level++;
383 }
384 for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
385 {
386 if ( line.charAt( i ) == '\t' )
387 {
388 level++;
389 break;
390 }
391 }
392 return level;
393 }
394 }