mirror of https://github.com/apache/maven.git
[MNG-7344] Track dependencyManagement import location in effective Model for MPH-183 (#603)
Co-authored-by: Maarten Mulders <mthmulders@apache.org> Co-authored-by: Juul Hobert <juul.hobert@infosupport.com> Co-authored-by: Giovanni van der Schelde <gvdschelde@gmail.com> Co-authored-by: Guillaume Nodet <gnodet@gmail.com>
This commit is contained in:
parent
1ee18d36ce
commit
5b61e95f23
|
@ -32,12 +32,14 @@ public class InputLocation implements Serializable, InputLocationTracker {
|
|||
private final int columnNumber;
|
||||
private final InputSource source;
|
||||
private final Map<Object, InputLocation> locations;
|
||||
private final InputLocation importedFrom;
|
||||
|
||||
public InputLocation(InputSource source) {
|
||||
this.lineNumber = -1;
|
||||
this.columnNumber = -1;
|
||||
this.source = source;
|
||||
this.locations = Collections.singletonMap(0, this);
|
||||
this.importedFrom = null;
|
||||
}
|
||||
|
||||
public InputLocation(int lineNumber, int columnNumber) {
|
||||
|
@ -54,6 +56,7 @@ public class InputLocation implements Serializable, InputLocationTracker {
|
|||
this.source = source;
|
||||
this.locations =
|
||||
selfLocationKey != null ? Collections.singletonMap(selfLocationKey, this) : Collections.emptyMap();
|
||||
this.importedFrom = null;
|
||||
}
|
||||
|
||||
public InputLocation(int lineNumber, int columnNumber, InputSource source, Map<Object, InputLocation> locations) {
|
||||
|
@ -61,6 +64,15 @@ public class InputLocation implements Serializable, InputLocationTracker {
|
|||
this.columnNumber = columnNumber;
|
||||
this.source = source;
|
||||
this.locations = ImmutableCollections.copy(locations);
|
||||
this.importedFrom = null;
|
||||
}
|
||||
|
||||
public InputLocation(InputLocation original) {
|
||||
this.lineNumber = original.lineNumber;
|
||||
this.columnNumber = original.columnNumber;
|
||||
this.source = original.source;
|
||||
this.locations = original.locations;
|
||||
this.importedFrom = original.importedFrom;
|
||||
}
|
||||
|
||||
public int getLineNumber() {
|
||||
|
@ -83,6 +95,17 @@ public class InputLocation implements Serializable, InputLocationTracker {
|
|||
return locations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parent InputLocation where this InputLocation may have been imported from.
|
||||
* Can return {@code null}.
|
||||
*
|
||||
* @return InputLocation
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public InputLocation getImportedFrom() {
|
||||
return importedFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the {@code source} location into the {@code target} location.
|
||||
*
|
||||
|
@ -152,4 +175,26 @@ public class InputLocation implements Serializable, InputLocationTracker {
|
|||
|
||||
return new InputLocation(-1, -1, InputSource.merge(source.getSource(), target.getSource()), locations);
|
||||
} // -- InputLocation merge( InputLocation, InputLocation, java.util.Collection )
|
||||
|
||||
/**
|
||||
* Class StringFormatter.
|
||||
*
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
public interface StringFormatter {
|
||||
|
||||
// -----------/
|
||||
// - Methods -/
|
||||
// -----------/
|
||||
|
||||
/**
|
||||
* Method toString.
|
||||
*/
|
||||
String toString(InputLocation location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s @ %d:%d", source.getLocation(), lineNumber, columnNumber);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,4 +20,13 @@ package org.apache.maven.api.model;
|
|||
|
||||
public interface InputLocationTracker {
|
||||
InputLocation getLocation(Object field);
|
||||
|
||||
/**
|
||||
* Gets the parent InputLocation where this InputLocation may have been imported from.
|
||||
* Can return {@code null}.
|
||||
*
|
||||
* @return InputLocation
|
||||
* @since 4.0.0
|
||||
*/
|
||||
InputLocation getImportedFrom();
|
||||
}
|
||||
|
|
|
@ -33,17 +33,24 @@ public class InputSource implements Serializable {
|
|||
private final String modelId;
|
||||
private final String location;
|
||||
private final List<InputSource> inputs;
|
||||
private final InputLocation importedFrom;
|
||||
|
||||
public InputSource(String modelId, String location) {
|
||||
this(modelId, location, null);
|
||||
}
|
||||
|
||||
public InputSource(String modelId, String location, InputLocation importedFrom) {
|
||||
this.modelId = modelId;
|
||||
this.location = location;
|
||||
this.inputs = null;
|
||||
this.importedFrom = importedFrom;
|
||||
}
|
||||
|
||||
public InputSource(Collection<InputSource> inputs) {
|
||||
this.modelId = null;
|
||||
this.location = null;
|
||||
this.inputs = ImmutableCollections.copy(inputs);
|
||||
this.importedFrom = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -64,6 +71,17 @@ public class InputSource implements Serializable {
|
|||
return this.modelId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parent InputLocation where this InputLocation may have been imported from.
|
||||
* Can return {@code null}.
|
||||
*
|
||||
* @return InputLocation
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public InputLocation getImportedFrom() {
|
||||
return importedFrom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
|
|
|
@ -123,6 +123,10 @@ under the License.
|
|||
<artifactId>hamcrest</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-di</artifactId>
|
||||
|
|
|
@ -32,6 +32,8 @@ import org.apache.maven.api.di.Singleton;
|
|||
import org.apache.maven.api.model.Dependency;
|
||||
import org.apache.maven.api.model.DependencyManagement;
|
||||
import org.apache.maven.api.model.Exclusion;
|
||||
import org.apache.maven.api.model.InputLocation;
|
||||
import org.apache.maven.api.model.InputSource;
|
||||
import org.apache.maven.api.model.Model;
|
||||
import org.apache.maven.api.services.BuilderProblem.Severity;
|
||||
import org.apache.maven.api.services.ModelBuilderRequest;
|
||||
|
@ -81,6 +83,10 @@ public class DefaultDependencyManagementImporter implements DependencyManagement
|
|||
+ toString(present) + ". Add the conflicting managed dependency directly "
|
||||
+ "to the dependencyManagement section of the POM.");
|
||||
}
|
||||
if (present == null && request.isLocationTracking()) {
|
||||
Dependency updatedDependency = updateWithImportedFrom(dependency, source);
|
||||
dependencies.put(key, updatedDependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,4 +150,43 @@ public class DefaultDependencyManagementImporter implements DependencyManagement
|
|||
return Objects.equals(e1.getGroupId(), e2.getGroupId())
|
||||
&& Objects.equals(e1.getArtifactId(), e2.getArtifactId());
|
||||
}
|
||||
|
||||
static Dependency updateWithImportedFrom(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 dependency;
|
||||
}
|
||||
|
||||
InputSource dependencySource = dependencyLocation.getSource();
|
||||
InputSource bomSource = bomLocation.getSource();
|
||||
|
||||
// If the dependency and BOM have the same source, it means we found the root where the dependency is declared.
|
||||
if (dependencySource == null
|
||||
|| bomSource == null
|
||||
|| Objects.equals(dependencySource.getModelId(), bomSource.getModelId())) {
|
||||
return Dependency.newBuilder(dependency, true)
|
||||
.importedFrom(bomLocation)
|
||||
.build();
|
||||
}
|
||||
|
||||
while (dependencySource.getImportedFrom() != null) {
|
||||
InputLocation importedFrom = dependencySource.getImportedFrom();
|
||||
|
||||
// Stop if the BOM is already in the list, no update necessary
|
||||
if (Objects.equals(importedFrom.getSource().getModelId(), bomSource.getModelId())) {
|
||||
return dependency;
|
||||
}
|
||||
|
||||
dependencySource = importedFrom.getSource();
|
||||
}
|
||||
|
||||
// We modify the input location that is used for the whole file.
|
||||
// This is likely correct because the POM hierarchy applies to the whole POM, not just one dependency.
|
||||
return Dependency.newBuilder(dependency, true)
|
||||
.importedFrom(new InputLocation(bomLocation))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.maven.internal.impl.model;
|
||||
|
||||
import org.apache.maven.api.model.Dependency;
|
||||
import org.apache.maven.api.model.DependencyManagement;
|
||||
import org.apache.maven.api.model.InputLocation;
|
||||
import org.apache.maven.api.model.InputSource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class DefaultDependencyManagementImporterTest {
|
||||
@Test
|
||||
void testUpdateWithImportedFrom_dependencyLocationAndBomLocationAreNull_dependencyReturned() {
|
||||
final Dependency dependency = Dependency.newBuilder().build();
|
||||
final DependencyManagement depMgmt = DependencyManagement.newBuilder().build();
|
||||
final Dependency result = DefaultDependencyManagementImporter.updateWithImportedFrom(dependency, depMgmt);
|
||||
|
||||
assertThat(dependency).isEqualTo(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateWithImportedFrom_dependencyManagementAndDependencyHaveSameSource_dependencyImportedFromSameSource() {
|
||||
final InputSource source = new InputSource("SINGLE_SOURCE", "");
|
||||
final Dependency dependency = Dependency.newBuilder()
|
||||
.location("", new InputLocation(1, 1, source))
|
||||
.build();
|
||||
final DependencyManagement bom = DependencyManagement.newBuilder()
|
||||
.location("", new InputLocation(1, 1, source))
|
||||
.build();
|
||||
|
||||
final Dependency result = DefaultDependencyManagementImporter.updateWithImportedFrom(dependency, bom);
|
||||
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getImportedFrom().toString())
|
||||
.isEqualTo(bom.getLocation("").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWithImportedFrom_singleLevel_importedFromSet() {
|
||||
// Arrange
|
||||
final InputSource dependencySource = new InputSource("DEPENDENCY", "DEPENDENCY");
|
||||
final InputSource bomSource = new InputSource("BOM", "BOM");
|
||||
final Dependency dependency = Dependency.newBuilder()
|
||||
.location("", new InputLocation(1, 1, dependencySource))
|
||||
.build();
|
||||
final DependencyManagement bom = DependencyManagement.newBuilder()
|
||||
.location("", new InputLocation(2, 2, bomSource))
|
||||
.build();
|
||||
|
||||
// Act
|
||||
final Dependency result = DefaultDependencyManagementImporter.updateWithImportedFrom(dependency, bom);
|
||||
|
||||
// Assert
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getImportedFrom().toString())
|
||||
.isEqualTo(bom.getLocation("").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWithImportedFrom_multiLevel_importedFromSetChanged() {
|
||||
// Arrange
|
||||
final InputSource bomSource = new InputSource("BOM", "BOM");
|
||||
final InputSource intermediateSource =
|
||||
new InputSource("INTERMEDIATE", "INTERMEDIATE", new InputLocation(bomSource));
|
||||
final InputSource dependencySource =
|
||||
new InputSource("DEPENDENCY", "DEPENDENCY", new InputLocation(intermediateSource));
|
||||
final InputLocation bomLocation = new InputLocation(2, 2, bomSource);
|
||||
final Dependency dependency = Dependency.newBuilder()
|
||||
.location("", new InputLocation(1, 1, dependencySource))
|
||||
.importedFrom(bomLocation)
|
||||
.build();
|
||||
final DependencyManagement bom =
|
||||
DependencyManagement.newBuilder().location("", bomLocation).build();
|
||||
|
||||
// Act
|
||||
final Dependency result = DefaultDependencyManagementImporter.updateWithImportedFrom(dependency, bom);
|
||||
|
||||
// Assert
|
||||
assertThat(result.getImportedFrom().toString())
|
||||
.isEqualTo(bom.getLocation("").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWithImportedFrom_multiLevelAlreadyFoundInDifferentSource_importedFromSetMaintained() {
|
||||
// Arrange
|
||||
final InputSource bomSource = new InputSource("BOM", "BOM");
|
||||
final InputSource intermediateSource =
|
||||
new InputSource("INTERMEDIATE", "INTERMEDIATE", new InputLocation(bomSource));
|
||||
final InputSource dependencySource =
|
||||
new InputSource("DEPENDENCY", "DEPENDENCY", new InputLocation(intermediateSource));
|
||||
final Dependency dependency = Dependency.newBuilder()
|
||||
.location("", new InputLocation(1, 1, dependencySource))
|
||||
.build();
|
||||
final DependencyManagement differentSource = DependencyManagement.newBuilder()
|
||||
.location("", new InputLocation(2, 2, new InputSource("BOM2", "BOM2")))
|
||||
.build();
|
||||
|
||||
// Act
|
||||
final Dependency result =
|
||||
DefaultDependencyManagementImporter.updateWithImportedFrom(dependency, differentSource);
|
||||
|
||||
// Assert
|
||||
assertThat(result.getImportedFrom().toString())
|
||||
.isEqualTo(differentSource.getLocation("").toString());
|
||||
}
|
||||
}
|
|
@ -1722,7 +1722,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
|
||||
importIds.add(importing);
|
||||
|
||||
List<org.apache.maven.api.model.DependencyManagement> importMgmts = null;
|
||||
// Model v4
|
||||
List<org.apache.maven.api.model.DependencyManagement> importMgmts = new ArrayList<>();
|
||||
|
||||
for (Iterator<Dependency> it = depMgmt.getDependencies().iterator(); it.hasNext(); ) {
|
||||
Dependency dependency = it.next();
|
||||
|
@ -1734,13 +1735,19 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
|
||||
it.remove();
|
||||
|
||||
// Model v3
|
||||
DependencyManagement importMgmt = loadDependencyManagement(model, request, problems, dependency, importIds);
|
||||
|
||||
if (importMgmt != null) {
|
||||
if (importMgmts == null) {
|
||||
importMgmts = new ArrayList<>();
|
||||
if (importMgmt == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (request.isLocationTracking()) {
|
||||
// Keep track of why this DependencyManagement was imported.
|
||||
// And map model v3 to model v4 -> importMgmt(v3).getDelegate() returns a v4 object
|
||||
importMgmts.add(
|
||||
org.apache.maven.api.model.DependencyManagement.newBuilder(importMgmt.getDelegate(), true)
|
||||
.build());
|
||||
} else {
|
||||
importMgmts.add(importMgmt.getDelegate());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,11 @@ public final class InputLocation implements java.io.Serializable, Cloneable, Inp
|
|||
*/
|
||||
private InputLocation location;
|
||||
|
||||
/**
|
||||
* Field importedFrom.
|
||||
*/
|
||||
private InputLocation importedFrom;
|
||||
|
||||
// ----------------/
|
||||
// - Constructors -/
|
||||
// ----------------/
|
||||
|
@ -73,6 +78,7 @@ public final class InputLocation implements java.io.Serializable, Cloneable, Inp
|
|||
.collect(Collectors.toMap(
|
||||
e -> e.getKey(),
|
||||
e -> e.getValue() == location ? this : new InputLocation(e.getValue())));
|
||||
this.importedFrom = location.getImportedFrom() != null ? new InputLocation(location.getImportedFrom()) : null;
|
||||
}
|
||||
|
||||
public InputLocation(int lineNumber, int columnNumber) {
|
||||
|
@ -217,6 +223,26 @@ public final class InputLocation implements java.io.Serializable, Cloneable, Inp
|
|||
return this.source;
|
||||
} // -- InputSource getSource()
|
||||
|
||||
/**
|
||||
* Gets the parent InputLocation where this InputLocation may have been imported from.
|
||||
* Can return {@code null}.
|
||||
*
|
||||
* @return InputLocation
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public InputLocation getImportedFrom() {
|
||||
return importedFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the imported from location.
|
||||
*
|
||||
* @param importedFrom
|
||||
*/
|
||||
public void setImportedFrom(InputLocation importedFrom) {
|
||||
this.importedFrom = importedFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method merge.
|
||||
*
|
||||
|
|
|
@ -50,6 +50,14 @@ public class InputSource implements java.io.Serializable, Cloneable {
|
|||
*/
|
||||
private String location;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* The location of the POM from which this POM was
|
||||
* imported from or {@code null} if unknown.
|
||||
*/
|
||||
private InputLocation importedFrom;
|
||||
|
||||
// ----------------/
|
||||
// - Constructors -/
|
||||
// ----------------/
|
||||
|
@ -59,6 +67,7 @@ public class InputSource implements java.io.Serializable, Cloneable {
|
|||
public InputSource(org.apache.maven.api.model.InputSource source) {
|
||||
this.modelId = source.getModelId();
|
||||
this.location = source.getLocation();
|
||||
this.importedFrom = source.getImportedFrom() != null ? new InputLocation(source.getImportedFrom()) : null;
|
||||
}
|
||||
|
||||
// -----------/
|
||||
|
@ -119,6 +128,24 @@ public class InputSource implements java.io.Serializable, Cloneable {
|
|||
this.modelId = modelId;
|
||||
} // -- void setModelId( String )
|
||||
|
||||
/**
|
||||
* Get the location of the POM from which this POM was
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public InputLocation getImportedFrom() {
|
||||
return importedFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the location of the POM from which this POM was imported from.
|
||||
*
|
||||
* @param importedFrom
|
||||
*/
|
||||
public void setImportedFrom(InputLocation importedFrom) {
|
||||
this.importedFrom = importedFrom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getModelId() + " " + getLocation();
|
||||
|
|
6
pom.xml
6
pom.xml
|
@ -161,6 +161,7 @@ under the License.
|
|||
<maven.site.path>ref/4-LATEST</maven.site.path>
|
||||
<project.build.outputTimestamp>2024-05-22T14:07:09Z</project.build.outputTimestamp>
|
||||
<!-- various versions -->
|
||||
<assertjVersion>3.26.0</assertjVersion>
|
||||
<asmVersion>9.7</asmVersion>
|
||||
<byteBuddyVersion>1.14.18</byteBuddyVersion>
|
||||
<cipherVersion>2.0</cipherVersion>
|
||||
|
@ -606,6 +607,11 @@ under the License.
|
|||
<version>${hamcrestVersion}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertjVersion}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.plexus</groupId>
|
||||
<artifactId>plexus-testing</artifactId>
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#set ( $dummy = $imports.add( "java.util.HashMap" ) )
|
||||
#set ( $dummy = $imports.add( "java.util.List" ) )
|
||||
#set ( $dummy = $imports.add( "java.util.Map" ) )
|
||||
#set ( $dummy = $imports.add( "java.util.Set" ) )
|
||||
#set ( $dummy = $imports.add( "java.util.Objects" ) )
|
||||
#set ( $dummy = $imports.add( "java.util.stream.Collectors" ) )
|
||||
#set ( $dummy = $imports.add( "java.util.stream.Stream" ) )
|
||||
|
@ -282,6 +283,20 @@ public class ${class.name}
|
|||
.location(key, location.toApiLocation()).build());
|
||||
}
|
||||
|
||||
public InputLocation getImportedFrom() {
|
||||
${packageModelV4}.InputLocation loc = getDelegate().getImportedFrom();
|
||||
return loc != null ? new InputLocation(loc) : null;
|
||||
}
|
||||
|
||||
public void setImportedFrom(InputLocation location) {
|
||||
update(${packageModelV4}.${class.name}.newBuilder(getDelegate(), true)
|
||||
.importedFrom(location.toApiLocation()).build());
|
||||
}
|
||||
|
||||
public Set<Object> getLocationKeys() {
|
||||
return getDelegate().getLocationKeys();
|
||||
}
|
||||
|
||||
#end
|
||||
protected boolean replace(Object oldDelegate, Object newDelegate) {
|
||||
if (super.replace(oldDelegate, newDelegate)) {
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#set ( $dummy = $imports.add( "java.util.Collections" ) )
|
||||
#set ( $dummy = $imports.add( "java.util.HashMap" ) )
|
||||
#set ( $dummy = $imports.add( "java.util.Map" ) )
|
||||
#set ( $dummy = $imports.add( "java.util.Set" ) )
|
||||
#set ( $dummy = $imports.add( "org.apache.maven.api.annotations.Experimental" ) )
|
||||
#set ( $dummy = $imports.add( "org.apache.maven.api.annotations.Generated" ) )
|
||||
#set ( $dummy = $imports.add( "org.apache.maven.api.annotations.Immutable" ) )
|
||||
|
@ -138,6 +139,8 @@ public class ${class.name}
|
|||
#if ( ! $class.superClass )
|
||||
/** Locations */
|
||||
final Map<Object, InputLocation> locations;
|
||||
/** Location tracking */
|
||||
final InputLocation importedFrom;
|
||||
#end
|
||||
#end
|
||||
|
||||
|
@ -159,7 +162,8 @@ public class ${class.name}
|
|||
$type $field.name${sep}
|
||||
#end
|
||||
#if ( $locationTracking )
|
||||
Map<Object, InputLocation> locations
|
||||
Map<Object, InputLocation> locations,
|
||||
InputLocation importedFrom
|
||||
#end
|
||||
) {
|
||||
#if ( $class.superClass )
|
||||
|
@ -169,7 +173,8 @@ public class ${class.name}
|
|||
${field.name}${sep}
|
||||
#end
|
||||
#if ( $locationTracking )
|
||||
locations
|
||||
locations,
|
||||
importedFrom
|
||||
#end
|
||||
);
|
||||
#end
|
||||
|
@ -187,6 +192,7 @@ public class ${class.name}
|
|||
#if ( $locationTracking )
|
||||
#if ( ! $class.superClass )
|
||||
this.locations = ImmutableCollections.copy(locations);
|
||||
this.importedFrom = importedFrom;
|
||||
#end
|
||||
#end
|
||||
}
|
||||
|
@ -252,6 +258,21 @@ public class ${class.name}
|
|||
return locations != null ? locations.get(key) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the keys of the locations of the input source.
|
||||
*/
|
||||
public Set<Object> getLocationKeys() {
|
||||
return locations != null ? locations.keySet() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the input location that caused this model to be read.
|
||||
*/
|
||||
public InputLocation getImportedFrom()
|
||||
{
|
||||
return importedFrom;
|
||||
}
|
||||
|
||||
#end
|
||||
/**
|
||||
* Creates a new builder with this object as the basis.
|
||||
|
@ -382,6 +403,7 @@ public class ${class.name}
|
|||
#end
|
||||
#if ( ! $class.superClass && $locationTracking )
|
||||
Map<Object, InputLocation> locations;
|
||||
InputLocation importedFrom;
|
||||
#end
|
||||
|
||||
Builder(boolean withDefaults) {
|
||||
|
@ -416,6 +438,7 @@ public class ${class.name}
|
|||
#end
|
||||
#if ( $locationTracking )
|
||||
this.locations = base.locations;
|
||||
this.importedFrom = base.importedFrom;
|
||||
#end
|
||||
} else {
|
||||
this.base = base;
|
||||
|
@ -461,6 +484,12 @@ public class ${class.name}
|
|||
return this;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Builder importedFrom(InputLocation importedFrom) {
|
||||
this.importedFrom = importedFrom;
|
||||
return this;
|
||||
}
|
||||
|
||||
#end
|
||||
@Nonnull
|
||||
public ${class.name} build() {
|
||||
|
@ -494,7 +523,8 @@ public class ${class.name}
|
|||
#end
|
||||
#end
|
||||
#if ( $locationTracking )
|
||||
locations
|
||||
locations,
|
||||
importedFrom
|
||||
#end
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue