You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by rf...@apache.org on 2019/08/29 16:44:39 UTC

[maven] branch MNG-6656 updated: [MNG-6656] Support reactor managed versions

This is an automated email from the ASF dual-hosted git repository.

rfscholte pushed a commit to branch MNG-6656
in repository https://gitbox.apache.org/repos/asf/maven.git


The following commit(s) were added to refs/heads/MNG-6656 by this push:
     new 712b95f  [MNG-6656] Support reactor managed versions
712b95f is described below

commit 712b95fe7d317e6714e5d82e0a7dfd4f39a6e9ae
Author: rfscholte <rf...@apache.org>
AuthorDate: Thu Aug 29 18:44:31 2019 +0200

    [MNG-6656] Support reactor managed versions
---
 .../maven/project/DefaultProjectBuilder.java       |   2 +
 .../internal/DefaultBuildPomXMLFilterFactory.java  |  20 +++
 .../maven/model/building/DefaultModelBuilder.java  |  17 ++-
 .../building/DefaultModelBuildingRequest.java      |  16 +++
 .../model/building/DefaultModelCacheManager.java   |  27 +++-
 .../model/building/FilterModelBuildingRequest.java |  12 ++
 .../maven/model/building/ModelBuildingRequest.java |   5 +-
 .../maven/model/building/ModelCacheManager.java    |   3 +
 .../org/apache/maven/model/building/ModelData.java |  21 ----
 .../maven/xml/filter/BuildPomXMLFilterFactory.java |  14 ++-
 .../{RelativeProject.java => DependencyKey.java}   |  56 +++++++--
 .../apache/maven/xml/filter/ParentXMLFilter.java   |   2 +-
 .../xml/filter/ReactorDependencyXMLFilter.java     | 140 +++++++++++++++++++++
 .../apache/maven/xml/filter/RelativeProject.java   |   6 +-
 .../maven/xml/filter/ConsumerPomXMLFilterTest.java |   6 +
 .../xml/filter/ReactorDependencyXMLFilterTest.java |  89 +++++++++++++
 16 files changed, 383 insertions(+), 53 deletions(-)

diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
index 7e18f1e..c3a0a8f 100644
--- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
+++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
@@ -164,6 +164,7 @@ public class DefaultProjectBuilder
                 request.setModelBuildingListener( listener );
 
                 request.setPomFile( pomFile );
+                request.setTransformPom( true );
                 request.setModelSource( modelSource );
                 request.setLocationTracking( true );
 
@@ -437,6 +438,7 @@ public class DefaultProjectBuilder
         request.setPomFile( pomFile );
         request.setTwoPhaseBuilding( true );
         request.setLocationTracking( true );
+        request.setTransformPom( true );
 
         DefaultModelBuildingListener listener =
             new DefaultModelBuildingListener( project, projectBuildingHelper, config.request );
diff --git a/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java b/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java
index cdded2b..e1b5ab5 100644
--- a/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java
+++ b/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java
@@ -32,6 +32,7 @@ import org.apache.maven.execution.MavenSession;
 import org.apache.maven.model.Model;
 import org.apache.maven.model.building.ModelCacheManager;
 import org.apache.maven.xml.filter.BuildPomXMLFilterFactory;
