You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sc...@apache.org on 2016/02/18 14:39:32 UTC

maven git commit: [MNG-5971] Imported dependencies should be available to inheritance processing

Repository: maven
Updated Branches:
  refs/heads/master ea73fcdb6 -> af2c42c2c


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

o Updated the 'DefaultDependencyManagementImporter' to stop
  ignoring import dependency conflicts silently. Such
  conflicts must be resolved manually by adding the conflicting
  dependency to the pom manually.
o Updated to add support for an 'include' scope in dependency
  management processed before inheritance and interpolation.
o Updated to add support for 'import' and 'include' scopes
  also for dependencies.


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

Branch: refs/heads/master
Commit: af2c42c2c16b6d6f15867646fd82b224359a5910
Parents: ea73fcd
Author: Christian Schulte <sc...@apache.org>
Authored: Thu Feb 18 14:07:02 2016 +0100
Committer: Christian Schulte <sc...@apache.org>
Committed: Thu Feb 18 14:39:23 2016 +0100

----------------------------------------------------------------------
 .../model/building/DefaultModelBuilder.java     | 216 ++++++++++++++++++-
 .../building/DefaultModelBuilderFactory.java    |   8 +
 .../maven/model/building/ModelCacheTag.java     |  35 +++
 .../DefaultDependenciesImporter.java            |  78 +++++++
 .../DefaultDependencyManagementImporter.java    |  42 ++--
 .../model/composition/DependenciesImporter.java |  48 +++++
 6 files changed, 401 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven/blob/af2c42c2/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 d42bfdd..8872a5b 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,6 +38,7 @@ 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;
@@ -68,6 +69,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -123,6 +125,9 @@ public class DefaultModelBuilder
     @Requirement
     private DependencyManagementImporter dependencyManagementImporter;
 
+    @Requirement
+    private DependenciesImporter dependenciesImporter;
+
     @Requirement( optional = true )
     private LifecycleBindingsInjector lifecycleBindingsInjector;
 
@@ -201,6 +206,12 @@ public class DefaultModelBuilder
         return this;
     }
 
+    public DefaultModelBuilder setDependenciesImporter( DependenciesImporter dependenciesImporter )
+    {
+        this.dependenciesImporter = dependenciesImporter;
+        return this;
+    }
+
     public DefaultModelBuilder setDependencyManagementInjector( DependencyManagementInjector depMngmntInjector )
     {
         this.dependencyManagementInjector = depMngmntInjector;
@@ -418,11 +429,11 @@ public class DefaultModelBuilder
     public ModelBuildingResult build( ModelBuildingRequest request, ModelBuildingResult result )
         throws ModelBuildingException
     {
-        return build( request, result, new LinkedHashSet<String>() );
+        return build( request, result, new LinkedHashSet<String>(), new LinkedHashSet<String>() );
     }
 
     private ModelBuildingResult build( ModelBuildingRequest request, ModelBuildingResult result,
-                                       Collection<String> imports )
+                                       Collection<String> managementImports, Collection<String> dependencyImports )
         throws ModelBuildingException
     {
         // phase 2
@@ -452,7 +463,10 @@ public class DefaultModelBuilder
         }
 
         // dependency management import
-        importDependencyManagement( resultModel, request, problems, imports );
+        importDependencyManagement( resultModel, "import", request, problems, managementImports );
+
+        // dependencies import
+        importDependencies( resultModel, "import", request, problems, dependencyImports );
 
         // dependency management injection
         dependencyManagementInjector.injectManagement( resultModel, request, problems );
@@ -601,6 +615,10 @@ public class DefaultModelBuilder
         model.setPomFile( pomFile );
 
         problems.setSource( model );
+
+        this.importDependencyManagement( model, "include", request, problems, new HashSet<String>() );
+        this.importDependencies( model, "include", request, problems, new HashSet<String>() );
+
         modelValidator.validateRawModel( model, request, problems );
 
         if ( hasFatalErrors( problems ) )
@@ -1097,7 +1115,7 @@ public class DefaultModelBuilder
         return superPomProvider.getSuperModel( "4.0.0" ).clone();
     }
 
