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