Repository: maven
Updated Branches:
  refs/heads/master 5f726e25e -> 2313861df


[MNG-5971] Imported dependencies should be available to inheritance processing

o Updated to remove the 'include' scope. Everyone agrees to the 'import' scope
  being broken the way it got implemented in Maven 2.0.x and to need fixing
  according to the description of the issue.
o Updated to remove support of 'import' and 'include' scopes of dependencies.
  Currently there are issues with the way Maven normalizes redundant
  dependencies to be backwards compatible to Maven 2. Import of dependencies
  cannot be implemented consistently with this backwards compatibility in place.
o Updated to fix the 'import' scope to behave as requested in MNG-5971.


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

Branch: refs/heads/master
Commit: 2313861dfde37b02e6aa8d5d701c8e8bb5a288ea
Parents: 5f726e2
Author: Christian Schulte <[email protected]>
Authored: Fri Feb 19 21:04:50 2016 +0100
Committer: Christian Schulte <[email protected]>
Committed: Fri Feb 19 21:40:48 2016 +0100

----------------------------------------------------------------------
 .../model/building/DefaultModelBuilder.java     | 249 ++-----------------
 .../building/DefaultModelBuilderFactory.java    |  15 +-
 .../maven/model/building/ModelCacheTag.java     |  37 +--
 .../DefaultDependenciesImporter.java            |  74 ------
 .../DefaultDependencyManagementImporter.java    | 131 +++++++++-
 .../model/composition/DependenciesImporter.java |  48 ----
 6 files changed, 157 insertions(+), 397 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven/blob/2313861d/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 5cc7fef..27252f9 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
@@ -38,7 +38,6 @@ import org.apache.maven.model.Profile;
 import org.apache.maven.model.Repository;
 import org.apache.maven.model.building.ModelProblem.Severity;
 import org.apache.maven.model.building.ModelProblem.Version;
-import org.apache.maven.model.composition.DependenciesImporter;
 import org.apache.maven.model.composition.DependencyManagementImporter;
 import org.apache.maven.model.inheritance.InheritanceAssembler;
 import org.apache.maven.model.interpolation.ModelInterpolator;
@@ -125,9 +124,6 @@ public class DefaultModelBuilder
     @Requirement
     private DependencyManagementImporter dependencyManagementImporter;
 
-    @Requirement
-    private DependenciesImporter dependenciesImporter;
-
     @Requirement( optional = true )
     private LifecycleBindingsInjector lifecycleBindingsInjector;
 
@@ -206,12 +202,6 @@ public class DefaultModelBuilder
         return this;
     }
 
-    public DefaultModelBuilder setDependenciesImporter( DependenciesImporter 
dependenciesImporter )
-    {
-        this.dependenciesImporter = dependenciesImporter;
-        return this;
-    }
-
     public DefaultModelBuilder setDependencyManagementInjector( 
DependencyManagementInjector depMngmntInjector )
     {
         this.dependencyManagementInjector = depMngmntInjector;
@@ -384,8 +374,8 @@ public class DefaultModelBuilder
         problems.setSource( inputModel );
         checkPluginVersions( lineage, request, problems );
 
-        // include processing
-        includeDependencies( lineage, request, problems );
+        // import processing
+        processImports( lineage, request, problems );
 
         // inheritance assembly
         assembleInheritance( lineage, request, problems );
@@ -465,15 +455,6 @@ public class DefaultModelBuilder
             lifecycleBindingsInjector.injectLifecycleBindings( resultModel, 
request, problems );
         }
 
-        // dependency management import
-        importDependencyManagement( resultModel, "import", request, problems, 
managementImports );
-
-        // dependencies import
-        importDependencies( resultModel, "import", request, problems, 
dependencyImports );
-
-        // re-validate after 'import' to warn for possible duplicates 
introduced by import
-        modelValidator.validateRawModel( resultModel, request, problems );
-
         // dependency management injection
         dependencyManagementInjector.injectManagement( resultModel, request, 
problems );
 
@@ -732,8 +713,8 @@ public class DefaultModelBuilder
         }
     }
 
