1 package org.apache.maven.archetype.ui.generation;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.archetype.ArchetypeGenerationRequest;
23 import org.apache.maven.archetype.common.ArchetypeArtifactManager;
24 import org.apache.maven.archetype.common.ArchetypeRegistryManager;
25 import org.apache.maven.archetype.common.Constants;
26 import org.apache.maven.archetype.exception.ArchetypeGenerationConfigurationFailure;
27 import org.apache.maven.archetype.exception.ArchetypeNotConfigured;
28 import org.apache.maven.archetype.exception.ArchetypeNotDefined;
29 import org.apache.maven.archetype.exception.UnknownArchetype;
30 import org.apache.maven.archetype.old.OldArchetype;
31 import org.apache.maven.archetype.ui.ArchetypeConfiguration;
32 import org.apache.maven.archetype.ui.ArchetypeDefinition;
33 import org.apache.maven.archetype.ui.ArchetypeFactory;
34 import org.apache.maven.artifact.repository.ArtifactRepository;
35
36 import org.codehaus.plexus.component.annotations.Component;
37 import org.codehaus.plexus.component.annotations.Requirement;
38 import org.codehaus.plexus.components.interactivity.PrompterException;
39 import org.codehaus.plexus.logging.AbstractLogEnabled;
40 import org.codehaus.plexus.util.StringUtils;
41
42 import java.io.IOException;
43
44 import java.util.ArrayList;
45 import java.util.Collections;
46 import java.util.Comparator;
47 import java.util.List;
48 import java.util.Properties;
49
50
51 @Component( role = ArchetypeGenerationConfigurator.class )
52 public class DefaultArchetypeGenerationConfigurator
53 extends AbstractLogEnabled
54 implements ArchetypeGenerationConfigurator
55 {
56 @Requirement
57 OldArchetype oldArchetype;
58
59 @Requirement
60 private ArchetypeArtifactManager archetypeArtifactManager;
61
62 @Requirement
63 private ArchetypeFactory archetypeFactory;
64
65 @Requirement
66 private ArchetypeGenerationQueryer archetypeGenerationQueryer;
67
68 @Requirement
69 private ArchetypeRegistryManager archetypeRegistryManager;
70
71 public void setArchetypeArtifactManager( ArchetypeArtifactManager archetypeArtifactManager )
72 {
73 this.archetypeArtifactManager = archetypeArtifactManager;
74 }
75
76 public void configureArchetype( ArchetypeGenerationRequest request, Boolean interactiveMode,
77 Properties executionProperties )
78 throws ArchetypeNotDefined, UnknownArchetype, ArchetypeNotConfigured, IOException, PrompterException,
79 ArchetypeGenerationConfigurationFailure
80 {
81 ArtifactRepository localRepository = request.getLocalRepository();
82
83 ArtifactRepository archetypeRepository = null;
84
85 List<ArtifactRepository> repositories = new ArrayList<ArtifactRepository>();
86
87 Properties properties = new Properties( executionProperties );
88
89 ArchetypeDefinition ad = new ArchetypeDefinition( request );
90
91 if ( !ad.isDefined() )
92 {
93 if ( !interactiveMode.booleanValue() )
94 {
95 throw new ArchetypeNotDefined( "No archetype was chosen" );
96 }
97 else
98 {
99 throw new ArchetypeNotDefined( "The archetype is not defined" );
100 }
101 }
102 if ( request.getArchetypeRepository() != null )
103 {
104 archetypeRepository =
105 archetypeRegistryManager.createRepository( request.getArchetypeRepository(),
106 ad.getArtifactId() + "-repo" );
107 repositories.add( archetypeRepository );
108 }
109 if ( request.getRemoteArtifactRepositories() != null )
110 {
111 repositories.addAll( request.getRemoteArtifactRepositories() );
112 }
113
114 if ( !archetypeArtifactManager.exists( ad.getGroupId(), ad.getArtifactId(), ad.getVersion(),
115 archetypeRepository, localRepository, repositories ) )
116 {
117 throw new UnknownArchetype( "The desired archetype does not exist (" + ad.getGroupId() + ":"
118 + ad.getArtifactId() + ":" + ad.getVersion() + ")" );
119 }
120
121 request.setArchetypeVersion( ad.getVersion() );
122
123 ArchetypeConfiguration archetypeConfiguration;
124
125 if ( archetypeArtifactManager.isFileSetArchetype( ad.getGroupId(), ad.getArtifactId(), ad.getVersion(),
126 archetypeRepository, localRepository, repositories ) )
127 {
128 org.apache.maven.archetype.metadata.ArchetypeDescriptor archetypeDescriptor =
129 archetypeArtifactManager.getFileSetArchetypeDescriptor( ad.getGroupId(), ad.getArtifactId(),
130 ad.getVersion(), archetypeRepository,
131 localRepository, repositories );
132
133 archetypeConfiguration = archetypeFactory.createArchetypeConfiguration( archetypeDescriptor, properties );
134 }
135 else if ( archetypeArtifactManager.isOldArchetype( ad.getGroupId(), ad.getArtifactId(), ad.getVersion(),
136 archetypeRepository, localRepository, repositories ) )
137 {
138 org.apache.maven.archetype.old.descriptor.ArchetypeDescriptor archetypeDescriptor =
139 archetypeArtifactManager.getOldArchetypeDescriptor( ad.getGroupId(), ad.getArtifactId(),
140 ad.getVersion(), archetypeRepository,
141 localRepository, repositories );
142
143 archetypeConfiguration = archetypeFactory.createArchetypeConfiguration( archetypeDescriptor, properties );
144 }
145 else
146 {
147 throw new ArchetypeGenerationConfigurationFailure( "The defined artifact is not an archetype" );
148 }
149
150 if ( interactiveMode.booleanValue() )
151 {
152 boolean confirmed = false;
153
154 while ( !confirmed )
155 {
156 List<String> propertiesRequired = archetypeConfiguration.getRequiredProperties();
157 getLogger().debug( "Required properties before content sort: " + propertiesRequired );
158 Collections.sort( propertiesRequired, new RequiredPropertyComparator( archetypeConfiguration ) );
159 getLogger().debug( "Required properties after content sort: " + propertiesRequired );
160
161 if ( !archetypeConfiguration.isConfigured() )
162 {
163 for ( String requiredProperty : propertiesRequired )
164 {
165 if ( !archetypeConfiguration.isConfigured( requiredProperty ) )
166 {
167 if ( "package".equals( requiredProperty ) )
168 {
169
170
171
172 String packageDefault = archetypeConfiguration.getDefaultValue( requiredProperty );
173 packageDefault =
174 ( null == packageDefault || "".equals( packageDefault ) ) ? archetypeConfiguration.getProperty( "groupId" )
175 : archetypeConfiguration.getDefaultValue( requiredProperty );
176
177 String value = getTransitiveDefaultValue( packageDefault, archetypeConfiguration );
178
179 value = archetypeGenerationQueryer.getPropertyValue( requiredProperty, value );
180
181 archetypeConfiguration.setProperty( requiredProperty, value );
182 }
183 else
184 {
185 String value = archetypeConfiguration.getDefaultValue( requiredProperty );
186
187 value = getTransitiveDefaultValue( value, archetypeConfiguration );
188
189 value = archetypeGenerationQueryer.getPropertyValue( requiredProperty, value );
190
191 archetypeConfiguration.setProperty( requiredProperty, value );
192 }
193 }
194 else
195 {
196 getLogger().info(
197 "Using property: " + requiredProperty + " = "
198 + archetypeConfiguration.getProperty( requiredProperty ) );
199 }
200 }
201 }
202 else
203 {
204
205 for ( String requiredProperty : propertiesRequired )
206 {
207 getLogger().info(
208 "Using property: " + requiredProperty + " = "
209 + archetypeConfiguration.getProperty( requiredProperty ) );
210 }
211 }
212
213 if ( !archetypeConfiguration.isConfigured() )
214 {
215 getLogger().warn( "Archetype is not fully configured" );
216 }
217 else if ( !archetypeGenerationQueryer.confirmConfiguration( archetypeConfiguration ) )
218 {
219 getLogger().debug( "Archetype generation configuration not confirmed" );
220 archetypeConfiguration.reset();
221 restoreCommandLineProperties( archetypeConfiguration, executionProperties );
222 }
223 else
224 {
225 getLogger().debug( "Archetype generation configuration confirmed" );
226
227 confirmed = true;
228 }
229 }
230 }
231 else
232 {
233 if ( !archetypeConfiguration.isConfigured() )
234 {
235 for ( String requiredProperty : archetypeConfiguration.getRequiredProperties() )
236 {
237 if ( !archetypeConfiguration.isConfigured( requiredProperty )
238 && ( archetypeConfiguration.getDefaultValue( requiredProperty ) != null ) )
239 {
240 archetypeConfiguration.setProperty( requiredProperty,
241 archetypeConfiguration.getDefaultValue( requiredProperty ) );
242 }
243 }
244
245
246 if ( !archetypeConfiguration.isConfigured() )
247 {
248 StringBuffer exceptionMessage = new StringBuffer();
249 exceptionMessage.append( "Archetype " );
250 exceptionMessage.append( request.getArchetypeGroupId() );
251 exceptionMessage.append( ":" );
252 exceptionMessage.append( request.getArchetypeArtifactId() );
253 exceptionMessage.append( ":" );
254 exceptionMessage.append( request.getArchetypeVersion() );
255 exceptionMessage.append( " is not configured" );
256
257 List<String> missingProperties = new ArrayList<String>( 0 );
258 for ( String requiredProperty : archetypeConfiguration.getRequiredProperties() )
259 {
260 if ( !archetypeConfiguration.isConfigured( requiredProperty ) )
261 {
262 exceptionMessage.append( "\n\tProperty " );
263 exceptionMessage.append( requiredProperty );
264 missingProperties.add( requiredProperty );
265 exceptionMessage.append( " is missing." );
266 getLogger().warn(
267 "Property " + requiredProperty + " is missing. Add -D" + requiredProperty
268 + "=someValue" );
269 }
270 }
271
272 throw new ArchetypeNotConfigured( exceptionMessage.toString(), missingProperties );
273 }
274 }
275 }
276
277 request.setGroupId( archetypeConfiguration.getProperty( Constants.GROUP_ID ) );
278
279 request.setArtifactId( archetypeConfiguration.getProperty( Constants.ARTIFACT_ID ) );
280
281 request.setVersion( archetypeConfiguration.getProperty( Constants.VERSION ) );
282
283 request.setPackage( archetypeConfiguration.getProperty( Constants.PACKAGE ) );
284
285 properties = archetypeConfiguration.getProperties();
286
287 request.setProperties( properties );
288 }
289
290 private String getTransitiveDefaultValue( String defaultValue, ArchetypeConfiguration archetypeConfiguration )
291 {
292 String result = defaultValue;
293 if ( null == result )
294 {
295 return null;
296 }
297 for ( String property : archetypeConfiguration.getRequiredProperties() )
298 {
299 if ( result.indexOf( "${" + property + "}" ) >= 0 )
300 {
301 result = StringUtils.replace( result, "${" + property + "}",
302 archetypeConfiguration.getProperty( property ) );
303 }
304 }
305 return result;
306 }
307
308 private void restoreCommandLineProperties( ArchetypeConfiguration archetypeConfiguration,
309 Properties executionProperties )
310 {
311 getLogger().debug( "Restoring command line properties" );
312
313 for ( String property : archetypeConfiguration.getRequiredProperties() )
314 {
315 if ( executionProperties.containsKey( property ) )
316 {
317 archetypeConfiguration.setProperty( property, executionProperties.getProperty( property ) );
318 getLogger().debug( "Restored " + property + "=" + archetypeConfiguration.getProperty( property ) );
319 }
320 }
321 }
322
323 public static class RequiredPropertyComparator
324 implements Comparator<String>
325 {
326 private final ArchetypeConfiguration archetypeConfiguration;
327
328 public RequiredPropertyComparator( ArchetypeConfiguration archetypeConfiguration )
329 {
330 this.archetypeConfiguration = archetypeConfiguration;
331 }
332
333 public int compare( String left, String right )
334 {
335 String leftDefault = archetypeConfiguration.getDefaultValue( left );
336
337 if ( ( leftDefault != null ) && leftDefault.indexOf( "${" + right + "}" ) >= 0 )
338 {
339 return 1;
340 }
341
342 String rightDefault = archetypeConfiguration.getDefaultValue( right );
343
344 if ( ( rightDefault != null ) && rightDefault.indexOf( "${" + left + "}" ) >= 0 )
345 {
346 return -1;
347 }
348
349 return comparePropertyName( left, right );
350 }
351
352 private int comparePropertyName( String left, String right )
353 {
354 if ( "groupId".equals( left ) )
355 {
356 return -1;
357 }
358 if ( "groupId".equals( right ) )
359 {
360 return 1;
361 }
362 if ( "artifactId".equals( left ) )
363 {
364 return -1;
365 }
366 if ( "artifactId".equals( right ) )
367 {
368 return 1;
369 }
370 if ( "version".equals( left ) )
371 {
372 return -1;
373 }
374 if ( "version".equals( right ) )
375 {
376 return 1;
377 }
378 if ( "package".equals( left ) )
379 {
380 return -1;
381 }
382 if ( "package".equals( right ) )
383 {
384 return 1;
385 }
386 return left.compareTo( right );
387 }
388 }
389 }