1 package org.apache.maven.archetype.ui.creation;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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.IOUtil;
47 import org.codehaus.plexus.util.StringUtils;
48
49 @Component( role = ArchetypeCreationConfigurator.class, hint = "default" )
50 public class DefaultArchetypeCreationConfigurator
51 extends AbstractLogEnabled
52 implements ArchetypeCreationConfigurator
53 {
54 @Requirement
55 private ArchetypeCreationQueryer archetypeCreationQueryer;
56
57 @Requirement
58 private ArchetypeFactory archetypeFactory;
59
60 @Requirement
61 private ArchetypeFilesResolver archetypeFilesResolver;
62
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() )
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 }
117
118 if ( !archetypeConfiguration.isConfigured() )
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 }
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 }
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 }
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 ) ) )
264 {
265 if ( StringUtils.isEmpty( resolvedPackage ) )
266 {
267 resolvedPackage = project.getGroupId();
268 }
269 getLogger().info( "Setting default package: " + resolvedPackage );
270
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 InputStream is = new FileInputStream( propertyFile );
283
284 try
285 {
286 properties.load( is );
287
288 getLogger().debug( "Read " + properties.size() + " properties" );
289 }
290 finally
291 {
292 IOUtil.close( is );
293 }
294 }
295
296 public void writeProperties( Properties properties, File propertyFile )
297 throws IOException
298 {
299 Properties storedProperties = new Properties();
300 try
301 {
302 readProperties( storedProperties, propertyFile );
303 }
304 catch ( FileNotFoundException ex )
305 {
306 getLogger().debug( "Property file not found. Creating a new one" );
307 }
308
309 getLogger().debug( "Adding " + properties.size() + " properties" );
310
311 Iterator<?> propertiesIterator = properties.keySet().iterator();
312 while ( propertiesIterator.hasNext() )
313 {
314 String propertyKey = (String) propertiesIterator.next();
315 storedProperties.setProperty( propertyKey, properties.getProperty( propertyKey ) );
316 }
317
318 OutputStream os = new FileOutputStream( propertyFile );
319
320 try
321 {
322 storedProperties.store( os, "" );
323
324 getLogger().debug( "Stored " + storedProperties.size() + " properties" );
325 }
326 finally
327 {
328 IOUtil.close( os );
329 }
330 }
331
332 private Properties initialiseArchetypeProperties( Properties commandLineProperties, File propertyFile )
333 throws IOException
334 {
335 Properties properties = new Properties();
336
337 if ( propertyFile != null )
338 {
339 try
340 {
341 readProperties( properties, propertyFile );
342 }
343 catch ( FileNotFoundException ex )
344 {
345 getLogger().debug( "archetype.properties does not exist" );
346 }
347 }
348
349 return properties;
350 }
351
352 }