View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.maven.archetype.mojos;
21  
22  import org.apache.maven.archetype.Archetype;
23  import org.apache.maven.archetype.ArchetypeGenerationRequest;
24  import org.apache.maven.archetype.ArchetypeGenerationResult;
25  import org.apache.maven.archetype.generator.ArchetypeGenerator;
26  import org.apache.maven.archetype.ui.ArchetypeGenerationConfigurator;
27  import org.apache.maven.archetype.ui.ArchetypeSelector;
28  import org.apache.maven.artifact.repository.ArtifactRepository;
29  import org.apache.maven.execution.MavenSession;
30  import org.apache.maven.plugin.AbstractMojo;
31  import org.apache.maven.plugin.ContextEnabled;
32  import org.apache.maven.plugin.MojoExecutionException;
33  import org.apache.maven.plugin.MojoFailureException;
34  import org.apache.maven.shared.invoker.DefaultInvocationRequest;
35  import org.apache.maven.shared.invoker.InvocationRequest;
36  import org.apache.maven.shared.invoker.Invoker;
37  import org.apache.maven.shared.invoker.MavenInvocationException;
38  import org.codehaus.plexus.util.StringUtils;
39  
40  import java.io.File;
41  import java.util.Arrays;
42  import java.util.List;
43  import java.util.Properties;
44  
45  /**
46   * Generates sample project from archetype.
47   *
48   * @author rafale
49   * @requiresProject false
50   * @goal generate
51   * @execute phase="generate-sources"
52   */
53  public class CreateProjectFromArchetypeMojo
54      extends AbstractMojo
55      implements ContextEnabled
56  {
57      /** @component */
58      private Archetype archetype;
59  
60      /** @component */
61      private ArchetypeSelector selector;
62  
63      /** @component */
64      ArchetypeGenerationConfigurator configurator;
65  
66      /** @component */
67      ArchetypeGenerator generator;
68  
69      /** @component */
70      private Invoker invoker;
71  
72      /**
73       * The archetype's artifactId.
74       *
75       * @parameter expression="${archetypeArtifactId}"
76       */
77      private String archetypeArtifactId;
78  
79      /**
80       * The archetype's groupId.
81       *
82       * @parameter expression="${archetypeGroupId}"
83       */
84      private String archetypeGroupId;
85  
86      /**
87       * The archetype's version.
88       *
89       * @parameter expression="${archetypeVersion}"
90       */
91      private String archetypeVersion;
92  
93      /**
94       * The archetype's repository.
95       *
96       * @parameter expression="${archetypeRepository}"
97       */
98      private String archetypeRepository;
99  
100     /**
101      * The archetype's catalogs.
102      * It is a comma separated list of catalogs.
103      * Catalogs use scheme:
104      * - 'file://...' with archetype-catalog.xml automatically appended when defining a directory
105      * - 'http://...' with archetype-catalog.xml always appended
106      * - 'local' which is the shortcut for 'file://~/.m2/archetype-catalog.xml'
107      * - 'remote' which is the shortcut for 'http://repo1.maven.org/maven2'
108      * - 'internal' which is an internal catalog
109      *
110      * @parameter expression="${archetypeCatalog}" default-value="internal"
111      */
112     private String archetypeCatalog;
113 
114     /**
115      * Local maven repository.
116      *
117      * @parameter expression="${localRepository}"
118      * @required
119      * @readonly
120      */
121     private ArtifactRepository localRepository;
122     
123     /**
124      * List of Remote Repositories used by the resolver.
125      *
126      * @parameter  expression="${project.remoteArtifactRepositories}"
127      * @readonly
128      * @required
129      */
130     private List remoteArtifactRepositories;
131         
132     /**
133      * User settings use to check the interactiveMode.
134      *
135      * @parameter expression="${archetype.interactive}" default-value="${settings.interactiveMode}"
136      * @required
137      */
138     private Boolean interactiveMode;
139 
140     /** @parameter expression="${basedir}" */
141     private File basedir;
142 
143     /** 
144      *  @parameter expression="${session}" 
145      *  @readonly
146      */
147     private MavenSession session;
148     /**
149      * Additional goals that can be specified by the user during the creation of the archetype.
150      *
151      * @parameter expression="${goals}"
152      */
153     private String goals;
154 
155     public void execute()
156         throws MojoExecutionException, MojoFailureException
157     {        
158         Properties executionProperties = session.getExecutionProperties();
159         
160         ArchetypeGenerationRequest request = new ArchetypeGenerationRequest()
161             .setArchetypeGroupId( archetypeGroupId )
162             .setArchetypeArtifactId( archetypeArtifactId )
163             .setArchetypeVersion( archetypeVersion )
164             .setOutputDirectory( basedir.getAbsolutePath() )
165             .setLocalRepository( localRepository )
166             .setArchetypeRepository(archetypeRepository)
167             .setRemoteArtifactRepositories(remoteArtifactRepositories);
168 
169         try
170         {
171             if( interactiveMode.booleanValue() )
172             {
173                 getLog().info( "Generating project in Interactive mode" );
174             }
175             else
176             {
177                 getLog().info( "Generating project in Batch mode" );
178             }
179             
180             selector.selectArchetype( request, interactiveMode, archetypeCatalog );
181 
182             // TODO: it's confusing that request has fields that get populated but not accepted as input (eg, groupId)
183             configurator.configureArchetype( request, interactiveMode, executionProperties );
184 
185             ArchetypeGenerationResult generationResult =
186                 archetype.generateProjectFromArchetype( request );
187             if( generationResult.getCause() != null )
188             {
189                 throw new MojoFailureException(
190                     generationResult.getCause(),
191                     generationResult.getCause().getMessage(),
192                     generationResult.getCause().getMessage()
193                 );
194             }
195         }
196         catch ( MojoFailureException ex )
197         {
198             throw ex;
199         }
200         catch ( Exception ex )
201         {
202             throw new MojoFailureException( ex, ex.getMessage(), ex.getMessage() );
203         }
204 
205         String artifactId = request.getArtifactId();
206 
207         String postArchetypeGenerationGoals = request.getArchetypeGoals();
208 
209         if ( StringUtils.isEmpty( postArchetypeGenerationGoals ) )
210         {
211             postArchetypeGenerationGoals = goals;
212         }
213 
214         if ( StringUtils.isNotEmpty( postArchetypeGenerationGoals ) )
215         {
216             invokePostArchetypeGenerationGoals( postArchetypeGenerationGoals, artifactId );
217         }
218     }
219 
220     private void invokePostArchetypeGenerationGoals( String goals, String artifactId )
221         throws MojoExecutionException, MojoFailureException
222     {
223         File projectBasedir = new File( basedir, artifactId );
224 
225         if ( projectBasedir.exists() )
226         {
227             InvocationRequest request = new DefaultInvocationRequest()
228                 .setBaseDirectory( projectBasedir )
229                 .setGoals( Arrays.asList( StringUtils.split( goals, "," ) ) );
230 
231             try
232             {
233                 invoker.execute( request );
234             }
235             catch ( MavenInvocationException e )
236             {
237                 throw new MojoExecutionException( "Cannot run additions goals." );
238             }
239         }
240     }
241 }