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.ui;
21  
22  import org.apache.maven.archetype.common.ArchetypeConfiguration;
23  import org.apache.maven.archetype.common.ArchetypeDefinition;
24  import org.apache.maven.archetype.common.ArchetypeFilesResolver;
25  import org.apache.maven.archetype.common.Constants;
26  import org.apache.maven.archetype.exception.ArchetypeNotConfigured;
27  import org.apache.maven.archetype.exception.ArchetypeNotDefined;
28  import org.apache.maven.archetype.exception.TemplateCreationException;
29  import org.apache.maven.project.MavenProject;
30  import org.codehaus.plexus.components.interactivity.PrompterException;
31  import org.codehaus.plexus.logging.AbstractLogEnabled;
32  import org.codehaus.plexus.util.StringUtils;
33  
34  import java.io.File;
35  import java.io.FileInputStream;
36  import java.io.FileNotFoundException;
37  import java.io.FileOutputStream;
38  import java.io.IOException;
39  import java.io.InputStream;
40  import java.io.OutputStream;
41  import java.util.ArrayList;
42  import java.util.Iterator;
43  import java.util.List;
44  import java.util.Properties;
45  import org.codehaus.plexus.util.IOUtil;
46  
47  /** @plexus.component */
48  public class DefaultArchetypeCreationConfigurator
49      extends AbstractLogEnabled
50      implements ArchetypeCreationConfigurator
51  {
52      /** @plexus.requirement */
53      private ArchetypeCreationQueryer archetypeCreationQueryer;
54  
55      /** @plexus.requirement */
56      private ArchetypeFactory archetypeFactory;
57  
58      /** @plexus.requirement */
59      private ArchetypeFilesResolver archetypeFilesResolver;
60  
61      public Properties configureArchetypeCreation( MavenProject project, Boolean interactiveMode,
62                                                    Properties commandLineProperties, File propertyFile, List languages )
63          throws IOException, ArchetypeNotDefined, ArchetypeNotConfigured, PrompterException, TemplateCreationException
64      {
65          Properties properties = initialiseArchetypeProperties( commandLineProperties, propertyFile );
66  
67          ArchetypeDefinition archetypeDefinition = archetypeFactory.createArchetypeDefinition( properties );
68  
69          if ( !archetypeDefinition.isDefined() )
70          {
71              archetypeDefinition = defineDefaultArchetype( project, properties );
72          }
73  
74          ArchetypeConfiguration archetypeConfiguration =
75              archetypeFactory.createArchetypeConfiguration( project, archetypeDefinition, properties );
76  
77          String resolvedPackage = archetypeFilesResolver.resolvePackage( project.getBasedir(), languages );
78  
79          if ( !archetypeConfiguration.isConfigured() )
80          {
81              archetypeConfiguration =
82                  defineDefaultConfiguration( project, archetypeDefinition, resolvedPackage, properties );
83          }
84  
85          if ( interactiveMode.booleanValue() )
86          {
87              getLogger().debug( "Entering interactive mode" );
88  
89              boolean confirmed = false;
90              while ( !confirmed )
91              {
92                  if ( !archetypeDefinition.isDefined() )// <editor-fold text="...">
93                  {
94                      getLogger().debug( "Archetype is yet not defined" );
95                      if ( !archetypeDefinition.isGroupDefined() )
96                      {
97                          getLogger().debug( "Asking for archetype's groupId" );
98                          archetypeDefinition.setGroupId( archetypeCreationQueryer.getArchetypeGroupId( project.getGroupId() ) );
99                      }
100                     if ( !archetypeDefinition.isArtifactDefined() )
101                     {
102                         getLogger().debug( "Asking for archetype's artifactId" );
103                         archetypeDefinition.setArtifactId( archetypeCreationQueryer.getArchetypeArtifactId( project.getArtifactId()
104                             + Constants.ARCHETYPE_SUFFIX ) );
105                     }
106                     if ( !archetypeDefinition.isVersionDefined() )
107                     {
108                         getLogger().debug( "Asking for archetype's version" );
109                         archetypeDefinition.setVersion( archetypeCreationQueryer.getArchetypeVersion( project.getVersion() ) );
110                     }
111 
112                     archetypeFactory.updateArchetypeConfiguration( archetypeConfiguration, archetypeDefinition );
113                 }// </editor-fold>
114 
115                 if ( !archetypeConfiguration.isConfigured() )// <editor-fold text="...">
116                 {
117                     getLogger().debug( "Archetype is not yet configured" );
118                     if ( !archetypeConfiguration.isConfigured( Constants.GROUP_ID ) )
119                     {
120                         getLogger().debug( "Asking for project's groupId" );
121                         archetypeConfiguration.setProperty(
122                                                             Constants.GROUP_ID,
123                                                             archetypeCreationQueryer.getGroupId( archetypeConfiguration.getDefaultValue( Constants.GROUP_ID ) ) );
124                     }
125                     if ( !archetypeConfiguration.isConfigured( Constants.ARTIFACT_ID ) )
126                     {
127                         getLogger().debug( "Asking for project's artifactId" );
128                         archetypeConfiguration.setProperty(
129                                                             Constants.ARTIFACT_ID,
130                                                             archetypeCreationQueryer.getArtifactId( archetypeConfiguration.getDefaultValue( Constants.ARTIFACT_ID ) ) );
131                     }
132                     if ( !archetypeConfiguration.isConfigured( Constants.VERSION ) )
133                     {
134                         getLogger().debug( "Asking for project's version" );
135                         archetypeConfiguration.setProperty(
136                                                             Constants.VERSION,
137                                                             archetypeCreationQueryer.getVersion( archetypeConfiguration.getDefaultValue( Constants.VERSION ) ) );
138                     }
139                     if ( !archetypeConfiguration.isConfigured( Constants.PACKAGE ) )
140                     {
141                         getLogger().debug( "Asking for project's package" );
142                         archetypeConfiguration.setProperty(
143                                                             Constants.PACKAGE,
144                                                             archetypeCreationQueryer.getPackage( StringUtils.isEmpty( resolvedPackage ) ? archetypeConfiguration.getDefaultValue( Constants.PACKAGE )
145                                                                             : resolvedPackage ) );
146                     }
147                 }// </editor-fold>
148 
149                 boolean stopAddingProperties = false;
150                 while ( !stopAddingProperties )
151                 {
152                     getLogger().debug( "Asking for another required property" );
153                     stopAddingProperties = !archetypeCreationQueryer.askAddAnotherProperty();
154 
155                     if ( !stopAddingProperties )
156                     {
157                         getLogger().debug( "Asking for required property key" );
158 
159                         String propertyKey = archetypeCreationQueryer.askNewPropertyKey();
160                         getLogger().debug( "Asking for required property value" );
161 
162                         String replacementValue =
163                             archetypeCreationQueryer.askReplacementValue(
164                                                                           propertyKey,
165                                                                           archetypeConfiguration.getDefaultValue( propertyKey ) );
166                         archetypeConfiguration.setDefaultProperty( propertyKey, replacementValue );
167                         archetypeConfiguration.setProperty( propertyKey, replacementValue );
168                     }
169                 }
170 
171                 getLogger().debug( "Asking for configuration confirmation" );
172                 if ( archetypeCreationQueryer.confirmConfiguration( archetypeConfiguration ) )
173                 {
174                     confirmed = true;
175                 }
176                 else
177                 {
178                     getLogger().debug( "Reseting archetype's definition and configuration" );
179                     archetypeConfiguration.reset();
180                     archetypeDefinition.reset();
181                 }
182             } // end while
183         }
184         else
185         {
186             getLogger().debug( "Entering batch mode" );
187             if ( !archetypeDefinition.isDefined() )
188             {
189                 throw new ArchetypeNotDefined( "The archetype is not defined" );
190             }
191             else if ( !archetypeConfiguration.isConfigured() )
192             {
193                 throw new ArchetypeNotConfigured( "The archetype is not configured", null );
194             }
195         } // end if
196 
197         return archetypeConfiguration.toProperties();
198     }
199 
200     private ArchetypeDefinition defineDefaultArchetype( MavenProject project, Properties properties )
201     {
202         if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_GROUP_ID ) ) )
203         {
204             properties.setProperty( Constants.ARCHETYPE_GROUP_ID, project.getGroupId() );
205         }
206         if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_ARTIFACT_ID ) ) )
207         {
208             properties.setProperty( Constants.ARCHETYPE_ARTIFACT_ID, project.getArtifactId()
209                 + Constants.ARCHETYPE_SUFFIX );
210         }
211         if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_VERSION ) ) )
212         {
213             properties.setProperty( Constants.ARCHETYPE_VERSION, project.getVersion() );
214         }
215 
216         return archetypeFactory.createArchetypeDefinition( properties );
217     }
218 
219     private ArchetypeConfiguration defineDefaultConfiguration( MavenProject project,
220                                                                ArchetypeDefinition archetypeDefinition,
221                                                                String resolvedPackage, Properties properties )
222     {
223         if ( StringUtils.isEmpty( properties.getProperty( Constants.GROUP_ID ) ) )
224         {
225             getLogger().info( "Setting default groupId: " + project.getGroupId() );
226             properties.setProperty( Constants.GROUP_ID, project.getGroupId() );
227         }
228 
229         if ( StringUtils.isEmpty( properties.getProperty( Constants.ARTIFACT_ID ) ) )
230         {
231             getLogger().info( "Setting default artifactId: " + project.getArtifactId() );
232             properties.setProperty( Constants.ARTIFACT_ID, project.getArtifactId() );
233         }
234 
235         if ( StringUtils.isEmpty( properties.getProperty( Constants.VERSION ) ) )
236         {
237             getLogger().info( "Setting default version: " + project.getVersion() );
238             properties.setProperty( Constants.VERSION, project.getVersion() );
239         }
240 
241         if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_GROUP_ID ) ) )
242         {
243             getLogger().info( "Setting default archetype's groupId: " + project.getGroupId() );
244             properties.setProperty( Constants.ARCHETYPE_GROUP_ID, project.getGroupId() );
245         }
246 
247         if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_ARTIFACT_ID ) ) )
248         {
249             getLogger().info( "Setting default archetype's artifactId: " + project.getArtifactId() );
250             properties.setProperty( Constants.ARCHETYPE_ARTIFACT_ID, project.getArtifactId()
251                 + Constants.ARCHETYPE_SUFFIX );
252         }
253 
254         if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_VERSION ) ) )
255         {
256             getLogger().info( "Setting default archetype's version: " + project.getVersion() );
257             properties.setProperty( Constants.ARCHETYPE_VERSION, project.getVersion() );
258         }
259 
260         if ( StringUtils.isEmpty( properties.getProperty( Constants.PACKAGE /*, properties.getProperty ( Constants.PACKAGE_NAME ) */ ) ) )
261         {
262             if ( StringUtils.isEmpty( resolvedPackage ) )
263             {
264                 resolvedPackage = project.getGroupId();
265             }
266             getLogger().info( "Setting default package: " + resolvedPackage );
267             /* properties.setProperty ( Constants.PACKAGE_NAME, resolvedPackage ); */
268             properties.setProperty( Constants.PACKAGE, resolvedPackage );
269         }
270 
271         return archetypeFactory.createArchetypeConfiguration( project, archetypeDefinition, properties );
272     }
273 
274     public void readProperties( Properties properties, File propertyFile )
275         throws IOException
276     {
277         getLogger().debug( "Reading property file " + propertyFile );
278 
279         InputStream is = new FileInputStream( propertyFile );
280 
281         try
282         {
283             properties.load( is );
284 
285             getLogger().debug( "Read " + properties.size() + " properties" );
286         }
287         finally
288         {
289             IOUtil.close( is );
290         }
291     }
292 
293     public void writeProperties( Properties properties, File propertyFile )
294         throws IOException
295     {
296         Properties storedProperties = new Properties();
297         try
298         {
299             readProperties( storedProperties, propertyFile );
300         }
301         catch ( FileNotFoundException ex )
302         {
303             getLogger().debug( "Property file not found. Creating a new one" );
304         }
305 
306         getLogger().debug( "Adding " + properties.size() + " properties" );
307 
308         Iterator propertiesIterator = properties.keySet().iterator();
309         while ( propertiesIterator.hasNext() )
310         {
311             String propertyKey = (String) propertiesIterator.next();
312             storedProperties.setProperty( propertyKey, properties.getProperty( propertyKey ) );
313         }
314 
315         OutputStream os = new FileOutputStream( propertyFile );
316 
317         try
318         {
319             storedProperties.store( os, "" );
320 
321             getLogger().debug( "Stored " + storedProperties.size() + " properties" );
322         }
323         finally
324         {
325             IOUtil.close( os );
326         }
327     }
328 
329     private Properties initialiseArchetypeProperties( Properties commandLineProperties, File propertyFile )
330         throws IOException
331     {
332         Properties properties = new Properties();
333 
334         if ( propertyFile != null )
335         {
336             try
337             {
338                 readProperties( properties, propertyFile );
339             }
340             catch ( FileNotFoundException ex )
341             {
342                 getLogger().debug( "archetype.properties does not exist" );
343             }
344         }
345 
346         return properties;
347     }
348 
349     private Properties removeDottedProperties( Properties properties )
350     {
351         List toRemove = new ArrayList( 0 );
352 
353         for ( Iterator keys = properties.keySet().iterator(); keys.hasNext(); )
354         {
355             String key = (String) keys.next();
356             if ( key.indexOf( "." ) >= 0 )
357             {
358                 toRemove.add( key );
359             }
360         }
361 
362         for ( Iterator keysToRemove = toRemove.iterator(); keysToRemove.hasNext(); )
363         {
364             String key = (String) keysToRemove.next();
365 
366             properties.remove( key );
367         }
368         return properties;
369     }
370 }