001package org.andromda.maven.plugin.bootstrap; 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-bootstrap-plugin.<br/> Call <pre> mvn andromda-bootstrap:help -Ddetail=true -Dgoal=<goal-name></pre> to display parameter details. 012 * 013 * @version generated on Thu Sep 18 15:54:13 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-bootstrap-plugin:3.5-SNAPSHOT", 0 ); 069 append( sb, "", 0 ); 070 071 append( sb, "AndroMDA Bootstrap Plugin", 0 ); 072 append( sb, "A plugin used to run AndroMDA in \'bootstrap\' mode", 1 ); 073 append( sb, "", 0 ); 074 075 if ( goal == null || goal.length() <= 0 ) 076 { 077 append( sb, "This plugin has 3 goals:", 0 ); 078 append( sb, "", 0 ); 079 } 080 081 if ( goal == null || goal.length() <= 0 || "help".equals( goal ) ) 082 { 083 append( sb, "andromda-bootstrap:help", 0 ); 084 append( sb, "Display help information on andromda-bootstrap-plugin.\nCall\n\u00a0\u00a0mvn\u00a0andromda-bootstrap:help\u00a0-Ddetail=true\u00a0-Dgoal=<goal-name>\nto display parameter details.", 1 ); 085 append( sb, "", 0 ); 086 if ( detail ) 087 { 088 append( sb, "Available parameters:", 1 ); 089 append( sb, "", 0 ); 090 091 append( sb, "detail (Default: false)", 2 ); 092 append( sb, "If true, display all settable properties for each goal.", 3 ); 093 append( sb, "Expression: ${detail}", 3 ); 094 append( sb, "", 0 ); 095 096 append( sb, "goal", 2 ); 097 append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 ); 098 append( sb, "Expression: ${goal}", 3 ); 099 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 || "run".equals( goal ) ) 114 { 115 append( sb, "andromda-bootstrap:run", 0 ); 116 append( sb, "This is exactly the same as the regular AndroMDAMojo in the andromda-maven-plugin, however this is the bootstrap plugin which is used to run AndroMDA in bootstrap mode (with the bootstrap artifacts).", 1 ); 117 append( sb, "", 0 ); 118 if ( detail ) 119 { 120 append( sb, "Available parameters:", 1 ); 121 append( sb, "", 0 ); 122 123 append( sb, "buildSourceDirectory", 2 ); 124 append( sb, "The directory to which the build source is located (any generated source).", 3 ); 125 append( sb, "Expression: ${project.build.directory}/src/main/java", 3 ); 126 append( sb, "", 0 ); 127 128 append( sb, "configurationUri", 2 ); 129 append( sb, "This is the URI to the AndroMDA configuration file.", 3 ); 130 append( sb, "Required: Yes", 3 ); 131 append( sb, "Expression: file:${basedir}/conf/andromda.xml", 3 ); 132 append( sb, "", 0 ); 133 134 append( sb, "lastModifiedCheck", 2 ); 135 append( sb, "Whether or not a last modified check should be performed before running AndroMDA again.", 3 ); 136 append( sb, "Required: Yes", 3 ); 137 append( sb, "Expression: false", 3 ); 138 append( sb, "", 0 ); 139 140 append( sb, "modelOutputHistory", 2 ); 141 append( sb, "The directory where the model generation output history is located (Modelname file containing a list of files generated by that model).", 3 ); 142 append( sb, "Expression: ${project.build.directory}/history", 3 ); 143 append( sb, "", 0 ); 144 145 append( sb, "propertyFiles", 2 ); 146 append( sb, "(no description available)", 3 ); 147 append( sb, "Expression: ${project.build.filters}", 3 ); 148 append( sb, "", 0 ); 149 } 150 } 151 152 if ( goal == null || goal.length() <= 0 || "test-translation-library".equals( goal ) ) 153 { 154 append( sb, "andromda-bootstrap:test-translation-library", 0 ); 155 append( sb, "The bootstrap version of the translation-library test.", 1 ); 156 append( sb, "", 0 ); 157 if ( detail ) 158 { 159 append( sb, "Available parameters:", 1 ); 160 append( sb, "", 0 ); 161 162 append( sb, "configurationUri", 2 ); 163 append( sb, "This is the URI to the AndroMDA configuration file.", 3 ); 164 append( sb, "Required: Yes", 3 ); 165 append( sb, "Expression: file:${basedir}/conf/test/andromda.xml", 3 ); 166 append( sb, "", 0 ); 167 168 append( sb, "propertyFiles", 2 ); 169 append( sb, "(no description available)", 3 ); 170 append( sb, "Expression: ${project.build.filters}", 3 ); 171 append( sb, "", 0 ); 172 173 append( sb, "reportDirectory", 2 ); 174 append( sb, "Base directory to which the cartridge test report is written", 3 ); 175 append( sb, "Expression: ${project.build.directory}/translation-library-test/reports", 3 ); 176 append( sb, "", 0 ); 177 178 append( sb, "skip", 2 ); 179 append( sb, "Set this to \'true\' to bypass cartridge tests entirely. Its use is NOT RECOMMENDED, but quite convenient on occasion.", 3 ); 180 append( sb, "Expression: ${maven.test.skip}", 3 ); 181 append( sb, "", 0 ); 182 183 append( sb, "skipTests", 2 ); 184 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 ); 185 append( sb, "Expression: ${skipTests}", 3 ); 186 append( sb, "", 0 ); 187 188 append( sb, "testFailureIgnore (Default: false)", 2 ); 189 append( sb, "Set this to true to ignore a failure during testing. Its use is NOT RECOMMENDED, but quite convenient on occasion.", 3 ); 190 append( sb, "Expression: ${maven.test.failure.ignore}", 3 ); 191 append( sb, "", 0 ); 192 193 append( sb, "traceExpression", 2 ); 194 append( sb, "Whether or not the expression shall be \'traced\' (i.e. the TraceTranslator will run instead of the specified translator). This is helpful, in allowing us to see which expressions are being parsed in what order, etc.", 3 ); 195 append( sb, "Expression: ${trace.expression}", 3 ); 196 append( sb, "", 0 ); 197 198 append( sb, "translationName", 2 ); 199 append( sb, "When specified, only this translation will be tested (If more than one TestTranslation-* file is found).", 3 ); 200 append( sb, "Expression: ${translation.name}", 3 ); 201 append( sb, "", 0 ); 202 } 203 } 204 205 if ( getLog().isInfoEnabled() ) 206 { 207 getLog().info( sb.toString() ); 208 } 209 } 210 211 /** 212 * <p>Repeat a String <code>n</code> times to form a new string.</p> 213 * 214 * @param str String to repeat 215 * @param repeat number of times to repeat str 216 * @return String with repeated String 217 * @throws NegativeArraySizeException if <code>repeat < 0</code> 218 * @throws NullPointerException if str is <code>null</code> 219 */ 220 private static String repeat( String str, int repeat ) 221 { 222 StringBuffer buffer = new StringBuffer( repeat * str.length() ); 223 224 for ( int i = 0; i < repeat; i++ ) 225 { 226 buffer.append( str ); 227 } 228 229 return buffer.toString(); 230 } 231 232 /** 233 * Append a description to the buffer by respecting the indentSize and lineLength parameters. 234 * <b>Note</b>: The last character is always a new line. 235 * 236 * @param sb The buffer to append the description, not <code>null</code>. 237 * @param description The description, not <code>null</code>. 238 * @param indent The base indentation level of each line, must not be negative. 239 */ 240 private void append( StringBuffer sb, String description, int indent ) 241 { 242 for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); ) 243 { 244 sb.append( it.next().toString() ).append( '\n' ); 245 } 246 } 247 248 /** 249 * Splits the specified text into lines of convenient display length. 250 * 251 * @param text The text to split into lines, must not be <code>null</code>. 252 * @param indent The base indentation level of each line, must not be negative. 253 * @param indentSize The size of each indentation, must not be negative. 254 * @param lineLength The length of the line, must not be negative. 255 * @return The sequence of display lines, never <code>null</code>. 256 * @throws NegativeArraySizeException if <code>indent < 0</code> 257 */ 258 private static List toLines( String text, int indent, int indentSize, int lineLength ) 259 { 260 List lines = new ArrayList(); 261 262 String ind = repeat( "\t", indent ); 263 String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" ); 264 for ( int i = 0; i < plainLines.length; i++ ) 265 { 266 toLines( lines, ind + plainLines[i], indentSize, lineLength ); 267 } 268 269 return lines; 270 } 271 272 /** 273 * Adds the specified line to the output sequence, performing line wrapping if necessary. 274 * 275 * @param lines The sequence of display lines, must not be <code>null</code>. 276 * @param line The line to add, must not be <code>null</code>. 277 * @param indentSize The size of each indentation, must not be negative. 278 * @param lineLength The length of the line, must not be negative. 279 */ 280 private static void toLines( List lines, String line, int indentSize, int lineLength ) 281 { 282 int lineIndent = getIndentLevel( line ); 283 StringBuffer buf = new StringBuffer( 256 ); 284 String[] tokens = line.split( " +" ); 285 for ( int i = 0; i < tokens.length; i++ ) 286 { 287 String token = tokens[i]; 288 if ( i > 0 ) 289 { 290 if ( buf.length() + token.length() >= lineLength ) 291 { 292 lines.add( buf.toString() ); 293 buf.setLength( 0 ); 294 buf.append( repeat( " ", lineIndent * indentSize ) ); 295 } 296 else 297 { 298 buf.append( ' ' ); 299 } 300 } 301 for ( int j = 0; j < token.length(); j++ ) 302 { 303 char c = token.charAt( j ); 304 if ( c == '\t' ) 305 { 306 buf.append( repeat( " ", indentSize - buf.length() % indentSize ) ); 307 } 308 else if ( c == '\u00A0' ) 309 { 310 buf.append( ' ' ); 311 } 312 else 313 { 314 buf.append( c ); 315 } 316 } 317 } 318 lines.add( buf.toString() ); 319 } 320 321 /** 322 * Gets the indentation level of the specified line. 323 * 324 * @param line The line whose indentation level should be retrieved, must not be <code>null</code>. 325 * @return The indentation level of the line. 326 */ 327 private static int getIndentLevel( String line ) 328 { 329 int level = 0; 330 for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ ) 331 { 332 level++; 333 } 334 for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ ) 335 { 336 if ( line.charAt( i ) == '\t' ) 337 { 338 level++; 339 break; 340 } 341 } 342 return level; 343 } 344}