[MNG-8494] Restore Maven 3 compatibility (#2031)

This commit is contained in:
Guillaume Nodet 2025-01-10 08:09:12 +01:00 committed by GitHub
parent 71c662fa4c
commit 5cef91e402
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
152 changed files with 8102 additions and 6488 deletions

View File

@ -1315,6 +1315,15 @@
]]>
</code>
</codeSegment>
<codeSegment>
<version>4.0.0/4.0.99</version>
<code>
public void clearManagementKey() {
managementKey = null;
}
</code>
</codeSegment>
</codeSegments>
</class>
<class>

View File

@ -331,6 +331,10 @@
}
return profileMap;
}
public void setModelEncoding(String modelEncoding) {
update(getDelegate().with().modelEncoding(modelEncoding).build());
}
]]>
</code>
</codeSegment>

View File

@ -102,6 +102,16 @@
</association>
</field>
</fields>
<codeSegments>
<codeSegment>
<version>1.0.0/1.1.0</version>
<code>
public void setModelEncoding(String modelEncoding) {
update(getDelegate().with().modelEncoding(modelEncoding).build());
}
</code>
</codeSegment>
</codeSegments>
</class>
<class>
<name>ToolchainModel</name>

View File

@ -1425,10 +1425,9 @@ public class MavenCli {
}
if (modelProcessor != null) {
return modelProcessor.locateExistingPom(current);
} else {
return current.isFile() ? current : null;
current = modelProcessor.locatePom(current);
}
return current.isFile() ? current : null;
}
// Visible for testing
@ -1742,8 +1741,7 @@ public class MavenCli {
//
protected TransferListener getConsoleTransferListener(boolean printResourceNames) {
return new SimplexTransferListener(
new ConsoleMavenTransferListener(messageBuilderFactory, System.out, printResourceNames));
return new SimplexTransferListener(new ConsoleMavenTransferListener(System.out, printResourceNames));
}
protected TransferListener getBatchTransferListener() {

View File

@ -19,10 +19,11 @@
package org.apache.maven.cli.transfer;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import org.apache.maven.api.services.MessageBuilder;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.apache.maven.jline.MessageUtils;
import org.eclipse.aether.transfer.AbstractTransferListener;
import org.eclipse.aether.transfer.TransferCancelledException;
import org.eclipse.aether.transfer.TransferEvent;
@ -33,31 +34,177 @@ import org.eclipse.aether.transfer.TransferResource;
*/
@Deprecated
public abstract class AbstractMavenTransferListener extends AbstractTransferListener {
public static final String STYLE = ".transfer:-faint";
protected final MessageBuilderFactory messageBuilderFactory;
protected final PrintWriter out;
private static final String ESC = "\u001B";
private static final String ANSI_DARK_SET = ESC + "[90m";
private static final String ANSI_DARK_RESET = ESC + "[0m";
protected AbstractMavenTransferListener(MessageBuilderFactory messageBuilderFactory, PrintStream out) {
this(messageBuilderFactory, new PrintWriter(out));
// CHECKSTYLE_OFF: LineLength
/**
* Formats file size with the associated <a href="https://en.wikipedia.org/wiki/Metric_prefix">SI</a> prefix
* (GB, MB, kB) and using the patterns <code>#0.0</code> for numbers between 1 and 10
* and <code>###0</code> for numbers between 10 and 1000+ by default.
*
* @see <a href="https://en.wikipedia.org/wiki/Metric_prefix">https://en.wikipedia.org/wiki/Metric_prefix</a>
* @see <a href="https://en.wikipedia.org/wiki/Binary_prefix">https://en.wikipedia.org/wiki/Binary_prefix</a>
* @see <a
* href="https://en.wikipedia.org/wiki/Octet_%28computing%29">https://en.wikipedia.org/wiki/Octet_(computing)</a>
*/
// CHECKSTYLE_ON: LineLength
// TODO Move me to Maven Shared Utils
static class FileSizeFormat {
enum ScaleUnit {
BYTE {
@Override
public long bytes() {
return 1L;
}
@Override
public String symbol() {
return "B";
}
},
KILOBYTE {
@Override
public long bytes() {
return 1000L;
}
@Override
public String symbol() {
return "kB";
}
},
MEGABYTE {
@Override
public long bytes() {
return KILOBYTE.bytes() * KILOBYTE.bytes();
}
@Override
public String symbol() {
return "MB";
}
},
GIGABYTE {
@Override
public long bytes() {
return MEGABYTE.bytes() * KILOBYTE.bytes();
}
;
@Override
public String symbol() {
return "GB";
}
};
public abstract long bytes();
public abstract String symbol();
public static ScaleUnit getScaleUnit(long size) {
if (size < 0L) {
throw new IllegalArgumentException("file size cannot be negative: " + size);
}
if (size >= GIGABYTE.bytes()) {
return GIGABYTE;
} else if (size >= MEGABYTE.bytes()) {
return MEGABYTE;
} else if (size >= KILOBYTE.bytes()) {
return KILOBYTE;
} else {
return BYTE;
}
}
}
private DecimalFormat smallFormat;
private DecimalFormat largeFormat;
FileSizeFormat(Locale locale) {
smallFormat = new DecimalFormat("#0.0", new DecimalFormatSymbols(locale));
largeFormat = new DecimalFormat("###0", new DecimalFormatSymbols(locale));
}
public String format(long size) {
return format(size, null);
}
public String format(long size, ScaleUnit unit) {
return format(size, unit, false);
}
public String format(long size, ScaleUnit unit, boolean omitSymbol) {
if (size < 0L) {
throw new IllegalArgumentException("file size cannot be negative: " + size);
}
if (unit == null) {
unit = ScaleUnit.getScaleUnit(size);
}
double scaledSize = (double) size / unit.bytes();
String scaledSymbol = " " + unit.symbol();
if (omitSymbol) {
scaledSymbol = "";
}
if (unit == ScaleUnit.BYTE) {
return largeFormat.format(size) + scaledSymbol;
}
if (scaledSize < 0.05 || scaledSize >= 10.0) {
return largeFormat.format(scaledSize) + scaledSymbol;
} else {
return smallFormat.format(scaledSize) + scaledSymbol;
}
}
public String formatProgress(long progressedSize, long size) {
if (progressedSize < 0L) {
throw new IllegalArgumentException("progressed file size cannot be negative: " + progressedSize);
}
if (size >= 0L && progressedSize > size) {
throw new IllegalArgumentException(
"progressed file size cannot be greater than size: " + progressedSize + " > " + size);
}
if (size >= 0L && progressedSize != size) {
ScaleUnit unit = ScaleUnit.getScaleUnit(size);
String formattedProgressedSize = format(progressedSize, unit, true);
String formattedSize = format(size, unit);
return formattedProgressedSize + "/" + formattedSize;
} else {
return format(progressedSize);
}
}
}
protected AbstractMavenTransferListener(MessageBuilderFactory messageBuilderFactory, PrintWriter out) {
this.messageBuilderFactory = messageBuilderFactory;
protected PrintStream out;
protected AbstractMavenTransferListener(PrintStream out) {
this.out = out;
}
@Override
public void transferInitiated(TransferEvent event) {
String darkOn = MessageUtils.isColorEnabled() ? ANSI_DARK_SET : "";
String darkOff = MessageUtils.isColorEnabled() ? ANSI_DARK_RESET : "";
String action = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading";
String direction = event.getRequestType() == TransferEvent.RequestType.PUT ? "to" : "from";
TransferResource resource = event.getResource();
MessageBuilder message = messageBuilderFactory.builder();
message.style(STYLE).append(action).append(' ').append(direction).append(' ');
message.resetStyle().append(resource.getRepositoryId());
message.style(STYLE).append(": ").append(resource.getRepositoryUrl());
message.resetStyle().append(resource.getResourceName());
StringBuilder message = new StringBuilder();
message.append(darkOn).append(action).append(' ').append(direction).append(' ');
message.append(darkOff).append(resource.getRepositoryId());
message.append(darkOn).append(": ").append(resource.getRepositoryUrl());
message.append(darkOff).append(resource.getResourceName());
out.println(message.toString());
}
@ -72,29 +219,30 @@ public abstract class AbstractMavenTransferListener extends AbstractTransferList
@Override
public void transferSucceeded(TransferEvent event) {
String darkOn = MessageUtils.isColorEnabled() ? ANSI_DARK_SET : "";
String darkOff = MessageUtils.isColorEnabled() ? ANSI_DARK_RESET : "";
String action = (event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded");
String direction = event.getRequestType() == TransferEvent.RequestType.PUT ? "to" : "from";
TransferResource resource = event.getResource();
long contentLength = event.getTransferredBytes();
FileSizeFormat format = new FileSizeFormat();
FileSizeFormat format = new FileSizeFormat(Locale.ENGLISH);
MessageBuilder message = messageBuilderFactory.builder();
message.append(action).style(STYLE).append(' ').append(direction).append(' ');
message.resetStyle().append(resource.getRepositoryId());
message.style(STYLE).append(": ").append(resource.getRepositoryUrl());
message.resetStyle().append(resource.getResourceName());
message.style(STYLE).append(" (").append(format.format(contentLength));
StringBuilder message = new StringBuilder();
message.append(action).append(darkOn).append(' ').append(direction).append(' ');
message.append(darkOff).append(resource.getRepositoryId());
message.append(darkOn).append(": ").append(resource.getRepositoryUrl());
message.append(darkOff).append(resource.getResourceName());
message.append(darkOn).append(" (").append(format.format(contentLength));
long duration = System.currentTimeMillis() - resource.getTransferStartTime();
if (duration > 0L) {
double bytesPerSecond = contentLength / (duration / 1000.0);
message.append(" at ");
format.format(message, (long) bytesPerSecond);
message.append("/s");
message.append(" at ").append(format.format((long) bytesPerSecond)).append("/s");
}
message.append(')').resetStyle();
message.append(')').append(darkOff);
out.println(message.toString());
}
}

View File

@ -0,0 +1,31 @@
/*
* 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.cli.transfer;
import java.io.PrintStream;
/**
* BatchModeMavenTransferListener
*/
@Deprecated
public class BatchModeMavenTransferListener extends AbstractMavenTransferListener {
public BatchModeMavenTransferListener(PrintStream out) {
super(out);
}
}

View File

@ -19,12 +19,12 @@
package org.apache.maven.cli.transfer;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.eclipse.aether.transfer.TransferCancelledException;
import org.eclipse.aether.transfer.TransferEvent;
import org.eclipse.aether.transfer.TransferResource;
@ -37,21 +37,14 @@ import org.eclipse.aether.transfer.TransferResource;
@Deprecated
public class ConsoleMavenTransferListener extends AbstractMavenTransferListener {
private final Map<TransferResourceIdentifier, TransferResourceAndSize> transfers = new LinkedHashMap<>();
private final FileSizeFormat format = new FileSizeFormat(); // use in a synchronized fashion
private final StringBuilder buffer = new StringBuilder(128); // use in a synchronized fashion
private final Map<TransferResourceIdentifier, TransferResourceAndSize> transfers =
Collections.synchronizedMap(new LinkedHashMap<TransferResourceIdentifier, TransferResourceAndSize>());
private final boolean printResourceNames;
private int lastLength;
public ConsoleMavenTransferListener(
MessageBuilderFactory messageBuilderFactory, PrintStream out, boolean printResourceNames) {
this(messageBuilderFactory, new PrintWriter(out), printResourceNames);
}
public ConsoleMavenTransferListener(
MessageBuilderFactory messageBuilderFactory, PrintWriter out, boolean printResourceNames) {
super(messageBuilderFactory, out);
public ConsoleMavenTransferListener(PrintStream out, boolean printResourceNames) {
super(out);
this.printResourceNames = printResourceNames;
}
@ -76,36 +69,19 @@ public class ConsoleMavenTransferListener extends AbstractMavenTransferListener
new TransferResourceIdentifier(resource),
new TransferResourceAndSize(resource, event.getTransferredBytes()));
StringBuilder buffer = new StringBuilder(128);
buffer.append("Progress (").append(transfers.size()).append("): ");
Iterator<TransferResourceAndSize> entries = transfers.values().iterator();
while (entries.hasNext()) {
TransferResourceAndSize entry = entries.next();
// just in case, make sure 0 <= complete <= total
long complete = Math.max(0, entry.transferredBytes);
long total = Math.max(complete, entry.resource.getContentLength());
String resourceName = entry.resource.getResourceName();
if (printResourceNames) {
int idx = resourceName.lastIndexOf('/');
if (idx < 0) {
buffer.append(resourceName);
} else {
buffer.append(resourceName, idx + 1, resourceName.length());
synchronized (transfers) {
Iterator<TransferResourceAndSize> entries = transfers.values().iterator();
while (entries.hasNext()) {
TransferResourceAndSize entry = entries.next();
long total = entry.resource.getContentLength();
Long complete = entry.transferredBytes;
buffer.append(getStatus(entry.resource.getResourceName(), complete, total));
if (entries.hasNext()) {
buffer.append(" | ");
}
buffer.append(" (");
}
format.formatProgress(buffer, complete, total);
if (printResourceNames) {
buffer.append(")");
}
if (entries.hasNext()) {
buffer.append(" | ");
}
}
@ -115,7 +91,35 @@ public class ConsoleMavenTransferListener extends AbstractMavenTransferListener
buffer.append('\r');
out.print(buffer);
out.flush();
buffer.setLength(0);
}
private String getStatus(String resourceName, long complete, long total) {
FileSizeFormat format = new FileSizeFormat(Locale.ENGLISH);
StringBuilder status = new StringBuilder();
if (printResourceNames) {
status.append(resourceName(resourceName));
status.append(" (");
}
status.append(format.formatProgress(complete, total));
if (printResourceNames) {
status.append(")");
}
return status.toString();
}
private String resourceName(String resourceName) {
if (resourceName == null || resourceName.trim().isEmpty()) {
return "";
}
final int pos = resourceName.lastIndexOf("/");
if (pos == -1 || pos == resourceName.length() - 1) {
return "";
}
return resourceName.substring(pos + 1);
}
private void pad(StringBuilder buffer, int spaces) {
@ -145,14 +149,23 @@ public class ConsoleMavenTransferListener extends AbstractMavenTransferListener
private void overridePreviousTransfer(TransferEvent event) {
if (lastLength > 0) {
StringBuilder buffer = new StringBuilder(128);
pad(buffer, lastLength);
buffer.append('\r');
out.print(buffer);
out.flush();
lastLength = 0;
buffer.setLength(0);
}
}
private record TransferResourceAndSize(TransferResource resource, long transferredBytes) {}
private final class TransferResourceAndSize {
private final TransferResource resource;
private final long transferredBytes;
private TransferResourceAndSize(TransferResource resource, long transferredBytes) {
this.resource = resource;
this.transferredBytes = transferredBytes;
}
}
}

View File

@ -1,140 +0,0 @@
/*
* 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.cli.transfer;
import java.io.File;
import java.io.PrintWriter;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.maven.jline.JLineMessageBuilderFactory;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.transfer.TransferCancelledException;
import org.eclipse.aether.transfer.TransferEvent;
import org.eclipse.aether.transfer.TransferListener;
import org.eclipse.aether.transfer.TransferResource;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
@Deprecated
class ConsoleMavenTransferListenerTest {
private CountDownLatch startLatch;
private CountDownLatch endLatch;
@Test
void testTransferProgressedWithPrintResourceNames() throws Exception {
int size = 1000;
ExecutorService service = Executors.newFixedThreadPool(size * 2);
startLatch = new CountDownLatch(size);
endLatch = new CountDownLatch(size);
Map<String, String> output = new ConcurrentHashMap<String, String>();
TransferListener listener = new SimplexTransferListener(new ConsoleMavenTransferListener(
new JLineMessageBuilderFactory(),
new PrintWriter(System.out) {
@Override
public void print(Object o) {
String string = o.toString();
int i = string.length() - 1;
while (i >= 0) {
char c = string.charAt(i);
if (c == '\n' || c == '\r' || c == ' ') i--;
else break;
}
string = string.substring(0, i + 1).trim();
output.put(string, string);
System.out.print(o);
}
},
true));
TransferResource resource =
new TransferResource(null, null, "http://maven.org/test/test-resource", new File(""), null);
resource.setContentLength(size - 1);
DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(h -> false); // no close handle
// warm up
test(listener, session, resource, 0);
for (int i = 1; i < size; i++) {
final int bytes = i;
service.execute(() -> {
test(listener, session, resource, bytes);
});
}
// start all threads at once
try {
startLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
// wait for all thread to end
try {
endLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
// despite all are back, we need to make sure all the events are processed (are async)
// this one should block until all processed
listener.transferSucceeded(new TransferEvent.Builder(session, resource)
.setType(TransferEvent.EventType.SUCCEEDED)
.build());
StringBuilder message = new StringBuilder("Messages [");
boolean test = true;
for (int i = 0; i < 999; i++) {
boolean ok = output.containsKey("Progress (1): test-resource (" + i + "/999 B)");
if (!ok) {
System.out.println("false : " + i);
message.append(i + ",");
}
test = test & ok;
}
assertTrue(test, message + "] are missing in " + output);
}
private void test(
TransferListener listener,
DefaultRepositorySystemSession session,
TransferResource resource,
final int bytes) {
TransferEvent event = new TransferEvent.Builder(session, resource)
.setType(TransferEvent.EventType.PROGRESSED)
.setTransferredBytes(bytes)
.build();
startLatch.countDown();
try {
listener.transferProgressed(event);
} catch (TransferCancelledException e) {
}
endLatch.countDown();
}
}

View File

@ -67,6 +67,10 @@ under the License.
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-builder-support</artifactId>
@ -93,6 +97,10 @@ under the License.
<artifactId>org.eclipse.sisu.inject</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
</dependency>
<!-- Testing -->
<dependency>
@ -115,11 +123,6 @@ under the License.
<artifactId>xmlunit-matchers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -141,52 +144,50 @@ under the License.
</oldVersion>
<parameter>
<excludes>
<exclude>org.apache.maven.model.building.DefaultModelBuilder#DefaultModelBuilder():CONSTRUCTOR_REMOVED</exclude>
<exclude>org.apache.maven.model.building.DefaultModelProcessor#setModelLocator(org.apache.maven.model.locator.ModelLocator):METHOD_REMOVED</exclude>
<exclude>org.apache.maven.model.building.DefaultModelProcessor#setModelReader(org.apache.maven.model.io.ModelReader):METHOD_REMOVED</exclude>
<exclude>org.apache.maven.model.building.DefaultModelProcessor#DefaultModelProcessor():CONSTRUCTOR_REMOVED</exclude>
<exclude>org.apache.maven.model.building.ModelCache#get(java.lang.String,java.lang.String,java.lang.String,java.lang.String):METHOD_REMOVED</exclude>
<exclude>org.apache.maven.model.building.ModelCache#put(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.Object):METHOD_REMOVED</exclude>
<exclude>org.apache.maven.model.composition.DependencyManagementImporter#importManagement(org.apache.maven.model.Model,java.util.List,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_REMOVED</exclude>
<exclude>org.apache.maven.model.composition.DefaultDependencyManagementImporter#importManagement(org.apache.maven.model.Model,java.util.List,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_REMOVED</exclude>
<exclude>org.apache.maven.model.inheritance.DefaultInheritanceAssembler</exclude>
<exclude>org.apache.maven.model.inheritance.InheritanceAssembler#assembleModelInheritance(org.apache.maven.model.Model,org.apache.maven.model.Model,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_REMOVED</exclude>
<exclude>org.apache.maven.model.interpolation.AbstractStringBasedModelInterpolator</exclude>
<exclude>org.apache.maven.model.interpolation.StringSearchModelInterpolator</exclude>
<exclude>org.apache.maven.model.interpolation.StringVisitorModelInterpolator</exclude>
<exclude>org.apache.maven.model.io.DefaultModelReader#DefaultModelReader():CONSTRUCTOR_REMOVED</exclude>
<exclude>org.apache.maven.model.locator.ModelLocator#locateExistingPom(java.io.File):METHOD_NEW_DEFAULT</exclude>
<exclude>org.apache.maven.model.management.DefaultDependencyManagementInjector$ManagementModelMerger</exclude>
<exclude>org.apache.maven.model.management.DefaultPluginManagementInjector$ManagementModelMerger</exclude>
<exclude>org.apache.maven.model.merge.MavenModelMerger</exclude>
<exclude>org.apache.maven.model.normalization.DefaultModelNormalizer$DuplicateMerger#mergePlugin(org.apache.maven.model.Plugin,org.apache.maven.model.Plugin):METHOD_REMOVED</exclude>
<exclude>org.apache.maven.model.normalization.DefaultModelNormalizer$DuplicateMerger:METHOD_REMOVED_IN_SUPERCLASS</exclude>
<exclude>org.apache.maven.model.path.DefaultModelPathTranslator#setPathTranslator(org.apache.maven.model.path.PathTranslator):METHOD_REMOVED</exclude>
<exclude>org.apache.maven.model.path.DefaultModelPathTranslator#DefaultModelPathTranslator():CONSTRUCTOR_REMOVED</exclude>
<exclude>org.apache.maven.model.path.DefaultModelUrlNormalizer#setUrlNormalizer(org.apache.maven.model.path.UrlNormalizer):METHOD_REMOVED</exclude>
<exclude>org.apache.maven.model.path.DefaultModelUrlNormalizer#DefaultModelUrlNormalizer():CONSTRUCTOR_REMOVED</exclude>
<exclude>org.apache.maven.model.path.ProfileActivationFilePathInterpolator#setPathTranslator(org.apache.maven.model.path.PathTranslator):METHOD_REMOVED</exclude>
<exclude>org.apache.maven.model.path.ProfileActivationFilePathInterpolator#ProfileActivationFilePathInterpolator():CONSTRUCTOR_REMOVED</exclude>
<exclude>org.apache.maven.model.profile.activation.FileProfileActivator#setProfileActivationFilePathInterpolator(org.apache.maven.model.path.ProfileActivationFilePathInterpolator):METHOD_REMOVED</exclude>
<exclude>org.apache.maven.model.profile.activation.FileProfileActivator#FileProfileActivator():CONSTRUCTOR_REMOVED</exclude>
<exclude>org.apache.maven.model.profile.DefaultProfileInjector</exclude>
<exclude>org.apache.maven.model.profile.ProfileInjector#injectProfile(org.apache.maven.api.model.Model,org.apache.maven.api.model.Profile,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_NEW_DEFAULT</exclude>
<exclude>org.apache.maven.model.profile.ProfileInjector#injectProfiles(org.apache.maven.api.model.Model,java.util.List,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_NEW_DEFAULT</exclude>
<exclude>org.apache.maven.model.profile.ProfileSelector#getActiveProfilesV4(java.util.Collection,org.apache.maven.model.profile.ProfileActivationContext,org.apache.maven.model.building.ModelProblemCollector):METHOD_NEW_DEFAULT</exclude>
<exclude>org.apache.maven.model.resolution.InvalidRepositoryException#getRepository():METHOD_RETURN_TYPE_CHANGED</exclude>
<exclude>org.apache.maven.model.resolution.InvalidRepositoryException#InvalidRepositoryException(java.lang.String,org.apache.maven.model.Repository,java.lang.Throwable):CONSTRUCTOR_REMOVED</exclude>
<exclude>org.apache.maven.model.resolution.InvalidRepositoryException#InvalidRepositoryException(java.lang.String,org.apache.maven.model.Repository):CONSTRUCTOR_REMOVED</exclude>
<exclude>org.apache.maven.model.resolution.ModelResolver#addRepository(org.apache.maven.api.model.Repository):METHOD_NEW_DEFAULT</exclude>
<exclude>org.apache.maven.model.resolution.ModelResolver#addRepository(org.apache.maven.api.model.Repository,boolean):METHOD_NEW_DEFAULT</exclude>
<exclude>org.apache.maven.model.resolution.ModelResolver#resolveModel(org.apache.maven.api.model.Parent,java.util.concurrent.atomic.AtomicReference):METHOD_NEW_DEFAULT</exclude>
<exclude>org.apache.maven.model.resolution.ModelResolver#resolveModel(org.apache.maven.api.model.Dependency,java.util.concurrent.atomic.AtomicReference):METHOD_NEW_DEFAULT</exclude>
<exclude>org.apache.maven.model.superpom.DefaultSuperPomProvider#getSuperModel(java.lang.String):METHOD_RETURN_TYPE_CHANGED</exclude>
<exclude>org.apache.maven.model.superpom.DefaultSuperPomProvider#setModelProcessor(org.apache.maven.model.building.ModelProcessor):METHOD_REMOVED</exclude>
<exclude>org.apache.maven.model.superpom.DefaultSuperPomProvider#DefaultSuperPomProvider():CONSTRUCTOR_REMOVED</exclude>
<exclude>org.apache.maven.model.superpom.SuperPomProvider#getSuperModel(java.lang.String):METHOD_RETURN_TYPE_CHANGED</exclude>
<exclude>org.apache.maven.model.validation.DefaultModelValidator#validateDependencyVersion(org.apache.maven.model.building.ModelProblemCollector,org.apache.maven.model.Dependency,java.lang.String):METHOD_REMOVED</exclude>
<exclude>org.apache.maven.model.validation.ModelValidator#validateFileModel(org.apache.maven.model.Model,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_NEW_DEFAULT</exclude>
<exclude>org.apache.maven.model.validation.ModelValidator#validateExternalProfiles(java.util.List,org.apache.maven.model.Model,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_NEW_DEFAULT</exclude>
<!-- <exclude>org.apache.maven.model.building.DefaultModelBuilder#DefaultModelBuilder():CONSTRUCTOR_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.building.DefaultModelProcessor#setModelLocator(org.apache.maven.model.locator.ModelLocator):METHOD_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.building.DefaultModelProcessor#setModelReader(org.apache.maven.model.io.ModelReader):METHOD_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.building.DefaultModelProcessor#DefaultModelProcessor():CONSTRUCTOR_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.building.ModelCache#get(java.lang.String,java.lang.String,java.lang.String,java.lang.String):METHOD_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.building.ModelCache#put(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.Object):METHOD_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.composition.DependencyManagementImporter#importManagement(org.apache.maven.model.Model,java.util.List,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.composition.DefaultDependencyManagementImporter#importManagement(org.apache.maven.model.Model,java.util.List,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.inheritance.DefaultInheritanceAssembler</exclude>-->
<!-- <exclude>org.apache.maven.model.inheritance.InheritanceAssembler#assembleModelInheritance(org.apache.maven.model.Model,org.apache.maven.model.Model,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.interpolation.StringVisitorModelInterpolator</exclude>-->
<!-- <exclude>org.apache.maven.model.io.DefaultModelReader#DefaultModelReader():CONSTRUCTOR_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.locator.ModelLocator#locateExistingPom(java.io.File):METHOD_NEW_DEFAULT</exclude>-->
<!-- <exclude>org.apache.maven.model.management.DefaultDependencyManagementInjector$ManagementModelMerger</exclude>-->
<!-- <exclude>org.apache.maven.model.management.DefaultPluginManagementInjector$ManagementModelMerger</exclude>-->
<!-- <exclude>org.apache.maven.model.merge.MavenModelMerger</exclude>-->
<!-- <exclude>org.apache.maven.model.normalization.DefaultModelNormalizer$DuplicateMerger#mergePlugin(org.apache.maven.model.Plugin,org.apache.maven.model.Plugin):METHOD_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.normalization.DefaultModelNormalizer$DuplicateMerger:METHOD_REMOVED_IN_SUPERCLASS</exclude>-->
<!-- <exclude>org.apache.maven.model.path.DefaultModelPathTranslator#setPathTranslator(org.apache.maven.model.path.PathTranslator):METHOD_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.path.DefaultModelPathTranslator#DefaultModelPathTranslator():CONSTRUCTOR_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.path.DefaultModelUrlNormalizer#setUrlNormalizer(org.apache.maven.model.path.UrlNormalizer):METHOD_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.path.DefaultModelUrlNormalizer#DefaultModelUrlNormalizer():CONSTRUCTOR_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.path.ProfileActivationFilePathInterpolator#setPathTranslator(org.apache.maven.model.path.PathTranslator):METHOD_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.path.ProfileActivationFilePathInterpolator#ProfileActivationFilePathInterpolator():CONSTRUCTOR_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.profile.activation.FileProfileActivator#setProfileActivationFilePathInterpolator(org.apache.maven.model.path.ProfileActivationFilePathInterpolator):METHOD_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.profile.activation.FileProfileActivator#FileProfileActivator():CONSTRUCTOR_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.profile.DefaultProfileInjector</exclude>-->
<!-- <exclude>org.apache.maven.model.profile.ProfileInjector#injectProfile(org.apache.maven.api.model.Model,org.apache.maven.api.model.Profile,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_NEW_DEFAULT</exclude>-->
<!-- <exclude>org.apache.maven.model.profile.ProfileInjector#injectProfiles(org.apache.maven.api.model.Model,java.util.List,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_NEW_DEFAULT</exclude>-->
<!-- <exclude>org.apache.maven.model.profile.ProfileSelector#getActiveProfilesV4(java.util.Collection,org.apache.maven.model.profile.ProfileActivationContext,org.apache.maven.model.building.ModelProblemCollector):METHOD_NEW_DEFAULT</exclude>-->
<!-- <exclude>org.apache.maven.model.resolution.InvalidRepositoryException#getRepository():METHOD_RETURN_TYPE_CHANGED</exclude>-->
<!-- <exclude>org.apache.maven.model.resolution.InvalidRepositoryException#InvalidRepositoryException(java.lang.String,org.apache.maven.model.Repository,java.lang.Throwable):CONSTRUCTOR_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.resolution.InvalidRepositoryException#InvalidRepositoryException(java.lang.String,org.apache.maven.model.Repository):CONSTRUCTOR_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.resolution.ModelResolver#addRepository(org.apache.maven.api.model.Repository):METHOD_NEW_DEFAULT</exclude>-->
<!-- <exclude>org.apache.maven.model.resolution.ModelResolver#addRepository(org.apache.maven.api.model.Repository,boolean):METHOD_NEW_DEFAULT</exclude>-->
<!-- <exclude>org.apache.maven.model.resolution.ModelResolver#resolveModel(org.apache.maven.api.model.Parent,java.util.concurrent.atomic.AtomicReference):METHOD_NEW_DEFAULT</exclude>-->
<!-- <exclude>org.apache.maven.model.resolution.ModelResolver#resolveModel(org.apache.maven.api.model.Dependency,java.util.concurrent.atomic.AtomicReference):METHOD_NEW_DEFAULT</exclude>-->
<!-- <exclude>org.apache.maven.model.superpom.DefaultSuperPomProvider#getSuperModel(java.lang.String):METHOD_RETURN_TYPE_CHANGED</exclude>-->
<!-- <exclude>org.apache.maven.model.superpom.DefaultSuperPomProvider#setModelProcessor(org.apache.maven.model.building.ModelProcessor):METHOD_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.superpom.DefaultSuperPomProvider#DefaultSuperPomProvider():CONSTRUCTOR_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.superpom.SuperPomProvider#getSuperModel(java.lang.String):METHOD_RETURN_TYPE_CHANGED</exclude>-->
<!-- <exclude>org.apache.maven.model.validation.DefaultModelValidator#validateDependencyVersion(org.apache.maven.model.building.ModelProblemCollector,org.apache.maven.model.Dependency,java.lang.String):METHOD_REMOVED</exclude>-->
<!-- <exclude>org.apache.maven.model.validation.ModelValidator#validateFileModel(org.apache.maven.model.Model,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_NEW_DEFAULT</exclude>-->
<!-- <exclude>org.apache.maven.model.validation.ModelValidator#validateExternalProfiles(java.util.List,org.apache.maven.model.Model,org.apache.maven.model.building.ModelBuildingRequest,org.apache.maven.model.building.ModelProblemCollector):METHOD_NEW_DEFAULT</exclude>-->
</excludes>
</parameter>
</configuration>

View File

@ -1,192 +0,0 @@
/*
* 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.model.building;
import javax.inject.Named;
import javax.inject.Singleton;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
/**
* ModelSourceTransformer for the build pom
*
* @since 4.0.0
* @deprecated use {@link org.apache.maven.api.services.ModelBuilder} instead
*/
@Named
@Singleton
@Deprecated(since = "4.0.0")
class BuildModelSourceTransformer implements ModelSourceTransformer {
public static final String NAMESPACE_PREFIX = "http://maven.apache.org/POM/";
@Override
public void transform(Path pomFile, TransformerContext context, Model model) {
handleModelVersion(model);
handleParent(pomFile, context, model);
handleReactorDependencies(context, model);
handleCiFriendlyVersion(context, model);
}
//
// Infer modelVersion from namespace URI
//
void handleModelVersion(Model model) {
String namespace = model.getDelegate().getNamespaceUri();
if (model.getModelVersion() == null && namespace != null && namespace.startsWith(NAMESPACE_PREFIX)) {
model.setModelVersion(namespace.substring(NAMESPACE_PREFIX.length()));
}
}
//
// Infer parent information
//
void handleParent(Path pomFile, TransformerContext context, Model model) {
Parent parent = model.getParent();
if (parent != null) {
String version = parent.getVersion();
String path = Optional.ofNullable(parent.getRelativePath()).orElse("..");
if (version == null && !path.isEmpty()) {
Optional<RelativeProject> resolvedParent = resolveRelativePath(
pomFile, context, Paths.get(path), parent.getGroupId(), parent.getArtifactId());
resolvedParent.ifPresent(relativeProject -> parent.setVersion(relativeProject.getVersion()));
}
}
}
//
// CI friendly versions
//
void handleCiFriendlyVersion(TransformerContext context, Model model) {
String version = model.getVersion();
String modVersion = replaceCiFriendlyVersion(context, version);
model.setVersion(modVersion);
Parent parent = model.getParent();
if (parent != null) {
version = parent.getVersion();
modVersion = replaceCiFriendlyVersion(context, version);
parent.setVersion(modVersion);
}
}
//
// Infer inner reactor dependencies version
//
void handleReactorDependencies(TransformerContext context, Model model) {
for (Dependency dep : model.getDependencies()) {
if (dep.getVersion() == null) {
Model depModel =
context.getRawModel(model.getDelegate().getPomFile(), dep.getGroupId(), dep.getArtifactId());
if (depModel != null) {
String v = depModel.getVersion();
if (v == null && depModel.getParent() != null) {
v = depModel.getParent().getVersion();
}
dep.setVersion(v);
}
}
}
}
protected String replaceCiFriendlyVersion(TransformerContext context, String version) {
if (version != null) {
for (String key : Arrays.asList("changelist", "revision", "sha1")) {
String val = context.getUserProperty(key);
if (val != null) {
version = version.replace("${" + key + "}", val);
}
}
}
return version;
}
protected Optional<RelativeProject> resolveRelativePath(
Path pomFile, TransformerContext context, Path relativePath, String groupId, String artifactId) {
Path pomPath = pomFile.resolveSibling(relativePath).normalize();
if (Files.isDirectory(pomPath)) {
pomPath = context.locate(pomPath);
}
if (pomPath == null || !Files.isRegularFile(pomPath)) {
return Optional.empty();
}
Optional<RelativeProject> mappedProject = Optional.ofNullable(context.getRawModel(pomFile, pomPath.normalize()))
.map(BuildModelSourceTransformer::toRelativeProject);
if (mappedProject.isPresent()) {
RelativeProject project = mappedProject.get();
if (Objects.equals(groupId, project.getGroupId()) && Objects.equals(artifactId, project.getArtifactId())) {
return mappedProject;
}
}
return Optional.empty();
}
private static RelativeProject toRelativeProject(final org.apache.maven.model.Model m) {
String groupId = m.getGroupId();
if (groupId == null && m.getParent() != null) {
groupId = m.getParent().getGroupId();
}
String version = m.getVersion();
if (version == null && m.getParent() != null) {
version = m.getParent().getVersion();
}
return new RelativeProject(groupId, m.getArtifactId(), version);
}
static class RelativeProject {
private final String groupId;
private final String artifactId;
private final String version;
RelativeProject(String groupId, String artifactId, String version) {
this.groupId = groupId;
this.artifactId = artifactId;
this.version = version;
}
public String getGroupId() {
return groupId;
}
public String getArtifactId() {
return artifactId;
}
public String getVersion() {
return version;
}
}
}

View File

@ -18,13 +18,6 @@
*/
package org.apache.maven.model.building;
import java.util.Arrays;
import org.apache.maven.api.Version;
import org.apache.maven.api.VersionConstraint;
import org.apache.maven.api.VersionRange;
import org.apache.maven.api.services.model.ModelVersionParser;
import org.apache.maven.api.spi.ModelParser;
import org.apache.maven.model.Model;
import org.apache.maven.model.composition.DefaultDependencyManagementImporter;
import org.apache.maven.model.composition.DependencyManagementImporter;
@ -69,165 +62,27 @@ import org.apache.maven.model.profile.activation.JdkVersionProfileActivator;
import org.apache.maven.model.profile.activation.OperatingSystemProfileActivator;
import org.apache.maven.model.profile.activation.ProfileActivator;
import org.apache.maven.model.profile.activation.PropertyProfileActivator;
import org.apache.maven.model.root.DefaultRootLocator;
import org.apache.maven.model.root.RootLocator;
import org.apache.maven.model.superpom.DefaultSuperPomProvider;
import org.apache.maven.model.superpom.SuperPomProvider;
import org.apache.maven.model.validation.DefaultModelValidator;
import org.apache.maven.model.validation.ModelValidator;
import static java.util.Objects.requireNonNull;
/**
* A factory to create model builder instances when no dependency injection is available. <em>Note:</em> This class is
* only meant as a utility for developers that want to employ the model builder outside the Maven build system, Maven
* only meant as a utility for developers that want to employ the model builder outside of the Maven build system, Maven
* plugins should always acquire model builder instances via dependency injection. Developers might want to subclass
* this factory to provide custom implementations for some of the components used by the model builder, or use the
* builder API to inject custom instances.
* this factory to provide custom implementations for some of the components used by the model builder.
*
* @deprecated use {@link org.apache.maven.api.services.ModelBuilder} instead
*/
@Deprecated(since = "4.0.0")
public class DefaultModelBuilderFactory {
private ModelProcessor modelProcessor;
private ModelValidator modelValidator;
private ModelNormalizer modelNormalizer;
private ModelInterpolator modelInterpolator;
private ModelPathTranslator modelPathTranslator;
private ModelUrlNormalizer modelUrlNormalizer;
private SuperPomProvider superPomProvider;
private InheritanceAssembler inheritanceAssembler;
private ProfileSelector profileSelector;
private ProfileInjector profileInjector;
private PluginManagementInjector pluginManagementInjector;
private DependencyManagementInjector dependencyManagementInjector;
private DependencyManagementImporter dependencyManagementImporter;
private LifecycleBindingsInjector lifecycleBindingsInjector;
private PluginConfigurationExpander pluginConfigurationExpander;
private ReportConfigurationExpander reportConfigurationExpander;
private ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator;
private ModelVersionProcessor versionProcessor;
private ModelSourceTransformer transformer;
private ModelVersionParser versionParser;
public DefaultModelBuilderFactory setModelProcessor(ModelProcessor modelProcessor) {
this.modelProcessor = modelProcessor;
return this;
}
public DefaultModelBuilderFactory setModelValidator(ModelValidator modelValidator) {
this.modelValidator = modelValidator;
return this;
}
public DefaultModelBuilderFactory setModelNormalizer(ModelNormalizer modelNormalizer) {
this.modelNormalizer = modelNormalizer;
return this;
}
public DefaultModelBuilderFactory setModelInterpolator(ModelInterpolator modelInterpolator) {
this.modelInterpolator = modelInterpolator;
return this;
}
public DefaultModelBuilderFactory setModelPathTranslator(ModelPathTranslator modelPathTranslator) {
this.modelPathTranslator = modelPathTranslator;
return this;
}
public DefaultModelBuilderFactory setModelUrlNormalizer(ModelUrlNormalizer modelUrlNormalizer) {
this.modelUrlNormalizer = modelUrlNormalizer;
return this;
}
public DefaultModelBuilderFactory setSuperPomProvider(SuperPomProvider superPomProvider) {
this.superPomProvider = superPomProvider;
return this;
}
public DefaultModelBuilderFactory setInheritanceAssembler(InheritanceAssembler inheritanceAssembler) {
this.inheritanceAssembler = inheritanceAssembler;
return this;
}
public DefaultModelBuilderFactory setProfileSelector(ProfileSelector profileSelector) {
this.profileSelector = profileSelector;
return this;
}
public DefaultModelBuilderFactory setProfileInjector(ProfileInjector profileInjector) {
this.profileInjector = profileInjector;
return this;
}
public DefaultModelBuilderFactory setPluginManagementInjector(PluginManagementInjector pluginManagementInjector) {
this.pluginManagementInjector = pluginManagementInjector;
return this;
}
public DefaultModelBuilderFactory setDependencyManagementInjector(
DependencyManagementInjector dependencyManagementInjector) {
this.dependencyManagementInjector = dependencyManagementInjector;
return this;
}
public DefaultModelBuilderFactory setDependencyManagementImporter(
DependencyManagementImporter dependencyManagementImporter) {
this.dependencyManagementImporter = dependencyManagementImporter;
return this;
}
public DefaultModelBuilderFactory setLifecycleBindingsInjector(
LifecycleBindingsInjector lifecycleBindingsInjector) {
this.lifecycleBindingsInjector = lifecycleBindingsInjector;
return this;
}
public DefaultModelBuilderFactory setPluginConfigurationExpander(
PluginConfigurationExpander pluginConfigurationExpander) {
this.pluginConfigurationExpander = pluginConfigurationExpander;
return this;
}
public DefaultModelBuilderFactory setReportConfigurationExpander(
ReportConfigurationExpander reportConfigurationExpander) {
this.reportConfigurationExpander = reportConfigurationExpander;
return this;
}
@Deprecated
public DefaultModelBuilderFactory setReportingConverter(ReportingConverter reportingConverter) {
return this;
}
public DefaultModelBuilderFactory setProfileActivationFilePathInterpolator(
ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator) {
this.profileActivationFilePathInterpolator = profileActivationFilePathInterpolator;
return this;
}
public DefaultModelBuilderFactory setVersionProcessor(ModelVersionProcessor versionProcessor) {
this.versionProcessor = versionProcessor;
return this;
}
public DefaultModelBuilderFactory setTransformer(ModelSourceTransformer transformer) {
this.transformer = transformer;
return this;
}
public DefaultModelBuilderFactory setModelVersionParser(ModelVersionParser versionParser) {
this.versionParser = versionParser;
return this;
}
protected ModelProcessor newModelProcessor() {
return new DefaultModelProcessor(Arrays.asList(newModelParsers()), newModelLocator(), newModelReader());
}
protected ModelParser[] newModelParsers() {
return new ModelParser[0];
DefaultModelProcessor processor = new DefaultModelProcessor();
processor.setModelLocator(newModelLocator());
processor.setModelReader(newModelReader());
return processor;
}
protected ModelLocator newModelLocator() {
@ -235,11 +90,17 @@ public class DefaultModelBuilderFactory {
}
protected ModelReader newModelReader() {
return new DefaultModelReader(newModelSourceTransformer());
return new DefaultModelReader();
}
protected ProfileSelector newProfileSelector() {
return new DefaultProfileSelector(Arrays.asList(newProfileActivators()));
DefaultProfileSelector profileSelector = new DefaultProfileSelector();
for (ProfileActivator activator : newProfileActivators()) {
profileSelector.addProfileActivator(activator);
}
return profileSelector;
}
protected ProfileActivator[] newProfileActivators() {
@ -247,12 +108,13 @@ public class DefaultModelBuilderFactory {
new JdkVersionProfileActivator(),
new OperatingSystemProfileActivator(),
new PropertyProfileActivator(),
new FileProfileActivator(newProfileActivationFilePathInterpolator())
new FileProfileActivator()
.setProfileActivationFilePathInterpolator(newProfileActivationFilePathInterpolator())
};
}
protected ProfileActivationFilePathInterpolator newProfileActivationFilePathInterpolator() {
return new ProfileActivationFilePathInterpolator(newPathTranslator(), newRootLocator());
return new ProfileActivationFilePathInterpolator().setPathTranslator(newPathTranslator());
}
protected UrlNormalizer newUrlNormalizer() {
@ -263,15 +125,13 @@ public class DefaultModelBuilderFactory {
return new DefaultPathTranslator();
}
protected RootLocator newRootLocator() {
return new DefaultRootLocator();
}
protected ModelInterpolator newModelInterpolator() {
UrlNormalizer normalizer = newUrlNormalizer();
PathTranslator pathTranslator = newPathTranslator();
RootLocator rootLocator = newRootLocator();
return new StringVisitorModelInterpolator(pathTranslator, normalizer, rootLocator);
return new StringVisitorModelInterpolator()
.setPathTranslator(pathTranslator)
.setUrlNormalizer(normalizer)
.setVersionPropertiesProcessor(newModelVersionPropertiesProcessor());
}
protected ModelVersionProcessor newModelVersionPropertiesProcessor() {
@ -279,8 +139,7 @@ public class DefaultModelBuilderFactory {
}
protected ModelValidator newModelValidator() {
ModelVersionProcessor processor = newModelVersionPropertiesProcessor();
return new DefaultModelValidator(processor);
return new DefaultModelValidator(newModelVersionPropertiesProcessor());
}
protected ModelNormalizer newModelNormalizer() {
@ -288,11 +147,11 @@ public class DefaultModelBuilderFactory {
}
protected ModelPathTranslator newModelPathTranslator() {
return new DefaultModelPathTranslator(newPathTranslator());
return new DefaultModelPathTranslator().setPathTranslator(newPathTranslator());
}
protected ModelUrlNormalizer newModelUrlNormalizer() {
return new DefaultModelUrlNormalizer(newUrlNormalizer());
return new DefaultModelUrlNormalizer().setUrlNormalizer(newUrlNormalizer());
}
protected InheritanceAssembler newInheritanceAssembler() {
@ -304,7 +163,7 @@ public class DefaultModelBuilderFactory {
}
protected SuperPomProvider newSuperPomProvider() {
return new DefaultSuperPomProvider(newModelProcessor());
return new DefaultSuperPomProvider().setModelProcessor(newModelProcessor());
}
protected DependencyManagementImporter newDependencyManagementImporter() {
@ -331,82 +190,38 @@ public class DefaultModelBuilderFactory {
return new DefaultReportConfigurationExpander();
}
@Deprecated
protected ReportingConverter newReportingConverter() {
return new DefaultReportingConverter();
}
private ModelSourceTransformer newModelSourceTransformer() {
return new BuildModelSourceTransformer();
}
private ModelVersionParser newModelVersionParser() {
// This is a limited parser that does not support ranges and compares versions as strings
// in real-life this parser should not be used, but replaced with a proper one
return new ModelVersionParser() {
@Override
public Version parseVersion(String version) {
requireNonNull(version, "version");
return new Version() {
@Override
public String asString() {
return version;
}
@Override
public int compareTo(Version o) {
return version.compareTo(o.asString());
}
};
}
@Override
public VersionRange parseVersionRange(String range) {
throw new IllegalArgumentException("ranges not supported by this parser");
}
@Override
public VersionConstraint parseVersionConstraint(String constraint) {
throw new IllegalArgumentException("constraint not supported by this parser");
}
@Override
public boolean isSnapshot(String version) {
requireNonNull(version, "version");
return version.endsWith("SNAPSHOT");
}
};
}
/**
* Creates a new model builder instance.
*
* @return The new model builder instance, never {@code null}.
*/
public DefaultModelBuilder newInstance() {
return new DefaultModelBuilder(
modelProcessor != null ? modelProcessor : newModelProcessor(),
modelValidator != null ? modelValidator : newModelValidator(),
modelNormalizer != null ? modelNormalizer : newModelNormalizer(),
modelInterpolator != null ? modelInterpolator : newModelInterpolator(),
modelPathTranslator != null ? modelPathTranslator : newModelPathTranslator(),
modelUrlNormalizer != null ? modelUrlNormalizer : newModelUrlNormalizer(),
superPomProvider != null ? superPomProvider : newSuperPomProvider(),
inheritanceAssembler != null ? inheritanceAssembler : newInheritanceAssembler(),
profileSelector != null ? profileSelector : newProfileSelector(),
profileInjector != null ? profileInjector : newProfileInjector(),
pluginManagementInjector != null ? pluginManagementInjector : newPluginManagementInjector(),
dependencyManagementInjector != null ? dependencyManagementInjector : newDependencyManagementInjector(),
dependencyManagementImporter != null ? dependencyManagementImporter : newDependencyManagementImporter(),
lifecycleBindingsInjector != null ? lifecycleBindingsInjector : newLifecycleBindingsInjector(),
pluginConfigurationExpander != null ? pluginConfigurationExpander : newPluginConfigurationExpander(),
reportConfigurationExpander != null ? reportConfigurationExpander : newReportConfigurationExpander(),
profileActivationFilePathInterpolator != null
? profileActivationFilePathInterpolator
: newProfileActivationFilePathInterpolator(),
versionProcessor != null ? versionProcessor : newModelVersionPropertiesProcessor(),
transformer != null ? transformer : newModelSourceTransformer(),
versionParser != null ? versionParser : newModelVersionParser());
DefaultModelBuilder modelBuilder = new DefaultModelBuilder();
modelBuilder.setModelProcessor(newModelProcessor());
modelBuilder.setModelValidator(newModelValidator());
modelBuilder.setModelNormalizer(newModelNormalizer());
modelBuilder.setModelPathTranslator(newModelPathTranslator());
modelBuilder.setModelUrlNormalizer(newModelUrlNormalizer());
modelBuilder.setModelInterpolator(newModelInterpolator());
modelBuilder.setInheritanceAssembler(newInheritanceAssembler());
modelBuilder.setProfileInjector(newProfileInjector());
modelBuilder.setProfileSelector(newProfileSelector());
modelBuilder.setSuperPomProvider(newSuperPomProvider());
modelBuilder.setDependencyManagementImporter(newDependencyManagementImporter());
modelBuilder.setDependencyManagementInjector(newDependencyManagementInjector());
modelBuilder.setLifecycleBindingsInjector(newLifecycleBindingsInjector());
modelBuilder.setPluginManagementInjector(newPluginManagementInjector());
modelBuilder.setPluginConfigurationExpander(newPluginConfigurationExpander());
modelBuilder.setReportConfigurationExpander(newReportConfigurationExpander());
modelBuilder.setReportingConverter(newReportingConverter());
modelBuilder.setProfileActivationFilePathInterpolator(newProfileActivationFilePathInterpolator());
return modelBuilder;
}
private static class StubLifecycleBindingsInjector implements LifecycleBindingsInjector {

View File

@ -28,7 +28,7 @@ import org.apache.maven.model.Model;
@Deprecated(since = "4.0.0")
class DefaultModelBuildingEvent implements ModelBuildingEvent {
private Model model;
private final Model model;
private final ModelBuildingRequest request;

View File

@ -19,7 +19,6 @@
package org.apache.maven.model.building;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -37,9 +36,10 @@ import org.apache.maven.model.resolution.WorkspaceModelResolver;
*/
@Deprecated(since = "4.0.0")
public class DefaultModelBuildingRequest implements ModelBuildingRequest {
private Model fileModel;
private Path pomPath;
private Model rawModel;
private File pomFile;
private ModelSource modelSource;
@ -71,10 +71,6 @@ public class DefaultModelBuildingRequest implements ModelBuildingRequest {
private WorkspaceModelResolver workspaceResolver;
private TransformerContextBuilder contextBuilder;
private Path rootDirectory;
/**
* Creates an empty request.
*/
@ -86,7 +82,7 @@ public class DefaultModelBuildingRequest implements ModelBuildingRequest {
* @param request The request to copy, must not be {@code null}.
*/
public DefaultModelBuildingRequest(ModelBuildingRequest request) {
setPomPath(request.getPomPath());
setPomFile(request.getPomFile());
setModelSource(request.getModelSource());
setValidationLevel(request.getValidationLevel());
setProcessPlugins(request.isProcessPlugins());
@ -101,39 +97,24 @@ public class DefaultModelBuildingRequest implements ModelBuildingRequest {
setModelResolver(request.getModelResolver());
setModelBuildingListener(request.getModelBuildingListener());
setModelCache(request.getModelCache());
setWorkspaceModelResolver(request.getWorkspaceModelResolver());
setTransformerContextBuilder(request.getTransformerContextBuilder());
setRootDirectory(request.getRootDirectory());
}
@Deprecated
@Override
public File getPomFile() {
return pomPath != null ? pomPath.toFile() : null;
return pomFile;
}
@Override
public Path getPomPath() {
return pomPath;
}
@Deprecated
@Override
public DefaultModelBuildingRequest setPomFile(File pomFile) {
this.pomPath = (pomFile != null) ? pomFile.toPath().toAbsolutePath() : null;
return this;
}
this.pomFile = (pomFile != null) ? pomFile.getAbsoluteFile() : null;
@Override
public DefaultModelBuildingRequest setPomPath(Path pomPath) {
this.pomPath = (pomPath != null) ? pomPath.toAbsolutePath() : null;
return this;
}
@Override
public synchronized ModelSource getModelSource() {
if (modelSource == null && pomPath != null) {
modelSource = new FileModelSource(pomPath);
if (modelSource == null && pomFile != null) {
modelSource = new FileModelSource(pomFile);
}
return modelSource;
}
@ -266,8 +247,9 @@ public class DefaultModelBuildingRequest implements ModelBuildingRequest {
public DefaultModelBuildingRequest setSystemProperties(Properties systemProperties) {
if (systemProperties != null) {
this.systemProperties = new Properties();
// avoid concurrent modification if someone else sets/removes an unrelated system property
synchronized (systemProperties) {
synchronized (
systemProperties) { // avoid concurrentmodification if someone else sets/removes an unrelated system
// property
this.systemProperties.putAll(systemProperties);
}
} else {
@ -346,24 +328,14 @@ public class DefaultModelBuildingRequest implements ModelBuildingRequest {
return this;
}
@Override
public Model getFileModel() {
return fileModel;
}
@Override
public ModelBuildingRequest setFileModel(Model fileModel) {
this.fileModel = fileModel;
return this;
}
@Override
public Model getRawModel() {
return null;
return rawModel;
}
@Override
public ModelBuildingRequest setRawModel(Model rawModel) {
this.rawModel = rawModel;
return this;
}
@ -377,26 +349,4 @@ public class DefaultModelBuildingRequest implements ModelBuildingRequest {
this.workspaceResolver = workspaceResolver;
return this;
}
@Override
public TransformerContextBuilder getTransformerContextBuilder() {
return contextBuilder;
}
@Override
public ModelBuildingRequest setTransformerContextBuilder(TransformerContextBuilder contextBuilder) {
this.contextBuilder = contextBuilder;
return this;
}
@Override
public Path getRootDirectory() {
return rootDirectory;
}
@Override
public ModelBuildingRequest setRootDirectory(Path rootDirectory) {
this.rootDirectory = rootDirectory;
return this;
}
}

View File

@ -34,7 +34,6 @@ import org.apache.maven.model.Profile;
*/
@Deprecated(since = "4.0.0")
class DefaultModelBuildingResult implements ModelBuildingResult {
private Model fileModel;
private Model effectiveModel;
@ -56,31 +55,6 @@ class DefaultModelBuildingResult implements ModelBuildingResult {
problems = new ArrayList<>();
}
DefaultModelBuildingResult(ModelBuildingResult result) {
this();
this.activeExternalProfiles.addAll(result.getActiveExternalProfiles());
this.effectiveModel = result.getEffectiveModel();
this.fileModel = result.getFileModel();
this.problems.addAll(result.getProblems());
for (String modelId : result.getModelIds()) {
this.modelIds.add(modelId);
this.rawModels.put(modelId, result.getRawModel(modelId));
this.activePomProfiles.put(modelId, result.getActivePomProfiles(modelId));
}
}
@Override
public Model getFileModel() {
return fileModel;
}
public DefaultModelBuildingResult setFileModel(Model fileModel) {
this.fileModel = fileModel;
return this;
}
@Override
public Model getEffectiveModel() {
return effectiveModel;

View File

@ -138,16 +138,16 @@ public class DefaultModelProblem implements ModelProblem {
@Override
public String getMessage() {
String msg = null;
String msg;
if (message != null && !message.isEmpty()) {
if (message != null && message.length() > 0) {
msg = message;
} else if (exception != null) {
} else {
msg = exception.getMessage();
}
if (msg == null) {
msg = "";
if (msg == null) {
msg = "";
}
}
return msg;
@ -169,11 +169,7 @@ public class DefaultModelProblem implements ModelProblem {
buffer.append('[').append(getSeverity()).append("] ");
buffer.append(getMessage());
String location = ModelProblemUtils.formatLocation(this, null);
if (!location.isEmpty()) {
buffer.append(" @ ");
buffer.append(location);
}
buffer.append(" @ ").append(ModelProblemUtils.formatLocation(this, null));
return buffer.toString();
}

View File

@ -26,18 +26,9 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import org.apache.maven.api.model.Model;
import org.apache.maven.api.spi.ModelParser;
import org.apache.maven.api.spi.ModelParserException;
import org.apache.maven.model.io.ModelParseException;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.ModelReader;
import org.apache.maven.model.locator.ModelLocator;
import org.eclipse.sisu.Typed;
@ -50,12 +41,12 @@ import org.eclipse.sisu.Typed;
* made this component available under all its interfaces then it could end up being injected
* into itself leading to a stack overflow.
*
* A side effect of using @Typed is that it translates to explicit bindings in the container.
* A side-effect of using @Typed is that it translates to explicit bindings in the container.
* So instead of binding the component under a 'wildcard' key it is now bound with an explicit
* key. Since this is a default component this will be a plain binding of ModelProcessor to
* this implementation type, ie. no hint/name.
*
* This leads to a second side effect in that any @Inject request for just ModelProcessor in
* This leads to a second side-effect in that any @Inject request for just ModelProcessor in
* the same injector is immediately matched to this explicit binding, which means extensions
* cannot override this binding. This is because the lookup is always short-circuited in this
* specific situation (plain @Inject request, and plain explicit binding for the same type.)
@ -75,132 +66,39 @@ import org.eclipse.sisu.Typed;
@Deprecated(since = "4.0.0")
public class DefaultModelProcessor implements ModelProcessor {
private final Collection<ModelParser> modelParsers;
private final ModelLocator modelLocator;
private final ModelReader modelReader;
@Inject
private ModelLocator locator;
@Inject
public DefaultModelProcessor(List<ModelParser> modelParsers, ModelLocator modelLocator, ModelReader modelReader) {
this.modelParsers = modelParsers;
this.modelLocator = modelLocator;
this.modelReader = modelReader;
private ModelReader reader;
public DefaultModelProcessor setModelLocator(ModelLocator locator) {
this.locator = locator;
return this;
}
public DefaultModelProcessor setModelReader(ModelReader reader) {
this.reader = reader;
return this;
}
@Deprecated
@Override
public File locatePom(File projectDirectory) {
return locatePom(projectDirectory.toPath()).toFile();
return locator.locatePom(projectDirectory);
}
@Override
public Path locatePom(Path projectDirectory) {
// Note that the ModelProcessor#locatePom never returns null
// while the ModelParser#locatePom needs to return an existing path!
Path pom = modelParsers.stream()
.map(m -> m.locate(projectDirectory)
.map(org.apache.maven.api.services.Source::getPath)
.orElse(null))
.filter(Objects::nonNull)
.findFirst()
.orElseGet(() -> modelLocator.locatePom(projectDirectory));
if (!pom.equals(projectDirectory) && !pom.getParent().equals(projectDirectory)) {
throw new IllegalArgumentException("The POM found does not belong to the given directory: " + pom);
}
return pom;
}
@Deprecated
@Override
public File locateExistingPom(File projectDirectory) {
Path path = locateExistingPom(projectDirectory.toPath());
return path != null ? path.toFile() : null;
public Model read(File input, Map<String, ?> options) throws IOException {
return reader.read(input, options);
}
@Override
public Path locateExistingPom(Path projectDirectory) {
// Note that the ModelProcessor#locatePom never returns null
// while the ModelParser#locatePom needs to return an existing path!
Path pom = modelParsers.stream()
.map(m -> m.locate(projectDirectory)
.map(org.apache.maven.api.services.Source::getPath)
.orElse(null))
.filter(Objects::nonNull)
.findFirst()
.orElseGet(() -> modelLocator.locateExistingPom(projectDirectory));
if (pom != null && !pom.equals(projectDirectory) && !pom.getParent().equals(projectDirectory)) {
throw new IllegalArgumentException("The POM found does not belong to the given directory: " + pom);
}
return pom;
}
protected org.apache.maven.api.model.Model read(
Path pomFile, InputStream input, Reader reader, Map<String, ?> options) throws IOException {
if (pomFile != null) {
Path projectDirectory = pomFile.getParent();
List<ModelParserException> exceptions = new ArrayList<>();
for (ModelParser parser : modelParsers) {
try {
Optional<Model> model = parser.locateAndParse(projectDirectory, options);
if (model.isPresent()) {
return model.get().withPomFile(pomFile);
}
} catch (ModelParserException e) {
exceptions.add(e);
}
}
try {
return readXmlModel(pomFile, null, null, options);
} catch (IOException e) {
exceptions.forEach(e::addSuppressed);
throw e;
}
} else {
return readXmlModel(pomFile, input, reader, options);
}
}
private org.apache.maven.api.model.Model readXmlModel(
Path pomFile, InputStream input, Reader reader, Map<String, ?> options) throws IOException {
if (pomFile != null) {
return modelReader.read(pomFile, options).getDelegate();
} else if (input != null) {
return modelReader.read(input, options).getDelegate();
} else {
return modelReader.read(reader, options).getDelegate();
}
}
@Deprecated
@Override
public org.apache.maven.model.Model read(File file, Map<String, ?> options) throws IOException {
Objects.requireNonNull(file, "file cannot be null");
return read(file.toPath(), options);
public Model read(Reader input, Map<String, ?> options) throws IOException {
return reader.read(input, options);
}
@Override
public org.apache.maven.model.Model read(Path path, Map<String, ?> options) throws IOException {
Objects.requireNonNull(path, "path cannot be null");
org.apache.maven.api.model.Model model = read(path, null, null, options);
return new org.apache.maven.model.Model(model);
}
@Override
public org.apache.maven.model.Model read(InputStream input, Map<String, ?> options) throws IOException {
Objects.requireNonNull(input, "input cannot be null");
try (InputStream in = input) {
org.apache.maven.api.model.Model model = read(null, in, null, options);
return new org.apache.maven.model.Model(model);
} catch (ModelParserException e) {
throw new ModelParseException("Unable to read model: " + e, e.getLineNumber(), e.getColumnNumber(), e);
}
}
@Override
public org.apache.maven.model.Model read(Reader reader, Map<String, ?> options) throws IOException {
Objects.requireNonNull(reader, "reader cannot be null");
try (Reader r = reader) {
org.apache.maven.api.model.Model model = read(null, null, r, options);
return new org.apache.maven.model.Model(model);
}
public Model read(InputStream input, Map<String, ?> options) throws IOException {
return reader.read(input, options);
}
}

View File

@ -1,144 +0,0 @@
/*
* 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.model.building;
import java.io.File;
import java.nio.file.Path;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import org.apache.maven.model.Model;
import org.apache.maven.model.locator.ModelLocator;
/**
*
* @since 4.0.0
* @deprecated use {@link org.apache.maven.api.services.ModelBuilder} instead
*/
@Deprecated(since = "4.0.0")
class DefaultTransformerContext implements TransformerContext {
final ModelLocator modelLocator;
final Map<String, String> userProperties = new ConcurrentHashMap<>();
final Map<Path, Holder> modelByPath = new ConcurrentHashMap<>();
final Map<GAKey, Holder> modelByGA = new ConcurrentHashMap<>();
public static class Holder {
private volatile boolean set;
private volatile Model model;
Holder() {}
Holder(Model model) {
this.model = Objects.requireNonNull(model);
this.set = true;
}
public static Model deref(Holder holder) {
return holder != null ? holder.get() : null;
}
public Model get() {
if (!set) {
synchronized (this) {
if (!set) {
try {
this.wait();
} catch (InterruptedException e) {
// Ignore
}
}
}
}
return model;
}
public Model computeIfAbsent(Supplier<Model> supplier) {
if (!set) {
synchronized (this) {
if (!set) {
this.set = true;
this.model = supplier.get();
this.notifyAll();
}
}
}
return model;
}
}
DefaultTransformerContext(ModelLocator modelLocator) {
this.modelLocator = modelLocator;
}
@Override
public String getUserProperty(String key) {
return userProperties.get(key);
}
@Override
public Model getRawModel(Path from, Path p) {
return Holder.deref(modelByPath.get(p));
}
@Override
public Model getRawModel(Path from, String groupId, String artifactId) {
return Holder.deref(modelByGA.get(new GAKey(groupId, artifactId)));
}
@Override
public Path locate(Path path) {
File file = modelLocator.locateExistingPom(path.toFile());
return file != null ? file.toPath() : null;
}
static class GAKey {
private final String groupId;
private final String artifactId;
private final int hashCode;
GAKey(String groupId, String artifactId) {
this.groupId = groupId;
this.artifactId = artifactId;
this.hashCode = Objects.hash(groupId, artifactId);
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof GAKey)) {
return false;
}
GAKey other = (GAKey) obj;
return Objects.equals(artifactId, other.artifactId) && Objects.equals(groupId, other.groupId);
}
}
}

View File

@ -1,227 +0,0 @@
/*
* 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.model.building;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.DefaultTransformerContext.GAKey;
import org.apache.maven.model.building.DefaultTransformerContext.Holder;
/**
* Builds up the transformer context.
* After the buildplan is ready, the build()-method returns the immutable context useful during distribution.
* This is an inner class, as it must be able to call readRawModel()
*
* @since 4.0.0
* @deprecated use {@link org.apache.maven.api.services.ModelBuilder} instead
*/
@Deprecated(since = "4.0.0")
class DefaultTransformerContextBuilder implements TransformerContextBuilder {
private final Graph dag = new Graph();
private final DefaultModelBuilder defaultModelBuilder;
private final DefaultTransformerContext context;
private final Map<String, Set<FileModelSource>> mappedSources = new ConcurrentHashMap<>(64);
private volatile boolean fullReactorLoaded;
DefaultTransformerContextBuilder(DefaultModelBuilder defaultModelBuilder) {
this.defaultModelBuilder = defaultModelBuilder;
this.context = new DefaultTransformerContext(defaultModelBuilder.getModelProcessor());
}
/**
* If an interface could be extracted, DefaultModelProblemCollector should be ModelProblemCollectorExt
*/
@Override
public TransformerContext initialize(ModelBuildingRequest request, ModelProblemCollector collector) {
// We must assume the TransformerContext was created using this.newTransformerContextBuilder()
DefaultModelProblemCollector problems = (DefaultModelProblemCollector) collector;
return new TransformerContext() {
@Override
public Path locate(Path path) {
return context.locate(path);
}
@Override
public String getUserProperty(String key) {
return context.userProperties.computeIfAbsent(
key, k -> request.getUserProperties().getProperty(key));
}
@Override
public Model getRawModel(Path from, String gId, String aId) {
Model model = findRawModel(from, gId, aId);
if (model != null) {
context.modelByGA.put(new GAKey(gId, aId), new Holder(model));
context.modelByPath.put(model.getPomPath(), new Holder(model));
}
return model;
}
@Override
public Model getRawModel(Path from, Path path) {
Model model = findRawModel(from, path);
if (model != null) {
String groupId = defaultModelBuilder.getGroupId(model);
context.modelByGA.put(
new DefaultTransformerContext.GAKey(groupId, model.getArtifactId()), new Holder(model));
context.modelByPath.put(path, new Holder(model));
}
return model;
}
private Model findRawModel(Path from, String groupId, String artifactId) {
FileModelSource source = getSource(groupId, artifactId);
if (source == null) {
// we need to check the whole reactor in case it's a dependency
loadFullReactor();
source = getSource(groupId, artifactId);
}
if (source != null) {
if (!addEdge(from, source.getPath(), problems)) {
return null;
}
try {
ModelBuildingRequest gaBuildingRequest =
new DefaultModelBuildingRequest(request).setModelSource(source);
return defaultModelBuilder.readRawModel(gaBuildingRequest, problems);
} catch (ModelBuildingException e) {
// gathered with problem collector
}
}
return null;
}
private void loadFullReactor() {
if (!fullReactorLoaded) {
synchronized (DefaultTransformerContextBuilder.this) {
if (!fullReactorLoaded) {
doLoadFullReactor();
fullReactorLoaded = true;
}
}
}
}
private void doLoadFullReactor() {
Path rootDirectory = request.getRootDirectory();
if (rootDirectory == null) {
return;
}
List<Path> toLoad = new ArrayList<>();
Path root = defaultModelBuilder.getModelProcessor().locateExistingPom(rootDirectory);
toLoad.add(root);
while (!toLoad.isEmpty()) {
Path pom = toLoad.remove(0);
try {
ModelBuildingRequest gaBuildingRequest =
new DefaultModelBuildingRequest(request).setModelSource(new FileModelSource(pom));
Model rawModel = defaultModelBuilder.readFileModel(gaBuildingRequest, problems);
for (String module : rawModel.getModules()) {
Path moduleFile = defaultModelBuilder
.getModelProcessor()
.locateExistingPom(pom.getParent().resolve(module));
if (moduleFile != null) {
toLoad.add(moduleFile);
}
}
} catch (ModelBuildingException e) {
// gathered with problem collector
}
}
}
private Model findRawModel(Path from, Path p) {
if (!Files.isRegularFile(p)) {
throw new IllegalArgumentException("Not a regular file: " + p);
}
if (!addEdge(from, p, problems)) {
return null;
}
DefaultModelBuildingRequest req =
new DefaultModelBuildingRequest(request).setPomPath(p).setModelSource(new FileModelSource(p));
try {
return defaultModelBuilder.readRawModel(req, problems);
} catch (ModelBuildingException e) {
// gathered with problem collector
}
return null;
}
};
}
private boolean addEdge(Path from, Path p, DefaultModelProblemCollector problems) {
try {
dag.addEdge(from.toString(), p.toString());
return true;
} catch (Graph.CycleDetectedException e) {
problems.add(new DefaultModelProblem(
"Cycle detected between models at " + from + " and " + p,
ModelProblem.Severity.FATAL,
null,
null,
0,
0,
null,
e));
return false;
}
}
@Override
public TransformerContext build() {
return context;
}
public FileModelSource getSource(String groupId, String artifactId) {
Set<FileModelSource> sources = mappedSources.get(groupId != null ? groupId + ":" + artifactId : artifactId);
if (sources == null) {
return null;
}
return sources.stream()
.reduce((a, b) -> {
throw new IllegalStateException(String.format(
"No unique Source for %s:%s: %s and %s",
groupId, artifactId, a.getLocation(), b.getLocation()));
})
.orElse(null);
}
public void putSource(String groupId, String artifactId, FileModelSource source) {
mappedSources
.computeIfAbsent(groupId + ":" + artifactId, k -> new HashSet<>())
.add(source);
if (groupId != null) {
mappedSources.computeIfAbsent(artifactId, k -> new HashSet<>()).add(source);
}
}
}

View File

@ -20,10 +20,8 @@ package org.apache.maven.model.building;
import java.io.File;
import java.net.URI;
import java.nio.file.Path;
import org.apache.maven.building.FileSource;
import org.apache.maven.model.locator.ModelLocator;
/**
* Wraps an ordinary {@link File} as a model source.
@ -31,29 +29,17 @@ import org.apache.maven.model.locator.ModelLocator;
* @deprecated use {@link org.apache.maven.api.services.ModelBuilder} instead
*/
@Deprecated(since = "4.0.0")
public class FileModelSource extends FileSource implements ModelSource3 {
public class FileModelSource extends FileSource implements ModelSource2 {
/**
* Creates a new model source backed by the specified file.
*
* @param pomFile The POM file, must not be {@code null}.
* @deprecated Use {@link #FileModelSource(Path)} instead.
*/
@Deprecated
public FileModelSource(File pomFile) {
super(pomFile);
}
/**
* Creates a new model source backed by the specified file.
*
* @param pomPath The POM file, must not be {@code null}.
* @since 4.0.0
*/
public FileModelSource(Path pomPath) {
super(pomPath);
}
/**
*
* @return the file of this source
@ -66,15 +52,18 @@ public class FileModelSource extends FileSource implements ModelSource3 {
}
@Override
public ModelSource3 getRelatedSource(ModelLocator locator, String relPath) {
public ModelSource2 getRelatedSource(String relPath) {
relPath = relPath.replace('\\', File.separatorChar).replace('/', File.separatorChar);
Path path = getPath().getParent().resolve(relPath);
File relatedPom = new File(getFile().getParentFile(), relPath);
Path relatedPom = locator.locateExistingPom(path);
if (relatedPom.isDirectory()) {
// TODO figure out how to reuse ModelLocator.locatePom(File) here
relatedPom = new File(relatedPom, "pom.xml");
}
if (relatedPom != null) {
return new FileModelSource(relatedPom.normalize());
if (relatedPom.isFile() && relatedPom.canRead()) {
return new FileModelSource(new File(relatedPom.toURI().normalize()));
}
return null;
@ -82,7 +71,7 @@ public class FileModelSource extends FileSource implements ModelSource3 {
@Override
public URI getLocationURI() {
return getPath().toUri();
return getFile().toURI();
}
@Override
@ -91,19 +80,15 @@ public class FileModelSource extends FileSource implements ModelSource3 {
return true;
}
if (obj == null) {
return false;
}
if (!FileModelSource.class.equals(obj.getClass())) {
if (!(obj instanceof FileModelSource)) {
return false;
}
FileModelSource other = (FileModelSource) obj;
return getPath().equals(other.getPath());
return getFile().equals(other.getFile());
}
@Override
public int hashCode() {
return getPath().hashCode();
return getFile().hashCode();
}
}

View File

@ -19,7 +19,6 @@
package org.apache.maven.model.building;
import java.io.File;
import java.nio.file.Path;
import java.util.Date;
import java.util.List;
import java.util.Properties;
@ -44,27 +43,15 @@ class FilterModelBuildingRequest implements ModelBuildingRequest {
this.request = request;
}
@Deprecated
@Override
public File getPomFile() {
return request.getPomFile();
}
@Override
public Path getPomPath() {
return request.getPomPath();
}
@Deprecated
@Override
public ModelBuildingRequest setPomFile(File pomFile) {
public FilterModelBuildingRequest setPomFile(File pomFile) {
request.setPomFile(pomFile);
return this;
}
@Override
public FilterModelBuildingRequest setPomPath(Path pomPath) {
request.setPomPath(pomPath);
return this;
}
@ -236,17 +223,6 @@ class FilterModelBuildingRequest implements ModelBuildingRequest {
return this;
}
@Override
public Model getFileModel() {
return request.getFileModel();
}
@Override
public ModelBuildingRequest setFileModel(Model fileModel) {
request.setFileModel(fileModel);
return this;
}
@Override
public Model getRawModel() {
return request.getRawModel();
@ -268,26 +244,4 @@ class FilterModelBuildingRequest implements ModelBuildingRequest {
request.setWorkspaceModelResolver(workspaceResolver);
return this;
}
@Override
public TransformerContextBuilder getTransformerContextBuilder() {
return request.getTransformerContextBuilder();
}
@Override
public ModelBuildingRequest setTransformerContextBuilder(TransformerContextBuilder contextBuilder) {
request.setTransformerContextBuilder(contextBuilder);
return this;
}
@Override
public Path getRootDirectory() {
return request.getRootDirectory();
}
@Override
public ModelBuildingRequest setRootDirectory(Path rootDirectory) {
request.setRootDirectory(rootDirectory);
return this;
}
}

View File

@ -19,7 +19,6 @@
package org.apache.maven.model.building;
import java.io.File;
import java.nio.file.Path;
import org.apache.maven.model.Model;
@ -55,31 +54,6 @@ public interface ModelBuilder {
/**
* Performs only the part of {@link ModelBuilder#build(ModelBuildingRequest)} that loads the raw model
*
* @deprecated Use {@link #buildRawModel(Path, int, boolean)} instead.
*/
@Deprecated
Result<? extends Model> buildRawModel(File pomFile, int validationLevel, boolean locationTracking);
/**
* Performs only the part of {@link ModelBuilder#build(ModelBuildingRequest)} that loads the raw model
*
* @since 4.0.0
*/
Result<? extends Model> buildRawModel(Path pomFile, int validationLevel, boolean locationTracking);
/**
* @deprecated Use {@link #buildRawModel(Path, int, boolean, TransformerContext)} instead.
*/
@Deprecated
Result<? extends Model> buildRawModel(
File pomFile, int validationLevel, boolean locationTracking, TransformerContext context);
/**
* @since 4.0.0
*/
Result<? extends Model> buildRawModel(
Path pomFile, int validationLevel, boolean locationTracking, TransformerContext context);
TransformerContextBuilder newTransformerContextBuilder();
}

View File

@ -35,5 +35,10 @@ interface ModelBuildingEventCatapult {
*/
void fire(ModelBuildingListener listener, ModelBuildingEvent event);
ModelBuildingEventCatapult BUILD_EXTENSIONS_ASSEMBLED = ModelBuildingListener::buildExtensionsAssembled;
ModelBuildingEventCatapult BUILD_EXTENSIONS_ASSEMBLED = new ModelBuildingEventCatapult() {
@Override
public void fire(ModelBuildingListener listener, ModelBuildingEvent event) {
listener.buildExtensionsAssembled(event);
}
};
}

View File

@ -42,7 +42,7 @@ public class ModelBuildingException extends Exception {
*
* @param model The model that could not be built, may be {@code null}.
* @param modelId The identifier of the model that could not be built, may be {@code null}.
* @param problems The problems that cause this exception, may be {@code null}.
* @param problems The problems that causes this exception, may be {@code null}.
* @deprecated Use {@link #ModelBuildingException(ModelBuildingResult)} instead.
*/
@Deprecated
@ -130,7 +130,6 @@ public class ModelBuildingException extends Exception {
return null;
}
// Package protected for test
static String toMessage(String modelId, List<ModelProblem> problems) {
StringWriter buffer = new StringWriter(1024);
@ -139,22 +138,19 @@ public class ModelBuildingException extends Exception {
writer.print(problems.size());
writer.print((problems.size() == 1) ? " problem was " : " problems were ");
writer.print("encountered while building the effective model");
if (modelId != null && !modelId.isEmpty()) {
if (modelId != null && modelId.length() > 0) {
writer.print(" for ");
writer.print(modelId);
}
writer.println();
for (ModelProblem problem : problems) {
writer.println();
writer.print(" - [");
writer.print("[");
writer.print(problem.getSeverity());
writer.print("] ");
writer.print(problem.getMessage());
String location = ModelProblemUtils.formatLocation(problem, modelId);
if (!location.isEmpty()) {
writer.print(" @ ");
writer.print(location);
}
writer.print(" @ ");
writer.println(ModelProblemUtils.formatLocation(problem, modelId));
}
return buffer.toString();

View File

@ -19,7 +19,6 @@
package org.apache.maven.model.building;
import java.io.File;
import java.nio.file.Path;
import java.util.Date;
import java.util.List;
import java.util.Properties;
@ -55,48 +54,27 @@ public interface ModelBuildingRequest {
int VALIDATION_LEVEL_MAVEN_3_0 = 30;
/**
* Denotes validation as performed by Maven 3.1. This validation level is meant for existing projects.
* Denotes validation as performed by Maven 3.1. This validation level is meant for new projects.
*/
int VALIDATION_LEVEL_MAVEN_3_1 = 31;
/**
* Denotes validation as performed by Maven 4.0. This validation level is meant for new projects.
*/
int VALIDATION_LEVEL_MAVEN_4_0 = 40;
/**
* Denotes strict validation as recommended by the current Maven version.
*/
int VALIDATION_LEVEL_STRICT = VALIDATION_LEVEL_MAVEN_4_0;
int VALIDATION_LEVEL_STRICT = VALIDATION_LEVEL_MAVEN_3_0;
/**
* Gets the file model to build (with profile activation).
* If not set, model source will be used to load file model.
* Gets the raw model to build. If not set, model source will be used to load raw model.
*
* @return The file model to build or {@code null} if not set.
* @since 4.0.0
* @return The raw model to build or {@code null} if not set.
*/
Model getFileModel();
/**
* Set the file model with profile activation
*
* @param fileModel
* @return This request, never {@code null}.
* @since 4.0.0
*/
ModelBuildingRequest setFileModel(Model fileModel);
/**
* @deprecated rawModel is never set, instead the fileModel is set
*/
@Deprecated
Model getRawModel();
/**
* @deprecated setting the rawModel has no effect, instead the fileModel of phase one will be set
* Set raw model.
*
* @param rawModel
*/
@Deprecated
ModelBuildingRequest setRawModel(Model rawModel);
/**
@ -108,7 +86,7 @@ public interface ModelBuildingRequest {
/**
* Sets the source of the POM to process. Eventually, either {@link #setModelSource(ModelSource)} or
* {@link #setPomPath(Path)} must be set.
* {@link #setPomFile(File)} must be set.
*
* @param modelSource The source of the POM to process, may be {@code null}.
* @return This request, never {@code null}.
@ -120,20 +98,9 @@ public interface ModelBuildingRequest {
*
* @return The POM file of the project or {@code null} if not applicable (i.e. when processing a POM from the
* repository).
* @deprecated Use {@link #getPomPath()} instead.
*/
@Deprecated
File getPomFile();
/**
* Gets the POM file of the project to build.
*
* @return The POM file of the project or {@code null} if not applicable (i.e. when processing a POM from the
* repository).
* @since 4.0.0
*/
Path getPomPath();
/**
* Sets the POM file of the project to build. Note that providing the path to a POM file via this method will make
* the model builder operate in project mode. This mode is meant for effective models that are employed during the
@ -144,25 +111,9 @@ public interface ModelBuildingRequest {
* @param pomFile The POM file of the project to build the effective model for, may be {@code null} to build the
* model of some POM from the repository.
* @return This request, never {@code null}.
* @deprecated Use {@link #setPomPath(Path)} instead.
*/
@Deprecated
ModelBuildingRequest setPomFile(File pomFile);
/**
* Sets the POM file of the project to build. Note that providing the path to a POM file via this method will make
* the model builder operate in project mode. This mode is meant for effective models that are employed during the
* build process of a local project. Hence the effective model will support the notion of a project directory. To
* build the model for a POM from the repository, use {@link #setModelSource(ModelSource)} in combination with a
* {@link FileModelSource} instead.
*
* @param pomPath The POM file of the project to build the effective model for, may be {@code null} to build the
* model of some POM from the repository.
* @return This request, never {@code null}.
* @since 4.0.0
*/
ModelBuildingRequest setPomPath(Path pomPath);
/**
* Gets the level of validation to perform on processed models.
*
@ -382,12 +333,4 @@ public interface ModelBuildingRequest {
WorkspaceModelResolver getWorkspaceModelResolver();
ModelBuildingRequest setWorkspaceModelResolver(WorkspaceModelResolver workspaceResolver);
TransformerContextBuilder getTransformerContextBuilder();
ModelBuildingRequest setTransformerContextBuilder(TransformerContextBuilder contextBuilder);
Path getRootDirectory();
ModelBuildingRequest setRootDirectory(Path rootDirectory);
}

View File

@ -33,21 +33,14 @@ public interface ModelBuildingResult {
/**
* Gets the sequence of model identifiers that denote the lineage of models from which the effective model was
* constructed. Model identifiers should be handled as "opaque strings" and this method should be used as source
* if navigating the linage. The first identifier from the list denotes the model on which the model builder
* was originally invoked. The last identifier will always be the super POM.
* constructed. Model identifiers have the form {@code <groupId>:<artifactId>:<version>}. The first identifier from
* the list denotes the model on which the model builder was originally invoked. The last identifier will always be
* an empty string that by definition denotes the super POM.
*
* @return The model identifiers from the lineage of models, never {@code null}.
*/
List<String> getModelIds();
/**
*
* @return the file model
* @since 4.0.0
*/
Model getFileModel();
/**
* Gets the assembled model.
*
@ -66,9 +59,9 @@ public interface ModelBuildingResult {
/**
* Gets the specified raw model as it was read from a model source. Apart from basic validation, a raw model has not
* undergone any updates by the model builder, e.g. reflects neither inheritance nor interpolation. The model
* identifier should be from the collection obtained by {@link #getModelIds()}.
* identifier should be from the collection obtained by {@link #getModelIds()}. As a special case, an empty string
* can be used as the identifier for the super POM.
*
* @see #getModelIds()
* @param modelId The identifier of the desired raw model, must not be {@code null}.
* @return The raw model or {@code null} if the specified model id does not refer to a known model.
*/
@ -76,9 +69,9 @@ public interface ModelBuildingResult {
/**
* Gets the profiles from the specified model that were active during model building. The model identifier should be
* from the collection obtained by {@link #getModelIds()}.
* from the collection obtained by {@link #getModelIds()}. As a special case, an empty string can be used as the
* identifier for the super POM.
*
* @see #getModelIds()
* @param modelId The identifier of the model whose active profiles should be retrieved, must not be {@code null}.
* @return The active profiles of the model or an empty list if none or {@code null} if the specified model id does
* not refer to a known model.

View File

@ -18,15 +18,11 @@
*/
package org.apache.maven.model.building;
import java.util.function.Supplier;
import org.apache.maven.building.Source;
/**
* Caches auxiliary data used during model building like already processed raw/effective models. The data in the cache
* is meant for exclusive consumption by the model builder and is opaque to the cache implementation. The cache key is
* formed by a combination of group id, artifact id, version and tag. The first three components generally refer to the
* identity of a model. The tag allows for further classification of the associated data on the sole discretion of the
* identify of a model. The tag allows for further classification of the associated data on the sole discretion of the
* model builder.
*
* @deprecated use {@link org.apache.maven.api.services.ModelBuilder} instead
@ -34,7 +30,25 @@ import org.apache.maven.building.Source;
@Deprecated(since = "4.0.0")
public interface ModelCache {
<T> T computeIfAbsent(String groupId, String artifactId, String version, String tag, Supplier<T> data);
/**
* Puts the specified data into the cache.
*
* @param groupId The group id of the cache record, must not be {@code null}.
* @param artifactId The artifact id of the cache record, must not be {@code null}.
* @param version The version of the cache record, must not be {@code null}.
* @param tag The tag of the cache record, must not be {@code null}.
* @param data The data to store in the cache, must not be {@code null}.
*/
void put(String groupId, String artifactId, String version, String tag, Object data);
<T> T computeIfAbsent(Source path, String tag, Supplier<T> data);
/**
* Gets the specified data from the cache.
*
* @param groupId The group id of the cache record, must not be {@code null}.
* @param artifactId The artifact id of the cache record, must not be {@code null}.
* @param version The version of the cache record, must not be {@code null}.
* @param tag The tag of the cache record, must not be {@code null}.
* @return The requested data or {@code null} if none was present in the cache.
*/
Object get(String groupId, String artifactId, String version, String tag);
}

View File

@ -18,8 +18,8 @@
*/
package org.apache.maven.model.building;
import org.apache.maven.api.model.DependencyManagement;
import org.apache.maven.api.model.Model;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.model.Model;
/**
* Describes a tag used by the model builder to access a {@link ModelCache}. This interface basically aggregates a name
@ -46,7 +46,25 @@ interface ModelCacheTag<T> {
Class<T> getType();
/**
* The tag used for the raw model without profile activation
* Creates a copy of the data suitable for storage in the cache. The original data to store can be mutated after the
* cache is populated but the state of the cache must not change so we need to make a copy.
*
* @param data The data to store in the cache, must not be {@code null}.
* @return The data being stored in the cache, never {@code null}.
*/
T intoCache(T data);
/**
* Creates a copy of the data suitable for retrieval from the cache. The retrieved data can be mutated after the
* cache is queried but the state of the cache must not change so we need to make a copy.
*
* @param data The data to retrieve from the cache, must not be {@code null}.
* @return The data being retrieved from the cache, never {@code null}.
*/
T fromCache(T data);
/**
* The tag used to denote raw model data.
*/
ModelCacheTag<ModelData> RAW = new ModelCacheTag<ModelData>() {
@ -59,6 +77,17 @@ interface ModelCacheTag<T> {
public Class<ModelData> getType() {
return ModelData.class;
}
@Override
public ModelData intoCache(ModelData data) {
Model model = (data.getModel() != null) ? data.getModel().clone() : null;
return new ModelData(data.getSource(), model, data.getGroupId(), data.getArtifactId(), data.getVersion());
}
@Override
public ModelData fromCache(ModelData data) {
return intoCache(data);
}
};
/**
@ -75,21 +104,15 @@ interface ModelCacheTag<T> {
public Class<DependencyManagement> getType() {
return DependencyManagement.class;
}
};
/**
* The tag used for the file model without profile activation
* @since 4.0.0
*/
ModelCacheTag<Model> FILE = new ModelCacheTag<Model>() {
@Override
public String getName() {
return "file";
public DependencyManagement intoCache(DependencyManagement data) {
return (data != null) ? data.clone() : null;
}
@Override
public Class<Model> getType() {
return Model.class;
public DependencyManagement fromCache(DependencyManagement data) {
return intoCache(data);
}
};
}

View File

@ -18,10 +18,10 @@
*/
package org.apache.maven.model.building;
import java.util.Objects;
import java.util.List;
import org.apache.maven.building.Source;
import org.apache.maven.model.Model;
import org.apache.maven.model.Profile;
/**
* Holds a model along with some auxiliary information. This internal utility class assists the model builder during POM
@ -31,9 +31,13 @@ import org.apache.maven.model.Model;
*/
@Deprecated(since = "4.0.0")
class ModelData {
private final Source source;
private final ModelSource source;
private final Model model;
private Model model;
private Model rawModel;
private List<Profile> activeProfiles;
private String groupId;
@ -46,7 +50,7 @@ class ModelData {
*
* @param model The model to wrap, may be {@code null}.
*/
ModelData(Source source, Model model) {
ModelData(ModelSource source, Model model) {
this.source = source;
this.model = model;
}
@ -59,15 +63,15 @@ class ModelData {
* @param artifactId The effective artifact identifier of the model, may be {@code null}.
* @param version The effective version of the model, may be {@code null}.
*/
ModelData(Source source, Model model, String groupId, String artifactId, String version) {
ModelData(ModelSource source, Model model, String groupId, String artifactId, String version) {
this.source = source;
this.model = model;
this.groupId = groupId;
this.artifactId = artifactId;
this.version = version;
setGroupId(groupId);
setArtifactId(artifactId);
setVersion(version);
}
public Source getSource() {
public ModelSource getSource() {
return source;
}
@ -80,6 +84,51 @@ class ModelData {
return model;
}
/**
* Sets the model being wrapped.
*
* @param model The model, may be {@code null}.
*/
public void setModel(Model model) {
this.model = model;
}
/**
* Gets the raw model being wrapped.
*
* @return The raw model or {@code null} if not set.
*/
public Model getRawModel() {
return rawModel;
}
/**
* Sets the raw model being wrapped.
*
* @param rawModel The raw model, may be {@code null}.
*/
public void setRawModel(Model rawModel) {
this.rawModel = rawModel;
}
/**
* Gets the active profiles from the model.
*
* @return The active profiles or {@code null} if not set.
*/
public List<Profile> getActiveProfiles() {
return activeProfiles;
}
/**
* Sets the active profiles from the model.
*
* @param activeProfiles The active profiles, may be {@code null}.
*/
public void setActiveProfiles(List<Profile> activeProfiles) {
this.activeProfiles = activeProfiles;
}
/**
* Gets the effective group identifier of the model.
*
@ -89,6 +138,15 @@ class ModelData {
return (groupId != null) ? groupId : "";
}
/**
* Sets the effective group identifier of the model.
*
* @param groupId The effective group identifier of the model, may be {@code null}.
*/
public void setGroupId(String groupId) {
this.groupId = groupId;
}
/**
* Gets the effective artifact identifier of the model.
*
@ -98,6 +156,15 @@ class ModelData {
return (artifactId != null) ? artifactId : "";
}
/**
* Sets the effective artifact identifier of the model.
*
* @param artifactId The effective artifact identifier of the model, may be {@code null}.
*/
public void setArtifactId(String artifactId) {
this.artifactId = artifactId;
}
/**
* Gets the effective version of the model.
*
@ -108,13 +175,29 @@ class ModelData {
}
/**
* Gets unique identifier of the model
* Sets the effective version of the model.
*
* @param version The effective version of the model, may be {@code null}.
*/
public void setVersion(String version) {
this.version = version;
}
/**
* Gets the effective identifier of the model in the form {@code <groupId>:<artifactId>:<version>}.
*
* @return The effective identifier of the model, never {@code null}.
*/
public String getId() {
// if source is null, it is the super model, which can be accessed via empty string
return Objects.toString(source, "");
StringBuilder buffer = new StringBuilder(128);
buffer.append(getGroupId())
.append(':')
.append(getArtifactId())
.append(':')
.append(getVersion());
return buffer.toString();
}
@Override

View File

@ -51,9 +51,10 @@ public interface ModelProblem {
}
/**
* Gets the identifier of the model from which the problem originated. The identifier is derived from the
* information that is available at the point the problem occurs and as such merely serves as best effort
* to provide information to the user to track the problem back to its origin.
* Gets the hint about the source of the problem. While the syntax of this hint is unspecified and depends on the
* creator of the problem, the general expectation is that the hint provides sufficient information to the user to
* track the problem back to its origin. A concrete example for such a source hint can be the file path or URL from
* which a POM was read.
*
* @return The hint about the source of the problem or an empty string if unknown, never {@code null}.
*/

View File

@ -18,16 +18,15 @@
*/
package org.apache.maven.model.building;
import java.nio.file.Path;
import java.io.File;
import org.apache.maven.model.Model;
/**
* Assists in the handling of model problems.
*
* @deprecated use {@link org.apache.maven.api.services.ModelBuilder} instead
* @author Benjamin Bentmann
*/
@Deprecated(since = "4.0.0")
public class ModelProblemUtils {
/**
@ -45,9 +44,9 @@ public class ModelProblemUtils {
buffer.append(toId(model));
Path pomPath = model.getPomPath();
if (pomPath != null) {
buffer.append(" (").append(pomPath).append(')');
File pomFile = model.getPomFile();
if (pomFile != null) {
buffer.append(" (").append(pomFile).append(')');
}
return buffer.toString();
@ -57,10 +56,10 @@ public class ModelProblemUtils {
String path = "";
if (model != null) {
Path pomPath = model.getPomPath();
File pomFile = model.getPomFile();
if (pomPath != null) {
path = pomPath.toAbsolutePath().toString();
if (pomFile != null) {
path = pomFile.getAbsolutePath();
}
}
@ -71,10 +70,7 @@ public class ModelProblemUtils {
if (model == null) {
return "";
}
return toId(model.getDelegate());
}
static String toId(org.apache.maven.api.model.Model model) {
String groupId = model.getGroupId();
if (groupId == null && model.getParent() != null) {
groupId = model.getParent().getGroupId();
@ -104,11 +100,11 @@ public class ModelProblemUtils {
static String toId(String groupId, String artifactId, String version) {
StringBuilder buffer = new StringBuilder(128);
buffer.append((groupId != null && !groupId.isEmpty()) ? groupId : "[unknown-group-id]");
buffer.append((groupId != null && groupId.length() > 0) ? groupId : "[unknown-group-id]");
buffer.append(':');
buffer.append((artifactId != null && !artifactId.isEmpty()) ? artifactId : "[unknown-artifact-id]");
buffer.append((artifactId != null && artifactId.length() > 0) ? artifactId : "[unknown-artifact-id]");
buffer.append(':');
buffer.append((version != null && !version.isEmpty()) ? version : "[unknown-version]");
buffer.append((version != null && version.length() > 0) ? version : "[unknown-version]");
return buffer.toString();
}
@ -129,7 +125,7 @@ public class ModelProblemUtils {
if (!problem.getModelId().equals(projectId)) {
buffer.append(problem.getModelId());
if (!problem.getSource().isEmpty()) {
if (problem.getSource().length() > 0) {
if (buffer.length() > 0) {
buffer.append(", ");
}

View File

@ -1,59 +0,0 @@
/*
* 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.model.building;
import org.apache.maven.model.locator.ModelLocator;
/**
* Enhancement to the {@link ModelSource2} to support locating POM files using the {@link ModelLocator}
* when pointing to a directory.
*
* @deprecated use {@link org.apache.maven.api.services.ModelBuilder} instead
*/
@Deprecated(since = "4.0.0")
public interface ModelSource3 extends ModelSource2 {
/**
* Returns model source identified by a path relative to this model source POM. Implementation <strong>MUST</strong>
* accept <code>relPath</code> parameter values that
* <ul>
* <li>use either / or \ file path separator</li>
* <li>have .. parent directory references</li>
* <li>point either at file or directory</li>
* </ul>
* If the given path points at a directory, the provided {@code ModelLocator} will be used
* to find the POM file, else if no locator is provided, a file named 'pom.xml' needs to be
* used by the requested model source.
*
* @param locator locator used to locate the pom file
* @param relPath path of the requested model source relative to this model source POM
* @return related model source or <code>null</code> if no such model source
*/
ModelSource3 getRelatedSource(ModelLocator locator, String relPath);
/**
* When using a ModelSource3, the method with a {@code ModelLocator} argument should
* be used instead.
*
* @deprecated use {@link #getRelatedSource(ModelLocator, String)} instead
*/
@Deprecated
default ModelSource3 getRelatedSource(String relPath) {
return getRelatedSource(null, relPath);
}
}

View File

@ -1,44 +0,0 @@
/*
* 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.model.building;
import java.nio.file.Path;
import org.apache.maven.model.Model;
/**
* The ModelSourceTransformer is a way to transform the local pom while streaming the input.
*
* The {@link #transform(Path, TransformerContext, Model)} method uses a Path on purpose, to ensure the
* local pom is the original source.
*
* @since 4.0.0
* @deprecated use {@link org.apache.maven.api.services.ModelBuilder} instead
*/
@Deprecated(since = "4.0.0")
public interface ModelSourceTransformer {
/**
*
* @param pomFile the pom file, cannot be null
* @param context the context, cannot be null
* @param model the model to transform
* @throws TransformerException if the transformation fails
*/
void transform(Path pomFile, TransformerContext context, Model model) throws TransformerException;
}

View File

@ -49,7 +49,7 @@ public class Result<T> {
* @param model
*/
public static <T> Result<T> success(T model) {
return success(model, Collections.emptyList());
return success(model, Collections.<ModelProblem>emptyList());
}
/**
@ -91,7 +91,7 @@ public class Result<T> {
}
public static <T> Result<T> error(T model) {
return error(model, Collections.emptyList());
return error(model, Collections.<ModelProblem>emptyList());
}
public static <T> Result<T> error(Result<?> result) {

View File

@ -1,67 +0,0 @@
/*
* 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.model.building;
import java.nio.file.Path;
import org.apache.maven.model.Model;
/**
* Context used to transform a pom file.
*
* @since 4.0.0
* @deprecated use {@link org.apache.maven.api.services.ModelBuilder} instead
*/
@Deprecated(since = "4.0.0")
public interface TransformerContext {
/**
* Key to get the TransformerContext from the SessionData
*/
Object KEY = TransformerContext.class;
/**
* Get the value of the Maven user property.
*/
String getUserProperty(String key);
/**
* Get the model based on the path when resolving the parent based on relativePath.
*
* @param from the requiring model
* @param pomFile the path to the pomFile
* @return the model, otherwise {@code null}
*/
Model getRawModel(Path from, Path pomFile);
/**
* Get the model from the reactor based on the groupId and artifactId when resolving reactor dependencies.
*
* @param from the requiring model
* @param groupId the groupId
* @param artifactId the artifactId
* @return the model, otherwise {@code null}
* @throws IllegalStateException if multiple versions of the same GA are part of the reactor
*/
Model getRawModel(Path from, String groupId, String artifactId);
/**
* Locate the POM file inside the given directory.
*/
Path locate(Path path);
}

View File

@ -1,45 +0,0 @@
/*
* 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.model.building;
/**
* The transformerContextBuilder is responsible for initializing the TransformerContext.
* In case rawModels are missing, it could do new buildingRequests on the ModelBuilder.
*
* @since 4.0.0
* @deprecated use {@link org.apache.maven.api.services.ModelBuilder} instead
*/
@Deprecated(since = "4.0.0")
public interface TransformerContextBuilder {
/**
* This method is used to initialize the TransformerContext
*
* @param request the modelBuildingRequest
* @param problems the problemCollector
* @return the mutable transformerContext
*/
TransformerContext initialize(ModelBuildingRequest request, ModelProblemCollector problems);
/**
* The immutable transformerContext, can be used after the buildplan is finished.
*
* @return the immutable transformerContext
*/
TransformerContext build();
}

View File

@ -21,23 +21,16 @@ package org.apache.maven.model.composition;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
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.Model;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblem;
import org.apache.maven.model.building.ModelProblemCollector;
import org.apache.maven.model.building.ModelProblemCollectorRequest;
/**
* Handles the import of dependency management from other models into the target model.
@ -50,7 +43,7 @@ import org.apache.maven.model.building.ModelProblemCollectorRequest;
public class DefaultDependencyManagementImporter implements DependencyManagementImporter {
@Override
public Model importManagement(
public void importManagement(
Model target,
List<? extends DependencyManagement> sources,
ModelBuildingRequest request,
@ -65,84 +58,20 @@ public class DefaultDependencyManagementImporter implements DependencyManagement
dependencies.put(dependency.getManagementKey(), dependency);
}
} else {
depMgmt = DependencyManagement.newInstance();
depMgmt = new DependencyManagement();
target.setDependencyManagement(depMgmt);
}
Set<String> directDependencies = new HashSet<>(dependencies.keySet());
for (DependencyManagement source : sources) {
for (Dependency dependency : source.getDependencies()) {
String key = dependency.getManagementKey();
Dependency present = dependencies.putIfAbsent(key, dependency);
if (present != null && !equals(dependency, present) && !directDependencies.contains(key)) {
// TODO: https://issues.apache.org/jira/browse/MNG-8004
problems.add(new ModelProblemCollectorRequest(
ModelProblem.Severity.WARNING, ModelProblem.Version.V40)
.setMessage("Ignored POM import for: " + toString(dependency) + " as already imported "
+ toString(present) + ". Add the conflicting managed dependency directly "
+ "to the dependencyManagement section of the POM."));
if (!dependencies.containsKey(key)) {
dependencies.put(key, dependency);
}
}
}
return target.withDependencyManagement(depMgmt.withDependencies(dependencies.values()));
depMgmt.setDependencies(new ArrayList<>(dependencies.values()));
}
return target;
}
private String toString(Dependency dependency) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder
.append(dependency.getGroupId())
.append(":")
.append(dependency.getArtifactId())
.append(":")
.append(dependency.getType());
if (dependency.getClassifier() != null && !dependency.getClassifier().isEmpty()) {
stringBuilder.append(":").append(dependency.getClassifier());
}
stringBuilder
.append(":")
.append(dependency.getVersion())
.append("@")
.append(dependency.getScope() == null ? "compile" : dependency.getScope());
if (dependency.isOptional()) {
stringBuilder.append("[optional]");
}
if (!dependency.getExclusions().isEmpty()) {
stringBuilder.append("[").append(dependency.getExclusions().size()).append(" exclusions]");
}
return stringBuilder.toString();
}
private boolean equals(Dependency d1, Dependency d2) {
return Objects.equals(d1.getGroupId(), d2.getGroupId())
&& Objects.equals(d1.getArtifactId(), d2.getArtifactId())
&& Objects.equals(d1.getVersion(), d2.getVersion())
&& Objects.equals(d1.getType(), d2.getType())
&& Objects.equals(d1.getClassifier(), d2.getClassifier())
&& Objects.equals(d1.getScope(), d2.getScope())
&& Objects.equals(d1.getSystemPath(), d2.getSystemPath())
&& Objects.equals(d1.getOptional(), d2.getOptional())
&& equals(d1.getExclusions(), d2.getExclusions());
}
private boolean equals(Collection<Exclusion> ce1, Collection<Exclusion> ce2) {
if (ce1.size() == ce2.size()) {
Iterator<Exclusion> i1 = ce1.iterator();
Iterator<Exclusion> i2 = ce2.iterator();
while (i1.hasNext() && i2.hasNext()) {
if (!equals(i1.next(), i2.next())) {
return false;
}
}
return !i1.hasNext() && !i2.hasNext();
}
return false;
}
private boolean equals(Exclusion e1, Exclusion e2) {
return Objects.equals(e1.getGroupId(), e2.getGroupId())
&& Objects.equals(e1.getArtifactId(), e2.getArtifactId());
}
}

View File

@ -20,8 +20,8 @@ package org.apache.maven.model.composition;
import java.util.List;
import org.apache.maven.api.model.DependencyManagement;
import org.apache.maven.api.model.Model;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblemCollector;
@ -41,7 +41,7 @@ public interface DependencyManagementImporter {
* @param request The model building request that holds further settings, must not be {@code null}.
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
*/
Model importManagement(
void importManagement(
Model target,
List<? extends DependencyManagement> sources,
ModelBuildingRequest request,

View File

@ -26,17 +26,19 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.maven.api.model.InputLocation;
import org.apache.maven.api.model.Model;
import org.apache.maven.api.model.ModelBase;
import org.apache.maven.api.model.Plugin;
import org.apache.maven.api.model.PluginContainer;
import org.apache.maven.api.model.ReportPlugin;
import org.apache.maven.api.model.Reporting;
import org.apache.maven.model.InputLocation;
import org.apache.maven.model.Model;
import org.apache.maven.model.ModelBase;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginContainer;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.model.Reporting;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblemCollector;
import org.apache.maven.model.merge.MavenModelMerger;
import org.codehaus.plexus.util.StringUtils;
/**
* Handles inheritance of model values.
@ -49,20 +51,20 @@ import org.apache.maven.model.merge.MavenModelMerger;
@Deprecated(since = "4.0.0")
public class DefaultInheritanceAssembler implements InheritanceAssembler {
private InheritanceModelMerger merger = new InheritanceModelMerger();
private static final String CHILD_DIRECTORY = "child-directory";
private static final String CHILD_DIRECTORY_PROPERTY = "project.directory";
private final InheritanceModelMerger merger = new InheritanceModelMerger();
@Override
public Model assembleModelInheritance(
public void assembleModelInheritance(
Model child, Model parent, ModelBuildingRequest request, ModelProblemCollector problems) {
Map<Object, Object> hints = new HashMap<>();
String childPath = child.getProperties().getOrDefault(CHILD_DIRECTORY_PROPERTY, child.getArtifactId());
String childPath = child.getProperties().getProperty(CHILD_DIRECTORY_PROPERTY, child.getArtifactId());
hints.put(CHILD_DIRECTORY, childPath);
hints.put(MavenModelMerger.CHILD_PATH_ADJUSTMENT, getChildPathAdjustment(child, parent, childPath));
return merger.merge(child, parent, false, hints);
merger.merge(child, parent, false, hints);
}
/**
@ -98,7 +100,7 @@ public class DefaultInheritanceAssembler implements InheritanceAssembler {
* depending on how the model was constructed (from filesystem or from repository).
*/
if (child.getProjectDirectory() != null) {
childName = child.getProjectDirectory().getFileName().toString();
childName = child.getProjectDirectory().getName();
}
for (String module : parent.getModules()) {
@ -137,17 +139,10 @@ public class DefaultInheritanceAssembler implements InheritanceAssembler {
Object childDirectory = context.get(CHILD_DIRECTORY);
Object childPathAdjustment = context.get(CHILD_PATH_ADJUSTMENT);
boolean isBlankParentUrl = true;
if (parentUrl != null) {
for (int i = 0; i < parentUrl.length(); i++) {
if (!Character.isWhitespace(parentUrl.charAt(i))) {
isBlankParentUrl = false;
}
}
}
if (isBlankParentUrl || childDirectory == null || childPathAdjustment == null || !appendPath) {
if (StringUtils.isBlank(parentUrl)
|| childDirectory == null
|| childPathAdjustment == null
|| !appendPath) {
return parentUrl;
}
@ -169,7 +164,7 @@ public class DefaultInheritanceAssembler implements InheritanceAssembler {
}
private void concatPath(StringBuilder url, String path) {
if (!path.isEmpty()) {
if (path.length() > 0) {
boolean initialUrlEndsWithSlash = url.charAt(url.length() - 1) == '/';
boolean pathStartsWithSlash = path.charAt(0) == '/';
@ -194,12 +189,8 @@ public class DefaultInheritanceAssembler implements InheritanceAssembler {
@Override
protected void mergeModelBase_Properties(
ModelBase.Builder builder,
ModelBase target,
ModelBase source,
boolean sourceDominant,
Map<Object, Object> context) {
Map<String, String> merged = new HashMap<>();
ModelBase target, ModelBase source, boolean sourceDominant, Map<Object, Object> context) {
Properties merged = new Properties();
if (sourceDominant) {
merged.putAll(target.getProperties());
putAll(merged, source.getProperties(), CHILD_DIRECTORY_PROPERTY);
@ -207,15 +198,15 @@ public class DefaultInheritanceAssembler implements InheritanceAssembler {
putAll(merged, source.getProperties(), CHILD_DIRECTORY_PROPERTY);
merged.putAll(target.getProperties());
}
builder.properties(merged);
builder.location(
target.setProperties(merged);
target.setLocation(
"properties",
InputLocation.merge(
target.getLocation("properties"), source.getLocation("properties"), sourceDominant));
}
private void putAll(Map<String, String> s, Map<String, String> t, Object excludeKey) {
for (Map.Entry<String, String> e : t.entrySet()) {
private void putAll(Map<Object, Object> s, Map<Object, Object> t, Object excludeKey) {
for (Map.Entry<Object, Object> e : t.entrySet()) {
if (!e.getKey().equals(excludeKey)) {
s.put(e.getKey(), e.getValue());
}
@ -224,11 +215,7 @@ public class DefaultInheritanceAssembler implements InheritanceAssembler {
@Override
protected void mergePluginContainer_Plugins(
PluginContainer.Builder builder,
PluginContainer target,
PluginContainer source,
boolean sourceDominant,
Map<Object, Object> context) {
PluginContainer target, PluginContainer source, boolean sourceDominant, Map<Object, Object> context) {
List<Plugin> src = source.getPlugins();
if (!src.isEmpty()) {
List<Plugin> tgt = target.getPlugins();
@ -237,10 +224,12 @@ public class DefaultInheritanceAssembler implements InheritanceAssembler {
for (Plugin element : src) {
if (element.isInherited() || !element.getExecutions().isEmpty()) {
// NOTE: Enforce recursive merge to trigger merging/inheritance logic for executions
Plugin plugin = Plugin.newInstance(false);
plugin = mergePlugin(plugin, element, sourceDominant, context);
Plugin plugin = new Plugin();
plugin.setLocation("", element.getLocation(""));
plugin.setGroupId(null);
mergePlugin(plugin, element, sourceDominant, context);
Object key = getPluginKey().apply(plugin);
Object key = getPluginKey(element);
master.put(key, plugin);
}
@ -249,10 +238,10 @@ public class DefaultInheritanceAssembler implements InheritanceAssembler {
Map<Object, List<Plugin>> predecessors = new LinkedHashMap<>();
List<Plugin> pending = new ArrayList<>();
for (Plugin element : tgt) {
Object key = getPluginKey().apply(element);
Object key = getPluginKey(element);
Plugin existing = master.get(key);
if (existing != null) {
element = mergePlugin(element, existing, sourceDominant, context);
mergePlugin(element, existing, sourceDominant, context);
master.put(key, element);
@ -275,58 +264,54 @@ public class DefaultInheritanceAssembler implements InheritanceAssembler {
}
result.addAll(pending);
builder.plugins(result);
target.setPlugins(result);
}
}
@Override
protected Plugin mergePlugin(
Plugin target, Plugin source, boolean sourceDominant, Map<Object, Object> context) {
Plugin.Builder builder = Plugin.newBuilder(target);
protected void mergePlugin(Plugin target, Plugin source, boolean sourceDominant, Map<Object, Object> context) {
if (source.isInherited()) {
mergeConfigurationContainer(builder, target, source, sourceDominant, context);
mergeConfigurationContainer(target, source, sourceDominant, context);
}
mergePlugin_GroupId(builder, target, source, sourceDominant, context);
mergePlugin_ArtifactId(builder, target, source, sourceDominant, context);
mergePlugin_Version(builder, target, source, sourceDominant, context);
mergePlugin_Extensions(builder, target, source, sourceDominant, context);
mergePlugin_Executions(builder, target, source, sourceDominant, context);
mergePlugin_Dependencies(builder, target, source, sourceDominant, context);
return builder.build();
mergePlugin_GroupId(target, source, sourceDominant, context);
mergePlugin_ArtifactId(target, source, sourceDominant, context);
mergePlugin_Version(target, source, sourceDominant, context);
mergePlugin_Extensions(target, source, sourceDominant, context);
mergePlugin_Dependencies(target, source, sourceDominant, context);
mergePlugin_Executions(target, source, sourceDominant, context);
}
@Override
protected void mergeReporting_Plugins(
Reporting.Builder builder,
Reporting target,
Reporting source,
boolean sourceDominant,
Map<Object, Object> context) {
Reporting target, Reporting source, boolean sourceDominant, Map<Object, Object> context) {
List<ReportPlugin> src = source.getPlugins();
if (!src.isEmpty()) {
List<ReportPlugin> tgt = target.getPlugins();
Map<Object, ReportPlugin> merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2);
for (ReportPlugin element : src) {
Object key = getReportPluginKey(element);
if (element.isInherited()) {
// NOTE: Enforce recursive merge to trigger merging/inheritance logic for executions as well
ReportPlugin plugin = ReportPlugin.newInstance(false);
plugin = mergeReportPlugin(plugin, element, sourceDominant, context);
ReportPlugin plugin = new ReportPlugin();
plugin.setLocation("", element.getLocation(""));
plugin.setGroupId(null);
mergeReportPlugin(plugin, element, sourceDominant, context);
merged.put(getReportPluginKey().apply(element), plugin);
merged.put(key, plugin);
}
}
for (ReportPlugin element : tgt) {
Object key = getReportPluginKey().apply(element);
Object key = getReportPluginKey(element);
ReportPlugin existing = merged.get(key);
if (existing != null) {
element = mergeReportPlugin(element, existing, sourceDominant, context);
mergeReportPlugin(element, existing, sourceDominant, context);
}
merged.put(key, element);
}
builder.plugins(merged.values());
target.setPlugins(new ArrayList<>(merged.values()));
}
}
}

View File

@ -18,7 +18,7 @@
*/
package org.apache.maven.model.inheritance;
import org.apache.maven.api.model.Model;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblemCollector;
@ -41,6 +41,6 @@ public interface InheritanceAssembler {
* @param request The model building request that holds further settings, must not be {@code null}.
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
*/
Model assembleModelInheritance(
void assembleModelInheritance(
Model child, Model parent, ModelBuildingRequest request, ModelProblemCollector problems);
}

View File

@ -20,26 +20,25 @@ package org.apache.maven.model.interpolation;
import javax.inject.Inject;
import java.net.URI;
import java.nio.file.Path;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.maven.api.model.Model;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblemCollector;
import org.apache.maven.model.path.PathTranslator;
import org.apache.maven.model.path.UrlNormalizer;
import org.apache.maven.model.root.RootLocator;
import org.codehaus.plexus.interpolation.AbstractValueSource;
import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
import org.codehaus.plexus.interpolation.MapBasedValueSource;
import org.codehaus.plexus.interpolation.ObjectBasedValueSource;
import org.codehaus.plexus.interpolation.PrefixAwareRecursionInterceptor;
import org.codehaus.plexus.interpolation.PrefixedObjectValueSource;
import org.codehaus.plexus.interpolation.PrefixedValueSourceWrapper;
import org.codehaus.plexus.interpolation.RecursionInterceptor;
import org.codehaus.plexus.interpolation.ValueSource;
@ -51,10 +50,7 @@ import org.codehaus.plexus.interpolation.ValueSource;
*/
@Deprecated(since = "4.0.0")
public abstract class AbstractStringBasedModelInterpolator implements ModelInterpolator {
private static final String PREFIX_PROJECT = "project.";
private static final String PREFIX_POM = "pom.";
private static final List<String> PROJECT_PREFIXES_3_1 = Arrays.asList(PREFIX_POM, PREFIX_PROJECT);
private static final List<String> PROJECT_PREFIXES_4_0 = Collections.singletonList(PREFIX_PROJECT);
private static final List<String> PROJECT_PREFIXES = Arrays.asList("pom.", "project.");
private static final Collection<String> TRANSLATED_PATH_EXPRESSIONS;
@ -77,68 +73,47 @@ public abstract class AbstractStringBasedModelInterpolator implements ModelInter
TRANSLATED_PATH_EXPRESSIONS = translatedPrefixes;
}
private final PathTranslator pathTranslator;
private final UrlNormalizer urlNormalizer;
private final RootLocator rootLocator;
@Inject
private PathTranslator pathTranslator;
@Inject
public AbstractStringBasedModelInterpolator(
PathTranslator pathTranslator, UrlNormalizer urlNormalizer, RootLocator rootLocator) {
private UrlNormalizer urlNormalizer;
@Inject
private ModelVersionProcessor versionProcessor;
public AbstractStringBasedModelInterpolator() {}
public AbstractStringBasedModelInterpolator setPathTranslator(PathTranslator pathTranslator) {
this.pathTranslator = pathTranslator;
return this;
}
public AbstractStringBasedModelInterpolator setUrlNormalizer(UrlNormalizer urlNormalizer) {
this.urlNormalizer = urlNormalizer;
this.rootLocator = rootLocator;
return this;
}
@Override
public org.apache.maven.model.Model interpolateModel(
org.apache.maven.model.Model model,
java.io.File projectDir,
ModelBuildingRequest request,
ModelProblemCollector problems) {
return new org.apache.maven.model.Model(interpolateModel(
model.getDelegate(), projectDir != null ? projectDir.toPath() : null, request, problems));
}
@Override
public org.apache.maven.model.Model interpolateModel(
org.apache.maven.model.Model model,
Path projectDir,
ModelBuildingRequest request,
ModelProblemCollector problems) {
return new org.apache.maven.model.Model(interpolateModel(model.getDelegate(), projectDir, request, problems));
}
protected List<String> getProjectPrefixes(ModelBuildingRequest config) {
return config.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_4_0
? PROJECT_PREFIXES_4_0
: PROJECT_PREFIXES_3_1;
public AbstractStringBasedModelInterpolator setVersionPropertiesProcessor(ModelVersionProcessor processor) {
this.versionProcessor = processor;
return this;
}
protected List<ValueSource> createValueSources(
final Model model,
final Path projectDir,
final File projectDir,
final ModelBuildingRequest config,
ModelProblemCollector problems) {
Map<String, String> modelProperties = model.getProperties();
final ModelProblemCollector problems) {
Properties modelProperties = model.getProperties();
ValueSource projectPrefixValueSource;
ValueSource prefixlessObjectBasedValueSource;
if (config.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_4_0) {
projectPrefixValueSource = new PrefixedObjectValueSource(PROJECT_PREFIXES_4_0, model, false);
prefixlessObjectBasedValueSource = new ObjectBasedValueSource(model);
} else {
projectPrefixValueSource = new PrefixedObjectValueSource(PROJECT_PREFIXES_3_1, model, false);
if (config.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) {
projectPrefixValueSource =
new ProblemDetectingValueSource(projectPrefixValueSource, PREFIX_POM, PREFIX_PROJECT, problems);
}
ValueSource modelValueSource1 = new PrefixedObjectValueSource(PROJECT_PREFIXES, model, false);
if (config.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) {
modelValueSource1 = new ProblemDetectingValueSource(modelValueSource1, "pom.", "project.", problems);
}
prefixlessObjectBasedValueSource = new ObjectBasedValueSource(model);
if (config.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) {
prefixlessObjectBasedValueSource =
new ProblemDetectingValueSource(prefixlessObjectBasedValueSource, "", PREFIX_PROJECT, problems);
}
ValueSource modelValueSource2 = new ObjectBasedValueSource(model);
if (config.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) {
modelValueSource2 = new ProblemDetectingValueSource(modelValueSource2, "", "project.", problems);
}
// NOTE: Order counts here!
@ -150,16 +125,12 @@ public abstract class AbstractStringBasedModelInterpolator implements ModelInter
@Override
public Object getValue(String expression) {
if ("basedir".equals(expression)) {
return projectDir.toAbsolutePath().toString();
} else if (expression.startsWith("basedir.")) {
Path basedir = projectDir.toAbsolutePath();
return new ObjectBasedValueSource(basedir)
.getValue(expression.substring("basedir.".length()));
return projectDir.getAbsolutePath();
}
return null;
}
},
getProjectPrefixes(config),
PROJECT_PREFIXES,
true);
valueSources.add(basedirValueSource);
@ -168,42 +139,28 @@ public abstract class AbstractStringBasedModelInterpolator implements ModelInter
@Override
public Object getValue(String expression) {
if ("baseUri".equals(expression)) {
return projectDir.toAbsolutePath().toUri().toASCIIString();
} else if (expression.startsWith("baseUri.")) {
URI baseUri = projectDir.toAbsolutePath().toUri();
return new ObjectBasedValueSource(baseUri)
.getValue(expression.substring("baseUri.".length()));
return projectDir
.getAbsoluteFile()
.toPath()
.toUri()
.toASCIIString();
}
return null;
}
},
getProjectPrefixes(config),
PROJECT_PREFIXES,
false);
valueSources.add(baseUriValueSource);
valueSources.add(new BuildTimestampValueSource(config.getBuildStartTime(), modelProperties));
}
valueSources.add(new PrefixedValueSourceWrapper(
new AbstractValueSource(false) {
@Override
public Object getValue(String expression) {
if ("rootDirectory".equals(expression)) {
Path root = rootLocator.findMandatoryRoot(projectDir);
return root.toFile().getPath();
} else if (expression.startsWith("rootDirectory.")) {
Path root = rootLocator.findMandatoryRoot(projectDir);
return new ObjectBasedValueSource(root)
.getValue(expression.substring("rootDirectory.".length()));
}
return null;
}
},
getProjectPrefixes(config)));
valueSources.add(projectPrefixValueSource);
valueSources.add(modelValueSource1);
valueSources.add(new MapBasedValueSource(config.getUserProperties()));
// Overwrite existing values in model properties. Otherwise it's not possible
// to define them via command line e.g.: mvn -Drevision=6.5.7 ...
versionProcessor.overwriteModelProperties(modelProperties, config);
valueSources.add(new MapBasedValueSource(modelProperties));
valueSources.add(new MapBasedValueSource(config.getSystemProperties()));
@ -215,23 +172,24 @@ public abstract class AbstractStringBasedModelInterpolator implements ModelInter
}
});
valueSources.add(prefixlessObjectBasedValueSource);
valueSources.add(modelValueSource2);
return valueSources;
}
protected List<? extends InterpolationPostProcessor> createPostProcessors(
final Model model, final Path projectDir, final ModelBuildingRequest config) {
final Model model, final File projectDir, final ModelBuildingRequest config) {
List<InterpolationPostProcessor> processors = new ArrayList<>(2);
if (projectDir != null) {
processors.add(new PathTranslatingPostProcessor(
getProjectPrefixes(config), TRANSLATED_PATH_EXPRESSIONS, projectDir, pathTranslator));
PROJECT_PREFIXES, TRANSLATED_PATH_EXPRESSIONS,
projectDir, pathTranslator));
}
processors.add(new UrlNormalizingPostProcessor(urlNormalizer));
return processors;
}
protected RecursionInterceptor createRecursionInterceptor(ModelBuildingRequest config) {
return new PrefixAwareRecursionInterceptor(getProjectPrefixes(config));
protected RecursionInterceptor createRecursionInterceptor() {
return new PrefixAwareRecursionInterceptor(PROJECT_PREFIXES);
}
}

View File

@ -19,7 +19,7 @@
package org.apache.maven.model.interpolation;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import org.codehaus.plexus.interpolation.AbstractValueSource;
@ -28,19 +28,17 @@ import org.codehaus.plexus.interpolation.AbstractValueSource;
*/
@Deprecated(since = "4.0.0")
class BuildTimestampValueSource extends AbstractValueSource {
private final Date startTime;
private final Map<String, String> properties;
private final MavenBuildTimestamp mavenBuildTimestamp;
BuildTimestampValueSource(Date startTime, Map<String, String> properties) {
BuildTimestampValueSource(Date startTime, Properties properties) {
super(false);
this.startTime = startTime;
this.properties = properties;
this.mavenBuildTimestamp = new MavenBuildTimestamp(startTime, properties);
}
@Override
public Object getValue(String expression) {
if ("build.timestamp".equals(expression) || "maven.build.timestamp".equals(expression)) {
return new MavenBuildTimestamp(startTime, properties).formattedTimestamp();
return mavenBuildTimestamp.formattedTimestamp();
}
return null;
}

View File

@ -21,7 +21,6 @@ package org.apache.maven.model.interpolation;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.Properties;
import java.util.TimeZone;
@ -49,16 +48,6 @@ public class MavenBuildTimestamp {
this(time, DEFAULT_BUILD_TIMESTAMP_FORMAT);
}
public MavenBuildTimestamp(Date time, Map<String, String> properties) {
this(time, properties != null ? properties.get(BUILD_TIMESTAMP_FORMAT_PROPERTY) : null);
}
/**
*
* @deprecated Use {@link #MavenBuildTimestamp(Date, Map)} or extract the format and pass it
* to {@link #MavenBuildTimestamp(Date, String)} instead.
*/
@Deprecated
public MavenBuildTimestamp(Date time, Properties properties) {
this(time, properties != null ? properties.getProperty(BUILD_TIMESTAMP_FORMAT_PROPERTY) : null);
}

View File

@ -19,7 +19,6 @@
package org.apache.maven.model.interpolation;
import java.io.File;
import java.nio.file.Path;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.ModelBuildingRequest;
@ -45,39 +44,6 @@ public interface ModelInterpolator {
* @param request The model building request that holds further settings, must not be {@code null}.
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
* @return The interpolated model, never {@code null}.
* @deprecated Use {@link #interpolateModel(Model, Path, ModelBuildingRequest, ModelProblemCollector)} instead.
*/
@Deprecated
Model interpolateModel(Model model, File projectDir, ModelBuildingRequest request, ModelProblemCollector problems);
@Deprecated
org.apache.maven.api.model.Model interpolateModel(
org.apache.maven.api.model.Model model,
File projectDir,
ModelBuildingRequest request,
ModelProblemCollector problems);
/**
* Interpolates expressions in the specified model. Note that implementations are free to either interpolate the
* provided model directly or to create a clone of the model and interpolate the clone. Callers should always use
* the returned model and must not rely on the input model being updated.
*
* @param model The model to interpolate, must not be {@code null}.
* @param projectDir The project directory, may be {@code null} if the model does not belong to a local project but
* to some artifact's metadata.
* @param request The model building request that holds further settings, must not be {@code null}.
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
* @return The interpolated model, never {@code null}.
* @since 4.0.0
*/
Model interpolateModel(Model model, Path projectDir, ModelBuildingRequest request, ModelProblemCollector problems);
/**
* @since 4.0.0
*/
org.apache.maven.api.model.Model interpolateModel(
org.apache.maven.api.model.Model model,
Path projectDir,
ModelBuildingRequest request,
ModelProblemCollector problems);
}

View File

@ -18,7 +18,7 @@
*/
package org.apache.maven.model.interpolation;
import java.nio.file.Path;
import java.io.File;
import java.util.Collection;
import java.util.List;
@ -34,14 +34,14 @@ import org.codehaus.plexus.interpolation.util.ValueSourceUtils;
class PathTranslatingPostProcessor implements InterpolationPostProcessor {
private final Collection<String> unprefixedPathKeys;
private final Path projectDir;
private final File projectDir;
private final PathTranslator pathTranslator;
private final List<String> expressionPrefixes;
PathTranslatingPostProcessor(
List<String> expressionPrefixes,
Collection<String> unprefixedPathKeys,
Path projectDir,
File projectDir,
PathTranslator pathTranslator) {
this.expressionPrefixes = expressionPrefixes;
this.unprefixedPathKeys = unprefixedPathKeys;

View File

@ -56,7 +56,7 @@ class ProblemDetectingValueSource implements ValueSource {
if (value != null && expression.startsWith(bannedPrefix)) {
String msg = "The expression ${" + expression + "} is deprecated.";
if (newPrefix != null && !newPrefix.isEmpty()) {
if (newPrefix != null && newPrefix.length() > 0) {
msg += " Please use ${" + newPrefix + expression.substring(bannedPrefix.length()) + "} instead.";
}
problems.add(new ModelProblemCollectorRequest(Severity.WARNING, Version.V20).setMessage(msg));

View File

@ -0,0 +1,398 @@
/*
* 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.model.interpolation;
import java.io.File;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.maven.model.InputLocation;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblem.Severity;
import org.apache.maven.model.building.ModelProblem.Version;
import org.apache.maven.model.building.ModelProblemCollector;
import org.apache.maven.model.building.ModelProblemCollectorRequest;
import org.codehaus.plexus.interpolation.InterpolationException;
import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
import org.codehaus.plexus.interpolation.RecursionInterceptor;
import org.codehaus.plexus.interpolation.StringSearchInterpolator;
import org.codehaus.plexus.interpolation.ValueSource;
/**
* StringSearchModelInterpolator
* @deprecated replaced by StringVisitorModelInterpolator (MNG-6697)
*/
@Deprecated
public class StringSearchModelInterpolator extends AbstractStringBasedModelInterpolator {
private static final Map<Class<?>, InterpolateObjectAction.CacheItem> CACHED_ENTRIES =
new ConcurrentHashMap<>(80, 0.75f, 2);
// Empirical data from 3.x, actual =40
private interface InnerInterpolator {
String interpolate(String value);
}
@Override
public Model interpolateModel(
Model model, File projectDir, ModelBuildingRequest config, ModelProblemCollector problems) {
interpolateObject(model, model, projectDir, config, problems);
return model;
}
void interpolateObject(
Object obj, Model model, File projectDir, ModelBuildingRequest config, ModelProblemCollector problems) {
List<? extends ValueSource> valueSources = createValueSources(model, projectDir, config, problems);
List<? extends InterpolationPostProcessor> postProcessors = createPostProcessors(model, projectDir, config);
InnerInterpolator innerInterpolator = createInterpolator(valueSources, postProcessors, problems);
new InterpolateObjectAction(obj, innerInterpolator, problems).run();
}
private InnerInterpolator createInterpolator(
List<? extends ValueSource> valueSources,
List<? extends InterpolationPostProcessor> postProcessors,
final ModelProblemCollector problems) {
final Map<String, String> cache = new HashMap<>();
final StringSearchInterpolator interpolator = new StringSearchInterpolator();
interpolator.setCacheAnswers(true);
for (ValueSource vs : valueSources) {
interpolator.addValueSource(vs);
}
for (InterpolationPostProcessor postProcessor : postProcessors) {
interpolator.addPostProcessor(postProcessor);
}
final RecursionInterceptor recursionInterceptor = createRecursionInterceptor();
return new InnerInterpolator() {
@Override
public String interpolate(String value) {
if (value != null && value.contains("${")) {
String c = cache.get(value);
if (c == null) {
try {
c = interpolator.interpolate(value, recursionInterceptor);
} catch (InterpolationException e) {
problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
.setMessage(e.getMessage())
.setException(e));
}
cache.put(value, c);
}
return c;
}
return value;
}
};
}
private static final class InterpolateObjectAction {
private final LinkedList<Object> interpolationTargets;
private final InnerInterpolator interpolator;
private final ModelProblemCollector problems;
InterpolateObjectAction(Object target, InnerInterpolator interpolator, ModelProblemCollector problems) {
this.interpolationTargets = new LinkedList<>();
interpolationTargets.add(target);
this.interpolator = interpolator;
this.problems = problems;
}
public Object run() {
while (!interpolationTargets.isEmpty()) {
Object obj = interpolationTargets.removeFirst();
traverseObjectWithParents(obj.getClass(), obj);
}
return null;
}
private String interpolate(String value) {
return interpolator.interpolate(value);
}
private void traverseObjectWithParents(Class<?> cls, Object target) {
if (cls == null) {
return;
}
CacheItem cacheEntry = getCacheEntry(cls);
if (cacheEntry.isArray()) {
evaluateArray(target, this);
} else if (cacheEntry.isQualifiedForInterpolation) {
cacheEntry.interpolate(target, this);
traverseObjectWithParents(cls.getSuperclass(), target);
}
}
private CacheItem getCacheEntry(Class<?> cls) {
CacheItem cacheItem = CACHED_ENTRIES.get(cls);
if (cacheItem == null) {
cacheItem = new CacheItem(cls);
CACHED_ENTRIES.put(cls, cacheItem);
}
return cacheItem;
}
private static void evaluateArray(Object target, InterpolateObjectAction ctx) {
int len = Array.getLength(target);
for (int i = 0; i < len; i++) {
Object value = Array.get(target, i);
if (value != null) {
if (String.class == value.getClass()) {
String interpolated = ctx.interpolate((String) value);
if (!interpolated.equals(value)) {
Array.set(target, i, interpolated);
}
} else {
ctx.interpolationTargets.add(value);
}
}
}
}
private static class CacheItem {
private final boolean isArray;
private final boolean isQualifiedForInterpolation;
private final CacheField[] fields;
private boolean isQualifiedForInterpolation(Class<?> cls) {
Package pkg = cls.getPackage();
if (pkg == null) {
return true;
}
String pkgName = pkg.getName();
return !pkgName.startsWith("java.") && !pkgName.startsWith("javax.");
}
private boolean isQualifiedForInterpolation(Field field, Class<?> fieldType) {
if (Map.class.equals(fieldType) && "locations".equals(field.getName())) {
return false;
}
if (InputLocation.class.equals(fieldType)) {
return false;
}
//noinspection SimplifiableIfStatement
if (fieldType.isPrimitive()) {
return false;
}
return !"parent".equals(field.getName());
}
CacheItem(Class clazz) {
this.isQualifiedForInterpolation = isQualifiedForInterpolation(clazz);
this.isArray = clazz.isArray();
List<CacheField> fields = new ArrayList<>();
if (isQualifiedForInterpolation) {
for (Field currentField : clazz.getDeclaredFields()) {
Class<?> type = currentField.getType();
if (isQualifiedForInterpolation(currentField, type)) {
if (String.class == type) {
if (!Modifier.isFinal(currentField.getModifiers())) {
fields.add(new StringField(currentField));
}
} else if (List.class.isAssignableFrom(type)) {
fields.add(new ListField(currentField));
} else if (Collection.class.isAssignableFrom(type)) {
throw new RuntimeException("We dont interpolate into collections, use a list instead");
} else if (Map.class.isAssignableFrom(type)) {
fields.add(new MapField(currentField));
} else {
fields.add(new ObjectField(currentField));
}
}
}
}
this.fields = fields.toArray(new CacheField[0]);
}
void interpolate(Object target, InterpolateObjectAction interpolateObjectAction) {
for (CacheField field : fields) {
field.interpolate(target, interpolateObjectAction);
}
}
boolean isArray() {
return isArray;
}
}
abstract static class CacheField {
final Field field;
CacheField(Field field) {
this.field = field;
field.setAccessible(true);
}
void interpolate(Object target, InterpolateObjectAction interpolateObjectAction) {
try {
doInterpolate(target, interpolateObjectAction);
} catch (IllegalArgumentException e) {
interpolateObjectAction.problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
.setMessage("Failed to interpolate field3: " + field + " on class: "
+ field.getType().getName())
.setException(e)); // TODO Not entirely the same message
} catch (IllegalAccessException e) {
interpolateObjectAction.problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
.setMessage("Failed to interpolate field4: " + field + " on class: "
+ field.getType().getName())
.setException(e));
}
}
abstract void doInterpolate(Object target, InterpolateObjectAction ctx) throws IllegalAccessException;
}
static final class StringField extends CacheField {
StringField(Field field) {
super(field);
}
@Override
void doInterpolate(Object target, InterpolateObjectAction ctx) throws IllegalAccessException {
String value = (String) field.get(target);
if (value == null) {
return;
}
String interpolated = ctx.interpolate(value);
if (interpolated != null && !interpolated.equals(value)) {
field.set(target, interpolated);
}
}
}
static final class ListField extends CacheField {
ListField(Field field) {
super(field);
}
@Override
void doInterpolate(Object target, InterpolateObjectAction ctx) throws IllegalAccessException {
@SuppressWarnings("unchecked")
List<Object> c = (List<Object>) field.get(target);
if (c == null) {
return;
}
for (int i = 0, size = c.size(); i < size; i++) {
Object value = c.get(i);
if (value != null) {
if (String.class == value.getClass()) {
String interpolated = ctx.interpolate((String) value);
if (!interpolated.equals(value)) {
try {
c.set(i, interpolated);
} catch (UnsupportedOperationException e) {
return;
}
}
} else {
if (value.getClass().isArray()) {
evaluateArray(value, ctx);
} else {
ctx.interpolationTargets.add(value);
}
}
}
}
}
}
static final class MapField extends CacheField {
MapField(Field field) {
super(field);
}
@Override
void doInterpolate(Object target, InterpolateObjectAction ctx) throws IllegalAccessException {
@SuppressWarnings("unchecked")
Map<Object, Object> m = (Map<Object, Object>) field.get(target);
if (m == null || m.isEmpty()) {
return;
}
for (Map.Entry<Object, Object> entry : m.entrySet()) {
Object value = entry.getValue();
if (value == null) {
continue;
}
if (String.class == value.getClass()) {
String interpolated = ctx.interpolate((String) value);
if (interpolated != null && !interpolated.equals(value)) {
try {
entry.setValue(interpolated);
} catch (UnsupportedOperationException ignore) {
// nop
}
}
} else if (value.getClass().isArray()) {
evaluateArray(value, ctx);
} else {
ctx.interpolationTargets.add(value);
}
}
}
}
static final class ObjectField extends CacheField {
private final boolean isArray;
ObjectField(Field field) {
super(field);
this.isArray = field.getType().isArray();
}
@Override
void doInterpolate(Object target, InterpolateObjectAction ctx) throws IllegalAccessException {
Object value = field.get(target);
if (value != null) {
if (isArray) {
evaluateArray(value, ctx);
} else {
ctx.interpolationTargets.add(value);
}
}
}
}
}
}

View File

@ -18,62 +18,44 @@
*/
package org.apache.maven.model.io;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.xml.stream.Location;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.Objects;
import org.apache.maven.model.InputSource;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.ModelSourceTransformer;
import org.apache.maven.model.v4.MavenStaxReader;
import org.codehaus.plexus.util.xml.XmlStreamWriter;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.model.io.xpp3.MavenXpp3ReaderEx;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.xml.XmlStreamReader;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
/**
* Handles deserialization of a model from some kind of textual format like XML.
*
* @deprecated use {@link XmlStreamWriter} instead
* @deprecated use {@link org.apache.maven.model.v4.MavenStaxReader} instead
*/
@Named
@Singleton
@Deprecated(since = "4.0.0")
public class DefaultModelReader implements ModelReader {
private final ModelSourceTransformer transformer;
@Inject
public DefaultModelReader(ModelSourceTransformer transformer) {
this.transformer = transformer;
}
@Override
public Model read(File input, Map<String, ?> options) throws IOException {
Objects.requireNonNull(input, "input cannot be null");
return read(input.toPath(), options);
}
@Override
public Model read(Path path, Map<String, ?> options) throws IOException {
Objects.requireNonNull(path, "path cannot be null");
Model model = read(new FileInputStream(input), options);
try (InputStream in = Files.newInputStream(path)) {
Model model = read(in, path, options);
model.setPomFile(input);
model.setPomPath(path);
return model;
}
return model;
}
@Override
@ -81,7 +63,7 @@ public class DefaultModelReader implements ModelReader {
Objects.requireNonNull(input, "input cannot be null");
try (Reader in = input) {
return read(in, null, options);
return read(in, isStrict(options), getSource(options));
}
}
@ -89,8 +71,8 @@ public class DefaultModelReader implements ModelReader {
public Model read(InputStream input, Map<String, ?> options) throws IOException {
Objects.requireNonNull(input, "input cannot be null");
try (InputStream in = input) {
return read(input, null, options);
try (XmlStreamReader in = ReaderFactory.newXmlReader(input)) {
return read(in, isStrict(options), getSource(options));
}
}
@ -104,56 +86,15 @@ public class DefaultModelReader implements ModelReader {
return (InputSource) value;
}
private Path getRootDirectory(Map<String, ?> options) {
Object value = (options != null) ? options.get(ROOT_DIRECTORY) : null;
return (Path) value;
}
private Model read(InputStream input, Path pomFile, Map<String, ?> options) throws IOException {
private Model read(Reader reader, boolean strict, InputSource source) throws IOException {
try {
XMLInputFactory factory = XMLInputFactory.newFactory();
factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
XMLStreamReader parser = factory.createXMLStreamReader(input);
InputSource source = getSource(options);
boolean strict = isStrict(options);
MavenStaxReader mr = new MavenStaxReader();
mr.setAddLocationInformation(source != null);
Model model = new Model(mr.read(parser, strict, source != null ? source.toApiSource() : null));
return model;
} catch (XMLStreamException e) {
Location location = e.getLocation();
throw new ModelParseException(
e.getMessage(),
location != null ? location.getLineNumber() : -1,
location != null ? location.getColumnNumber() : -1,
e);
} catch (Exception e) {
throw new IOException("Unable to transform pom", e);
}
}
private Model read(Reader reader, Path pomFile, Map<String, ?> options) throws IOException {
try {
XMLInputFactory factory = XMLInputFactory.newFactory();
factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
XMLStreamReader parser = factory.createXMLStreamReader(reader);
InputSource source = getSource(options);
boolean strict = isStrict(options);
MavenStaxReader mr = new MavenStaxReader();
mr.setAddLocationInformation(source != null);
Model model = new Model(mr.read(parser, strict, source != null ? source.toApiSource() : null));
return model;
} catch (XMLStreamException e) {
Location location = e.getLocation();
throw new ModelParseException(
e.getMessage(),
location != null ? location.getLineNumber() : -1,
location != null ? location.getColumnNumber() : -1,
e);
} catch (Exception e) {
throw new IOException("Unable to transform pom", e);
if (source != null) {
return new MavenXpp3ReaderEx().read(reader, strict, source);
} else {
return new MavenXpp3Reader().read(reader, strict);
}
} catch (XmlPullParserException e) {
throw new ModelParseException(e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e);
}
}
}

View File

@ -20,25 +20,23 @@ package org.apache.maven.model.io;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.xml.stream.XMLStreamException;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.file.Files;
import java.util.Map;
import java.util.Objects;
import org.apache.maven.api.model.Model;
import org.apache.maven.model.v4.MavenStaxWriter;
import org.codehaus.plexus.util.xml.XmlStreamWriter;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.codehaus.plexus.util.WriterFactory;
/**
* Handles serialization of a model into some kind of textual format like XML.
*
* @deprecated use {@link XmlStreamWriter} instead
* @deprecated use {@link org.apache.maven.model.v4.MavenStaxWriter} instead
*/
@Named
@Singleton
@ -52,7 +50,7 @@ public class DefaultModelWriter implements ModelWriter {
output.getParentFile().mkdirs();
write(new XmlStreamWriter(Files.newOutputStream(output.toPath())), options, model);
write(WriterFactory.newXmlWriter(output), options, model);
}
@Override
@ -61,9 +59,7 @@ public class DefaultModelWriter implements ModelWriter {
Objects.requireNonNull(model, "model cannot be null");
try (Writer out = output) {
new MavenStaxWriter().write(out, model);
} catch (XMLStreamException e) {
throw new IOException(e);
new MavenXpp3Writer().write(out, model);
}
}
@ -73,7 +69,8 @@ public class DefaultModelWriter implements ModelWriter {
Objects.requireNonNull(model, "model cannot be null");
String encoding = model.getModelEncoding();
if (encoding == null || encoding.isEmpty()) {
// TODO Use StringUtils here
if (encoding == null || encoding.length() <= 0) {
encoding = "UTF-8";
}
@ -81,21 +78,4 @@ public class DefaultModelWriter implements ModelWriter {
write(out, options, model);
}
}
@Override
public void write(File output, Map<String, Object> options, org.apache.maven.model.Model model) throws IOException {
write(output, options, model.getDelegate());
}
@Override
public void write(Writer output, Map<String, Object> options, org.apache.maven.model.Model model)
throws IOException {
write(output, options, model.getDelegate());
}
@Override
public void write(OutputStream output, Map<String, Object> options, org.apache.maven.model.Model model)
throws IOException {
write(output, options, model.getDelegate());
}
}

View File

@ -22,7 +22,6 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.file.Path;
import java.util.Map;
import org.apache.maven.model.Model;
@ -48,12 +47,6 @@ public interface ModelReader {
*/
String INPUT_SOURCE = "org.apache.maven.model.io.inputSource";
/**
* Name of the property used to store the project's root directory to use with
* XInclude support.
*/
String ROOT_DIRECTORY = "rootDirectory";
/**
* Reads the model from the specified file.
*
@ -62,22 +55,9 @@ public interface ModelReader {
* @return The deserialized model, never {@code null}.
* @throws IOException If the model could not be deserialized.
* @throws ModelParseException If the input format could not be parsed.
* @deprecated Use {@link #read(Path, Map)} instead.
*/
@Deprecated
Model read(File input, Map<String, ?> options) throws IOException, ModelParseException;
/**
* Reads the model from the specified file.
*
* @param input The file to deserialize the model from, must not be {@code null}.
* @param options The options to use for deserialization, may be {@code null} to use the default values.
* @return The deserialized model, never {@code null}.
* @throws IOException If the model could not be deserialized.
* @throws ModelParseException If the input format could not be parsed.
*/
Model read(Path input, Map<String, ?> options) throws IOException, ModelParseException;
/**
* Reads the model from the specified character reader. The reader will be automatically closed before the method
* returns.

View File

@ -24,7 +24,7 @@ import java.io.OutputStream;
import java.io.Writer;
import java.util.Map;
import org.apache.maven.api.model.Model;
import org.apache.maven.model.Model;
/**
* Handles serialization of a model into some kind of textual format like XML.
@ -66,37 +66,4 @@ public interface ModelWriter {
* @throws IOException If the model could not be serialized.
*/
void write(OutputStream output, Map<String, Object> options, Model model) throws IOException;
/**
* Writes the supplied model to the specified file. Any non-existing parent directories of the output file will be
* created automatically.
*
* @param output The file to serialize the model to, must not be {@code null}.
* @param options The options to use for serialization, may be {@code null} to use the default values.
* @param model The model to serialize, must not be {@code null}.
* @throws IOException If the model could not be serialized.
*/
void write(File output, Map<String, Object> options, org.apache.maven.model.Model model) throws IOException;
/**
* Writes the supplied model to the specified character writer. The writer will be automatically closed before the
* method returns.
*
* @param output The writer to serialize the model to, must not be {@code null}.
* @param options The options to use for serialization, may be {@code null} to use the default values.
* @param model The model to serialize, must not be {@code null}.
* @throws IOException If the model could not be serialized.
*/
void write(Writer output, Map<String, Object> options, org.apache.maven.model.Model model) throws IOException;
/**
* Writes the supplied model to the specified byte stream. The stream will be automatically closed before the method
* returns.
*
* @param output The stream to serialize the model to, must not be {@code null}.
* @param options The options to use for serialization, may be {@code null} to use the default values.
* @param model The model to serialize, must not be {@code null}.
* @throws IOException If the model could not be serialized.
*/
void write(OutputStream output, Map<String, Object> options, org.apache.maven.model.Model model) throws IOException;
}

View File

@ -22,9 +22,6 @@ import javax.inject.Named;
import javax.inject.Singleton;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Locates a POM file within a project base directory.
@ -36,37 +33,8 @@ import java.nio.file.Paths;
@Deprecated(since = "4.0.0")
public class DefaultModelLocator implements ModelLocator {
@Deprecated
@Override
public File locatePom(File projectDirectory) {
Path path = locatePom(projectDirectory != null ? projectDirectory.toPath() : null);
return path != null ? path.toFile() : null;
}
@Override
public Path locatePom(Path projectDirectory) {
return projectDirectory != null ? projectDirectory : Paths.get(System.getProperty("user.dir"));
}
@Deprecated
@Override
public File locateExistingPom(File project) {
Path path = locateExistingPom(project != null ? project.toPath() : null);
return path != null ? path.toFile() : null;
}
@Override
public Path locateExistingPom(Path project) {
if (project == null || Files.isDirectory(project)) {
project = locatePom(project);
}
if (Files.isDirectory(project)) {
Path pom = project.resolve("pom.xml");
return Files.isRegularFile(pom) ? pom : null;
} else if (Files.isRegularFile(project)) {
return project;
} else {
return null;
}
return new File(projectDirectory, "pom.xml");
}
}

View File

@ -19,7 +19,6 @@
package org.apache.maven.model.locator;
import java.io.File;
import java.nio.file.Path;
/**
* Locates a POM file within a project base directory.
@ -31,46 +30,13 @@ public interface ModelLocator {
/**
* Locates the POM file within the specified project directory. In case the given project directory does not exist
* or does not contain a POM file, the return value indicates the expected path to the POM file. Subdirectories of
* or does not contain a POM file, the return value indicates the expected path to the POM file. Sub directories of
* the project directory will not be considered when locating the POM file. The return value will be an absolute
* path if the project directory is given as an absolute path.
*
* @param projectDirectory The (possibly non-existent) base directory to locate the POM file in, must not be {@code
* null}.
* @return The path to the (possibly non-existent) POM file, never {@code null}.
* @deprecated Use {@link #locatePom(Path)} instead.
*/
@Deprecated
File locatePom(File projectDirectory);
/**
* Locates the POM file within the specified project directory. In case the given project directory does not exist
* or does not contain a POM file, the return value indicates the expected path to the POM file. Subdirectories of
* the project directory will not be considered when locating the POM file. The return value will be an absolute
* path if the project directory is given as an absolute path.
*
* @param projectDirectory The (possibly non-existent) base directory to locate the POM file in, must not be {@code
* null}.
* @return The path to the (possibly non-existent) POM file, never {@code null}.
* @since 4.0.0
*/
Path locatePom(Path projectDirectory);
/**
* Returns the file containing the pom or null if a pom can not be found at the given file or in the given directory.
*
* @deprecated Use {@link #locateExistingPom(Path)} instead.
*/
@Deprecated
default File locateExistingPom(File project) {
Path path = locateExistingPom(project != null ? project.toPath() : null);
return path != null ? path.toFile() : null;
}
/**
* Returns the file containing the pom or null if a pom can not be found at the given file or in the given directory.
*
* @since 4.0.0
*/
Path locateExistingPom(Path project);
}

View File

@ -21,16 +21,15 @@ package org.apache.maven.model.management;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.Model;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.model.Exclusion;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblemCollector;
import org.apache.maven.model.merge.MavenModelMerger;
@ -49,9 +48,8 @@ public class DefaultDependencyManagementInjector implements DependencyManagement
private ManagementModelMerger merger = new ManagementModelMerger();
@Override
public void injectManagement(
org.apache.maven.model.Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
model.update(merger.mergeManagedDependencies(model.getDelegate()));
public void injectManagement(Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
merger.mergeManagedDependencies(model);
}
/**
@ -59,64 +57,44 @@ public class DefaultDependencyManagementInjector implements DependencyManagement
*/
protected static class ManagementModelMerger extends MavenModelMerger {
public Model mergeManagedDependencies(Model model) {
public void mergeManagedDependencies(Model model) {
DependencyManagement dependencyManagement = model.getDependencyManagement();
if (dependencyManagement != null) {
Map<Object, Dependency> dependencies = new HashMap<>();
Map<Object, Object> context = Collections.emptyMap();
for (Dependency dependency : model.getDependencies()) {
Object key = getDependencyKey().apply(dependency);
Object key = getDependencyKey(dependency);
dependencies.put(key, dependency);
}
boolean modified = false;
for (Dependency managedDependency : dependencyManagement.getDependencies()) {
Object key = getDependencyKey().apply(managedDependency);
Object key = getDependencyKey(managedDependency);
Dependency dependency = dependencies.get(key);
if (dependency != null) {
Dependency merged = mergeDependency(dependency, managedDependency, false, context);
if (merged != dependency) {
dependencies.put(key, merged);
modified = true;
}
mergeDependency(dependency, managedDependency, false, context);
}
}
if (modified) {
List<Dependency> newDeps = new ArrayList<>(dependencies.size());
for (Dependency dep : model.getDependencies()) {
Object key = getDependencyKey().apply(dep);
Dependency dependency = dependencies.get(key);
newDeps.add(dependency);
}
return Model.newBuilder(model).dependencies(newDeps).build();
}
}
return model;
}
@Override
protected void mergeDependency_Optional(
Dependency.Builder builder,
Dependency target,
Dependency source,
boolean sourceDominant,
Map<Object, Object> context) {
Dependency target, Dependency source, boolean sourceDominant, Map<Object, Object> context) {
// optional flag is not managed
}
@Override
protected void mergeDependency_Exclusions(
Dependency.Builder builder,
Dependency target,
Dependency source,
boolean sourceDominant,
Map<Object, Object> context) {
Dependency target, Dependency source, boolean sourceDominant, Map<Object, Object> context) {
List<Exclusion> tgt = target.getExclusions();
if (tgt.isEmpty()) {
List<Exclusion> src = source.getExclusions();
builder.exclusions(src);
for (Exclusion element : src) {
Exclusion clone = element.clone();
target.addExclusion(clone);
}
}
}
}

View File

@ -27,12 +27,12 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.maven.api.model.Build;
import org.apache.maven.api.model.Model;
import org.apache.maven.api.model.Plugin;
import org.apache.maven.api.model.PluginContainer;
import org.apache.maven.api.model.PluginExecution;
import org.apache.maven.api.model.PluginManagement;
import org.apache.maven.model.Build;
import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginContainer;
import org.apache.maven.model.PluginExecution;
import org.apache.maven.model.PluginManagement;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblemCollector;
import org.apache.maven.model.merge.MavenModelMerger;
@ -51,9 +51,8 @@ public class DefaultPluginManagementInjector implements PluginManagementInjector
private ManagementModelMerger merger = new ManagementModelMerger();
@Override
public void injectManagement(
org.apache.maven.model.Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
model.update(merger.mergeManagedBuildPlugins(model.getDelegate()));
public void injectManagement(Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
merger.mergeManagedBuildPlugins(model);
}
/**
@ -61,50 +60,43 @@ public class DefaultPluginManagementInjector implements PluginManagementInjector
*/
protected static class ManagementModelMerger extends MavenModelMerger {
public Model mergeManagedBuildPlugins(Model model) {
public void mergeManagedBuildPlugins(Model model) {
Build build = model.getBuild();
if (build != null) {
PluginManagement pluginManagement = build.getPluginManagement();
if (pluginManagement != null) {
return model.withBuild(mergePluginContainerPlugins(build, pluginManagement));
mergePluginContainerPlugins(build, pluginManagement);
}
}
return model;
}
private Build mergePluginContainerPlugins(Build target, PluginContainer source) {
private void mergePluginContainerPlugins(PluginContainer target, PluginContainer source) {
List<Plugin> src = source.getPlugins();
if (!src.isEmpty()) {
List<Plugin> tgt = target.getPlugins();
Map<Object, Plugin> managedPlugins = new LinkedHashMap<>(src.size() * 2);
Map<Object, Object> context = Collections.emptyMap();
for (Plugin element : src) {
Object key = getPluginKey().apply(element);
Object key = getPluginKey(element);
managedPlugins.put(key, element);
}
List<Plugin> newPlugins = new ArrayList<>();
for (Plugin element : target.getPlugins()) {
Object key = getPluginKey().apply(element);
for (Plugin element : tgt) {
Object key = getPluginKey(element);
Plugin managedPlugin = managedPlugins.get(key);
if (managedPlugin != null) {
element = mergePlugin(element, managedPlugin, false, context);
mergePlugin(element, managedPlugin, false, context);
}
newPlugins.add(element);
}
return target.withPlugins(newPlugins);
}
return target;
}
@Override
protected void mergePlugin_Executions(
Plugin.Builder builder,
Plugin target,
Plugin source,
boolean sourceDominant,
Map<Object, Object> context) {
Plugin target, Plugin source, boolean sourceDominant, Map<Object, Object> context) {
List<PluginExecution> src = source.getExecutions();
if (!src.isEmpty()) {
List<PluginExecution> tgt = target.getExecutions();
@ -112,20 +104,20 @@ public class DefaultPluginManagementInjector implements PluginManagementInjector
Map<Object, PluginExecution> merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2);
for (PluginExecution element : src) {
Object key = getPluginExecutionKey().apply(element);
merged.put(key, element);
Object key = getPluginExecutionKey(element);
merged.put(key, element.clone());
}
for (PluginExecution element : tgt) {
Object key = getPluginExecutionKey().apply(element);
Object key = getPluginExecutionKey(element);
PluginExecution existing = merged.get(key);
if (existing != null) {
element = mergePluginExecution(element, existing, sourceDominant, context);
mergePluginExecution(element, existing, sourceDominant, context);
}
merged.put(key, element);
}
builder.executions(merged.values());
target.setExecutions(new ArrayList<>(merged.values()));
}
}
}

View File

@ -18,8 +18,34 @@
*/
package org.apache.maven.model.merge;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import org.apache.maven.model.BuildBase;
import org.apache.maven.model.CiManagement;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DeploymentRepository;
import org.apache.maven.model.DistributionManagement;
import org.apache.maven.model.Exclusion;
import org.apache.maven.model.Extension;
import org.apache.maven.model.InputLocation;
import org.apache.maven.model.IssueManagement;
import org.apache.maven.model.Model;
import org.apache.maven.model.ModelBase;
import org.apache.maven.model.Organization;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginExecution;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.model.ReportSet;
import org.apache.maven.model.Repository;
import org.apache.maven.model.RepositoryBase;
import org.apache.maven.model.Scm;
import org.apache.maven.model.Site;
import org.codehaus.plexus.util.StringUtils;
/**
* The domain-specific model merger for the Maven POM, overriding generic code from parent class when necessary with
@ -27,29 +53,533 @@ import java.util.Objects;
*
* @deprecated use {@link org.apache.maven.internal.impl.model.MavenModelMerger} instead
*/
public class MavenModelMerger extends org.apache.maven.internal.impl.model.MavenModelMerger {
@Deprecated(since = "4.0.0")
public class MavenModelMerger extends ModelMerger {
/**
* Merges the specified source object into the given target object.
*
* @param target The target object whose existing contents should be merged with the source, must not be
* <code>null</code>.
* @param source The (read-only) source object that should be merged into the target object, may be
* <code>null</code>.
* @param sourceDominant A flag indicating whether either the target object or the source object provides the
* dominant data.
* @param hints A set of key-value pairs that customized merger implementations can use to carry domain-specific
* information along, may be <code>null</code>.
* The hint key for the child path adjustment used during inheritance for URL calculations.
*/
public void merge(
org.apache.maven.model.Model target,
org.apache.maven.model.Model source,
boolean sourceDominant,
Map<?, ?> hints) {
Objects.requireNonNull(target, "target cannot be null");
if (source == null) {
return;
public static final String CHILD_PATH_ADJUSTMENT = "child-path-adjustment";
/**
* The context key for the artifact id of the target model.
*/
public static final String ARTIFACT_ID = "artifact-id";
@Override
protected void mergeModel(Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
context.put(ARTIFACT_ID, target.getArtifactId());
super.mergeModel(target, source, sourceDominant, context);
}
@Override
protected void mergeModel_Name(Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
String src = source.getName();
if (src != null) {
if (sourceDominant) {
target.setName(src);
target.setLocation("name", source.getLocation("name"));
}
}
target.update(merge(target.getDelegate(), source.getDelegate(), sourceDominant, hints));
}
@Override
protected void mergeModel_Url(Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
String src = source.getUrl();
if (src != null) {
if (sourceDominant) {
target.setUrl(src);
target.setLocation("url", source.getLocation("url"));
} else if (target.getUrl() == null) {
target.setUrl(extrapolateChildUrl(src, source.isChildProjectUrlInheritAppendPath(), context));
target.setLocation("url", source.getLocation("url"));
}
}
}
/*
* TODO: Whether the merge continues recursively into an existing node or not could be an option for the generated
* merger
*/
@Override
protected void mergeModel_Organization(
Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
Organization src = source.getOrganization();
if (src != null) {
Organization tgt = target.getOrganization();
if (tgt == null) {
tgt = new Organization();
tgt.setLocation("", src.getLocation(""));
target.setOrganization(tgt);
mergeOrganization(tgt, src, sourceDominant, context);
}
}
}
@Override
protected void mergeModel_IssueManagement(
Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
IssueManagement src = source.getIssueManagement();
if (src != null) {
IssueManagement tgt = target.getIssueManagement();
if (tgt == null) {
tgt = new IssueManagement();
tgt.setLocation("", src.getLocation(""));
target.setIssueManagement(tgt);
mergeIssueManagement(tgt, src, sourceDominant, context);
}
}
}
@Override
protected void mergeModel_CiManagement(
Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
CiManagement src = source.getCiManagement();
if (src != null) {
CiManagement tgt = target.getCiManagement();
if (tgt == null) {
tgt = new CiManagement();
tgt.setLocation("", src.getLocation(""));
target.setCiManagement(tgt);
mergeCiManagement(tgt, src, sourceDominant, context);
}
}
}
@Override
protected void mergeModel_ModelVersion(
Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
// neither inherited nor injected
}
@Override
protected void mergeModel_ArtifactId(
Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
// neither inherited nor injected
}
@Override
protected void mergeModel_Profiles(
Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
// neither inherited nor injected
}
@Override
protected void mergeModel_Prerequisites(
Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
// neither inherited nor injected
}
@Override
protected void mergeModel_Licenses(
Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
if (target.getLicenses().isEmpty()) {
target.setLicenses(new ArrayList<>(source.getLicenses()));
}
}
@Override
protected void mergeModel_Developers(
Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
if (target.getDevelopers().isEmpty()) {
target.setDevelopers(new ArrayList<>(source.getDevelopers()));
}
}
@Override
protected void mergeModel_Contributors(
Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
if (target.getContributors().isEmpty()) {
target.setContributors(new ArrayList<>(source.getContributors()));
}
}
@Override
protected void mergeModel_MailingLists(
Model target, Model source, boolean sourceDominant, Map<Object, Object> context) {
if (target.getMailingLists().isEmpty()) {
target.setMailingLists(new ArrayList<>(source.getMailingLists()));
}
}
@Override
protected void mergeModelBase_Modules(
ModelBase target, ModelBase source, boolean sourceDominant, Map<Object, Object> context) {
List<String> src = source.getModules();
if (!src.isEmpty() && sourceDominant) {
List<Integer> indices = new ArrayList<>();
List<String> tgt = target.getModules();
Set<String> excludes = new LinkedHashSet<>(tgt);
List<String> merged = new ArrayList<>(tgt.size() + src.size());
merged.addAll(tgt);
for (int i = 0, n = tgt.size(); i < n; i++) {
indices.add(i);
}
for (int i = 0, n = src.size(); i < n; i++) {
String s = src.get(i);
if (!excludes.contains(s)) {
merged.add(s);
indices.add(~i);
}
}
target.setModules(merged);
target.setLocation(
"modules",
InputLocation.merge(target.getLocation("modules"), source.getLocation("modules"), indices));
}
}
/*
* TODO: The order of the merged list could be controlled by an attribute in the model association: target-first,
* source-first, dominant-first, recessive-first
*/
@Override
protected void mergeModelBase_Repositories(
ModelBase target, ModelBase source, boolean sourceDominant, Map<Object, Object> context) {
List<Repository> src = source.getRepositories();
if (!src.isEmpty()) {
List<Repository> tgt = target.getRepositories();
Map<Object, Repository> merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2);
List<Repository> dominant, recessive;
if (sourceDominant) {
dominant = src;
recessive = tgt;
} else {
dominant = tgt;
recessive = src;
}
for (Repository element : dominant) {
Object key = getRepositoryKey(element);
merged.put(key, element);
}
for (Repository element : recessive) {
Object key = getRepositoryKey(element);
if (!merged.containsKey(key)) {
merged.put(key, element);
}
}
target.setRepositories(new ArrayList<>(merged.values()));
}
}
@Override
protected void mergeModelBase_PluginRepositories(
ModelBase target, ModelBase source, boolean sourceDominant, Map<Object, Object> context) {
List<Repository> src = source.getPluginRepositories();
if (!src.isEmpty()) {
List<Repository> tgt = target.getPluginRepositories();
Map<Object, Repository> merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2);
List<Repository> dominant, recessive;
if (sourceDominant) {
dominant = src;
recessive = tgt;
} else {
dominant = tgt;
recessive = src;
}
for (Repository element : dominant) {
Object key = getRepositoryKey(element);
merged.put(key, element);
}
for (Repository element : recessive) {
Object key = getRepositoryKey(element);
if (!merged.containsKey(key)) {
merged.put(key, element);
}
}
target.setPluginRepositories(new ArrayList<>(merged.values()));
}
}
/*
* TODO: Whether duplicates should be removed looks like an option for the generated merger.
*/
@Override
protected void mergeBuildBase_Filters(
BuildBase target, BuildBase source, boolean sourceDominant, Map<Object, Object> context) {
List<String> src = source.getFilters();
if (!src.isEmpty()) {
List<String> tgt = target.getFilters();
Set<String> excludes = new LinkedHashSet<>(tgt);
List<String> merged = new ArrayList<>(tgt.size() + src.size());
merged.addAll(tgt);
for (String s : src) {
if (!excludes.contains(s)) {
merged.add(s);
}
}
target.setFilters(merged);
}
}
@Override
protected void mergeBuildBase_Resources(
BuildBase target, BuildBase source, boolean sourceDominant, Map<Object, Object> context) {
if (sourceDominant || target.getResources().isEmpty()) {
super.mergeBuildBase_Resources(target, source, sourceDominant, context);
}
}
@Override
protected void mergeBuildBase_TestResources(
BuildBase target, BuildBase source, boolean sourceDominant, Map<Object, Object> context) {
if (sourceDominant || target.getTestResources().isEmpty()) {
super.mergeBuildBase_TestResources(target, source, sourceDominant, context);
}
}
@Override
protected void mergeDistributionManagement_Repository(
DistributionManagement target,
DistributionManagement source,
boolean sourceDominant,
Map<Object, Object> context) {
DeploymentRepository src = source.getRepository();
if (src != null) {
DeploymentRepository tgt = target.getRepository();
if (sourceDominant || tgt == null) {
tgt = new DeploymentRepository();
tgt.setLocation("", src.getLocation(""));
target.setRepository(tgt);
mergeDeploymentRepository(tgt, src, sourceDominant, context);
}
}
}
@Override
protected void mergeDistributionManagement_SnapshotRepository(
DistributionManagement target,
DistributionManagement source,
boolean sourceDominant,
Map<Object, Object> context) {
DeploymentRepository src = source.getSnapshotRepository();
if (src != null) {
DeploymentRepository tgt = target.getSnapshotRepository();
if (sourceDominant || tgt == null) {
tgt = new DeploymentRepository();
tgt.setLocation("", src.getLocation(""));
target.setSnapshotRepository(tgt);
mergeDeploymentRepository(tgt, src, sourceDominant, context);
}
}
}
@Override
protected void mergeDistributionManagement_Site(
DistributionManagement target,
DistributionManagement source,
boolean sourceDominant,
Map<Object, Object> context) {
Site src = source.getSite();
if (src != null) {
Site tgt = target.getSite();
if (sourceDominant || tgt == null || isSiteEmpty(tgt)) {
if (tgt == null) {
tgt = new Site();
}
tgt.setLocation("", src.getLocation(""));
target.setSite(tgt);
mergeSite(tgt, src, sourceDominant, context);
}
mergeSite_ChildSiteUrlInheritAppendPath(tgt, src, sourceDominant, context);
}
}
@Override
protected void mergeSite(Site target, Site source, boolean sourceDominant, Map<Object, Object> context) {
mergeSite_Id(target, source, sourceDominant, context);
mergeSite_Name(target, source, sourceDominant, context);
mergeSite_Url(target, source, sourceDominant, context);
}
protected boolean isSiteEmpty(Site site) {
return StringUtils.isEmpty(site.getId())
&& StringUtils.isEmpty(site.getName())
&& StringUtils.isEmpty(site.getUrl());
}
@Override
protected void mergeSite_Url(Site target, Site source, boolean sourceDominant, Map<Object, Object> context) {
String src = source.getUrl();
if (src != null) {
if (sourceDominant) {
target.setUrl(src);
target.setLocation("url", source.getLocation("url"));
} else if (target.getUrl() == null) {
target.setUrl(extrapolateChildUrl(src, source.isChildSiteUrlInheritAppendPath(), context));
target.setLocation("url", source.getLocation("url"));
}
}
}
@Override
protected void mergeScm_Url(Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context) {
String src = source.getUrl();
if (src != null) {
if (sourceDominant) {
target.setUrl(src);
target.setLocation("url", source.getLocation("url"));
} else if (target.getUrl() == null) {
target.setUrl(extrapolateChildUrl(src, source.isChildScmUrlInheritAppendPath(), context));
target.setLocation("url", source.getLocation("url"));
}
}
}
@Override
protected void mergeScm_Connection(Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context) {
String src = source.getConnection();
if (src != null) {
if (sourceDominant) {
target.setConnection(src);
target.setLocation("connection", source.getLocation("connection"));
} else if (target.getConnection() == null) {
target.setConnection(extrapolateChildUrl(src, source.isChildScmConnectionInheritAppendPath(), context));
target.setLocation("connection", source.getLocation("connection"));
}
}
}
@Override
protected void mergeScm_DeveloperConnection(
Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context) {
String src = source.getDeveloperConnection();
if (src != null) {
if (sourceDominant) {
target.setDeveloperConnection(src);
target.setLocation("developerConnection", source.getLocation("developerConnection"));
} else if (target.getDeveloperConnection() == null) {
String e = extrapolateChildUrl(src, source.isChildScmDeveloperConnectionInheritAppendPath(), context);
target.setDeveloperConnection(e);
target.setLocation("developerConnection", source.getLocation("developerConnection"));
}
}
}
@Override
protected void mergePlugin_Executions(
Plugin target, Plugin source, boolean sourceDominant, Map<Object, Object> context) {
List<PluginExecution> src = source.getExecutions();
if (!src.isEmpty()) {
List<PluginExecution> tgt = target.getExecutions();
Map<Object, PluginExecution> merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2);
for (PluginExecution element : src) {
if (sourceDominant || (element.getInherited() != null ? element.isInherited() : source.isInherited())) {
Object key = getPluginExecutionKey(element);
merged.put(key, element);
}
}
for (PluginExecution element : tgt) {
Object key = getPluginExecutionKey(element);
PluginExecution existing = merged.get(key);
if (existing != null) {
mergePluginExecution(element, existing, sourceDominant, context);
}
merged.put(key, element);
}
target.setExecutions(new ArrayList<>(merged.values()));
}
}
@Override
protected void mergePluginExecution_Goals(
PluginExecution target, PluginExecution source, boolean sourceDominant, Map<Object, Object> context) {
List<String> src = source.getGoals();
if (!src.isEmpty()) {
List<String> tgt = target.getGoals();
Set<String> excludes = new LinkedHashSet<>(tgt);
List<String> merged = new ArrayList<>(tgt.size() + src.size());
merged.addAll(tgt);
for (String s : src) {
if (!excludes.contains(s)) {
merged.add(s);
}
}
target.setGoals(merged);
}
}
@Override
protected void mergeReportPlugin_ReportSets(
ReportPlugin target, ReportPlugin source, boolean sourceDominant, Map<Object, Object> context) {
List<ReportSet> src = source.getReportSets();
if (!src.isEmpty()) {
List<ReportSet> tgt = target.getReportSets();
Map<Object, ReportSet> merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2);
for (ReportSet rset : src) {
if (sourceDominant || (rset.getInherited() != null ? rset.isInherited() : source.isInherited())) {
Object key = getReportSetKey(rset);
merged.put(key, rset);
}
}
for (ReportSet element : tgt) {
Object key = getReportSetKey(element);
ReportSet existing = merged.get(key);
if (existing != null) {
mergeReportSet(element, existing, sourceDominant, context);
}
merged.put(key, element);
}
target.setReportSets(new ArrayList<>(merged.values()));
}
}
@Override
protected Object getDependencyKey(Dependency dependency) {
return dependency.getManagementKey();
}
@Override
protected Object getPluginKey(Plugin plugin) {
return plugin.getKey();
}
@Override
protected Object getPluginExecutionKey(PluginExecution pluginExecution) {
return pluginExecution.getId();
}
@Override
protected Object getReportPluginKey(ReportPlugin reportPlugin) {
return reportPlugin.getKey();
}
@Override
protected Object getReportSetKey(ReportSet reportSet) {
return reportSet.getId();
}
@Override
protected Object getRepositoryBaseKey(RepositoryBase repositoryBase) {
return repositoryBase.getId();
}
@Override
protected Object getExtensionKey(Extension extension) {
return extension.getGroupId() + ':' + extension.getArtifactId();
}
@Override
protected Object getExclusionKey(Exclusion exclusion) {
return exclusion.getGroupId() + ':' + exclusion.getArtifactId();
}
protected String extrapolateChildUrl(String parentUrl, boolean appendPath, Map<Object, Object> context) {
return parentUrl;
}
}

View File

@ -26,15 +26,15 @@ import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import org.apache.maven.api.model.Build;
import org.apache.maven.api.model.Dependency;
import org.apache.maven.api.model.Model;
import org.apache.maven.api.model.Plugin;
import org.apache.maven.model.Build;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblemCollector;
import org.apache.maven.model.merge.MavenModelMerger;
import org.codehaus.plexus.util.StringUtils;
/**
* Handles normalization of a model.
@ -49,21 +49,7 @@ public class DefaultModelNormalizer implements ModelNormalizer {
private DuplicateMerger merger = new DuplicateMerger();
@Override
public void mergeDuplicates(
org.apache.maven.model.Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
model.update(mergeDuplicates(model.getDelegate(), request, problems));
}
@Override
public void injectDefaultValues(
org.apache.maven.model.Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
model.update(injectDefaultValues(model.getDelegate(), request, problems));
}
@Override
public Model mergeDuplicates(Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
Model.Builder builder = Model.newBuilder(model);
public void mergeDuplicates(Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
Build build = model.getBuild();
if (build != null) {
List<Plugin> plugins = build.getPlugins();
@ -73,14 +59,13 @@ public class DefaultModelNormalizer implements ModelNormalizer {
Object key = plugin.getKey();
Plugin first = normalized.get(key);
if (first != null) {
plugin = merger.mergePlugin(plugin, first);
merger.mergePlugin(plugin, first);
}
normalized.put(key, plugin);
}
if (plugins.size() != normalized.size()) {
builder.build(
Build.newBuilder(build).plugins(normalized.values()).build());
build.setPlugins(new ArrayList<>(normalized.values()));
}
}
@ -99,10 +84,8 @@ public class DefaultModelNormalizer implements ModelNormalizer {
}
if (dependencies.size() != normalized.size()) {
builder.dependencies(normalized.values());
model.setDependencies(new ArrayList<>(normalized.values()));
}
return builder.build();
}
/**
@ -110,53 +93,29 @@ public class DefaultModelNormalizer implements ModelNormalizer {
*/
protected static class DuplicateMerger extends MavenModelMerger {
public Plugin mergePlugin(Plugin target, Plugin source) {
return super.mergePlugin(target, source, false, Collections.emptyMap());
public void mergePlugin(Plugin target, Plugin source) {
super.mergePlugin(target, source, false, Collections.emptyMap());
}
}
@Override
public Model injectDefaultValues(Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
Model.Builder builder = Model.newBuilder(model);
public void injectDefaultValues(Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
injectDependencyDefaults(model.getDependencies());
builder.dependencies(injectList(model.getDependencies(), this::injectDependency));
Build build = model.getBuild();
if (build != null) {
Build newBuild = Build.newBuilder(build)
.plugins(injectList(build.getPlugins(), this::injectPlugin))
.build();
builder.build(newBuild != build ? newBuild : null);
}
return builder.build();
}
private Plugin injectPlugin(Plugin p) {
return Plugin.newBuilder(p)
.dependencies(injectList(p.getDependencies(), this::injectDependency))
.build();
}
private Dependency injectDependency(Dependency d) {
// we cannot set this directly in the MDO due to the interactions with dependency management
return (d.getScope() == null || d.getScope().isEmpty()) ? d.withScope("compile") : d;
}
/**
* Returns a list suited for the builders, i.e. null if not modified
*/
private <T> List<T> injectList(List<T> list, Function<T, T> modifer) {
List<T> newList = null;
for (int i = 0; i < list.size(); i++) {
T oldT = list.get(i);
T newT = modifer.apply(oldT);
if (newT != oldT) {
if (newList == null) {
newList = new ArrayList<>(list);
}
newList.set(i, newT);
for (Plugin plugin : build.getPlugins()) {
injectDependencyDefaults(plugin.getDependencies());
}
}
}
private void injectDependencyDefaults(List<Dependency> dependencies) {
for (Dependency dependency : dependencies) {
if (StringUtils.isEmpty(dependency.getScope())) {
// we cannot set this directly in the MDO due to the interactions with dependency management
dependency.setScope("compile");
}
}
return newList;
}
}

View File

@ -49,10 +49,4 @@ public interface ModelNormalizer {
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
*/
void injectDefaultValues(Model model, ModelBuildingRequest request, ModelProblemCollector problems);
org.apache.maven.api.model.Model mergeDuplicates(
org.apache.maven.api.model.Model model, ModelBuildingRequest request, ModelProblemCollector problems);
org.apache.maven.api.model.Model injectDefaultValues(
org.apache.maven.api.model.Model model, ModelBuildingRequest request, ModelProblemCollector problems);
}

View File

@ -23,16 +23,13 @@ import javax.inject.Named;
import javax.inject.Singleton;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import org.apache.maven.api.model.Build;
import org.apache.maven.api.model.Model;
import org.apache.maven.api.model.Reporting;
import org.apache.maven.api.model.Resource;
import org.apache.maven.model.Build;
import org.apache.maven.model.Model;
import org.apache.maven.model.Reporting;
import org.apache.maven.model.Resource;
import org.apache.maven.model.building.ModelBuildingRequest;
/**
@ -45,100 +42,60 @@ import org.apache.maven.model.building.ModelBuildingRequest;
@Deprecated(since = "4.0.0")
public class DefaultModelPathTranslator implements ModelPathTranslator {
private final PathTranslator pathTranslator;
@Inject
public DefaultModelPathTranslator(PathTranslator pathTranslator) {
private PathTranslator pathTranslator;
public DefaultModelPathTranslator setPathTranslator(PathTranslator pathTranslator) {
this.pathTranslator = pathTranslator;
}
@Deprecated
@Override
public void alignToBaseDirectory(org.apache.maven.model.Model modelV3, File basedir, ModelBuildingRequest request) {
if (modelV3 == null || basedir == null) {
return;
}
alignToBaseDirectory(modelV3, basedir.toPath(), request);
return this;
}
@Override
public void alignToBaseDirectory(org.apache.maven.model.Model modelV3, Path basedir, ModelBuildingRequest request) {
if (modelV3 == null || basedir == null) {
public void alignToBaseDirectory(Model model, File basedir, ModelBuildingRequest request) {
if (model == null || basedir == null) {
return;
}
Model model = modelV3.getDelegate();
Build build = model.getBuild();
Build newBuild = null;
if (build != null) {
newBuild = Build.newBuilder(build)
.directory(alignToBaseDirectory(build.getDirectory(), basedir))
.sourceDirectory(alignToBaseDirectory(build.getSourceDirectory(), basedir))
.testSourceDirectory(alignToBaseDirectory(build.getTestSourceDirectory(), basedir))
.scriptSourceDirectory(alignToBaseDirectory(build.getScriptSourceDirectory(), basedir))
.resources(map(build.getResources(), r -> alignToBaseDirectory(r, basedir)))
.testResources(map(build.getTestResources(), r -> alignToBaseDirectory(r, basedir)))
.filters(map(build.getFilters(), s -> alignToBaseDirectory(s, basedir)))
.outputDirectory(alignToBaseDirectory(build.getOutputDirectory(), basedir))
.testOutputDirectory(alignToBaseDirectory(build.getTestOutputDirectory(), basedir))
.build();
build.setDirectory(alignToBaseDirectory(build.getDirectory(), basedir));
build.setSourceDirectory(alignToBaseDirectory(build.getSourceDirectory(), basedir));
build.setTestSourceDirectory(alignToBaseDirectory(build.getTestSourceDirectory(), basedir));
build.setScriptSourceDirectory(alignToBaseDirectory(build.getScriptSourceDirectory(), basedir));
for (Resource resource : build.getResources()) {
resource.setDirectory(alignToBaseDirectory(resource.getDirectory(), basedir));
}
for (Resource resource : build.getTestResources()) {
resource.setDirectory(alignToBaseDirectory(resource.getDirectory(), basedir));
}
if (build.getFilters() != null) {
List<String> filters = new ArrayList<>(build.getFilters().size());
for (String filter : build.getFilters()) {
filters.add(alignToBaseDirectory(filter, basedir));
}
build.setFilters(filters);
}
build.setOutputDirectory(alignToBaseDirectory(build.getOutputDirectory(), basedir));
build.setTestOutputDirectory(alignToBaseDirectory(build.getTestOutputDirectory(), basedir));
}
Reporting reporting = model.getReporting();
Reporting newReporting = null;
if (reporting != null) {
newReporting = Reporting.newBuilder(reporting)
.outputDirectory(alignToBaseDirectory(reporting.getOutputDirectory(), basedir))
.build();
}
if (newBuild != build || newReporting != reporting) {
modelV3.update(Model.newBuilder(model)
.build(newBuild)
.reporting(newReporting)
.build());
reporting.setOutputDirectory(alignToBaseDirectory(reporting.getOutputDirectory(), basedir));
}
}
private <T> List<T> map(List<T> resources, Function<T, T> mapper) {
List<T> newResources = null;
if (resources != null) {
for (int i = 0; i < resources.size(); i++) {
T resource = resources.get(i);
T newResource = mapper.apply(resource);
if (newResource != null) {
if (newResources == null) {
newResources = new ArrayList<>(resources);
}
newResources.set(i, newResource);
}
}
}
return newResources;
}
private Resource alignToBaseDirectory(Resource resource, Path basedir) {
if (resource != null) {
String newDir = mayAlignToBaseDirectoryOrNull(resource.getDirectory(), basedir);
if (newDir != null) {
return resource.withDirectory(newDir);
}
}
return resource;
}
private String alignToBaseDirectory(String path, Path basedir) {
String newPath = mayAlignToBaseDirectoryOrNull(path, basedir);
if (newPath != null) {
return newPath;
}
return path;
}
/**
* Returns aligned path or {@code null} if no need for change.
*/
private String mayAlignToBaseDirectoryOrNull(String path, Path basedir) {
String newPath = pathTranslator.alignToBaseDirectory(path, basedir);
return Objects.equals(path, newPath) ? null : newPath;
private String alignToBaseDirectory(String path, File basedir) {
return pathTranslator.alignToBaseDirectory(path, basedir);
}
}

View File

@ -39,11 +39,12 @@ import org.apache.maven.model.building.ModelBuildingRequest;
@Deprecated(since = "4.0.0")
public class DefaultModelUrlNormalizer implements ModelUrlNormalizer {
private final UrlNormalizer urlNormalizer;
@Inject
public DefaultModelUrlNormalizer(UrlNormalizer urlNormalizer) {
private UrlNormalizer urlNormalizer;
public DefaultModelUrlNormalizer setUrlNormalizer(UrlNormalizer urlNormalizer) {
this.urlNormalizer = urlNormalizer;
return this;
}
@Override

View File

@ -22,7 +22,6 @@ import javax.inject.Named;
import javax.inject.Singleton;
import java.io.File;
import java.nio.file.Path;
/**
* Resolves relative paths against a specific base directory.
@ -36,11 +35,6 @@ public class DefaultPathTranslator implements PathTranslator {
@Override
public String alignToBaseDirectory(String path, File basedir) {
return alignToBaseDirectory(path, basedir != null ? basedir.toPath() : null);
}
@Override
public String alignToBaseDirectory(String path, Path basedir) {
String result = path;
if (path != null && basedir != null) {
@ -55,7 +49,7 @@ public class DefaultPathTranslator implements PathTranslator {
result = file.getAbsolutePath();
} else {
// an ordinary relative path, align with project directory
result = basedir.resolve(path).normalize().toString();
result = new File(new File(basedir, path).toURI().normalize()).getAbsolutePath();
}
}

View File

@ -19,7 +19,6 @@
package org.apache.maven.model.path;
import java.io.File;
import java.nio.file.Path;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.ModelBuildingRequest;
@ -39,19 +38,6 @@ public interface ModelPathTranslator {
* @param model The model whose paths should be resolved, may be {@code null}.
* @param basedir The base directory to resolve relative paths against, may be {@code null}.
* @param request The model building request that holds further settings, must not be {@code null}.
* @deprecated Use {@link #alignToBaseDirectory(Model, Path, ModelBuildingRequest)} instead.
*/
@Deprecated
void alignToBaseDirectory(Model model, File basedir, ModelBuildingRequest request);
/**
* Resolves the well-known paths of the specified model against the given base directory. Paths within plugin
* configuration are not processed.
*
* @param model The model whose paths should be resolved, may be {@code null}.
* @param basedir The base directory to resolve relative paths against, may be {@code null}.
* @param request The model building request that holds further settings, must not be {@code null}.
* @since 4.0.0
*/
void alignToBaseDirectory(Model model, Path basedir, ModelBuildingRequest request);
}

View File

@ -19,7 +19,6 @@
package org.apache.maven.model.path;
import java.io.File;
import java.nio.file.Path;
/**
* Resolves relative paths against a specific base directory.
@ -37,20 +36,6 @@ public interface PathTranslator {
* @param path The path to resolve, may be {@code null}.
* @param basedir The base directory to resolve relative paths against, may be {@code null}.
* @return The resolved path or {@code null} if the input path was {@code null}.
* @deprecated Use {@link #alignToBaseDirectory(String, Path)} instead.
*/
@Deprecated
String alignToBaseDirectory(String path, File basedir);
/**
* Resolves the specified path against the given base directory. The resolved path will be absolute and uses the
* platform-specific file separator if a base directory is given. Otherwise, the input path will be returned
* unaltered.
*
* @param path The path to resolve, may be {@code null}.
* @param basedir The base directory to resolve relative paths against, may be {@code null}.
* @return The resolved path or {@code null} if the input path was {@code null}.
* @since 4.0.0
*/
String alignToBaseDirectory(String path, Path basedir);
}

View File

@ -25,7 +25,7 @@ import javax.inject.Singleton;
import java.io.File;
import java.nio.file.Path;
import org.apache.maven.api.model.ActivationFile;
import org.apache.maven.model.ActivationFile;
import org.apache.maven.model.profile.ProfileActivationContext;
import org.apache.maven.model.root.RootLocator;
import org.codehaus.plexus.interpolation.AbstractValueSource;
@ -43,14 +43,20 @@ import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
@Deprecated
public class ProfileActivationFilePathInterpolator {
private final PathTranslator pathTranslator;
private final RootLocator rootLocator;
@Inject
private PathTranslator pathTranslator;
@Inject
public ProfileActivationFilePathInterpolator(PathTranslator pathTranslator, RootLocator rootLocator) {
private RootLocator rootLocator;
public ProfileActivationFilePathInterpolator setPathTranslator(PathTranslator pathTranslator) {
this.pathTranslator = pathTranslator;
return this;
}
public ProfileActivationFilePathInterpolator setRootLocator(RootLocator rootLocator) {
this.rootLocator = rootLocator;
return this;
}
/**

View File

@ -23,7 +23,6 @@ import javax.inject.Singleton;
import java.util.List;
import org.apache.maven.api.xml.XmlNode;
import org.apache.maven.model.Build;
import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin;
@ -31,6 +30,7 @@ import org.apache.maven.model.PluginExecution;
import org.apache.maven.model.PluginManagement;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblemCollector;
import org.codehaus.plexus.util.xml.Xpp3Dom;
/**
* Handles expansion of general build plugin configuration into individual executions.
@ -59,13 +59,16 @@ public class DefaultPluginConfigurationExpander implements PluginConfigurationEx
private void expand(List<Plugin> plugins) {
for (Plugin plugin : plugins) {
XmlNode pluginConfiguration = plugin.getDelegate().getConfiguration();
Xpp3Dom pluginConfiguration = (Xpp3Dom) plugin.getConfiguration();
if (pluginConfiguration != null) {
for (PluginExecution execution : plugin.getExecutions()) {
XmlNode executionConfiguration = execution.getDelegate().getConfiguration();
executionConfiguration = XmlNode.merge(executionConfiguration, pluginConfiguration);
execution.update(execution.getDelegate().withConfiguration(executionConfiguration));
Xpp3Dom executionConfiguration = (Xpp3Dom) execution.getConfiguration();
executionConfiguration =
Xpp3Dom.mergeXpp3Dom(executionConfiguration, new Xpp3Dom(pluginConfiguration));
execution.setConfiguration(executionConfiguration);
}
}
}

View File

@ -21,13 +21,13 @@ package org.apache.maven.model.plugin;
import javax.inject.Named;
import javax.inject.Singleton;
import org.apache.maven.api.xml.XmlNode;
import org.apache.maven.model.Model;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.model.ReportSet;
import org.apache.maven.model.Reporting;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblemCollector;
import org.codehaus.plexus.util.xml.Xpp3Dom;
/**
* Handles expansion of general report plugin configuration into individual report sets.
@ -45,13 +45,13 @@ public class DefaultReportConfigurationExpander implements ReportConfigurationEx
if (reporting != null) {
for (ReportPlugin reportPlugin : reporting.getPlugins()) {
XmlNode parentDom = reportPlugin.getDelegate().getConfiguration();
Xpp3Dom parentDom = (Xpp3Dom) reportPlugin.getConfiguration();
if (parentDom != null) {
for (ReportSet execution : reportPlugin.getReportSets()) {
XmlNode childDom = execution.getDelegate().getConfiguration();
childDom = XmlNode.merge(childDom, parentDom);
execution.update(execution.getDelegate().withConfiguration(childDom));
Xpp3Dom childDom = (Xpp3Dom) execution.getConfiguration();
childDom = Xpp3Dom.mergeXpp3Dom(childDom, new Xpp3Dom(parentDom));
execution.setConfiguration(childDom);
}
}
}

View File

@ -21,9 +21,22 @@ package org.apache.maven.model.plugin;
import javax.inject.Named;
import javax.inject.Singleton;
import org.apache.maven.model.Build;
import org.apache.maven.model.InputLocation;
import org.apache.maven.model.InputSource;
import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginManagement;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.model.ReportSet;
import org.apache.maven.model.Reporting;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblem.Severity;
import org.apache.maven.model.building.ModelProblem.Version;
import org.apache.maven.model.building.ModelProblemCollector;
import org.apache.maven.model.building.ModelProblemCollectorRequest;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.Xpp3Dom;
/**
* Handles conversion of the <code>&lt;reporting&gt;</code> section into the configuration of Maven Site Plugin 3.x,
@ -35,7 +48,199 @@ import org.apache.maven.model.building.ModelProblemCollector;
@Singleton
@Deprecated
public class DefaultReportingConverter implements ReportingConverter {
private final InputLocation location;
{
String modelId = "org.apache.maven:maven-model-builder:"
+ this.getClass().getPackage().getImplementationVersion() + ":reporting-converter";
InputSource inputSource = new InputSource();
inputSource.setModelId(modelId);
location = new InputLocation(-1, -1, inputSource);
location.setLocation(0, location);
}
@Override
public void convertReporting(Model model, ModelBuildingRequest request, ModelProblemCollector problems) {}
public void convertReporting(Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
Reporting reporting = model.getReporting();
if (reporting == null) {
return;
}
Build build = model.getBuild();
if (build == null) {
build = new Build();
model.setBuild(build);
model.setLocation("build", location);
}
Plugin sitePlugin = findSitePlugin(build);
if (sitePlugin == null) {
sitePlugin = new Plugin();
sitePlugin.setArtifactId("maven-site-plugin");
sitePlugin.setLocation("artifactId", location);
PluginManagement pluginManagement = build.getPluginManagement();
if (pluginManagement == null) {
pluginManagement = new PluginManagement();
build.setPluginManagement(pluginManagement);
}
pluginManagement.addPlugin(sitePlugin);
}
Xpp3Dom configuration = (Xpp3Dom) sitePlugin.getConfiguration();
if (configuration == null) {
configuration = new Xpp3Dom("configuration", location);
sitePlugin.setConfiguration(configuration);
}
Xpp3Dom reportPlugins = configuration.getChild("reportPlugins");
if (reportPlugins != null) {
// new-style report configuration already present: warn since this new style has been deprecated
// in favor of classical reporting section MSITE-647 / MSITE-684
problems.add(new ModelProblemCollectorRequest(Severity.WARNING, Version.BASE)
.setMessage("Reporting configuration should be done in <reporting> section, "
+ "not in maven-site-plugin <configuration> as reportPlugins parameter.")
.setLocation(sitePlugin.getLocation("configuration")));
return;
}
if (configuration.getChild("outputDirectory") == null) {
addDom(
configuration,
"outputDirectory",
reporting.getOutputDirectory(),
reporting.getLocation("outputDirectory"));
}
reportPlugins = new Xpp3Dom("reportPlugins", location);
configuration.addChild(reportPlugins);
boolean hasMavenProjectInfoReportsPlugin = false;
/* waiting for MSITE-484 before deprecating <reporting> section
if ( !reporting.getPlugins().isEmpty()
&& request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_1 )
{
problems.add( new ModelProblemCollectorRequest( Severity.WARNING, Version.V31 )
.setMessage( "The <reporting> section is deprecated, please move the reports to the <configuration>"
+ " section of the new Maven Site Plugin." )
.setLocation( reporting.getLocation( "" ) ) );
}*/
for (ReportPlugin plugin : reporting.getPlugins()) {
Xpp3Dom reportPlugin = convert(plugin);
reportPlugins.addChild(reportPlugin);
if (!reporting.isExcludeDefaults()
&& !hasMavenProjectInfoReportsPlugin
&& "org.apache.maven.plugins".equals(plugin.getGroupId())
&& "maven-project-info-reports-plugin".equals(plugin.getArtifactId())) {
hasMavenProjectInfoReportsPlugin = true;
}
}
if (!reporting.isExcludeDefaults() && !hasMavenProjectInfoReportsPlugin) {
Xpp3Dom dom = new Xpp3Dom("reportPlugin", location);
addDom(dom, "groupId", "org.apache.maven.plugins");
addDom(dom, "artifactId", "maven-project-info-reports-plugin");
reportPlugins.addChild(dom);
}
}
private Plugin findSitePlugin(Build build) {
for (Plugin plugin : build.getPlugins()) {
if (isSitePlugin(plugin)) {
return plugin;
}
}
PluginManagement pluginManagement = build.getPluginManagement();
if (pluginManagement != null) {
for (Plugin plugin : pluginManagement.getPlugins()) {
if (isSitePlugin(plugin)) {
return plugin;
}
}
}
return null;
}
private boolean isSitePlugin(Plugin plugin) {
return "maven-site-plugin".equals(plugin.getArtifactId())
&& "org.apache.maven.plugins".equals(plugin.getGroupId());
}
private Xpp3Dom convert(ReportPlugin plugin) {
Xpp3Dom dom = new Xpp3Dom("reportPlugin", plugin.getLocation(""));
addDom(dom, "groupId", plugin.getGroupId(), plugin.getLocation("groupId"));
addDom(dom, "artifactId", plugin.getArtifactId(), plugin.getLocation("artifactId"));
addDom(dom, "version", plugin.getVersion(), plugin.getLocation("version"));
Xpp3Dom configuration = (Xpp3Dom) plugin.getConfiguration();
if (configuration != null) {
configuration = new Xpp3Dom(configuration);
dom.addChild(configuration);
}
if (!plugin.getReportSets().isEmpty()) {
Xpp3Dom reportSets = new Xpp3Dom("reportSets", plugin.getLocation("reportSets"));
for (ReportSet reportSet : plugin.getReportSets()) {
Xpp3Dom rs = convert(reportSet);
reportSets.addChild(rs);
}
dom.addChild(reportSets);
}
return dom;
}
private Xpp3Dom convert(ReportSet reportSet) {
Xpp3Dom dom = new Xpp3Dom("reportSet", reportSet.getLocation(""));
InputLocation idLocation = reportSet.getLocation("id");
addDom(dom, "id", reportSet.getId(), idLocation == null ? location : idLocation);
Xpp3Dom configuration = (Xpp3Dom) reportSet.getConfiguration();
if (configuration != null) {
configuration = new Xpp3Dom(configuration);
dom.addChild(configuration);
}
if (!reportSet.getReports().isEmpty()) {
InputLocation location = reportSet.getLocation("reports");
Xpp3Dom reports = new Xpp3Dom("reports", location);
int n = 0;
for (String report : reportSet.getReports()) {
addDom(reports, "report", report, (location == null) ? null : location.getLocation(n++));
}
dom.addChild(reports);
}
return dom;
}
private void addDom(Xpp3Dom parent, String childName, String childValue) {
addDom(parent, childName, childValue, location);
}
private void addDom(Xpp3Dom parent, String childName, String childValue, InputLocation location) {
if (StringUtils.isNotEmpty(childValue)) {
parent.addChild(newDom(childName, childValue, location));
}
}
private Xpp3Dom newDom(String name, String value, InputLocation location) {
Xpp3Dom dom = new Xpp3Dom(name, location);
dom.setValue(value);
return dom;
}
}

View File

@ -23,7 +23,9 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toMap;
/**
* Describes the environmental context used to determine the activation status of profiles.
@ -57,7 +59,12 @@ public class DefaultProfileActivationContext implements ProfileActivationContext
* @return This context, never {@code null}.
*/
public DefaultProfileActivationContext setActiveProfileIds(List<String> activeProfileIds) {
this.activeProfileIds = unmodifiable(activeProfileIds);
if (activeProfileIds != null) {
this.activeProfileIds = Collections.unmodifiableList(activeProfileIds);
} else {
this.activeProfileIds = Collections.emptyList();
}
return this;
}
@ -73,7 +80,12 @@ public class DefaultProfileActivationContext implements ProfileActivationContext
* @return This context, never {@code null}.
*/
public DefaultProfileActivationContext setInactiveProfileIds(List<String> inactiveProfileIds) {
this.inactiveProfileIds = unmodifiable(inactiveProfileIds);
if (inactiveProfileIds != null) {
this.inactiveProfileIds = Collections.unmodifiableList(inactiveProfileIds);
} else {
this.inactiveProfileIds = Collections.emptyList();
}
return this;
}
@ -91,7 +103,13 @@ public class DefaultProfileActivationContext implements ProfileActivationContext
*/
@SuppressWarnings("unchecked")
public DefaultProfileActivationContext setSystemProperties(Properties systemProperties) {
return setSystemProperties(toMap(systemProperties));
if (systemProperties != null) {
this.systemProperties = Collections.unmodifiableMap((Map) systemProperties);
} else {
this.systemProperties = Collections.emptyMap();
}
return this;
}
/**
@ -102,7 +120,12 @@ public class DefaultProfileActivationContext implements ProfileActivationContext
* @return This context, never {@code null}.
*/
public DefaultProfileActivationContext setSystemProperties(Map<String, String> systemProperties) {
this.systemProperties = unmodifiable(systemProperties);
if (systemProperties != null) {
this.systemProperties = Collections.unmodifiableMap(systemProperties);
} else {
this.systemProperties = Collections.emptyMap();
}
return this;
}
@ -121,7 +144,13 @@ public class DefaultProfileActivationContext implements ProfileActivationContext
*/
@SuppressWarnings("unchecked")
public DefaultProfileActivationContext setUserProperties(Properties userProperties) {
return setUserProperties(toMap(userProperties));
if (userProperties != null) {
this.userProperties = Collections.unmodifiableMap((Map) userProperties);
} else {
this.userProperties = Collections.emptyMap();
}
return this;
}
/**
@ -133,7 +162,12 @@ public class DefaultProfileActivationContext implements ProfileActivationContext
* @return This context, never {@code null}.
*/
public DefaultProfileActivationContext setUserProperties(Map<String, String> userProperties) {
this.userProperties = unmodifiable(userProperties);
if (userProperties != null) {
this.userProperties = Collections.unmodifiableMap(userProperties);
} else {
this.userProperties = Collections.emptyMap();
}
return this;
}
@ -161,30 +195,15 @@ public class DefaultProfileActivationContext implements ProfileActivationContext
}
public DefaultProfileActivationContext setProjectProperties(Properties projectProperties) {
return setProjectProperties(toMap(projectProperties));
}
public DefaultProfileActivationContext setProjectProperties(Map<String, String> projectProperties) {
this.projectProperties = unmodifiable(projectProperties);
if (projectProperties != null) {
this.projectProperties = projectProperties.entrySet().stream()
.collect(collectingAndThen(
toMap(e -> String.valueOf(e.getKey()), e -> String.valueOf(e.getValue())),
Collections::unmodifiableMap));
} else {
this.projectProperties = Collections.emptyMap();
}
return this;
}
private static List<String> unmodifiable(List<String> list) {
return list != null ? Collections.unmodifiableList(list) : Collections.emptyList();
}
private static Map<String, String> unmodifiable(Map<String, String> map) {
return map != null ? Collections.unmodifiableMap(map) : Collections.emptyMap();
}
private static Map<String, String> toMap(Properties properties) {
if (properties != null && !properties.isEmpty()) {
return properties.entrySet().stream()
.collect(Collectors.toMap(e -> String.valueOf(e.getKey()), e -> String.valueOf(e.getValue())));
} else {
return null;
}
}
}

View File

@ -26,20 +26,18 @@ import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.maven.api.model.Build;
import org.apache.maven.api.model.BuildBase;
import org.apache.maven.api.model.Model;
import org.apache.maven.api.model.ModelBase;
import org.apache.maven.api.model.Plugin;
import org.apache.maven.api.model.PluginContainer;
import org.apache.maven.api.model.PluginExecution;
import org.apache.maven.api.model.Profile;
import org.apache.maven.api.model.ReportPlugin;
import org.apache.maven.api.model.ReportSet;
import org.apache.maven.api.model.Reporting;
import org.apache.maven.model.Build;
import org.apache.maven.model.BuildBase;
import org.apache.maven.model.Model;
import org.apache.maven.model.ModelBase;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginContainer;
import org.apache.maven.model.PluginExecution;
import org.apache.maven.model.Profile;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.model.ReportSet;
import org.apache.maven.model.Reporting;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblemCollector;
import org.apache.maven.model.merge.MavenModelMerger;
@ -55,57 +53,21 @@ import org.apache.maven.model.merge.MavenModelMerger;
@SuppressWarnings({"checkstyle:methodname"})
public class DefaultProfileInjector implements ProfileInjector {
private static final Map<Model, Map<List<Profile>, Model>> CACHE = Collections.synchronizedMap(new WeakHashMap<>());
// In order for the weak hash map to work correctly, we must not hold any reference to
// the model used as the key. So we use a dummy model as a placeholder to indicate that
// we want to store the model used as they key.
private static final Model KEY = Model.newInstance();
private ProfileModelMerger merger = new ProfileModelMerger();
@Override
public void injectProfile(
org.apache.maven.model.Model model,
org.apache.maven.model.Profile profile,
ModelBuildingRequest request,
ModelProblemCollector problems) {
model.update(
injectProfile(model.getDelegate(), profile != null ? profile.getDelegate() : null, request, problems));
}
@Override
public Model injectProfile(
Model model, Profile profile, ModelBuildingRequest request, ModelProblemCollector problems) {
return injectProfiles(model, Collections.singletonList(profile), request, problems);
}
if (profile != null) {
merger.mergeModelBase(model, profile);
@Override
public Model injectProfiles(
Model model, List<Profile> profiles, ModelBuildingRequest request, ModelProblemCollector problems) {
Model result = CACHE.computeIfAbsent(model, k -> new ConcurrentHashMap<>())
.computeIfAbsent(profiles, l -> doInjectProfiles(model, profiles));
return result == KEY ? model : result;
}
private Model doInjectProfiles(Model model, List<Profile> profiles) {
Model orgModel = model;
for (Profile profile : profiles) {
if (profile != null) {
Model.Builder builder = Model.newBuilder(model);
merger.mergeModelBase(builder, model, profile);
if (profile.getBuild() != null) {
Build build = model.getBuild() != null ? model.getBuild() : Build.newInstance();
Build.Builder bbuilder = Build.newBuilder(build);
merger.mergeBuildBase(bbuilder, build, profile.getBuild());
builder.build(bbuilder.build());
if (profile.getBuild() != null) {
if (model.getBuild() == null) {
model.setBuild(new Build());
}
model = builder.build();
merger.mergeBuildBase(model.getBuild(), profile.getBuild());
}
}
return model == orgModel ? KEY : model;
}
/**
@ -113,45 +75,41 @@ public class DefaultProfileInjector implements ProfileInjector {
*/
protected static class ProfileModelMerger extends MavenModelMerger {
public void mergeModelBase(ModelBase.Builder builder, ModelBase target, ModelBase source) {
mergeModelBase(builder, target, source, true, Collections.emptyMap());
public void mergeModelBase(ModelBase target, ModelBase source) {
mergeModelBase(target, source, true, Collections.emptyMap());
}
public void mergeBuildBase(BuildBase.Builder builder, BuildBase target, BuildBase source) {
mergeBuildBase(builder, target, source, true, Collections.emptyMap());
public void mergeBuildBase(BuildBase target, BuildBase source) {
mergeBuildBase(target, source, true, Collections.emptyMap());
}
@Override
protected void mergePluginContainer_Plugins(
PluginContainer.Builder builder,
PluginContainer target,
PluginContainer source,
boolean sourceDominant,
Map<Object, Object> context) {
PluginContainer target, PluginContainer source, boolean sourceDominant, Map<Object, Object> context) {
List<Plugin> src = source.getPlugins();
if (!src.isEmpty()) {
List<Plugin> tgt = target.getPlugins();
Map<Object, Plugin> master = new LinkedHashMap<>(tgt.size() * 2);
for (Plugin element : tgt) {
Object key = getPluginKey().apply(element);
Object key = getPluginKey(element);
master.put(key, element);
}
Map<Object, List<Plugin>> predecessors = new LinkedHashMap<>();
List<Plugin> pending = new ArrayList<>();
for (Plugin element : src) {
Object key = getPluginKey().apply(element);
Object key = getPluginKey(element);
Plugin existing = master.get(key);
if (existing != null) {
existing = mergePlugin(existing, element, sourceDominant, context);
master.put(key, existing);
mergePlugin(existing, element, sourceDominant, context);
if (!pending.isEmpty()) {
predecessors.put(key, pending);
pending = new ArrayList<>();
}
} else {
pending.add(element);
pending.add(element.clone());
}
}
@ -165,97 +123,88 @@ public class DefaultProfileInjector implements ProfileInjector {
}
result.addAll(pending);
builder.plugins(result);
target.setPlugins(result);
}
}
@Override
protected void mergePlugin_Executions(
Plugin.Builder builder,
Plugin target,
Plugin source,
boolean sourceDominant,
Map<Object, Object> context) {
Plugin target, Plugin source, boolean sourceDominant, Map<Object, Object> context) {
List<PluginExecution> src = source.getExecutions();
if (!src.isEmpty()) {
List<PluginExecution> tgt = target.getExecutions();
Map<Object, PluginExecution> merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2);
for (PluginExecution element : tgt) {
Object key = getPluginExecutionKey().apply(element);
Object key = getPluginExecutionKey(element);
merged.put(key, element);
}
for (PluginExecution element : src) {
Object key = getPluginExecutionKey().apply(element);
Object key = getPluginExecutionKey(element);
PluginExecution existing = merged.get(key);
if (existing != null) {
element = mergePluginExecution(existing, element, sourceDominant, context);
mergePluginExecution(existing, element, sourceDominant, context);
} else {
merged.put(key, element.clone());
}
merged.put(key, element);
}
builder.executions(merged.values());
target.setExecutions(new ArrayList<>(merged.values()));
}
}
@Override
protected void mergeReporting_Plugins(
Reporting.Builder builder,
Reporting target,
Reporting source,
boolean sourceDominant,
Map<Object, Object> context) {
Reporting target, Reporting source, boolean sourceDominant, Map<Object, Object> context) {
List<ReportPlugin> src = source.getPlugins();
if (!src.isEmpty()) {
List<ReportPlugin> tgt = target.getPlugins();
Map<Object, ReportPlugin> merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2);
for (ReportPlugin element : tgt) {
Object key = getReportPluginKey().apply(element);
Object key = getReportPluginKey(element);
merged.put(key, element);
}
for (ReportPlugin element : src) {
Object key = getReportPluginKey().apply(element);
Object key = getReportPluginKey(element);
ReportPlugin existing = merged.get(key);
if (existing != null) {
element = mergeReportPlugin(existing, element, sourceDominant, context);
if (existing == null) {
merged.put(key, element.clone());
} else {
mergeReportPlugin(existing, element, sourceDominant, context);
}
merged.put(key, element);
}
builder.plugins(merged.values());
target.setPlugins(new ArrayList<>(merged.values()));
}
}
@Override
protected void mergeReportPlugin_ReportSets(
ReportPlugin.Builder builder,
ReportPlugin target,
ReportPlugin source,
boolean sourceDominant,
Map<Object, Object> context) {
ReportPlugin target, ReportPlugin source, boolean sourceDominant, Map<Object, Object> context) {
List<ReportSet> src = source.getReportSets();
if (!src.isEmpty()) {
List<ReportSet> tgt = target.getReportSets();
Map<Object, ReportSet> merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2);
for (ReportSet element : tgt) {
Object key = getReportSetKey().apply(element);
Object key = getReportSetKey(element);
merged.put(key, element);
}
for (ReportSet element : src) {
Object key = getReportSetKey().apply(element);
Object key = getReportSetKey(element);
ReportSet existing = merged.get(key);
if (existing != null) {
element = mergeReportSet(existing, element, sourceDominant, context);
mergeReportSet(existing, element, sourceDominant, context);
} else {
merged.put(key, element.clone());
}
merged.put(key, element);
}
builder.reportSets(merged.values());
target.setReportSets(new ArrayList<>(merged.values()));
}
}
}

View File

@ -26,7 +26,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.maven.model.Activation;
import org.apache.maven.model.Profile;
@ -46,16 +45,8 @@ import org.apache.maven.model.profile.activation.ProfileActivator;
@Deprecated(since = "4.0.0")
public class DefaultProfileSelector implements ProfileSelector {
private final List<ProfileActivator> activators;
public DefaultProfileSelector() {
this.activators = new ArrayList<>();
}
@Inject
public DefaultProfileSelector(List<ProfileActivator> activators) {
this.activators = new ArrayList<>(activators);
}
private List<ProfileActivator> activators = new ArrayList<>();
public DefaultProfileSelector addProfileActivator(ProfileActivator profileActivator) {
if (profileActivator != null) {
@ -64,17 +55,6 @@ public class DefaultProfileSelector implements ProfileSelector {
return this;
}
@Override
public List<org.apache.maven.api.model.Profile> getActiveProfilesV4(
Collection<org.apache.maven.api.model.Profile> profiles,
ProfileActivationContext context,
ModelProblemCollector problems) {
return getActiveProfiles(profiles.stream().map(Profile::new).collect(Collectors.toList()), context, problems)
.stream()
.map(Profile::getDelegate)
.collect(Collectors.toList());
}
@Override
public List<Profile> getActiveProfiles(
Collection<Profile> profiles, ProfileActivationContext context, ModelProblemCollector problems) {
@ -115,18 +95,20 @@ public class DefaultProfileSelector implements ProfileSelector {
for (ProfileActivator activator : activators) {
if (activator.presentInConfig(profile, context, problems)) {
isActive = true;
try {
if (!activator.isActive(profile, context, problems)) {
return false;
}
} catch (RuntimeException e) {
problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
.setMessage("Failed to determine activation for profile " + profile.getId() + ": "
+ e.getMessage())
.setLocation(profile.getLocation(""))
.setException(e));
return false;
}
}
for (ProfileActivator activator : activators) {
try {
if (activator.presentInConfig(profile, context, problems)) {
isActive &= activator.isActive(profile, context, problems);
}
} catch (RuntimeException e) {
problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
.setMessage(
"Failed to determine activation for profile " + profile.getId() + ": " + e.getMessage())
.setLocation(profile.getLocation(""))
.setException(e));
return false;
}
}
return isActive;

View File

@ -32,7 +32,7 @@ public interface ProfileActivationContext {
/**
* Key of the property containing the project's packaging.
* Available in {@link #getUserProperties()}.
* @since 4.0.0
* @since 3.9
*/
String PROPERTY_NAME_PACKAGING = "packaging";

View File

@ -18,8 +18,6 @@
*/
package org.apache.maven.model.profile;
import java.util.List;
import org.apache.maven.model.Model;
import org.apache.maven.model.Profile;
import org.apache.maven.model.building.ModelBuildingRequest;
@ -43,45 +41,4 @@ public interface ProfileInjector {
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
*/
void injectProfile(Model model, Profile profile, ModelBuildingRequest request, ModelProblemCollector problems);
/**
* Merges values from the specified profile into the given model. Implementations are expected to keep the profile
* and model completely decoupled by injecting deep copies rather than the original objects from the profile.
*
* @param model The model into which to merge the values defined by the profile, must not be <code>null</code>.
* @param profile The (read-only) profile whose values should be injected, may be <code>null</code>.
* @param request The model building request that holds further settings, must not be {@code null}.
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
*/
default org.apache.maven.api.model.Model injectProfile(
org.apache.maven.api.model.Model model,
org.apache.maven.api.model.Profile profile,
ModelBuildingRequest request,
ModelProblemCollector problems) {
Model m = new Model(model);
injectProfile(m, profile != null ? new Profile(profile) : null, request, problems);
return m.getDelegate();
}
/**
* Merges values from the specified profile into the given model. Implementations are expected to keep the profile
* and model completely decoupled by injecting deep copies rather than the original objects from the profile.
*
* @param model The model into which to merge the values defined by the profile, must not be <code>null</code>.
* @param profiles The (read-only) list of profiles whose values should be injected, must not be <code>null</code>.
* @param request The model building request that holds further settings, must not be {@code null}.
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
*/
default org.apache.maven.api.model.Model injectProfiles(
org.apache.maven.api.model.Model model,
List<org.apache.maven.api.model.Profile> profiles,
ModelBuildingRequest request,
ModelProblemCollector problems) {
for (org.apache.maven.api.model.Profile profile : profiles) {
if (profile != null) {
model = injectProfile(model, profile, request, problems);
}
}
return model;
}
}

View File

@ -20,7 +20,6 @@ package org.apache.maven.model.profile;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.maven.model.Profile;
import org.apache.maven.model.building.ModelProblemCollector;
@ -45,24 +44,4 @@ public interface ProfileSelector {
*/
List<Profile> getActiveProfiles(
Collection<Profile> profiles, ProfileActivationContext context, ModelProblemCollector problems);
/**
* Determines the profiles which are active in the specified activation context. Active profiles will eventually be
* injected into the model.
*
* @param profiles The profiles whose activation status should be determined, must not be {@code null}.
* @param context The environmental context used to determine the activation status of a profile, must not be
* {@code null}.
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
* @return The profiles that have been activated, never {@code null}.
*/
default List<org.apache.maven.api.model.Profile> getActiveProfilesV4(
Collection<org.apache.maven.api.model.Profile> profiles,
ProfileActivationContext context,
ModelProblemCollector problems) {
return getActiveProfiles(profiles.stream().map(Profile::new).collect(Collectors.toList()), context, problems)
.stream()
.map(Profile::getDelegate)
.collect(Collectors.toList());
}
}

View File

@ -34,6 +34,7 @@ import org.apache.maven.model.building.ModelProblemCollectorRequest;
import org.apache.maven.model.path.ProfileActivationFilePathInterpolator;
import org.apache.maven.model.profile.ProfileActivationContext;
import org.codehaus.plexus.interpolation.InterpolationException;
import org.codehaus.plexus.util.StringUtils;
/**
* Determines profile activation based on the existence/absence of some file.
@ -49,11 +50,13 @@ import org.codehaus.plexus.interpolation.InterpolationException;
@Deprecated(since = "4.0.0")
public class FileProfileActivator implements ProfileActivator {
private final ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator;
@Inject
public FileProfileActivator(ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator) {
private ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator;
public FileProfileActivator setProfileActivationFilePathInterpolator(
ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator) {
this.profileActivationFilePathInterpolator = profileActivationFilePathInterpolator;
return this;
}
@Override
@ -73,10 +76,10 @@ public class FileProfileActivator implements ProfileActivator {
String path;
boolean missing;
if (file.getExists() != null && !file.getExists().isEmpty()) {
if (StringUtils.isNotEmpty(file.getExists())) {
path = file.getExists();
missing = false;
} else if (file.getMissing() != null && !file.getMissing().isEmpty()) {
} else if (StringUtils.isNotEmpty(file.getMissing())) {
path = file.getMissing();
missing = true;
} else {
@ -106,7 +109,7 @@ public class FileProfileActivator implements ProfileActivator {
boolean fileExists = f.exists();
return missing != fileExists;
return missing ? !fileExists : fileExists;
}
@Override
@ -119,6 +122,9 @@ public class FileProfileActivator implements ProfileActivator {
ActivationFile file = activation.getFile();
return file != null;
if (file == null) {
return false;
}
return true;
}
}

View File

@ -65,30 +65,28 @@ public class JdkVersionProfileActivator implements ProfileActivator {
String version = context.getSystemProperties().get("java.version");
if (version == null || version.isEmpty()) {
if (version == null || version.length() <= 0) {
problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
.setMessage("Failed to determine Java version for profile " + profile.getId())
.setLocation(activation.getLocation("jdk")));
return false;
}
try {
return isJavaVersionCompatible(jdk, version);
} catch (NumberFormatException e) {
problems.add(new ModelProblemCollectorRequest(Severity.WARNING, Version.BASE)
.setMessage("Failed to determine JDK activation for profile " + profile.getId()
+ " due invalid JDK version: '" + version + "'")
.setLocation(activation.getLocation("jdk")));
return false;
}
}
public static boolean isJavaVersionCompatible(String requiredJdkRange, String currentJavaVersion) {
if (requiredJdkRange.startsWith("!")) {
return !currentJavaVersion.startsWith(requiredJdkRange.substring(1));
} else if (isRange(requiredJdkRange)) {
return isInRange(currentJavaVersion, getRange(requiredJdkRange));
if (jdk.startsWith("!")) {
return !version.startsWith(jdk.substring(1));
} else if (isRange(jdk)) {
try {
return isInRange(version, getRange(jdk));
} catch (NumberFormatException e) {
problems.add(new ModelProblemCollectorRequest(Severity.WARNING, Version.BASE)
.setMessage("Failed to determine JDK activation for profile " + profile.getId()
+ " due invalid JDK version: '" + version + "'")
.setLocation(profile.getLocation(""))
.setException(e));
return false;
}
} else {
return currentJavaVersion.startsWith(requiredJdkRange);
return version.startsWith(jdk);
}
}
@ -102,7 +100,10 @@ public class JdkVersionProfileActivator implements ProfileActivator {
String jdk = activation.getJdk();
return jdk != null;
if (jdk == null) {
return false;
}
return true;
}
private static boolean isInRange(String value, List<RangeValue> range) {
@ -120,7 +121,7 @@ public class JdkVersionProfileActivator implements ProfileActivator {
}
private static int getRelationOrder(String value, RangeValue rangeValue, boolean isLeft) {
if (rangeValue.value.isEmpty()) {
if (rangeValue.value.length() <= 0) {
return isLeft ? 1 : -1;
}
@ -169,7 +170,7 @@ public class JdkVersionProfileActivator implements ProfileActivator {
ranges.add(new RangeValue(token.replace("]", ""), true));
} else if (token.endsWith(")")) {
ranges.add(new RangeValue(token.replace(")", ""), false));
} else if (token.isEmpty()) {
} else if (token.length() <= 0) {
ranges.add(new RangeValue("", false));
}
}

View File

@ -95,7 +95,10 @@ public class OperatingSystemProfileActivator implements ProfileActivator {
ActivationOS os = activation.getOs();
return os != null;
if (os == null) {
return false;
}
return true;
}
private boolean ensureAtLeastOneNonNull(ActivationOS os) {
@ -130,7 +133,7 @@ public class OperatingSystemProfileActivator implements ProfileActivator {
boolean result = actualArch.equals(test);
return reverse != result;
return reverse ? !result : result;
}
private boolean determineNameMatch(String expectedName, String actualName) {
@ -144,7 +147,7 @@ public class OperatingSystemProfileActivator implements ProfileActivator {
boolean result = actualName.equals(test);
return reverse != result;
return reverse ? !result : result;
}
private boolean determineFamilyMatch(String family, String actualName) {
@ -158,6 +161,6 @@ public class OperatingSystemProfileActivator implements ProfileActivator {
boolean result = Os.isFamily(test, actualName);
return reverse != result;
return reverse ? !result : result;
}
}

View File

@ -29,6 +29,7 @@ import org.apache.maven.model.building.ModelProblem.Version;
import org.apache.maven.model.building.ModelProblemCollector;
import org.apache.maven.model.building.ModelProblemCollectorRequest;
import org.apache.maven.model.profile.ProfileActivationContext;
import org.codehaus.plexus.util.StringUtils;
/**
* Determines profile activation based on the existence or value of some execution property.
@ -63,7 +64,7 @@ public class PropertyProfileActivator implements ProfileActivator {
name = name.substring(1);
}
if (name == null || name.isEmpty()) {
if (name == null || name.length() <= 0) {
problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
.setMessage("The property name is required to activate the profile " + profile.getId())
.setLocation(property.getLocation("")));
@ -76,7 +77,7 @@ public class PropertyProfileActivator implements ProfileActivator {
}
String propValue = property.getValue();
if (propValue != null && !propValue.isEmpty()) {
if (StringUtils.isNotEmpty(propValue)) {
boolean reverseValue = false;
if (propValue.startsWith("!")) {
reverseValue = true;
@ -84,9 +85,13 @@ public class PropertyProfileActivator implements ProfileActivator {
}
// we have a value, so it has to match the system value...
return reverseValue != propValue.equals(sysValue);
boolean result = propValue.equals(sysValue);
return reverseValue ? !result : result;
} else {
return reverseName != (sysValue != null && !sysValue.isEmpty());
boolean result = StringUtils.isNotEmpty(sysValue);
return reverseName ? !result : result;
}
}
@ -100,6 +105,9 @@ public class PropertyProfileActivator implements ProfileActivator {
ActivationProperty property = activation.getProperty();
return property != null;
if (property == null) {
return false;
}
return true;
}
}

View File

@ -18,7 +18,7 @@
*/
package org.apache.maven.model.resolution;
import org.apache.maven.api.model.Repository;
import org.apache.maven.model.Repository;
/**
* Signals an error when adding a repository to the model resolver.

View File

@ -18,11 +18,9 @@
*/
package org.apache.maven.model.resolution;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.maven.api.model.Dependency;
import org.apache.maven.api.model.Parent;
import org.apache.maven.api.model.Repository;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Parent;
import org.apache.maven.model.Repository;
import org.apache.maven.model.building.ModelSource;
/**
@ -64,7 +62,7 @@ public interface ModelResolver {
*
* @see Parent#clone()
*/
ModelSource resolveModel(org.apache.maven.model.Parent parent) throws UnresolvableModelException;
ModelSource resolveModel(Parent parent) throws UnresolvableModelException;
/**
* Tries to resolve the POM for the specified dependency coordinates possibly updating {@code dependency}.
@ -84,7 +82,7 @@ public interface ModelResolver {
*
* @see Dependency#clone()
*/
ModelSource resolveModel(org.apache.maven.model.Dependency dependency) throws UnresolvableModelException;
ModelSource resolveModel(Dependency dependency) throws UnresolvableModelException;
/**
* Adds a repository to use for subsequent resolution requests. The order in which repositories are added matters,
@ -94,20 +92,20 @@ public interface ModelResolver {
* @param repository The repository to add to the internal search chain, must not be {@code null}.
* @throws InvalidRepositoryException If the repository could not be added (e.g. due to invalid URL or layout).
*/
void addRepository(org.apache.maven.model.Repository repository) throws InvalidRepositoryException;
void addRepository(Repository repository) throws InvalidRepositoryException;
/**
* Adds a repository to use for subsequent resolution requests. The order in which repositories are added matters,
* repositories that were added first should also be searched first. When multiple repositories with the same
* identifier are added, then the value of the replace argument determines the behaviour.
* identifier are added, then the value of the replace argument is determines the behaviour.
*
* If replace is false then any existing repository with the same Id will remain in use. If replace
* If replace is false than any existing repository with the same Id will remain in use. If replace
* is true the new repository replaces the original.
*
* @param repository The repository to add to the internal search chain, must not be {@code null}.
* @throws InvalidRepositoryException If the repository could not be added (e.g. due to invalid URL or layout).
*/
void addRepository(org.apache.maven.model.Repository repository, boolean replace) throws InvalidRepositoryException;
void addRepository(Repository repository, boolean replace) throws InvalidRepositoryException;
/**
* Clones this resolver for usage in a forked resolution process. In general, implementors need not provide a deep
@ -117,32 +115,4 @@ public interface ModelResolver {
* @return The cloned resolver, never {@code null}.
*/
ModelResolver newCopy();
default ModelSource resolveModel(Parent parent, AtomicReference<Parent> modified)
throws UnresolvableModelException {
org.apache.maven.model.Parent p = new org.apache.maven.model.Parent(parent);
ModelSource result = resolveModel(p);
if (p.getDelegate() != parent) {
modified.set(p.getDelegate());
}
return result;
}
default ModelSource resolveModel(Dependency dependency, AtomicReference<Dependency> modified)
throws UnresolvableModelException {
org.apache.maven.model.Dependency d = new org.apache.maven.model.Dependency(dependency);
ModelSource result = resolveModel(d);
if (d.getDelegate() != dependency) {
modified.set(d.getDelegate());
}
return result;
}
default void addRepository(Repository repository) throws InvalidRepositoryException {
addRepository(new org.apache.maven.model.Repository(repository));
}
default void addRepository(Repository repository, boolean replace) throws InvalidRepositoryException {
addRepository(new org.apache.maven.model.Repository(repository), replace);
}
}

View File

@ -26,10 +26,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.maven.api.model.InputSource;
import org.apache.maven.model.InputSource;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.ModelProcessor;
@ -43,22 +41,23 @@ import org.apache.maven.model.building.ModelProcessor;
@Deprecated(since = "4.0.0")
public class DefaultSuperPomProvider implements SuperPomProvider {
private final ModelProcessor modelProcessor;
/**
* The cached super POM, lazily created.
*/
private static final Map<String, Model> SUPER_MODELS = new ConcurrentHashMap<>();
private Model superModel;
@Inject
public DefaultSuperPomProvider(ModelProcessor modelProcessor) {
private ModelProcessor modelProcessor;
public DefaultSuperPomProvider setModelProcessor(ModelProcessor modelProcessor) {
this.modelProcessor = modelProcessor;
return this;
}
@Override
public Model getSuperModel(String version) {
return SUPER_MODELS.computeIfAbsent(Objects.requireNonNull(version), v -> {
String resource = "/org/apache/maven/model/pom-" + v + ".xml";
if (superModel == null) {
String resource = "/org/apache/maven/model/pom-" + version + ".xml";
InputStream is = getClass().getResourceAsStream(resource);
@ -68,22 +67,25 @@ public class DefaultSuperPomProvider implements SuperPomProvider {
}
try {
Map<String, Object> options = new HashMap<>(2);
options.put("xml:" + version, "xml:" + version);
Map<String, Object> options = new HashMap<>();
options.put("xml:4.0.0", "xml:4.0.0");
String modelId = "org.apache.maven:maven-model-builder:" + version + "-"
String modelId = "org.apache.maven:maven-model-builder:"
+ this.getClass().getPackage().getImplementationVersion() + ":super-pom";
InputSource inputSource = new InputSource(
modelId, getClass().getResource(resource).toExternalForm());
options.put(ModelProcessor.INPUT_SOURCE, new org.apache.maven.model.InputSource(inputSource));
InputSource inputSource = new InputSource();
inputSource.setModelId(modelId);
inputSource.setLocation(getClass().getResource(resource).toExternalForm());
options.put(ModelProcessor.INPUT_SOURCE, inputSource);
return modelProcessor.read(is, options);
superModel = modelProcessor.read(is, options);
} catch (IOException e) {
throw new IllegalStateException(
"The super POM " + resource + " is damaged"
+ ", please verify the integrity of your Maven installation",
e);
}
});
}
return superModel;
}
}

View File

@ -18,10 +18,7 @@
*/
package org.apache.maven.model.validation;
import java.util.List;
import org.apache.maven.model.Model;
import org.apache.maven.model.Profile;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblemCollector;
@ -32,46 +29,17 @@ import org.apache.maven.model.building.ModelProblemCollector;
*/
@Deprecated(since = "4.0.0")
public interface ModelValidator {
/**
* Checks the specified file model for missing or invalid values. This model is directly created from the POM
* Checks the specified (raw) model for missing or invalid values. The raw model is directly created from the POM
* file and has not been subjected to inheritance, interpolation or profile/default injection.
*
* @param model The model to validate, must not be {@code null}.
* @param request The model building request that holds further settings, must not be {@code null}.
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
*/
default void validateFileModel(Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
// do nothing
}
/**
* Checks the specified (raw) model for missing or invalid values. The raw model is the file model + buildpom filter
* transformation and has not been subjected to inheritance, interpolation or profile/default injection.
*
* @param model The model to validate, must not be {@code null}.
* @param request The model building request that holds further settings, must not be {@code null}.
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
*/
void validateRawModel(Model model, ModelBuildingRequest request, ModelProblemCollector problems);
/**
* Checks the specified (raw) model for clashes with the passed active external profiles. The raw model is the
* file model + buildpom filter transformation and has not been subjected to inheritance, interpolation or profile/default injection.
*
* @param activeExternalProfiles the active profiles coming from external sources (settings.xml), must not be {@code null}
* @param model The model to validate, must not be {@code null}.
* @param request The model building request that holds further settings, must not be {@code null}.
* @param problems The container used to collect problems that were encountered, must not be {@code null}.
* @since 4.0.0
*/
default void validateExternalProfiles(
List<Profile> activeExternalProfiles,
Model model,
ModelBuildingRequest request,
ModelProblemCollector problems) {
// do nothing
}
/**
* Checks the specified (effective) model for missing or invalid values. The effective model is fully assembled and
* has undergone inheritance, interpolation and other model operations.

View File

@ -128,6 +128,11 @@ public class Os {
*/
private static final String DARWIN = "darwin";
/**
* The path separator.
*/
private static final String PATH_SEP = System.getProperty("path.separator");
static {
// Those two public constants are initialized here, as they need all the private constants
// above to be initialized first, but the code style imposes the public constants to be

View File

@ -1,155 +0,0 @@
/*
* 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.model.building;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import org.apache.maven.model.Model;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class BuildModelSourceTransformerTest {
Path pomFile;
TransformerContext context = org.mockito.Mockito.mock(TransformerContext.class);
@Test
void testModelVersion() {
Model initial = new Model(org.apache.maven.api.model.Model.newBuilder()
.namespaceUri("http://maven.apache.org/POM/4.0.0")
.build());
Model expected = new Model(org.apache.maven.api.model.Model.newBuilder()
.namespaceUri("http://maven.apache.org/POM/4.0.0")
.modelVersion("4.0.0")
.build());
Model actual = transform(initial);
assertTrue(equalsDeep(expected, actual));
}
@Test
void testParent() {
Path root = Paths.get(".").toAbsolutePath().normalize();
pomFile = root.resolve("child/pom.xml");
Model parent = new Model(org.apache.maven.api.model.Model.newBuilder()
.groupId("GROUPID")
.artifactId("ARTIFACTID")
.version("1.0-SNAPSHOT")
.build());
Mockito.when(context.getRawModel(pomFile, root.resolve("pom.xml"))).thenReturn(parent);
Mockito.when(context.locate(root)).thenReturn(root.resolve("pom.xml"));
Model initial = new Model(org.apache.maven.api.model.Model.newBuilder()
.parent(org.apache.maven.api.model.Parent.newBuilder()
.groupId("GROUPID")
.artifactId("ARTIFACTID")
.build())
.build());
Model expected = new Model(org.apache.maven.api.model.Model.newBuilder()
.parent(org.apache.maven.api.model.Parent.newBuilder()
.groupId("GROUPID")
.artifactId("ARTIFACTID")
.version("1.0-SNAPSHOT")
.build())
.build());
Model actual = transform(initial);
assertTrue(equalsDeep(expected, actual));
}
@Test
void testReactorDependencies() {
Model dep = new Model(org.apache.maven.api.model.Model.newBuilder()
.groupId("GROUPID")
.artifactId("ARTIFACTID")
.version("1.0-SNAPSHOT")
.build());
Mockito.when(context.getRawModel(pomFile, "GROUPID", "ARTIFACTID")).thenReturn(dep);
Model initial = new Model(org.apache.maven.api.model.Model.newBuilder()
.dependencies(Collections.singleton(org.apache.maven.api.model.Dependency.newBuilder()
.groupId("GROUPID")
.artifactId("ARTIFACTID")
.build()))
.build());
Model expected = new Model(org.apache.maven.api.model.Model.newBuilder()
.dependencies(Collections.singleton(org.apache.maven.api.model.Dependency.newBuilder()
.groupId("GROUPID")
.artifactId("ARTIFACTID")
.version("1.0-SNAPSHOT")
.build()))
.build());
Model actual = transform(initial);
assertTrue(equalsDeep(expected, actual));
}
@Test
void testCiFriendlyVersion() {
Model initial = new Model(org.apache.maven.api.model.Model.newBuilder()
.version("${revision}-${sha1}")
.build());
Mockito.when(context.getUserProperty("revision")).thenReturn("therev");
Mockito.when(context.getUserProperty("sha1")).thenReturn("thesha");
Model expected = new Model(org.apache.maven.api.model.Model.newBuilder()
.version("therev-thesha")
.build());
Model actual = transform(initial);
assertTrue(equalsDeep(expected, actual));
}
Model transform(Model model) {
Model transformed = model.clone();
new BuildModelSourceTransformer().transform(pomFile, context, transformed);
return transformed;
}
public static boolean equalsDeep(Object m1, Object m2) {
try {
if (m1 == m2) {
return true;
}
if (m1 == null || m2 == null) {
return false;
}
if (!Objects.equals(m1.getClass(), m2.getClass())) {
return false;
}
BeanInfo bean = Introspector.getBeanInfo(m1.getClass());
for (PropertyDescriptor prop : bean.getPropertyDescriptors()) {
if (("first".equals(prop.getName()) || "last".equals(prop.getName()))
&& List.class.equals(prop.getReadMethod().getDeclaringClass())) {
continue;
}
Object p1 = prop.getReadMethod().invoke(m1);
Object p2 = prop.getReadMethod().invoke(m2);
if (!equalsDeep(p1, p2)) {
return false;
}
}
return true;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -29,6 +29,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
/**
*/
@Deprecated
class ComplexActivationTest {
private File getPom(String name) {

View File

@ -34,6 +34,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
/**
*/
@Deprecated
class DefaultModelBuilderFactoryTest {
private static final String BASE_DIR =

View File

@ -18,28 +18,24 @@
*/
package org.apache.maven.model.building;
import java.io.File;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.maven.api.model.Dependency;
import org.apache.maven.api.model.Parent;
import org.apache.maven.api.model.Repository;
import org.apache.maven.model.Model;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Parent;
import org.apache.maven.model.Repository;
import org.apache.maven.model.resolution.InvalidRepositoryException;
import org.apache.maven.model.resolution.ModelResolver;
import org.apache.maven.model.resolution.UnresolvableModelException;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
*/
class DefaultModelBuilderTest {
@Deprecated
public class DefaultModelBuilderTest {
private static final String BASE1_ID = "thegroup:base1:pom";
private static final String BASE1_ID2 = "thegroup:base1:1";
private static final String BASE1 = "<project>\n" + " <modelVersion>4.0.0</modelVersion>\n"
+ " <groupId>thegroup</groupId>\n"
@ -60,6 +56,7 @@ class DefaultModelBuilderTest {
+ "</project>\n";
private static final String BASE2_ID = "thegroup:base2:pom";
private static final String BASE2_ID2 = "thegroup:base2:1";
private static final String BASE2 = "<project>\n" + " <modelVersion>4.0.0</modelVersion>\n"
+ " <groupId>thegroup</groupId>\n"
@ -80,7 +77,7 @@ class DefaultModelBuilderTest {
+ "</project>\n";
@Test
void testCycleInImports() throws Exception {
public void testCycleInImports() throws Exception {
ModelBuilder builder = new DefaultModelBuilderFactory().newInstance();
assertNotNull(builder);
@ -93,13 +90,14 @@ class DefaultModelBuilderTest {
static class CycleInImportsResolver extends BaseModelResolver {
@Override
public ModelSource resolveModel(org.apache.maven.model.Dependency dependency)
throws UnresolvableModelException {
return switch (dependency.getManagementKey()) {
case BASE1_ID -> new StringModelSource(BASE1);
case BASE2_ID -> new StringModelSource(BASE2);
default -> null;
};
public ModelSource resolveModel(Dependency dependency) throws UnresolvableModelException {
switch (dependency.getManagementKey()) {
case BASE1_ID:
return new StringModelSource(BASE1);
case BASE2_ID:
return new StringModelSource(BASE2);
}
return null;
}
}
@ -107,18 +105,22 @@ class DefaultModelBuilderTest {
@Override
public ModelSource resolveModel(String groupId, String artifactId, String version)
throws UnresolvableModelException {
switch (groupId + ":" + artifactId + ":" + version) {
case BASE1_ID2:
return new StringModelSource(BASE1);
case BASE2_ID2:
return new StringModelSource(BASE2);
}
return null;
}
@Override
public ModelSource resolveModel(Parent parent, AtomicReference<Parent> modified)
throws UnresolvableModelException {
public ModelSource resolveModel(Parent parent) throws UnresolvableModelException {
return null;
}
@Override
public ModelSource resolveModel(Dependency dependency, AtomicReference<Dependency> modified)
throws UnresolvableModelException {
public ModelSource resolveModel(Dependency dependency) throws UnresolvableModelException {
return null;
}
@ -132,238 +134,5 @@ class DefaultModelBuilderTest {
public ModelResolver newCopy() {
return this;
}
@Override
public ModelSource resolveModel(org.apache.maven.model.Parent parent) throws UnresolvableModelException {
return null;
}
@Override
public ModelSource resolveModel(org.apache.maven.model.Dependency dependency)
throws UnresolvableModelException {
return null;
}
@Override
public void addRepository(org.apache.maven.model.Repository repository) throws InvalidRepositoryException {}
@Override
public void addRepository(org.apache.maven.model.Repository repository, boolean replace)
throws InvalidRepositoryException {}
}
@Test
void testBuildRawModel() throws Exception {
ModelBuilder builder = new DefaultModelBuilderFactory().newInstance();
assertNotNull(builder);
Result<? extends Model> res = builder.buildRawModel(
new File(getClass().getResource("/poms/factory/simple.xml").getFile()),
ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL,
false);
assertNotNull(res.get());
}
/**
* This test has
* - a dependency directly managed to 0.2
* - then a BOM import which manages that same dep to 0.1
* This <i>currently</i> results in 0.2 and a no warning
*/
@Test
void testManagedDependencyBeforeImport() throws Exception {
ModelBuilder builder = new DefaultModelBuilderFactory().newInstance();
assertNotNull(builder);
DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
request.setModelSource(new FileModelSource(new File(
getClass().getResource("/poms/depmgmt/root-dep-first.xml").getFile())));
request.setModelResolver(new BaseModelResolver() {
public ModelSource resolveModel(org.apache.maven.model.Dependency dependency)
throws UnresolvableModelException {
if (dependency.getManagementKey().equals("test:import:pom")) {
return new FileModelSource(new File(
getClass().getResource("/poms/depmgmt/import.xml").getFile()));
}
throw new UnresolvableModelException(
"Cannot resolve", dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion());
}
});
ModelBuildingResult result = builder.build(request);
Dependency dep = result.getEffectiveModel().getDelegate().getDependencyManagement().getDependencies().stream()
.filter(d -> "test:mydep:jar".equals(d.getManagementKey()))
.findFirst()
.get();
assertEquals("0.2", dep.getVersion());
assertEquals(0, result.getProblems().size());
}
/**
* This test has
* - a BOM import which manages the dep to 0.1
* - then a directly managed dependency to 0.2
* This <i>currently</i> results in 0.2 and no warning
*/
@Test
void testManagedDependencyAfterImport() throws Exception {
ModelBuilder builder = new DefaultModelBuilderFactory().newInstance();
assertNotNull(builder);
DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
request.setModelSource(new FileModelSource(new File(
getClass().getResource("/poms/depmgmt/root-dep-last.xml").getFile())));
request.setModelResolver(new BaseModelResolver() {
public ModelSource resolveModel(org.apache.maven.model.Dependency dependency)
throws UnresolvableModelException {
if (dependency.getManagementKey().equals("test:import:pom")) {
return new FileModelSource(new File(
getClass().getResource("/poms/depmgmt/import.xml").getFile()));
}
throw new UnresolvableModelException(
"Cannot resolve", dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion());
}
});
ModelBuildingResult result = builder.build(request);
Dependency dep = result.getEffectiveModel().getDelegate().getDependencyManagement().getDependencies().stream()
.filter(d -> "test:mydep:jar".equals(d.getManagementKey()))
.findFirst()
.get();
assertEquals("0.2", dep.getVersion());
assertEquals(0, result.getProblems().size());
}
/**
* This test has
* - a BOM import which manages dep to 0.3
* - another BOM import which manages the dep to 0.1
* This <i>currently</i> results in 0.3 (first wins) and a warning
*/
@Test
void testManagedDependencyTwoImports() throws Exception {
ModelBuilder builder = new DefaultModelBuilderFactory().newInstance();
assertNotNull(builder);
DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
request.setModelSource(new FileModelSource(new File(
getClass().getResource("/poms/depmgmt/root-two-imports.xml").getFile())));
request.setModelResolver(new BaseModelResolver() {
public ModelSource resolveModel(org.apache.maven.model.Dependency dependency)
throws UnresolvableModelException {
return switch (dependency.getManagementKey()) {
case "test:import:pom" -> new FileModelSource(new File(
getClass().getResource("/poms/depmgmt/import.xml").getFile()));
case "test:other:pom" -> new FileModelSource(new File(getClass()
.getResource("/poms/depmgmt/other-import.xml")
.getFile()));
default -> throw new UnresolvableModelException(
"Cannot resolve",
dependency.getGroupId(),
dependency.getArtifactId(),
dependency.getVersion());
};
}
});
ModelBuildingResult result = builder.build(request);
Dependency dep = result.getEffectiveModel().getDelegate().getDependencyManagement().getDependencies().stream()
.filter(d -> "test:mydep:jar".equals(d.getManagementKey()))
.findFirst()
.get();
assertEquals("0.3", dep.getVersion());
assertEquals(1, result.getProblems().size());
ModelProblem problem = result.getProblems().get(0);
assertTrue(problem.toString().contains("Ignored POM import"));
}
/**
* This test has
* - a BOM import which itself imports the junit BOM which manages the dep to 0.1
* - a BOM import to the junit BOM which manages the dep to 0.2
* This <i>currently</i> results in 0.1 (first wins, unexpected as this is not the closest) and a warning
*/
@Test
void testManagedDependencyDistance() throws Exception {
ModelBuilder builder = new DefaultModelBuilderFactory().newInstance();
assertNotNull(builder);
DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
request.setLocationTracking(true);
request.setModelSource(new FileModelSource(new File(
getClass().getResource("/poms/depmgmt/root-distance.xml").getFile())));
request.setModelResolver(new BaseModelResolver() {
public ModelSource resolveModel(org.apache.maven.model.Dependency dependency)
throws UnresolvableModelException {
return switch (dependency.getManagementKey()) {
case "org.junit:bom:pom" -> new FileModelSource(new File(getClass()
.getResource("/poms/depmgmt/junit-" + dependency.getVersion() + ".xml")
.getFile()));
case "test:other:pom" -> new FileModelSource(new File(getClass()
.getResource("/poms/depmgmt/distant-import.xml")
.getFile()));
default -> throw new UnresolvableModelException(
"Cannot resolve",
dependency.getGroupId(),
dependency.getArtifactId(),
dependency.getVersion());
};
}
});
ModelBuildingResult result = builder.build(request);
Dependency dep = result.getEffectiveModel().getDelegate().getDependencyManagement().getDependencies().stream()
.filter(d -> "org.junit:junit:jar".equals(d.getManagementKey()))
.findFirst()
.get();
assertEquals("0.1", dep.getVersion());
assertEquals(1, result.getProblems().size());
ModelProblem problem = result.getProblems().get(0);
assertTrue(problem.toString().contains("Ignored POM import"));
}
/**
* This test has
* - a BOM import which itself imports the junit BOM which manages the dep to 0.1
* - a BOM import to the junit BOM which manages the dep to 0.2
* - a direct managed dependency to the dep at 0.3 (as suggested by the warning)
* This results in 0.3 (explicit managed wins) and no warning
*/
@Test
void testManagedDependencyDistanceWithExplicit() throws Exception {
ModelBuilder builder = new DefaultModelBuilderFactory().newInstance();
assertNotNull(builder);
DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
request.setLocationTracking(true);
request.setModelSource(new FileModelSource(new File(getClass()
.getResource("/poms/depmgmt/root-distance-explicit.xml")
.getFile())));
request.setModelResolver(new BaseModelResolver() {
public ModelSource resolveModel(org.apache.maven.model.Dependency dependency)
throws UnresolvableModelException {
return switch (dependency.getManagementKey()) {
case "org.junit:bom:pom" -> new FileModelSource(new File(getClass()
.getResource("/poms/depmgmt/junit-" + dependency.getVersion() + ".xml")
.getFile()));
case "test:other:pom" -> new FileModelSource(new File(getClass()
.getResource("/poms/depmgmt/distant-import.xml")
.getFile()));
default -> throw new UnresolvableModelException(
"Cannot resolve",
dependency.getGroupId(),
dependency.getArtifactId(),
dependency.getVersion());
};
}
});
ModelBuildingResult result = builder.build(request);
Dependency dep = result.getEffectiveModel().getDelegate().getDependencyManagement().getDependencies().stream()
.filter(d -> "org.junit:junit:jar".equals(d.getManagementKey()))
.findFirst()
.get();
assertEquals("0.3", dep.getVersion());
assertEquals(0, result.getProblems().size());
}
}

View File

@ -32,6 +32,7 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
* Test that validate the solution of MNG-6261 issue
*
*/
@Deprecated
class FileModelSourceTest {
/**

View File

@ -31,6 +31,7 @@ import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItems;
@Deprecated
class FileToRawModelMergerTest {
/**

View File

@ -29,6 +29,7 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
@Deprecated
public class GraphTest {
@Test

View File

@ -1,42 +0,0 @@
/*
* 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.model.building;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class ModelBuildingExceptionTest {
@Test
void testMessage() {
DefaultModelProblem pb1 =
new DefaultModelProblem("message1", ModelProblem.Severity.ERROR, null, "source", 0, 0, "modelId", null);
DefaultModelProblem pb2 =
new DefaultModelProblem("message2", ModelProblem.Severity.ERROR, null, "source", 0, 0, "modelId", null);
String msg = ModelBuildingException.toMessage("modelId", Arrays.asList(pb1, pb2));
assertEquals(
"2 problems were encountered while building the effective model for modelId" + System.lineSeparator()
+ " - [ERROR] message1" + System.lineSeparator()
+ " - [ERROR] message2",
msg);
}
}

View File

@ -27,6 +27,7 @@ import org.apache.maven.model.Model;
* A simple model problem collector for testing the model building components.
*
*/
@Deprecated
public class SimpleProblemCollector implements ModelProblemCollector {
private Model model;

View File

@ -21,7 +21,7 @@ package org.apache.maven.model.inheritance;
import java.io.File;
import java.io.IOException;
import org.apache.maven.api.model.Model;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.SimpleProblemCollector;
import org.apache.maven.model.io.DefaultModelReader;
import org.apache.maven.model.io.DefaultModelWriter;
@ -36,6 +36,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
/**
*/
@Deprecated
class DefaultInheritanceAssemblerTest {
private DefaultModelReader reader;
@ -45,7 +46,7 @@ class DefaultInheritanceAssemblerTest {
@BeforeEach
void setUp() throws Exception {
reader = new DefaultModelReader(null);
reader = new DefaultModelReader();
writer = new DefaultModelWriter();
assembler = new DefaultInheritanceAssembler();
}
@ -55,7 +56,7 @@ class DefaultInheritanceAssemblerTest {
}
private Model getModel(String name) throws IOException {
return reader.read(getPom(name), null).getDelegate();
return reader.read(getPom(name), null);
}
@Test
@ -170,13 +171,16 @@ class DefaultInheritanceAssemblerTest {
if (fromRepo) {
// when model is read from repo, a stream is used, then pomFile == null
// (has consequences in inheritance algorithm since getProjectDirectory() returns null)
parent = Model.newBuilder(parent, true).pomFile(null).build();
child = Model.newBuilder(child, true).pomFile(null).build();
parent = parent.clone();
parent.setPomFile(null);
child = child.clone();
child.setPomFile(null);
}
SimpleProblemCollector problems = new SimpleProblemCollector();
Model assembled = assembler.assembleModelInheritance(child, parent, null, problems);
Model assembled = child.clone();
assembler.assembleModelInheritance(assembled, parent, null, problems);
// write baseName + "-actual"
File actual = new File(
@ -198,11 +202,11 @@ class DefaultInheritanceAssemblerTest {
SimpleProblemCollector problems = new SimpleProblemCollector();
Model model = assembler.assembleModelInheritance(child, parent, null, problems);
assembler.assembleModelInheritance(child, parent, null, problems);
File actual = new File("target/test-classes/poms/inheritance/module-path-not-artifactId-actual.xml");
writer.write(actual, null, model);
writer.write(actual, null, child);
// check with getPom( "module-path-not-artifactId-effective" )
File expected = getPom("module-path-not-artifactId-expected");

View File

@ -1,111 +0,0 @@
/*
* 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.model.inheritance;
import java.io.InputStream;
import java.io.StringReader;
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.model.v4.MavenMerger;
import org.apache.maven.model.v4.MavenStaxReader;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
class MergerTest {
@Test
void testMergerPreserveLocations() throws Exception {
try (InputStream is = getClass().getResourceAsStream("/poms/factory/complex.xml")) {
InputSource inputSource = new InputSource(null, "classpath:/poms/factory/complex.xml");
Model model = new MavenStaxReader().read(is, true, inputSource);
InputLocation propertiesLocation = model.getLocation("properties");
assertNotNull(propertiesLocation);
assertEquals(13, propertiesLocation.getLineNumber());
assertEquals(5, propertiesLocation.getColumnNumber());
InputLocation filterPropLocation = propertiesLocation.getLocation("my.filter.value");
assertNotNull(filterPropLocation);
assertEquals(14, filterPropLocation.getLineNumber());
assertEquals(31, filterPropLocation.getColumnNumber());
Model model2 = Model.newBuilder(model).build();
propertiesLocation = model2.getLocation("properties");
assertNotNull(propertiesLocation);
assertEquals(13, propertiesLocation.getLineNumber());
assertEquals(5, propertiesLocation.getColumnNumber());
filterPropLocation = propertiesLocation.getLocation("my.filter.value");
assertNotNull(filterPropLocation);
assertEquals(14, filterPropLocation.getLineNumber());
assertEquals(31, filterPropLocation.getColumnNumber());
assertNotNull(model.getLocation("groupId"));
Model mergeInput = new MavenStaxReader()
.read(
new StringReader("<project>\n"
+ " <properties>\n"
+ " <my.prop>my-value</my.prop>\n"
+ " </properties>\n"
+ "</project>"),
true,
new InputSource(null, "merge-input"));
propertiesLocation = mergeInput.getLocation("properties");
assertNotNull(propertiesLocation);
assertEquals(2, propertiesLocation.getLineNumber());
assertEquals(3, propertiesLocation.getColumnNumber());
filterPropLocation = propertiesLocation.getLocation("my.prop");
assertNotNull(filterPropLocation);
assertEquals(3, filterPropLocation.getLineNumber());
assertEquals(22, filterPropLocation.getColumnNumber());
Model result = new MavenMerger().merge(model, mergeInput, true, null);
propertiesLocation = result.getLocation("properties");
assertNotNull(propertiesLocation);
assertEquals(-1, propertiesLocation.getLineNumber());
assertEquals(-1, propertiesLocation.getColumnNumber());
filterPropLocation = propertiesLocation.getLocation("my.filter.value");
assertNotNull(filterPropLocation);
assertEquals(14, filterPropLocation.getLineNumber());
assertEquals(31, filterPropLocation.getColumnNumber());
filterPropLocation = propertiesLocation.getLocation("my.prop");
assertNotNull(filterPropLocation);
assertEquals(3, filterPropLocation.getLineNumber());
assertEquals(22, filterPropLocation.getColumnNumber());
assertNotNull(result.getLocation("groupId"));
result = new DefaultInheritanceAssembler.InheritanceModelMerger().merge(model, mergeInput, true, null);
propertiesLocation = result.getLocation("properties");
assertNotNull(propertiesLocation);
assertEquals(-1, propertiesLocation.getLineNumber());
assertEquals(-1, propertiesLocation.getColumnNumber());
filterPropLocation = propertiesLocation.getLocation("my.filter.value");
assertNotNull(filterPropLocation);
assertEquals(14, filterPropLocation.getLineNumber());
assertEquals(31, filterPropLocation.getColumnNumber());
filterPropLocation = propertiesLocation.getLocation("my.prop");
assertNotNull(filterPropLocation);
assertEquals(3, filterPropLocation.getLineNumber());
assertEquals(22, filterPropLocation.getColumnNumber());
assertNotNull(result.getLocation("groupId"));
}
}
}

View File

@ -19,10 +19,7 @@
package org.apache.maven.model.interpolation;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
@ -33,27 +30,22 @@ import java.util.Map;
import java.util.Properties;
import java.util.TimeZone;
import org.apache.maven.api.model.Build;
import org.apache.maven.api.model.Dependency;
import org.apache.maven.api.model.Model;
import org.apache.maven.api.model.Organization;
import org.apache.maven.api.model.Repository;
import org.apache.maven.api.model.Resource;
import org.apache.maven.api.model.Scm;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.Resource;
import org.apache.maven.model.building.DefaultModelBuildingRequest;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.SimpleProblemCollector;
import org.apache.maven.model.root.RootLocator;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
*/
@Deprecated
public abstract class AbstractModelInterpolatorTest {
private Properties context;
@ -70,6 +62,7 @@ public abstract class AbstractModelInterpolatorTest {
assertEquals(0, collector.getFatals().size(), "Expected no fatals");
}
@SuppressWarnings("SameParameterValue")
protected void assertCollectorState(
int numFatals, int numErrors, int numWarnings, SimpleProblemCollector collector) {
assertEquals(numErrors, collector.getErrors().size(), "Errors");
@ -142,8 +135,11 @@ public abstract class AbstractModelInterpolatorTest {
@Test
public void testShouldNotThrowExceptionOnReferenceToNonExistentValue() throws Exception {
Scm scm = Scm.newBuilder().connection("${test}/somepath").build();
Model model = Model.newBuilder().scm(scm).build();
Model model = new Model(org.apache.maven.api.model.Model.newBuilder()
.scm(org.apache.maven.api.model.Scm.newBuilder()
.connection("${test}/somepath")
.build())
.build());
ModelInterpolator interpolator = createInterpolator();
@ -156,24 +152,29 @@ public abstract class AbstractModelInterpolatorTest {
@Test
public void testShouldThrowExceptionOnRecursiveScmConnectionReference() throws Exception {
Scm scm = Scm.newBuilder()
.connection("${project.scm.connection}/somepath")
.build();
Model model = Model.newBuilder().scm(scm).build();
var model = new Model(org.apache.maven.api.model.Model.newBuilder()
.scm(org.apache.maven.api.model.Scm.newBuilder()
.connection("${project.scm.connection}/somepath")
.build())
.build());
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
interpolator.interpolateModel(model, (Path) null, createModelBuildingRequest(context), collector);
interpolator.interpolateModel(model, null, createModelBuildingRequest(context), collector);
assertCollectorState(0, 1, 0, collector);
}
@Test
public void testShouldNotThrowExceptionOnReferenceToValueContainingNakedExpression() throws Exception {
Scm scm = Scm.newBuilder().connection("${test}/somepath").build();
Map<String, String> props = new HashMap<>();
props.put("test", "test");
Model model = Model.newBuilder().scm(scm).properties(props).build();
Model model = new Model(org.apache.maven.api.model.Model.newBuilder()
.scm(org.apache.maven.api.model.Scm.newBuilder()
.connection("${test}/somepath")
.build())
.properties(props)
.build());
ModelInterpolator interpolator = createInterpolator();
@ -189,10 +190,12 @@ public abstract class AbstractModelInterpolatorTest {
public void shouldInterpolateOrganizationNameCorrectly() throws Exception {
String orgName = "MyCo";
Model model = Model.newBuilder()
Model model = new Model(org.apache.maven.api.model.Model.newBuilder()
.name("${project.organization.name} Tools")
.organization(Organization.newBuilder().name(orgName).build())
.build();
.organization(org.apache.maven.api.model.Organization.newBuilder()
.name(orgName)
.build())
.build());
ModelInterpolator interpolator = createInterpolator();
@ -204,11 +207,12 @@ public abstract class AbstractModelInterpolatorTest {
@Test
public void shouldInterpolateDependencyVersionToSetSameAsProjectVersion() throws Exception {
Model model = Model.newBuilder()
Model model = new Model(org.apache.maven.api.model.Model.newBuilder()
.version("3.8.1")
.dependencies(Collections.singletonList(
Dependency.newBuilder().version("${project.version}").build()))
.build();
.dependencies(Collections.singletonList(org.apache.maven.api.model.Dependency.newBuilder()
.version("${project.version}")
.build()))
.build());
ModelInterpolator interpolator = createInterpolator();
@ -221,11 +225,12 @@ public abstract class AbstractModelInterpolatorTest {
@Test
public void testShouldNotInterpolateDependencyVersionWithInvalidReference() throws Exception {
Model model = Model.newBuilder()
Model model = new Model(org.apache.maven.api.model.Model.newBuilder()
.version("3.8.1")
.dependencies(Collections.singletonList(
Dependency.newBuilder().version("${something}").build()))
.build();
.dependencies(Collections.singletonList(org.apache.maven.api.model.Dependency.newBuilder()
.version("${something}")
.build()))
.build());
/*
// This is the desired behaviour, however there are too many crappy poms in the repo and an issue with the
@ -253,13 +258,13 @@ public abstract class AbstractModelInterpolatorTest {
@Test
public void testTwoReferences() throws Exception {
Model model = Model.newBuilder()
Model model = new Model(org.apache.maven.api.model.Model.newBuilder()
.version("3.8.1")
.artifactId("foo")
.dependencies(Collections.singletonList(Dependency.newBuilder()
.dependencies(Collections.singletonList(org.apache.maven.api.model.Dependency.newBuilder()
.version("${project.artifactId}-${project.version}")
.build()))
.build();
.build());
ModelInterpolator interpolator = createInterpolator();
@ -272,18 +277,18 @@ public abstract class AbstractModelInterpolatorTest {
@Test
public void testBasedir() throws Exception {
Model model = Model.newBuilder()
Model model = new Model(org.apache.maven.api.model.Model.newBuilder()
.version("3.8.1")
.artifactId("foo")
.repositories(Collections.singletonList(Repository.newBuilder()
.repositories(Collections.singletonList(org.apache.maven.api.model.Repository.newBuilder()
.url("file://localhost/${basedir}/temp-repo")
.build()))
.build();
.build());
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel(model, (Path) null, createModelBuildingRequest(context), collector);
Model out = interpolator.interpolateModel(model, null, createModelBuildingRequest(context), collector);
assertProblemFree(collector);
assertEquals(
@ -292,90 +297,23 @@ public abstract class AbstractModelInterpolatorTest {
@Test
public void testBaseUri() throws Exception {
Model model = Model.newBuilder()
Model model = new Model(org.apache.maven.api.model.Model.newBuilder()
.version("3.8.1")
.artifactId("foo")
.repositories(Collections.singletonList(Repository.newBuilder()
.repositories(Collections.singletonList(org.apache.maven.api.model.Repository.newBuilder()
.url("${project.baseUri}/temp-repo")
.build()))
.build();
.build());
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel(model, (Path) null, createModelBuildingRequest(context), collector);
Model out = interpolator.interpolateModel(model, null, createModelBuildingRequest(context), collector);
assertProblemFree(collector);
assertEquals("myBaseUri/temp-repo", (out.getRepositories().get(0)).getUrl());
}
@Test
void testRootDirectory() throws Exception {
Path rootDirectory = Paths.get("myRootDirectory");
Model model = Model.newBuilder()
.version("3.8.1")
.artifactId("foo")
.repositories(Collections.singletonList(Repository.newBuilder()
.url("file:${project.rootDirectory}/temp-repo")
.build()))
.build();
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel(
model, rootDirectory.toFile(), createModelBuildingRequest(context), collector);
assertProblemFree(collector);
assertEquals("file:myRootDirectory/temp-repo", (out.getRepositories().get(0)).getUrl());
}
@Test
void testRootDirectoryWithUri() throws Exception {
Path rootDirectory = Paths.get("myRootDirectory");
Model model = Model.newBuilder()
.version("3.8.1")
.artifactId("foo")
.repositories(Collections.singletonList(Repository.newBuilder()
.url("${project.rootDirectory.uri}/temp-repo")
.build()))
.build();
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel(
model, rootDirectory.toFile(), createModelBuildingRequest(context), collector);
assertProblemFree(collector);
assertEquals(
rootDirectory.resolve("temp-repo").toUri().toString(),
(out.getRepositories().get(0)).getUrl());
}
@Test
void testRootDirectoryWithNull() throws Exception {
Model model = Model.newBuilder()
.version("3.8.1")
.artifactId("foo")
.repositories(Collections.singletonList(Repository.newBuilder()
.url("file:///${project.rootDirectory}/temp-repo")
.build()))
.build();
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
IllegalStateException e = assertThrows(
IllegalStateException.class,
() -> interpolator.interpolateModel(
model, (Path) null, createModelBuildingRequest(context), collector));
assertEquals(RootLocator.UNABLE_TO_FIND_ROOT_PROJECT_MESSAGE, e.getMessage());
}
@Test
public void testEnvars() throws Exception {
context.put("env.HOME", "/path/to/home");
@ -383,7 +321,9 @@ public abstract class AbstractModelInterpolatorTest {
Map<String, String> modelProperties = new HashMap<>();
modelProperties.put("outputDirectory", "${env.HOME}");
Model model = Model.newBuilder().properties(modelProperties).build();
Model model = new Model(org.apache.maven.api.model.Model.newBuilder()
.properties(modelProperties)
.build());
ModelInterpolator interpolator = createInterpolator();
@ -400,7 +340,9 @@ public abstract class AbstractModelInterpolatorTest {
Map<String, String> modelProperties = new HashMap<>();
modelProperties.put("outputDirectory", "${env.DOES_NOT_EXIST}");
Model model = Model.newBuilder().properties(modelProperties).build();
Model model = new Model(org.apache.maven.api.model.Model.newBuilder()
.properties(modelProperties)
.build());
ModelInterpolator interpolator = createInterpolator();
@ -408,7 +350,7 @@ public abstract class AbstractModelInterpolatorTest {
Model out = interpolator.interpolateModel(model, new File("."), createModelBuildingRequest(context), collector);
assertProblemFree(collector);
assertEquals(out.getProperties().get("outputDirectory"), "${env.DOES_NOT_EXIST}");
assertEquals("${env.DOES_NOT_EXIST}", out.getProperties().get("outputDirectory"));
}
@Test
@ -416,7 +358,9 @@ public abstract class AbstractModelInterpolatorTest {
Map<String, String> modelProperties = new HashMap<>();
modelProperties.put("outputDirectory", "${DOES_NOT_EXIST}");
Model model = Model.newBuilder().properties(modelProperties).build();
Model model = new Model(org.apache.maven.api.model.Model.newBuilder()
.properties(modelProperties)
.build());
ModelInterpolator interpolator = createInterpolator();
@ -424,24 +368,24 @@ public abstract class AbstractModelInterpolatorTest {
Model out = interpolator.interpolateModel(model, new File("."), createModelBuildingRequest(context), collector);
assertProblemFree(collector);
assertEquals(out.getProperties().get("outputDirectory"), "${DOES_NOT_EXIST}");
assertEquals("${DOES_NOT_EXIST}", out.getProperties().get("outputDirectory"));
}
@Test
public void shouldInterpolateSourceDirectoryReferencedFromResourceDirectoryCorrectly() throws Exception {
Model model = Model.newBuilder()
.build(Build.newBuilder()
Model model = new Model(org.apache.maven.api.model.Model.newBuilder()
.build(org.apache.maven.api.model.Build.newBuilder()
.sourceDirectory("correct")
.resources(Arrays.asList(Resource.newBuilder()
.resources(List.of(org.apache.maven.api.model.Resource.newBuilder()
.directory("${project.build.sourceDirectory}")
.build()))
.build())
.build();
.build());
ModelInterpolator interpolator = createInterpolator();
final SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel(model, (Path) null, createModelBuildingRequest(context), collector);
Model out = interpolator.interpolateModel(model, null, createModelBuildingRequest(context), collector);
assertCollectorState(0, 0, 0, collector);
List<Resource> outResources = out.getBuild().getResources();
@ -453,11 +397,11 @@ public abstract class AbstractModelInterpolatorTest {
@Test
public void shouldInterpolateUnprefixedBasedirExpression() throws Exception {
File basedir = new File("/test/path");
Model model = Model.newBuilder()
.dependencies(Collections.singletonList(Dependency.newBuilder()
Model model = new Model(org.apache.maven.api.model.Model.newBuilder()
.dependencies(Collections.singletonList(org.apache.maven.api.model.Dependency.newBuilder()
.systemPath("${basedir}/artifact.jar")
.build()))
.build();
.build());
ModelInterpolator interpolator = createInterpolator();
@ -480,11 +424,12 @@ public abstract class AbstractModelInterpolatorTest {
props.put("bb", "${aa}");
DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
Model model = Model.newBuilder().properties(props).build();
Model model = new Model(
org.apache.maven.api.model.Model.newBuilder().properties(props).build());
SimpleProblemCollector collector = new SimpleProblemCollector();
ModelInterpolator interpolator = createInterpolator();
interpolator.interpolateModel(model, (Path) null, request, collector);
interpolator.interpolateModel(model, null, request, collector);
assertCollectorState(0, 2, 0, collector);
assertTrue(collector.getErrors().get(0).contains("Detected the following recursive expression cycle"));
@ -496,11 +441,12 @@ public abstract class AbstractModelInterpolatorTest {
props.put("basedir", "${basedir}");
DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
Model model = Model.newBuilder().properties(props).build();
Model model = new Model(
org.apache.maven.api.model.Model.newBuilder().properties(props).build());
SimpleProblemCollector collector = new SimpleProblemCollector();
ModelInterpolator interpolator = createInterpolator();
interpolator.interpolateModel(model, (Path) null, request, collector);
interpolator.interpolateModel(model, null, request, collector);
assertCollectorState(0, 1, 0, collector);
assertEquals(
@ -508,51 +454,5 @@ public abstract class AbstractModelInterpolatorTest {
collector.getErrors().get(0));
}
@Test
public void shouldIgnorePropertiesWithPomPrefix() throws Exception {
final String orgName = "MyCo";
final String uninterpolatedName = "${pom.organization.name} Tools";
final String interpolatedName = uninterpolatedName;
Model model = Model.newBuilder()
.name(uninterpolatedName)
.organization(Organization.newBuilder().name(orgName).build())
.build();
ModelInterpolator interpolator = createInterpolator();
SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel(
model,
(Path) null,
createModelBuildingRequest(context).setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_4_0),
collector);
assertCollectorState(0, 0, 0, collector);
assertEquals(interpolatedName, out.getName());
}
@Test
public void shouldWarnPropertiesWithPomPrefix() throws Exception {
final String orgName = "MyCo";
final String uninterpolatedName = "${pom.organization.name} Tools";
final String interpolatedName = "MyCo Tools";
Model model = Model.newBuilder()
.name(uninterpolatedName)
.organization(Organization.newBuilder().name(orgName).build())
.build();
ModelInterpolator interpolator = createInterpolator();
SimpleProblemCollector collector = new SimpleProblemCollector();
Model out = interpolator.interpolateModel(
model,
(Path) null,
createModelBuildingRequest(context).setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_1),
collector);
assertCollectorState(0, 0, 1, collector);
assertEquals(interpolatedName, out.getName());
}
protected abstract ModelInterpolator createInterpolator() throws Exception;
}

View File

@ -19,17 +19,17 @@
package org.apache.maven.model.interpolation;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
@Deprecated
class MavenBuildTimestampTest {
@Test
void testMavenBuildTimestampUsesUTC() {
Map<String, String> interpolationProperties = new HashMap<>();
Properties interpolationProperties = new Properties();
interpolationProperties.put("maven.build.timestamp.format", "yyyyMMdd'T'HHmm'Z'");
MavenBuildTimestamp timestamp = new MavenBuildTimestamp(new Date(), interpolationProperties);
String formattedTimestamp = timestamp.formattedTimestamp();

View File

@ -18,8 +18,9 @@
*/
package org.apache.maven.model.interpolation;
@Deprecated
public class StringVisitorModelInterpolatorTest extends AbstractModelInterpolatorTest {
protected ModelInterpolator createInterpolator() {
return new StringVisitorModelInterpolator(null, null, bd -> true);
return new StringVisitorModelInterpolator().setVersionPropertiesProcessor(new DefaultModelVersionProcessor());
}
}

View File

@ -49,6 +49,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
/**
* ReflectionValueExtractorTest class.
*/
@Deprecated
public class ReflectionValueExtractorTest {
private Project project;

View File

@ -25,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
/**
*/
@Deprecated
class DefaultUrlNormalizerTest {
private UrlNormalizer normalizer = new DefaultUrlNormalizer();

Some files were not shown because too many files have changed in this diff Show More