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(
62 MavenProject project,
63 Boolean interactiveMode,
64 Properties commandLineProperties,
65 File propertyFile,
66 List languages
67 )
68 throws
69 IOException,
70 ArchetypeNotDefined,
71 ArchetypeNotConfigured,
72 PrompterException,
73 TemplateCreationException
74 {
75 Properties properties =
76 initialiseArchetypeProperties( commandLineProperties, propertyFile );
77
78 ArchetypeDefinition archetypeDefinition =
79 archetypeFactory.createArchetypeDefinition( properties );
80
81 if ( !archetypeDefinition.isDefined() )
82 {
83 archetypeDefinition = defineDefaultArchetype( project, properties );
84 }
85
86 ArchetypeConfiguration archetypeConfiguration =
87 archetypeFactory.createArchetypeConfiguration(
88 project,
89 archetypeDefinition,
90 properties
91 );
92
93 String resolvedPackage =
94 archetypeFilesResolver.resolvePackage( project.getBasedir(), languages );
95
96 if ( !archetypeConfiguration.isConfigured() )
97 {
98 archetypeConfiguration =
99 defineDefaultConfiguration(
100 project,
101 archetypeDefinition,
102 resolvedPackage,
103 properties
104 );
105 }
106
107 if ( interactiveMode.booleanValue() )
108 {
109 getLogger().debug( "Entering interactive mode" );
110
111 boolean confirmed = false;
112 while ( !confirmed )
113 {
114 if ( !archetypeDefinition.isDefined() )
115 {
116 getLogger().debug( "Archetype is yet not defined" );
117 if ( !archetypeDefinition.isGroupDefined() )
118 {
119 getLogger().debug( "Asking for archetype's groupId" );
120 archetypeDefinition.setGroupId(
121 archetypeCreationQueryer.getArchetypeGroupId( project.getGroupId() )
122 );
123 }
124 if ( !archetypeDefinition.isArtifactDefined() )
125 {
126 getLogger().debug( "Asking for archetype's artifactId" );
127 archetypeDefinition.setArtifactId(
128 archetypeCreationQueryer.getArchetypeArtifactId(
129 project.getArtifactId() + Constants.ARCHETYPE_SUFFIX
130 )
131 );
132 }
133 if ( !archetypeDefinition.isVersionDefined() )
134 {
135 getLogger().debug( "Asking for archetype's version" );
136 archetypeDefinition.setVersion(
137 archetypeCreationQueryer.getArchetypeVersion( project.getVersion() )
138 );
139 }
140
141 archetypeFactory.updateArchetypeConfiguration(
142 archetypeConfiguration,
143 archetypeDefinition
144 );
145 }
146
147 if ( !archetypeConfiguration.isConfigured() )
148 {
149 getLogger().debug( "Archetype is not yet configured" );
150 if ( !archetypeConfiguration.isConfigured( Constants.GROUP_ID ) )
151 {
152 getLogger().debug( "Asking for project's groupId" );
153 archetypeConfiguration.setProperty(
154 Constants.GROUP_ID,
155 archetypeCreationQueryer.getGroupId(
156 archetypeConfiguration.getDefaultValue( Constants.GROUP_ID )
157 )
158 );
159 }
160 if ( !archetypeConfiguration.isConfigured( Constants.ARTIFACT_ID ) )
161 {
162 getLogger().debug( "Asking for project's artifactId" );
163 archetypeConfiguration.setProperty(
164 Constants.ARTIFACT_ID,
165 archetypeCreationQueryer.getArtifactId(
166 archetypeConfiguration.getDefaultValue( Constants.ARTIFACT_ID )
167 )
168 );
169 }
170 if ( !archetypeConfiguration.isConfigured( Constants.VERSION ) )
171 {
172 getLogger().debug( "Asking for project's version" );
173 archetypeConfiguration.setProperty(
174 Constants.VERSION,
175 archetypeCreationQueryer.getVersion(
176 archetypeConfiguration.getDefaultValue( Constants.VERSION )
177 )
178 );
179 }
180 if ( !archetypeConfiguration.isConfigured( Constants.PACKAGE ) )
181 {
182 getLogger().debug( "Asking for project's package" );
183 archetypeConfiguration.setProperty(
184 Constants.PACKAGE,
185 archetypeCreationQueryer.getPackage(
186 StringUtils.isEmpty( resolvedPackage )
187 ? archetypeConfiguration.getDefaultValue( Constants.PACKAGE )
188 : resolvedPackage
189 )
190 );
191 }
192 }
193
194 boolean stopAddingProperties = false;
195 while ( !stopAddingProperties )
196 {
197 getLogger().debug( "Asking for another required property" );
198 stopAddingProperties = !archetypeCreationQueryer.askAddAnotherProperty();
199
200 if ( !stopAddingProperties )
201 {
202 getLogger().debug( "Asking for required property key" );
203
204 String propertyKey = archetypeCreationQueryer.askNewPropertyKey();
205 getLogger().debug( "Asking for required property value" );
206
207 String replacementValue =
208 archetypeCreationQueryer.askReplacementValue(
209 propertyKey,
210 archetypeConfiguration.getDefaultValue( propertyKey )
211 );
212 archetypeConfiguration.setDefaultProperty( propertyKey, replacementValue );
213 archetypeConfiguration.setProperty( propertyKey, replacementValue );
214 }
215 }
216
217 getLogger().debug( "Asking for configuration confirmation" );
218 if ( archetypeCreationQueryer.confirmConfiguration( archetypeConfiguration ) )
219 {
220 confirmed = true;
221 }
222 else
223 {
224 getLogger().debug( "Reseting archetype's definition and configuration" );
225 archetypeConfiguration.reset();
226 archetypeDefinition.reset();
227 }
228 }
229 }
230 else
231 {
232 getLogger().debug( "Entering batch mode" );
233 if ( !archetypeDefinition.isDefined() )
234 {
235 throw new ArchetypeNotDefined( "The archetype is not defined" );
236 }
237 else if ( !archetypeConfiguration.isConfigured() )
238 {
239 throw new ArchetypeNotConfigured( "The archetype is not configured", null );
240 }
241 }
242
243 return archetypeConfiguration.toProperties();
244 }
245
246 private ArchetypeDefinition defineDefaultArchetype(
247 MavenProject project,
248 Properties properties
249 )
250 {
251 if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_GROUP_ID ) ) )
252 {
253 properties.setProperty( Constants.ARCHETYPE_GROUP_ID, project.getGroupId() );
254 }
255 if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_ARTIFACT_ID ) ) )
256 {
257 properties.setProperty(
258 Constants.ARCHETYPE_ARTIFACT_ID,
259 project.getArtifactId() + Constants.ARCHETYPE_SUFFIX
260 );
261 }
262 if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_VERSION ) ) )
263 {
264 properties.setProperty( Constants.ARCHETYPE_VERSION, project.getVersion() );
265 }
266
267 return archetypeFactory.createArchetypeDefinition( properties );
268 }
269
270 private ArchetypeConfiguration defineDefaultConfiguration(
271 MavenProject project,
272 ArchetypeDefinition archetypeDefinition,
273 String resolvedPackage,
274 Properties properties
275 )
276 {
277 if ( StringUtils.isEmpty( properties.getProperty( Constants.GROUP_ID ) ) )
278 {
279 getLogger().info( "Setting default groupId: " + project.getGroupId() );
280 properties.setProperty( Constants.GROUP_ID, project.getGroupId() );
281 }
282
283 if ( StringUtils.isEmpty( properties.getProperty( Constants.ARTIFACT_ID ) ) )
284 {
285 getLogger().info( "Setting default artifactId: " + project.getArtifactId() );
286 properties.setProperty( Constants.ARTIFACT_ID, project.getArtifactId() );
287 }
288
289 if ( StringUtils.isEmpty( properties.getProperty( Constants.VERSION ) ) )
290 {
291 getLogger().info( "Setting default version: " + project.getVersion() );
292 properties.setProperty( Constants.VERSION, project.getVersion() );
293 }
294
295 if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_GROUP_ID ) ) )
296 {
297 getLogger().info( "Setting default archetype's groupId: " + project.getGroupId() );
298 properties.setProperty( Constants.ARCHETYPE_GROUP_ID, project.getGroupId() );
299 }
300
301 if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_ARTIFACT_ID ) ) )
302 {
303 getLogger().info( "Setting default archetype's artifactId: " + project.getArtifactId() );
304 properties.setProperty( Constants.ARCHETYPE_ARTIFACT_ID, project.getArtifactId()+Constants.ARCHETYPE_SUFFIX );
305 }
306
307 if ( StringUtils.isEmpty( properties.getProperty( Constants.ARCHETYPE_VERSION ) ) )
308 {
309 getLogger().info( "Setting default archetype's version: " + project.getVersion() );
310 properties.setProperty( Constants.ARCHETYPE_VERSION, project.getVersion() );
311 }
312
313 if ( StringUtils.isEmpty(
314 properties.getProperty(
315 Constants.PACKAGE
316
317 )
318 )
319 )
320 {
321 if ( StringUtils.isEmpty( resolvedPackage ) )
322 {
323 resolvedPackage = project.getGroupId();
324 }
325 getLogger().info( "Setting default package: " + resolvedPackage );
326
327 properties.setProperty( Constants.PACKAGE, resolvedPackage );
328 }
329
330 return
331 archetypeFactory.createArchetypeConfiguration(
332 project,
333 archetypeDefinition,
334 properties
335 );
336 }
337
338 public void readProperties( Properties properties,
339 File propertyFile )
340 throws
341 IOException
342 {
343 getLogger().debug( "Reading property file " + propertyFile );
344
345 InputStream is = new FileInputStream( propertyFile );
346
347 try
348 {
349 properties.load( is );
350
351 getLogger().debug( "Read " + properties.size() + " properties" );
352 }
353 finally
354 {
355 IOUtil.close( is );
356 }
357 }
358
359 public void writeProperties( Properties properties,
360 File propertyFile )
361 throws
362 IOException
363 {
364 Properties storedProperties = new Properties();
365 try
366 {
367 readProperties( storedProperties, propertyFile );
368 }
369 catch ( FileNotFoundException ex )
370 {
371 getLogger().debug( "Property file not found. Creating a new one" );
372 }
373
374 getLogger().debug( "Adding " + properties.size() + " properties" );
375
376 Iterator propertiesIterator = properties.keySet().iterator();
377 while ( propertiesIterator.hasNext() )
378 {
379 String propertyKey = (String) propertiesIterator.next();
380 storedProperties.setProperty( propertyKey, properties.getProperty( propertyKey ) );
381 }
382
383 OutputStream os = new FileOutputStream( propertyFile );
384
385 try
386 {
387 storedProperties.store( os, "" );
388
389 getLogger().debug( "Stored " + storedProperties.size() + " properties" );
390 }
391 finally
392 {
393 IOUtil.close( os );
394 }
395 }
396
397 private Properties initialiseArchetypeProperties(
398 Properties commandLineProperties,
399 File propertyFile
400 )
401 throws
402 IOException
403 {
404 Properties properties = new Properties();
405
406 if ( propertyFile != null )
407 {
408 try
409 {
410 readProperties( properties, propertyFile );
411 }
412 catch ( FileNotFoundException ex )
413 {
414 getLogger().debug( "archetype.properties does not exist" );
415 }
416 }
417
418 return properties;
419 }
420
421 private Properties removeDottedProperties(Properties properties) {
422 List toRemove=new ArrayList(0);
423 Iterator keys = properties.keySet().iterator();
424 while (keys.hasNext())
425 {
426 String key = (String) keys.next();
427 if (key.indexOf(".")>=0)
428 {
429 toRemove.add(key);
430 }
431 }
432 Iterator keysToRemove =toRemove.iterator();
433 while(keysToRemove.hasNext())
434 {
435 String key = (String) keysToRemove.next();
436 properties.remove(key);
437 }
438 return properties;
439
440
441 }
442 }