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 }