[MNG-4463] Dependency management import should support version ranges.

o Extended the 'ModelResolver' interface to support resolving 'Dependency's
  in addition to 'Parent's.

Closes #64 without merging. ITs are pending to be committed.


Project: http://git-wip-us.apache.org/repos/asf/maven/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven/commit/086ebf06
Tree: http://git-wip-us.apache.org/repos/asf/maven/tree/086ebf06
Diff: http://git-wip-us.apache.org/repos/asf/maven/diff/086ebf06

Branch: refs/heads/DEPMGMT
Commit: 086ebf0682399c66a268b3f185f71f45a2383815
Parents: 9353ad7
Author: Christian Schulte <schu...@apache.org>
Authored: Sat Jan 30 19:17:34 2016 +0100
Committer: Christian Schulte <schu...@apache.org>
Committed: Wed Feb 1 21:19:41 2017 +0100

----------------------------------------------------------------------
 .../maven/project/ProjectModelResolver.java     | 82 +++++++++++++++----
 .../model/building/DefaultModelBuilder.java     | 20 ++++-
 .../maven/model/resolution/ModelResolver.java   | 32 ++++++++
 .../internal/DefaultModelResolver.java          | 84 ++++++++++++++++----
 4 files changed, 184 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven/blob/086ebf06/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java
----------------------------------------------------------------------
diff --git 
a/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java 
b/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java
index 184be70..f11e77d 100644
--- 
a/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java
+++ 
b/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java
@@ -26,6 +26,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.maven.model.Dependency;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 
@@ -203,24 +204,26 @@ public class ProjectModelResolver
         return new FileModelSource( pomFile );
     }
 
-    public ModelSource resolveModel( Parent parent )
+    @Override
+    public ModelSource resolveModel( final Parent parent )
         throws UnresolvableModelException
     {
-        Artifact artifact = new DefaultArtifact( parent.getGroupId(), 
parent.getArtifactId(), "", "pom",
-                                                 parent.getVersion() );
-
-        VersionRangeRequest versionRangeRequest = new VersionRangeRequest( 
artifact, repositories, context );
-        versionRangeRequest.setTrace( trace );
-
         try
         {
-            VersionRangeResult versionRangeResult = 
resolver.resolveVersionRange( session, versionRangeRequest );
+            final Artifact artifact = new DefaultArtifact( 
parent.getGroupId(), parent.getArtifactId(), "", "pom",
+                                                           parent.getVersion() 
);
+
+            final VersionRangeRequest versionRangeRequest = new 
VersionRangeRequest( artifact, repositories, context );
+            versionRangeRequest.setTrace( trace );
+
+            final VersionRangeResult versionRangeResult = 
resolver.resolveVersionRange( session, versionRangeRequest );
 
             if ( versionRangeResult.getHighestVersion() == null )
             {
-                throw new UnresolvableModelException( "No versions matched the 
requested range '" + parent.getVersion()
-                                                          + "'", 
parent.getGroupId(), parent.getArtifactId(),
-                                                      parent.getVersion() );
+                throw new UnresolvableModelException(
+                    String.format( "No versions matched the requested parent 
version range '%s'",
+                                   parent.getVersion() ),
+                    parent.getGroupId(), parent.getArtifactId(), 
parent.getVersion() );
 
             }
 
@@ -228,21 +231,68 @@ public class ProjectModelResolver
                      && versionRangeResult.getVersionConstraint().getRange() 
!= null
                      && 
versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null )
             {
-                throw new UnresolvableModelException( "The requested version 
range '" + parent.getVersion()
-                                                          + "' does not 
specify an upper bound", parent.getGroupId(),
-                                                      parent.getArtifactId(), 
parent.getVersion() );
+                throw new UnresolvableModelException(
+                    String.format( "The requested parent version range '%s' 
does not specify an upper bound",
+                                   parent.getVersion() ),
+                    parent.getGroupId(), parent.getArtifactId(), 
parent.getVersion() );
 
             }
 
             parent.setVersion( 
versionRangeResult.getHighestVersion().toString() );
+
+            return resolveModel( parent.getGroupId(), parent.getArtifactId(), 
parent.getVersion() );
         }
