1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.model.merge;
20
21 import java.util.ArrayList;
22 import java.util.LinkedHashMap;
23 import java.util.LinkedHashSet;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27
28 import org.apache.maven.model.BuildBase;
29 import org.apache.maven.model.CiManagement;
30 import org.apache.maven.model.Dependency;
31 import org.apache.maven.model.DeploymentRepository;
32 import org.apache.maven.model.DistributionManagement;
33 import org.apache.maven.model.Exclusion;
34 import org.apache.maven.model.Extension;
35 import org.apache.maven.model.InputLocation;
36 import org.apache.maven.model.IssueManagement;
37 import org.apache.maven.model.Model;
38 import org.apache.maven.model.ModelBase;
39 import org.apache.maven.model.Organization;
40 import org.apache.maven.model.Plugin;
41 import org.apache.maven.model.PluginExecution;
42 import org.apache.maven.model.ReportPlugin;
43 import org.apache.maven.model.ReportSet;
44 import org.apache.maven.model.Repository;
45 import org.apache.maven.model.RepositoryBase;
46 import org.apache.maven.model.Scm;
47 import org.apache.maven.model.Site;
48 import org.codehaus.plexus.util.StringUtils;
49
50
51
52
53
54
55
56 public class MavenModelMerger extends ModelMerger {
57
58
59
60
61 public static final String CHILD_PATH_ADJUSTMENT = "child-path-adjustment";
62
63
64
65
66 public static final String ARTIFACT_ID = "artifact-id";
67
68 @Override
69 protected void mergeModel(Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
70 context.put(ARTIFACT_ID, target.getArtifactId());
71
72 super.mergeModel(target, source, sourceDominant, context);
73 }
74
75 @Override
76 protected void mergeModel_Name(Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
77 String src = source.getName();
78 if (src != null) {
79 if (sourceDominant) {
80 target.setName(src);
81 target.setLocation("name", source.getLocation("name"));
82 }
83 }
84 }
85
86 @Override
87 protected void mergeModel_Url(Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
88 String src = source.getUrl();
89 if (src != null) {
90 if (sourceDominant) {
91 target.setUrl(src);
92 target.setLocation("url", source.getLocation("url"));
93 } else if (target.getUrl() == null) {
94 target.setUrl(extrapolateChildUrl(src, source.isChildProjectUrlInheritAppendPath(), context));
95 target.setLocation("url", source.getLocation("url"));
96 }
97 }
98 }
99
100
101
102
103
104 @Override
105 protected void mergeModel_Organization(
106 Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
107 Organization src = source.getOrganization();
108 if (src != null) {
109 Organization tgt = target.getOrganization();
110 if (tgt == null) {
111 tgt = new Organization();
112 tgt.setLocation("", src.getLocation(""));
113 target.setOrganization(tgt);
114 mergeOrganization(tgt, src, sourceDominant, context);
115 }
116 }
117 }
118
119 @Override
120 protected void mergeModel_IssueManagement(
121 Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
122 IssueManagement src = source.getIssueManagement();
123 if (src != null) {
124 IssueManagement tgt = target.getIssueManagement();
125 if (tgt == null) {
126 tgt = new IssueManagement();
127 tgt.setLocation("", src.getLocation(""));
128 target.setIssueManagement(tgt);
129 mergeIssueManagement(tgt, src, sourceDominant, context);
130 }
131 }
132 }
133
134 @Override
135 protected void mergeModel_CiManagement(
136 Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
137 CiManagement src = source.getCiManagement();
138 if (src != null) {
139 CiManagement tgt = target.getCiManagement();
140 if (tgt == null) {
141 tgt = new CiManagement();
142 tgt.setLocation("", src.getLocation(""));
143 target.setCiManagement(tgt);
144 mergeCiManagement(tgt, src, sourceDominant, context);
145 }
146 }
147 }
148
149 @Override
150 protected void mergeModel_ModelVersion(
151 Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
152
153 }
154
155 @Override
156 protected void mergeModel_ArtifactId(
157 Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
158
159 }
160
161 @Override
162 protected void mergeModel_Profiles(
163 Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
164
165 }
166
167 @Override
168 protected void mergeModel_Prerequisites(
169 Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
170
171 }
172
173 @Override
174 protected void mergeModel_Licenses(
175 Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
176 if (target.getLicenses().isEmpty()) {
177 target.setLicenses(new ArrayList<>(source.getLicenses()));
178 }
179 }
180
181 @Override
182 protected void mergeModel_Developers(
183 Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
184 if (target.getDevelopers().isEmpty()) {
185 target.setDevelopers(new ArrayList<>(source.getDevelopers()));
186 }
187 }
188
189 @Override
190 protected void mergeModel_Contributors(
191 Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
192 if (target.getContributors().isEmpty()) {
193 target.setContributors(new ArrayList<>(source.getContributors()));
194 }
195 }
196
197 @Override
198 protected void mergeModel_MailingLists(
199 Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
200 if (target.getMailingLists().isEmpty()) {
201 target.setMailingLists(new ArrayList<>(source.getMailingLists()));
202 }
203 }
204
205 @Override
206 protected void mergeModelBase_Modules(
207 ModelBase target, ModelBase source, boolean sourceDominant, Map<Object, Object> context) {
208 List<String> src = source.getModules();
209 if (!src.isEmpty() && sourceDominant) {
210 List<Integer> indices = new ArrayList<>();
211 List<String> tgt = target.getModules();
212 Set<String> excludes = new LinkedHashSet<>(tgt);
213 List<String> merged = new ArrayList<>(tgt.size() + src.size());
214 merged.addAll(tgt);
215 for (int i = 0, n = tgt.size(); i < n; i++) {
216 indices.add(i);
217 }
218 for (int i = 0, n = src.size(); i < n; i++) {
219 String s = src.get(i);
220 if (!excludes.contains(s)) {
221 merged.add(s);
222 indices.add(~i);
223 }
224 }
225 target.setModules(merged);
226 target.setLocation(
227 "modules",
228 InputLocation.merge(target.getLocation("modules"), source.getLocation("modules"), indices));
229 }
230 }
231
232
233
234
235
236 @Override
237 protected void mergeModelBase_Repositories(
238 ModelBase target, ModelBase source, boolean sourceDominant, Map<Object, Object> context) {
239 List<Repository> src = source.getRepositories();
240 if (!src.isEmpty()) {
241 List<Repository> tgt = target.getRepositories();
242 Map<Object, Repository> merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2);
243
244 List<Repository> dominant, recessive;
245 if (sourceDominant) {
246 dominant = src;
247 recessive = tgt;
248 } else {
249 dominant = tgt;
250 recessive = src;
251 }
252
253 for (Repository element : dominant) {
254 Object key = getRepositoryKey(element);
255 merged.put(key, element);
256 }
257
258 for (Repository element : recessive) {
259 Object key = getRepositoryKey(element);
260 if (!merged.containsKey(key)) {
261 merged.put(key, element);
262 }
263 }
264
265 target.setRepositories(new ArrayList<>(merged.values()));
266 }
267 }
268
269 @Override
270 protected void mergeModelBase_PluginRepositories(
271 ModelBase target, ModelBase source, boolean sourceDominant, Map<Object, Object> context) {
272 List<Repository> src = source.getPluginRepositories();
273 if (!src.isEmpty()) {
274 List<Repository> tgt = target.getPluginRepositories();
275 Map<Object, Repository> merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2);
276
277 List<Repository> dominant, recessive;
278 if (sourceDominant) {
279 dominant = src;
280 recessive = tgt;
281 } else {
282 dominant = tgt;
283 recessive = src;
284 }
285
286 for (Repository element : dominant) {
287 Object key = getRepositoryKey(element);
288 merged.put(key, element);
289 }
290
291 for (Repository element : recessive) {
292 Object key = getRepositoryKey(element);
293 if (!merged.containsKey(key)) {
294 merged.put(key, element);
295 }
296 }
297
298 target.setPluginRepositories(new ArrayList<>(merged.values()));
299 }
300 }
301
302
303
304
305 @Override
306 protected void mergeBuildBase_Filters(
307 BuildBase target, BuildBase source, boolean sourceDominant, Map<Object, Object> context) {
308 List<String> src = source.getFilters();
309 if (!src.isEmpty()) {
310 List<String> tgt = target.getFilters();
311 Set<String> excludes = new LinkedHashSet<>(tgt);
312 List<String> merged = new ArrayList<>(tgt.size() + src.size());
313 merged.addAll(tgt);
314 for (String s : src) {
315 if (!excludes.contains(s)) {
316 merged.add(s);
317 }
318 }
319 target.setFilters(merged);
320 }
321 }
322
323 @Override
324 protected void mergeBuildBase_Resources(
325 BuildBase target, BuildBase source, boolean sourceDominant, Map<Object, Object> context) {
326 if (sourceDominant || target.getResources().isEmpty()) {
327 super.mergeBuildBase_Resources(target, source, sourceDominant, context);
328 }
329 }
330
331 @Override
332 protected void mergeBuildBase_TestResources(
333 BuildBase target, BuildBase source, boolean sourceDominant, Map<Object, Object> context) {
334 if (sourceDominant || target.getTestResources().isEmpty()) {
335 super.mergeBuildBase_TestResources(target, source, sourceDominant, context);
336 }
337 }
338
339 @Override
340 protected void mergeDistributionManagement_Repository(
341 DistributionManagement target,
342 DistributionManagement source,
343 boolean sourceDominant,
344 Map<Object, Object> context) {
345 DeploymentRepository src = source.getRepository();
346 if (src != null) {
347 DeploymentRepository tgt = target.getRepository();
348 if (sourceDominant || tgt == null) {
349 tgt = new DeploymentRepository();
350 tgt.setLocation("", src.getLocation(""));
351 target.setRepository(tgt);
352 mergeDeploymentRepository(tgt, src, sourceDominant, context);
353 }
354 }
355 }
356
357 @Override
358 protected void mergeDistributionManagement_SnapshotRepository(
359 DistributionManagement target,
360 DistributionManagement source,
361 boolean sourceDominant,
362 Map<Object, Object> context) {
363 DeploymentRepository src = source.getSnapshotRepository();
364 if (src != null) {
365 DeploymentRepository tgt = target.getSnapshotRepository();
366 if (sourceDominant || tgt == null) {
367 tgt = new DeploymentRepository();
368 tgt.setLocation("", src.getLocation(""));
369 target.setSnapshotRepository(tgt);
370 mergeDeploymentRepository(tgt, src, sourceDominant, context);
371 }
372 }
373 }
374
375 @Override
376 protected void mergeDistributionManagement_Site(
377 DistributionManagement target,
378 DistributionManagement source,
379 boolean sourceDominant,
380 Map<Object, Object> context) {
381 Site src = source.getSite();
382 if (src != null) {
383 Site tgt = target.getSite();
384 if (sourceDominant || tgt == null || isSiteEmpty(tgt)) {
385 if (tgt == null) {
386 tgt = new Site();
387 }
388 tgt.setLocation("", src.getLocation(""));
389 target.setSite(tgt);
390 mergeSite(tgt, src, sourceDominant, context);
391 }
392 mergeSite_ChildSiteUrlInheritAppendPath(tgt, src, sourceDominant, context);
393 }
394 }
395
396 @Override
397 protected void mergeSite(Site target, Site source, boolean sourceDominant, Map<Object, Object> context) {
398 mergeSite_Id(target, source, sourceDominant, context);
399 mergeSite_Name(target, source, sourceDominant, context);
400 mergeSite_Url(target, source, sourceDominant, context);
401 }
402
403 protected boolean isSiteEmpty(Site site) {
404 return StringUtils.isEmpty(site.getId())
405 && StringUtils.isEmpty(site.getName())
406 && StringUtils.isEmpty(site.getUrl());
407 }
408
409 @Override
410 protected void mergeSite_Url(Site target, Site source, boolean sourceDominant, Map<Object, Object> context) {
411 String src = source.getUrl();
412 if (src != null) {
413 if (sourceDominant) {
414 target.setUrl(src);
415 target.setLocation("url", source.getLocation("url"));
416 } else if (target.getUrl() == null) {
417 target.setUrl(extrapolateChildUrl(src, source.isChildSiteUrlInheritAppendPath(), context));
418 target.setLocation("url", source.getLocation("url"));
419 }
420 }
421 }
422
423 @Override
424 protected void mergeScm_Url(Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context) {
425 String src = source.getUrl();
426 if (src != null) {
427 if (sourceDominant) {
428 target.setUrl(src);
429 target.setLocation("url", source.getLocation("url"));
430 } else if (target.getUrl() == null) {
431 target.setUrl(extrapolateChildUrl(src, source.isChildScmUrlInheritAppendPath(), context));
432 target.setLocation("url", source.getLocation("url"));
433 }
434 }
435 }
436
437 @Override
438 protected void mergeScm_Connection(Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context) {
439 String src = source.getConnection();
440 if (src != null) {
441 if (sourceDominant) {
442 target.setConnection(src);
443 target.setLocation("connection", source.getLocation("connection"));
444 } else if (target.getConnection() == null) {
445 target.setConnection(extrapolateChildUrl(src, source.isChildScmConnectionInheritAppendPath(), context));
446 target.setLocation("connection", source.getLocation("connection"));
447 }
448 }
449 }
450
451 @Override
452 protected void mergeScm_DeveloperConnection(
453 Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context) {
454 String src = source.getDeveloperConnection();
455 if (src != null) {
456 if (sourceDominant) {
457 target.setDeveloperConnection(src);
458 target.setLocation("developerConnection", source.getLocation("developerConnection"));
459 } else if (target.getDeveloperConnection() == null) {
460 String e = extrapolateChildUrl(src, source.isChildScmDeveloperConnectionInheritAppendPath(), context);
461 target.setDeveloperConnection(e);
462 target.setLocation("developerConnection", source.getLocation("developerConnection"));
463 }
464 }
465 }
466
467 @Override
468 protected void mergePlugin_Executions(
469 Plugin target, Plugin source, boolean sourceDominant, Map<Object, Object> context) {
470 List<PluginExecution> src = source.getExecutions();
471 if (!src.isEmpty()) {
472 List<PluginExecution> tgt = target.getExecutions();
473 Map<Object, PluginExecution> merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2);
474
475 for (PluginExecution element : src) {
476 if (sourceDominant || (element.getInherited() != null ? element.isInherited() : source.isInherited())) {
477 Object key = getPluginExecutionKey(element);
478 merged.put(key, element);
479 }
480 }
481
482 for (PluginExecution element : tgt) {
483 Object key = getPluginExecutionKey(element);
484 PluginExecution existing = merged.get(key);
485 if (existing != null) {
486 mergePluginExecution(element, existing, sourceDominant, context);
487 }
488 merged.put(key, element);
489 }
490
491 target.setExecutions(new ArrayList<>(merged.values()));
492 }
493 }
494
495 @Override
496 protected void mergePluginExecution_Goals(
497 PluginExecution target, PluginExecution source, boolean sourceDominant, Map<Object, Object> context) {
498 List<String> src = source.getGoals();
499 if (!src.isEmpty()) {
500 List<String> tgt = target.getGoals();
501 Set<String> excludes = new LinkedHashSet<>(tgt);
502 List<String> merged = new ArrayList<>(tgt.size() + src.size());
503 merged.addAll(tgt);
504 for (String s : src) {
505 if (!excludes.contains(s)) {
506 merged.add(s);
507 }
508 }
509 target.setGoals(merged);
510 }
511 }
512
513 @Override
514 protected void mergeReportPlugin_ReportSets(
515 ReportPlugin target, ReportPlugin source, boolean sourceDominant, Map<Object, Object> context) {
516 List<ReportSet> src = source.getReportSets();
517 if (!src.isEmpty()) {
518 List<ReportSet> tgt = target.getReportSets();
519 Map<Object, ReportSet> merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2);
520
521 for (ReportSet rset : src) {
522 if (sourceDominant || (rset.getInherited() != null ? rset.isInherited() : source.isInherited())) {
523 Object key = getReportSetKey(rset);
524 merged.put(key, rset);
525 }
526 }
527
528 for (ReportSet element : tgt) {
529 Object key = getReportSetKey(element);
530 ReportSet existing = merged.get(key);
531 if (existing != null) {
532 mergeReportSet(element, existing, sourceDominant, context);
533 }
534 merged.put(key, element);
535 }
536
537 target.setReportSets(new ArrayList<>(merged.values()));
538 }
539 }
540
541 @Override
542 protected Object getDependencyKey(Dependency dependency) {
543 return dependency.getManagementKey();
544 }
545
546 @Override
547 protected Object getPluginKey(Plugin plugin) {
548 return plugin.getKey();
549 }
550
551 @Override
552 protected Object getPluginExecutionKey(PluginExecution pluginExecution) {
553 return pluginExecution.getId();
554 }
555
556 @Override
557 protected Object getReportPluginKey(ReportPlugin reportPlugin) {
558 return reportPlugin.getKey();
559 }
560
561 @Override
562 protected Object getReportSetKey(ReportSet reportSet) {
563 return reportSet.getId();
564 }
565
566 @Override
567 protected Object getRepositoryBaseKey(RepositoryBase repositoryBase) {
568 return repositoryBase.getId();
569 }
570
571 @Override
572 protected Object getExtensionKey(Extension extension) {
573 return extension.getGroupId() + ':' + extension.getArtifactId();
574 }
575
576 @Override
577 protected Object getExclusionKey(Exclusion exclusion) {
578 return exclusion.getGroupId() + ':' + exclusion.getArtifactId();
579 }
580
581 protected String extrapolateChildUrl(String parentUrl, boolean appendPath, Map<Object, Object> context) {
582 return parentUrl;
583 }
584 }