Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@ public interface XmlReaderRequest {

boolean isAddDefaultEntities();

/**
* Indicates whether location information (line/column tracking) should be
* recorded during parsing. Defaults to {@code true}. Setting this to
* {@code false} for imported dependency management POMs avoids allocating
* location maps that are never read, significantly reducing memory churn
* in large reactors.
*
* @return {@code true} if location information should be tracked
* @since 4.0.0
*/
default boolean isAddLocationInformation() {
return true;
}

interface Transformer {
/**
* Interpolate the value read from the xml document
Expand Down Expand Up @@ -95,6 +109,7 @@ class XmlReaderRequestBuilder {
String modelId;
String location;
boolean addDefaultEntities = true;
boolean addLocationInformation = true;

public XmlReaderRequestBuilder path(Path path) {
this.path = path;
Expand Down Expand Up @@ -146,6 +161,11 @@ public XmlReaderRequestBuilder addDefaultEntities(boolean addDefaultEntities) {
return this;
}

public XmlReaderRequestBuilder addLocationInformation(boolean addLocationInformation) {
this.addLocationInformation = addLocationInformation;
return this;
}

public XmlReaderRequest build() {
return new DefaultXmlReaderRequest(
path,
Expand All @@ -157,7 +177,8 @@ public XmlReaderRequest build() {
strict,
modelId,
location,
addDefaultEntities);
addDefaultEntities,
addLocationInformation);
}

private static class DefaultXmlReaderRequest implements XmlReaderRequest {
Expand All @@ -171,6 +192,7 @@ private static class DefaultXmlReaderRequest implements XmlReaderRequest {
final String modelId;
final String location;
final boolean addDefaultEntities;
final boolean addLocationInformation;

@SuppressWarnings("checkstyle:ParameterNumber")
DefaultXmlReaderRequest(
Expand All @@ -183,7 +205,8 @@ private static class DefaultXmlReaderRequest implements XmlReaderRequest {
boolean strict,
String modelId,
String location,
boolean addDefaultEntities) {
boolean addDefaultEntities,
boolean addLocationInformation) {
this.path = path;
this.rootDirectory = rootDirectory;
this.url = url;
Expand All @@ -194,6 +217,7 @@ private static class DefaultXmlReaderRequest implements XmlReaderRequest {
this.modelId = modelId;
this.location = location;
this.addDefaultEntities = addDefaultEntities;
this.addLocationInformation = addLocationInformation;
}

@Override
Expand Down Expand Up @@ -245,6 +269,11 @@ public String getLocation() {
public boolean isAddDefaultEntities() {
return addDefaultEntities;
}

@Override
public boolean isAddLocationInformation() {
return addLocationInformation;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,21 @@ Model importManagement(
List<? extends DependencyManagement> sources,
ModelBuilderRequest request,
ModelProblemCollector problems);

/**
* Builder-accepting variant of {@link #importManagement}.
*
* @since 4.0.0
*/
default void importManagement(
Model.Builder builder,
List<? extends DependencyManagement> sources,
ModelBuilderRequest request,
ModelProblemCollector problems) {
Model built = builder.build();
Model result = importManagement(built, sources, request, problems);
if (result != built) {
builder.reset(result);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,24 @@ public interface DependencyManagementInjector {
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
*/
Model injectManagement(Model model, ModelBuilderRequest request, ModelProblemCollector problems);

/**
* Builder-accepting variant that operates on a {@link Model.Builder} directly,
* avoiding an intermediate {@code Model.build()} between pipeline stages.
* <p>
* The default implementation bridges to {@link #injectManagement(Model, ModelBuilderRequest, ModelProblemCollector)}
* by building the model, processing it, and resetting the builder to the result.
*
* @param builder The model builder to modify in place, must not be {@code null}.
* @param request The model building request, must not be {@code null}.
* @param problems The container used to collect problems, must not be {@code null}.
* @since 4.0.0
*/
default void injectManagement(Model.Builder builder, ModelBuilderRequest request, ModelProblemCollector problems) {
Model built = builder.build();
Model result = injectManagement(built, request, problems);
if (result != built) {
builder.reset(result);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,18 @@ public interface InheritanceAssembler {
*/
Model assembleModelInheritance(
Model child, Model parent, ModelBuilderRequest request, ModelProblemCollector problems);

/**
* Builder-accepting variant that merges parent values into the child builder directly.
*
* @since 4.0.0
*/
default void assembleModelInheritance(
Model.Builder childBuilder, Model parent, ModelBuilderRequest request, ModelProblemCollector problems) {
Model built = childBuilder.build();
Model result = assembleModelInheritance(built, parent, request, problems);
if (result != built) {
childBuilder.reset(result);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,21 @@ Model interpolateModel(
@Nullable Path projectDir,
@Nonnull ModelBuilderRequest request,
@Nonnull ModelProblemCollector problems);

/**
* Builder-accepting variant of {@link #interpolateModel}.
*
* @since 4.0.0
*/
default void interpolateModel(
@Nonnull Model.Builder builder,
@Nullable Path projectDir,
@Nonnull ModelBuilderRequest request,
@Nonnull ModelProblemCollector problems) {
Model built = builder.build();
Model result = interpolateModel(built, projectDir, request, problems);
if (result != built) {
builder.reset(result);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,31 @@ public interface ModelNormalizer {
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
*/
Model injectDefaultValues(Model model, ModelBuilderRequest request, ModelProblemCollector problems);

/**
* Builder-accepting variant of {@link #mergeDuplicates}.
*
* @since 4.0.0
*/
default void mergeDuplicates(Model.Builder builder, ModelBuilderRequest request, ModelProblemCollector problems) {
Model built = builder.build();
Model result = mergeDuplicates(built, request, problems);
if (result != built) {
builder.reset(result);
}
}

/**
* Builder-accepting variant of {@link #injectDefaultValues}.
*
* @since 4.0.0
*/
default void injectDefaultValues(
Model.Builder builder, ModelBuilderRequest request, ModelProblemCollector problems) {
Model built = builder.build();
Model result = injectDefaultValues(built, request, problems);
if (result != built) {
builder.reset(result);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,17 @@ public interface ModelPathTranslator {
* @since 4.0.0
*/
Model alignToBaseDirectory(Model model, Path basedir, ModelBuilderRequest request);

/**
* Builder-accepting variant of {@link #alignToBaseDirectory}.
*
* @since 4.0.0
*/
default void alignToBaseDirectory(Model.Builder builder, Path basedir, ModelBuilderRequest request) {
Model built = builder.build();
Model result = alignToBaseDirectory(built, basedir, request);
if (result != built) {
builder.reset(result);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,17 @@ public interface ModelUrlNormalizer {
* @param request The model building request that holds further settings, must not be {@code null}.
*/
Model normalize(Model model, ModelBuilderRequest request);

/**
* Builder-accepting variant of {@link #normalize}.
*
* @since 4.0.0
*/
default void normalize(Model.Builder builder, ModelBuilderRequest request) {
Model built = builder.build();
Model result = normalize(built, request);
if (result != built) {
builder.reset(result);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,18 @@ public interface PluginConfigurationExpander {
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
*/
Model expandPluginConfiguration(Model model, ModelBuilderRequest request, ModelProblemCollector problems);

/**
* Builder-accepting variant of {@link #expandPluginConfiguration}.
*
* @since 4.0.0
*/
default void expandPluginConfiguration(
Model.Builder builder, ModelBuilderRequest request, ModelProblemCollector problems) {
Model built = builder.build();
Model result = expandPluginConfiguration(built, request, problems);
if (result != built) {
builder.reset(result);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,17 @@ public interface PluginManagementInjector {
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
*/
Model injectManagement(Model model, ModelBuilderRequest request, ModelProblemCollector problems);

/**
* Builder-accepting variant of {@link #injectManagement}.
*
* @since 4.0.0
*/
default void injectManagement(Model.Builder builder, ModelBuilderRequest request, ModelProblemCollector problems) {
Model built = builder.build();
Model result = injectManagement(built, request, problems);
if (result != built) {
builder.reset(result);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,21 @@ default Model injectProfile(
*/
Model injectProfiles(
Model model, List<Profile> profiles, ModelBuilderRequest request, ModelProblemCollector problems);

/**
* Builder-accepting variant that injects profile values into the model builder directly.
*
* @since 4.0.0
*/
default void injectProfiles(
Model.Builder builder,
List<Profile> profiles,
ModelBuilderRequest request,
ModelProblemCollector problems) {
Model built = builder.build();
Model result = injectProfiles(built, profiles, request, problems);
if (result != built) {
builder.reset(result);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ class FileToRawModelMergerTest {
void testOverriddenMergeMethods() {
List<String> methodNames = Stream.of(MavenMerger.class.getDeclaredMethods())
.filter(m -> m.getName().startsWith("merge"))
// Exclude *ToBuilder variants and void methods whose first parameter
// is a Builder — only the object-returning merge methods need overriding
.filter(m -> !m.getName().endsWith("ToBuilder"))
.filter(m -> !m.getParameterTypes()[0].getSimpleName().equals("Builder"))
.filter(m -> {
String baseName = m.getName().substring(5 /* merge */);
String entity = baseName.substring(baseName.indexOf('_') + 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,7 @@ private List<MavenProject> trimProjectsToRequest(
if (request.getPom() != null) {
result = getProjectsInRequestScope(request, activeProjects);

List<MavenProject> sortedProjects = graph.getSortedProjects();
result.sort(comparing(sortedProjects::indexOf));
result.sort(comparing(buildProjectIndexMap(graph.getSortedProjects())::get));

result = includeAlsoMakeTransitively(result, request, graph);
}
Expand Down Expand Up @@ -189,8 +188,7 @@ private List<MavenProject> trimSelectedProjects(
result = includeAlsoMakeTransitively(result, request, graph);

// Order the new list in the original order
List<MavenProject> sortedProjects = graph.getSortedProjects();
result.sort(comparing(sortedProjects::indexOf));
result.sort(comparing(buildProjectIndexMap(graph.getSortedProjects())::get));
}
}

Expand Down Expand Up @@ -290,13 +288,24 @@ private List<MavenProject> includeAlsoMakeTransitively(
result = new ArrayList<>(projectsSet);

// Order the new list in the original order
List<MavenProject> sortedProjects = graph.getSortedProjects();
result.sort(comparing(sortedProjects::indexOf));
result.sort(comparing(buildProjectIndexMap(graph.getSortedProjects())::get));
}

return result;
}

/**
* Builds a Map from MavenProject to its index in the sorted list, enabling O(1) index lookups
* for sorting instead of O(n) ArrayList.indexOf() scans that cause O(n² log n) sort performance.
*/
private static Map<MavenProject, Integer> buildProjectIndexMap(List<MavenProject> sortedProjects) {
Map<MavenProject, Integer> indexMap = new HashMap<>(sortedProjects.size() * 2);
for (int i = 0; i < sortedProjects.size(); i++) {
indexMap.put(sortedProjects.get(i), i);
}
return indexMap;
}

private void enrichRequestFromResumptionData(List<MavenProject> projects, MavenExecutionRequest request) {
if (request.isResume()) {
projects.stream()
Expand Down
Loading
Loading