Skip to content

Commit

Permalink
[MPH-183] BOM hierarchy in InputSource
Browse files Browse the repository at this point in the history
  • Loading branch information
jjkester committed Oct 31, 2021
1 parent a5f1bca commit b814fec
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -75,6 +78,10 @@ public void importManagement( Model target, List<? extends DependencyManagement>
if ( !dependencies.containsKey( key ) )
{
dependencies.put( key, dependency );
if ( request.isLocationTracking() )
{
updateDependencyHierarchy( dependency, source );
}
}
}
}
Expand All @@ -83,4 +90,43 @@ public void importManagement( Model target, List<? extends DependencyManagement>
}
}

static void updateDependencyHierarchy( Dependency dependency, DependencyManagement bom )
{
// We are only interested in the InputSource, so the location of the <dependency> 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 );
}

}
Original file line number Diff line number Diff line change
@@ -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() );
}
}
14 changes: 14 additions & 0 deletions maven-model/src/main/mdo/maven.mdo
Original file line number Diff line number Diff line change
Expand Up @@ -3137,6 +3137,20 @@
]]>
</description>
</field>
<field>
<name>importedBy</name>
<version>4.0.0+</version>
<association>
<type>InputSource</type>
<bidi>false</bidi>
</association>
<description>
<![CDATA[
The InputSource of the pom that imported this pom in dependency management, or {@code null} if unknown or
top-level.
]]>
</description>
</field>
</fields>
<codeSegments>
<codeSegment>
Expand Down

0 comments on commit b814fec

Please sign in to comment.