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 }