-    private void importDependencyManagement( Model model, ModelBuildingRequest request,
+    private void importDependencyManagement( Model model, String scope, ModelBuildingRequest request,
                                              DefaultModelProblemCollector problems, Collection<String> importIds )
     {
         DependencyManagement depMngt = model.getDependencyManagement();
@@ -1122,7 +1140,7 @@ public class DefaultModelBuilder
         {
             Dependency dependency = it.next();
 
-            if ( !"pom".equals( dependency.getType() ) || !"import".equals( dependency.getScope() ) )
+            if ( !"pom".equals( dependency.getType() ) || !scope.equals( dependency.getScope() ) )
             {
                 continue;
             }
@@ -1296,6 +1314,194 @@ 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 with scope=import 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 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 )
+                    {
+                        StringBuilder buffer = new StringBuilder( 256 );
+                        buffer.append( "Non-resolvable import 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/af2c42c2/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 36a0f46..526db68 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,7 +20,9 @@ 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;
@@ -169,6 +171,11 @@ public class DefaultModelBuilderFactory
         return new DefaultDependencyManagementImporter();
     }
 
+    protected DependenciesImporter newDependenciesImporter()
+    {
+        return new DefaultDependenciesImporter();
+    }
+
     protected DependencyManagementInjector newDependencyManagementInjector()
     {
         return new DefaultDependencyManagementInjector();
@@ -219,6 +226,7 @@ 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/af2c42c2/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 8452f96..a7009b2 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,6 +19,9 @@ 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;
 
@@ -129,4 +132,36 @@ 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/af2c42c2/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
new file mode 100644
index 0000000..171153e
--- /dev/null
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependenciesImporter.java
@@ -0,0 +1,78 @@
+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 );
+                    }
+                }
+            }
+
+            final List<Dependency> dependencies = new ArrayList<>( targetDependencies.values() );
+            dependencies.addAll( sourceDependencies );
+
+            target.getDependencies().clear();
+            target.getDependencies().addAll( dependencies );
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/af2c42c2/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 d895913..7ab0f05 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
@@ -42,41 +42,41 @@ public class DefaultDependencyManagementImporter
 {
 
     @Override
-    public void importManagement( Model target, List<? extends DependencyManagement> sources,
-                                  ModelBuildingRequest request, ModelProblemCollector problems )
+    public void importManagement( final Model target, final List<? extends DependencyManagement> sources,
+                                  final ModelBuildingRequest request, final ModelProblemCollector problems )
     {
         if ( sources != null && !sources.isEmpty() )
         {
-            Map<String, Dependency> dependencies = new LinkedHashMap<>();
+            final Map<String, Dependency> targetDependencies = new LinkedHashMap<>();
+            final DependencyManagement targetDependencyManagement = target.getDependencyManagement() != null
+                                                                        ? target.getDependencyManagement()
+                                                                        : new DependencyManagement();
 
-            DependencyManagement depMngt = target.getDependencyManagement();
-
-            if ( depMngt != null )
+            for ( final Dependency targetDependency : targetDependencyManagement.getDependencies() )
             {
-                for ( Dependency dependency : depMngt.getDependencies() )
-                {
-                    dependencies.put( dependency.getManagementKey(), dependency );
-                }
-            }
-            else
-            {
-                depMngt = new DependencyManagement();
-                target.setDependencyManagement( depMngt );
+                targetDependencies.put( targetDependency.getManagementKey(), targetDependency );
             }
 
-            for ( DependencyManagement source : sources )
+            final List<Dependency> sourceDependencies = new ArrayList<>( 128 );
+
+            for ( final DependencyManagement source : sources )
             {
-                for ( Dependency dependency : source.getDependencies() )
+                for ( final Dependency sourceDependency : source.getDependencies() )
                 {
-                    String key = dependency.getManagementKey();
-                    if ( !dependencies.containsKey( key ) )
+                    if ( !targetDependencies.containsKey( sourceDependency.getManagementKey() ) )
                     {
-                        dependencies.put( key, dependency );
+                        // 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 );
                     }
                 }
             }
 
-            depMngt.setDependencies( new ArrayList<>( dependencies.values() ) );
+            final List<Dependency> dependencies = new ArrayList<>( targetDependencies.values() );
+            dependencies.addAll( sourceDependencies );
+
+            targetDependencyManagement.setDependencies( dependencies );
+            target.setDependencyManagement( targetDependencyManagement );
         }
     }
 

http://git-wip-us.apache.org/repos/asf/maven/blob/af2c42c2/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
new file mode 100644
index 0000000..5874f6a
--- /dev/null
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/composition/DependenciesImporter.java
@@ -0,0 +1,48 @@
+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 );
+
+}