Author: jdcasey Date: Fri May 27 14:47:12 2005 New Revision: 178825 URL: http://svn.apache.org/viewcvs?rev=178825&view=rev Log: Added inheritance of Plugins according to the rules we decided upon. This consists of:
- inheritanceApplied flag on Plugin and Goal (NOT fields, just a code-only flag) - flushGoalMap/flushPluginMap to clear caching of these calculated attributes - ModelUtils.mergePluginLists() and ModelUtils.mergePluginDefinitions() for use in both * DefaultModelInheritanceAssembler (Plugin/PluginManagement lists) * DefaultModelDefaultsInjector (PluginManagement -> Plugin merges) - Also added a few unit tests for basic Plugin inheritance stuff. This could be more thoroughly tested... Modified: maven/components/trunk/maven-model/maven.mdo maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/ModelUtils.java maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssembler.java maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/injection/DefaultModelDefaultsInjector.java maven/components/trunk/maven-project/src/test/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssemblerTest.java Modified: maven/components/trunk/maven-model/maven.mdo URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-model/maven.mdo?rev=178825&r1=178824&r2=178825&view=diff ============================================================================== --- maven/components/trunk/maven-model/maven.mdo (original) +++ maven/components/trunk/maven-model/maven.mdo Fri May 27 14:47:12 2005 @@ -680,6 +680,11 @@ <version>4.0.0</version> <code><![CDATA[ Map pluginMap; + + public void flushPluginMap() + { + this.pluginMap = null; + } public Map getPluginsAsMap() { @@ -2045,6 +2050,22 @@ <version>4.0.0</version> <code><![CDATA[ private Map goalMap = null; + private boolean inheritanceApplied = false; + + public void setInheritanceApplied() + { + this.inheritanceApplied = true; + } + + public boolean isInheritanceApplied() + { + return inheritanceApplied; + } + + public void flushGoalMap() + { + this.goalMap = null; + } public Map getGoalsAsMap() { @@ -2096,6 +2117,23 @@ <type>DOM</type> </field> </fields> + <codeSegments> + <codeSegment> + <code><![CDATA[ + private boolean inheritanceApplied = false; + + public void setInheritanceApplied() + { + this.inheritanceApplied = true; + } + + public boolean isInheritanceApplied() + { + return inheritanceApplied; + } + ]]></code> + </codeSegment> + </codeSegments> </class> <class> <name>DependencyManagement</name> Modified: maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/ModelUtils.java URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/ModelUtils.java?rev=178825&r1=178824&r2=178825&view=diff ============================================================================== --- maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/ModelUtils.java (original) +++ maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/ModelUtils.java Fri May 27 14:47:12 2005 @@ -2,11 +2,14 @@ import org.apache.maven.model.Goal; import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginContainer; import org.codehaus.plexus.util.xml.Xpp3Dom; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.TreeMap; /* * Copyright 2001-2005 The Apache Software Foundation. @@ -26,44 +29,152 @@ public final class ModelUtils { - - public static void mergeSupplementalPluginDefinition( Plugin main, Plugin supplemental ) + + public static void mergePluginLists( PluginContainer childContainer, PluginContainer parentContainer, + boolean handleAsInheritance ) { - if ( main.getVersion() == null && supplemental.getVersion() != null ) + if( childContainer == null || parentContainer == null ) { - main.setVersion( supplemental.getVersion() ); + // nothing to do. + return; } + + List parentPlugins = parentContainer.getPlugins(); + + if ( parentPlugins != null && !parentPlugins.isEmpty() ) + { + Map assembledPlugins = new TreeMap(); + + Map childPlugins = childContainer.getPluginsAsMap(); + + for ( Iterator it = parentPlugins.iterator(); it.hasNext(); ) + { + Plugin parentPlugin = (Plugin) it.next(); + + String parentInherited = parentPlugin.getInherited(); + + if ( !handleAsInheritance || parentInherited == null + || Boolean.valueOf( parentInherited ).booleanValue() ) + { + + Plugin assembledPlugin = parentPlugin; + + Plugin childPlugin = (Plugin) childPlugins.get( parentPlugin.getKey() ); + + if ( childPlugin != null ) + { + assembledPlugin = childPlugin; + + ModelUtils.mergePluginDefinitions( childPlugin, parentPlugin, handleAsInheritance ); + } - Map supplementalGoals = supplemental.getGoalsAsMap(); + if ( handleAsInheritance ) + { + assembledPlugin.setInheritanceApplied(); + } - List pluginGoals = main.getGoals(); + assembledPlugins.put( assembledPlugin.getKey(), assembledPlugin ); + } + } + + for ( Iterator it = childPlugins.values().iterator(); it.hasNext(); ) + { + Plugin childPlugin = (Plugin) it.next(); + + if ( !assembledPlugins.containsKey( childPlugin.getKey() ) ) + { + assembledPlugins.put( childPlugin.getKey(), childPlugin ); + } + } + + childContainer.setPlugins( new ArrayList( assembledPlugins.values() ) ); + + childContainer.flushPluginMap(); + } + } - if ( pluginGoals != null ) + public static void mergePluginDefinitions( Plugin child, Plugin parent, boolean handleAsInheritance ) + { + if( child == null || parent == null ) + { + // nothing to do. + return; + } + + if ( child.getVersion() == null && parent.getVersion() != null ) + { + child.setVersion( parent.getVersion() ); + } + + List parentGoals = parent.getGoals(); + + // if the supplemental goals are non-existent, then nothing related to goals changes. + if ( parentGoals != null && !parentGoals.isEmpty() ) { - for ( Iterator it = pluginGoals.iterator(); it.hasNext(); ) + Map assembledGoals = new TreeMap(); + + Map childGoals = child.getGoalsAsMap(); + + if ( childGoals != null ) { - Goal pluginGoal = (Goal) it.next(); + for ( Iterator it = parentGoals.iterator(); it.hasNext(); ) + { + Goal parentGoal = (Goal) it.next(); - Goal supplementalGoal = (Goal) supplementalGoals.get( pluginGoal.getId() ); + String parentInherited = parentGoal.getInherited(); - if ( supplementalGoal != null ) + if ( !handleAsInheritance || parentInherited == null + || Boolean.valueOf( parentInherited ).booleanValue() ) + { + Goal assembledGoal = parentGoal; + + Goal childGoal = (Goal) childGoals.get( parentGoal.getId() ); + + if ( childGoal != null ) + { + Xpp3Dom childGoalConfig = (Xpp3Dom) childGoal.getConfiguration(); + Xpp3Dom parentGoalConfig = (Xpp3Dom) parentGoal.getConfiguration(); + + childGoalConfig = Xpp3Dom.mergeXpp3Dom( childGoalConfig, parentGoalConfig ); + + childGoal.setConfiguration( childGoalConfig ); + + assembledGoal = childGoal; + } + + if ( handleAsInheritance ) + { + assembledGoal.setInheritanceApplied(); + } + + assembledGoals.put( assembledGoal.getId(), assembledGoal ); + } + } + + for ( Iterator it = childGoals.entrySet().iterator(); it.hasNext(); ) { - Xpp3Dom pluginGoalConfig = (Xpp3Dom) pluginGoal.getConfiguration(); - Xpp3Dom supplementalGoalConfig = (Xpp3Dom) supplementalGoal.getConfiguration(); + Map.Entry entry = (Map.Entry) it.next(); - pluginGoalConfig = Xpp3Dom.mergeXpp3Dom( pluginGoalConfig, supplementalGoalConfig ); + String key = (String) entry.getKey(); + Goal childGoal = (Goal) entry.getValue(); - pluginGoal.setConfiguration( pluginGoalConfig ); + if ( !assembledGoals.containsKey( key ) ) + { + assembledGoals.put( key, childGoal ); + } } + + child.setGoals( new ArrayList( assembledGoals.values() ) ); + child.flushGoalMap(); } } - Xpp3Dom pluginConfiguration = (Xpp3Dom) main.getConfiguration(); - Xpp3Dom supplementalConfiguration = (Xpp3Dom) supplemental.getConfiguration(); + Xpp3Dom childConfiguration = (Xpp3Dom) child.getConfiguration(); + Xpp3Dom parentConfiguration = (Xpp3Dom) parent.getConfiguration(); - pluginConfiguration = Xpp3Dom.mergeXpp3Dom( pluginConfiguration, supplementalConfiguration ); + childConfiguration = Xpp3Dom.mergeXpp3Dom( childConfiguration, parentConfiguration ); - main.setConfiguration( pluginConfiguration ); + child.setConfiguration( childConfiguration ); } } Modified: maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssembler.java URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssembler.java?rev=178825&r1=178824&r2=178825&view=diff ============================================================================== --- maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssembler.java (original) +++ maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssembler.java Fri May 27 14:47:12 2005 @@ -20,15 +20,13 @@ import org.apache.maven.model.Dependency; import org.apache.maven.model.DependencyManagement; import org.apache.maven.model.DistributionManagement; -import org.apache.maven.model.Goal; import org.apache.maven.model.Model; import org.apache.maven.model.Plugin; -import org.apache.maven.model.PluginManagement; import org.apache.maven.model.Repository; import org.apache.maven.model.Scm; import org.apache.maven.model.Site; +import org.apache.maven.project.ModelUtils; import org.codehaus.plexus.util.StringUtils; -import org.codehaus.plexus.util.xml.Xpp3Dom; import java.util.Iterator; import java.util.List; @@ -202,70 +200,8 @@ } assembleDependencyManagementInheritance( child, parent ); - } - - private void assemblePluginManagementInheritance( Build childBuild, Build parentBuild ) - { - PluginManagement parentPluginMgmt = parentBuild.getPluginManagement(); - - PluginManagement childPluginMgmt = childBuild.getPluginManagement(); - - if ( parentPluginMgmt != null ) - { - if ( childPluginMgmt == null ) - { - childBuild.setPluginManagement( parentPluginMgmt ); - } - else - { - Map mappedChildPlugins = childPluginMgmt.getPluginsAsMap(); - - for ( Iterator it = parentPluginMgmt.getPlugins().iterator(); it.hasNext(); ) - { - Plugin plugin = (Plugin) it.next(); - - if ( !mappedChildPlugins.containsKey( plugin.getKey() ) ) - { - childPluginMgmt.addPlugin( plugin ); - } - else - { - Plugin childPlugin = (Plugin) mappedChildPlugins.get( plugin.getKey() ); - - if ( childPlugin.getVersion() == null ) - { - childPlugin.setVersion( childPlugin.getVersion() ); - } - - Map mappedChildGoals = childPlugin.getGoalsAsMap(); - - for ( Iterator itGoals = plugin.getGoals().iterator(); itGoals.hasNext(); ) - { - Goal parentGoal = (Goal) itGoals.next(); - Goal childGoal = (Goal) mappedChildGoals.get( parentGoal.getId() ); - - if ( childGoal == null ) - { - childPlugin.addGoal( parentGoal ); - } - else - { - Xpp3Dom childDom = (Xpp3Dom) childGoal.getConfiguration(); - Xpp3Dom parentDom = (Xpp3Dom) parentGoal.getConfiguration(); - childGoal.setConfiguration( Xpp3Dom.mergeXpp3Dom( childDom, parentDom ) ); - } - } - - Xpp3Dom childConfig = (Xpp3Dom) childPlugin.getConfiguration(); - Xpp3Dom parentConfig = (Xpp3Dom) plugin.getConfiguration(); - childPlugin.setConfiguration( Xpp3Dom.mergeXpp3Dom( childConfig, parentConfig ) ); - } - } - } - } - } - + private void assembleDependencyManagementInheritance( Model child, Model parent ) { DependencyManagement parentDepMgmt = parent.getDependencyManagement(); @@ -369,9 +305,14 @@ childBuild.setTestResources( parentBuild.getTestResources() ); } - // Plugins are not aggregated, but management is - - assemblePluginManagementInheritance( childBuild, parentBuild ); + // Plugins are aggregated if Plugin.inherit != false + ModelUtils.mergePluginLists( childBuild, parentBuild, true ); + + // Plugin management :: aggregate + if( childBuild != null && parentBuild != null ) + { + ModelUtils.mergePluginLists( childBuild.getPluginManagement(), parentBuild.getPluginManagement(), false ); + } } } Modified: maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/injection/DefaultModelDefaultsInjector.java URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/injection/DefaultModelDefaultsInjector.java?rev=178825&r1=178824&r2=178825&view=diff ============================================================================== --- maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/injection/DefaultModelDefaultsInjector.java (original) +++ maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/injection/DefaultModelDefaultsInjector.java Fri May 27 14:47:12 2005 @@ -18,12 +18,9 @@ import org.apache.maven.model.Dependency; import org.apache.maven.model.DependencyManagement; -import org.apache.maven.model.Goal; import org.apache.maven.model.Model; import org.apache.maven.model.Plugin; -import org.apache.maven.model.PluginManagement; import org.apache.maven.project.ModelUtils; -import org.codehaus.plexus.util.xml.Xpp3Dom; import java.util.Iterator; import java.util.List; @@ -42,38 +39,13 @@ injectDependencyDefaults( model.getDependencies(), model.getDependencyManagement() ); if ( model.getBuild() != null ) { - injectPluginDefaults( model.getBuild().getPluginsAsMap(), model.getBuild().getPluginManagement() ); - } - } - - private void injectPluginDefaults( Map pluginMap, PluginManagement pluginManagement ) - { - if ( pluginManagement != null ) - { - // a given project's plugins should be smaller than the - // group-defined defaults set... - // in other words, the project's plugins will probably be a subset - // of - // those specified in defaults. - - List managedPlugins = pluginManagement.getPlugins(); - - for ( Iterator it = managedPlugins.iterator(); it.hasNext(); ) - { - Plugin def = (Plugin) it.next(); - - Plugin plugin = (Plugin) pluginMap.get( def.getKey() ); - if ( plugin != null ) - { - mergePluginWithDefaults( plugin, def ); - } - } + ModelUtils.mergePluginLists( model.getBuild(), model.getBuild().getPluginManagement(), false ); } } public void mergePluginWithDefaults( Plugin plugin, Plugin def ) { - ModelUtils.mergeSupplementalPluginDefinition( plugin, def ); + ModelUtils.mergePluginDefinitions( plugin, def, false ); } private void injectDependencyDefaults( List dependencies, DependencyManagement dependencyManagement ) Modified: maven/components/trunk/maven-project/src/test/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssemblerTest.java URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-project/src/test/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssemblerTest.java?rev=178825&r1=178824&r2=178825&view=diff ============================================================================== --- maven/components/trunk/maven-project/src/test/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssemblerTest.java (original) +++ maven/components/trunk/maven-project/src/test/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssemblerTest.java Fri May 27 14:47:12 2005 @@ -18,8 +18,10 @@ import junit.framework.TestCase; import org.apache.maven.model.Build; +import org.apache.maven.model.Goal; import org.apache.maven.model.Model; import org.apache.maven.model.Parent; +import org.apache.maven.model.Plugin; import org.apache.maven.model.Repository; import org.apache.maven.model.Resource; import org.apache.maven.model.Scm; @@ -28,6 +30,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Map; /** * @author jdcasey @@ -265,6 +268,140 @@ // TODO: a lot easier if modello generated equals() :) assertRepositories( repos, child.getRepositories() ); + } + + public void testPluginInheritanceWhereParentPluginWithoutInheritFlagAndChildHasNoPlugins() + { + Model parent = makeBaseModel( "parent" ); + + Model child = makeBaseModel( "child" ); + + Plugin parentPlugin = new Plugin(); + parentPlugin.setArtifactId( "maven-testInheritance-plugin" ); + parentPlugin.setGroupId( "org.apache.maven.plugins" ); + parentPlugin.setVersion( "1.0" ); + + List parentPlugins = Collections.singletonList( parentPlugin ); + + Build parentBuild = new Build(); + parentBuild.setPlugins( parentPlugins ); + + parent.setBuild( parentBuild ); + + assembler.assembleModelInheritance( child, parent ); + + assertPlugins( parentPlugins, child ); + } + + public void testPluginInheritanceWhereParentPluginWithTrueInheritFlagAndChildHasNoPlugins() + { + Model parent = makeBaseModel( "parent" ); + + Model child = makeBaseModel( "child" ); + + Plugin parentPlugin = new Plugin(); + parentPlugin.setArtifactId( "maven-testInheritance2-plugin" ); + parentPlugin.setGroupId( "org.apache.maven.plugins" ); + parentPlugin.setVersion( "1.0" ); + parentPlugin.setInherited( "true" ); + + List parentPlugins = Collections.singletonList( parentPlugin ); + + Build parentBuild = new Build(); + parentBuild.setPlugins( parentPlugins ); + + parent.setBuild( parentBuild ); + + assembler.assembleModelInheritance( child, parent ); + + assertPlugins( parentPlugins, child ); + } + + public void testPluginInheritanceWhereParentPluginWithFalseInheritFlagAndChildHasNoPlugins() + { + Model parent = makeBaseModel( "parent" ); + + Model child = makeBaseModel( "child" ); + + Plugin parentPlugin = new Plugin(); + parentPlugin.setArtifactId("maven-testInheritance3-plugin"); + parentPlugin.setGroupId("org.apache.maven.plugins"); + parentPlugin.setVersion("1.0"); + parentPlugin.setInherited("false"); + + List parentPlugins = Collections.singletonList(parentPlugin); + + Build parentBuild = new Build(); + parentBuild.setPlugins(parentPlugins); + + parent.setBuild(parentBuild); + + assembler.assembleModelInheritance( child, parent ); + + assertPlugins( new ArrayList(), child ); + } + + private void assertPlugins( List expectedPlugins, Model child ) + { + Build childBuild = child.getBuild(); + + if( expectedPlugins != null && !expectedPlugins.isEmpty() ) + { + assertNotNull( childBuild ); + + Map childPluginsMap = childBuild.getPluginsAsMap(); + + if( childPluginsMap != null ) + { + assertEquals( expectedPlugins.size(), childPluginsMap.size() ); + + for ( Iterator it = expectedPlugins.iterator(); it.hasNext(); ) + { + Plugin expectedPlugin = (Plugin) it.next(); + + Plugin childPlugin = (Plugin) childPluginsMap.get( expectedPlugin.getKey() ); + + assertPluginsEqual( expectedPlugin, childPlugin ); + } + } + else + { + fail( "child plugins collection is null, but expectations map is not." ); + } + } + else + { + assertTrue( childBuild == null || childBuild.getPlugins() == null || childBuild.getPlugins().isEmpty() ); + } + } + + private void assertPluginsEqual( Plugin reference, Plugin test ) + { + assertEquals("Plugin keys don't match", reference.getKey(), test.getKey()); + assertEquals("Plugin configurations don't match", reference.getConfiguration(), test.getConfiguration()); + + List referenceGoals = reference.getGoals(); + Map testGoalsMap = test.getGoalsAsMap(); + + if( referenceGoals != null && !referenceGoals.isEmpty() ) + { + assertTrue( "Missing goals specification", ( testGoalsMap != null && !testGoalsMap.isEmpty() ) ); + + for ( Iterator it = referenceGoals.iterator(); it.hasNext(); ) + { + Goal referenceGoal = (Goal) it.next(); + Goal testGoal = (Goal) testGoalsMap.get( referenceGoal.getId() ); + + assertNotNull( "Goal from reference not found in test", testGoal ); + + assertEquals( "Goal IDs don't match", referenceGoal.getId(), testGoal.getId() ); + assertEquals( "Goal configurations don't match", referenceGoal.getConfiguration(), testGoal.getConfiguration() ); + } + } + else + { + assertTrue( "Unexpected goals specification", ( testGoalsMap == null || testGoalsMap.isEmpty() ) ); + } } // ---------------------------------------------------------------------- --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]