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.commons.collections.iterators.ArrayIterator;
23 import org.apache.maven.archetype.ArchetypeGenerationRequest;
24 import org.apache.maven.archetype.catalog.Archetype;
25 import org.apache.maven.archetype.common.ArchetypeDefinition;
26 import org.apache.maven.archetype.exception.ArchetypeNotDefined;
27 import org.apache.maven.archetype.exception.ArchetypeSelectionFailure;
28 import org.apache.maven.archetype.exception.UnknownArchetype;
29 import org.apache.maven.archetype.exception.UnknownGroup;
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.IOException;
35 import java.util.HashMap;
36 import java.util.Iterator;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Properties;
40
41
42 public class DefaultArchetypeSelector
43 extends AbstractLogEnabled
44 implements ArchetypeSelector
45 {
46 static final String DEFAULT_ARCHETYPE_GROUPID = "org.apache.maven.archetypes";
47
48 static final String DEFAULT_ARCHETYPE_VERSION = "1.0";
49
50 static final String DEFAULT_ARCHETYPE_ARTIFACTID = "maven-archetype-quickstart";
51
52
53 private ArchetypeSelectionQueryer archetypeSelectionQueryer;
54
55 private org.apache.maven.archetype.Archetype archetype;
56
57 public void selectArchetype( ArchetypeGenerationRequest request, Boolean interactiveMode, String catalogs )
58 throws ArchetypeNotDefined, UnknownArchetype, UnknownGroup, IOException, PrompterException,
59 ArchetypeSelectionFailure
60 {
61
62 ArchetypeDefinition definition = new ArchetypeDefinition();
63
64 definition.setGroupId( request.getArchetypeGroupId() );
65 definition.setArtifactId( request.getArchetypeArtifactId() );
66 definition.setVersion( request.getArchetypeVersion() );
67
68 Map archetypes = getArchetypesByCatalog( catalogs );
69
70 if ( definition.isDefined() && StringUtils.isNotEmpty( request.getArchetypeRepository() ) )
71 {
72 getLogger().info( "Archetype defined by properties" );
73 }
74 else
75 {
76 if ( definition.isDefined() && StringUtils.isEmpty( request.getArchetypeRepository() ) )
77 {
78 Iterator ca = new ArrayIterator( StringUtils.split ( catalogs, "," ) );
79 boolean found = false;
80 while ( !found && ca.hasNext() )
81 {
82 String catalogKey = (String) ca.next();
83
84 String[] keySplitted = catalogKey.split( "-", 2 );
85
86 List catalog = (List) archetypes.get( catalogKey );
87
88 Archetype example = new Archetype();
89 example.setGroupId( request.getArchetypeGroupId() );
90 example.setArtifactId( request.getArchetypeArtifactId() );
91
92 if ( catalog.contains( example ) )
93 {
94 found = true;
95
96 Archetype foundArchetype = (Archetype) catalog.get( catalog.indexOf( example ) );
97 definition.setName( foundArchetype.getArtifactId() );
98 if ( StringUtils.isNotEmpty( foundArchetype.getRepository() ) )
99 {
100 definition.setRepository( foundArchetype.getRepository() );
101 }
102 else if ( keySplitted.length > 1 )
103 {
104 int lastIndex = catalogKey.lastIndexOf( "/" );
105 String catalogBase =
106 catalogKey.substring( 0, ( lastIndex > 7 ? lastIndex : catalogKey.length() ) );
107 definition.setRepository( catalogBase );
108 }
109
110 getLogger().info(
111 "Archetype repository missing. Using the one from " + foundArchetype
112 + " found in catalog " + catalogKey );
113 }
114 }
115 if ( !found )
116 {
117 getLogger().warn( "No archetype repository found. Falling back to central repository (http://repo1.maven.org/maven2). " );
118 getLogger().warn( "Use -DarchetypeRepository=<your repository> if archetype's repository is elsewhere." );
119
120 definition.setRepository( "http://repo1.maven.org/maven2" );
121 }
122 }
123 if ( !definition.isDefined() && definition.isPartiallyDefined() )
124 {
125 Iterator ca = new ArrayIterator( StringUtils.split( catalogs, "," ) );
126 boolean found = false;
127 while ( !found && ca.hasNext() )
128 {
129 String catalogKey = (String) ca.next();
130
131 List catalog = (List) archetypes.get( catalogKey );
132
133 String[] keySplitted = catalogKey.split( ":", 2 );
134
135 Archetype example = new Archetype();
136 example.setGroupId( request.getArchetypeGroupId() );
137 example.setArtifactId( request.getArchetypeArtifactId() );
138
139 if ( catalog.contains ( example ) )
140 {
141 found = true;
142
143 Archetype foundArchetype = (Archetype) catalog.get( catalog.indexOf( example ) );
144 definition.setGroupId( foundArchetype.getGroupId() );
145 definition.setArtifactId( foundArchetype.getArtifactId() );
146 definition.setVersion( foundArchetype.getVersion() );
147 definition.setName( foundArchetype.getArtifactId() );
148
149 if ( StringUtils.isNotEmpty( foundArchetype.getRepository() ) )
150 {
151 definition.setRepository( foundArchetype.getRepository() );
152 }
153 else if ( keySplitted.length > 1 )
154 {
155 int lastIndex = catalogKey.lastIndexOf( "/" );
156 String catalogBase =
157 catalogKey.substring( 0, ( lastIndex > 7 ? lastIndex : catalogKey.length() ) );
158 definition.setRepository( catalogBase );
159 }
160
161 String goals = StringUtils.join( foundArchetype.getGoals().iterator(), "," );
162 definition.setGoals( goals );
163
164 getLogger().info( "Archetype " + foundArchetype + " found in catalog " + catalogKey );
165 }
166 }
167 if ( !found )
168 {
169 getLogger().warn( "Specified archetype not found." );
170 if ( interactiveMode.booleanValue() )
171 {
172 definition.setVersion( null );
173 definition.setGroupId( null );
174 definition.setArtifactId( null );
175 }
176 }
177 }
178 }
179
180
181 if ( definition.getGroupId() == null )
182 {
183 definition.setGroupId( DEFAULT_ARCHETYPE_GROUPID );
184 }
185 if ( definition.getVersion() == null )
186 {
187 definition.setVersion( DEFAULT_ARCHETYPE_VERSION );
188 }
189
190 if ( !definition.isDefined() && !definition.isPartiallyDefined() )
191 {
192
193 if ( definition.getArtifactId() == null )
194 {
195 getLogger().info( "No archetype defined. Using " + DEFAULT_ARCHETYPE_ARTIFACTID + " ("
196 + definition.getGroupId() + ":" + DEFAULT_ARCHETYPE_ARTIFACTID + ":" + definition.getVersion()
197 + ")" );
198 definition.setArtifactId( DEFAULT_ARCHETYPE_ARTIFACTID );
199 }
200
201 if ( interactiveMode.booleanValue() )
202 {
203 if ( archetypes.size() > 0 )
204 {
205 Archetype selectedArchetype = archetypeSelectionQueryer.selectArchetype( archetypes, definition );
206
207 definition.setGroupId( selectedArchetype.getGroupId() );
208 definition.setArtifactId( selectedArchetype.getArtifactId() );
209 definition.setVersion( selectedArchetype.getVersion() );
210 definition.setName( selectedArchetype.getArtifactId() );
211 String catalogKey = getCatalogKey( archetypes, selectedArchetype );
212 String[] keySplitted = catalogKey.split( ":", 2 );
213 if ( StringUtils.isNotEmpty( selectedArchetype.getRepository() ) )
214 {
215 definition.setRepository( selectedArchetype.getRepository() );
216 }
217 else if ( keySplitted.length > 1 )
218 {
219 int lastIndex = catalogKey.lastIndexOf( "/" );
220 String catalogBase =
221 catalogKey.substring( 0, ( lastIndex > 7 ? lastIndex : catalogKey.length() ) );
222 definition.setRepository( catalogBase );
223 }
224 String goals = StringUtils.join( selectedArchetype.getGoals().iterator(), "," );
225 definition.setGoals( goals );
226 }
227 }
228 }
229
230
231
232
233 if ( !definition.isPartiallyDefined() )
234 {
235 throw new ArchetypeSelectionFailure( "No valid archetypes could be found to choose." );
236 }
237
238 request.setArchetypeGroupId( definition.getGroupId() );
239
240 request.setArchetypeArtifactId( definition.getArtifactId() );
241
242 request.setArchetypeVersion( definition.getVersion() );
243
244 request.setArchetypeGoals( definition.getGoals() );
245
246 request.setArchetypeName( definition.getName() );
247
248 if ( StringUtils.isNotEmpty( definition.getRepository() ) )
249 {
250 request.setArchetypeRepository( definition.getRepository() );
251 }
252 }
253
254 private Map getArchetypesByCatalog( String catalogs )
255 {
256 if ( catalogs == null )
257 {
258 throw new NullPointerException( "catalogs can not be null" );
259 }
260
261 Map archetypes = new HashMap();
262
263 for ( Iterator ca = new ArrayIterator( StringUtils.split( catalogs, "," ) ); ca.hasNext(); )
264 {
265 String catalog = (String) ca.next();
266
267 if ( "internal".equalsIgnoreCase( catalog ) )
268 {
269 archetypes.put( "internal", archetype.getInternalCatalog().getArchetypes() );
270 }
271 else if ( "local".equalsIgnoreCase( catalog ) )
272 {
273 archetypes.put( "local", archetype.getDefaultLocalCatalog().getArchetypes() );
274 }
275 else if ( "remote".equalsIgnoreCase( catalog ) )
276 {
277 List archetypesFromRemote = archetype.getRemoteCatalog().getArchetypes();
278 if ( archetypesFromRemote.size() > 0 )
279 {
280 archetypes.put( "remote", archetypesFromRemote );
281 }
282 else
283 {
284 getLogger().warn( "No archetype found in Remote catalog. Defaulting to internal Catalog" );
285 archetypes.put( "internal", archetype.getInternalCatalog().getArchetypes() );
286 }
287 }
288 else if ( catalog.startsWith( "file://" ) )
289 {
290 String path = catalog.substring( 7 );
291 archetypes.put( catalog, archetype.getLocalCatalog( path ).getArchetypes() );
292 }
293 else if ( catalog.startsWith( "http://" ) )
294 {
295 archetypes.put( catalog, archetype.getRemoteCatalog( catalog ).getArchetypes() );
296 }
297 }
298
299 if ( archetypes.size() == 0 )
300 {
301 getLogger().info( "No catalog defined. Using internal catalog" );
302
303 archetypes.put( "internal", archetype.getInternalCatalog().getArchetypes() );
304 }
305 return archetypes;
306 }
307
308 private Properties getArchetypeDataSourceProperties( String sourceRoleHint, Properties archetypeCatalogProperties )
309 {
310 Properties p = new Properties();
311
312 for ( Iterator i = archetypeCatalogProperties.keySet().iterator(); i.hasNext(); )
313 {
314 String key = (String) i.next();
315
316 if ( key.startsWith( sourceRoleHint ) )
317 {
318 String k = key.substring( sourceRoleHint.length() + 1 );
319
320 p.setProperty( k, archetypeCatalogProperties.getProperty( key ) );
321 }
322 }
323
324 return p;
325 }
326
327 public void setArchetypeSelectionQueryer( ArchetypeSelectionQueryer archetypeSelectionQueryer )
328 {
329 this.archetypeSelectionQueryer = archetypeSelectionQueryer;
330 }
331
332 private String getCatalogKey( Map archetypes, Archetype selectedArchetype )
333 {
334 String key = "";
335 Iterator keys = archetypes.keySet().iterator();
336 boolean found = false;
337 while ( keys.hasNext() && !found )
338 {
339 key = (String) keys.next();
340 List catalog = (List) archetypes.get( key );
341 if ( catalog.contains( selectedArchetype ) )
342 {
343 found = true;
344 }
345 }
346 return key;
347 }
348 }