-        catch ( VersionRangeResolutionException e )
+        catch ( final VersionRangeResolutionException e )
         {
             throw new UnresolvableModelException( e.getMessage(), 
parent.getGroupId(), parent.getArtifactId(),
                                                   parent.getVersion(), e );
 
         }
+    }
+
+    @Override
+    public ModelSource resolveModel( final Dependency dependency )
+        throws UnresolvableModelException
+    {
+        try
+        {
+            final Artifact artifact = new DefaultArtifact( 
dependency.getGroupId(), dependency.getArtifactId(), "",
+                                                           "pom", 
dependency.getVersion() );
+
+            final VersionRangeRequest versionRangeRequest = new 
VersionRangeRequest( artifact, repositories, context );
+            versionRangeRequest.setTrace( trace );
+
+            final VersionRangeResult versionRangeResult = 
resolver.resolveVersionRange( session, versionRangeRequest );
+
+            if ( versionRangeResult.getHighestVersion() == null )
+            {
+                throw new UnresolvableModelException(
+                    String.format( "No versions matched the requested 
dependency version range '%s'",
+                                   dependency.getVersion() ),
+                    dependency.getGroupId(), dependency.getArtifactId(), 
dependency.getVersion() );
+
+            }
+
+            if ( versionRangeResult.getVersionConstraint() != null
+                     && versionRangeResult.getVersionConstraint().getRange() 
!= null
+                     && 
versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null )
+            {
+                throw new UnresolvableModelException(
+                    String.format( "The requested dependency version range 
'%s' does not specify an upper bound",
+                                   dependency.getVersion() ),
+                    dependency.getGroupId(), dependency.getArtifactId(), 
dependency.getVersion() );
+
+            }
+
+            dependency.setVersion( 
versionRangeResult.getHighestVersion().toString() );
+
+            return resolveModel( dependency.getGroupId(), 
dependency.getArtifactId(), dependency.getVersion() );
+        }
+        catch ( VersionRangeResolutionException e )
+        {
+            throw new UnresolvableModelException( e.getMessage(), 
dependency.getGroupId(), dependency.getArtifactId(),
+                                                  dependency.getVersion(), e );
 
-        return resolveModel( parent.getGroupId(), parent.getArtifactId(), 
parent.getVersion() );
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/maven/blob/086ebf06/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
----------------------------------------------------------------------
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 49a1f3c..3532660 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
@@ -1208,7 +1208,25 @@ public class DefaultModelBuilder
                     final ModelSource importSource;
                     try
                     {
-                        importSource = modelResolver.resolveModel( groupId, 
artifactId, version );
+                        dependency = dependency.clone();
+                        importSource = modelResolver.resolveModel( dependency 
);
+                        final String resolvedId =
+                            dependency.getGroupId() + ':' + 
dependency.getArtifactId() + ':' + dependency.getVersion();
+
+                        if ( !imported.equals( resolvedId ) && 
importIds.contains( resolvedId ) )
+                        {
+                            // A version range has been resolved to a cycle.
+                            String message = "The dependencies of type=pom and 
with scope=import form a cycle: ";
+                            for ( String modelId : importIds )
+                            {
+                                message += modelId + " -> ";
+                            }
+                            message += resolvedId;
+                            problems.add( new ModelProblemCollectorRequest( 
Severity.ERROR, Version.BASE ).
+                                setMessage( message ) );
+
+                            continue;
+                        }
                     }
                     catch ( UnresolvableModelException e )
                     {

http://git-wip-us.apache.org/repos/asf/maven/blob/086ebf06/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java
----------------------------------------------------------------------
diff --git 
a/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java
 
b/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java
index c81a536..cb2a3ed 100644
--- 
a/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java
+++ 
b/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java
@@ -19,6 +19,7 @@ package org.apache.maven.model.resolution;
  * under the License.
  */
 
+import org.apache.maven.model.Dependency;
 import org.apache.maven.model.Parent;
 import org.apache.maven.model.Repository;
 import org.apache.maven.model.building.ModelSource;
@@ -47,16 +48,47 @@ public interface ModelResolver
 
     /**
      * Tries to resolve the POM for the specified parent coordinates possibly 
updating {@code parent}.
+     * <p>
+     * Unlike the {@link #resolveModel(java.lang.String, java.lang.String, 
java.lang.String)} method, this method
+     * supports version ranges and updates the given {@code parent} instance 
to match the returned {@code ModelSource}.
+     * If {@code parent} declares a version range, the version corresponding 
to the returned {@code ModelSource} will
+     * be set on the given {@code parent}.
+     * </p>
      *
      * @param parent The parent coordinates to resolve, must not be {@code 
null}.
+     *
      * @return The source of the requested POM, never {@code null}.
+     *
      * @throws UnresolvableModelException If the POM could not be resolved 
from any configured repository.
      * @since 3.2.2
+     *
+     * @see Parent#clone()
      */
     ModelSource resolveModel( Parent parent )
         throws UnresolvableModelException;
 
     /**
+     * Tries to resolve the POM for the specified dependency coordinates 
possibly updating {@code dependency}.
+     * <p>
+     * Unlike the {@link #resolveModel(java.lang.String, java.lang.String, 
java.lang.String)} method, this method
+     * supports version ranges and updates the given {@code dependency} 
instance to match the returned
+     * {@code ModelSource}. If {@code dependency} declares a version range, 
the version corresponding to the returned
+     * {@code ModelSource} will be set on the given {@code dependency}.
+     * </p>
+     *
+     * @param dependency The dependency coordinates to resolve, must not be 
{@code null}.
+     *
+     * @return The source of the requested POM, never {@code null}.
+     *
+     * @throws UnresolvableModelException If the POM could not be resolved 
from any configured repository.
+     * @since 3.4
+     *
+     * @see Dependency#clone()
+     */
+    ModelSource resolveModel( Dependency dependency )
+        throws UnresolvableModelException;
+
+    /**
      * Adds a repository to use for subsequent resolution requests. The order 
in which repositories are added matters,
      * repositories that were added first should also be searched first. When 
multiple repositories with the same
      * identifier are added, only the first repository being added will be 
used.

http://git-wip-us.apache.org/repos/asf/maven/blob/086ebf06/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java
----------------------------------------------------------------------
diff --git 
a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java
 
b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java
index f344959..0832a3a 100644
--- 
a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java
+++ 
b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java
@@ -26,6 +26,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.maven.model.Dependency;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 import org.apache.maven.model.Parent;
@@ -182,25 +183,27 @@ class DefaultModelResolver
         return new FileModelSource( pomFile );
     }
 
-    public ModelSource resolveModel( Parent parent )
+    @Override
+    public ModelSource resolveModel( final Parent parent )
         throws UnresolvableModelException
     {
-        Artifact artifact = new DefaultArtifact( parent.getGroupId(), 
parent.getArtifactId(), "", "pom",
-                                                 parent.getVersion() );
-
-        VersionRangeRequest versionRangeRequest = new VersionRangeRequest( 
artifact, repositories, context );
-        versionRangeRequest.setTrace( trace );
-
         try
         {
-            VersionRangeResult versionRangeResult =
+            final Artifact artifact = new DefaultArtifact( 
parent.getGroupId(), parent.getArtifactId(), "", "pom",
+                                                           parent.getVersion() 
);
+
+            final VersionRangeRequest versionRangeRequest = new 
VersionRangeRequest( artifact, repositories, context );
+            versionRangeRequest.setTrace( trace );
+
+            final VersionRangeResult versionRangeResult =
                 versionRangeResolver.resolveVersionRange( session, 
versionRangeRequest );
 
             if ( versionRangeResult.getHighestVersion() == null )
             {
-                throw new UnresolvableModelException( "No versions matched the 
requested range '" + parent.getVersion()
-                                                          + "'", 
parent.getGroupId(), parent.getArtifactId(),
-                                                      parent.getVersion() );
+                throw new UnresolvableModelException(
+                    String.format( "No versions matched the requested parent 
version range '%s'",
+                                   parent.getVersion() ),
+                    parent.getGroupId(), parent.getArtifactId(), 
parent.getVersion() );
 
             }
 
@@ -208,22 +211,69 @@ class DefaultModelResolver
                      && versionRangeResult.getVersionConstraint().getRange() 
!= null
                      && 
versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null )
             {
-                throw new UnresolvableModelException( "The requested version 
range '" + parent.getVersion()
-                                                          + "' does not 
specify an upper bound", parent.getGroupId(),
-                                                      parent.getArtifactId(), 
parent.getVersion() );
+                throw new UnresolvableModelException(
+                    String.format( "The requested parent version range '%s' 
does not specify an upper bound",
+                                   parent.getVersion() ),
+                    parent.getGroupId(), parent.getArtifactId(), 
parent.getVersion() );
 
             }
 
             parent.setVersion( 
versionRangeResult.getHighestVersion().toString() );
+
+            return resolveModel( parent.getGroupId(), parent.getArtifactId(), 
parent.getVersion() );
         }
-        catch ( VersionRangeResolutionException e )
+        catch ( final VersionRangeResolutionException e )
         {
             throw new UnresolvableModelException( e.getMessage(), 
parent.getGroupId(), parent.getArtifactId(),
                                                   parent.getVersion(), e );
 
         }
-
-        return resolveModel( parent.getGroupId(), parent.getArtifactId(), 
parent.getVersion() );
     }
 
+    @Override
+    public ModelSource resolveModel( final Dependency dependency )
+        throws UnresolvableModelException
+    {
+        try
+        {
+            final Artifact artifact = new DefaultArtifact( 
dependency.getGroupId(), dependency.getArtifactId(), "",
+                                                           "pom", 
dependency.getVersion() );
+
+            final VersionRangeRequest versionRangeRequest = new 
VersionRangeRequest( artifact, repositories, context );
+            versionRangeRequest.setTrace( trace );
+
+            final VersionRangeResult versionRangeResult =
+                versionRangeResolver.resolveVersionRange( session, 
versionRangeRequest );
+
+            if ( versionRangeResult.getHighestVersion() == null )
+            {
+                throw new UnresolvableModelException(
+                    String.format( "No versions matched the requested 
dependency version range '%s'",
+                                   dependency.getVersion() ),
+                    dependency.getGroupId(), dependency.getArtifactId(), 
dependency.getVersion() );
+
+            }
+
+            if ( versionRangeResult.getVersionConstraint() != null
+                     && versionRangeResult.getVersionConstraint().getRange() 
!= null
+                     && 
versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null )
+            {
+                throw new UnresolvableModelException(
+                    String.format( "The requested dependency version range 
'%s' does not specify an upper bound",
+                                   dependency.getVersion() ),
+                    dependency.getGroupId(), dependency.getArtifactId(), 
dependency.getVersion() );
+
+            }
+
+            dependency.setVersion( 
versionRangeResult.getHighestVersion().toString() );
+
+            return resolveModel( dependency.getGroupId(), 
dependency.getArtifactId(), dependency.getVersion() );
+        }
+        catch ( VersionRangeResolutionException e )
+        {
+            throw new UnresolvableModelException( e.getMessage(), 
dependency.getGroupId(), dependency.getArtifactId(),
+                                                  dependency.getVersion(), e );
+
+        }
+    }
 }

Reply via email to