1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
48 public class DefaultArchetypeCreationConfigurator
49 extends AbstractLogEnabled
50 implements ArchetypeCreationConfigurator
51 {
52
53 private ArchetypeCreationQueryer archetypeCreationQueryer;
54
55
56 private ArchetypeFactory archetypeFactory;
57
58
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() )
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 }
114
115 if ( !archetypeConfiguration.isConfigured() )
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 }
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 }
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 }
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
261 {
262 if ( StringUtils.isEmpty( resolvedPackage ) )
263 {
264 resolvedPackage = project.getGroupId();
265 }
266 getLogger().info( "Setting default package: " + resolvedPackage );
267
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 }