001package org.andromda.beautifier.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-beautifier-plugin.<br/> Call <pre>  mvn andromda-beautifier:help -Ddetail=true -Dgoal=&lt;goal-name&gt;</pre> to display parameter details.
012 *
013 * @version generated on Thu Sep 18 16:35:50 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-beautifier-plugin:3.5-SNAPSHOT", 0 );
069        append( sb, "", 0 );
070
071        append( sb, "AndroMDA Beautifier Plugin", 0 );
072        append( sb, "The AndroMDA Maven plugins", 1 );
073        append( sb, "", 0 );
074
075        if ( goal == null || goal.length() <= 0 )
076        {
077            append( sb, "This plugin has 2 goals:", 0 );
078            append( sb, "", 0 );
079        }
080
081        if ( goal == null || goal.length() <= 0 || "beautify-imports".equals( goal ) )
082        {
083            append( sb, "andromda-beautifier:beautify-imports", 0 );
084            append( sb, "Runs andromda beautifier", 1 );
085            append( sb, "", 0 );
086            if ( detail )
087            {
088                append( sb, "Available parameters:", 1 );
089                append( sb, "", 0 );
090
091                append( sb, "inputDirectory", 2 );
092                append( sb, "Location of the directory to be recursively beautified. Defaults to all source directories for parent project (..)", 3 );
093                append( sb, "Expression: ${basedir}", 3 );
094                append( sb, "", 0 );
095
096                append( sb, "outputDirectory", 2 );
097                append( sb, "Location of the output directory for beautified source. Defaults to the source directory", 3 );
098                append( sb, "Expression: ${basedir}", 3 );
099                append( sb, "", 0 );
100
101                append( sb, "skipProcessing", 2 );
102                append( sb, "Whether or not processing should be skipped (this is if you just want to force Beautifier not to run on your code, i.e. if generating site from already formatted source code).", 3 );
103                append( sb, "Expression: ${beautifier.run.skip}", 3 );
104                append( sb, "", 0 );
105            }
106        }
107
108        if ( goal == null || goal.length() <= 0 || "help".equals( goal ) )
109        {
110            append( sb, "andromda-beautifier:help", 0 );
111            append( sb, "Display help information on andromda-beautifier-plugin.\nCall\n\u00a0\u00a0mvn\u00a0andromda-beautifier:help\u00a0-Ddetail=true\u00a0-Dgoal=<goal-name>\nto display parameter details.", 1 );
112            append( sb, "", 0 );
113            if ( detail )
114            {
115                append( sb, "Available parameters:", 1 );
116                append( sb, "", 0 );
117
118                append( sb, "detail (Default: false)", 2 );
119                append( sb, "If true, display all settable properties for each goal.", 3 );
120                append( sb, "Expression: ${detail}", 3 );
121                append( sb, "", 0 );
122
123                append( sb, "goal", 2 );
124                append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 );
125                append( sb, "Expression: ${goal}", 3 );
126                append( sb, "", 0 );
127
128                append( sb, "indentSize (Default: 2)", 2 );
129                append( sb, "The number of spaces per indentation level, should be positive.", 3 );
130                append( sb, "Expression: ${indentSize}", 3 );
131                append( sb, "", 0 );
132
133                append( sb, "lineLength (Default: 80)", 2 );
134                append( sb, "The maximum length of a display line, should be positive.", 3 );
135                append( sb, "Expression: ${lineLength}", 3 );
136                append( sb, "", 0 );
137            }
138        }
139
140        if ( getLog().isInfoEnabled() )
141        {
142            getLog().info( sb.toString() );
143        }
144    }
145
146    /**
147     * <p>Repeat a String <code>n</code> times to form a new string.</p>
148     *
149     * @param str String to repeat
150     * @param repeat number of times to repeat str
151     * @return String with repeated String
152     * @throws NegativeArraySizeException if <code>repeat < 0</code>
153     * @throws NullPointerException if str is <code>null</code>
154     */
155    private static String repeat( String str, int repeat )
156    {
157        StringBuffer buffer = new StringBuffer( repeat * str.length() );
158
159        for ( int i = 0; i < repeat; i++ )
160        {
161            buffer.append( str );
162        }
163
164        return buffer.toString();
165    }
166
167    /** 
168     * Append a description to the buffer by respecting the indentSize and lineLength parameters.
169     * <b>Note</b>: The last character is always a new line.
170     * 
171     * @param sb The buffer to append the description, not <code>null</code>.
172     * @param description The description, not <code>null</code>.
173     * @param indent The base indentation level of each line, must not be negative.
174     */
175    private void append( StringBuffer sb, String description, int indent )
176    {
177        for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
178        {
179            sb.append( it.next().toString() ).append( '\n' );
180        }
181    }
182
183    /** 
184     * Splits the specified text into lines of convenient display length.
185     * 
186     * @param text The text to split into lines, must not be <code>null</code>.
187     * @param indent The base indentation level of each line, must not be negative.
188     * @param indentSize The size of each indentation, must not be negative.
189     * @param lineLength The length of the line, must not be negative.
190     * @return The sequence of display lines, never <code>null</code>.
191     * @throws NegativeArraySizeException if <code>indent < 0</code>
192     */
193    private static List toLines( String text, int indent, int indentSize, int lineLength )
194    {
195        List lines = new ArrayList();
196
197        String ind = repeat( "\t", indent );
198        String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
199        for ( int i = 0; i < plainLines.length; i++ )
200        {
201            toLines( lines, ind + plainLines[i], indentSize, lineLength );
202        }
203
204        return lines;
205    }
206
207    /** 
208     * Adds the specified line to the output sequence, performing line wrapping if necessary.
209     * 
210     * @param lines The sequence of display lines, must not be <code>null</code>.
211     * @param line The line to add, must not be <code>null</code>.
212     * @param indentSize The size of each indentation, must not be negative.
213     * @param lineLength The length of the line, must not be negative.
214     */
215    private static void toLines( List lines, String line, int indentSize, int lineLength )
216    {
217        int lineIndent = getIndentLevel( line );
218        StringBuffer buf = new StringBuffer( 256 );
219        String[] tokens = line.split( " +" );
220        for ( int i = 0; i < tokens.length; i++ )
221        {
222            String token = tokens[i];
223            if ( i > 0 )
224            {
225                if ( buf.length() + token.length() >= lineLength )
226                {
227                    lines.add( buf.toString() );
228                    buf.setLength( 0 );
229                    buf.append( repeat( " ", lineIndent * indentSize ) );
230                }
231                else
232                {
233                    buf.append( ' ' );
234                }
235            }
236            for ( int j = 0; j < token.length(); j++ )
237            {
238                char c = token.charAt( j );
239                if ( c == '\t' )
240                {
241                    buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
242                }
243                else if ( c == '\u00A0' )
244                {
245                    buf.append( ' ' );
246                }
247                else
248                {
249                    buf.append( c );
250                }
251            }
252        }
253        lines.add( buf.toString() );
254    }
255
256    /** 
257     * Gets the indentation level of the specified line.
258     * 
259     * @param line The line whose indentation level should be retrieved, must not be <code>null</code>.
260     * @return The indentation level of the line.
261     */
262    private static int getIndentLevel( String line )
263    {
264        int level = 0;
265        for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
266        {
267            level++;
268        }
269        for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
270        {
271            if ( line.charAt( i ) == '\t' )
272            {
273                level++;
274                break;
275            }
276        }
277        return level;
278    }
279}