001package org.andromda.maven.plugin; 002 003import java.util.ArrayList; 004import java.util.Iterator; 005import java.util.List; 006 007import org.apache.maven.plugin.AbstractMojo; 008import org.apache.maven.plugin.MojoExecutionException; 009 010/** 011 * Display help information on andromda-maven-plugin.<br/> Call <pre> mvn andromda:help -Ddetail=true -Dgoal=<goal-name></pre> to display parameter details. 012 * 013 * @version generated on Thu Sep 18 16:08:07 EDT 2014 014 * @author org.apache.maven.tools.plugin.generator.PluginHelpGenerator (version 2.9) 015 * @goal help 016 * @requiresProject false 017 * @threadSafe 018 */ 019public class HelpMojo 020 extends AbstractMojo 021{ 022 /** 023 * If <code>true</code>, display all settable properties for each goal. 024 * 025 * @parameter expression="${detail}" default-value="false" 026 */ 027 private boolean detail; 028 029 /** 030 * The name of the goal for which to show help. If unspecified, all goals will be displayed. 031 * 032 * @parameter expression="${goal}" 033 */ 034 private java.lang.String goal; 035 036 /** 037 * The maximum length of a display line, should be positive. 038 * 039 * @parameter expression="${lineLength}" default-value="80" 040 */ 041 private int lineLength; 042 043 /** 044 * The number of spaces per indentation level, should be positive. 045 * 046 * @parameter expression="${indentSize}" default-value="2" 047 */ 048 private int indentSize; 049 050 051 /** {@inheritDoc} */ 052 public void execute() 053 throws MojoExecutionException 054 { 055 if ( lineLength <= 0 ) 056 { 057 getLog().warn( "The parameter 'lineLength' should be positive, using '80' as default." ); 058 lineLength = 80; 059 } 060 if ( indentSize <= 0 ) 061 { 062 getLog().warn( "The parameter 'indentSize' should be positive, using '2' as default." ); 063 indentSize = 2; 064 } 065 066 StringBuffer sb = new StringBuffer(); 067 068 append( sb, "org.andromda.maven.plugins:andromda-maven-plugin:3.5-SNAPSHOT", 0 ); 069 append( sb, "", 0 ); 070 071 append( sb, "AndroMDA Maven Plugin", 0 ); 072 append( sb, "A plugin for running AndroMDA\'s model processor.", 1 ); 073 append( sb, "", 0 ); 074 075 if ( goal == null || goal.length() <= 0 ) 076 { 077 append( sb, "This plugin has 5 goals:", 0 ); 078 append( sb, "", 0 ); 079 } 080 081 if ( goal == null || goal.length() <= 0 || "export2emf".equals( goal ) ) 082 { 083 append( sb, "andromda:export2emf", 0 ); 084 append( sb, "Exports the MagicDraw project file to EMF XMI (requires valid MagicDraw installation in MD_HOME, but only if target files are not up-to-date)", 1 ); 085 append( sb, "", 0 ); 086 if ( detail ) 087 { 088 append( sb, "Available parameters:", 1 ); 089 append( sb, "", 0 ); 090 091 append( sb, "allowMultipleRuns (Default: false)", 2 ); 092 append( sb, "Do we allow the code generation to run multiple times? Yes for AndroMDA server, no for all other cases unless overridden. This prevents multiple code generation runs while creating site documentation, generate-sources phase can run more than 8 times for each model when initiated by many of the reporting plugins.", 3 ); 093 append( sb, "Required: Yes", 3 ); 094 append( sb, "", 0 ); 095 096 append( sb, "configurationUri", 2 ); 097 append( sb, "This is the URI to the AndroMDA configuration file.", 3 ); 098 append( sb, "Required: Yes", 3 ); 099 append( sb, "Expression: file:${project.basedir}/conf/andromda.xml", 3 ); 100 append( sb, "", 0 ); 101 102 append( sb, "magicDrawHome", 2 ); 103 append( sb, "The home/root directory of the magicdraw installation.", 3 ); 104 append( sb, "Expression: ${magicDrawHome}", 3 ); 105 append( sb, "", 0 ); 106 107 append( sb, "propertyFiles", 2 ); 108 append( sb, "(no description available)", 3 ); 109 append( sb, "Expression: ${project.build.filters}", 3 ); 110 append( sb, "", 0 ); 111 } 112 } 113 114 if ( goal == null || goal.length() <= 0 || "help".equals( goal ) ) 115 { 116 append( sb, "andromda:help", 0 ); 117 append( sb, "Display help information on andromda-maven-plugin.\nCall\n\u00a0\u00a0mvn\u00a0andromda:help\u00a0-Ddetail=true\u00a0-Dgoal=<goal-name>\nto display parameter details.", 1 ); 118 append( sb, "", 0 ); 119 if ( detail ) 120 { 121 append( sb, "Available parameters:", 1 ); 122 append( sb, "", 0 ); 123 124 append( sb, "detail (Default: false)", 2 ); 125 append( sb, "If true, display all settable properties for each goal.", 3 ); 126 append( sb, "Expression: ${detail}", 3 ); 127 append( sb, "", 0 ); 128 129 append( sb, "goal", 2 ); 130 append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 ); 131 append( sb, "Expression: ${goal}", 3 ); 132 append( sb, "", 0 ); 133 134 append( sb, "indentSize (Default: 2)", 2 ); 135 append( sb, "The number of spaces per indentation level, should be positive.", 3 ); 136 append( sb, "Expression: ${indentSize}", 3 ); 137 append( sb, "", 0 ); 138 139 append( sb, "lineLength (Default: 80)", 2 ); 140 append( sb, "The maximum length of a display line, should be positive.", 3 ); 141 append( sb, "Expression: ${lineLength}", 3 ); 142 append( sb, "", 0 ); 143 } 144 } 145 146 if ( goal == null || goal.length() <= 0 || "run".equals( goal ) ) 147 { 148 append( sb, "andromda:run", 0 ); 149 append( sb, "A Maven2 plugin to run AndroMDA.", 1 ); 150 append( sb, "", 0 ); 151 if ( detail ) 152 { 153 append( sb, "Available parameters:", 1 ); 154 append( sb, "", 0 ); 155 156 append( sb, "allowMultipleRuns (Default: false)", 2 ); 157 append( sb, "Do we allow the code generation to run multiple times? Yes for AndroMDA server, no for all other cases unless overridden. This prevents multiple code generation runs while creating site documentation, generate-sources phase can run more than 8 times for each model when initiated by many of the reporting plugins.", 3 ); 158 append( sb, "Required: Yes", 3 ); 159 append( sb, "", 0 ); 160 161 append( sb, "buildSourceDirectory", 2 ); 162 append( sb, "The directory to which the build source is located (any generated source).", 3 ); 163 append( sb, "Expression: ${project.build.directory}/src/main/java", 3 ); 164 append( sb, "", 0 ); 165 166 append( sb, "configurationUri", 2 ); 167 append( sb, "This is the URI to the AndroMDA configuration file.", 3 ); 168 append( sb, "Required: Yes", 3 ); 169 append( sb, "Expression: file:${project.basedir}/conf/andromda.xml", 3 ); 170 append( sb, "", 0 ); 171 172 append( sb, "lastModifiedCheck (Default: true)", 2 ); 173 append( sb, "Whether or not a last modified check should be performed before running AndroMDA again. Checks files in buildSourceDirectory against configurationUri and referenced model dates.", 3 ); 174 append( sb, "Expression: ${lastModifiedCheck}", 3 ); 175 append( sb, "", 0 ); 176 177 append( sb, "modelOutputHistory", 2 ); 178 append( sb, "The directory where the model generation output history is located (Modelname file containing a list of files generated by that model).", 3 ); 179 append( sb, "Expression: ${project.build.directory}/history", 3 ); 180 append( sb, "", 0 ); 181 182 append( sb, "propertyFiles", 2 ); 183 append( sb, "(no description available)", 3 ); 184 append( sb, "Expression: ${project.build.filters}", 3 ); 185 append( sb, "", 0 ); 186 187 append( sb, "skipProcessing (Default: false)", 2 ); 188 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 ); 189 append( sb, "Expression: ${andromda.run.skip}", 3 ); 190 append( sb, "", 0 ); 191 } 192 } 193 194 if ( goal == null || goal.length() <= 0 || "start-server".equals( goal ) ) 195 { 196 append( sb, "andromda:start-server", 0 ); 197 append( sb, "Provides the ability to start the AndroMDA server.", 1 ); 198 append( sb, "", 0 ); 199 if ( detail ) 200 { 201 append( sb, "Available parameters:", 1 ); 202 append( sb, "", 0 ); 203 204 append( sb, "allowMultipleRuns (Default: false)", 2 ); 205 append( sb, "Do we allow the code generation to run multiple times? Yes for AndroMDA server, no for all other cases unless overridden. This prevents multiple code generation runs while creating site documentation, generate-sources phase can run more than 8 times for each model when initiated by many of the reporting plugins.", 3 ); 206 append( sb, "Required: Yes", 3 ); 207 append( sb, "", 0 ); 208 209 append( sb, "configurationUri", 2 ); 210 append( sb, "This is the URI to the AndroMDA configuration file.", 3 ); 211 append( sb, "Required: Yes", 3 ); 212 append( sb, "Expression: file:${project.basedir}/conf/andromda.xml", 3 ); 213 append( sb, "", 0 ); 214 215 append( sb, "propertyFiles", 2 ); 216 append( sb, "(no description available)", 3 ); 217 append( sb, "Expression: ${project.build.filters}", 3 ); 218 append( sb, "", 0 ); 219 } 220 } 221 222 if ( goal == null || goal.length() <= 0 || "stop-server".equals( goal ) ) 223 { 224 append( sb, "andromda:stop-server", 0 ); 225 append( sb, "Provides the ability to stop the AndroMDA server.", 1 ); 226 append( sb, "", 0 ); 227 if ( detail ) 228 { 229 append( sb, "Available parameters:", 1 ); 230 append( sb, "", 0 ); 231 232 append( sb, "allowMultipleRuns (Default: false)", 2 ); 233 append( sb, "Do we allow the code generation to run multiple times? Yes for AndroMDA server, no for all other cases unless overridden. This prevents multiple code generation runs while creating site documentation, generate-sources phase can run more than 8 times for each model when initiated by many of the reporting plugins.", 3 ); 234 append( sb, "Required: Yes", 3 ); 235 append( sb, "", 0 ); 236 237 append( sb, "configurationUri", 2 ); 238 append( sb, "This is the URI to the AndroMDA configuration file.", 3 ); 239 append( sb, "Required: Yes", 3 ); 240 append( sb, "Expression: file:${project.basedir}/conf/andromda.xml", 3 ); 241 append( sb, "", 0 ); 242 243 append( sb, "propertyFiles", 2 ); 244 append( sb, "(no description available)", 3 ); 245 append( sb, "Expression: ${project.build.filters}", 3 ); 246 append( sb, "", 0 ); 247 } 248 } 249 250 if ( getLog().isInfoEnabled() ) 251 { 252 getLog().info( sb.toString() ); 253 } 254 } 255 256 /** 257 * <p>Repeat a String <code>n</code> times to form a new string.</p> 258 * 259 * @param str String to repeat 260 * @param repeat number of times to repeat str 261 * @return String with repeated String 262 * @throws NegativeArraySizeException if <code>repeat < 0</code> 263 * @throws NullPointerException if str is <code>null</code> 264 */ 265 private static String repeat( String str, int repeat ) 266 { 267 StringBuffer buffer = new StringBuffer( repeat * str.length() ); 268 269 for ( int i = 0; i < repeat; i++ ) 270 { 271 buffer.append( str ); 272 } 273 274 return buffer.toString(); 275 } 276 277 /** 278 * Append a description to the buffer by respecting the indentSize and lineLength parameters. 279 * <b>Note</b>: The last character is always a new line. 280 * 281 * @param sb The buffer to append the description, not <code>null</code>. 282 * @param description The description, not <code>null</code>. 283 * @param indent The base indentation level of each line, must not be negative. 284 */ 285 private void append( StringBuffer sb, String description, int indent ) 286 { 287 for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); ) 288 { 289 sb.append( it.next().toString() ).append( '\n' ); 290 } 291 } 292 293 /** 294 * Splits the specified text into lines of convenient display length. 295 * 296 * @param text The text to split into lines, must not be <code>null</code>. 297 * @param indent The base indentation level of each line, must not be negative. 298 * @param indentSize The size of each indentation, must not be negative. 299 * @param lineLength The length of the line, must not be negative. 300 * @return The sequence of display lines, never <code>null</code>. 301 * @throws NegativeArraySizeException if <code>indent < 0</code> 302 */ 303 private static List toLines( String text, int indent, int indentSize, int lineLength ) 304 { 305 List lines = new ArrayList(); 306 307 String ind = repeat( "\t", indent ); 308 String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" ); 309 for ( int i = 0; i < plainLines.length; i++ ) 310 { 311 toLines( lines, ind + plainLines[i], indentSize, lineLength ); 312 } 313 314 return lines; 315 } 316 317 /** 318 * Adds the specified line to the output sequence, performing line wrapping if necessary. 319 * 320 * @param lines The sequence of display lines, must not be <code>null</code>. 321 * @param line The line to add, must not be <code>null</code>. 322 * @param indentSize The size of each indentation, must not be negative. 323 * @param lineLength The length of the line, must not be negative. 324 */ 325 private static void toLines( List lines, String line, int indentSize, int lineLength ) 326 { 327 int lineIndent = getIndentLevel( line ); 328 StringBuffer buf = new StringBuffer( 256 ); 329 String[] tokens = line.split( " +" ); 330 for ( int i = 0; i < tokens.length; i++ ) 331 { 332 String token = tokens[i]; 333 if ( i > 0 ) 334 { 335 if ( buf.length() + token.length() >= lineLength ) 336 { 337 lines.add( buf.toString() ); 338 buf.setLength( 0 ); 339 buf.append( repeat( " ", lineIndent * indentSize ) ); 340 } 341 else 342 { 343 buf.append( ' ' ); 344 } 345 } 346 for ( int j = 0; j < token.length(); j++ ) 347 { 348 char c = token.charAt( j ); 349 if ( c == '\t' ) 350 { 351 buf.append( repeat( " ", indentSize - buf.length() % indentSize ) ); 352 } 353 else if ( c == '\u00A0' ) 354 { 355 buf.append( ' ' ); 356 } 357 else 358 { 359 buf.append( c ); 360 } 361 } 362 } 363 lines.add( buf.toString() ); 364 } 365 366 /** 367 * Gets the indentation level of the specified line. 368 * 369 * @param line The line whose indentation level should be retrieved, must not be <code>null</code>. 370 * @return The indentation level of the line. 371 */ 372 private static int getIndentLevel( String line ) 373 { 374 int level = 0; 375 for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ ) 376 { 377 level++; 378 } 379 for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ ) 380 { 381 if ( line.charAt( i ) == '\t' ) 382 { 383 level++; 384 break; 385 } 386 } 387 return level; 388 } 389}