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