-    private void includeDependencies( final List<ModelData> lineage, final 
ModelBuildingRequest request,
-                                      final DefaultModelProblemCollector 
problems )
+    private void processImports( final List<ModelData> lineage, final 
ModelBuildingRequest request,
+                                 final DefaultModelProblemCollector problems )
     {
         // Creates an intermediate model with property inheritance and 
interpolation.
         final List<Model> intermediateLineage = new ArrayList<>( 
lineage.size() );
@@ -753,11 +734,25 @@ public class DefaultModelBuilder
             properties.putAll( parent.getProperties() );
             properties.putAll( child.getProperties() );
             child.setProperties( properties );
+
+            final List<Repository> repositories = new ArrayList<>();
+            repositories.addAll( child.getRepositories() );
+
+            for ( final Repository parentRepository : parent.getRepositories() 
)
+            {
+                if ( !repositories.contains( parentRepository ) )
+                {
+                    repositories.add( parentRepository );
+                }
+            }
+
+            child.setRepositories( repositories );
         }
 
         for ( int i = 0, s0 = intermediateLineage.size(); i < s0; i++ )
         {
             final Model model = intermediateLineage.get( i );
+            problems.setSource( model );
             this.interpolateModel( model, request, problems );
         }
 
@@ -772,7 +767,7 @@ public class DefaultModelBuilder
                 {
                     final Dependency dependency = 
model.getDependencyManagement().getDependencies().get( j );
 
-                    if ( "include".equals( dependency.getScope() ) && 
"pom".equals( dependency.getType() ) )
+                    if ( "import".equals( dependency.getScope() ) && 
"pom".equals( dependency.getType() ) )
                     {
                         final Dependency interpolated =
                             intermediateLineage.get( i 
).getDependencyManagement().getDependencies().get( j );
@@ -781,28 +776,18 @@ public class DefaultModelBuilder
                     }
                 }
             }
-
-            for ( int j = 0, s1 = model.getDependencies().size(); j < s1; j++ )
-            {
-                final Dependency dependency = model.getDependencies().get( j );
-
-                if ( "include".equals( dependency.getScope() ) && 
"pom".equals( dependency.getType() ) )
-                {
-                    final Dependency interpolated = intermediateLineage.get( i 
).getDependencies().get( j );
-                    model.getDependencies().set( j, interpolated );
-                }
-            }
         }
 
         // Performs inclusion of dependencies in the original lineage.
         for ( int i = 0, s0 = lineage.size(), superModelIdx = lineage.size() - 
1; i < s0; i++ )
         {
             final Model model = lineage.get( i ).getModel();
-            this.importDependencyManagement( model, "include", request, 
problems, new HashSet<String>() );
-            this.importDependencies( model, "include", request, problems, new 
HashSet<String>() );
+            this.configureResolver( request.getModelResolver(), 
intermediateLineage.get( i ), problems, true );
+            this.importDependencyManagement( model, "import", request, 
problems, new HashSet<String>() );
 
             if ( i != superModelIdx )
             {
+                problems.setSource( model );
                 modelValidator.validateRawModel( model, request, problems );
             }
         }
@@ -1204,6 +1189,8 @@ public class DefaultModelBuilder
             return;
         }
 
+        problems.setSource( model );
+
         String importing = model.getGroupId() + ':' + model.getArtifactId() + 
':' + model.getVersion();
 
         importIds.add( importing );
@@ -1392,194 +1379,6 @@ public class DefaultModelBuilder
         dependencyManagementImporter.importManagement( model, importMngts, 
request, problems );
     }
 
