1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.lifecycle.internal;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.LinkedHashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31
32 import org.apache.maven.lifecycle.DefaultLifecycles;
33 import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer;
34 import org.apache.maven.lifecycle.Lifecycle;
35 import org.apache.maven.lifecycle.mapping.LifecycleMapping;
36 import org.apache.maven.lifecycle.mapping.LifecycleMojo;
37 import org.apache.maven.lifecycle.mapping.LifecyclePhase;
38 import org.apache.maven.model.InputLocation;
39 import org.apache.maven.model.InputSource;
40 import org.apache.maven.model.Plugin;
41 import org.apache.maven.model.PluginExecution;
42 import org.codehaus.plexus.PlexusContainer;
43 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
44 import org.codehaus.plexus.util.StringUtils;
45 import org.codehaus.plexus.util.xml.Xpp3Dom;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49
50
51
52
53
54
55
56
57
58 @Singleton
59 @Named
60 public class DefaultLifecyclePluginAnalyzer implements LifeCyclePluginAnalyzer {
61
62 private final Logger logger = LoggerFactory.getLogger(getClass());
63
64 @Inject
65 private Map<String, LifecycleMapping> lifecycleMappings;
66
67 @Inject
68 private DefaultLifecycles defaultLifeCycles;
69
70 @Inject
71 private PlexusContainer plexusContainer;
72
73 public DefaultLifecyclePluginAnalyzer() {}
74
75
76
77
78
79
80
81
82
83
84
85 public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles(String packaging) {
86 if (logger.isDebugEnabled()) {
87 logger.debug("Looking up lifecycle mappings for packaging " + packaging + " from "
88 + Thread.currentThread().getContextClassLoader());
89 }
90
91 Map<String, LifecycleMapping> filtered = new HashMap<>();
92
93
94 if (this.plexusContainer != null) {
95 for (String name : this.lifecycleMappings.keySet()) {
96 try {
97 filtered.put(name, plexusContainer.lookup(LifecycleMapping.class, name));
98 } catch (ComponentLookupException e) {
99
100 }
101 }
102 } else {
103 filtered.putAll(this.lifecycleMappings);
104 }
105
106 LifecycleMapping lifecycleMappingForPackaging = filtered.get(packaging);
107
108 if (lifecycleMappingForPackaging == null) {
109 return null;
110 }
111
112 Map<Plugin, Plugin> plugins = new LinkedHashMap<>();
113
114 for (Lifecycle lifecycle : defaultLifeCycles.getLifeCycles()) {
115 org.apache.maven.lifecycle.mapping.Lifecycle lifecycleConfiguration =
116 lifecycleMappingForPackaging.getLifecycles().get(lifecycle.getId());
117
118 Map<String, LifecyclePhase> phaseToGoalMapping = null;
119
120 if (lifecycleConfiguration != null) {
121 phaseToGoalMapping = lifecycleConfiguration.getLifecyclePhases();
122 } else if (lifecycle.getDefaultLifecyclePhases() != null) {
123 phaseToGoalMapping = lifecycle.getDefaultLifecyclePhases();
124 }
125
126 if (phaseToGoalMapping != null) {
127 for (Map.Entry<String, LifecyclePhase> goalsForLifecyclePhase : phaseToGoalMapping.entrySet()) {
128 String phase = goalsForLifecyclePhase.getKey();
129 LifecyclePhase goals = goalsForLifecyclePhase.getValue();
130 if (goals != null) {
131 parseLifecyclePhaseDefinitions(plugins, phase, goals);
132 }
133 }
134 }
135 }
136
137 return plugins.keySet();
138 }
139
140 private void parseLifecyclePhaseDefinitions(Map<Plugin, Plugin> plugins, String phase, LifecyclePhase goals) {
141 String modelId = "org.apache.maven:maven-core:"
142 + this.getClass().getPackage().getImplementationVersion() + ":default-lifecycle-bindings";
143 InputSource inputSource = new InputSource();
144 inputSource.setModelId(modelId);
145 InputLocation location = new InputLocation(-1, -1, inputSource);
146 location.setLocation(0, location);
147
148 List<LifecycleMojo> mojos = goals.getMojos();
149 if (mojos != null) {
150
151 for (int i = 0; i < mojos.size(); i++) {
152 LifecycleMojo mojo = mojos.get(i);
153
154 GoalSpec gs = parseGoalSpec(mojo.getGoal());
155
156 if (gs == null) {
157 logger.warn("Ignored invalid goal specification '" + mojo.getGoal()
158 + "' from lifecycle mapping for phase " + phase);
159 continue;
160 }
161
162 Plugin plugin = new Plugin();
163 plugin.setGroupId(gs.groupId);
164 plugin.setArtifactId(gs.artifactId);
165 plugin.setVersion(gs.version);
166
167 plugin.setLocation("", location);
168 plugin.setLocation("groupId", location);
169 plugin.setLocation("artifactId", location);
170 plugin.setLocation("version", location);
171
172 Plugin existing = plugins.get(plugin);
173 if (existing != null) {
174 if (existing.getVersion() == null) {
175 existing.setVersion(plugin.getVersion());
176 existing.setLocation("version", location);
177 }
178 plugin = existing;
179 } else {
180 plugins.put(plugin, plugin);
181 }
182
183 PluginExecution execution = new PluginExecution();
184 execution.setId(getExecutionId(plugin, gs.goal));
185 execution.setPhase(phase);
186 execution.setPriority(i - mojos.size());
187 execution.getGoals().add(gs.goal);
188
189 execution.setLocation("", location);
190 execution.setLocation("id", location);
191 execution.setLocation("phase", location);
192 execution.setLocation("goals", location);
193
194 Xpp3Dom lifecycleConfiguration = mojo.getConfiguration();
195 if (lifecycleConfiguration != null) {
196 execution.setConfiguration(new Xpp3Dom(lifecycleConfiguration));
197 }
198
199 plugin.setDependencies(mojo.getDependencies());
200 plugin.getExecutions().add(execution);
201 }
202 }
203 }
204
205 private GoalSpec parseGoalSpec(String goalSpec) {
206 GoalSpec gs = new GoalSpec();
207
208 String[] p = StringUtils.split(goalSpec.trim(), ":");
209
210 if (p.length == 3) {
211
212 gs.groupId = p[0];
213 gs.artifactId = p[1];
214 gs.goal = p[2];
215 } else if (p.length == 4) {
216
217 gs.groupId = p[0];
218 gs.artifactId = p[1];
219 gs.version = p[2];
220 gs.goal = p[3];
221 } else {
222
223 gs = null;
224 }
225
226 return gs;
227 }
228
229 private String getExecutionId(Plugin plugin, String goal) {
230 Set<String> existingIds = new HashSet<>();
231 for (PluginExecution execution : plugin.getExecutions()) {
232 existingIds.add(execution.getId());
233 }
234
235 String base = "default-" + goal;
236 String id = base;
237
238 for (int index = 1; existingIds.contains(id); index++) {
239 id = base + '-' + index;
240 }
241
242 return id;
243 }
244
245 static class GoalSpec {
246
247 String groupId;
248
249 String artifactId;
250
251 String version;
252
253 String goal;
254 }
255 }