maven-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From schu...@apache.org
Subject maven git commit: [MNG-5971] Imported dependencies should be available to inheritance processing
Date Fri, 19 Feb 2016 20:47:38 GMT
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 <schulte@apache.org>
Authored: Fri Feb 19 21:04:50 2016 +0100
Committer: Christian Schulte <schulte@apache.org>
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 );
-
-}


Mime
View raw message