From b814fec63d1e5eb49f3b64af620897f19a5e6963 Mon Sep 17 00:00:00 2001 From: Jan-Jelle Kester Date: Sat, 30 Oct 2021 15:59:26 +0200 Subject: [PATCH] [MPH-183] BOM hierarchy in InputSource --- .../DefaultDependencyManagementImporter.java | 46 +++++++ ...faultDependencyManagementImporterTest.java | 115 ++++++++++++++++++ maven-model/src/main/mdo/maven.mdo | 14 +++ 3 files changed, 175 insertions(+) create mode 100644 maven-model-builder/src/test/java/org/apache/maven/model/composition/DefaultDependencyManagementImporterTest.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 b277bf3a1caf..bbee5042c571 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 @@ -23,12 +23,15 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import javax.inject.Named; import javax.inject.Singleton; import org.apache.maven.model.Dependency; import org.apache.maven.model.DependencyManagement; +import org.apache.maven.model.InputLocation; +import org.apache.maven.model.InputSource; import org.apache.maven.model.Model; import org.apache.maven.model.building.ModelBuildingRequest; import org.apache.maven.model.building.ModelProblemCollector; @@ -75,6 +78,10 @@ public void importManagement( Model target, List if ( !dependencies.containsKey( key ) ) { dependencies.put( key, dependency ); + if ( request.isLocationTracking() ) + { + updateDependencyHierarchy( dependency, source ); + } } } } @@ -83,4 +90,43 @@ public void importManagement( Model target, List } } + static void updateDependencyHierarchy( Dependency dependency, DependencyManagement bom ) + { + // We are only interested in the InputSource, so the location of the element is sufficient + InputLocation dependencyLocation = dependency.getLocation( "" ); + InputLocation bomLocation = bom.getLocation( "" ); + + if ( dependencyLocation == null || bomLocation == null ) + { + return; + } + + InputSource hierarchicalSource = dependencyLocation.getSource(); + InputSource bomSource = bomLocation.getSource(); + + // Skip if the dependency and bom have the same source + if ( hierarchicalSource == null || bomSource == null || Objects.equals( hierarchicalSource.getModelId(), + bomSource.getModelId() ) ) + { + return; + } + + while ( hierarchicalSource.getImportedBy() != null ) + { + InputSource newSource = hierarchicalSource.getImportedBy(); + + // Stop if the bom is already in the list, no update necessary + if ( Objects.equals( newSource.getModelId(), bomSource.getModelId() ) ) + { + return; + } + + hierarchicalSource = newSource; + } + + // We modify the InputSource that is used for the whole file + // This is assumed to be correct because the pom hierarchy applies to the whole pom, not just one dependency + hierarchicalSource.setImportedBy( bomSource ); + } + } diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/composition/DefaultDependencyManagementImporterTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/composition/DefaultDependencyManagementImporterTest.java new file mode 100644 index 000000000000..2483ac9b0a3a --- /dev/null +++ b/maven-model-builder/src/test/java/org/apache/maven/model/composition/DefaultDependencyManagementImporterTest.java @@ -0,0 +1,115 @@ +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 org.apache.maven.model.Dependency; +import org.apache.maven.model.DependencyManagement; +import org.apache.maven.model.InputLocation; +import org.apache.maven.model.InputSource; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class DefaultDependencyManagementImporterTest +{ + @Test + public void testUpdateDependencyHierarchy_SameSource() + { + InputSource source = new InputSource(); + source.setModelId( "SINGLE_SOURCE" ); + Dependency dependency = new Dependency(); + dependency.setLocation( "", new InputLocation( 1, 1, source ) ); + DependencyManagement bom = new DependencyManagement(); + bom.setLocation( "", new InputLocation( 2, 2, source ) ); + + DefaultDependencyManagementImporter.updateDependencyHierarchy( dependency, bom ); + + assertSame( source, dependency.getLocation( "" ).getSource() ); + assertSame( source, bom.getLocation( "" ).getSource() ); + assertNull( source.getImportedBy() ); + } + + @Test + public void testUpdateDependencyHierarchy_SingleLevel() + { + InputSource dependencySource = new InputSource(); + dependencySource.setModelId( "DEPENDENCY" ); + InputSource bomSource = new InputSource(); + bomSource.setModelId( "BOM" ); + Dependency dependency = new Dependency(); + dependency.setLocation( "", new InputLocation( 1, 1, dependencySource ) ); + DependencyManagement bom = new DependencyManagement(); + bom.setLocation( "", new InputLocation( 2, 2, bomSource ) ); + + DefaultDependencyManagementImporter.updateDependencyHierarchy( dependency, bom ); + + assertSame( dependencySource, dependency.getLocation( "" ).getSource() ); + assertSame( bomSource, bom.getLocation( "" ).getSource() ); + assertEquals( bomSource, dependencySource.getImportedBy() ); + } + + @Test + public void testUpdateDependencyHierarchy_MultiLevel() + { + InputSource intermediateSource = new InputSource(); + intermediateSource.setModelId( "INTERMEDIATE" ); + InputSource dependencySource = new InputSource(); + dependencySource.setModelId( "DEPENDENCY" ); + dependencySource.setImportedBy( intermediateSource ); + InputSource bomSource = new InputSource(); + bomSource.setModelId( "BOM" ); + Dependency dependency = new Dependency(); + dependency.setLocation( "", new InputLocation( 1, 1, dependencySource ) ); + DependencyManagement bom = new DependencyManagement(); + bom.setLocation( "", new InputLocation( 2, 2, bomSource ) ); + + DefaultDependencyManagementImporter.updateDependencyHierarchy( dependency, bom ); + + assertSame( dependencySource, dependency.getLocation( "" ).getSource() ); + assertSame( bomSource, bom.getLocation( "" ).getSource() ); + assertEquals( intermediateSource, dependencySource.getImportedBy() ); + assertEquals( bomSource, intermediateSource.getImportedBy() ); + } + + @Test + public void testUpdateDependencyHierarchy_PresentSource() + { + InputSource bomSource = new InputSource(); + bomSource.setModelId( "BOM" ); + InputSource intermediateSource = new InputSource(); + intermediateSource.setModelId( "INTERMEDIATE" ); + intermediateSource.setImportedBy( bomSource ); + InputSource dependencySource = new InputSource(); + dependencySource.setModelId( "DEPENDENCY" ); + dependencySource.setImportedBy( intermediateSource ); + Dependency dependency = new Dependency(); + dependency.setLocation( "", new InputLocation( 1, 1, dependencySource ) ); + DependencyManagement bom = new DependencyManagement(); + bom.setLocation( "", new InputLocation( 2, 2, bomSource ) ); + + DefaultDependencyManagementImporter.updateDependencyHierarchy( dependency, bom ); + + assertSame( dependencySource, dependency.getLocation( "" ).getSource() ); + assertSame( bomSource, bom.getLocation( "" ).getSource() ); + assertEquals( intermediateSource, dependencySource.getImportedBy() ); + assertEquals( bomSource, intermediateSource.getImportedBy() ); + assertNull( bomSource.getImportedBy() ); + } +} diff --git a/maven-model/src/main/mdo/maven.mdo b/maven-model/src/main/mdo/maven.mdo index c0d253b6e586..3578b4b52f4d 100644 --- a/maven-model/src/main/mdo/maven.mdo +++ b/maven-model/src/main/mdo/maven.mdo @@ -3137,6 +3137,20 @@ ]]> + + importedBy + 4.0.0+ + + InputSource + false + + + + +