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