+import org.apache.maven.xml.filter.DependencyKey;
 import org.apache.maven.xml.filter.RelativeProject;
 
 /**
@@ -77,6 +78,14 @@ public class DefaultBuildPomXMLFilterFactory extends BuildPomXMLFilterFactory
     {
         return p -> Optional.ofNullable( rawModelCache.get( p ) ).map( m -> toRelativeProject( m ) );
     }
+    
+    @Override
+    protected Function<DependencyKey, String> getDependencyKeyToVersionMapper()
+    {
+        return k -> Optional.ofNullable( rawModelCache.get( k ) )
+                            .map( m -> toVersion( m ) )
+                            .orElse( null );
+    }
 
     private RelativeProject toRelativeProject( final Model m )
     {
@@ -94,4 +103,15 @@ public class DefaultBuildPomXMLFilterFactory extends BuildPomXMLFilterFactory
 
         return new RelativeProject( groupId, m.getArtifactId(), version );
     }
+    
+    private String toVersion( final Model m )
+    {
+        String version = m.getVersion();
+        if ( version == null && m.getParent() != null )
+        {
+            version = m.getParent().getVersion();
+        }
+
+        return version;
+    }
 }
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
index 0b0a615..d60e68d 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
@@ -300,10 +300,6 @@ public class DefaultModelBuilder
         {
             inputModel = readModel( request.getModelSource(), request.getPomFile(), request, problems );
         }
-        if ( modelCacheManager != null && request.getPomFile() != null )
-        {
-            modelCacheManager.put( request.getPomFile().toPath(), inputModel ); 
-        }
         
         problems.setRootModel( inputModel );
 
@@ -439,6 +435,11 @@ public class DefaultModelBuilder
         resultData.setVersion( resultModel.getVersion() );
 
         result.setEffectiveModel( resultModel );
+        
+        if ( modelCacheManager != null && request.getPomFile() != null )
+        {
+            modelCacheManager.put( request.getPomFile().toPath(), resultModel ); 
+        }
 
         for ( ModelData currentData : lineage )
         {
@@ -765,7 +766,7 @@ public class DefaultModelBuilder
         }
         
         // re-read model from file
-        if ( Boolean.getBoolean( "maven.experimental.buildconsumer" ) && !lineage.get( 0 ).isExternal() )
+        if ( Boolean.getBoolean( "maven.experimental.buildconsumer" ) && request.isTransformPom() )
         {
             try
             {
@@ -805,6 +806,8 @@ public class DefaultModelBuilder
         // Should always be FileSource for reactor poms
         FileSource source = (FileSource) modelData.getSource();
         
+        System.out.println( "transforming " + source.getFile() );
+        
         final SAXSource transformSource =
             new SAXSource( buildPomXMLFilterFactory.get().get( source.getFile().toPath() ),
                            new org.xml.sax.InputSource( modelData.getSource().getInputStream() ) );
@@ -1116,8 +1119,6 @@ public class DefaultModelBuilder
          */
 
         ModelData parentData = new ModelData( candidateSource, candidateModel, groupId, artifactId, version );
-        
-        parentData.setExternal( false );
 
         return parentData;
     }
@@ -1235,8 +1236,6 @@ public class DefaultModelBuilder
         ModelData parentData = new ModelData( modelSource, parentModel, parent.getGroupId(), parent.getArtifactId(),
                                               parent.getVersion() );
 
-        parentData.setExternal( true );
-
         return parentData;
     }
 
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java
index 84a68f7..06128a8 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java
@@ -72,6 +72,8 @@ public class DefaultModelBuildingRequest
     private ModelCache modelCache;
 
     private WorkspaceModelResolver workspaceResolver;
