1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.archetype.ui.generation;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.SortedMap;
32 import java.util.TreeMap;
33
34 import org.apache.commons.lang3.math.NumberUtils;
35 import org.apache.maven.archetype.catalog.Archetype;
36 import org.apache.maven.archetype.ui.ArchetypeDefinition;
37 import org.apache.maven.artifact.versioning.ArtifactVersion;
38 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
39 import org.codehaus.plexus.components.interactivity.Prompter;
40 import org.codehaus.plexus.components.interactivity.PrompterException;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 @Named("default")
45 @Singleton
46 public class DefaultArchetypeSelectionQueryer implements ArchetypeSelectionQueryer {
47 private static final Logger LOGGER = LoggerFactory.getLogger(DefaultArchetypeSelectionQueryer.class);
48
49 @Inject
50 @Named("archetype")
51 private Prompter prompter;
52
53 @Override
54 public Archetype selectArchetype(Map<String, List<Archetype>> catalogs) throws PrompterException {
55 return selectArchetype(catalogs, null);
56 }
57
58 @Override
59 public Archetype selectArchetype(Map<String, List<Archetype>> catalogs, ArchetypeDefinition defaultDefinition)
60 throws PrompterException {
61 Archetype selection = null;
62 Map<String, List<Archetype>> filteredCatalogs = catalogs;
63
64 do {
65 StringBuilder query = new StringBuilder("Choose archetype:\n");
66
67 Set<String> archetypeKeys = new HashSet<>();
68 List<String> answers = new ArrayList<>();
69 Map<String, Archetype> archetypeAnswerMap = new HashMap<>();
70
71 int counter = 0;
72 int defaultSelection = 0;
73
74 for (Map.Entry<String, List<Archetype>> entry : filteredCatalogs.entrySet()) {
75 String catalog = entry.getKey();
76
77 for (Archetype archetype : entry.getValue()) {
78 String archetypeKey = archetype.getGroupId() + ":" + archetype.getArtifactId();
79
80 if (!archetypeKeys.add(archetypeKey)) {
81 continue;
82 }
83
84 counter++;
85
86 String description = archetype.getDescription();
87 if (description == null) {
88 description = "-";
89 }
90
91 String answer = String.valueOf(counter);
92
93 query.append(answer + ": " + catalog + " -> " + archetype.getGroupId() + ":"
94 + archetype.getArtifactId() + " (" + description + ")\n");
95
96 answers.add(answer);
97
98 archetypeAnswerMap.put(answer, archetype);
99
100
101 if (defaultDefinition != null
102 && archetype.getGroupId().equals(defaultDefinition.getGroupId())
103 && archetype.getArtifactId().equals(defaultDefinition.getArtifactId())) {
104 defaultSelection = counter;
105 }
106 }
107 }
108
109 if (counter == 0) {
110 query.append(" Your filter doesn't match any archetype (hint: enter to return to initial list)\n");
111 }
112
113 query.append("Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): ");
114
115 String answer;
116 if (defaultSelection == 0) {
117 answer = prompter.prompt(query.toString());
118 } else {
119 answer = prompter.prompt(query.toString(), Integer.toString(defaultSelection));
120 }
121
122 if (NumberUtils.isCreatable(answer)) {
123 selection = archetypeAnswerMap.get(answer);
124 } else {
125
126 filteredCatalogs = ArchetypeSelectorUtils.getFilteredArchetypesByCatalog(catalogs, answer);
127 }
128 } while (selection == null);
129
130 return selectVersion(catalogs, selection.getGroupId(), selection.getArtifactId());
131 }
132
133 private Archetype selectVersion(Map<String, List<Archetype>> catalogs, String groupId, String artifactId)
134 throws PrompterException {
135 SortedMap<ArtifactVersion, Archetype> archetypeVersionsMap = new TreeMap<>();
136
137 for (Map.Entry<String, List<Archetype>> entry : catalogs.entrySet()) {
138 for (Archetype archetype : entry.getValue()) {
139 if (!groupId.equals(archetype.getGroupId()) || !artifactId.equals(archetype.getArtifactId())) {
140 continue;
141 }
142
143 ArtifactVersion version = new DefaultArtifactVersion(archetype.getVersion());
144
145
146 if (!archetypeVersionsMap.containsKey(version)) {
147 archetypeVersionsMap.put(version, archetype);
148 }
149 }
150 }
151
152 if (archetypeVersionsMap.size() == 1) {
153 return archetypeVersionsMap.values().iterator().next();
154 }
155
156
157 StringBuilder query = new StringBuilder("Choose " + groupId + ":" + artifactId + " version: \n");
158
159 List<String> answers = new ArrayList<>();
160 Map<String, Archetype> answerMap = new HashMap<>();
161
162 int counter = 1;
163 String mapKey = null;
164
165 for (Map.Entry<ArtifactVersion, Archetype> entry : archetypeVersionsMap.entrySet()) {
166 ArtifactVersion version = entry.getKey();
167 Archetype archetype = entry.getValue();
168
169 mapKey = String.valueOf(counter);
170
171 query.append(mapKey + ": " + version + "\n");
172
173 answers.add(mapKey);
174
175 answerMap.put(mapKey, archetype);
176
177 counter++;
178 }
179
180 query.append("Choose a number: ");
181
182 Archetype archetype = null;
183
184 do {
185 String answer = prompter.prompt(query.toString(), answers, mapKey);
186
187 archetype = answerMap.get(answer);
188 } while (archetype == null);
189
190 return archetype;
191 }
192
193 public void setPrompter(Prompter prompter) {
194 this.prompter = prompter;
195 }
196 }