Skip to content

Commit b814fec

Browse files
committed
[MPH-183] BOM hierarchy in InputSource
1 parent a5f1bca commit b814fec

File tree

3 files changed

+175
-0
lines changed

3 files changed

+175
-0
lines changed

maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,15 @@
2323
import java.util.LinkedHashMap;
2424
import java.util.List;
2525
import java.util.Map;
26+
import java.util.Objects;
2627

2728
import javax.inject.Named;
2829
import javax.inject.Singleton;
2930

3031
import org.apache.maven.model.Dependency;
3132
import org.apache.maven.model.DependencyManagement;
33+
import org.apache.maven.model.InputLocation;
34+
import org.apache.maven.model.InputSource;
3235
import org.apache.maven.model.Model;
3336
import org.apache.maven.model.building.ModelBuildingRequest;
3437
import org.apache.maven.model.building.ModelProblemCollector;
@@ -75,6 +78,10 @@ public void importManagement( Model target, List<? extends DependencyManagement>
7578
if ( !dependencies.containsKey( key ) )
7679
{
7780
dependencies.put( key, dependency );
81+
if ( request.isLocationTracking() )
82+
{
83+
updateDependencyHierarchy( dependency, source );
84+
}
7885
}
7986
}
8087
}
@@ -83,4 +90,43 @@ public void importManagement( Model target, List<? extends DependencyManagement>
8390
}
8491
}
8592