+    
+    private boolean transformPom;
 
     /**
      * Creates an empty request.
@@ -101,6 +103,7 @@ public class DefaultModelBuildingRequest
         setModelResolver( request.getModelResolver() );
         setModelBuildingListener( request.getModelBuildingListener() );
         setModelCache( request.getModelCache() );
+        setTransformPom( request.isTransformPom() );
     }
 
     @Override
@@ -407,5 +410,18 @@ public class DefaultModelBuildingRequest
         this.workspaceResolver = workspaceResolver;
         return this;
     }
+    
+    @Override
+    public boolean isTransformPom()
+    {
+        return transformPom;
+    }
+    
+    @Override
+    public ModelBuildingRequest setTransformPom( boolean transformPom )
+    {
+        this.transformPom = transformPom;
+        return this;
+    }
 
 }
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java
index 9a87805..f33d713 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java
@@ -28,6 +28,7 @@ import javax.inject.Named;
 import javax.inject.Singleton;
 
 import org.apache.maven.model.Model;
+import org.apache.maven.xml.filter.DependencyKey;
 
 /**
  * 
@@ -38,18 +39,36 @@ import org.apache.maven.model.Model;
 @Singleton
 public class DefaultModelCacheManager implements ModelCacheManager
 {
-    private static final Map<Path, Model> RAWMODELCACHE = Collections.synchronizedMap( new HashMap<Path, Model>() );
+    private static final Map<Path, Model> MODELCACHE = Collections.synchronizedMap( new HashMap<Path, Model>() );
+    
+    private static final Map<DependencyKey, Model> DEPKEYMODELCACHE =
+        Collections.synchronizedMap( new HashMap<DependencyKey, Model>() );
     
     @Override
-    public void put( Path p, Model t )
+    public void put( Path p, Model m )
     {
-        RAWMODELCACHE.put( p, t );
+        MODELCACHE.put( p, m );
+        
+        String groupId = m.getGroupId();
+        if ( groupId == null && m.getParent() != null )
+        {
+            groupId = m.getParent().getGroupId();
+        }
+        
+        String artifactId = m.getArtifactId();
+        DEPKEYMODELCACHE.put( new DependencyKey( groupId, artifactId ), m );
     }
 
     @Override
     public Model get( Path p )
     {
-        return RAWMODELCACHE.get( p );
+        return MODELCACHE.get( p );
+    }
+
+    @Override
+    public Model get( DependencyKey k )
+    {
+        return DEPKEYMODELCACHE.get( k );
     }
 
 }
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java
index a51126f..a9012a1 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java
@@ -282,4 +282,16 @@ class FilterModelBuildingRequest
         return this;
     }
 
+    @Override
+    public boolean isTransformPom()
+    {
+        return request.isTransformPom();
+    }
+
+    @Override
+    public ModelBuildingRequest setTransformPom( boolean transform )
+    {
+        request.setTransformPom( transform );
+        return this;
+    }
 }
\ No newline at end of file
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java
index dce0c32..10aedc1 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java
@@ -334,5 +334,8 @@ public interface ModelBuildingRequest
     WorkspaceModelResolver getWorkspaceModelResolver();
 
     ModelBuildingRequest setWorkspaceModelResolver( WorkspaceModelResolver workspaceResolver );
-
+    
+    boolean isTransformPom();
+    
+    ModelBuildingRequest setTransformPom( boolean transform );
 }
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java
index 6619607..f28116f 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java
@@ -22,6 +22,7 @@ package org.apache.maven.model.building;
 import java.nio.file.Path;
 
 import org.apache.maven.model.Model;
+import org.apache.maven.xml.filter.DependencyKey;
 
 /**
  * Registers models for usage later on
@@ -34,5 +35,7 @@ public interface ModelCacheManager
     void put( Path p, Model t );
     
     Model get( Path p );
+    
+    Model get( DependencyKey k );
 
 }
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java
index 2d093c6..5117602 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java
@@ -46,8 +46,6 @@ class ModelData
 
     private String version;
     
-    private boolean external = true;
-
     /**
      * Creates a new container for the specified model.
      *
@@ -202,25 +200,6 @@ class ModelData
     }
 
     /**
-     * 
-     * @return {@code false} if model is part of reactor, otherwise {@code true}
-     */
-    public boolean isExternal()
-    {
-        return external;
-    }
-    
-    /**
-     * Set to {@code false} if model is part of reactor, otherwise {@code true}
-     * 
-     * @param external
-     */
-    public void setExternal( boolean external )
-    {
-        this.external = external;
-    }
-    
-    /**
      * Gets the effective identifier of the model in the form {@code <groupId>:<artifactId>:<version>}.
      *
      * @return The effective identifier of the model, never {@code null}.
diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java
index 7a3f52a..83eafe6 100644
--- a/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java
+++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java
@@ -41,7 +41,15 @@ public abstract class BuildPomXMLFilterFactory
         throws SAXException, ParserConfigurationException
     {
         XMLReader parent = getParent();
-        
+
+        if ( getDependencyKeyToVersionMapper() != null )
+        {
+            ReactorDependencyXMLFilter reactorDependencyXMLFilter =
+                new ReactorDependencyXMLFilter( getDependencyKeyToVersionMapper() );
+            reactorDependencyXMLFilter.setParent( parent );
+            parent = reactorDependencyXMLFilter;
+        }
+
         if ( getRelativePathMapper() != null )
         {
             ParentXMLFilter parentFilter = new ParentXMLFilter( getRelativePathMapper() );
@@ -60,7 +68,7 @@ public abstract class BuildPomXMLFilterFactory
             ciFriendlyFilter.setParent( parent );
             parent = ciFriendlyFilter;
         }
-        
+
         return new BuildPomXMLFilter( parent );
     }
     
@@ -82,4 +90,6 @@ public abstract class BuildPomXMLFilterFactory
      * @return the mapper or {@code null} if relativePaths don't need to be mapped
      */
     protected abstract Function<Path, Optional<RelativeProject>> getRelativePathMapper();
