1   package org.apache.maven.project;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.model.Build;
23  import org.apache.maven.model.Dependency;
24  import org.apache.maven.model.Plugin;
25  import org.apache.maven.model.PluginContainer;
26  import org.apache.maven.model.PluginExecution;
27  import org.apache.maven.model.ReportPlugin;
28  import org.apache.maven.model.Reporting;
29  import org.codehaus.plexus.util.xml.Xpp3Dom;
30  
31  import java.util.Collections;
32  import java.util.Iterator;
33  import java.util.List;
34  import java.util.Map;
35  
36  import junit.framework.TestCase;
37  
38  public class ModelUtilsTest
39      extends TestCase
40  {
41  
42      public void testShouldUseMainPluginDependencyVersionOverManagedDepVersion()
43      {
44          Plugin mgtPlugin = createPlugin( "group", "artifact", "1", Collections.EMPTY_MAP );
45          Dependency mgtDep = createDependency( "g", "a", "2" );
46          mgtPlugin.addDependency( mgtDep );
47  
48          Plugin plugin = createPlugin( "group", "artifact", "1", Collections.EMPTY_MAP );
49          Dependency dep = createDependency( "g", "a", "1" );
50          plugin.addDependency( dep );
51  
52          ModelUtils.mergePluginDefinitions( plugin, mgtPlugin, false );
53  
54          assertEquals( dep.getVersion(), ((Dependency) plugin.getDependencies().get( 0 ) ).getVersion() );
55      }
56  
57      private Dependency createDependency( String gid,
58                                           String aid,
59                                           String ver )
60      {
61          Dependency dep = new Dependency();
62          dep.setGroupId( gid );
63          dep.setArtifactId( aid );
64          dep.setVersion( ver );
65  
66          return dep;
67      }
68  
69      public void testShouldNotInheritPluginWithInheritanceSetToFalse()
70      {
71          PluginContainer parent = new PluginContainer();
72  
73          Plugin parentPlugin = createPlugin( "group", "artifact", "1.0", Collections.EMPTY_MAP );
74          parentPlugin.setInherited( "false" );
75  
76          parent.addPlugin( parentPlugin );
77  
78          PluginContainer child = new PluginContainer();
79  
80          child.addPlugin( createPlugin( "group3", "artifact3", "1.0", Collections.EMPTY_MAP ) );
81  
82          ModelUtils.mergePluginLists( child, parent, true );
83  
84          List results = child.getPlugins();
85  
86          assertEquals( 1, results.size() );
87  
88          Plugin result1 = (Plugin) results.get( 0 );
89          assertEquals( "group3", result1.getGroupId() );
90          assertEquals( "artifact3", result1.getArtifactId() );
91      }
92  
93      /**
94       * Test that this is the resulting ordering of plugins after merging:
95       *
96       * Given:
97       *
98       *   parent: X -> A -> B -> D -> E
99       *   child: Y -> A -> C -> D -> F
100      *
101      * Result:
102      *
103      *   X -> Y -> A -> B -> C -> D -> E -> F
104      */
105     public void testShouldPreserveChildOrderingOfPluginsAfterParentMerge()
106     {
107         PluginContainer parent = new PluginContainer();
108 
109         parent.addPlugin( createPlugin( "group", "artifact", "1.0", Collections.EMPTY_MAP ) );
110         parent.addPlugin( createPlugin( "group2", "artifact2", "1.0", Collections.singletonMap( "key", "value" ) ) );
111 
112         PluginContainer child = new PluginContainer();
113 
114         child.addPlugin( createPlugin( "group3", "artifact3", "1.0", Collections.EMPTY_MAP ) );
115         child.addPlugin( createPlugin( "group2", "artifact2", "1.0", Collections.singletonMap( "key2", "value2" ) ) );
116 
117         ModelUtils.mergePluginLists( child, parent, true );
118 
119         List results = child.getPlugins();
120 
121         assertEquals( 3, results.size() );
122 
123         Plugin result1 = (Plugin) results.get( 0 );
124 
125         assertEquals( "group", result1.getGroupId() );
126         assertEquals( "artifact", result1.getArtifactId() );
127 
128         Plugin result2 = (Plugin) results.get( 1 );
129 
130         assertEquals( "group3", result2.getGroupId() );
131         assertEquals( "artifact3", result2.getArtifactId() );
132 
133         Plugin result3 = (Plugin) results.get( 2 );
134 
135         assertEquals( "group2", result3.getGroupId() );
136         assertEquals( "artifact2", result3.getArtifactId() );
137 
138         Xpp3Dom result3Config = (Xpp3Dom) result3.getConfiguration();
139 
140         assertNotNull( result3Config );
141         assertNotNull( result3Config.getChild( "key" ) );
142         assertNotNull( result3Config.getChild( "key2" ) );
143 
144         assertEquals( "value", result3Config.getChild( "key" ).getValue() );
145         assertEquals( "value2", result3Config.getChild( "key2" ).getValue() );
146     }
147 
148     /**
149      * Test that this is the resulting ordering of reports after merging:
150      *
151      * Given:
152      *
153      *   parent: X -> A -> B -> D -> E
154      *   child: Y -> A -> C -> D -> F
155      *
156      * Result:
157      *
158      *   X -> Y -> A -> B -> C -> D -> E -> F
159      */
160     public void testShouldPreserveChildOrderingOfReportsAfterParentMerge()
161     {
162         Reporting parent = new Reporting();
163 
164         parent.addPlugin( createReportPlugin( "group", "artifact", "1.0", Collections.EMPTY_MAP ) );
165         parent.addPlugin( createReportPlugin( "group2", "artifact2", "1.0", Collections.singletonMap( "key", "value" ) ) );
166 
167         Reporting child = new Reporting();
168 
169         child.addPlugin( createReportPlugin( "group3", "artifact3", "1.0", Collections.EMPTY_MAP ) );
170         child.addPlugin( createReportPlugin( "group2", "artifact2", "1.0", Collections.singletonMap( "key2", "value2" ) ) );
171 
172         ModelUtils.mergeReportPluginLists( child, parent, true );
173 
174         List results = child.getPlugins();
175 
176         assertEquals( 3, results.size() );
177 
178         ReportPlugin result1 = (ReportPlugin) results.get( 0 );
179 
180         assertEquals( "group", result1.getGroupId() );
181         assertEquals( "artifact", result1.getArtifactId() );
182 
183         ReportPlugin result2 = (ReportPlugin) results.get( 1 );
184 
185         assertEquals( "group3", result2.getGroupId() );
186         assertEquals( "artifact3", result2.getArtifactId() );
187 
188         ReportPlugin result3 = (ReportPlugin) results.get( 2 );
189 
190         assertEquals( "group2", result3.getGroupId() );
191         assertEquals( "artifact2", result3.getArtifactId() );
192 
193         Xpp3Dom result3Config = (Xpp3Dom) result3.getConfiguration();
194 
195         assertNotNull( result3Config );
196         assertNotNull( result3Config.getChild( "key" ) );
197         assertNotNull( result3Config.getChild( "key2" ) );
198 
199         //assertEquals( "value", result3Config.getChild( "key" ).getValue() );
200         assertEquals( "value2", result3Config.getChild( "key2" ).getValue() );
201     }
202 
203     private Xpp3Dom createConfiguration( Map configuration )
204     {
205         Xpp3Dom config = new Xpp3Dom( "configuration" );
206 
207         if( configuration != null )
208         {
209             for ( Iterator it = configuration.entrySet().iterator(); it.hasNext(); )
210             {
211                 Map.Entry entry = (Map.Entry) it.next();
212 
213                 Xpp3Dom param = new Xpp3Dom( String.valueOf( entry.getKey() ) );
214                 param.setValue( String.valueOf( entry.getValue() ) );
215 
216                 config.addChild( param );
217             }
218         }
219 
220         return config;
221     }
222 
223     private Plugin createPlugin( String groupId, String artifactId, String version, Map configuration )
224     {
225         Plugin plugin = new Plugin();
226         plugin.setGroupId( groupId );
227         plugin.setArtifactId( artifactId );
228         plugin.setVersion( version );
229         plugin.setConfiguration( createConfiguration( configuration ) );
230         return plugin;
231     }
232 
233     private ReportPlugin createReportPlugin( String groupId, String artifactId, String version, Map configuration )
234     {
235         ReportPlugin plugin = new ReportPlugin();
236         plugin.setGroupId( groupId );
237         plugin.setArtifactId( artifactId );
238         plugin.setVersion( version );
239         plugin.setConfiguration( createConfiguration( configuration ) );
240         return plugin;
241     }
242 
243     public void testShouldInheritOnePluginWithExecution()
244     {
245         Plugin parent = new Plugin();
246         parent.setArtifactId( "testArtifact" );
247         parent.setGroupId( "testGroup" );
248         parent.setVersion( "1.0" );
249 
250         PluginExecution parentExecution = new PluginExecution();
251         parentExecution.setId( "testExecution" );
252 
253         parent.addExecution( parentExecution );
254 
255         Plugin child = new Plugin();
256         child.setArtifactId( "testArtifact" );
257         child.setGroupId( "testGroup" );
258         child.setVersion( "1.0" );
259 
260         ModelUtils.mergePluginDefinitions( child, parent, false );
261 
262         assertEquals( 1, child.getExecutions().size() );
263     }
264 
265     public void testShouldMergeInheritedPluginHavingExecutionWithLocalPlugin()
266     {
267         Plugin parent = new Plugin();
268         parent.setArtifactId( "testArtifact" );
269         parent.setGroupId( "testGroup" );
270         parent.setVersion( "1.0" );
271 
272         PluginExecution parentExecution = new PluginExecution();
273         parentExecution.setId( "testExecution" );
274 
275         parent.addExecution( parentExecution );
276 
277         Plugin child = new Plugin();
278         child.setArtifactId( "testArtifact" );
279         child.setGroupId( "testGroup" );
280         child.setVersion( "1.0" );
281 
282         PluginExecution childExecution = new PluginExecution();
283         childExecution.setId( "testExecution2" );
284 
285         child.addExecution( childExecution );
286 
287         ModelUtils.mergePluginDefinitions( child, parent, false );
288 
289         assertEquals( 2, child.getExecutions().size() );
290     }
291 
292     public void testShouldMergeOnePluginWithInheritExecutionWithoutDuplicatingPluginInList()
293     {
294         Plugin parent = new Plugin();
295         parent.setArtifactId( "testArtifact" );
296         parent.setGroupId( "testGroup" );
297         parent.setVersion( "1.0" );
298 
299         PluginExecution parentExecution = new PluginExecution();
300         parentExecution.setId( "testExecution" );
301 
302         parent.addExecution( parentExecution );
303 
304         Build parentContainer = new Build();
305         parentContainer.addPlugin( parent );
306 
307         Plugin child = new Plugin();
308         child.setArtifactId( "testArtifact" );
309         child.setGroupId( "testGroup" );
310         child.setVersion( "1.0" );
311 
312         Build childContainer = new Build();
313         childContainer.addPlugin( child );
314 
315         ModelUtils.mergePluginLists( childContainer, parentContainer, true );
316 
317         List plugins = childContainer.getPlugins();
318 
319         assertEquals( 1, plugins.size() );
320 
321         Plugin plugin = (Plugin) plugins.get( 0 );
322 
323         assertEquals( 1, plugin.getExecutions().size() );
324     }
325 
326     public void testShouldMergePluginWithDifferentExecutionFromParentWithoutDuplicatingPluginInList()
327     {
328         Plugin parent = new Plugin();
329         parent.setArtifactId( "testArtifact" );
330         parent.setGroupId( "testGroup" );
331         parent.setVersion( "1.0" );
332 
333         PluginExecution parentExecution = new PluginExecution();
334         parentExecution.setId( "testExecution" );
335 
336         parent.addExecution( parentExecution );
337 
338         Build parentContainer = new Build();
339         parentContainer.addPlugin( parent );
340 
341         Plugin child = new Plugin();
342         child.setArtifactId( "testArtifact" );
343         child.setGroupId( "testGroup" );
344         child.setVersion( "1.0" );
345 
346         PluginExecution childExecution = new PluginExecution();
347         childExecution.setId( "testExecution2" );
348 
349         child.addExecution( childExecution );
350 
351 
352         Build childContainer = new Build();
353         childContainer.addPlugin( child );
354 
355         ModelUtils.mergePluginLists( childContainer, parentContainer, true );
356 
357         List plugins = childContainer.getPlugins();
358 
359         assertEquals( 1, plugins.size() );
360 
361         Plugin plugin = (Plugin) plugins.get( 0 );
362 
363         assertEquals( 2, plugin.getExecutions().size() );
364     }
365 
366     public void testShouldNOTMergeInheritedPluginHavingInheritEqualFalse()
367     {
368         Plugin parent = new Plugin();
369         parent.setArtifactId( "testArtifact" );
370         parent.setGroupId( "testGroup" );
371         parent.setVersion( "1.0" );
372         parent.setInherited( "false" );
373 
374         PluginExecution parentExecution = new PluginExecution();
375         parentExecution.setId( "testExecution" );
376 
377         parent.addExecution( parentExecution );
378 
379         Plugin child = new Plugin();
380         child.setArtifactId( "testArtifact" );
381         child.setGroupId( "testGroup" );
382         child.setVersion( "1.0" );
383 
384         ModelUtils.mergePluginDefinitions( child, parent, true );
385 
386         assertEquals( 0, child.getExecutions().size() );
387     }
388 
389     /**
390      * Verifies MNG-1499: The order of the merged list should be the plugins specified by the parent followed by the
391      * child list.
392      */
393     public void testShouldKeepOriginalPluginOrdering()
394     {
395         Plugin parentPlugin1 = new Plugin();
396         parentPlugin1.setArtifactId( "testArtifact" );
397         parentPlugin1.setGroupId( "zzz" );  // This will put this plugin last in the sorted map
398         parentPlugin1.setVersion( "1.0" );
399 
400         PluginExecution parentExecution1 = new PluginExecution();
401         parentExecution1.setId( "testExecution" );
402 
403         parentPlugin1.addExecution( parentExecution1 );
404 
405         Plugin parentPlugin2 = new Plugin();
406         parentPlugin2.setArtifactId( "testArtifact" );
407         parentPlugin2.setGroupId( "yyy" );
408         parentPlugin2.setVersion( "1.0" );
409 
410         PluginExecution parentExecution2 = new PluginExecution();
411         parentExecution2.setId( "testExecution" );
412 
413         parentPlugin2.addExecution( parentExecution2 );
414 
415         PluginContainer parentContainer = new PluginContainer();
416         parentContainer.addPlugin(parentPlugin1);
417         parentContainer.addPlugin(parentPlugin2);
418 
419 
420         Plugin childPlugin1 = new Plugin();
421         childPlugin1.setArtifactId( "testArtifact" );
422         childPlugin1.setGroupId( "bbb" );
423         childPlugin1.setVersion( "1.0" );
424 
425         PluginExecution childExecution1 = new PluginExecution();
426         childExecution1.setId( "testExecution" );
427 
428         childPlugin1.addExecution( childExecution1 );
429 
430         Plugin childPlugin2 = new Plugin();
431         childPlugin2.setArtifactId( "testArtifact" );
432         childPlugin2.setGroupId( "aaa" );
433         childPlugin2.setVersion( "1.0" );
434 
435         PluginExecution childExecution2 = new PluginExecution();
436         childExecution2.setId( "testExecution" );
437 
438         childPlugin2.addExecution( childExecution2 );
439 
440         PluginContainer childContainer = new PluginContainer();
441         childContainer.addPlugin(childPlugin1);
442         childContainer.addPlugin(childPlugin2);
443 
444 
445         ModelUtils.mergePluginLists(childContainer, parentContainer, true);
446 
447         assertEquals( 4, childContainer.getPlugins().size() );
448         assertSame(parentPlugin1, childContainer.getPlugins().get(0));
449         assertSame(parentPlugin2, childContainer.getPlugins().get(1));
450         assertSame(childPlugin1, childContainer.getPlugins().get(2));
451         assertSame(childPlugin2, childContainer.getPlugins().get(3));
452     }
453 
454     /**
455      * Verifies MNG-1499: The ordering of plugin executions should also be in the specified order.
456      */
457     public void testShouldKeepOriginalPluginExecutionOrdering()
458     {
459         Plugin parent = new Plugin();
460         parent.setArtifactId( "testArtifact" );
461         parent.setGroupId( "testGroup" );
462         parent.setVersion( "1.0" );
463 
464         PluginExecution parentExecution1 = new PluginExecution();
465         parentExecution1.setId( "zzz" );  // Will show up last in the sorted map
466         PluginExecution parentExecution2 = new PluginExecution();
467         parentExecution2.setId( "yyy" );  // Will show up last in the sorted map
468 
469         parent.addExecution( parentExecution1 );
470         parent.addExecution( parentExecution2 );
471 
472         // this block verifies MNG-1703
473         Dependency dep = new Dependency();
474         dep.setGroupId( "depGroupId" );
475         dep.setArtifactId( "depArtifactId" );
476         dep.setVersion( "depVersion" );
477         parent.setDependencies( Collections.singletonList( dep ) );
478 
479         Plugin child = new Plugin();
480         child.setArtifactId( "testArtifact" );
481         child.setGroupId( "testGroup" );
482         child.setVersion( "1.0" );
483 
484         PluginExecution childExecution1 = new PluginExecution();
485         childExecution1.setId( "bbb" );
486         PluginExecution childExecution2 = new PluginExecution();
487         childExecution2.setId( "aaa" );
488 
489         child.addExecution( childExecution1 );
490         child.addExecution( childExecution2 );
491 
492         ModelUtils.mergePluginDefinitions( child, parent, false );
493 
494         assertEquals( 4, child.getExecutions().size() );
495         assertSame(parentExecution1, child.getExecutions().get(0));
496         assertSame(parentExecution2, child.getExecutions().get(1));
497         assertSame(childExecution1, child.getExecutions().get(2));
498         assertSame(childExecution2, child.getExecutions().get(3));
499 
500         // this block prevents MNG-1703
501         assertEquals( 1, child.getDependencies().size() );
502         Dependency dep2 = (Dependency) child.getDependencies().get( 0 );
503         assertEquals( dep.getManagementKey(), dep2.getManagementKey() );
504     }
505 
506     public void testShouldMergeTwoPluginDependenciesOnMergeDupePluginDefs()
507     {
508         PluginContainer first = new PluginContainer();
509         Plugin fPlugin = createPlugin( "g", "a", "1", Collections.EMPTY_MAP );
510         Dependency fDep = new Dependency();
511         fDep.setGroupId( "group" );
512         fDep.setArtifactId( "artifact" );
513         fDep.setVersion( "1" );
514 
515         first.addPlugin( fPlugin );
516         fPlugin.addDependency( fDep );
517 
518         Plugin sPlugin = createPlugin( "g", "a", "1", Collections.EMPTY_MAP );
519         Dependency sDep = new Dependency();
520         sDep.setGroupId( "group" );
521         sDep.setArtifactId( "artifact2" );
522         sDep.setVersion( "1" );
523         first.addPlugin( sPlugin );
524         sPlugin.addDependency( sDep );
525 
526         ModelUtils.mergeDuplicatePluginDefinitions( first );
527 
528         assertEquals( 2, ((Plugin)first.getPlugins().get( 0 ) ).getDependencies().size() );
529     }
530 
531     public void testShouldNotMergePluginExecutionWhenExecInheritedIsFalseAndTreatAsInheritanceIsTrue()
532     {
533         String gid = "group";
534         String aid = "artifact";
535         String ver = "1";
536 
537         PluginContainer parent = new PluginContainer();
538         Plugin pParent = createPlugin( gid, aid, ver, Collections.EMPTY_MAP );
539 
540         pParent.setInherited( Boolean.toString( true ) );
541 
542         PluginExecution eParent = new PluginExecution();
543 
544         String testId = "test";
545 
546         eParent.setId( testId );
547         eParent.addGoal( "run" );
548         eParent.setPhase( "initialize" );
549         eParent.setInherited( Boolean.toString( false ) );
550 
551         pParent.addExecution( eParent );
552         parent.addPlugin( pParent );
553 
554         PluginContainer child = new PluginContainer();
555         Plugin pChild = createPlugin( gid, aid, ver, Collections.EMPTY_MAP );
556         PluginExecution eChild = new PluginExecution();
557 
558         eChild.setId( "child-specified" );
559         eChild.addGoal( "child" );
560         eChild.setPhase( "compile" );
561 
562         pChild.addExecution( eChild );
563         child.addPlugin( pChild );
564 
565         ModelUtils.mergePluginDefinitions( pChild, pParent, true );
566 
567         Map executionMap = pChild.getExecutionsAsMap();
568         assertNull( "test execution should not be inherited from parent.", executionMap.get( testId ) );
569     }
570 
571     public void testShouldNotMergePluginExecutionWhenPluginInheritedIsFalseAndTreatAsInheritanceIsTrue()
572     {
573         String gid = "group";
574         String aid = "artifact";
575         String ver = "1";
576 
577         PluginContainer parent = new PluginContainer();
578         Plugin pParent = createPlugin( gid, aid, ver, Collections.EMPTY_MAP );
579 
580         pParent.setInherited( Boolean.toString( false ) );
581 
582         PluginExecution eParent = new PluginExecution();
583 
584         String testId = "test";
585 
586         eParent.setId( testId );
587         eParent.addGoal( "run" );
588         eParent.setPhase( "initialize" );
589         eParent.setInherited( Boolean.toString( true ) );
590 
591         pParent.addExecution( eParent );
592         parent.addPlugin( pParent );
593 
594         PluginContainer child = new PluginContainer();
595         Plugin pChild = createPlugin( gid, aid, ver, Collections.EMPTY_MAP );
596         PluginExecution eChild = new PluginExecution();
597 
598         eChild.setId( "child-specified" );
599         eChild.addGoal( "child" );
600         eChild.setPhase( "compile" );
601 
602         pChild.addExecution( eChild );
603         child.addPlugin( pChild );
604 
605         ModelUtils.mergePluginDefinitions( pChild, pParent, true );
606 
607         Map executionMap = pChild.getExecutionsAsMap();
608         assertNull( "test execution should not be inherited from parent.", executionMap.get( testId ) );
609     }
610 
611     public void testShouldMergePluginExecutionWhenExecInheritedIsTrueAndTreatAsInheritanceIsTrue()
612     {
613         String gid = "group";
614         String aid = "artifact";
615         String ver = "1";
616 
617         PluginContainer parent = new PluginContainer();
618         Plugin pParent = createPlugin( gid, aid, ver, Collections.EMPTY_MAP );
619 
620         pParent.setInherited( Boolean.toString( true ) );
621 
622         PluginExecution eParent = new PluginExecution();
623 
624         String testId = "test";
625 
626         eParent.setId( testId );
627         eParent.addGoal( "run" );
628         eParent.setPhase( "initialize" );
629         eParent.setInherited( Boolean.toString( true ) );
630 
631         pParent.addExecution( eParent );
632         parent.addPlugin( pParent );
633 
634         PluginContainer child = new PluginContainer();
635         Plugin pChild = createPlugin( gid, aid, ver, Collections.EMPTY_MAP );
636         PluginExecution eChild = new PluginExecution();
637 
638         eChild.setId( "child-specified" );
639         eChild.addGoal( "child" );
640         eChild.setPhase( "compile" );
641 
642         pChild.addExecution( eChild );
643         child.addPlugin( pChild );
644 
645         ModelUtils.mergePluginDefinitions( pChild, pParent, true );
646 
647         Map executionMap = pChild.getExecutionsAsMap();
648         assertNotNull( "test execution should be inherited from parent.", executionMap.get( testId ) );
649     }
650 
651 }