001package org.apache.maven.project; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.io.IOException; 023import java.io.StringReader; 024import java.util.Arrays; 025import java.util.Collections; 026import java.util.List; 027import java.util.Map; 028 029import junit.framework.TestCase; 030 031import org.apache.maven.model.Build; 032import org.apache.maven.model.Dependency; 033import org.apache.maven.model.Plugin; 034import org.apache.maven.model.PluginContainer; 035import org.apache.maven.model.PluginExecution; 036import org.codehaus.plexus.util.xml.Xpp3Dom; 037import org.codehaus.plexus.util.xml.Xpp3DomBuilder; 038import org.codehaus.plexus.util.xml.pull.XmlPullParserException; 039 040public class ModelUtilsTest 041 extends TestCase 042{ 043 044 public void testShouldUseMainPluginDependencyVersionOverManagedDepVersion() 045 { 046 Plugin mgtPlugin = createPlugin( "group", "artifact", "1", Collections.EMPTY_MAP ); 047 Dependency mgtDep = createDependency( "g", "a", "2" ); 048 mgtPlugin.addDependency( mgtDep ); 049 050 Plugin plugin = createPlugin( "group", "artifact", "1", Collections.EMPTY_MAP ); 051 Dependency dep = createDependency( "g", "a", "1" ); 052 plugin.addDependency( dep ); 053 054 ModelUtils.mergePluginDefinitions( plugin, mgtPlugin, false ); 055 056 assertEquals( dep.getVersion(), plugin.getDependencies().get( 0 ).getVersion() ); 057 } 058 059 private Dependency createDependency( String gid, 060 String aid, 061 String ver ) 062 { 063 Dependency dep = new Dependency(); 064 dep.setGroupId( gid ); 065 dep.setArtifactId( aid ); 066 dep.setVersion( ver ); 067 068 return dep; 069 } 070 071 public void testShouldNotInheritPluginWithInheritanceSetToFalse() 072 { 073 PluginContainer parent = new PluginContainer(); 074 075 Plugin parentPlugin = createPlugin( "group", "artifact", "1.0", Collections.EMPTY_MAP ); 076 parentPlugin.setInherited( "false" ); 077 078 parent.addPlugin( parentPlugin ); 079 080 PluginContainer child = new PluginContainer(); 081 082 child.addPlugin( createPlugin( "group3", "artifact3", "1.0", Collections.EMPTY_MAP ) ); 083 084 ModelUtils.mergePluginLists( child, parent, true ); 085 086 List results = child.getPlugins(); 087 088 assertEquals( 1, results.size() ); 089 090 Plugin result1 = (Plugin) results.get( 0 ); 091 assertEquals( "group3", result1.getGroupId() ); 092 assertEquals( "artifact3", result1.getArtifactId() ); 093 } 094 095 /** 096 * Test that this is the resulting ordering of plugins after merging: 097 * 098 * Given: 099 * 100 * parent: X -> A -> B -> D -> E 101 * child: Y -> A -> C -> D -> F 102 * 103 * Result: 104 * 105 * X -> Y -> A -> B -> C -> D -> E -> F 106 */ 107 public void testShouldPreserveChildOrderingOfPluginsAfterParentMerge() 108 { 109 PluginContainer parent = new PluginContainer(); 110 111 parent.addPlugin( createPlugin( "group", "artifact", "1.0", Collections.EMPTY_MAP ) ); 112 parent.addPlugin( createPlugin( "group2", "artifact2", "1.0", Collections.singletonMap( "key", "value" ) ) ); 113 114 PluginContainer child = new PluginContainer(); 115 116 child.addPlugin( createPlugin( "group3", "artifact3", "1.0", Collections.EMPTY_MAP ) ); 117 child.addPlugin( createPlugin( "group2", "artifact2", "1.0", Collections.singletonMap( "key2", "value2" ) ) ); 118 119 ModelUtils.mergePluginLists( child, parent, true ); 120 121 List results = child.getPlugins(); 122 123 assertEquals( 3, results.size() ); 124 125 Plugin result1 = (Plugin) results.get( 0 ); 126 127 assertEquals( "group", result1.getGroupId() ); 128 assertEquals( "artifact", result1.getArtifactId() ); 129 130 Plugin result2 = (Plugin) results.get( 1 ); 131 132 assertEquals( "group3", result2.getGroupId() ); 133 assertEquals( "artifact3", result2.getArtifactId() ); 134 135 Plugin result3 = (Plugin) results.get( 2 ); 136 137 assertEquals( "group2", result3.getGroupId() ); 138 assertEquals( "artifact2", result3.getArtifactId() ); 139 140 Xpp3Dom result3Config = (Xpp3Dom) result3.getConfiguration(); 141 142 assertNotNull( result3Config ); 143 144 assertEquals( "value", result3Config.getChild( "key" ).getValue() ); 145 assertEquals( "value2", result3Config.getChild( "key2" ).getValue() ); 146 } 147 148 private Plugin createPlugin( String groupId, String artifactId, String version, Map configuration ) 149 { 150 Plugin plugin = new Plugin(); 151 plugin.setGroupId( groupId ); 152 plugin.setArtifactId( artifactId ); 153 plugin.setVersion( version ); 154 155 Xpp3Dom config = new Xpp3Dom( "configuration" ); 156 157 if( configuration != null ) 158 { 159 for ( Object o : configuration.entrySet() ) 160 { 161 Map.Entry entry = (Map.Entry) o; 162 163 Xpp3Dom param = new Xpp3Dom( String.valueOf( entry.getKey() ) ); 164 param.setValue( String.valueOf( entry.getValue() ) ); 165 166 config.addChild( param ); 167 } 168 } 169 170 plugin.setConfiguration( config ); 171 172 return plugin; 173 } 174 175 public void testShouldInheritOnePluginWithExecution() 176 { 177 Plugin parent = new Plugin(); 178 parent.setArtifactId( "testArtifact" ); 179 parent.setGroupId( "testGroup" ); 180 parent.setVersion( "1.0" ); 181 182 PluginExecution parentExecution = new PluginExecution(); 183 parentExecution.setId( "testExecution" ); 184 185 parent.addExecution( parentExecution ); 186 187 Plugin child = new Plugin(); 188 child.setArtifactId( "testArtifact" ); 189 child.setGroupId( "testGroup" ); 190 child.setVersion( "1.0" ); 191 192 ModelUtils.mergePluginDefinitions( child, parent, false ); 193 194 assertEquals( 1, child.getExecutions().size() ); 195 } 196 197 public void testShouldMergeInheritedPluginHavingExecutionWithLocalPlugin() 198 { 199 Plugin parent = new Plugin(); 200 parent.setArtifactId( "testArtifact" ); 201 parent.setGroupId( "testGroup" ); 202 parent.setVersion( "1.0" ); 203 204 PluginExecution parentExecution = new PluginExecution(); 205 parentExecution.setId( "testExecution" ); 206 207 parent.addExecution( parentExecution ); 208 209 Plugin child = new Plugin(); 210 child.setArtifactId( "testArtifact" ); 211 child.setGroupId( "testGroup" ); 212 child.setVersion( "1.0" ); 213 214 PluginExecution childExecution = new PluginExecution(); 215 childExecution.setId( "testExecution2" ); 216 217 child.addExecution( childExecution ); 218 219 ModelUtils.mergePluginDefinitions( child, parent, false ); 220 221 assertEquals( 2, child.getExecutions().size() ); 222 } 223 224 public void testShouldMergeOnePluginWithInheritExecutionWithoutDuplicatingPluginInList() 225 { 226 Plugin parent = new Plugin(); 227 parent.setArtifactId( "testArtifact" ); 228 parent.setGroupId( "testGroup" ); 229 parent.setVersion( "1.0" ); 230 231 PluginExecution parentExecution = new PluginExecution(); 232 parentExecution.setId( "testExecution" ); 233 234 parent.addExecution( parentExecution ); 235 236 Build parentContainer = new Build(); 237 parentContainer.addPlugin( parent ); 238 239 Plugin child = new Plugin(); 240 child.setArtifactId( "testArtifact" ); 241 child.setGroupId( "testGroup" ); 242 child.setVersion( "1.0" ); 243 244 Build childContainer = new Build(); 245 childContainer.addPlugin( child ); 246 247 ModelUtils.mergePluginLists( childContainer, parentContainer, true ); 248 249 List plugins = childContainer.getPlugins(); 250 251 assertEquals( 1, plugins.size() ); 252 253 Plugin plugin = (Plugin) plugins.get( 0 ); 254 255 assertEquals( 1, plugin.getExecutions().size() ); 256 } 257 258 public void testShouldMergePluginWithDifferentExecutionFromParentWithoutDuplicatingPluginInList() 259 { 260 Plugin parent = new Plugin(); 261 parent.setArtifactId( "testArtifact" ); 262 parent.setGroupId( "testGroup" ); 263 parent.setVersion( "1.0" ); 264 265 PluginExecution parentExecution = new PluginExecution(); 266 parentExecution.setId( "testExecution" ); 267 268 parent.addExecution( parentExecution ); 269 270 Build parentContainer = new Build(); 271 parentContainer.addPlugin( parent ); 272 273 Plugin child = new Plugin(); 274 child.setArtifactId( "testArtifact" ); 275 child.setGroupId( "testGroup" ); 276 child.setVersion( "1.0" ); 277 278 PluginExecution childExecution = new PluginExecution(); 279 childExecution.setId( "testExecution2" ); 280 281 child.addExecution( childExecution ); 282 283 284 Build childContainer = new Build(); 285 childContainer.addPlugin( child ); 286 287 ModelUtils.mergePluginLists( childContainer, parentContainer, true ); 288 289 List plugins = childContainer.getPlugins(); 290 291 assertEquals( 1, plugins.size() ); 292 293 Plugin plugin = (Plugin) plugins.get( 0 ); 294 295 assertEquals( 2, plugin.getExecutions().size() ); 296 } 297 298 public void testShouldNOTMergeInheritedPluginHavingInheritEqualFalse() 299 { 300 Plugin parent = new Plugin(); 301 parent.setArtifactId( "testArtifact" ); 302 parent.setGroupId( "testGroup" ); 303 parent.setVersion( "1.0" ); 304 parent.setInherited( "false" ); 305 306 PluginExecution parentExecution = new PluginExecution(); 307 parentExecution.setId( "testExecution" ); 308 309 parent.addExecution( parentExecution ); 310 311 Plugin child = new Plugin(); 312 child.setArtifactId( "testArtifact" ); 313 child.setGroupId( "testGroup" ); 314 child.setVersion( "1.0" ); 315 316 ModelUtils.mergePluginDefinitions( child, parent, true ); 317 318 assertEquals( 0, child.getExecutions().size() ); 319 } 320 321 /** 322 * Verifies MNG-1499: The order of the merged list should be the plugins specified by the parent followed by the 323 * child list. 324 */ 325 public void testShouldKeepOriginalPluginOrdering() 326 { 327 Plugin parentPlugin1 = new Plugin(); 328 parentPlugin1.setArtifactId( "testArtifact" ); 329 parentPlugin1.setGroupId( "zzz" ); // This will put this plugin last in the sorted map 330 parentPlugin1.setVersion( "1.0" ); 331 332 PluginExecution parentExecution1 = new PluginExecution(); 333 parentExecution1.setId( "testExecution" ); 334 335 parentPlugin1.addExecution( parentExecution1 ); 336 337 Plugin parentPlugin2 = new Plugin(); 338 parentPlugin2.setArtifactId( "testArtifact" ); 339 parentPlugin2.setGroupId( "yyy" ); 340 parentPlugin2.setVersion( "1.0" ); 341 342 PluginExecution parentExecution2 = new PluginExecution(); 343 parentExecution2.setId( "testExecution" ); 344 345 parentPlugin2.addExecution( parentExecution2 ); 346 347 PluginContainer parentContainer = new PluginContainer(); 348 parentContainer.addPlugin(parentPlugin1); 349 parentContainer.addPlugin(parentPlugin2); 350 351 352 Plugin childPlugin1 = new Plugin(); 353 childPlugin1.setArtifactId( "testArtifact" ); 354 childPlugin1.setGroupId( "bbb" ); 355 childPlugin1.setVersion( "1.0" ); 356 357 PluginExecution childExecution1 = new PluginExecution(); 358 childExecution1.setId( "testExecution" ); 359 360 childPlugin1.addExecution( childExecution1 ); 361 362 Plugin childPlugin2 = new Plugin(); 363 childPlugin2.setArtifactId( "testArtifact" ); 364 childPlugin2.setGroupId( "aaa" ); 365 childPlugin2.setVersion( "1.0" ); 366 367 PluginExecution childExecution2 = new PluginExecution(); 368 childExecution2.setId( "testExecution" ); 369 370 childPlugin2.addExecution( childExecution2 ); 371 372 PluginContainer childContainer = new PluginContainer(); 373 childContainer.addPlugin(childPlugin1); 374 childContainer.addPlugin(childPlugin2); 375 376 377 ModelUtils.mergePluginLists(childContainer, parentContainer, true); 378 379 assertEquals( 4, childContainer.getPlugins().size() ); 380 assertSame(parentPlugin1, childContainer.getPlugins().get(0)); 381 assertSame(parentPlugin2, childContainer.getPlugins().get(1)); 382 assertSame(childPlugin1, childContainer.getPlugins().get(2)); 383 assertSame(childPlugin2, childContainer.getPlugins().get(3)); 384 } 385 386 /** 387 * Verifies MNG-1499: The ordering of plugin executions should also be in the specified order. 388 */ 389 public void testShouldKeepOriginalPluginExecutionOrdering() 390 { 391 Plugin parent = new Plugin(); 392 parent.setArtifactId( "testArtifact" ); 393 parent.setGroupId( "testGroup" ); 394 parent.setVersion( "1.0" ); 395 396 PluginExecution parentExecution1 = new PluginExecution(); 397 parentExecution1.setId( "zzz" ); // Will show up last in the sorted map 398 PluginExecution parentExecution2 = new PluginExecution(); 399 parentExecution2.setId( "yyy" ); // Will show up last in the sorted map 400 401 parent.addExecution( parentExecution1 ); 402 parent.addExecution( parentExecution2 ); 403 404 // this block verifies MNG-1703 405 Dependency dep = new Dependency(); 406 dep.setGroupId( "depGroupId" ); 407 dep.setArtifactId( "depArtifactId" ); 408 dep.setVersion( "depVersion" ); 409 parent.setDependencies( Collections.singletonList( dep ) ); 410 411 Plugin child = new Plugin(); 412 child.setArtifactId( "testArtifact" ); 413 child.setGroupId( "testGroup" ); 414 child.setVersion( "1.0" ); 415 416 PluginExecution childExecution1 = new PluginExecution(); 417 childExecution1.setId( "bbb" ); 418 PluginExecution childExecution2 = new PluginExecution(); 419 childExecution2.setId( "aaa" ); 420 421 child.addExecution( childExecution1 ); 422 child.addExecution( childExecution2 ); 423 424 ModelUtils.mergePluginDefinitions( child, parent, false ); 425 426 assertEquals( 4, child.getExecutions().size() ); 427 assertSame(parentExecution1, child.getExecutions().get(0)); 428 assertSame(parentExecution2, child.getExecutions().get(1)); 429 assertSame(childExecution1, child.getExecutions().get(2)); 430 assertSame(childExecution2, child.getExecutions().get(3)); 431 432 // this block prevents MNG-1703 433 assertEquals( 1, child.getDependencies().size() ); 434 Dependency dep2 = child.getDependencies().get( 0 ); 435 assertEquals( dep.getManagementKey(), dep2.getManagementKey() ); 436 } 437 438 public void testShouldOverwritePluginConfigurationSubItemsByDefault() 439 throws XmlPullParserException, IOException 440 { 441 String parentConfigStr = "<configuration><items><item>one</item><item>two</item></items></configuration>"; 442 Xpp3Dom parentConfig = Xpp3DomBuilder.build( new StringReader( parentConfigStr ) ); 443 444 Plugin parentPlugin = createPlugin( "group", "artifact", "1", null ); 445 parentPlugin.setConfiguration( parentConfig ); 446 447 String childConfigStr = "<configuration><items><item>three</item></items></configuration>"; 448 Xpp3Dom childConfig = Xpp3DomBuilder.build( new StringReader( childConfigStr ) ); 449 450 Plugin childPlugin = createPlugin( "group", "artifact", "1", null ); 451 childPlugin.setConfiguration( childConfig ); 452 453 ModelUtils.mergePluginDefinitions( childPlugin, parentPlugin, true ); 454 455 Xpp3Dom result = (Xpp3Dom) childPlugin.getConfiguration(); 456 Xpp3Dom items = result.getChild( "items" ); 457 458 assertEquals( 1, items.getChildCount() ); 459 460 Xpp3Dom item = items.getChild( 0 ); 461 assertEquals( "three", item.getValue() ); 462 } 463 464 public void testShouldMergePluginConfigurationSubItemsWithMergeAttributeSet() 465 throws XmlPullParserException, IOException 466 { 467 String parentConfigStr = "<configuration><items><item>one</item><item>two</item></items></configuration>"; 468 Xpp3Dom parentConfig = Xpp3DomBuilder.build( new StringReader( parentConfigStr ) ); 469 470 Plugin parentPlugin = createPlugin( "group", "artifact", "1", null ); 471 parentPlugin.setConfiguration( parentConfig ); 472 473 String childConfigStr = "<configuration><items combine.children=\"append\"><item>three</item></items></configuration>"; 474 Xpp3Dom childConfig = Xpp3DomBuilder.build( new StringReader( childConfigStr ) ); 475 476 Plugin childPlugin = createPlugin( "group", "artifact", "1", null ); 477 childPlugin.setConfiguration( childConfig ); 478 479 ModelUtils.mergePluginDefinitions( childPlugin, parentPlugin, true ); 480 481 Xpp3Dom result = (Xpp3Dom) childPlugin.getConfiguration(); 482 Xpp3Dom items = result.getChild( "items" ); 483 484 assertEquals( 3, items.getChildCount() ); 485 486 Xpp3Dom[] item = items.getChildren(); 487 488 List<String> actual = Arrays.asList( item[0].getValue(), item[1].getValue(), item[2].getValue() ); 489 List<String> expected = Arrays.asList( "one", "two", "three" ); 490 Collections.sort( actual ); 491 Collections.sort( expected ); 492 assertEquals( expected, actual ); 493 } 494 495 public void testShouldNotMergePluginExecutionWhenExecInheritedIsFalseAndTreatAsInheritanceIsTrue() 496 { 497 String gid = "group"; 498 String aid = "artifact"; 499 String ver = "1"; 500 501 PluginContainer parent = new PluginContainer(); 502 Plugin pParent = createPlugin( gid, aid, ver, Collections.EMPTY_MAP ); 503 504 pParent.setInherited( Boolean.toString( true ) ); 505 506 PluginExecution eParent = new PluginExecution(); 507 508 String testId = "test"; 509 510 eParent.setId( testId ); 511 eParent.addGoal( "run" ); 512 eParent.setPhase( "initialize" ); 513 eParent.setInherited( Boolean.toString( false ) ); 514 515 pParent.addExecution( eParent ); 516 parent.addPlugin( pParent ); 517 518 PluginContainer child = new PluginContainer(); 519 Plugin pChild = createPlugin( gid, aid, ver, Collections.EMPTY_MAP ); 520 PluginExecution eChild = new PluginExecution(); 521 522 eChild.setId( "child-specified" ); 523 eChild.addGoal( "child" ); 524 eChild.setPhase( "compile" ); 525 526 pChild.addExecution( eChild ); 527 child.addPlugin( pChild ); 528 529 ModelUtils.mergePluginDefinitions( pChild, pParent, true ); 530 531 Map executionMap = pChild.getExecutionsAsMap(); 532 assertNull( "test execution should not be inherited from parent.", executionMap.get( testId ) ); 533 } 534 535 public void testShouldNotMergePluginExecutionWhenPluginInheritedIsFalseAndTreatAsInheritanceIsTrue() 536 { 537 String gid = "group"; 538 String aid = "artifact"; 539 String ver = "1"; 540 541 PluginContainer parent = new PluginContainer(); 542 Plugin pParent = createPlugin( gid, aid, ver, Collections.EMPTY_MAP ); 543 544 pParent.setInherited( Boolean.toString( false ) ); 545 546 PluginExecution eParent = new PluginExecution(); 547 548 String testId = "test"; 549 550 eParent.setId( testId ); 551 eParent.addGoal( "run" ); 552 eParent.setPhase( "initialize" ); 553 eParent.setInherited( Boolean.toString( true ) ); 554 555 pParent.addExecution( eParent ); 556 parent.addPlugin( pParent ); 557 558 PluginContainer child = new PluginContainer(); 559 Plugin pChild = createPlugin( gid, aid, ver, Collections.EMPTY_MAP ); 560 PluginExecution eChild = new PluginExecution(); 561 562 eChild.setId( "child-specified" ); 563 eChild.addGoal( "child" ); 564 eChild.setPhase( "compile" ); 565 566 pChild.addExecution( eChild ); 567 child.addPlugin( pChild ); 568 569 ModelUtils.mergePluginDefinitions( pChild, pParent, true ); 570 571 Map executionMap = pChild.getExecutionsAsMap(); 572 assertNull( "test execution should not be inherited from parent.", executionMap.get( testId ) ); 573 } 574 575 public void testShouldMergePluginExecutionWhenExecInheritedIsTrueAndTreatAsInheritanceIsTrue() 576 { 577 String gid = "group"; 578 String aid = "artifact"; 579 String ver = "1"; 580 581 PluginContainer parent = new PluginContainer(); 582 Plugin pParent = createPlugin( gid, aid, ver, Collections.EMPTY_MAP ); 583 584 pParent.setInherited( Boolean.toString( true ) ); 585 586 PluginExecution eParent = new PluginExecution(); 587 588 String testId = "test"; 589 590 eParent.setId( testId ); 591 eParent.addGoal( "run" ); 592 eParent.setPhase( "initialize" ); 593 eParent.setInherited( Boolean.toString( true ) ); 594 595 pParent.addExecution( eParent ); 596 parent.addPlugin( pParent ); 597 598 PluginContainer child = new PluginContainer(); 599 Plugin pChild = createPlugin( gid, aid, ver, Collections.EMPTY_MAP ); 600 PluginExecution eChild = new PluginExecution(); 601 602 eChild.setId( "child-specified" ); 603 eChild.addGoal( "child" ); 604 eChild.setPhase( "compile" ); 605 606 pChild.addExecution( eChild ); 607 child.addPlugin( pChild ); 608 609 ModelUtils.mergePluginDefinitions( pChild, pParent, true ); 610 611 Map executionMap = pChild.getExecutionsAsMap(); 612 assertNotNull( "test execution should be inherited from parent.", executionMap.get( testId ) ); 613 } 614 615}