+    
+    protected abstract Function<DependencyKey, String> getDependencyKeyToVersionMapper();
 }
diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/DependencyKey.java
similarity index 56%
copy from maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java
copy to maven-xml/src/main/java/org/apache/maven/xml/filter/DependencyKey.java
index bbceff3..bf91cf9 100644
--- a/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java
+++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/DependencyKey.java
@@ -19,26 +19,25 @@ package org.apache.maven.xml.filter;
  * under the License.
  */
 
+import java.util.Objects;
+
 /**
  * 
  * @author Robert Scholte
  * @since 3.7.0
  */
-public class RelativeProject
+public class DependencyKey
 {
-    private String groupId;
-    
-    private String artifactId;
-    
-    private String version;
+    private final String groupId;
     
-    public RelativeProject( String groupId, String artifactId, String version )
+    private final String artifactId;
+
+    public DependencyKey( String groupId, String artifactId )
     {
         this.groupId = groupId;
         this.artifactId = artifactId;
-        this.version = version;
     }
-
+ 
     public String getGroupId()
     {
         return groupId;
@@ -48,9 +47,42 @@ public class RelativeProject
     {
         return artifactId;
     }
-    
-    public String getVersion()
+
+    @Override
+    public int hashCode()
+    {
+        return Objects.hash( artifactId, groupId );
+    }
+
+    @Override
+    public boolean equals( Object obj )
     {
-        return version;
+        if ( this == obj ) 
+        {
+            return true;
+        }
+        if ( obj == null )
+        {
+            return false;
+        }
+        if ( getClass() != obj.getClass() )
+        {
+            return false;
+        }
+        
+        DependencyKey other = (DependencyKey) obj;
+        
+        if ( !Objects.equals( artifactId, other.artifactId ) )
+        {
+            return false;
+        }
+        if ( !Objects.equals( groupId, other.groupId ) )
+        {
+            return false;
+        }
+        
+        return true;
     }
+    
+    
 }
diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java
index 244ecc5..747a283 100644
--- a/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java
+++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java
@@ -47,7 +47,7 @@ import org.xml.sax.helpers.XMLFilterImpl;
 class ParentXMLFilter
     extends XMLFilterImpl
 {
-    private boolean parsingParent = false;
+    private boolean parsingParent;
 
     // states
     private String state;
diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilter.java
new file mode 100644
index 0000000..a568df5
--- /dev/null
+++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilter.java
@@ -0,0 +1,140 @@
+package org.apache.maven.xml.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.function.Function;
+
+import org.apache.maven.xml.SAXEventUtils;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.XMLFilterImpl;
+
+/**
+ * Will apply the version if the dependency is part of the reactor
+ * 
+ * @author Robert Scholte
+ * @since 4.0.0
+ */
+public class ReactorDependencyXMLFilter extends XMLFilterImpl
+{
+    private boolean parsingDependency;
+
+    // states
+    private String state;
+
+    private boolean hasVersion;
+
+    private String groupId;
+
+    private String artifactId;
+
+    private final Function<DependencyKey, String> reactorVersionMapper;
+
+    public ReactorDependencyXMLFilter( Function<DependencyKey, String> reactorVersionMapper )
+    {
+        this.reactorVersionMapper = reactorVersionMapper;
+    }
+
+    @Override
+    public void startElement( String uri, String localName, String qName, Attributes atts )
+        throws SAXException
+    {
+        if ( !parsingDependency && "dependency".equals( localName ) )
+        {
+            parsingDependency = true;
+        }
+        
+        if ( parsingDependency )
+        {
+            state = localName;
+
+            hasVersion |= "version".equals( localName );
+        }
+        super.startElement( uri, localName, qName, atts );
+    }
+
+    @Override
+    public void characters( char[] ch, int start, int length )
+        throws SAXException
+    {
+        if ( parsingDependency )
+        {
+            final String eventState = state;
+            switch ( eventState )
+            {
+                case "groupId":
+                    groupId = new String( ch, start, length );
+                    break;
+                case "artifactId":
+                    artifactId = new String( ch, start, length );
+                    break;
+                default:
+                    break;
+            }
+        }
+        super.characters( ch, start, length );
+    }
+
+    @Override
+    public void endElement( String uri, final String localName, String qName )
+        throws SAXException
+    {
+        if ( parsingDependency )
+        {
+            switch ( localName )
+            {
+                case "dependency":
+                    if ( !hasVersion )
+                    {
+                        String version = getVersion();
+
+                        // dependency is not part of reactor, probably it is managed
+                        if ( version != null )
+                        {
+                            String versionQName = SAXEventUtils.renameQName( qName, "version" );
+                            super.startElement( uri, "version", versionQName, null );
+                            super.characters( version.toCharArray(), 0, version.length() );
+                            super.endElement( uri, "version", versionQName );
+                        }
+                    }
+                    parsingDependency = false;
+                    
+                    // reset
+                    hasVersion = false;
+                    groupId = null;
+                    artifactId = null;
+                    
+                    break;
+                default: 
+                    break;
+            }
+        }
+
+        super.endElement( uri, localName, qName );
+        
+        state = "dependency";
+    }
+
+    private String getVersion()
+    {
+        return reactorVersionMapper.apply( new DependencyKey( groupId, artifactId ) );
+    }
+    
+}
diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java
index bbceff3..a158d38 100644
--- a/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java
+++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java
@@ -26,11 +26,11 @@ package org.apache.maven.xml.filter;
  */
 public class RelativeProject
 {
-    private String groupId;
+    private final String groupId;
     
-    private String artifactId;
+    private final String artifactId;
     
-    private String version;
+    private final String version;
     
     public RelativeProject( String groupId, String artifactId, String version )
     {
diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java
index b02589e..5484ea6 100644
--- a/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java
+++ b/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java
@@ -63,6 +63,12 @@ public class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests
             {
                 return null;
             }
+            
+            @Override
+            protected Function<DependencyKey, String> getDependencyKeyToVersionMapper()
+            {
+                return null;
+            }
         };
         
         Provider<BuildPomXMLFilterFactory> provider = new Provider<BuildPomXMLFilterFactory>()
diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilterTest.java
new file mode 100644
index 0000000..6a5998e
--- /dev/null
+++ b/maven-xml/src/test/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilterTest.java
@@ -0,0 +1,89 @@
+package org.apache.maven.xml.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.junit.Assert.*;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.junit.Test;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLFilter;
+
+public class ReactorDependencyXMLFilterTest extends AbstractXMLFilterTests
+{
+    @Override
+    protected XMLFilter getFilter()
+        throws TransformerException, SAXException, ParserConfigurationException
+    {
+        return new ReactorDependencyXMLFilter( r -> "1.0.0" );
+    }
+
+    @Test
+    public void testDefaultDependency() throws Exception
+    {
+        String input = "<dependency>"
+            + "<groupId>GROUPID</groupId>"
+            + "<artifactId>ARTIFACTID</artifactId>"
+            + "<version>VERSION</version>"
+            + "</dependency>";
+        String expected = input;
+        
+        String actual = transform( input );
+        
+        assertEquals( expected, actual );
+    }
+
+    @Test
+    public void testManagedDependency() throws Exception
+    {
+        XMLFilter filter = new ReactorDependencyXMLFilter( r -> null );
+        
+        String input = "<dependency>"
+            + "<groupId>GROUPID</groupId>"
+            + "<artifactId>ARTIFACTID</artifactId>"
+            + "</dependency>";
+        String expected = input;
+        
+        String actual = transform( input, filter );
+        
+        assertEquals( expected, actual );
+    }
+
+    @Test
+    public void testReactorDependency() throws Exception
+    {
+        String input = "<dependency>"
+                        + "<groupId>GROUPID</groupId>"
+                        + "<artifactId>ARTIFACTID</artifactId>"
+                        + "</dependency>";
+        String expected = "<dependency>"
+                        + "<groupId>GROUPID</groupId>"
+                        + "<artifactId>ARTIFACTID</artifactId>"
+                        + "<version>1.0.0</version>"
+                        + "</dependency>";
+        
+        String actual = transform( input );
+        
+        assertEquals( expected, actual );
+    }
+
+}