View Javadoc
1   package org.apache.maven.archetype.ui.creation;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.FileInputStream;
24  import java.io.FileNotFoundException;
25  import java.io.FileOutputStream;
26  import java.io.IOException;
27  import java.io.InputStream;
28  import java.io.OutputStream;
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.Properties;
32  
33  import org.apache.maven.archetype.common.ArchetypeFilesResolver;
34  import org.apache.maven.archetype.common.Constants;
35  import org.apache.maven.archetype.exception.ArchetypeNotConfigured;
36  import org.apache.maven.archetype.exception.ArchetypeNotDefined;
37  import org.apache.maven.archetype.exception.TemplateCreationException;
38  import org.apache.maven.archetype.ui.ArchetypeConfiguration;
39  import org.apache.maven.archetype.ui.ArchetypeDefinition;
40  import org.apache.maven.archetype.ui.ArchetypeFactory;
41  import org.apache.maven.project.MavenProject;
42  import org.codehaus.plexus.component.annotations.Component;
43  import org.codehaus.plexus.component.annotations.Requirement;
44  import org.codehaus.plexus.components.interactivity.PrompterException;
45  import org.codehaus.plexus.logging.AbstractLogEnabled;
46  import org.codehaus.plexus.util.StringUtils;
47  
48  @Component( role = ArchetypeCreationConfigurator.class, hint = "default" )
49  public class DefaultArchetypeCreationConfigurator
50      extends AbstractLogEnabled
51      implements ArchetypeCreationConfigurator
52  {
53      @Requirement
54      private ArchetypeCreationQueryer archetypeCreationQueryer;
55  
56      @Requirement
57      private ArchetypeFactory archetypeFactory;
58  
59      @Requirement
60      private ArchetypeFilesResolver archetypeFilesResolver;
61  
62      @Override
63      public Properties configureArchetypeCreation( MavenProject project, Boolean interactiveMode,
64                                                    Properties commandLineProperties, File propertyFile,
65                                                    List<String> languages )
66          throws IOException, ArchetypeNotDefined, ArchetypeNotConfigured, PrompterException, TemplateCreationException
67      {
68          Properties properties = initialiseArchetypeProperties( commandLineProperties, propertyFile );
69  
70          ArchetypeDefinition archetypeDefinition = archetypeFactory.createArchetypeDefinition( properties );
71  
72          if ( !archetypeDefinition.isDefined() )
73          {
74              archetypeDefinition = defineDefaultArchetype( project, properties );
75          }
76  
77          ArchetypeConfiguration archetypeConfiguration =
78              archetypeFactory.createArchetypeConfiguration( project, archetypeDefinition, properties );
79  
80          String resolvedPackage = archetypeFilesResolver.resolvePackage( project.getBasedir(), languages );
81  
82          if ( !archetypeConfiguration.isConfigured() )
83          {
84              archetypeConfiguration =
85                  defineDefaultConfiguration( project, archetypeDefinition, resolvedPackage, properties );
86          }
87  
88          if ( interactiveMode.booleanValue() )
89          {
90              getLogger().debug( "Entering interactive mode" );
91  
92              boolean confirmed = false;
93              while ( !confirmed )
94              {
95                  if ( !archetypeDefinition.isDefined() )// <editor-fold text="...">
96                  {
97                      getLogger().debug( "Archetype is yet not defined" );
98                      if ( !archetypeDefinition.isGroupDefined() )
99                      {
100                         getLogger().debug( "Asking for archetype's groupId" );
101                         archetypeDefinition.setGroupId( archetypeCreationQueryer.getArchetypeGroupId( project.getGroupId() ) );
102                     }
103                     if ( !archetypeDefinition.isArtifactDefined() )
104                     {
105                         getLogger().debug( "Asking for archetype's artifactId" );
106                         archetypeDefinition.setArtifactId( archetypeCreationQueryer.getArchetypeArtifactId( project.getArtifactId()
107                             + Constants.ARCHETYPE_SUFFIX ) );
108                     }
109                     if ( !archetypeDefinition.isVersionDefined() )
110                     {
111                         getLogger().debug( "Asking for archetype's version" );
112                         archetypeDefinition.setVersion( archetypeCreationQueryer.getArchetypeVersion( project.getVersion() ) );
113                     }
114 
115                     archetypeFactory.updateArchetypeConfiguration( archetypeConfiguration, archetypeDefinition );
116                 } // </editor-fold>
117 
118                 if ( !archetypeConfiguration.isConfigured() )// <editor-fold text="...">
119                 {
120                     getLogger().debug( "Archetype is not yet configured" );
121                     if ( !archetypeConfiguration.isConfigured( Constants.GROUP_ID ) )
122                     {
123                         getLogger().debug( "Asking for project's groupId" );
124                         archetypeConfiguration.setProperty(
125                                                             Constants.GROUP_ID,
126                                                             archetypeCreationQueryer.getGroupId( archetypeConfiguration.getDefaultValue( Constants.GROUP_ID ) ) );
127                     }
128                     if ( !archetypeConfiguration.isConfigured( Constants.ARTIFACT_ID ) )
129                     {
130                         getLogger().debug( "Asking for project's artifactId" );
131                         archetypeConfiguration.setProperty(
132                                                             Constants.ARTIFACT_ID,
133                                                             archetypeCreationQueryer.getArtifactId( archetypeConfiguration.getDefaultValue( Constants.ARTIFACT_ID ) ) );
134                     }
135                     if ( !archetypeConfiguration.isConfigured( Constants.VERSION ) )
136                     {
137                         getLogger().debug( "Asking for project's version" );
138                         archetypeConfiguration.setProperty(
139                                                             Constants.VERSION,
140                                                             archetypeCreationQueryer.getVersion( archetypeConfiguration.getDefaultValue( Constants.VERSION ) ) );
141                     }
142                     if ( !archetypeConfiguration.isConfigured( Constants.PACKAGE ) )
143                     {
144                         getLogger().debug( "Asking for project's package" );
145                         archetypeConfiguration.setProperty(
146                                                             Constants.PACKAGE,
147                                                             archetypeCreationQueryer.getPackage( StringUtils.isEmpty( resolvedPackage ) ? archetypeConfiguration.getDefaultValue( Constants.PACKAGE )
148                                                                             : resolvedPackage ) );
149                     }
150                 } // </editor-fold>
151 
152                 boolean stopAddingProperties = false;
153                 while ( !stopAddingProperties )
154                 {
155                     getLogger().debug( "Asking for another required property" );
156                     stopAddingProperties = !archetypeCreationQueryer.askAddAnotherProperty();
157 
158                     if ( !stopAddingProperties )
159                     {
160                         getLogger().debug( "Asking for required property key" );
161 
162                         String propertyKey = archetypeCreationQueryer.askNewPropertyKey();
163                         getLogger().debug( "Asking for required property value" );
164 
165                         String replacementValue =
166                             archetypeCreationQueryer.askReplacementValue(
167                                                                           propertyKey,
168                                                                           archetypeConfiguration.getDefaultValue( propertyKey ) );
169                         archetypeConfiguration.setDefaultProperty( propertyKey, replacementValue );
170                         archetypeConfiguration.setProperty( propertyKey, replacementValue );
171                     }
172                 }
173 
174                 getLogger().debug( "Asking for configuration confirmation" );
175                 if ( archetypeCreationQueryer.confirmConfiguration( archetypeConfiguration ) )
176                 {
177                     confirmed = true;
178                 }
179                 else
180                 {
181                     getLogger().debug( "Reseting archetype's definition and configuration" );
182                     archetypeConfiguration.reset();
183                     archetypeDefinition.reset();
184                 }
185             } // end while
186         }
187         else
188         {
189             getLogger().debug( "Entering batch mode" );
190             if ( !archetypeDefinition.isDefined() )
191             {
192                 throw new ArchetypeNotDefined( "The archetype is not defined" );
193             }
194             else if ( !archetypeConfiguration.isConfigured() )
195             {
196                 throw new ArchetypeNotConfigured( "The archetype is not configured", null );
197             }
198         } // end if
199 
200         return archetypeConfiguration.toProperties();
201     }
202 
203     private ArchetypeDefinition defineDefaultArchetype( MavenProject project, Properties properties )
204     {
205         if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_GROUP_ID ) ) )
206         {
207             properties.setProperty( Constants.ARCHETYPE_GROUP_ID, project.getGroupId() );
208         }
209         if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_ARTIFACT_ID ) ) )
210         {
211             properties.setProperty( Constants.ARCHETYPE_ARTIFACT_ID, project.getArtifactId()
212                 + Constants.ARCHETYPE_SUFFIX );
213         }
214         if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_VERSION ) ) )
215         {
216             properties.setProperty( Constants.ARCHETYPE_VERSION, project.getVersion() );
217         }
218 
219         return archetypeFactory.createArchetypeDefinition( properties );
220     }
221 
222     private ArchetypeConfiguration defineDefaultConfiguration( MavenProject project,
223                                                                ArchetypeDefinition archetypeDefinition,
224                                                                String resolvedPackage, Properties properties )
225     {
226         if ( StringUtils.isEmpty( properties.getProperty( Constants.GROUP_ID ) ) )
227         {
228             getLogger().info( "Setting default groupId: " + project.getGroupId() );
229             properties.setProperty( Constants.GROUP_ID, project.getGroupId() );
230         }
231 
232         if ( StringUtils.isEmpty( properties.getProperty( Constants.ARTIFACT_ID ) ) )
233         {
234             getLogger().info( "Setting default artifactId: " + project.getArtifactId() );
235             properties.setProperty( Constants.ARTIFACT_ID, project.getArtifactId() );
236         }
237 
238         if ( StringUtils.isEmpty( properties.getProperty( Constants.VERSION ) ) )
239         {
240             getLogger().info( "Setting default version: " + project.getVersion() );
241             properties.setProperty( Constants.VERSION, project.getVersion() );
242         }
243 
244         if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_GROUP_ID ) ) )
245         {
246             getLogger().info( "Setting default archetype's groupId: " + project.getGroupId() );
247             properties.setProperty( Constants.ARCHETYPE_GROUP_ID, project.getGroupId() );
248         }
249 
250         if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_ARTIFACT_ID ) ) )
251         {
252             getLogger().info( "Setting default archetype's artifactId: " + project.getArtifactId() );
253             properties.setProperty( Constants.ARCHETYPE_ARTIFACT_ID, project.getArtifactId()
254                 + Constants.ARCHETYPE_SUFFIX );
255         }
256 
257         if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_VERSION ) ) )
258         {
259             getLogger().info( "Setting default archetype's version: " + project.getVersion() );
260             properties.setProperty( Constants.ARCHETYPE_VERSION, project.getVersion() );
261         }
262 
263         if ( StringUtils.isEmpty( properties.getProperty( Constants.PACKAGE /*, properties.getProperty ( Constants.PACKAGE_NAME ) */ ) ) )
264         {
265             if ( StringUtils.isEmpty( resolvedPackage ) )
266             {
267                 resolvedPackage = project.getGroupId();
268             }
269             getLogger().info( "Setting default package: " + resolvedPackage );
270             /* properties.setProperty ( Constants.PACKAGE_NAME, resolvedPackage ); */
271             properties.setProperty( Constants.PACKAGE, resolvedPackage );
272         }
273 
274         return archetypeFactory.createArchetypeConfiguration( project, archetypeDefinition, properties );
275     }
276 
277     public void readProperties( Properties properties, File propertyFile )
278         throws IOException
279     {
280         getLogger().debug( "Reading property file " + propertyFile );
281 
282         try ( InputStream is = new FileInputStream( propertyFile ) ) 
283         {
284             properties.load( is );
285 
286             getLogger().debug( "Read " + properties.size() + " properties" );
287         }
288     }
289 
290     public void writeProperties( Properties properties, File propertyFile )
291         throws IOException
292     {
293         Properties storedProperties = new Properties();
294         try
295         {
296             readProperties( storedProperties, propertyFile );
297         }
298         catch ( FileNotFoundException ex )
299         {
300             getLogger().debug( "Property file not found. Creating a new one" );
301         }
302 
303         getLogger().debug( "Adding " + properties.size() + " properties" );
304 
305         Iterator<?> propertiesIterator = properties.keySet().iterator();
306         while ( propertiesIterator.hasNext() )
307         {
308             String propertyKey = (String) propertiesIterator.next();
309             storedProperties.setProperty( propertyKey, properties.getProperty( propertyKey ) );
310         }
311 
312         propertyFile.getParentFile().mkdirs();
313 
314         if ( !propertyFile.exists() && !propertyFile.createNewFile() )
315         {
316             getLogger().warn( "Could not create new file \"" + propertyFile.getPath()
317                     + "\" or the file already exists." );
318         }
319 
320         try ( OutputStream os = new FileOutputStream( propertyFile ) )
321         {
322             storedProperties.store( os, "" );
323 
324             getLogger().debug( "Stored " + storedProperties.size() + " properties" );
325         }
326     }
327 
328     private Properties initialiseArchetypeProperties( Properties commandLineProperties, File propertyFile )
329         throws IOException
330     {
331         Properties properties = new Properties();
332 
333         if ( propertyFile != null )
334         {
335             try
336             {
337                 readProperties( properties, propertyFile );
338             }
339             catch ( FileNotFoundException ex )
340             {
341                 getLogger().debug( propertyFile.getName() + "  does not exist" );
342             }
343         }
344 
345         return properties;
346     }
347 
348 }