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