1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin.resources.remote;
20
21 import java.util.ArrayList;
22 import java.util.Iterator;
23 import java.util.LinkedHashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.TreeMap;
27
28 import org.apache.maven.model.Dependency;
29 import org.apache.maven.model.Plugin;
30 import org.apache.maven.model.PluginContainer;
31 import org.apache.maven.model.PluginExecution;
32 import org.apache.maven.model.Repository;
33 import org.codehaus.plexus.util.xml.Xpp3Dom;
34
35
36 public final class ModelUtils {
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public static void mergePluginLists(
52 PluginContainer childContainer, PluginContainer parentContainer, boolean handleAsInheritance) {
53 if ((childContainer == null) || (parentContainer == null)) {
54
55 return;
56 }
57
58 List<Plugin> parentPlugins = parentContainer.getPlugins();
59
60 if ((parentPlugins != null) && !parentPlugins.isEmpty()) {
61 parentPlugins = new ArrayList<>(parentPlugins);
62
63
64
65 if (handleAsInheritance) {
66 for (Iterator<Plugin> it = parentPlugins.iterator(); it.hasNext(); ) {
67 Plugin plugin = it.next();
68
69 String inherited = plugin.getInherited();
70
71 if ((inherited != null) && !Boolean.parseBoolean(inherited)) {
72 it.remove();
73 }
74 }
75 }
76
77 List<Plugin> assembledPlugins = new ArrayList<>();
78
79 Map<String, Plugin> childPlugins = childContainer.getPluginsAsMap();
80
81 for (Plugin parentPlugin : parentPlugins) {
82 String parentInherited = parentPlugin.getInherited();
83
84
85
86
87
88
89 if (!handleAsInheritance || (parentInherited == null) || Boolean.parseBoolean(parentInherited)) {
90 Plugin childPlugin = childPlugins.get(parentPlugin.getKey());
91
92 if ((childPlugin != null) && !assembledPlugins.contains(childPlugin)) {
93 Plugin assembledPlugin = childPlugin;
94
95 mergePluginDefinitions(childPlugin, parentPlugin, handleAsInheritance);
96
97
98 assembledPlugins.add(assembledPlugin);
99 }
100
101
102
103
104 if (handleAsInheritance && (parentInherited == null)) {
105 parentPlugin.unsetInheritanceApplied();
106 }
107 }
108
109
110
111 List<Plugin> results =
112 ModelUtils.orderAfterMerge(assembledPlugins, parentPlugins, childContainer.getPlugins());
113
114 childContainer.setPlugins(results);
115
116 childContainer.flushPluginMap();
117 }
118 }
119 }
120
121 public static List<Plugin> orderAfterMerge(
122 List<Plugin> merged, List<Plugin> highPrioritySource, List<Plugin> lowPrioritySource) {
123 List<Plugin> results = new ArrayList<>();
124
125 if (!merged.isEmpty()) {
126 results.addAll(merged);
127 }
128
129 List<Plugin> missingFromResults = new ArrayList<>();
130
131 List<List<Plugin>> sources = new ArrayList<>();
132
133 sources.add(highPrioritySource);
134 sources.add(lowPrioritySource);
135
136 for (List<Plugin> source : sources) {
137 for (Plugin item : source) {
138 if (results.contains(item)) {
139 if (!missingFromResults.isEmpty()) {
140 int idx = results.indexOf(item);
141
142 if (idx < 0) {
143 idx = 0;
144 }
145
146 results.addAll(idx, missingFromResults);
147
148 missingFromResults.clear();
149 }
150 } else {
151 missingFromResults.add(item);
152 }
153 }
154
155 if (!missingFromResults.isEmpty()) {
156 results.addAll(missingFromResults);
157
158 missingFromResults.clear();
159 }
160 }
161
162 return results;
163 }
164
165 public static void mergePluginDefinitions(Plugin child, Plugin parent, boolean handleAsInheritance) {
166 if ((child == null) || (parent == null)) {
167
168 return;
169 }
170
171 if (parent.isExtensions()) {
172 child.setExtensions(true);
173 }
174
175 if ((child.getVersion() == null) && (parent.getVersion() != null)) {
176 child.setVersion(parent.getVersion());
177 }
178
179 Xpp3Dom childConfiguration = (Xpp3Dom) child.getConfiguration();
180 Xpp3Dom parentConfiguration = (Xpp3Dom) parent.getConfiguration();
181
182 childConfiguration = Xpp3Dom.mergeXpp3Dom(childConfiguration, parentConfiguration);
183
184 child.setConfiguration(childConfiguration);
185
186 child.setDependencies(mergeDependencyList(child.getDependencies(), parent.getDependencies()));
187
188
189 String parentInherited = parent.getInherited();
190
191 boolean parentIsInherited = (parentInherited == null) || Boolean.parseBoolean(parentInherited);
192
193 List<PluginExecution> parentExecutions = parent.getExecutions();
194
195 if ((parentExecutions != null) && !parentExecutions.isEmpty()) {
196 List<PluginExecution> mergedExecutions = new ArrayList<>();
197
198 Map<String, PluginExecution> assembledExecutions = new TreeMap<>();
199
200 Map<String, PluginExecution> childExecutions = child.getExecutionsAsMap();
201
202 for (PluginExecution parentExecution : parentExecutions) {
203 String inherited = parentExecution.getInherited();
204
205 boolean parentExecInherited =
206 parentIsInherited && ((inherited == null) || Boolean.parseBoolean(inherited));
207
208 if (!handleAsInheritance || parentExecInherited) {
209 PluginExecution assembled = parentExecution;
210
211 PluginExecution childExecution = childExecutions.get(parentExecution.getId());
212
213 if (childExecution != null) {
214 mergePluginExecutionDefinitions(childExecution, parentExecution);
215
216 assembled = childExecution;
217 } else if (handleAsInheritance && (parentInherited == null)) {
218 parentExecution.unsetInheritanceApplied();
219 }
220
221 assembledExecutions.put(assembled.getId(), assembled);
222 mergedExecutions.add(assembled);
223 }
224 }
225
226 for (PluginExecution childExecution : child.getExecutions()) {
227 if (!assembledExecutions.containsKey(childExecution.getId())) {
228 mergedExecutions.add(childExecution);
229 }
230 }
231
232 child.setExecutions(mergedExecutions);
233
234 child.flushExecutionMap();
235 }
236 }
237
238 private static void mergePluginExecutionDefinitions(PluginExecution child, PluginExecution parent) {
239 if (child.getPhase() == null) {
240 child.setPhase(parent.getPhase());
241 }
242
243 List<String> parentGoals = parent.getGoals();
244 List<String> childGoals = child.getGoals();
245
246 List<String> goals = new ArrayList<>();
247
248 if ((childGoals != null) && !childGoals.isEmpty()) {
249 goals.addAll(childGoals);
250 }
251
252 if (parentGoals != null) {
253 for (String goal : parentGoals) {
254 if (!goals.contains(goal)) {
255 goals.add(goal);
256 }
257 }
258 }
259
260 child.setGoals(goals);
261
262 Xpp3Dom childConfiguration = (Xpp3Dom) child.getConfiguration();
263 Xpp3Dom parentConfiguration = (Xpp3Dom) parent.getConfiguration();
264
265 childConfiguration = Xpp3Dom.mergeXpp3Dom(childConfiguration, parentConfiguration);
266
267 child.setConfiguration(childConfiguration);
268 }
269
270 public static List<Repository> mergeRepositoryLists(List<Repository> dominant, List<Repository> recessive) {
271
272 List<Repository> repositories = new ArrayList<>(dominant);
273
274 for (Repository repository : recessive) {
275 if (!repositories.contains(repository)) {
276 repositories.add(repository);
277 }
278 }
279
280 return repositories;
281 }
282
283 public static void mergeFilterLists(List<String> childFilters, List<String> parentFilters) {
284 for (String f : parentFilters) {
285 if (!childFilters.contains(f)) {
286 childFilters.add(f);
287 }
288 }
289 }
290
291 private static List<Dependency> mergeDependencyList(List<Dependency> child, List<Dependency> parent) {
292 Map<String, Dependency> depsMap = new LinkedHashMap<>();
293
294 if (parent != null) {
295 for (Dependency dependency : parent) {
296 depsMap.put(dependency.getManagementKey(), dependency);
297 }
298 }
299
300 if (child != null) {
301 for (Dependency dependency : child) {
302 depsMap.put(dependency.getManagementKey(), dependency);
303 }
304 }
305
306 return new ArrayList<>(depsMap.values());
307 }
308 }