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