1 package org.andromda.maven.plugin.andromdapp;
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:andromdapp-maven-plugin:3.5-SNAPSHOT", 0 );
69 append( sb, "", 0 );
70
71 append( sb, "AndroMDA Application Generator Maven Plugin", 0 );
72 append( sb, "A plugin for running AndroMDA\'s AndroMDApp application generator to generate Maven2 AndroMDA powered applications.", 1 );
73 append( sb, "", 0 );
74
75 if ( goal == null || goal.length() <= 0 )
76 {
77 append( sb, "This plugin has 10 goals:", 0 );
78 append( sb, "", 0 );
79 }
80
81 if ( goal == null || goal.length() <= 0 || "build".equals( goal ) )
82 {
83 append( sb, "andromdapp:build", 0 );
84 append( sb, "A Mojo used for executing the build goals from the top level project.", 1 );
85 append( sb, "", 0 );
86 if ( detail )
87 {
88 append( sb, "Available parameters:", 1 );
89 append( sb, "", 0 );
90
91 append( sb, "baseDirectory", 2 );
92 append( sb, "(no description available)", 3 );
93 append( sb, "Expression: ${project.basedir}", 3 );
94 append( sb, "", 0 );
95
96 append( sb, "environmentVariablePrefix", 2 );
97 append( sb, "The prefix environment variables must have.", 3 );
98 append( sb, "Expression: env.", 3 );
99 append( sb, "", 0 );
100
101 append( sb, "executionProperties", 2 );
102 append( sb, "Any execution properties.", 3 );
103 append( sb, "", 0 );
104
105 append( sb, "goals", 2 );
106 append( sb, "The default module goals to execute.", 3 );
107 append( sb, "", 0 );
108
109 append( sb, "modules", 2 );
110 append( sb, "A comma separated list of modules to execute in the form: -Dmodules=mda,core,common or if you want to specify the goals to execute as well: -Dmodules=mda:[goal1+goal2+goal3],core:[goal1].", 3 );
111 append( sb, "Expression: ${modules}", 3 );
112 append( sb, "", 0 );
113
114 append( sb, "session", 2 );
115 append( sb, "(no description available)", 3 );
116 append( sb, "Expression: ${session}", 3 );
117 append( sb, "", 0 );
118
119 append( sb, "startConsole", 2 );
120 append( sb, "If defined starts the build console (i.e. keeps maven loaded and running)", 3 );
121 append( sb, "Expression: ${console}", 3 );
122 append( sb, "", 0 );
123 }
124 }
125
126 if ( goal == null || goal.length() <= 0 || "clean-structure".equals( goal ) )
127 {
128 append( sb, "andromdapp:clean-structure", 0 );
129 append( sb, "Removes the an AndroMDApp generated application structure.", 1 );
130 append( sb, "", 0 );
131 if ( detail )
132 {
133 append( sb, "Available parameters:", 1 );
134 append( sb, "", 0 );
135
136 append( sb, "configurationUri", 2 );
137 append( sb, "The URI to an optional AndroMDApp configuration file.", 3 );
138 append( sb, "Expression: ${configuration.uri}", 3 );
139 append( sb, "", 0 );
140
141 append( sb, "propertyFiles", 2 );
142 append( sb, "(no description available)", 3 );
143 append( sb, "Expression: ${project.build.filters}", 3 );
144 append( sb, "", 0 );
145
146 append( sb, "skip", 2 );
147 append( sb, "Set this to \'true\' to bypass cartridge tests entirely. Its use is NOT RECOMMENDED, but quite convenient on occasion.", 3 );
148 append( sb, "Expression: ${maven.test.skip}", 3 );
149 append( sb, "", 0 );
150
151 append( sb, "skipProcessing", 2 );
152 append( sb, "Whether or not processing should be skipped (this is if you want to completely skip code generation, i.e. if code is already generated and you are creating the site from already generated source code).", 3 );
153 append( sb, "Expression: ${andromdapp.run.skip}", 3 );
154 append( sb, "", 0 );
155
156 append( sb, "skipTests", 2 );
157 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 );
158 append( sb, "Expression: ${skipTests}", 3 );
159 append( sb, "", 0 );
160
161 append( sb, "testFailureIgnore (Default: false)", 2 );
162 append( sb, "Set this to true to ignore a failure during testing. Its use is NOT RECOMMENDED, but quite convenient on occasion.", 3 );
163 append( sb, "Expression: ${maven.test.failure.ignore}", 3 );
164 append( sb, "", 0 );
165 }
166 }
167
168 if ( goal == null || goal.length() <= 0 || "deploy".equals( goal ) )
169 {
170 append( sb, "andromdapp:deploy", 0 );
171 append( sb, "Provides the deployment of applications to a given directory.", 1 );
172 append( sb, "", 0 );
173 if ( detail )
174 {
175 append( sb, "Available parameters:", 1 );
176 append( sb, "", 0 );
177
178 append( sb, "deploy", 2 );
179 append( sb, "Indicates whether or not this plugin should perform the deploy.", 3 );
180 append( sb, "Expression: ${deploy}", 3 );
181 append( sb, "", 0 );
182
183 append( sb, "deployLocation", 2 );
184 append( sb, "The location (i.e. path) to deploy.", 3 );
185 append( sb, "Required: Yes", 3 );
186 append( sb, "", 0 );
187
188 append( sb, "excludes", 2 );
189 append( sb, "Any files to exclude in the deploy.", 3 );
190 append( sb, "", 0 );
191
192 append( sb, "includes", 2 );
193 append( sb, "Any additional files to include in the deploy liked datasource files etc (the files must reside in the project build directory). By default nothing besides the file artifact is deployed.", 3 );
194 append( sb, "", 0 );
195 }
196 }
197
198 if ( goal == null || goal.length() <= 0 || "eclipse".equals( goal ) )
199 {
200 append( sb, "andromdapp:eclipse", 0 );
201 append( sb, "Writes the necessary .classpath and .project files for a new eclipse application.", 1 );
202 append( sb, "", 0 );
203 if ( detail )
204 {
205 append( sb, "Available parameters:", 1 );
206 append( sb, "", 0 );
207
208 append( sb, "classpathArtifactTypes", 2 );
209 append( sb, "The artifact types which should be included in the generated Eclipse classpath.", 3 );
210 append( sb, "", 0 );
211
212 append( sb, "classpathMerge", 2 );
213 append( sb, "Allows non-generated configuration to be \'merged\' into the generated .classpath file.", 3 );
214 append( sb, "", 0 );
215
216 append( sb, "excludePoms", 2 );
217 append( sb, "Defines the POMs to exclude when generating the eclipse files.", 3 );
218 append( sb, "Expression: ${exclude.poms}", 3 );
219 append( sb, "", 0 );
220
221 append( sb, "excludes", 2 );
222 append( sb, "Defines the POMs to exclude when generating the eclipse files.", 3 );
223 append( sb, "", 0 );
224
225 append( sb, "includes", 2 );
226 append( sb, "Defines the POMs to include when generating the eclipse files.", 3 );
227 append( sb, "", 0 );
228
229 append( sb, "repositoryVariableName", 2 );
230 append( sb, "The name of the variable that will store the maven repository location.", 3 );
231 append( sb, "Expression: ${repository.variable.name}", 3 );
232 append( sb, "", 0 );
233
234 append( sb, "resolveTransitiveDependencies", 2 );
235 append( sb, "Whether or not transitive dependencies shall be included in any resources (i.e. .classpath that are generated by this mojo).", 3 );
236 append( sb, "Expression: ${resolveTransitiveDependencies}", 3 );
237 append( sb, "", 0 );
238
239 append( sb, "session", 2 );
240 append( sb, "(no description available)", 3 );
241 append( sb, "Expression: ${session}", 3 );
242 append( sb, "", 0 );
243
244 append( sb, "skipProcessing", 2 );
245 append( sb, "Whether or not processing should be skipped (this is if you just want to force AndroMDA not to run on your model).", 3 );
246 append( sb, "Expression: ${andromda.run.skip}", 3 );
247 append( sb, "", 0 );
248
249 append( sb, "variables", 2 );
250 append( sb, "(no description available)", 3 );
251 append( sb, "", 0 );
252 }
253 }
254
255 if ( goal == null || goal.length() <= 0 || "generate".equals( goal ) )
256 {
257 append( sb, "andromdapp:generate", 0 );
258 append( sb, "AndroMDA application generator Mojo.", 1 );
259 append( sb, "", 0 );
260 if ( detail )
261 {
262 append( sb, "Available parameters:", 1 );
263 append( sb, "", 0 );
264
265 append( sb, "configurationUri", 2 );
266 append( sb, "The URI to an optional AndroMDApp configuration file.", 3 );
267 append( sb, "Expression: ${configuration.uri}", 3 );
268 append( sb, "", 0 );
269
270 append( sb, "propertyFiles", 2 );
271 append( sb, "(no description available)", 3 );
272 append( sb, "Expression: ${project.build.filters}", 3 );
273 append( sb, "", 0 );
274
275 append( sb, "skip", 2 );
276 append( sb, "Set this to \'true\' to bypass cartridge tests entirely. Its use is NOT RECOMMENDED, but quite convenient on occasion.", 3 );
277 append( sb, "Expression: ${maven.test.skip}", 3 );
278 append( sb, "", 0 );
279
280 append( sb, "skipProcessing", 2 );
281 append( sb, "Whether or not processing should be skipped (this is if you want to completely skip code generation, i.e. if code is already generated and you are creating the site from already generated source code).", 3 );
282 append( sb, "Expression: ${andromdapp.run.skip}", 3 );
283 append( sb, "", 0 );
284
285 append( sb, "skipTests", 2 );
286 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 );
287 append( sb, "Expression: ${skipTests}", 3 );
288 append( sb, "", 0 );
289
290 append( sb, "testFailureIgnore (Default: false)", 2 );
291 append( sb, "Set this to true to ignore a failure during testing. Its use is NOT RECOMMENDED, but quite convenient on occasion.", 3 );
292 append( sb, "Expression: ${maven.test.failure.ignore}", 3 );
293 append( sb, "", 0 );
294 }
295 }
296
297 if ( goal == null || goal.length() <= 0 || "help".equals( goal ) )
298 {
299 append( sb, "andromdapp:help", 0 );
300 append( sb, "Display help information on andromdapp-maven-plugin.\nCall\n\u00a0\u00a0mvn\u00a0andromdapp:help\u00a0-Ddetail=true\u00a0-Dgoal=<goal-name>\nto display parameter details.", 1 );
301 append( sb, "", 0 );
302 if ( detail )
303 {
304 append( sb, "Available parameters:", 1 );
305 append( sb, "", 0 );
306
307 append( sb, "detail (Default: false)", 2 );
308 append( sb, "If true, display all settable properties for each goal.", 3 );
309 append( sb, "Expression: ${detail}", 3 );
310 append( sb, "", 0 );
311
312 append( sb, "goal", 2 );
313 append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 );
314 append( sb, "Expression: ${goal}", 3 );
315 append( sb, "", 0 );
316
317 append( sb, "indentSize (Default: 2)", 2 );
318 append( sb, "The number of spaces per indentation level, should be positive.", 3 );
319 append( sb, "Expression: ${indentSize}", 3 );
320 append( sb, "", 0 );
321
322 append( sb, "lineLength (Default: 80)", 2 );
323 append( sb, "The maximum length of a display line, should be positive.", 3 );
324 append( sb, "Expression: ${lineLength}", 3 );
325 append( sb, "", 0 );
326 }
327 }
328
329 if ( goal == null || goal.length() <= 0 || "instrument-scripts".equals( goal ) )
330 {
331 append( sb, "andromdapp:instrument-scripts", 0 );
332 append( sb, "Allows for the ScriptClassGenerator mojo to be invoked. on one or more given classes.", 1 );
333 append( sb, "", 0 );
334 if ( detail )
335 {
336 append( sb, "Available parameters:", 1 );
337 append( sb, "", 0 );
338
339 append( sb, "locations", 2 );
340 append( sb, "Defines the java files who\'s classes will be instrumented.", 3 );
341 append( sb, "Required: Yes", 3 );
342 append( sb, "", 0 );
343
344 append( sb, "scriptWrapper", 2 );
345 append( sb, "Defines the fully qualified class name of the script wrapper implementation.", 3 );
346 append( sb, "Required: Yes", 3 );
347 append( sb, "", 0 );
348 }
349 }
350
351 if ( goal == null || goal.length() <= 0 || "link".equals( goal ) )
352 {
353 append( sb, "andromdapp:link", 0 );
354 append( sb, "Basically post processes a previously built ear and replaces any war artifacts with symbolic links and then symbolic links the ear to the deploy directory so that we don\'t have to redeploy an ear in order to make jsp changes.", 1 );
355 append( sb, "", 0 );
356 if ( detail )
357 {
358 append( sb, "Available parameters:", 1 );
359 append( sb, "", 0 );
360
361 append( sb, "deployLocation", 2 );
362 append( sb, "The location in which to link the exploded ear.", 3 );
363 append( sb, "Expression: ${env.JBOSS_HOME}/server/default/deploy", 3 );
364 append( sb, "", 0 );
365
366 append( sb, "rootProjectLimit", 2 );
367 append( sb, "The number of levels allowed to travel up before we get to the \'root project\' (i.e. this will prevent the system from attempting to get parent project that aren\'t really part of the direct project).", 3 );
368 append( sb, "Expression: 1", 3 );
369 append( sb, "", 0 );
370 }
371 }
372
373 if ( goal == null || goal.length() <= 0 || "schema".equals( goal ) )
374 {
375 append( sb, "andromdapp:schema", 0 );
376 append( sb, "Provides the ability to drop database schemas.", 1 );
377 append( sb, "", 0 );
378 if ( detail )
379 {
380 append( sb, "Available parameters:", 1 );
381 append( sb, "", 0 );
382
383 append( sb, "executeScripts", 2 );
384 append( sb, "Whether or not scripts should be executed (if this is set to false, they will only be generated, but not executed).", 3 );
385 append( sb, "Expression: ${executeScripts}", 3 );
386 append( sb, "", 0 );
387
388 append( sb, "jdbcConnectionUrl", 2 );
389 append( sb, "The JDBC connection URL.", 3 );
390 append( sb, "Required: Yes", 3 );
391 append( sb, "", 0 );
392
393 append( sb, "jdbcDriver", 2 );
394 append( sb, "The name of the JDBC driver class.", 3 );
395 append( sb, "Required: Yes", 3 );
396 append( sb, "", 0 );
397
398 append( sb, "jdbcDriverJar", 2 );
399 append( sb, "The jar containing the JDBC driver.", 3 );
400 append( sb, "Required: Yes", 3 );
401 append( sb, "", 0 );
402
403 append( sb, "jdbcPassword", 2 );
404 append( sb, "The JDBC password for the database.", 3 );
405 append( sb, "", 0 );
406
407 append( sb, "jdbcUsername", 2 );
408 append( sb, "The JDBC username for the database.", 3 );
409 append( sb, "Required: Yes", 3 );
410 append( sb, "", 0 );
411
412 append( sb, "pluginArtifacts", 2 );
413 append( sb, "(no description available)", 3 );
414 append( sb, "Required: Yes", 3 );
415 append( sb, "Expression: ${plugin.artifacts}", 3 );
416 append( sb, "", 0 );
417
418 append( sb, "properties", 2 );
419 append( sb, "The properties that can be passed to the schema task.", 3 );
420 append( sb, "", 0 );
421
422 append( sb, "propertyFiles", 2 );
423 append( sb, "Any property files that should be loaded into the schema properties.", 3 );
424 append( sb, "", 0 );
425
426 append( sb, "scripts", 2 );
427 append( sb, "Defines the location(s) of any SQL scripts to be executed.", 3 );
428 append( sb, "", 0 );
429
430 append( sb, "tasks", 2 );
431 append( sb, "The schema task to execute (create, drop, update, validate)", 3 );
432 append( sb, "Expression: ${tasks}", 3 );
433 append( sb, "", 0 );
434
435 append( sb, "taskType", 2 );
436 append( sb, "The type of the create schema task to execute.", 3 );
437 append( sb, "Required: Yes", 3 );
438 append( sb, "Expression: hibernate", 3 );
439 append( sb, "", 0 );
440 }
441 }
442
443 if ( goal == null || goal.length() <= 0 || "undeploy".equals( goal ) )
444 {
445 append( sb, "andromdapp:undeploy", 0 );
446 append( sb, "Provides the undeployment of applications from a given directory.", 1 );
447 append( sb, "", 0 );
448 if ( detail )
449 {
450 append( sb, "Available parameters:", 1 );
451 append( sb, "", 0 );
452
453 append( sb, "deployLocation", 2 );
454 append( sb, "The location (i.e. path) to deploy.", 3 );
455 append( sb, "Required: Yes", 3 );
456 append( sb, "", 0 );
457 }
458 }
459
460 if ( getLog().isInfoEnabled() )
461 {
462 getLog().info( sb.toString() );
463 }
464 }
465
466
467
468
469
470
471
472
473
474
475 private static String repeat( String str, int repeat )
476 {
477 StringBuffer buffer = new StringBuffer( repeat * str.length() );
478
479 for ( int i = 0; i < repeat; i++ )
480 {
481 buffer.append( str );
482 }
483
484 return buffer.toString();
485 }
486
487
488
489
490
491
492
493
494
495 private void append( StringBuffer sb, String description, int indent )
496 {
497 for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
498 {
499 sb.append( it.next().toString() ).append( '\n' );
500 }
501 }
502
503
504
505
506
507
508
509
510
511
512
513 private static List toLines( String text, int indent, int indentSize, int lineLength )
514 {
515 List lines = new ArrayList();
516
517 String ind = repeat( "\t", indent );
518 String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
519 for ( int i = 0; i < plainLines.length; i++ )
520 {
521 toLines( lines, ind + plainLines[i], indentSize, lineLength );
522 }
523
524 return lines;
525 }
526
527
528
529
530
531
532
533
534
535 private static void toLines( List lines, String line, int indentSize, int lineLength )
536 {
537 int lineIndent = getIndentLevel( line );
538 StringBuffer buf = new StringBuffer( 256 );
539 String[] tokens = line.split( " +" );
540 for ( int i = 0; i < tokens.length; i++ )
541 {
542 String token = tokens[i];
543 if ( i > 0 )
544 {
545 if ( buf.length() + token.length() >= lineLength )
546 {
547 lines.add( buf.toString() );
548 buf.setLength( 0 );
549 buf.append( repeat( " ", lineIndent * indentSize ) );
550 }
551 else
552 {
553 buf.append( ' ' );
554 }
555 }
556 for ( int j = 0; j < token.length(); j++ )
557 {
558 char c = token.charAt( j );
559 if ( c == '\t' )
560 {
561 buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
562 }
563 else if ( c == '\u00A0' )
564 {
565 buf.append( ' ' );
566 }
567 else
568 {
569 buf.append( c );
570 }
571 }
572 }
573 lines.add( buf.toString() );
574 }
575
576
577
578
579
580
581
582 private static int getIndentLevel( String line )
583 {
584 int level = 0;
585 for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
586 {
587 level++;
588 }
589 for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
590 {
591 if ( line.charAt( i ) == '\t' )
592 {
593 level++;
594 break;
595 }
596 }
597 return level;
598 }
599 }