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.commons.lang.math.NumberUtils;
23 import org.apache.maven.archetype.catalog.Archetype;
24 import org.apache.maven.archetype.ui.ArchetypeDefinition;
25 import org.apache.maven.artifact.versioning.ArtifactVersion;
26 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
27 import org.codehaus.plexus.components.interactivity.Prompter;
28 import org.codehaus.plexus.components.interactivity.PrompterException;
29 import org.codehaus.plexus.logging.AbstractLogEnabled;
30
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Set;
38 import java.util.SortedMap;
39 import java.util.TreeMap;
40
41
42
43
44 public class DefaultArchetypeSelectionQueryer
45 extends AbstractLogEnabled
46 implements ArchetypeSelectionQueryer
47 {
48
49
50
51 private Prompter prompter;
52
53 public boolean confirmSelection( ArchetypeDefinition archetypeDefinition )
54 throws PrompterException
55 {
56 String query =
57 "Confirm archetype selection: \n" + archetypeDefinition.getGroupId() + "/" + archetypeDefinition.getName()
58 + "\n";
59
60 String answer = prompter.prompt( query, Arrays.asList( new String[]{ "Y", "N" } ), "Y" );
61
62 return "Y".equalsIgnoreCase( answer );
63 }
64
65 public Archetype selectArchetype( Map<String, List<Archetype>> catalogs )
66 throws PrompterException
67 {
68 return selectArchetype( catalogs, null );
69 }
70
71 public Archetype selectArchetype( Map<String, List<Archetype>> catalogs, ArchetypeDefinition defaultDefinition )
72 throws PrompterException
73 {
74 Archetype selection = null;
75 Map<String, List<Archetype>> filteredCatalogs = catalogs;
76
77 do
78 {
79 StringBuilder query = new StringBuilder( "Choose archetype:\n" );
80
81 Set<String> archetypeKeys = new HashSet<String>();
82 List<String> answers = new ArrayList<String>();
83 Map<String, Archetype> archetypeAnswerMap = new HashMap<String, Archetype>();
84
85 int counter = 0;
86 int defaultSelection = 0;
87
88 for ( Map.Entry<String, List<Archetype>> entry : filteredCatalogs.entrySet() )
89 {
90 String catalog = entry.getKey();
91
92 for ( Archetype archetype : entry.getValue() )
93 {
94 String archetypeKey = archetype.getGroupId() + ":" + archetype.getArtifactId();
95
96 if ( !archetypeKeys.add( archetypeKey ) )
97 {
98 continue;
99 }
100
101 counter++;
102
103 String description = archetype.getDescription();
104 if ( description == null )
105 {
106 description = "-";
107 }
108
109 String answer = String.valueOf( counter );
110
111 query.append( answer + ": " + catalog + " -> " + archetype.getGroupId() + ":"
112 + archetype.getArtifactId() + " (" + description + ")\n" );
113
114 answers.add( answer );
115
116 archetypeAnswerMap.put( answer, archetype );
117
118
119 if ( defaultDefinition != null && archetype.getGroupId().equals( defaultDefinition.getGroupId() )
120 && archetype.getArtifactId().equals( defaultDefinition.getArtifactId() ) )
121 {
122 defaultSelection = counter;
123 }
124 }
125 }
126
127 if ( counter == 0 )
128 {
129 query.append( " Your filter doesn't match any archetype (hint: enter to return to initial list)\n" );
130 }
131
132 query.append( "Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): " );
133
134 String answer;
135 if ( defaultSelection == 0 )
136 {
137 answer = prompter.prompt( query.toString() );
138 }
139 else
140 {
141 answer = prompter.prompt( query.toString(), Integer.toString( defaultSelection ) );
142 }
143
144 if ( NumberUtils.isNumber( answer ) )
145 {
146 selection = archetypeAnswerMap.get( answer );
147 }
148 else
149 {
150
151 filteredCatalogs = ArchetypeSelectorUtils.getFilteredArchetypesByCatalog( catalogs, answer );
152 }
153 }
154 while ( selection == null );
155
156 return selectVersion( catalogs, selection.getGroupId(), selection.getArtifactId() );
157 }
158
159 private Archetype selectVersion( Map<String, List<Archetype>> catalogs, String groupId, String artifactId )
160 throws PrompterException
161 {
162 SortedMap<ArtifactVersion, Archetype> archetypeVersionsMap = new TreeMap<ArtifactVersion, Archetype>();
163
164 for ( Map.Entry<String, List<Archetype>> entry : catalogs.entrySet() )
165 {
166 for ( Archetype archetype : entry.getValue() )
167 {
168 if ( !groupId.equals( archetype.getGroupId() ) || !artifactId.equals( archetype.getArtifactId() ) )
169 {
170 continue;
171 }
172
173 ArtifactVersion version = new DefaultArtifactVersion( archetype.getVersion() );
174
175
176 if ( !archetypeVersionsMap.containsKey( version ) )
177 {
178 archetypeVersionsMap.put( version, archetype );
179 }
180 }
181 }
182
183 if ( archetypeVersionsMap.size() == 1 )
184 {
185 return archetypeVersionsMap.values().iterator().next();
186 }
187
188
189 StringBuilder query = new StringBuilder( "Choose version: \n" );
190
191 List<String> answers = new ArrayList<String>();
192 Map<String, Archetype> answerMap = new HashMap<String, Archetype>();
193
194 int counter = 1;
195 String mapKey = null;
196
197 for ( Map.Entry<ArtifactVersion, Archetype> entry : archetypeVersionsMap.entrySet() )
198 {
199 ArtifactVersion version = entry.getKey();
200 Archetype archetype = entry.getValue();
201
202 mapKey = String.valueOf( counter );
203
204 query.append( mapKey + ": " + version + "\n" );
205
206 answers.add( mapKey );
207
208 answerMap.put( mapKey, archetype );
209
210 counter++;
211 }
212
213 query.append( "Choose a number: " );
214
215 Archetype archetype = null;
216
217 do
218 {
219 String answer = prompter.prompt( query.toString(), answers, mapKey );
220
221 archetype = answerMap.get( answer );
222 }
223 while ( archetype == null );
224
225 return archetype;
226 }
227
228 public void setPrompter( Prompter prompter )
229 {
230 this.prompter = prompter;
231 }
232 }