93+
static void updateDependencyHierarchy( Dependency dependency, DependencyManagement bom )
94+
{
95+
// We are only interested in the InputSource, so the location of the <dependency> element is sufficient
96+
InputLocation dependencyLocation = dependency.getLocation( "" );
97+
InputLocation bomLocation = bom.getLocation( "" );
98+
99+
if ( dependencyLocation == null || bomLocation == null )
100+
{
101+
return;
102+
}
103+
104+
InputSource hierarchicalSource = dependencyLocation.getSource();
105+
InputSource bomSource = bomLocation.getSource();
106+
107+
// Skip if the dependency and bom have the same source
108+
if ( hierarchicalSource == null || bomSource == null || Objects.equals( hierarchicalSource.getModelId(),
109+
bomSource.getModelId() ) )
110+
{
111+
return;
112+
}
113+
114+
while ( hierarchicalSource.getImportedBy() != null )
115+
{
116+
InputSource newSource = hierarchicalSource.getImportedBy();
117+
118+
// Stop if the bom is already in the list, no update necessary
119+
if ( Objects.equals( newSource.getModelId(), bomSource.getModelId() ) )
120+
{
121+
return;
122+
}
123+
124+
hierarchicalSource = newSource;
125+
}
126+
127+
// We modify the InputSource that is used for the whole file
128+
// This is assumed to be correct because the pom hierarchy applies to the whole pom, not just one dependency
129+
hierarchicalSource.setImportedBy( bomSource );
130+
}
131+
86132
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package org.apache.maven.model.composition;
2+
3+
/*
4+
* Licensed to the Apache Software Foundation (ASF) under one
5+
* or more contributor license agreements. See the NOTICE file
6+
* distributed with this work for additional information
7+
* regarding copyright ownership. The ASF licenses this file
8+
* to you under the Apache License, Version 2.0 (the
9+
* "License"); you may not use this file except in compliance
10+
* with the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing,
15+
* software distributed under the License is distributed on an
16+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
* KIND, either express or implied. See the License for the
18+
* specific language governing permissions and limitations
19+
* under the License.
20+
*/
21+
22+
import org.apache.maven.model.Dependency;
23+
import org.apache.maven.model.DependencyManagement;
24+
import org.apache.maven.model.InputLocation;
25+
import org.apache.maven.model.InputSource;
26+
import org.junit.jupiter.api.Test;
27+
28+
import static org.junit.jupiter.api.Assertions.*;
29+
30+
class DefaultDependencyManagementImporterTest
31+
{
32+
@Test
33+
public void testUpdateDependencyHierarchy_SameSource()
34+
{
35+
InputSource source = new InputSource();
36+
source.setModelId( "SINGLE_SOURCE" );
37+
Dependency dependency = new Dependency();
38+
dependency.setLocation( "", new InputLocation( 1, 1, source ) );
39+
DependencyManagement bom = new DependencyManagement();
40+
bom.setLocation( "", new InputLocation( 2, 2, source ) );
41+
42+
DefaultDependencyManagementImporter.updateDependencyHierarchy( dependency, bom );
43+
44+
assertSame( source, dependency.getLocation( "" ).getSource() );
45+
assertSame( source, bom.getLocation( "" ).getSource() );
46+
assertNull( source.getImportedBy() );
47+
}
48+
49+
@Test
50+
public void testUpdateDependencyHierarchy_SingleLevel()
51+
{
52+
InputSource dependencySource = new InputSource();
53+
dependencySource.setModelId( "DEPENDENCY" );
54+
InputSource bomSource = new InputSource();
55+
bomSource.setModelId( "BOM" );
56+
Dependency dependency = new Dependency();
57+
dependency.setLocation( "", new InputLocation( 1, 1, dependencySource ) );
58+
DependencyManagement bom = new DependencyManagement();
59+
bom.setLocation( "", new InputLocation( 2, 2, bomSource ) );
60+
61+
DefaultDependencyManagementImporter.updateDependencyHierarchy( dependency, bom );
62+
63+
assertSame( dependencySource, dependency.getLocation( "" ).getSource() );
64+
assertSame( bomSource, bom.getLocation( "" ).getSource() );
65+
assertEquals( bomSource, dependencySource.getImportedBy() );
66+
}
67+
68+
@Test
69+
public void testUpdateDependencyHierarchy_MultiLevel()
70+
{
71+
InputSource intermediateSource = new InputSource();
72+
intermediateSource.setModelId( "INTERMEDIATE" );
73+
InputSource dependencySource = new InputSource();
74+
dependencySource.setModelId( "DEPENDENCY" );
75+
dependencySource.setImportedBy( intermediateSource );
76+
InputSource bomSource = new InputSource();
77+
bomSource.setModelId( "BOM" );
78+
Dependency dependency = new Dependency();
79+
dependency.setLocation( "", new InputLocation( 1, 1, dependencySource ) );
80+
DependencyManagement bom = new DependencyManagement();
81+
bom.setLocation( "", new InputLocation( 2, 2, bomSource ) );
82+
83+
DefaultDependencyManagementImporter.updateDependencyHierarchy( dependency, bom );
84+
85+
assertSame( dependencySource, dependency.getLocation( "" ).getSource() );
86+
assertSame( bomSource, bom.getLocation( "" ).getSource() );
87+
assertEquals( intermediateSource, dependencySource.getImportedBy() );
88+
assertEquals( bomSource, intermediateSource.getImportedBy() );
89+
}
90+
91+
@Test
92+
public void testUpdateDependencyHierarchy_PresentSource()
93+
{
94+
InputSource bomSource = new InputSource();
95+
bomSource.setModelId( "BOM" );
96+
InputSource intermediateSource = new InputSource();
97+
intermediateSource.setModelId( "INTERMEDIATE" );
98+
intermediateSource.setImportedBy( bomSource );
99+
InputSource dependencySource = new InputSource();
100+
dependencySource.setModelId( "DEPENDENCY" );
101+
dependencySource.setImportedBy( intermediateSource );
102+
Dependency dependency = new Dependency();
103+
dependency.setLocation( "", new InputLocation( 1, 1, dependencySource ) );
104+
DependencyManagement bom = new DependencyManagement();
105+
bom.setLocation( "", new InputLocation( 2, 2, bomSource ) );
106+
107+
DefaultDependencyManagementImporter.updateDependencyHierarchy( dependency, bom );
108+
109+
assertSame( dependencySource, dependency.getLocation( "" ).getSource() );
110+
assertSame( bomSource, bom.getLocation( "" ).getSource() );
111+
assertEquals( intermediateSource, dependencySource.getImportedBy() );
112+
assertEquals( bomSource, intermediateSource.getImportedBy() );
113+
assertNull( bomSource.getImportedBy() );
114+
}
115+
}

maven-model/src/main/mdo/maven.mdo

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3137,6 +3137,20 @@
31373137
]]>
31383138
</description>
31393139
</field>
3140+
<field>
3141+
<name>importedBy</name>
3142+
<version>4.0.0+</version>
3143+
<association>
3144+
<type>InputSource</type>
3145+
<bidi>false</bidi>
3146+
</association>
3147+
<description>
3148+
<![CDATA[
3149+
The InputSource of the pom that imported this pom in dependency management, or {@code null} if unknown or
3150+
top-level.
3151+
]]>
3152+
</description>
3153+
</field>
31403154
</fields>
31413155
<codeSegments>
31423156
<codeSegment>

0 commit comments

Comments
 (0)