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