001    package org.apache.maven.tools.plugin.generator;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.maven.plugin.descriptor.MojoDescriptor;
023    import org.apache.maven.plugin.descriptor.PluginDescriptor;
024    import org.apache.maven.project.MavenProject;
025    import org.apache.maven.tools.plugin.PluginToolsRequest;
026    import org.apache.velocity.VelocityContext;
027    import org.codehaus.plexus.logging.AbstractLogEnabled;
028    import org.codehaus.plexus.logging.Logger;
029    import org.codehaus.plexus.logging.console.ConsoleLogger;
030    import org.codehaus.plexus.util.IOUtil;
031    import org.codehaus.plexus.util.StringUtils;
032    import org.codehaus.plexus.velocity.VelocityComponent;
033    
034    import java.io.File;
035    import java.io.FileOutputStream;
036    import java.io.IOException;
037    import java.io.InputStream;
038    import java.io.InputStreamReader;
039    import java.io.OutputStreamWriter;
040    import java.io.StringWriter;
041    import java.io.Writer;
042    import java.util.List;
043    import java.util.Properties;
044    
045    /**
046     * Generates an <code>HelpMojo</code> class.
047     *
048     * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
049     * @version $Id: PluginHelpGenerator.java 1342957 2012-05-26 20:29:09Z hboutemy $
050     * @since 2.4
051     */
052    public class PluginHelpGenerator
053        extends AbstractLogEnabled
054        implements Generator
055    {
056        /**
057         * Default generated class name
058         */
059        private static final String HELP_MOJO_CLASS_NAME = "HelpMojo";
060    
061        /**
062         * Default goal
063         */
064        private static final String HELP_GOAL = "help";
065    
066        private String helpPackageName;
067    
068        private VelocityComponent velocityComponent;
069    
070        /**
071         * Default constructor
072         */
073        public PluginHelpGenerator()
074        {
075            this.enableLogging( new ConsoleLogger( Logger.LEVEL_INFO, "PluginHelpGenerator" ) );
076        }
077    
078        // ----------------------------------------------------------------------
079        // Public methods
080        // ----------------------------------------------------------------------
081    
082    
083        /**
084         * {@inheritDoc}
085         */
086        public void execute( File destinationDirectory, PluginToolsRequest request )
087            throws GeneratorException
088        {
089            PluginDescriptor pluginDescriptor = request.getPluginDescriptor();
090    
091            String helpImplementation = getImplementation( pluginDescriptor );
092    
093            @SuppressWarnings( "unchecked" )
094            List<MojoDescriptor> mojoDescriptors = pluginDescriptor.getMojos();
095    
096            if ( mojoDescriptors != null )
097            {
098                // Verify that no help goal already exists
099                for ( MojoDescriptor descriptor : mojoDescriptors )
100                {
101                    if ( HELP_GOAL.equals( descriptor.getGoal() )
102                        && !descriptor.getImplementation().equals( helpImplementation ) )
103                    {
104                        if ( getLogger().isWarnEnabled() )
105                        {
106                            getLogger().warn( "\n\nA help goal (" + descriptor.getImplementation()
107                                                  + ") already exists in this plugin. SKIPPED THE "
108                                                  + helpImplementation + " GENERATION.\n" );
109                        }
110    
111                        return;
112                    }
113                }
114            }
115            Properties properties = new Properties();
116            properties.put( "helpPackageName", helpPackageName == null ? "" : helpPackageName );
117    
118            MavenProject mavenProject = request.getProject();
119    
120            String propertiesFilePath = "META-INF/maven/" + mavenProject.getGroupId() + "/" + mavenProject.getArtifactId();
121    
122            File tmpPropertiesFile =
123                new File( request.getProject().getBuild().getDirectory(), "maven-plugin-help.properties" );
124            if ( tmpPropertiesFile.exists() )
125            {
126                tmpPropertiesFile.delete();
127            }
128            else
129            {
130                if ( !tmpPropertiesFile.getParentFile().exists() )
131                {
132                    tmpPropertiesFile.getParentFile().mkdirs();
133                }
134            }
135            FileOutputStream fos = null;
136            try
137            {
138                fos = new FileOutputStream( tmpPropertiesFile );
139                properties.store( fos, "maven plugin help generation informations" );
140            }
141            catch ( IOException e )
142            {
143                throw new GeneratorException( e.getMessage(), e );
144            }
145            finally
146            {
147                IOUtil.close( fos );
148            }
149    
150            String sourcePath = helpImplementation.replace( '.', File.separatorChar ) + ".java";
151            File helpClass = new File( destinationDirectory, sourcePath );
152            helpClass.getParentFile().mkdirs();
153    
154            Writer writer = null;
155            try
156            {
157                writer = new OutputStreamWriter( new FileOutputStream( helpClass ), request.getEncoding() );
158                writer.write( getHelpClassSources( propertiesFilePath ) );
159                writer.flush();
160            }
161            catch ( IOException e )
162            {
163                throw new GeneratorException( e.getMessage(), e );
164            }
165            finally
166            {
167                IOUtil.close( writer );
168            }
169        }
170    
171        public PluginHelpGenerator setHelpPackageName( String helpPackageName )
172        {
173            this.helpPackageName = helpPackageName;
174            return this;
175        }
176    
177        public VelocityComponent getVelocityComponent()
178        {
179            return velocityComponent;
180        }
181    
182        public PluginHelpGenerator setVelocityComponent( VelocityComponent velocityComponent )
183        {
184            this.velocityComponent = velocityComponent;
185            return this;
186        }
187    
188        // ----------------------------------------------------------------------
189        // Private methods
190        // ----------------------------------------------------------------------
191    
192        protected String getHelpClassSources( String propertiesFilePath )
193        {
194            Properties properties = new Properties();
195            VelocityContext context = new VelocityContext( properties );
196            if ( this.helpPackageName != null )
197            {
198                properties.put( "helpPackageName", this.helpPackageName );
199            }
200            else
201            {
202                properties.put( "helpPackageName", "" );
203            }
204            properties.put( "pluginHelpPath", propertiesFilePath + "/plugin-help.xml" );
205            // FIXME encoding !
206    
207            StringWriter stringWriter = new StringWriter();
208    
209            InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream( "help-class-source.vm" );
210            InputStreamReader isReader = new InputStreamReader( is );
211            velocityComponent.getEngine().evaluate( context, stringWriter, "", isReader );
212    
213            return stringWriter.toString();
214        }
215    
216    
217        /**
218         * @param pluginDescriptor The descriptor of the plugin for which to generate a help goal, must not be
219         *                         <code>null</code>.
220         * @return The implementation.
221         */
222        private String getImplementation( PluginDescriptor pluginDescriptor )
223        {
224            String packageName = helpPackageName;
225            if ( StringUtils.isEmpty( packageName ) )
226            {
227                packageName = GeneratorUtils.discoverPackageName( pluginDescriptor );
228            }
229    
230            return StringUtils.isEmpty( packageName ) ? HELP_MOJO_CLASS_NAME : packageName + '.' + HELP_MOJO_CLASS_NAME;
231        }
232    }