-    private void importDependencies( final Model model, final String scope, 
final ModelBuildingRequest request,
-                                     final DefaultModelProblemCollector 
problems, final Collection<String> importIds )
-    {
-        final String importing = model.getGroupId() + ':' + 
model.getArtifactId() + ':' + model.getVersion();
-
-        importIds.add( importing );
-
-        final WorkspaceModelResolver workspaceResolver = 
request.getWorkspaceModelResolver();
-        final ModelResolver modelResolver = request.getModelResolver();
-
-        ModelBuildingRequest importRequest = null;
-
-        List<List<? extends Dependency>> imports = null;
-
-        for ( final Iterator<Dependency> it = 
model.getDependencies().iterator(); it.hasNext(); )
-        {
-            Dependency dependency = it.next();
-
-            if ( !"pom".equals( dependency.getType() ) || !scope.equals( 
dependency.getScope() ) )
-            {
-                continue;
-            }
-
-            it.remove();
-
-            final String groupId = dependency.getGroupId();
-            final String artifactId = dependency.getArtifactId();
-            final String version = dependency.getVersion();
-
-            if ( groupId == null || groupId.length() <= 0 )
-            {
-                problems.add( new ModelProblemCollectorRequest( 
Severity.ERROR, Version.BASE )
-                    .setMessage( "'dependencies.dependency.groupId' for "
-                                     + dependency.getManagementKey() + " is 
missing." )
-                    .setLocation( dependency.getLocation( "" ) ) );
-                continue;
-            }
-            if ( artifactId == null || artifactId.length() <= 0 )
-            {
-                problems.add( new ModelProblemCollectorRequest( 
Severity.ERROR, Version.BASE )
-                    .setMessage( "'dependencies.dependency.artifactId' for "
-                                     + dependency.getManagementKey() + " is 
missing." )
-                    .setLocation( dependency.getLocation( "" ) ) );
-                continue;
-            }
-            if ( version == null || version.length() <= 0 )
-            {
-                problems.add( new ModelProblemCollectorRequest( 
Severity.ERROR, Version.BASE )
-                    .setMessage( "'dependencies.dependency.version' for "
-                                     + dependency.getManagementKey() + " is 
missing." )
-                    .setLocation( dependency.getLocation( "" ) ) );
-                continue;
-            }
-
-            final String imported = groupId + ':' + artifactId + ':' + version;
-
-            if ( importIds.contains( imported ) )
-            {
-                String message = "The dependencies of type=pom and scope=" + 
scope + " form a cycle: ";
-                for ( String modelId : importIds )
-                {
-                    message += modelId + " -> ";
-                }
-                message += imported;
-                problems.add( new ModelProblemCollectorRequest( 
Severity.ERROR, Version.BASE ).setMessage( message ) );
-                continue;
-            }
-
-            List<? extends Dependency> importDependencies =
-                getCache( request.getModelCache(), groupId, artifactId, 
version, ModelCacheTag.DEPENDENCIES );
-
-            if ( importDependencies == null )
-            {
-                if ( workspaceResolver == null && modelResolver == null )
-                {
-                    throw new NullPointerException( String.format(
-                        "request.workspaceModelResolver and 
request.modelResolver cannot be null"
-                            + " (parent POM %s and POM %s)",
-                        ModelProblemUtils.toId( groupId, artifactId, version ),
-                        ModelProblemUtils.toSourceHint( model ) ) );
-                }
-
-                Model importModel = null;
-                if ( workspaceResolver != null )
-                {
-                    try
-                    {
-                        importModel = workspaceResolver.resolveEffectiveModel( 
groupId, artifactId, version );
-                    }
-                    catch ( UnresolvableModelException e )
-                    {
-                        problems.add( new ModelProblemCollectorRequest( 
Severity.FATAL, Version.BASE )
-                            .setMessage( e.getMessage().toString() 
).setException( e ) );
-                        continue;
-                    }
-                }
-
-                // no workspace resolver or workspace resolver returned null 
(i.e. model not in workspace)
-                if ( importModel == null )
-                {
-                    final ModelSource importSource;
-                    try
-                    {
-                        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 
scope=" + scope + " 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 )
-                    {
-                        StringBuilder buffer = new StringBuilder( 256 );
-                        buffer.append( "Non-resolvable " + scope + " POM" );
-                        if ( !containsCoordinates( e.getMessage(), groupId, 
artifactId, version ) )
-                        {
-                            buffer.append( ' ' ).append( 
ModelProblemUtils.toId( groupId, artifactId, version ) );
-                        }
-                        buffer.append( ": " ).append( e.getMessage() );
-
-                        problems.add( new ModelProblemCollectorRequest( 
Severity.ERROR, Version.BASE )
-                            .setMessage( buffer.toString() ).setLocation( 
dependency.getLocation( "" ) )
-                            .setException( e ) );
-                        continue;
-                    }
-
-                    if ( importRequest == null )
-                    {
-                        importRequest = new DefaultModelBuildingRequest();
-                        importRequest.setValidationLevel( 
ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
-                        importRequest.setModelCache( request.getModelCache() );
-                        importRequest.setSystemProperties( 
request.getSystemProperties() );
-                        importRequest.setUserProperties( 
request.getUserProperties() );
-                        importRequest.setLocationTracking( 
request.isLocationTracking() );
-                    }
-
-                    importRequest.setModelSource( importSource );
-                    importRequest.setModelResolver( modelResolver.newCopy() );
-
-                    final ModelBuildingResult importResult;
-                    try
-                    {
-                        importResult = build( importRequest );
-                    }
-                    catch ( ModelBuildingException e )
-                    {
-                        problems.addAll( e.getProblems() );
-                        continue;
-                    }
-
-                    problems.addAll( importResult.getProblems() );
-
-                    importModel = importResult.getEffectiveModel();
-                }
-
-                importDependencies = importModel.getDependencies();
-
-                putCache( request.getModelCache(), groupId, artifactId, 
version, ModelCacheTag.DEPENDENCIES,
-                          importDependencies );
-
-            }
-
-            if ( imports == null )
-            {
-                imports = new ArrayList<>();
-            }
-
-            imports.add( importDependencies );
-        }
-
-        importIds.remove( importing );
-
-        dependenciesImporter.importDependencies( model, imports, request, 
problems );
-    }
-
     private <T> void putCache( ModelCache modelCache, String groupId, String 
artifactId, String version,
                                ModelCacheTag<T> tag, T data )
     {

http://git-wip-us.apache.org/repos/asf/maven/blob/2313861d/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java
----------------------------------------------------------------------
diff --git 
a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java
 
b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java
index 526db68..313d307 100644
--- 
a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java
+++ 
b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java
@@ -20,9 +20,7 @@ package org.apache.maven.model.building;
  */
 
 import org.apache.maven.model.Model;
-import org.apache.maven.model.composition.DefaultDependenciesImporter;
 import org.apache.maven.model.composition.DefaultDependencyManagementImporter;
-import org.apache.maven.model.composition.DependenciesImporter;
 import org.apache.maven.model.composition.DependencyManagementImporter;
 import org.apache.maven.model.inheritance.DefaultInheritanceAssembler;
 import org.apache.maven.model.inheritance.InheritanceAssembler;
@@ -110,8 +108,11 @@ public class DefaultModelBuilderFactory
 
     protected ProfileActivator[] newProfileActivators()
     {
-        return new ProfileActivator[] { new JdkVersionProfileActivator(), new 
OperatingSystemProfileActivator(),
-            new PropertyProfileActivator(), new 
FileProfileActivator().setPathTranslator( newPathTranslator() ) };
+        return new ProfileActivator[]
+        {
+            new JdkVersionProfileActivator(), new 
OperatingSystemProfileActivator(),
+            new PropertyProfileActivator(), new 
FileProfileActivator().setPathTranslator( newPathTranslator() )
+        };
     }
 
     protected UrlNormalizer newUrlNormalizer()
@@ -171,11 +172,6 @@ public class DefaultModelBuilderFactory
         return new DefaultDependencyManagementImporter();
     }
 
-    protected DependenciesImporter newDependenciesImporter()
-    {
-        return new DefaultDependenciesImporter();
-    }
-
     protected DependencyManagementInjector newDependencyManagementInjector()
     {
         return new DefaultDependencyManagementInjector();
@@ -226,7 +222,6 @@ public class DefaultModelBuilderFactory
         modelBuilder.setProfileSelector( newProfileSelector() );
         modelBuilder.setSuperPomProvider( newSuperPomProvider() );
         modelBuilder.setDependencyManagementImporter( 
newDependencyManagementImporter() );
-        modelBuilder.setDependenciesImporter( newDependenciesImporter() );
         modelBuilder.setDependencyManagementInjector( 
newDependencyManagementInjector() );
         modelBuilder.setLifecycleBindingsInjector( 
newLifecycleBindingsInjector() );
         modelBuilder.setPluginManagementInjector( 
newPluginManagementInjector() );

http://git-wip-us.apache.org/repos/asf/maven/blob/2313861d/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java
----------------------------------------------------------------------
diff --git 
a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java
 
b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java
index a7009b2..e57db8e 100644
--- 
a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java
+++ 
b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java
@@ -19,9 +19,6 @@ package org.apache.maven.model.building;
  * under the License.
  */
 
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.maven.model.Dependency;
 import org.apache.maven.model.DependencyManagement;
 import org.apache.maven.model.Model;
 
@@ -54,6 +51,7 @@ interface ModelCacheTag<T>
      * cache is populated but the state of the cache must not change so we 
need to make a copy.
      *
      * @param data The data to store in the cache, must not be {@code null}.
+     *
      * @return The data being stored in the cache, never {@code null}.
      */
     T intoCache( T data );
@@ -63,6 +61,7 @@ interface ModelCacheTag<T>
      * cache is queried but the state of the cache must not change so we need 
to make a copy.
      *
      * @param data The data to retrieve from the cache, must not be {@code 
null}.
+     *
      * @return The data being retrieved from the cache, never {@code null}.
      */
     T fromCache( T data );
@@ -132,36 +131,4 @@ interface ModelCacheTag<T>
 
     };
 
-    /**
-     * The tag used to denote an effective dependencies section from an 
imported model.
-     */
-    ModelCacheTag<List<? extends Dependency>> DEPENDENCIES = new 
ModelCacheTag<List<? extends Dependency>>()
-    {
-
-        @Override
-        public String getName()
-        {
-            return "dependencies";
-        }
-
-        @Override
-        public Class<List<? extends Dependency>> getType()
-        {
-            return (Class<List<? extends Dependency>>) (Class) List.class;
-        }
-
-        @Override
-        public List<? extends Dependency> intoCache( List<? extends 
Dependency> data )
-        {
-            return ( data != null ) ? new ArrayList<>( data ) : null;
-        }
-
-        @Override
-        public List<? extends Dependency> fromCache( List<? extends 
Dependency> data )
-        {
-            return intoCache( data );
-        }
-
-    };
-
 }

http://git-wip-us.apache.org/repos/asf/maven/blob/2313861d/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependenciesImporter.java
----------------------------------------------------------------------
diff --git 
a/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependenciesImporter.java
 
b/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependenciesImporter.java
deleted file mode 100644
index b9496fb..0000000
--- 
a/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependenciesImporter.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.apache.maven.model.composition;
-
-/*
- * 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.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.maven.model.Dependency;
-import org.apache.maven.model.Model;
-import org.apache.maven.model.building.ModelBuildingRequest;
-import org.apache.maven.model.building.ModelProblemCollector;
-import org.codehaus.plexus.component.annotations.Component;
-
-/**
- * Handles the import of dependencies from other models into the target model.
- *
- * @author Christian Schulte
- */
-@Component( role = DependenciesImporter.class )
-public class DefaultDependenciesImporter
-    implements DependenciesImporter
-{
-
-    @Override
-    public void importDependencies( final Model target, final List<? extends 
List<? extends Dependency>> sources,
-                                    final ModelBuildingRequest request, final 
ModelProblemCollector problems )
-    {
-        if ( sources != null && !sources.isEmpty() )
-        {
-            final Map<String, Dependency> targetDependencies = new 
LinkedHashMap<>();
-
-            for ( final Dependency targetDependency : target.getDependencies() 
)
-            {
-                targetDependencies.put( targetDependency.getManagementKey(), 
targetDependency );
-            }
-
-            final List<Dependency> sourceDependencies = new ArrayList<>( 128 );
-
-            for ( final List<? extends Dependency> source : sources )
-            {
-                for ( final Dependency sourceDependency : source )
-                {
-                    if ( !targetDependencies.containsKey( 
sourceDependency.getManagementKey() ) )
-                    {
-                        // Intentionally does not check for conflicts in the 
source dependencies. We want
-                        // such conflicts to be resolved manually instead of 
silently getting dropped.
-                        sourceDependencies.add( sourceDependency );
-                    }
-                }
-            }
-
-            target.getDependencies().addAll( sourceDependencies );
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/maven/blob/2313861d/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java
----------------------------------------------------------------------
diff --git 
a/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java
 
b/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java
index 8b0f880..a5a05e8 100644
--- 
a/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java
+++ 
b/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java
@@ -20,12 +20,14 @@ package org.apache.maven.model.composition;
  */
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.Exclusion;
 import org.apache.maven.model.Model;
 import org.apache.maven.model.building.ModelBuildingRequest;
 import org.apache.maven.model.building.ModelProblemCollector;
@@ -45,6 +47,9 @@ public class DefaultDependencyManagementImporter
     public void importManagement( final Model target, final List<? extends 
DependencyManagement> sources,
                                   final ModelBuildingRequest request, final 
ModelProblemCollector problems )
     {
+        // Intentionally does not check for conflicts in the source 
dependencies. We want such conflicts to be resolved
+        // manually instead of silently getting dropped.
+
         if ( sources != null && !sources.isEmpty() )
         {
             final Map<String, Dependency> targetDependencies = new 
LinkedHashMap<>();
@@ -59,7 +64,7 @@ public class DefaultDependencyManagementImporter
                 targetDependencies.put( targetDependency.getManagementKey(), 
targetDependency );
             }
 
-            final List<Dependency> sourceDependencies = new ArrayList<>( 128 );
+            final Map<String, List<Dependency>> sourceDependencies = new 
LinkedHashMap<>();
 
             for ( final DependencyManagement source : sources )
             {
@@ -67,15 +72,131 @@ public class DefaultDependencyManagementImporter
                 {
                     if ( !targetDependencies.containsKey( 
sourceDependency.getManagementKey() ) )
                     {
-                        // Intentionally does not check for conflicts in the 
source dependency managements. We want
-                        // such conflicts to be resolved manually instead of 
silently getting dropped.
-                        sourceDependencies.add( sourceDependency );
+                        List<Dependency> conflictingDependencies =
+                            sourceDependencies.get( 
sourceDependency.getManagementKey() );
+
+                        if ( conflictingDependencies == null )
+                        {
+                            conflictingDependencies = new ArrayList<>();
+                            sourceDependencies.put( 
sourceDependency.getManagementKey(), conflictingDependencies );
+                        }
+
+                        conflictingDependencies.add( sourceDependency );
                     }
                 }
             }
 
-            targetDependencyManagement.getDependencies().addAll( 
sourceDependencies );
+            for ( final List<Dependency> conflictingDependencies : 
sourceDependencies.values() )
+            {
+                targetDependencyManagement.getDependencies().
+                    addAll( this.removeRedundantDependencies( 
conflictingDependencies ) );
+
+            }
         }
     }
 
+    private List<Dependency> removeRedundantDependencies( final 
List<Dependency> candidateDependencies )
+    {
+        final List<Dependency> resultDependencies = new ArrayList<>( 
candidateDependencies.size() );
+
+        while ( !candidateDependencies.isEmpty() )
+        {
+            final Dependency resultDependency = candidateDependencies.remove( 
0 );
+            resultDependencies.add( resultDependency );
+
+            // Removes redundant dependencies.
+            for ( final Iterator<Dependency> it = 
candidateDependencies.iterator(); it.hasNext(); )
+            {
+                final Dependency candidateDependency = it.next();
+                it.remove();
+
+                boolean redundant = true;
+
+                redundancy_check:
+                {
+                    if ( !( resultDependency.getOptional() != null
+                            ? resultDependency.getOptional().equals( 
candidateDependency.getOptional() )
+                            : candidateDependency.getOptional() == null ) )
+                    {
+                        redundant = false;
+                        break redundancy_check;
+                    }
+
+                    if ( !( resultDependency.getScope() != null
+                            ? resultDependency.getScope().equals( 
candidateDependency.getScope() )
+                            : candidateDependency.getScope() == null ) )
+                    {
+                        redundant = false;
+                        break redundancy_check;
+                    }
+
+                    if ( !( resultDependency.getSystemPath() != null
+                            ? resultDependency.getSystemPath().equals( 
candidateDependency.getSystemPath() )
+                            : candidateDependency.getSystemPath() == null ) )
+                    {
+                        redundant = false;
+                        break redundancy_check;
+                    }
+
+                    if ( !( resultDependency.getVersion() != null
+                            ? resultDependency.getVersion().equals( 
candidateDependency.getVersion() )
+                            : candidateDependency.getVersion() == null ) )
+                    {
+                        redundant = false;
+                        break redundancy_check;
+                    }
+
+                    for ( int i = 0, s0 = 
resultDependency.getExclusions().size(); i < s0; i++ )
+                    {
+                        final Exclusion resultExclusion = 
resultDependency.getExclusions().get( i );
+
+                        if ( !containsExclusion( 
candidateDependency.getExclusions(), resultExclusion ) )
+                        {
+                            redundant = false;
+                            break redundancy_check;
+                        }
+                    }
+
+                    for ( int i = 0, s0 = 
candidateDependency.getExclusions().size(); i < s0; i++ )
+                    {
+                        final Exclusion candidateExclusion = 
candidateDependency.getExclusions().get( i );
+
+                        if ( !containsExclusion( 
resultDependency.getExclusions(), candidateExclusion ) )
+                        {
+                            redundant = false;
+                            break redundancy_check;
+                        }
+                    }
+                }
+
+                if ( !redundant )
+                {
+                    resultDependencies.add( candidateDependency );
+                }
+            }
+        }
+
+        return resultDependencies;
+    }
+
+    private static boolean containsExclusion( final List<Exclusion> 
exclusions, final Exclusion exclusion )
+    {
+        for ( int i = 0, s0 = exclusions.size(); i < s0; i++ )
+        {
+            final Exclusion current = exclusions.get( i );
+
+            if ( ( exclusion.getArtifactId() != null
+                   ? exclusion.getArtifactId().equals( current.getArtifactId() 
)
+                   : current.getArtifactId() == null )
+                     && ( exclusion.getGroupId() != null
+                          ? exclusion.getGroupId().equals( 
current.getGroupId() )
+                          : current.getGroupId() == null ) )
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/maven/blob/2313861d/maven-model-builder/src/main/java/org/apache/maven/model/composition/DependenciesImporter.java
----------------------------------------------------------------------
diff --git 
a/maven-model-builder/src/main/java/org/apache/maven/model/composition/DependenciesImporter.java
 
b/maven-model-builder/src/main/java/org/apache/maven/model/composition/DependenciesImporter.java
deleted file mode 100644
index 5874f6a..0000000
--- 
a/maven-model-builder/src/main/java/org/apache/maven/model/composition/DependenciesImporter.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.apache.maven.model.composition;
-
-/*
- * 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.List;
-import org.apache.maven.model.Dependency;
-import org.apache.maven.model.Model;
-import org.apache.maven.model.building.ModelBuildingRequest;
-import org.apache.maven.model.building.ModelProblemCollector;
-
-/**
- * Handles the import of dependencies from other models into the target model.
- *
- * @author Christian Schulte
- * @since 3.4
- */
-public interface DependenciesImporter
-{
-
-    /**
-     * Imports the specified dependencies sections into the given target model.
-     *
-     * @param target The model into which to import the dependencies sections, 
must not be <code>null</code>.
-     * @param sources The dependencies sections to import, may be 
<code>null</code>.
-     * @param request The model building request that holds further settings, 
must not be {@code null}.
-     * @param problems The container used to collect problems that were 
encountered, must not be {@code null}.
-     */
-    void importDependencies( final Model target, final List<? extends List<? 
extends Dependency>> sources,
-                             final ModelBuildingRequest request, final 
ModelProblemCollector problems );
-
-}

Reply via email to