diff --git a/api/maven-api-model/src/main/mdo/maven.mdo b/api/maven-api-model/src/main/mdo/maven.mdo index 2829ffdc22..32fff55632 100644 --- a/api/maven-api-model/src/main/mdo/maven.mdo +++ b/api/maven-api-model/src/main/mdo/maven.mdo @@ -1315,6 +1315,15 @@ ]]> + + 4.0.0/4.0.99 + + public void clearManagementKey() { + managementKey = null; + } + + + diff --git a/api/maven-api-settings/src/main/mdo/settings.mdo b/api/maven-api-settings/src/main/mdo/settings.mdo index 14ac0672b3..86c2820650 100644 --- a/api/maven-api-settings/src/main/mdo/settings.mdo +++ b/api/maven-api-settings/src/main/mdo/settings.mdo @@ -331,6 +331,10 @@ } return profileMap; } + + public void setModelEncoding(String modelEncoding) { + update(getDelegate().with().modelEncoding(modelEncoding).build()); + } ]]> diff --git a/api/maven-api-toolchain/src/main/mdo/toolchains.mdo b/api/maven-api-toolchain/src/main/mdo/toolchains.mdo index b8e2b1bbf8..4b90fd8ac8 100644 --- a/api/maven-api-toolchain/src/main/mdo/toolchains.mdo +++ b/api/maven-api-toolchain/src/main/mdo/toolchains.mdo @@ -102,6 +102,16 @@ + + + 1.0.0/1.1.0 + + public void setModelEncoding(String modelEncoding) { + update(getDelegate().with().modelEncoding(modelEncoding).build()); + } + + + ToolchainModel diff --git a/compat/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/compat/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index 5187a07774..28beaeb51c 100644 --- a/compat/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/compat/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -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() { diff --git a/compat/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java b/compat/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java index e678e62994..b070274c4b 100644 --- a/compat/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java +++ b/compat/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java @@ -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 SI prefix + * (GB, MB, kB) and using the patterns #0.0 for numbers between 1 and 10 + * and ###0 for numbers between 10 and 1000+ by default. + * + * @see https://en.wikipedia.org/wiki/Metric_prefix + * @see https://en.wikipedia.org/wiki/Binary_prefix + * @see https://en.wikipedia.org/wiki/Octet_(computing) + */ + // 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()); } } diff --git a/compat/maven-embedder/src/main/java/org/apache/maven/cli/transfer/BatchModeMavenTransferListener.java b/compat/maven-embedder/src/main/java/org/apache/maven/cli/transfer/BatchModeMavenTransferListener.java new file mode 100644 index 0000000000..2e13e5b134 --- /dev/null +++ b/compat/maven-embedder/src/main/java/org/apache/maven/cli/transfer/BatchModeMavenTransferListener.java @@ -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); + } +} diff --git a/compat/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java b/compat/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java index c03d001491..9146d6b720 100644 --- a/compat/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java +++ b/compat/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java @@ -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 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 transfers = + Collections.synchronizedMap(new LinkedHashMap()); 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 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 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; + } + } } diff --git a/compat/maven-embedder/src/test/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListenerTest.java b/compat/maven-embedder/src/test/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListenerTest.java deleted file mode 100644 index 8a7f4426f5..0000000000 --- a/compat/maven-embedder/src/test/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListenerTest.java +++ /dev/null @@ -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 output = new ConcurrentHashMap(); - - 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(); - } -} diff --git a/compat/maven-model-builder/pom.xml b/compat/maven-model-builder/pom.xml index 31b91726bc..1731dbda56 100644 --- a/compat/maven-model-builder/pom.xml +++ b/compat/maven-model-builder/pom.xml @@ -67,6 +67,10 @@ under the License. org.apache.maven maven-model + + org.apache.maven + maven-artifact + org.apache.maven maven-builder-support @@ -93,6 +97,10 @@ under the License. org.eclipse.sisu.inject provided + + org.codehaus.plexus + plexus-utils + @@ -115,11 +123,6 @@ under the License. xmlunit-matchers test - - org.codehaus.plexus - plexus-utils - test - @@ -141,52 +144,50 @@ under the License. - org.apache.maven.model.building.DefaultModelBuilder#DefaultModelBuilder():CONSTRUCTOR_REMOVED - org.apache.maven.model.building.DefaultModelProcessor#setModelLocator(org.apache.maven.model.locator.ModelLocator):METHOD_REMOVED - org.apache.maven.model.building.DefaultModelProcessor#setModelReader(org.apache.maven.model.io.ModelReader):METHOD_REMOVED - org.apache.maven.model.building.DefaultModelProcessor#DefaultModelProcessor():CONSTRUCTOR_REMOVED - org.apache.maven.model.building.ModelCache#get(java.lang.String,java.lang.String,java.lang.String,java.lang.String):METHOD_REMOVED - org.apache.maven.model.building.ModelCache#put(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.Object):METHOD_REMOVED - 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 - 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 - org.apache.maven.model.inheritance.DefaultInheritanceAssembler - 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 - org.apache.maven.model.interpolation.AbstractStringBasedModelInterpolator - org.apache.maven.model.interpolation.StringSearchModelInterpolator - org.apache.maven.model.interpolation.StringVisitorModelInterpolator - org.apache.maven.model.io.DefaultModelReader#DefaultModelReader():CONSTRUCTOR_REMOVED - org.apache.maven.model.locator.ModelLocator#locateExistingPom(java.io.File):METHOD_NEW_DEFAULT - org.apache.maven.model.management.DefaultDependencyManagementInjector$ManagementModelMerger - org.apache.maven.model.management.DefaultPluginManagementInjector$ManagementModelMerger - org.apache.maven.model.merge.MavenModelMerger - org.apache.maven.model.normalization.DefaultModelNormalizer$DuplicateMerger#mergePlugin(org.apache.maven.model.Plugin,org.apache.maven.model.Plugin):METHOD_REMOVED - org.apache.maven.model.normalization.DefaultModelNormalizer$DuplicateMerger:METHOD_REMOVED_IN_SUPERCLASS - org.apache.maven.model.path.DefaultModelPathTranslator#setPathTranslator(org.apache.maven.model.path.PathTranslator):METHOD_REMOVED - org.apache.maven.model.path.DefaultModelPathTranslator#DefaultModelPathTranslator():CONSTRUCTOR_REMOVED - org.apache.maven.model.path.DefaultModelUrlNormalizer#setUrlNormalizer(org.apache.maven.model.path.UrlNormalizer):METHOD_REMOVED - org.apache.maven.model.path.DefaultModelUrlNormalizer#DefaultModelUrlNormalizer():CONSTRUCTOR_REMOVED - org.apache.maven.model.path.ProfileActivationFilePathInterpolator#setPathTranslator(org.apache.maven.model.path.PathTranslator):METHOD_REMOVED - org.apache.maven.model.path.ProfileActivationFilePathInterpolator#ProfileActivationFilePathInterpolator():CONSTRUCTOR_REMOVED - org.apache.maven.model.profile.activation.FileProfileActivator#setProfileActivationFilePathInterpolator(org.apache.maven.model.path.ProfileActivationFilePathInterpolator):METHOD_REMOVED - org.apache.maven.model.profile.activation.FileProfileActivator#FileProfileActivator():CONSTRUCTOR_REMOVED - org.apache.maven.model.profile.DefaultProfileInjector - 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 - 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 - 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 - org.apache.maven.model.resolution.InvalidRepositoryException#getRepository():METHOD_RETURN_TYPE_CHANGED - org.apache.maven.model.resolution.InvalidRepositoryException#InvalidRepositoryException(java.lang.String,org.apache.maven.model.Repository,java.lang.Throwable):CONSTRUCTOR_REMOVED - org.apache.maven.model.resolution.InvalidRepositoryException#InvalidRepositoryException(java.lang.String,org.apache.maven.model.Repository):CONSTRUCTOR_REMOVED - org.apache.maven.model.resolution.ModelResolver#addRepository(org.apache.maven.api.model.Repository):METHOD_NEW_DEFAULT - org.apache.maven.model.resolution.ModelResolver#addRepository(org.apache.maven.api.model.Repository,boolean):METHOD_NEW_DEFAULT - org.apache.maven.model.resolution.ModelResolver#resolveModel(org.apache.maven.api.model.Parent,java.util.concurrent.atomic.AtomicReference):METHOD_NEW_DEFAULT - org.apache.maven.model.resolution.ModelResolver#resolveModel(org.apache.maven.api.model.Dependency,java.util.concurrent.atomic.AtomicReference):METHOD_NEW_DEFAULT - org.apache.maven.model.superpom.DefaultSuperPomProvider#getSuperModel(java.lang.String):METHOD_RETURN_TYPE_CHANGED - org.apache.maven.model.superpom.DefaultSuperPomProvider#setModelProcessor(org.apache.maven.model.building.ModelProcessor):METHOD_REMOVED - org.apache.maven.model.superpom.DefaultSuperPomProvider#DefaultSuperPomProvider():CONSTRUCTOR_REMOVED - org.apache.maven.model.superpom.SuperPomProvider#getSuperModel(java.lang.String):METHOD_RETURN_TYPE_CHANGED - org.apache.maven.model.validation.DefaultModelValidator#validateDependencyVersion(org.apache.maven.model.building.ModelProblemCollector,org.apache.maven.model.Dependency,java.lang.String):METHOD_REMOVED - 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 - 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/BuildModelSourceTransformer.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/BuildModelSourceTransformer.java deleted file mode 100644 index f0c01c81c6..0000000000 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/BuildModelSourceTransformer.java +++ /dev/null @@ -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 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 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 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; - } - } -} diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java index 8dd4de675c..4bb75270a4 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java @@ -24,10 +24,9 @@ import javax.inject.Singleton; import java.io.File; import java.io.IOException; -import java.lang.reflect.Field; -import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; @@ -36,37 +35,31 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Properties; -import java.util.concurrent.Callable; -import java.util.function.Supplier; -import java.util.function.UnaryOperator; -import java.util.stream.Collectors; -import java.util.stream.Stream; +import java.util.function.Consumer; +import java.util.stream.IntStream; -import org.apache.maven.api.VersionRange; -import org.apache.maven.api.model.ActivationFile; -import org.apache.maven.api.model.Exclusion; -import org.apache.maven.api.model.InputSource; -import org.apache.maven.api.services.VersionParserException; -import org.apache.maven.api.services.model.ModelVersionParser; -import org.apache.maven.building.Source; +import org.apache.maven.artifact.versioning.DefaultArtifactVersion; +import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; +import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.model.Activation; import org.apache.maven.model.Build; import org.apache.maven.model.Dependency; import org.apache.maven.model.DependencyManagement; import org.apache.maven.model.InputLocation; +import org.apache.maven.model.InputLocationTracker; +import org.apache.maven.model.InputSource; import org.apache.maven.model.Model; import org.apache.maven.model.Parent; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginManagement; import org.apache.maven.model.Profile; +import org.apache.maven.model.Repository; import org.apache.maven.model.building.ModelProblem.Severity; import org.apache.maven.model.building.ModelProblem.Version; import org.apache.maven.model.composition.DependencyManagementImporter; import org.apache.maven.model.inheritance.InheritanceAssembler; import org.apache.maven.model.interpolation.ModelInterpolator; -import org.apache.maven.model.interpolation.ModelVersionProcessor; import org.apache.maven.model.io.ModelParseException; -import org.apache.maven.model.io.ModelReader; import org.apache.maven.model.management.DependencyManagementInjector; import org.apache.maven.model.management.PluginManagementInjector; import org.apache.maven.model.normalization.ModelNormalizer; @@ -86,609 +79,178 @@ import org.apache.maven.model.resolution.ModelResolver; import org.apache.maven.model.resolution.UnresolvableModelException; import org.apache.maven.model.resolution.WorkspaceModelResolver; import org.apache.maven.model.superpom.SuperPomProvider; -import org.apache.maven.model.v4.MavenTransformer; -import org.apache.maven.model.validation.DefaultModelValidator; import org.apache.maven.model.validation.ModelValidator; import org.codehaus.plexus.interpolation.InterpolationException; -import org.codehaus.plexus.interpolation.Interpolator; import org.codehaus.plexus.interpolation.MapBasedValueSource; import org.codehaus.plexus.interpolation.RegexBasedInterpolator; import org.codehaus.plexus.interpolation.StringSearchInterpolator; +import org.codehaus.plexus.util.StringUtils; import org.eclipse.sisu.Nullable; -import static org.apache.maven.api.services.ModelBuilder.MODEL_VERSION_4_0_0; import static org.apache.maven.model.building.Result.error; import static org.apache.maven.model.building.Result.newResult; /** * @deprecated use {@link org.apache.maven.api.services.ModelBuilder} instead */ +@SuppressWarnings("UnusedReturnValue") @Named @Singleton @Deprecated(since = "4.0.0") public class DefaultModelBuilder implements ModelBuilder { - - private final ModelProcessor modelProcessor; - private final ModelValidator modelValidator; - private final ModelNormalizer modelNormalizer; - private final ModelInterpolator modelInterpolator; - private final ModelPathTranslator modelPathTranslator; - private final ModelUrlNormalizer modelUrlNormalizer; - private final SuperPomProvider superPomProvider; - private final InheritanceAssembler inheritanceAssembler; - private final ProfileSelector profileSelector; - private final ProfileInjector profileInjector; - private final PluginManagementInjector pluginManagementInjector; - private final DependencyManagementInjector dependencyManagementInjector; - private final DependencyManagementImporter dependencyManagementImporter; - private final LifecycleBindingsInjector lifecycleBindingsInjector; - private final PluginConfigurationExpander pluginConfigurationExpander; - private final ReportConfigurationExpander reportConfigurationExpander; - private final ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator; - private final ModelVersionProcessor versionProcessor; - private final ModelSourceTransformer transformer; - private final ModelVersionParser versionParser; - - @SuppressWarnings("checkstyle:ParameterNumber") @Inject - public DefaultModelBuilder( - ModelProcessor modelProcessor, - ModelValidator modelValidator, - ModelNormalizer modelNormalizer, - ModelInterpolator modelInterpolator, - ModelPathTranslator modelPathTranslator, - ModelUrlNormalizer modelUrlNormalizer, - SuperPomProvider superPomProvider, - InheritanceAssembler inheritanceAssembler, - ProfileSelector profileSelector, - ProfileInjector profileInjector, - PluginManagementInjector pluginManagementInjector, - DependencyManagementInjector dependencyManagementInjector, - DependencyManagementImporter dependencyManagementImporter, - @Nullable LifecycleBindingsInjector lifecycleBindingsInjector, - PluginConfigurationExpander pluginConfigurationExpander, - ReportConfigurationExpander reportConfigurationExpander, - ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator, - ModelVersionProcessor versionProcessor, - ModelSourceTransformer transformer, - ModelVersionParser versionParser) { - this.modelProcessor = modelProcessor; - this.modelValidator = modelValidator; - this.modelNormalizer = modelNormalizer; - this.modelInterpolator = modelInterpolator; - this.modelPathTranslator = modelPathTranslator; - this.modelUrlNormalizer = modelUrlNormalizer; - this.superPomProvider = superPomProvider; - this.inheritanceAssembler = inheritanceAssembler; - this.profileSelector = profileSelector; - this.profileInjector = profileInjector; - this.pluginManagementInjector = pluginManagementInjector; - this.dependencyManagementInjector = dependencyManagementInjector; - this.dependencyManagementImporter = dependencyManagementImporter; - this.lifecycleBindingsInjector = lifecycleBindingsInjector; - this.pluginConfigurationExpander = pluginConfigurationExpander; - this.reportConfigurationExpander = reportConfigurationExpander; - this.profileActivationFilePathInterpolator = profileActivationFilePathInterpolator; - this.versionProcessor = versionProcessor; - this.transformer = transformer; - this.versionParser = versionParser; - } + private ModelProcessor modelProcessor; + + @Inject + private ModelValidator modelValidator; + + @Inject + private ModelNormalizer modelNormalizer; + + @Inject + private ModelInterpolator modelInterpolator; + + @Inject + private ModelPathTranslator modelPathTranslator; + + @Inject + private ModelUrlNormalizer modelUrlNormalizer; + + @Inject + private SuperPomProvider superPomProvider; + + @Inject + private InheritanceAssembler inheritanceAssembler; + + @Inject + private ProfileSelector profileSelector; + + @Inject + private ProfileInjector profileInjector; + + @Inject + private PluginManagementInjector pluginManagementInjector; + + @Inject + private DependencyManagementInjector dependencyManagementInjector; + + @Inject + private DependencyManagementImporter dependencyManagementImporter; + + @Inject + @Nullable + private LifecycleBindingsInjector lifecycleBindingsInjector; + + @Inject + private PluginConfigurationExpander pluginConfigurationExpander; + + @Inject + private ReportConfigurationExpander reportConfigurationExpander; + + @Inject + private ReportingConverter reportingConverter; + + @Inject + private ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator; - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setModelProcessor(ModelProcessor) - */ - @Deprecated public DefaultModelBuilder setModelProcessor(ModelProcessor modelProcessor) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setModelProcessor(ModelProcessor) - */ - @Deprecated - public DefaultModelBuilder setModelValidator(ModelValidator modelValidator) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setModelNormalizer(ModelNormalizer) - */ - @Deprecated - public DefaultModelBuilder setModelNormalizer(ModelNormalizer modelNormalizer) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setModelInterpolator(ModelInterpolator) - */ - @Deprecated - public DefaultModelBuilder setModelInterpolator(ModelInterpolator modelInterpolator) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setModelPathTranslator(ModelPathTranslator) - */ - @Deprecated - public DefaultModelBuilder setModelPathTranslator(ModelPathTranslator modelPathTranslator) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setModelUrlNormalizer(ModelUrlNormalizer) - */ - @Deprecated - public DefaultModelBuilder setModelUrlNormalizer(ModelUrlNormalizer modelUrlNormalizer) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setSuperPomProvider(SuperPomProvider) - */ - @Deprecated - public DefaultModelBuilder setSuperPomProvider(SuperPomProvider superPomProvider) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setInheritanceAssembler(InheritanceAssembler) - */ - @Deprecated - public DefaultModelBuilder setInheritanceAssembler(InheritanceAssembler inheritanceAssembler) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setProfileSelector(ProfileSelector) - */ - @Deprecated - public DefaultModelBuilder setProfileSelector(ProfileSelector profileSelector) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setProfileInjector(ProfileInjector) - */ - @Deprecated - public DefaultModelBuilder setProfileInjector(ProfileInjector profileInjector) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setPluginManagementInjector(PluginManagementInjector) - */ - @Deprecated - public DefaultModelBuilder setPluginManagementInjector(PluginManagementInjector pluginManagementInjector) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setDependencyManagementInjector(DependencyManagementInjector) - */ - @Deprecated - public DefaultModelBuilder setDependencyManagementInjector( - DependencyManagementInjector dependencyManagementInjector) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setDependencyManagementImporter(DependencyManagementImporter) - */ - @Deprecated - public DefaultModelBuilder setDependencyManagementImporter( - DependencyManagementImporter dependencyManagementImporter) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setLifecycleBindingsInjector(LifecycleBindingsInjector) - */ - @Deprecated - public DefaultModelBuilder setLifecycleBindingsInjector(LifecycleBindingsInjector lifecycleBindingsInjector) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setPluginConfigurationExpander(PluginConfigurationExpander) - */ - @Deprecated - public DefaultModelBuilder setPluginConfigurationExpander(PluginConfigurationExpander pluginConfigurationExpander) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setReportConfigurationExpander(ReportConfigurationExpander) - */ - @Deprecated - public DefaultModelBuilder setReportConfigurationExpander(ReportConfigurationExpander reportConfigurationExpander) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setProfileActivationFilePathInterpolator(ProfileActivationFilePathInterpolator) - */ - @Deprecated - public DefaultModelBuilder setProfileActivationFilePathInterpolator( - ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator) { - return new DefaultModelBuilder( - modelProcessor, - modelValidator, - modelNormalizer, - modelInterpolator, - modelPathTranslator, - modelUrlNormalizer, - superPomProvider, - inheritanceAssembler, - profileSelector, - profileInjector, - pluginManagementInjector, - dependencyManagementInjector, - dependencyManagementImporter, - lifecycleBindingsInjector, - pluginConfigurationExpander, - reportConfigurationExpander, - profileActivationFilePathInterpolator, - versionProcessor, - transformer, - versionParser); - } - - /** - * @deprecated since Maven 4 - * @see DefaultModelBuilderFactory#setReportingConverter(ReportingConverter) - */ - @Deprecated - public DefaultModelBuilder setReportingConverter(ReportingConverter reportingConverter) { + this.modelProcessor = modelProcessor; return this; } - @Override - public DefaultTransformerContextBuilder newTransformerContextBuilder() { - return new DefaultTransformerContextBuilder(this); + public DefaultModelBuilder setModelValidator(ModelValidator modelValidator) { + this.modelValidator = modelValidator; + return this; } + public DefaultModelBuilder setModelNormalizer(ModelNormalizer modelNormalizer) { + this.modelNormalizer = modelNormalizer; + return this; + } + + public DefaultModelBuilder setModelInterpolator(ModelInterpolator modelInterpolator) { + this.modelInterpolator = modelInterpolator; + return this; + } + + public DefaultModelBuilder setModelPathTranslator(ModelPathTranslator modelPathTranslator) { + this.modelPathTranslator = modelPathTranslator; + return this; + } + + public DefaultModelBuilder setModelUrlNormalizer(ModelUrlNormalizer modelUrlNormalizer) { + this.modelUrlNormalizer = modelUrlNormalizer; + return this; + } + + public DefaultModelBuilder setSuperPomProvider(SuperPomProvider superPomProvider) { + this.superPomProvider = superPomProvider; + return this; + } + + public DefaultModelBuilder setProfileSelector(ProfileSelector profileSelector) { + this.profileSelector = profileSelector; + return this; + } + + public DefaultModelBuilder setProfileInjector(ProfileInjector profileInjector) { + this.profileInjector = profileInjector; + return this; + } + + public DefaultModelBuilder setInheritanceAssembler(InheritanceAssembler inheritanceAssembler) { + this.inheritanceAssembler = inheritanceAssembler; + return this; + } + + public DefaultModelBuilder setDependencyManagementImporter(DependencyManagementImporter depMgmtImporter) { + this.dependencyManagementImporter = depMgmtImporter; + return this; + } + + public DefaultModelBuilder setDependencyManagementInjector(DependencyManagementInjector depMgmtInjector) { + this.dependencyManagementInjector = depMgmtInjector; + return this; + } + + public DefaultModelBuilder setLifecycleBindingsInjector(LifecycleBindingsInjector lifecycleBindingsInjector) { + this.lifecycleBindingsInjector = lifecycleBindingsInjector; + return this; + } + + public DefaultModelBuilder setPluginConfigurationExpander(PluginConfigurationExpander pluginConfigurationExpander) { + this.pluginConfigurationExpander = pluginConfigurationExpander; + return this; + } + + public DefaultModelBuilder setPluginManagementInjector(PluginManagementInjector pluginManagementInjector) { + this.pluginManagementInjector = pluginManagementInjector; + return this; + } + + public DefaultModelBuilder setReportConfigurationExpander(ReportConfigurationExpander reportConfigurationExpander) { + this.reportConfigurationExpander = reportConfigurationExpander; + return this; + } + + public DefaultModelBuilder setReportingConverter(ReportingConverter reportingConverter) { + this.reportingConverter = reportingConverter; + return this; + } + + public DefaultModelBuilder setProfileActivationFilePathInterpolator( + ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator) { + this.profileActivationFilePathInterpolator = profileActivationFilePathInterpolator; + return this; + } + + @SuppressWarnings("checkstyle:methodlength") @Override public ModelBuildingResult build(ModelBuildingRequest request) throws ModelBuildingException { - return build(request, new LinkedHashSet<>()); + return build(request, new LinkedHashSet()); } + @SuppressWarnings("checkstyle:methodlength") protected ModelBuildingResult build(ModelBuildingRequest request, Collection importIds) throws ModelBuildingException { // phase 1 @@ -697,32 +259,13 @@ public class DefaultModelBuilder implements ModelBuilder { DefaultModelProblemCollector problems = new DefaultModelProblemCollector(result); // read and validate raw model - Model fileModel = readFileModel(request, problems); - - request.setFileModel(fileModel); - result.setFileModel(fileModel.clone()); - - activateFileModel(request, result, problems); - - if (!request.isTwoPhaseBuilding()) { - return build(request, result, importIds); - } else if (hasModelErrors(problems)) { - throw problems.newModelBuildingException(); + Model inputModel = request.getRawModel(); + if (inputModel == null) { + inputModel = readModel(request.getModelSource(), request.getPomFile(), request, problems); } - return result; - } - - private void activateFileModel( - final ModelBuildingRequest request, - final DefaultModelBuildingResult result, - DefaultModelProblemCollector problems) - throws ModelBuildingException { - Model inputModel = request.getFileModel(); - problems.setRootModel(inputModel); - // profile activation - DefaultProfileActivationContext profileActivationContext = getProfileActivationContext(request); + DefaultProfileActivationContext profileActivationContext = getProfileActivationContext(request, inputModel); problems.setSource("(external profiles)"); List activeExternalProfiles = @@ -739,124 +282,90 @@ public class DefaultModelBuilder implements ModelBuilder { profileActivationContext.setUserProperties(profileProps); } - profileActivationContext.setProjectProperties(inputModel.getDelegate().getProperties()); - problems.setSource(inputModel); - List activePomProfiles = - profileSelector.getActiveProfiles(inputModel.getProfiles(), profileActivationContext, problems); - - // model normalization - problems.setSource(inputModel); - inputModel.update(modelNormalizer.mergeDuplicates(inputModel.getDelegate(), request, problems)); - - Map interpolatedActivations = getProfileActivations(inputModel, false); - injectProfileActivations(inputModel, interpolatedActivations); - - // profile injection - for (Profile activeProfile : activePomProfiles) { - profileInjector.injectProfile(inputModel, activeProfile, request, problems); - } - - modelValidator.validateExternalProfiles(activeExternalProfiles, inputModel, request, problems); - for (Profile activeProfile : activeExternalProfiles) { - profileInjector.injectProfile(inputModel, activeProfile, request, problems); - } - } - - @SuppressWarnings("checkstyle:methodlength") - private Model readEffectiveModel( - final ModelBuildingRequest request, - final DefaultModelBuildingResult result, - DefaultModelProblemCollector problems) - throws ModelBuildingException { - Model inputModel = readRawModel(request, problems); - if (problems.hasFatalErrors()) { - throw problems.newModelBuildingException(); - } - problems.setRootModel(inputModel); ModelData resultData = new ModelData(request.getModelSource(), inputModel); - String superModelVersion = - inputModel.getModelVersion() != null ? inputModel.getModelVersion() : MODEL_VERSION_4_0_0; - if (!DefaultModelValidator.VALID_MODEL_VERSIONS.contains(superModelVersion)) { - // Maven 3.x is always using 4.0.0 version to load the supermodel, so - // do the same when loading a dependency. The model validator will also - // check that field later. - superModelVersion = MODEL_VERSION_4_0_0; - } - ModelData superData = new ModelData(null, getSuperModel(superModelVersion)); - - // profile activation - DefaultProfileActivationContext profileActivationContext = getProfileActivationContext(request); - - List activeExternalProfiles = result.getActiveExternalProfiles(); - - if (!activeExternalProfiles.isEmpty()) { - Properties profileProps = new Properties(); - for (Profile profile : activeExternalProfiles) { - profileProps.putAll(profile.getProperties()); - } - profileProps.putAll(profileActivationContext.getUserProperties()); - profileActivationContext.setUserProperties(profileProps); - } + ModelData superData = new ModelData(null, getSuperModel()); Collection parentIds = new LinkedHashSet<>(); + List lineage = new ArrayList<>(); - List lineage = new ArrayList<>(); + for (ModelData currentData = resultData; currentData != null; ) { + lineage.add(currentData); - for (ModelData currentData = resultData; ; ) { - String modelId = currentData.getId(); - result.addModelId(modelId); + Model rawModel = currentData.getModel(); + currentData.setRawModel(rawModel); - Model model = currentData.getModel(); - result.setRawModel(modelId, model); - problems.setSource(model); - org.apache.maven.api.model.Model modelv4 = model.getDelegate(); + Model tmpModel = rawModel.clone(); + currentData.setModel(tmpModel); + + problems.setSource(tmpModel); // model normalization - modelv4 = modelNormalizer.mergeDuplicates(modelv4, request, problems); + modelNormalizer.mergeDuplicates(tmpModel, request, problems); - // profile activation - profileActivationContext.setProjectProperties(modelv4.getProperties()); + profileActivationContext.setProjectProperties(tmpModel.getProperties()); - List interpolatedProfiles = - interpolateActivations(modelv4.getProfiles(), profileActivationContext, problems); + List interpolatedProfiles = getInterpolatedProfiles(rawModel, profileActivationContext, problems); + tmpModel.setProfiles(interpolatedProfiles); + + List activePomProfiles = + profileSelector.getActiveProfiles(tmpModel.getProfiles(), profileActivationContext, problems); + + List rawProfiles = new ArrayList<>(); + for (Profile activePomProfile : activePomProfiles) { + rawProfiles.add(rawModel.getProfiles().get(interpolatedProfiles.indexOf(activePomProfile))); + } + currentData.setActiveProfiles(rawProfiles); // profile injection - List activePomProfiles = - profileSelector.getActiveProfilesV4(interpolatedProfiles, profileActivationContext, problems); - result.setActivePomProfiles( - modelId, activePomProfiles.stream().map(Profile::new).collect(Collectors.toList())); - modelv4 = profileInjector.injectProfiles(modelv4, activePomProfiles, request, problems); - if (currentData == resultData) { - for (Profile activeProfile : activeExternalProfiles) { - modelv4 = profileInjector.injectProfile(modelv4, activeProfile.getDelegate(), request, problems); - } + for (Profile activeProfile : activePomProfiles) { + profileInjector.injectProfile(tmpModel, activeProfile, request, problems); } - lineage.add(new Model(modelv4)); + if (currentData == resultData) { + for (Profile activeProfile : activeExternalProfiles) { + profileInjector.injectProfile(tmpModel, activeProfile, request, problems); + } + } if (currentData == superData) { break; } - // add repositories specified by the current model so that we can resolve the parent - configureResolver(request.getModelResolver(), modelv4, problems, false); + configureResolver(request.getModelResolver(), tmpModel, problems); - // we pass a cloned model, so that resolving the parent version does not affect the returned model - ModelData parentData = readParent(new Model(modelv4), currentData.getSource(), request, problems); + ModelData parentData = readParent(tmpModel, currentData.getSource(), request, problems); if (parentData == null) { currentData = superData; + } else if (currentData == resultData) { // First iteration - add initial id after version resolution. + currentData.setGroupId( + currentData.getRawModel().getGroupId() == null + ? parentData.getGroupId() + : currentData.getRawModel().getGroupId()); + + currentData.setVersion( + currentData.getRawModel().getVersion() == null + ? parentData.getVersion() + : currentData.getRawModel().getVersion()); + + currentData.setArtifactId(currentData.getRawModel().getArtifactId()); + parentIds.add(currentData.getId()); + // Reset - only needed for 'getId'. + currentData.setGroupId(null); + currentData.setArtifactId(null); + currentData.setVersion(null); + currentData = parentData; } else if (!parentIds.add(parentData.getId())) { - StringBuilder message = new StringBuilder("The parents form a cycle: "); - for (String parentId : parentIds) { - message.append(parentId).append(" -> "); + String message = "The parents form a cycle: "; + for (String modelId : parentIds) { + message += modelId + " -> "; } - message.append(parentData.getId()); + message += parentData.getId(); problems.add(new ModelProblemCollectorRequest(ModelProblem.Severity.FATAL, ModelProblem.Version.BASE) - .setMessage(message.toString())); + .setMessage(message)); throw problems.newModelBuildingException(); } else { @@ -864,166 +373,144 @@ public class DefaultModelBuilder implements ModelBuilder { } } - Model tmpModel = lineage.get(0); - - // inject interpolated activations - List interpolated = - interpolateActivations(tmpModel.getDelegate().getProfiles(), profileActivationContext, problems); - if (interpolated != tmpModel.getDelegate().getProfiles()) { - tmpModel.update(tmpModel.getDelegate().withProfiles(interpolated)); - } - - // inject external profile into current model - tmpModel.update(profileInjector.injectProfiles( - tmpModel.getDelegate(), - activeExternalProfiles.stream().map(Profile::getDelegate).collect(Collectors.toList()), - request, - problems)); - + problems.setSource(inputModel); checkPluginVersions(lineage, request, problems); // inheritance assembly - Model resultModel = assembleInheritance(lineage, request, problems); + assembleInheritance(lineage, request, problems); - // consider caching inherited model + Model resultModel = resultData.getModel(); problems.setSource(resultModel); problems.setRootModel(resultModel); // model interpolation resultModel = interpolateModel(resultModel, request, problems); + resultData.setModel(resultModel); + + if (resultModel.getParent() != null) { + final ModelData parentData = lineage.get(1); + if (parentData.getVersion() == null || parentData.getVersion().contains("${")) { + final Model interpolatedParent = interpolateModel(parentData.getModel(), request, problems); + // parentData.setModel( interpolatedParent ); + parentData.setVersion(interpolatedParent.getVersion()); + } + } // url normalization modelUrlNormalizer.normalize(resultModel, request); + // Now the fully interpolated model is available: reconfigure the resolver + configureResolver(request.getModelResolver(), resultModel, problems, true); + + resultData.setGroupId(resultModel.getGroupId()); + resultData.setArtifactId(resultModel.getArtifactId()); + resultData.setVersion(resultModel.getVersion()); + result.setEffectiveModel(resultModel); - // Now the fully interpolated model is available: reconfigure the resolver - configureResolver(request.getModelResolver(), resultModel.getDelegate(), problems, true); + for (ModelData currentData : lineage) { + String modelId = (currentData != superData) ? currentData.getId() : ""; - return resultModel; + result.addModelId(modelId); + result.setActivePomProfiles(modelId, currentData.getActiveProfiles()); + result.setRawModel(modelId, currentData.getRawModel()); + } + + if (!request.isTwoPhaseBuilding()) { + build(request, result, importIds); + } + + return result; } - private List interpolateActivations( - List profiles, - DefaultProfileActivationContext context, - DefaultModelProblemCollector problems) { - if (profiles.stream() - .map(org.apache.maven.api.model.Profile::getActivation) - .noneMatch(Objects::nonNull)) { - return profiles; + @FunctionalInterface + private interface InterpolateString { + String apply(String s) throws InterpolationException; + } + + private List getInterpolatedProfiles( + Model rawModel, DefaultProfileActivationContext context, DefaultModelProblemCollector problems) { + List interpolatedActivations = getProfiles(rawModel, true); + + if (interpolatedActivations.isEmpty()) { + return Collections.emptyList(); } - final Interpolator xform = new RegexBasedInterpolator(); - xform.setCacheAnswers(true); - Stream.of(context.getUserProperties(), context.getSystemProperties()) - .map(MapBasedValueSource::new) - .forEach(xform::addValueSource); + RegexBasedInterpolator interpolator = new RegexBasedInterpolator(); - class ProfileInterpolator extends MavenTransformer - implements UnaryOperator { - ProfileInterpolator() { - super(s -> { - if (isNotEmpty(s)) { - try { - return xform.interpolate(s); - } catch (InterpolationException e) { - problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE) - .setMessage(e.getMessage()) - .setException(e)); - } - } - return s; - }); + interpolator.addValueSource(new MapBasedValueSource(context.getProjectProperties())); + interpolator.addValueSource(new MapBasedValueSource(context.getUserProperties())); + interpolator.addValueSource(new MapBasedValueSource(context.getSystemProperties())); + + class Interpolation { + final InputLocationTracker target; + + final InterpolateString impl; + + Interpolation(InputLocationTracker target, InterpolateString impl) { + this.target = target; + this.impl = impl; } - @Override - public org.apache.maven.api.model.Profile apply(org.apache.maven.api.model.Profile p) { - return org.apache.maven.api.model.Profile.newBuilder(p) - .activation(transformActivation(p.getActivation())) - .build(); - } - - @Override - protected ActivationFile.Builder transformActivationFile_Missing( - Supplier creator, - ActivationFile.Builder builder, - ActivationFile target) { - final String path = target.getMissing(); - final String xformed = transformPath(path, target, "missing"); - return xformed != path ? (builder != null ? builder : creator.get()).missing(xformed) : builder; - } - - @Override - protected ActivationFile.Builder transformActivationFile_Exists( - Supplier creator, - ActivationFile.Builder builder, - ActivationFile target) { - final String path = target.getExists(); - final String xformed = transformPath(path, target, "exists"); - return xformed != path ? (builder != null ? builder : creator.get()).exists(xformed) : builder; - } - - private String transformPath(String path, ActivationFile target, String locationKey) { - if (isNotEmpty(path)) { - try { - return profileActivationFilePathInterpolator.interpolate(path, context); - } catch (InterpolationException e) { - addInterpolationProblem(problems, target, path, e, locationKey); - } + void performFor(String value, String locationKey, Consumer mutator) { + if (StringUtils.isEmpty(value)) { + return; + } + try { + mutator.accept(impl.apply(value)); + } catch (InterpolationException e) { + problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE) + .setMessage("Failed to interpolate value " + value + ": " + e.getMessage()) + .setLocation(target.getLocation(locationKey)) + .setException(e)); } - return path; } } - return profiles.stream().map(new ProfileInterpolator()).toList(); - } - - private static void addInterpolationProblem( - DefaultModelProblemCollector problems, - org.apache.maven.api.model.InputLocationTracker target, - String path, - InterpolationException e, - String locationKey) { - problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE) - .setMessage("Failed to interpolate file location " + path + ": " + e.getMessage()) - .setLocation(Optional.ofNullable(target.getLocation(locationKey)) - .map(InputLocation::new) - .orElse(null)) - .setException(e)); - } - - private static boolean isNotEmpty(String string) { - return string != null && !string.isEmpty(); + for (Profile profile : interpolatedActivations) { + Activation activation = profile.getActivation(); + Optional a = Optional.ofNullable(activation); + a.map(Activation::getFile).ifPresent(fa -> { + Interpolation nt = + new Interpolation(fa, s -> profileActivationFilePathInterpolator.interpolate(s, context)); + nt.performFor(fa.getExists(), "exists", fa::setExists); + nt.performFor(fa.getMissing(), "missing", fa::setMissing); + }); + a.map(Activation::getOs).ifPresent(oa -> { + Interpolation nt = new Interpolation(oa, interpolator::interpolate); + nt.performFor(oa.getArch(), "arch", oa::setArch); + nt.performFor(oa.getFamily(), "family", oa::setFamily); + nt.performFor(oa.getName(), "name", oa::setName); + nt.performFor(oa.getVersion(), "version", oa::setVersion); + }); + a.map(Activation::getProperty).ifPresent(pa -> { + Interpolation nt = new Interpolation(pa, interpolator::interpolate); + nt.performFor(pa.getName(), "name", pa::setName); + nt.performFor(pa.getValue(), "value", pa::setValue); + }); + a.map(Activation::getJdk).ifPresent(ja -> new Interpolation(activation, interpolator::interpolate) + .performFor(ja, "jdk", activation::setJdk)); + } + return interpolatedActivations; } @Override - public ModelBuildingResult build(final ModelBuildingRequest request, final ModelBuildingResult result) + public ModelBuildingResult build(ModelBuildingRequest request, ModelBuildingResult result) throws ModelBuildingException { - return build(request, result, new LinkedHashSet<>()); - } - - public Model buildRawModel(final ModelBuildingRequest request) throws ModelBuildingException { - DefaultModelProblemCollector problems = new DefaultModelProblemCollector(new DefaultModelBuildingResult()); - Model model = readRawModel(request, problems); - if (hasModelErrors(problems)) { - throw problems.newModelBuildingException(); - } - return model; + return build(request, result, new LinkedHashSet()); } private ModelBuildingResult build( - final ModelBuildingRequest request, final ModelBuildingResult phaseOneResult, Collection imports) + ModelBuildingRequest request, ModelBuildingResult result, Collection imports) throws ModelBuildingException { - DefaultModelBuildingResult result = asDefaultModelBuildingResult(phaseOneResult); + // phase 2 + Model resultModel = result.getEffectiveModel(); DefaultModelProblemCollector problems = new DefaultModelProblemCollector(result); - - // phase 2 - Model resultModel = readEffectiveModel(request, result, problems); problems.setSource(resultModel); problems.setRootModel(resultModel); // model path translation - modelPathTranslator.alignToBaseDirectory(resultModel, resultModel.getProjectDirectoryPath(), request); + modelPathTranslator.alignToBaseDirectory(resultModel, resultModel.getProjectDirectory(), request); // plugin management injection pluginManagementInjector.injectManagement(resultModel, request, problems); @@ -1045,12 +532,15 @@ public class DefaultModelBuilder implements ModelBuilder { // dependency management injection dependencyManagementInjector.injectManagement(resultModel, request, problems); - resultModel.update(modelNormalizer.injectDefaultValues(resultModel.getDelegate(), request, problems)); + modelNormalizer.injectDefaultValues(resultModel, request, problems); if (request.isProcessPlugins()) { // reports configuration reportConfigurationExpander.expandPluginConfiguration(resultModel, request, problems); + // reports conversion to decoupled site plugin + reportingConverter.convertReporting(resultModel, request, problems); + // plugins configuration pluginConfigurationExpander.expandPluginConfiguration(resultModel, request, problems); } @@ -1065,104 +555,45 @@ public class DefaultModelBuilder implements ModelBuilder { return result; } - private DefaultModelBuildingResult asDefaultModelBuildingResult(ModelBuildingResult phaseOneResult) { - if (phaseOneResult instanceof DefaultModelBuildingResult) { - return (DefaultModelBuildingResult) phaseOneResult; - } else { - return new DefaultModelBuildingResult(phaseOneResult); - } - } - - @Deprecated @Override public Result buildRawModel(File pomFile, int validationLevel, boolean locationTracking) { - return buildRawModel(pomFile.toPath(), validationLevel, locationTracking, null); - } - - @Override - public Result buildRawModel(Path pomFile, int validationLevel, boolean locationTracking) { - return buildRawModel(pomFile, validationLevel, locationTracking, null); - } - - @Deprecated - @Override - public Result buildRawModel( - File pomFile, int validationLevel, boolean locationTracking, TransformerContext context) { - return buildRawModel(pomFile.toPath(), validationLevel, locationTracking, context); - } - - @Override - public Result buildRawModel( - Path pomFile, int validationLevel, boolean locationTracking, TransformerContext context) { final ModelBuildingRequest request = new DefaultModelBuildingRequest() .setValidationLevel(validationLevel) - .setLocationTracking(locationTracking) - .setModelSource(new FileModelSource(pomFile)); - DefaultModelProblemCollector problems = new DefaultModelProblemCollector(new DefaultModelBuildingResult()); + .setLocationTracking(locationTracking); + final DefaultModelProblemCollector collector = + new DefaultModelProblemCollector(new DefaultModelBuildingResult()); try { - Model model = readFileModel(request, problems); - - try { - if (transformer != null && context != null) { - transformer.transform(pomFile, context, model); - } - } catch (TransformerException e) { - problems.add( - new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.V40).setException(e)); - } - - return newResult(model, problems.getProblems()); + return newResult(readModel(null, pomFile, request, collector), collector.getProblems()); } catch (ModelBuildingException e) { - return error(problems.getProblems()); + return error(collector.getProblems()); } } - Model readFileModel(ModelBuildingRequest request, DefaultModelProblemCollector problems) + private Model readModel( + ModelSource modelSource, File pomFile, ModelBuildingRequest request, DefaultModelProblemCollector problems) throws ModelBuildingException { - ModelSource modelSource = request.getModelSource(); - org.apache.maven.api.model.Model model = cache( - request.getModelCache(), - modelSource, - ModelCacheTag.FILE, - () -> doReadFileModel(modelSource, request, problems)); + Model model; - if (modelSource instanceof FileModelSource) { - if (request.getTransformerContextBuilder() instanceof DefaultTransformerContextBuilder) { - DefaultTransformerContextBuilder contextBuilder = - (DefaultTransformerContextBuilder) request.getTransformerContextBuilder(); - contextBuilder.putSource(getGroupId(model), model.getArtifactId(), (FileModelSource) modelSource); + if (modelSource == null) { + if (pomFile != null) { + modelSource = new FileModelSource(pomFile); + } else { + throw new NullPointerException("neither pomFile nor modelSource can be null"); } } - return new Model(model); - } - - @SuppressWarnings("checkstyle:methodlength") - private org.apache.maven.api.model.Model doReadFileModel( - ModelSource modelSource, ModelBuildingRequest request, DefaultModelProblemCollector problems) - throws ModelBuildingException { - org.apache.maven.api.model.Model model; problems.setSource(modelSource.getLocation()); try { boolean strict = request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0; + InputSource source = request.isLocationTracking() ? new InputSource() : null; - Map options = new HashMap<>(3); + Map options = new HashMap<>(); options.put(ModelProcessor.IS_STRICT, strict); + options.put(ModelProcessor.INPUT_SOURCE, source); options.put(ModelProcessor.SOURCE, modelSource); - options.put(ModelReader.ROOT_DIRECTORY, request.getRootDirectory()); - - InputSource source; - if (request.isLocationTracking()) { - source = new InputSource(null, modelSource.getLocation()); - options.put(ModelProcessor.INPUT_SOURCE, new org.apache.maven.model.InputSource(source)); - } else { - source = null; - } try { - model = modelProcessor - .read(modelSource.getInputStream(), options) - .getDelegate(); + model = modelProcessor.read(modelSource.getInputStream(), options); } catch (ModelParseException e) { if (!strict) { throw e; @@ -1171,42 +602,35 @@ public class DefaultModelBuilder implements ModelBuilder { options.put(ModelProcessor.IS_STRICT, Boolean.FALSE); try { - model = modelProcessor - .read(modelSource.getInputStream(), options) - .getDelegate(); + model = modelProcessor.read(modelSource.getInputStream(), options); } catch (ModelParseException ne) { // still unreadable even in non-strict mode, rethrow original error throw e; } - Severity severity = (modelSource instanceof FileModelSource) ? Severity.ERROR : Severity.WARNING; - problems.add(new ModelProblemCollectorRequest(severity, ModelProblem.Version.V20) - .setMessage("Malformed POM " + modelSource.getLocation() + ": " + e.getMessage()) - .setException(e)); + if (pomFile != null) { + problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.V20) + .setMessage("Malformed POM " + modelSource.getLocation() + ": " + e.getMessage()) + .setException(e)); + } else { + problems.add(new ModelProblemCollectorRequest(Severity.WARNING, Version.V20) + .setMessage("Malformed POM " + modelSource.getLocation() + ": " + e.getMessage()) + .setException(e)); + } } if (source != null) { - try { - org.apache.maven.api.model.InputLocation loc = model.getLocation(""); - org.apache.maven.api.model.InputSource v4src = loc != null ? loc.getSource() : null; - if (v4src != null) { - Field field = InputSource.class.getDeclaredField("modelId"); - field.setAccessible(true); - field.set(v4src, ModelProblemUtils.toId(model)); - } - } catch (Throwable t) { - // TODO: use a lazy source ? - throw new IllegalStateException("Unable to set modelId on InputSource", t); - } + source.setModelId(ModelProblemUtils.toId(model)); + source.setLocation(modelSource.getLocation()); } } catch (ModelParseException e) { - problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.BASE) + problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.BASE) .setMessage("Non-parseable POM " + modelSource.getLocation() + ": " + e.getMessage()) .setException(e)); throw problems.newModelBuildingException(); } catch (IOException e) { String msg = e.getMessage(); - if (msg == null || msg.isEmpty()) { + if (msg == null || msg.length() <= 0) { // NOTE: There's java.nio.charset.MalformedInputException and sun.io.MalformedInputException if (e.getClass().getName().endsWith("MalformedInputException")) { msg = "Some input bytes do not match the file encoding."; @@ -1214,21 +638,16 @@ public class DefaultModelBuilder implements ModelBuilder { msg = e.getClass().getSimpleName(); } } - problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.BASE) + problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.BASE) .setMessage("Non-readable POM " + modelSource.getLocation() + ": " + msg) .setException(e)); throw problems.newModelBuildingException(); } - if (modelSource instanceof FileModelSource) { - model = model.withPomFile(((FileModelSource) modelSource).getPath()); - } + model.setPomFile(pomFile); - Model retModel = new Model(model); - - problems.setSource(retModel); - - modelValidator.validateFileModel(retModel, request, problems); + problems.setSource(model); + modelValidator.validateRawModel(model, request, problems); if (hasFatalErrors(problems)) { throw problems.newModelBuildingException(); @@ -1237,80 +656,7 @@ public class DefaultModelBuilder implements ModelBuilder { return model; } - Model readRawModel(ModelBuildingRequest request, DefaultModelProblemCollector problems) - throws ModelBuildingException { - ModelSource modelSource = request.getModelSource(); - - ModelData modelData = cache( - request.getModelCache(), - modelSource, - ModelCacheTag.RAW, - () -> doReadRawModel(modelSource, request, problems)); - - return modelData.getModel(); - } - - private ModelData doReadRawModel( - ModelSource modelSource, ModelBuildingRequest request, DefaultModelProblemCollector problems) - throws ModelBuildingException { - Model rawModel; - if (modelSource instanceof FileModelSource) { - rawModel = readFileModel(request, problems); - - if (!MODEL_VERSION_4_0_0.equals(rawModel.getModelVersion())) { - File pomFile = ((FileModelSource) modelSource).getFile(); - - try { - if (request.getTransformerContextBuilder() != null) { - TransformerContext context = - request.getTransformerContextBuilder().initialize(request, problems); - transformer.transform(pomFile.toPath(), context, rawModel); - } - } catch (TransformerException e) { - problems.add( - new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.V40).setException(e)); - } - } - } else if (request.getFileModel() == null) { - rawModel = readFileModel(request, problems); - } else { - rawModel = request.getFileModel().clone(); - } - - modelValidator.validateRawModel(rawModel, request, problems); - - if (hasFatalErrors(problems)) { - throw problems.newModelBuildingException(); - } - - String groupId = getGroupId(rawModel); - String artifactId = rawModel.getArtifactId(); - String version = getVersion(rawModel); - - return new ModelData(modelSource, rawModel, groupId, artifactId, version); - } - - String getGroupId(Model model) { - return getGroupId(model.getDelegate()); - } - - private String getGroupId(org.apache.maven.api.model.Model model) { - String groupId = model.getGroupId(); - if (groupId == null && model.getParent() != null) { - groupId = model.getParent().getGroupId(); - } - return groupId; - } - - private String getVersion(Model model) { - String version = model.getVersion(); - if (version == null && model.getParent() != null) { - version = model.getParent().getVersion(); - } - return version; - } - - private DefaultProfileActivationContext getProfileActivationContext(ModelBuildingRequest request) { + private DefaultProfileActivationContext getProfileActivationContext(ModelBuildingRequest request, Model rawModel) { DefaultProfileActivationContext context = new DefaultProfileActivationContext(); context.setActiveProfileIds(request.getActiveProfileIds()); @@ -1318,11 +664,8 @@ public class DefaultModelBuilder implements ModelBuilder { context.setSystemProperties(request.getSystemProperties()); // enrich user properties with project packaging Properties userProperties = request.getUserProperties(); - if (!userProperties.containsKey(ProfileActivationContext.PROPERTY_NAME_PACKAGING)) { - userProperties.put( - ProfileActivationContext.PROPERTY_NAME_PACKAGING, - request.getFileModel().getPackaging()); - } + userProperties.computeIfAbsent( + (Object) ProfileActivationContext.PROPERTY_NAME_PACKAGING, (p) -> (Object) rawModel.getPackaging()); context.setUserProperties(userProperties); context.setProjectDirectory( (request.getPomFile() != null) ? request.getPomFile().getParentFile() : null); @@ -1330,27 +673,37 @@ public class DefaultModelBuilder implements ModelBuilder { return context; } + private void configureResolver(ModelResolver modelResolver, Model model, DefaultModelProblemCollector problems) { + configureResolver(modelResolver, model, problems, false); + } + private void configureResolver( ModelResolver modelResolver, - org.apache.maven.api.model.Model model, + Model model, DefaultModelProblemCollector problems, boolean replaceRepositories) { - if (modelResolver != null) { - for (org.apache.maven.api.model.Repository repository : model.getRepositories()) { - try { - modelResolver.addRepository(repository, replaceRepositories); - } catch (InvalidRepositoryException e) { - problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE) - .setMessage("Invalid repository " + repository.getId() + ": " + e.getMessage()) - .setLocation(new InputLocation(repository.getLocation(""))) - .setException(e)); - } + if (modelResolver == null) { + return; + } + + problems.setSource(model); + + List repositories = model.getRepositories(); + + for (Repository repository : repositories) { + try { + modelResolver.addRepository(repository, replaceRepositories); + } catch (InvalidRepositoryException e) { + problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE) + .setMessage("Invalid repository " + repository.getId() + ": " + e.getMessage()) + .setLocation(repository.getLocation("")) + .setException(e)); } } } private void checkPluginVersions( - List lineage, ModelBuildingRequest request, ModelProblemCollector problems) { + List lineage, ModelBuildingRequest request, ModelProblemCollector problems) { if (request.getValidationLevel() < ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) { return; } @@ -1360,7 +713,7 @@ public class DefaultModelBuilder implements ModelBuilder { Map managedVersions = new HashMap<>(); for (int i = lineage.size() - 1; i >= 0; i--) { - Model model = lineage.get(i); + Model model = lineage.get(i).getModel(); Build build = model.getBuild(); if (build != null) { for (Plugin plugin : build.getPlugins()) { @@ -1374,7 +727,9 @@ public class DefaultModelBuilder implements ModelBuilder { if (mgmt != null) { for (Plugin plugin : mgmt.getPlugins()) { String key = plugin.getKey(); - managedVersions.computeIfAbsent(key, k -> plugin.getVersion()); + if (managedVersions.get(key) == null) { + managedVersions.put(key, plugin.getVersion()); + } } } } @@ -1383,62 +738,39 @@ public class DefaultModelBuilder implements ModelBuilder { for (String key : versions.keySet()) { if (versions.get(key) == null && managedVersions.get(key) == null) { InputLocation location = plugins.get(key).getLocation(""); - problems.add(new ModelProblemCollectorRequest(Severity.WARNING, ModelProblem.Version.V20) + problems.add(new ModelProblemCollectorRequest(Severity.WARNING, Version.V20) .setMessage("'build.plugins.plugin.version' for " + key + " is missing.") .setLocation(location)); } } } - private Model assembleInheritance( - List lineage, ModelBuildingRequest request, ModelProblemCollector problems) { - org.apache.maven.api.model.Model parent = - lineage.get(lineage.size() - 1).getDelegate(); + private void assembleInheritance( + List lineage, ModelBuildingRequest request, ModelProblemCollector problems) { for (int i = lineage.size() - 2; i >= 0; i--) { - Model child = lineage.get(i); - parent = inheritanceAssembler.assembleModelInheritance(child.getDelegate(), parent, request, problems); + Model parent = lineage.get(i + 1).getModel(); + Model child = lineage.get(i).getModel(); + inheritanceAssembler.assembleModelInheritance(child, parent, request, problems); } - return new Model(parent); } - private Map getProfileActivations(Model model, boolean clone) { - Map activations = new HashMap<>(); + private List getProfiles(Model model, boolean clone) { + ArrayList profiles = new ArrayList<>(); for (Profile profile : model.getProfiles()) { - Activation activation = profile.getActivation(); - - if (activation == null) { - continue; - } - if (clone) { - activation = activation.clone(); + profile = profile.clone(); } - - activations.put(profile.getId(), activation); - } - - return activations; - } - - private void injectProfileActivations(Model model, Map activations) { - for (Profile profile : model.getProfiles()) { - Activation activation = profile.getActivation(); - - if (activation == null) { - continue; - } - - // restore activation - profile.setActivation(activations.get(profile.getId())); + profiles.add(profile); } + return profiles; } private Model interpolateModel(Model model, ModelBuildingRequest request, ModelProblemCollector problems) { // save profile activations before interpolation, since they are evaluated with limited scope - Map originalActivations = getProfileActivations(model, true); + List originalProfiles = getProfiles(model, true); - Model interpolatedModel = new Model(modelInterpolator.interpolateModel( - model.getDelegate(), model.getProjectDirectoryPath(), request, problems)); + Model interpolatedModel = + modelInterpolator.interpolateModel(model, model.getProjectDirectory(), request, problems); if (interpolatedModel.getParent() != null) { StringSearchInterpolator ssi = new StringSearchInterpolator(); ssi.addValueSource(new MapBasedValueSource(request.getUserProperties())); @@ -1452,8 +784,7 @@ public class DefaultModelBuilder implements ModelBuilder { ssi.interpolate(interpolatedModel.getParent().getVersion()); interpolatedModel.getParent().setVersion(interpolated); } catch (Exception e) { - ModelProblemCollectorRequest mpcr = new ModelProblemCollectorRequest( - Severity.ERROR, ModelProblem.Version.BASE) + ModelProblemCollectorRequest mpcr = new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE) .setMessage("Failed to interpolate field: " + interpolatedModel.getParent().getVersion() + " on class: ") @@ -1461,43 +792,86 @@ public class DefaultModelBuilder implements ModelBuilder { problems.add(mpcr); } } - interpolatedModel.setPomPath(model.getPomPath()); + interpolatedModel.setPomFile(model.getPomFile()); - // restore profiles with file activation to their value before full interpolation - injectProfileActivations(model, originalActivations); + // restore profiles with any activation to their value before full interpolation + List interpolatedProfiles = model.getProfiles(); + IntStream.range(0, interpolatedProfiles.size()).forEach(i -> interpolatedProfiles + .get(i) + .setActivation(originalProfiles.get(i).getActivation())); return interpolatedModel; } private ModelData readParent( - Model childModel, Source childSource, ModelBuildingRequest request, DefaultModelProblemCollector problems) + Model childModel, + ModelSource childSource, + ModelBuildingRequest request, + DefaultModelProblemCollector problems) throws ModelBuildingException { - ModelData parentData = null; + ModelData parentData; Parent parent = childModel.getParent(); + if (parent != null) { - parentData = readParentLocally(childModel, childSource, request, problems); + String groupId = parent.getGroupId(); + String artifactId = parent.getArtifactId(); + String version = parent.getVersion(); + + parentData = getCache(request.getModelCache(), groupId, artifactId, version, ModelCacheTag.RAW); + if (parentData == null) { - parentData = readParentExternally(childModel, request, problems); + parentData = readParentLocally(childModel, childSource, request, problems); + + if (parentData == null) { + parentData = readParentExternally(childModel, request, problems); + } + + putCache(request.getModelCache(), groupId, artifactId, version, ModelCacheTag.RAW, parentData); + } else { + /* + * NOTE: This is a sanity check of the cache hit. If the cached parent POM was locally resolved, the + * child's should point at that parent, too. If it doesn't, we ignore the cache and + * resolve externally, to mimic the behavior if the cache didn't exist in the first place. Otherwise, + * the cache would obscure a bad POM. + */ + + File pomFile = parentData.getModel().getPomFile(); + if (pomFile != null) { + FileModelSource pomSource = new FileModelSource(pomFile); + ModelSource expectedParentSource = getParentPomFile(childModel, childSource); + + if (expectedParentSource == null + || (expectedParentSource instanceof ModelSource2 + && !pomSource.equals(expectedParentSource))) { + parentData = readParentExternally(childModel, request, problems); + } + } } Model parentModel = parentData.getModel(); + if (!"pom".equals(parentModel.getPackaging())) { - problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE) + problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE) .setMessage("Invalid packaging for parent POM " + ModelProblemUtils.toSourceHint(parentModel) + ", must be \"pom\" but is \"" + parentModel.getPackaging() + "\"") .setLocation(parentModel.getLocation("packaging"))); } + } else { + parentData = null; } return parentData; } private ModelData readParentLocally( - Model childModel, Source childSource, ModelBuildingRequest request, DefaultModelProblemCollector problems) + Model childModel, + ModelSource childSource, + ModelBuildingRequest request, + DefaultModelProblemCollector problems) throws ModelBuildingException { final Parent parent = childModel.getParent(); - final ModelSource2 candidateSource; + final ModelSource candidateSource; final Model candidateModel; final WorkspaceModelResolver resolver = request.getWorkspaceModelResolver(); if (resolver == null) { @@ -1507,17 +881,19 @@ public class DefaultModelBuilder implements ModelBuilder { return null; } - ModelBuildingRequest candidateBuildRequest = - new DefaultModelBuildingRequest(request).setModelSource(candidateSource); + File pomFile = null; + if (candidateSource instanceof FileModelSource) { + pomFile = ((FileModelSource) candidateSource).getPomFile(); + } - candidateModel = readRawModel(candidateBuildRequest, problems); + candidateModel = readModel(candidateSource, pomFile, request, problems); } else { try { candidateModel = resolver.resolveRawModel(parent.getGroupId(), parent.getArtifactId(), parent.getVersion()); } catch (UnresolvableModelException e) { - problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.BASE) // - .setMessage(e.getMessage()) + problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.BASE) // + .setMessage(e.getMessage().toString()) .setLocation(parent.getLocation("")) .setException(e)); throw problems.newModelBuildingException(); @@ -1525,7 +901,7 @@ public class DefaultModelBuilder implements ModelBuilder { if (candidateModel == null) { return null; } - candidateSource = new FileModelSource(candidateModel.getPomPath()); + candidateSource = new FileModelSource(candidateModel.getPomFile()); } // @@ -1534,8 +910,15 @@ public class DefaultModelBuilder implements ModelBuilder { // before because with parents as ranges it will never work in this scenario. // - String groupId = getGroupId(candidateModel); + String groupId = candidateModel.getGroupId(); + if (groupId == null && candidateModel.getParent() != null) { + groupId = candidateModel.getParent().getGroupId(); + } String artifactId = candidateModel.getArtifactId(); + String version = candidateModel.getVersion(); + if (version == null && candidateModel.getParent() != null) { + version = candidateModel.getParent().getVersion(); + } if (groupId == null || !groupId.equals(parent.getGroupId()) @@ -1551,17 +934,19 @@ public class DefaultModelBuilder implements ModelBuilder { buffer.append(parent.getArtifactId()).append(", please verify your project structure"); problems.setSource(childModel); - problems.add(new ModelProblemCollectorRequest(Severity.WARNING, ModelProblem.Version.BASE) + problems.add(new ModelProblemCollectorRequest(Severity.WARNING, Version.BASE) .setMessage(buffer.toString()) .setLocation(parent.getLocation(""))); return null; } - - String version = getVersion(candidateModel); if (version != null && parent.getVersion() != null && !version.equals(parent.getVersion())) { try { - VersionRange parentRange = versionParser.parseVersionRange(parent.getVersion()); - if (!parentRange.contains(versionParser.parseVersion(version))) { + VersionRange parentRange = VersionRange.createFromVersionSpec(parent.getVersion()); + if (!parentRange.hasRestrictions()) { + // the parent version is not a range, we have version skew, drop back to resolution from repo + return null; + } + if (!parentRange.containsVersion(new DefaultArtifactVersion(version))) { // version skew drop back to resolution from the repository return null; } @@ -1571,21 +956,21 @@ public class DefaultModelBuilder implements ModelBuilder { if (rawChildModelVersion == null) { // Message below is checked for in the MNG-2199 core IT. - problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.V31) + problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V31) .setMessage("Version must be a constant") .setLocation(childModel.getLocation(""))); } else { if (rawChildVersionReferencesParent(rawChildModelVersion)) { // Message below is checked for in the MNG-2199 core IT. - problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.V31) + problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V31) .setMessage("Version must be a constant") .setLocation(childModel.getLocation("version"))); } } // MNG-2199: What else to check here ? - } catch (VersionParserException e) { + } catch (InvalidVersionSpecificationException e) { // invalid version range, so drop back to resolution from the repository return null; } @@ -1600,7 +985,9 @@ public class DefaultModelBuilder implements ModelBuilder { * if ( version == null || !version.equals( parent.getVersion() ) ) { return null; } */ - return new ModelData(candidateSource, candidateModel, groupId, artifactId, version); + ModelData parentData = new ModelData(candidateSource, candidateModel, groupId, artifactId, version); + + return parentData; } private boolean rawChildVersionReferencesParent(String rawChildModelVersion) { @@ -1610,24 +997,21 @@ public class DefaultModelBuilder implements ModelBuilder { || rawChildModelVersion.equals("${project.parent.version}"); } - private ModelSource2 getParentPomFile(Model childModel, Source source) { + private ModelSource getParentPomFile(Model childModel, ModelSource source) { if (!(source instanceof ModelSource2)) { return null; } String parentPath = childModel.getParent().getRelativePath(); if (parentPath == null) { - parentPath = ".."; - childModel.getParent().setRelativePath(parentPath); - } else if (parentPath.isEmpty()) { + parentPath = "../pom.xml"; + } + + if (parentPath.length() <= 0) { return null; } - if (source instanceof ModelSource3) { - return ((ModelSource3) source).getRelatedSource(modelProcessor, parentPath); - } else { - return ((ModelSource2) source).getRelatedSource(parentPath); - } + return ((ModelSource2) source).getRelatedSource(parentPath); } private ModelData readParentExternally( @@ -1635,7 +1019,7 @@ public class DefaultModelBuilder implements ModelBuilder { throws ModelBuildingException { problems.setSource(childModel); - Parent parent = childModel.getParent(); + Parent parent = childModel.getParent().clone(); String groupId = parent.getGroupId(); String artifactId = parent.getArtifactId(); @@ -1663,42 +1047,46 @@ public class DefaultModelBuilder implements ModelBuilder { buffer.append(" for ").append(ModelProblemUtils.toId(childModel)); } buffer.append(": ").append(e.getMessage()); - if (childModel.getProjectDirectoryPath() != null) { - if (parent.getRelativePath() == null || parent.getRelativePath().isEmpty()) { + if (childModel.getProjectDirectory() != null) { + if (parent.getRelativePath() == null || parent.getRelativePath().length() <= 0) { buffer.append(" and 'parent.relativePath' points at no local POM"); } else { buffer.append(" and 'parent.relativePath' points at wrong local POM"); } } - problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.BASE) + problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.BASE) .setMessage(buffer.toString()) .setLocation(parent.getLocation("")) .setException(e)); throw problems.newModelBuildingException(); } - int validationLevel = Math.min(request.getValidationLevel(), ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0); - ModelBuildingRequest lenientRequest = new DefaultModelBuildingRequest(request) - .setValidationLevel(validationLevel) - .setFileModel(null) - .setModelSource(modelSource); + ModelBuildingRequest lenientRequest = request; + if (request.getValidationLevel() > ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) { + lenientRequest = new FilterModelBuildingRequest(request) { + @Override + public int getValidationLevel() { + return ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0; + } + }; + } - Model parentModel = readRawModel(lenientRequest, problems); + Model parentModel = readModel(modelSource, null, lenientRequest, problems); if (!parent.getVersion().equals(version)) { String rawChildModelVersion = childModel.getVersion(); if (rawChildModelVersion == null) { // Message below is checked for in the MNG-2199 core IT. - problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.V31) + problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V31) .setMessage("Version must be a constant") .setLocation(childModel.getLocation(""))); } else { if (rawChildVersionReferencesParent(rawChildModelVersion)) { // Message below is checked for in the MNG-2199 core IT. - problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.V31) + problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V31) .setMessage("Version must be a constant") .setLocation(childModel.getLocation("version"))); } @@ -1707,14 +1095,17 @@ public class DefaultModelBuilder implements ModelBuilder { // MNG-2199: What else to check here ? } - return new ModelData( + ModelData parentData = new ModelData( modelSource, parentModel, parent.getGroupId(), parent.getArtifactId(), parent.getVersion()); + + return parentData; } - private Model getSuperModel(String modelVersion) { - return superPomProvider.getSuperModel(modelVersion); + private Model getSuperModel() { + return superPomProvider.getSuperModel("4.0.0").clone(); } + @SuppressWarnings("checkstyle:methodlength") private void importDependencyManagement( Model model, ModelBuildingRequest request, @@ -1730,262 +1121,175 @@ public class DefaultModelBuilder implements ModelBuilder { importIds.add(importing); - // Model v4 - List importMgmts = new ArrayList<>(); + final WorkspaceModelResolver workspaceResolver = request.getWorkspaceModelResolver(); + final ModelResolver modelResolver = request.getModelResolver(); + + ModelBuildingRequest importRequest = null; + + List importMgmts = null; for (Iterator it = depMgmt.getDependencies().iterator(); it.hasNext(); ) { Dependency dependency = it.next(); - if (!("pom".equals(dependency.getType()) && "import".equals(dependency.getScope())) - || "bom".equals(dependency.getType())) { + if (!"pom".equals(dependency.getType()) || !"import".equals(dependency.getScope())) { continue; } it.remove(); - // Model v3 - DependencyManagement importMgmt = loadDependencyManagement(model, request, problems, dependency, importIds); - if (importMgmt == null) { + String groupId = dependency.getGroupId(); + String artifactId = dependency.getArtifactId(); + String version = dependency.getVersion(); + + if (groupId == null || groupId.length() <= 0) { + problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE) + .setMessage("'dependencyManagement.dependencies.dependency.groupId' for " + + dependency.getManagementKey() + " is missing.") + .setLocation(dependency.getLocation(""))); + continue; + } + if (artifactId == null || artifactId.length() <= 0) { + problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE) + .setMessage("'dependencyManagement.dependencies.dependency.artifactId' for " + + dependency.getManagementKey() + " is missing.") + .setLocation(dependency.getLocation(""))); + continue; + } + if (version == null || version.length() <= 0) { + problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE) + .setMessage("'dependencyManagement.dependencies.dependency.version' for " + + dependency.getManagementKey() + " is missing.") + .setLocation(dependency.getLocation(""))); continue; } - if (request.isLocationTracking()) { - // Keep track of why this DependencyManagement was imported. - // And map model v3 to model v4 -> importMgmt(v3).getDelegate() returns a v4 object - importMgmts.add( - org.apache.maven.api.model.DependencyManagement.newBuilder(importMgmt.getDelegate(), true) - .build()); - } else { - importMgmts.add(importMgmt.getDelegate()); + String imported = groupId + ':' + artifactId + ':' + version; + + if (importIds.contains(imported)) { + String message = "The dependencies of type=pom and with scope=import form a cycle: "; + for (String modelId : importIds) { + message += modelId + " -> "; + } + message += imported; + problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE).setMessage(message)); + + continue; } + + DependencyManagement importMgmt = + getCache(request.getModelCache(), groupId, artifactId, version, ModelCacheTag.IMPORT); + + if (importMgmt == null) { + if (workspaceResolver == null && modelResolver == null) { + throw new NullPointerException(String.format( + "request.workspaceModelResolver and request.modelResolver cannot be null" + + " (parent POM %s and POM %s)", + ModelProblemUtils.toId(groupId, artifactId, version), + ModelProblemUtils.toSourceHint(model))); + } + + Model importModel = null; + if (workspaceResolver != null) { + try { + importModel = workspaceResolver.resolveEffectiveModel(groupId, artifactId, version); + } catch (UnresolvableModelException e) { + problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.BASE) + .setMessage(e.getMessage().toString()) + .setException(e)); + continue; + } + } + + // no workspace resolver or workspace resolver returned null (i.e. model not in workspace) + if (importModel == null) { + final ModelSource importSource; + try { + importSource = modelResolver.resolveModel(groupId, artifactId, version); + } catch (UnresolvableModelException e) { + StringBuilder buffer = new StringBuilder(256); + buffer.append("Non-resolvable import POM"); + if (!containsCoordinates(e.getMessage(), groupId, artifactId, version)) { + buffer.append(' ').append(ModelProblemUtils.toId(groupId, artifactId, version)); + } + buffer.append(": ").append(e.getMessage()); + + problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE) + .setMessage(buffer.toString()) + .setLocation(dependency.getLocation("")) + .setException(e)); + continue; + } + + if (importRequest == null) { + importRequest = new DefaultModelBuildingRequest(); + importRequest.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL); + importRequest.setModelCache(request.getModelCache()); + importRequest.setSystemProperties(request.getSystemProperties()); + importRequest.setUserProperties(request.getUserProperties()); + importRequest.setLocationTracking(request.isLocationTracking()); + } + + importRequest.setModelSource(importSource); + importRequest.setModelResolver(modelResolver.newCopy()); + + final ModelBuildingResult importResult; + try { + importResult = build(importRequest, importIds); + } catch (ModelBuildingException e) { + problems.addAll(e.getProblems()); + continue; + } + + problems.addAll(importResult.getProblems()); + + importModel = importResult.getEffectiveModel(); + } + + importMgmt = importModel.getDependencyManagement(); + + if (importMgmt == null) { + importMgmt = new DependencyManagement(); + } + + putCache(request.getModelCache(), groupId, artifactId, version, ModelCacheTag.IMPORT, importMgmt); + } + + if (importMgmts == null) { + importMgmts = new ArrayList<>(); + } + + importMgmts.add(importMgmt); } importIds.remove(importing); - model.update( - dependencyManagementImporter.importManagement(model.getDelegate(), importMgmts, request, problems)); + dependencyManagementImporter.importManagement(model, importMgmts, request, problems); } - private DependencyManagement loadDependencyManagement( - Model model, - ModelBuildingRequest request, - DefaultModelProblemCollector problems, - Dependency dependency, - Collection importIds) { - String groupId = dependency.getGroupId(); - String artifactId = dependency.getArtifactId(); - String version = dependency.getVersion(); - - if (groupId == null || groupId.isEmpty()) { - problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE) - .setMessage("'dependencyManagement.dependencies.dependency.groupId' for " - + dependency.getManagementKey() + " is missing.") - .setLocation(dependency.getLocation(""))); - return null; + private void putCache( + ModelCache modelCache, String groupId, String artifactId, String version, ModelCacheTag tag, T data) { + if (modelCache != null) { + modelCache.put(groupId, artifactId, version, tag.getName(), tag.intoCache(data)); } - if (artifactId == null || artifactId.isEmpty()) { - problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE) - .setMessage("'dependencyManagement.dependencies.dependency.artifactId' for " - + dependency.getManagementKey() + " is missing.") - .setLocation(dependency.getLocation(""))); - return null; - } - if (version == null || version.isEmpty()) { - problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE) - .setMessage("'dependencyManagement.dependencies.dependency.version' for " - + dependency.getManagementKey() + " is missing.") - .setLocation(dependency.getLocation(""))); - return null; - } - - String imported = groupId + ':' + artifactId + ':' + version; - - if (importIds.contains(imported)) { - StringBuilder message = - new StringBuilder("The dependencies of type=pom and with scope=import form a cycle: "); - for (String modelId : importIds) { - message.append(modelId).append(" -> "); - } - message.append(imported); - problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE) - .setMessage(message.toString())); - - return null; - } - - org.apache.maven.api.model.DependencyManagement importMgmt = cache( - request.getModelCache(), - groupId, - artifactId, - version, - ModelCacheTag.IMPORT, - () -> doLoadDependencyManagement( - model, request, problems, dependency, groupId, artifactId, version, importIds)); - - // [MNG-5600] Dependency management import should support exclusions. - List exclusions = dependency.getDelegate().getExclusions(); - if (importMgmt != null && !exclusions.isEmpty()) { - // Dependency excluded from import. - List dependencies = importMgmt.getDependencies().stream() - .filter(candidate -> exclusions.stream().noneMatch(exclusion -> match(exclusion, candidate))) - .map(candidate -> addExclusions(candidate, exclusions)) - .collect(Collectors.toList()); - importMgmt = importMgmt.withDependencies(dependencies); - } - - return importMgmt != null ? new DependencyManagement(importMgmt) : null; } - private static org.apache.maven.api.model.Dependency addExclusions( - org.apache.maven.api.model.Dependency candidate, List exclusions) { - return candidate.withExclusions(Stream.concat(candidate.getExclusions().stream(), exclusions.stream()) - .toList()); - } - - private boolean match(Exclusion exclusion, org.apache.maven.api.model.Dependency candidate) { - return match(exclusion.getGroupId(), candidate.getGroupId()) - && match(exclusion.getArtifactId(), candidate.getArtifactId()); - } - - private boolean match(String match, String text) { - return match.equals("*") || match.equals(text); - } - - @SuppressWarnings("checkstyle:parameternumber") - private org.apache.maven.api.model.DependencyManagement doLoadDependencyManagement( - Model model, - ModelBuildingRequest request, - DefaultModelProblemCollector problems, - Dependency dependency, - String groupId, - String artifactId, - String version, - Collection importIds) { - DependencyManagement importMgmt; - final WorkspaceModelResolver workspaceResolver = request.getWorkspaceModelResolver(); - final ModelResolver modelResolver = request.getModelResolver(); - if (workspaceResolver == null && modelResolver == null) { - throw new NullPointerException(String.format( - "request.workspaceModelResolver and request.modelResolver cannot be null (parent POM %s and POM %s)", - ModelProblemUtils.toId(groupId, artifactId, version), ModelProblemUtils.toSourceHint(model))); - } - - Model importModel = null; - if (workspaceResolver != null) { - try { - importModel = workspaceResolver.resolveEffectiveModel(groupId, artifactId, version); - } catch (UnresolvableModelException e) { - problems.add(new ModelProblemCollectorRequest(Severity.FATAL, ModelProblem.Version.BASE) - .setMessage(e.getMessage()) - .setException(e)); - return null; + private T getCache( + ModelCache modelCache, String groupId, String artifactId, String version, ModelCacheTag tag) { + if (modelCache != null) { + Object data = modelCache.get(groupId, artifactId, version, tag.getName()); + if (data != null) { + return tag.fromCache(tag.getType().cast(data)); } } - - // no workspace resolver or workspace resolver returned null (i.e. model not in workspace) - if (importModel == null) { - final ModelSource importSource; - try { - importSource = modelResolver.resolveModel(dependency); - } catch (UnresolvableModelException e) { - StringBuilder buffer = new StringBuilder(256); - buffer.append("Non-resolvable import POM"); - if (!containsCoordinates(e.getMessage(), groupId, artifactId, version)) { - buffer.append(' ').append(ModelProblemUtils.toId(groupId, artifactId, version)); - } - buffer.append(": ").append(e.getMessage()); - - problems.add(new ModelProblemCollectorRequest(Severity.ERROR, ModelProblem.Version.BASE) - .setMessage(buffer.toString()) - .setLocation(dependency.getLocation("")) - .setException(e)); - return null; - } - - if (importSource instanceof FileModelSource && request.getRootDirectory() != null) { - Path sourcePath = ((FileModelSource) importSource).getPath(); - if (sourcePath.startsWith(request.getRootDirectory())) { - problems.add(new ModelProblemCollectorRequest(Severity.WARNING, ModelProblem.Version.BASE) - .setMessage("BOM imports from within reactor should be avoided") - .setLocation(dependency.getLocation(""))); - } - } - - final ModelBuildingResult importResult; - try { - ModelBuildingRequest importRequest = new DefaultModelBuildingRequest(); - importRequest.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL); - importRequest.setModelCache(request.getModelCache()); - importRequest.setSystemProperties(request.getSystemProperties()); - importRequest.setUserProperties(request.getUserProperties()); - importRequest.setLocationTracking(request.isLocationTracking()); - - importRequest.setModelSource(importSource); - importRequest.setModelResolver(modelResolver.newCopy()); - - importResult = build(importRequest, importIds); - } catch (ModelBuildingException e) { - problems.addAll(e.getProblems()); - return null; - } - - problems.addAll(importResult.getProblems()); - - importModel = importResult.getEffectiveModel(); - } - - importMgmt = importModel.getDependencyManagement(); - - if (importMgmt == null) { - importMgmt = new DependencyManagement(); - } - return importMgmt.getDelegate(); - } - - private static T cache( - ModelCache cache, - String groupId, - String artifactId, - String version, - ModelCacheTag tag, - Callable supplier) { - Supplier s = asSupplier(supplier); - if (cache == null) { - return s.get(); - } else { - return cache.computeIfAbsent(groupId, artifactId, version, tag.getName(), s); - } - } - - private static T cache(ModelCache cache, Source source, ModelCacheTag tag, Callable supplier) { - Supplier s = asSupplier(supplier); - if (cache == null) { - return s.get(); - } else { - return cache.computeIfAbsent(source, tag.getName(), s); - } - } - - private static Supplier asSupplier(Callable supplier) { - return () -> { - try { - return supplier.call(); - } catch (Exception e) { - uncheckedThrow(e); - return null; - } - }; - } - - static void uncheckedThrow(Throwable t) throws T { - throw (T) t; // rely on vacuous cast + return null; } private void fireEvent( Model model, ModelBuildingRequest request, ModelProblemCollector problems, - ModelBuildingEventCatapult catapult) { + ModelBuildingEventCatapult catapult) + throws ModelBuildingException { ModelBuildingListener listener = request.getModelBuildingListener(); if (listener != null) { @@ -2021,8 +1325,4 @@ public class DefaultModelBuilder implements ModelBuilder { throw new IllegalStateException(); } } - - ModelProcessor getModelProcessor() { - return modelProcessor; - } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java index 92db3fdc6b..d21c86841d 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java @@ -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. Note: 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 { diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingEvent.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingEvent.java index c78b798b99..95eef4773b 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingEvent.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingEvent.java @@ -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; diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java index c4e562f7e5..22b1c96f72 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java @@ -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; - } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java index fbedb32a0e..c13a22b649 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java @@ -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; diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblem.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblem.java index 01422f05fc..1f71d61c1e 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblem.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblem.java @@ -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(); } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java index 9012477557..5ffa16bce0 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java @@ -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 modelParsers; - private final ModelLocator modelLocator; - private final ModelReader modelReader; + @Inject + private ModelLocator locator; @Inject - public DefaultModelProcessor(List 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 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 options) throws IOException { - if (pomFile != null) { - Path projectDirectory = pomFile.getParent(); - List exceptions = new ArrayList<>(); - for (ModelParser parser : modelParsers) { - try { - Optional 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 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 options) throws IOException { - Objects.requireNonNull(file, "file cannot be null"); - return read(file.toPath(), options); + public Model read(Reader input, Map options) throws IOException { + return reader.read(input, options); } @Override - public org.apache.maven.model.Model read(Path path, Map 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 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 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 options) throws IOException { + return reader.read(input, options); } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContext.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContext.java deleted file mode 100644 index ecbc09303d..0000000000 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContext.java +++ /dev/null @@ -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 userProperties = new ConcurrentHashMap<>(); - - final Map modelByPath = new ConcurrentHashMap<>(); - - final Map 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 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); - } - } -} diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContextBuilder.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContextBuilder.java deleted file mode 100644 index e0f22ef2c5..0000000000 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContextBuilder.java +++ /dev/null @@ -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> 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 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 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); - } - } -} diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/FileModelSource.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/FileModelSource.java index 7bc8135e41..2b8f03acfb 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/FileModelSource.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/FileModelSource.java @@ -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(); } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java index 6eb9b9d2f1..40480ce2f5 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java @@ -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; - } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java index 2217517689..f2c75b305a 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java @@ -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 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 buildRawModel(Path pomFile, int validationLevel, boolean locationTracking); - - /** - * @deprecated Use {@link #buildRawModel(Path, int, boolean, TransformerContext)} instead. - */ - @Deprecated - Result buildRawModel( - File pomFile, int validationLevel, boolean locationTracking, TransformerContext context); - - /** - * @since 4.0.0 - */ - Result buildRawModel( - Path pomFile, int validationLevel, boolean locationTracking, TransformerContext context); - - TransformerContextBuilder newTransformerContextBuilder(); } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingEventCatapult.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingEventCatapult.java index 75a8022a39..f9d68a6127 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingEventCatapult.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingEventCatapult.java @@ -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); + } + }; } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java index 771039ae61..b4ba8d3390 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java @@ -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 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(); diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java index ebf066d80f..d607d43391 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java @@ -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); } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java index 6f9502d04c..d3e88d5f42 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java @@ -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 ::}. 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 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. diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCache.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCache.java index 22e516a1c2..bb28e7ba3f 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCache.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCache.java @@ -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 computeIfAbsent(String groupId, String artifactId, String version, String tag, Supplier 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 computeIfAbsent(Source path, String tag, Supplier 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); } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java index 43801539d0..eeaaa66336 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java @@ -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 { Class 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 RAW = new ModelCacheTag() { @@ -59,6 +77,17 @@ interface ModelCacheTag { public Class 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 { public Class getType() { return DependencyManagement.class; } - }; - /** - * The tag used for the file model without profile activation - * @since 4.0.0 - */ - ModelCacheTag FILE = new ModelCacheTag() { @Override - public String getName() { - return "file"; + public DependencyManagement intoCache(DependencyManagement data) { + return (data != null) ? data.clone() : null; } @Override - public Class getType() { - return Model.class; + public DependencyManagement fromCache(DependencyManagement data) { + return intoCache(data); } }; } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java index 20164c10b4..3fc221bb19 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java @@ -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 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 getActiveProfiles() { + return activeProfiles; + } + + /** + * Sets the active profiles from the model. + * + * @param activeProfiles The active profiles, may be {@code null}. + */ + public void setActiveProfiles(List 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 ::}. * * @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 diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblem.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblem.java index 624ae09e89..4a8feb3343 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblem.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblem.java @@ -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}. */ diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemUtils.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemUtils.java index bcbcaf575c..8a694d122c 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemUtils.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemUtils.java @@ -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(", "); } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSource3.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSource3.java deleted file mode 100644 index e66814349a..0000000000 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSource3.java +++ /dev/null @@ -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 MUST - * accept relPath parameter values that - *
    - *
  • use either / or \ file path separator
  • - *
  • have .. parent directory references
  • - *
  • point either at file or directory
  • - *
- * 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 null 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); - } -} diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java deleted file mode 100644 index ea08b588db..0000000000 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java +++ /dev/null @@ -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; -} diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/Result.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/Result.java index c4ac3a0b53..ef68b928eb 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/Result.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/Result.java @@ -49,7 +49,7 @@ public class Result { * @param model */ public static Result success(T model) { - return success(model, Collections.emptyList()); + return success(model, Collections.emptyList()); } /** @@ -91,7 +91,7 @@ public class Result { } public static Result error(T model) { - return error(model, Collections.emptyList()); + return error(model, Collections.emptyList()); } public static Result error(Result result) { diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerContext.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerContext.java deleted file mode 100644 index 3f65204827..0000000000 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerContext.java +++ /dev/null @@ -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); -} diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerContextBuilder.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerContextBuilder.java deleted file mode 100644 index e2b714e854..0000000000 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerContextBuilder.java +++ /dev/null @@ -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(); -} diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java index 6b542e74ac..6835c5e982 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java @@ -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 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 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 ce1, Collection ce2) { - if (ce1.size() == ce2.size()) { - Iterator i1 = ce1.iterator(); - Iterator 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()); } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/composition/DependencyManagementImporter.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/composition/DependencyManagementImporter.java index 787248e07e..2d9ae33f3d 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/composition/DependencyManagementImporter.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/composition/DependencyManagementImporter.java @@ -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 sources, ModelBuildingRequest request, diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java index fb28922999..18070ce187 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java @@ -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 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 context) { - Map merged = new HashMap<>(); + ModelBase target, ModelBase source, boolean sourceDominant, Map 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 s, Map t, Object excludeKey) { - for (Map.Entry e : t.entrySet()) { + private void putAll(Map s, Map t, Object excludeKey) { + for (Map.Entry 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 context) { + PluginContainer target, PluginContainer source, boolean sourceDominant, Map context) { List src = source.getPlugins(); if (!src.isEmpty()) { List 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> predecessors = new LinkedHashMap<>(); List 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 context) { - Plugin.Builder builder = Plugin.newBuilder(target); + protected void mergePlugin(Plugin target, Plugin source, boolean sourceDominant, Map 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 context) { + Reporting target, Reporting source, boolean sourceDominant, Map context) { List src = source.getPlugins(); if (!src.isEmpty()) { List tgt = target.getPlugins(); Map 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())); } } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/InheritanceAssembler.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/InheritanceAssembler.java index c4c7347539..efab77ea1e 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/InheritanceAssembler.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/InheritanceAssembler.java @@ -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); } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java index 09d1737fc0..78fdd1883b 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java @@ -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 PROJECT_PREFIXES_3_1 = Arrays.asList(PREFIX_POM, PREFIX_PROJECT); - private static final List PROJECT_PREFIXES_4_0 = Collections.singletonList(PREFIX_PROJECT); + private static final List PROJECT_PREFIXES = Arrays.asList("pom.", "project."); private static final Collection 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 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 createValueSources( final Model model, - final Path projectDir, + final File projectDir, final ModelBuildingRequest config, - ModelProblemCollector problems) { - Map 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 createPostProcessors( - final Model model, final Path projectDir, final ModelBuildingRequest config) { + final Model model, final File projectDir, final ModelBuildingRequest config) { List 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); } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/BuildTimestampValueSource.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/BuildTimestampValueSource.java index e0794f2c82..931890897e 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/BuildTimestampValueSource.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/BuildTimestampValueSource.java @@ -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 properties; + private final MavenBuildTimestamp mavenBuildTimestamp; - BuildTimestampValueSource(Date startTime, Map 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; } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/MavenBuildTimestamp.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/MavenBuildTimestamp.java index ae6dd2f864..235164e1eb 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/MavenBuildTimestamp.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/MavenBuildTimestamp.java @@ -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 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); } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ModelInterpolator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ModelInterpolator.java index 90d765c095..e2c3bc4ffc 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ModelInterpolator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ModelInterpolator.java @@ -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); } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/PathTranslatingPostProcessor.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/PathTranslatingPostProcessor.java index 0579a891a9..58bde4132b 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/PathTranslatingPostProcessor.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/PathTranslatingPostProcessor.java @@ -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 unprefixedPathKeys; - private final Path projectDir; + private final File projectDir; private final PathTranslator pathTranslator; private final List expressionPrefixes; PathTranslatingPostProcessor( List expressionPrefixes, Collection unprefixedPathKeys, - Path projectDir, + File projectDir, PathTranslator pathTranslator) { this.expressionPrefixes = expressionPrefixes; this.unprefixedPathKeys = unprefixedPathKeys; diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ProblemDetectingValueSource.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ProblemDetectingValueSource.java index 35586d9118..28484c4c38 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ProblemDetectingValueSource.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ProblemDetectingValueSource.java @@ -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)); diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringSearchModelInterpolator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringSearchModelInterpolator.java new file mode 100644 index 0000000000..52d912ca8d --- /dev/null +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringSearchModelInterpolator.java @@ -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, 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 valueSources = createValueSources(model, projectDir, config, problems); + List postProcessors = createPostProcessors(model, projectDir, config); + + InnerInterpolator innerInterpolator = createInterpolator(valueSources, postProcessors, problems); + + new InterpolateObjectAction(obj, innerInterpolator, problems).run(); + } + + private InnerInterpolator createInterpolator( + List valueSources, + List postProcessors, + final ModelProblemCollector problems) { + final Map 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 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 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 c = (List) 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 m = (Map) field.get(target); + if (m == null || m.isEmpty()) { + return; + } + + for (Map.Entry 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); + } + } + } + } + } +} diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringVisitorModelInterpolator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringVisitorModelInterpolator.java index e29879a4ae..d325eb6e73 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringVisitorModelInterpolator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringVisitorModelInterpolator.java @@ -18,31 +18,64 @@ */ package org.apache.maven.model.interpolation; -import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import java.io.File; -import java.nio.file.Path; import java.util.HashMap; import java.util.List; +import java.util.ListIterator; import java.util.Map; +import java.util.Properties; -import org.apache.maven.api.model.Model; +import org.apache.maven.model.Activation; +import org.apache.maven.model.ActivationFile; +import org.apache.maven.model.ActivationOS; +import org.apache.maven.model.ActivationProperty; +import org.apache.maven.model.Build; +import org.apache.maven.model.BuildBase; +import org.apache.maven.model.CiManagement; +import org.apache.maven.model.Contributor; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.DependencyManagement; +import org.apache.maven.model.Developer; +import org.apache.maven.model.DistributionManagement; +import org.apache.maven.model.Exclusion; +import org.apache.maven.model.Extension; +import org.apache.maven.model.IssueManagement; +import org.apache.maven.model.License; +import org.apache.maven.model.MailingList; +import org.apache.maven.model.Model; +import org.apache.maven.model.ModelBase; +import org.apache.maven.model.Notifier; +import org.apache.maven.model.Organization; +import org.apache.maven.model.Parent; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginExecution; +import org.apache.maven.model.PluginManagement; +import org.apache.maven.model.Prerequisites; +import org.apache.maven.model.Profile; +import org.apache.maven.model.Relocation; +import org.apache.maven.model.ReportPlugin; +import org.apache.maven.model.ReportSet; +import org.apache.maven.model.Reporting; +import org.apache.maven.model.Repository; +import org.apache.maven.model.RepositoryBase; +import org.apache.maven.model.RepositoryPolicy; +import org.apache.maven.model.Resource; +import org.apache.maven.model.Scm; +import org.apache.maven.model.Site; 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.apache.maven.model.path.PathTranslator; -import org.apache.maven.model.path.UrlNormalizer; -import org.apache.maven.model.root.RootLocator; -import org.apache.maven.model.v4.MavenTransformer; 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; +import org.codehaus.plexus.util.xml.Xpp3Dom; /** * StringVisitorModelInterpolator @@ -54,39 +87,28 @@ import org.codehaus.plexus.interpolation.ValueSource; @Singleton @Deprecated(since = "4.0.0") public class StringVisitorModelInterpolator extends AbstractStringBasedModelInterpolator { - @Inject - public StringVisitorModelInterpolator( - PathTranslator pathTranslator, UrlNormalizer urlNormalizer, RootLocator rootLocator) { - super(pathTranslator, urlNormalizer, rootLocator); - } interface InnerInterpolator { String interpolate(String value); } - @Deprecated @Override public Model interpolateModel( Model model, File projectDir, ModelBuildingRequest config, ModelProblemCollector problems) { - return interpolateModel(model, projectDir != null ? projectDir.toPath() : null, config, problems); - } - - @Override - public Model interpolateModel( - Model model, Path projectDir, ModelBuildingRequest config, ModelProblemCollector problems) { List valueSources = createValueSources(model, projectDir, config, problems); List postProcessors = createPostProcessors(model, projectDir, config); - InnerInterpolator innerInterpolator = createInterpolator(valueSources, postProcessors, problems, config); + InnerInterpolator innerInterpolator = createInterpolator(valueSources, postProcessors, problems); - return new MavenTransformer(innerInterpolator::interpolate).visit(model); + new ModelVisitor(innerInterpolator).visit(model); + + return model; } private InnerInterpolator createInterpolator( List valueSources, List postProcessors, - final ModelProblemCollector problems, - ModelBuildingRequest config) { + final ModelProblemCollector problems) { final Map cache = new HashMap<>(); final StringSearchInterpolator interpolator = new StringSearchInterpolator(); interpolator.setCacheAnswers(true); @@ -96,23 +118,1106 @@ public class StringVisitorModelInterpolator extends AbstractStringBasedModelInte for (InterpolationPostProcessor postProcessor : postProcessors) { interpolator.addPostProcessor(postProcessor); } - final RecursionInterceptor recursionInterceptor = createRecursionInterceptor(config); - return 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)); + 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); } - cache.put(value, c); + return c; } - return c; + return value; } - return value; }; } + + @SuppressWarnings("StringEquality") + private static final class ModelVisitor { + private final InnerInterpolator interpolator; + + ModelVisitor(InnerInterpolator interpolator) { + this.interpolator = interpolator; + } + + void visit(Model model) { + if (model != null) { + visit((ModelBase) model); + // ModelVersion + String orgModelVersion = model.getModelVersion(); + String intModelVersion = interpolate(orgModelVersion); + if (orgModelVersion != intModelVersion) { + model.setModelVersion(intModelVersion); + } + visit(model.getParent()); + // GroupId + String orgGroupId = model.getGroupId(); + String intGroupId = interpolate(orgGroupId); + if (orgGroupId != intGroupId) { + model.setGroupId(intGroupId); + } + // ArtifactId + String orgArtifactId = model.getArtifactId(); + String intArtifactId = interpolate(orgArtifactId); + if (orgArtifactId != intArtifactId) { + model.setArtifactId(intArtifactId); + } + // Version + String orgVersion = model.getVersion(); + String intVersion = interpolate(orgVersion); + if (orgVersion != intVersion) { + model.setVersion(intVersion); + } + + // Packaging + String orgPackaging = model.getPackaging(); + String intPackaging = interpolate(orgPackaging); + if (orgPackaging != intPackaging) { + model.setPackaging(intPackaging); + } + // Name + String orgName = model.getName(); + String intName = interpolate(orgName); + if (orgName != intName) { + model.setName(intName); + } + // Description + String orgDescription = model.getDescription(); + String intDescription = interpolate(orgDescription); + if (orgDescription != intDescription) { + model.setDescription(intDescription); + } + // Url + String orgUrl = model.getUrl(); + String intUrl = interpolate(orgUrl); + if (orgUrl != intUrl) { + model.setUrl(intUrl); + } + // ChildProjectUrlInheritAppendPath + String orgChildProjectUrlInheritAppendPath = model.getChildProjectUrlInheritAppendPath(); + String intChildProjectUrlInheritAppendPath = interpolate(orgChildProjectUrlInheritAppendPath); + if (orgChildProjectUrlInheritAppendPath != intChildProjectUrlInheritAppendPath) { + model.setChildProjectUrlInheritAppendPath(intChildProjectUrlInheritAppendPath); + } + // InceptionYear + String orgInceptionYear = model.getInceptionYear(); + String intInceptionYear = interpolate(orgInceptionYear); + if (orgInceptionYear != intInceptionYear) { + model.setInceptionYear(intInceptionYear); + } + visit(model.getOrganization()); + for (License license : model.getLicenses()) { + visit(license); + } + for (Developer developer : model.getDevelopers()) { + visit(developer); + } + for (Contributor contributor : model.getContributors()) { + visit(contributor); + } + for (MailingList mailingList : model.getMailingLists()) { + visit(mailingList); + } + visit(model.getPrerequisites()); + visit(model.getScm()); + visit(model.getIssueManagement()); + visit(model.getCiManagement()); + visit(model.getBuild()); + for (Profile profile : model.getProfiles()) { + visit(profile); + } + } + } + + private void visit(Parent parent) { + if (parent != null) { + String org, val; + // GroupId + org = parent.getGroupId(); + val = interpolate(org); + if (org != val) { + parent.setGroupId(val); + } + // ArtifactId + org = parent.getArtifactId(); + val = interpolate(org); + if (org != val) { + parent.setArtifactId(val); + } + // Version + org = parent.getVersion(); + val = interpolate(org); + if (org != val) { + parent.setVersion(val); + } + // RelativePath + org = parent.getRelativePath(); + val = interpolate(org); + if (org != val) { + parent.setRelativePath(val); + } + } + } + + private void visit(Organization organization) { + if (organization != null) { + String org, val; + // Name + org = organization.getName(); + val = interpolate(org); + if (org != val) { + organization.setName(val); + } + // Url + org = organization.getUrl(); + val = interpolate(org); + if (org != val) { + organization.setUrl(val); + } + } + } + + private void visit(License license) { + if (license != null) { + String org, val; + // Name + org = license.getName(); + val = interpolate(org); + if (org != val) { + license.setName(val); + } + // Url + org = license.getUrl(); + val = interpolate(org); + if (org != val) { + license.setUrl(val); + } + // Distribution + org = license.getDistribution(); + val = interpolate(org); + if (org != val) { + license.setDistribution(val); + } + // Comments + org = license.getComments(); + val = interpolate(org); + if (org != val) { + license.setComments(val); + } + } + } + + private void visit(Developer developer) { + if (developer != null) { + String org, val; + // Contributor + visit((Contributor) developer); + // Distribution + org = developer.getId(); + val = interpolate(org); + if (org != val) { + developer.setId(val); + } + } + } + + private void visit(Contributor contributor) { + if (contributor != null) { + String org, val; + // Name + org = contributor.getName(); + val = interpolate(org); + if (org != val) { + contributor.setName(val); + } + // Email + org = contributor.getEmail(); + val = interpolate(org); + if (org != val) { + contributor.setEmail(val); + } + // Url + org = contributor.getUrl(); + val = interpolate(org); + if (org != val) { + contributor.setUrl(val); + } + // Organization + org = contributor.getOrganization(); + val = interpolate(org); + if (org != val) { + contributor.setOrganization(val); + } + // OrganizationUrl + org = contributor.getOrganizationUrl(); + val = interpolate(org); + if (org != val) { + contributor.setOrganizationUrl(val); + } + // Roles + visit(contributor.getRoles()); + } + } + + private void visit(MailingList mailingList) { + if (mailingList != null) { + String org, val; + // Name + org = mailingList.getName(); + val = interpolate(org); + if (org != val) { + mailingList.setName(val); + } + // Subscribe + org = mailingList.getSubscribe(); + val = interpolate(org); + if (org != val) { + mailingList.setSubscribe(val); + } + // Unsubscribe + org = mailingList.getUnsubscribe(); + val = interpolate(org); + if (org != val) { + mailingList.setUnsubscribe(val); + } + // Post + org = mailingList.getPost(); + val = interpolate(org); + if (org != val) { + mailingList.setPost(val); + } + // Archive + org = mailingList.getArchive(); + val = interpolate(org); + if (org != val) { + mailingList.setArchive(val); + } + } + } + + private void visit(Prerequisites prerequisites) { + if (prerequisites != null) { + String org, val; + // Maven + org = prerequisites.getMaven(); + val = interpolate(org); + if (org != val) { + prerequisites.setMaven(val); + } + } + } + + private void visit(Scm scm) { + if (scm != null) { + String org, val; + // Connection + org = scm.getConnection(); + val = interpolate(org); + if (org != val) { + scm.setConnection(val); + } + // DeveloperConnection + org = scm.getDeveloperConnection(); + val = interpolate(org); + if (org != val) { + scm.setDeveloperConnection(val); + } + // Tag + org = scm.getTag(); + val = interpolate(org); + if (org != val) { + scm.setTag(val); + } + // Url + org = scm.getUrl(); + val = interpolate(org); + if (org != val) { + scm.setUrl(val); + } + // ChildScmConnectionInheritAppendPath + org = scm.getChildScmConnectionInheritAppendPath(); + val = interpolate(org); + if (org != val) { + scm.setChildScmConnectionInheritAppendPath(val); + } + // ChildScmDeveloperConnectionInheritAppendPath + org = scm.getChildScmDeveloperConnectionInheritAppendPath(); + val = interpolate(org); + if (org != val) { + scm.setChildScmDeveloperConnectionInheritAppendPath(val); + } + // ChildScmUrlInheritAppendPath + org = scm.getChildScmUrlInheritAppendPath(); + val = interpolate(org); + if (org != val) { + scm.setChildScmUrlInheritAppendPath(val); + } + } + } + + private void visit(IssueManagement issueManagement) { + if (issueManagement != null) { + String org, val; + // System + org = issueManagement.getSystem(); + val = interpolate(org); + if (org != val) { + issueManagement.setSystem(val); + } + // Url + org = issueManagement.getUrl(); + val = interpolate(org); + if (org != val) { + issueManagement.setUrl(val); + } + } + } + + private void visit(CiManagement ciManagement) { + if (ciManagement != null) { + String org, val; + // System + org = ciManagement.getSystem(); + val = interpolate(org); + if (org != val) { + ciManagement.setSystem(val); + } + // Url + org = ciManagement.getUrl(); + val = interpolate(org); + if (org != val) { + ciManagement.setUrl(val); + } + // Notifiers + for (Notifier notifier : ciManagement.getNotifiers()) { + visit(notifier); + } + } + } + + private void visit(Notifier notifier) { + if (notifier != null) { + String org, val; + // Type + org = notifier.getType(); + val = interpolate(org); + if (org != val) { + notifier.setType(val); + } + // Configuration + visit(notifier.getConfiguration()); + } + } + + private void visit(BuildBase build) { + if (build != null) { + String org, val; + // Plugins + for (Plugin plugin : build.getPlugins()) { + visit(plugin); + } + // PluginManagement + visit(build.getPluginManagement()); + // DefaultGoal + org = build.getDefaultGoal(); + val = interpolate(org); + if (org != val) { + build.setDefaultGoal(val); + } + // Resources + for (Resource resource : build.getResources()) { + visit(resource); + } + // TestResources + for (Resource resource : build.getTestResources()) { + visit(resource); + } + // Directory + org = build.getDirectory(); + val = interpolate(org); + if (org != val) { + build.setDirectory(val); + } + // FinalName + org = build.getFinalName(); + val = interpolate(org); + if (org != val) { + build.setFinalName(val); + } + // Filters + visit(build.getFilters()); + } + } + + private void visit(PluginManagement pluginManagement) { + if (pluginManagement != null) { + for (Plugin plugin : pluginManagement.getPlugins()) { + visit(plugin); + } + } + } + + private void visit(Build build) { + if (build != null) { + String org, val; + // BuildBase + visit((BuildBase) build); + // SourceDirectory + org = build.getSourceDirectory(); + val = interpolate(org); + if (org != val) { + build.setSourceDirectory(val); + } + // ScriptSourceDirectory + org = build.getScriptSourceDirectory(); + val = interpolate(org); + if (org != val) { + build.setScriptSourceDirectory(val); + } + // TestSourceDirectory + org = build.getTestSourceDirectory(); + val = interpolate(org); + if (org != val) { + build.setTestSourceDirectory(val); + } + // OutputDirectory + org = build.getOutputDirectory(); + val = interpolate(org); + if (org != val) { + build.setOutputDirectory(val); + } + // TestOutputDirectory + org = build.getTestOutputDirectory(); + val = interpolate(org); + if (org != val) { + build.setTestOutputDirectory(val); + } + // Extensions + for (Extension extension : build.getExtensions()) { + visit(extension); + } + } + } + + private void visit(Resource resource) { + if (resource != null) { + String org, val; + // Includes + visit(resource.getIncludes()); + // Excludes + visit(resource.getExcludes()); + // Directory + org = resource.getDirectory(); + val = interpolate(org); + if (org != val) { + resource.setDirectory(val); + } + // TargetPath + org = resource.getTargetPath(); + val = interpolate(org); + if (org != val) { + resource.setTargetPath(val); + } + // Filtering + org = resource.getFiltering(); + val = interpolate(org); + if (org != val) { + resource.setFiltering(val); + } + } + } + + private void visit(Plugin plugin) { + if (plugin != null) { + String org, val; + // Inherited + org = plugin.getInherited(); + val = interpolate(org); + if (org != val) { + plugin.setInherited(val); + } + // Configuration + visit((Xpp3Dom) plugin.getConfiguration()); + // GroupId + org = plugin.getGroupId(); + val = interpolate(org); + if (org != val) { + plugin.setGroupId(val); + } + // ArtifactId + org = plugin.getArtifactId(); + val = interpolate(org); + if (org != val) { + plugin.setArtifactId(val); + } + // Version + org = plugin.getVersion(); + val = interpolate(org); + if (org != val) { + plugin.setVersion(val); + } + // Extensions + org = plugin.getExtensions(); + val = interpolate(org); + if (org != val) { + plugin.setExtensions(val); + } + // Executions + for (PluginExecution execution : plugin.getExecutions()) { + visit(execution); + } + // Dependencies + for (Dependency dependency : plugin.getDependencies()) { + visit(dependency); + } + } + } + + private void visit(PluginExecution execution) { + if (execution != null) { + String org, val; + // Inherited + org = execution.getInherited(); + val = interpolate(org); + if (org != val) { + execution.setInherited(val); + } + // Configuration + visit((Xpp3Dom) execution.getConfiguration()); + // Id + org = execution.getId(); + val = interpolate(org); + if (org != val) { + execution.setId(val); + } + // Phase + org = execution.getPhase(); + val = interpolate(org); + if (org != val) { + execution.setPhase(val); + } + // Goals + visit(execution.getGoals()); + } + } + + private void visit(Xpp3Dom dom) { + if (dom != null) { + String org, val; + // Content + org = dom.getValue(); + val = interpolate(org); + if (org != val) { + dom.setValue(val); + } + // Attributes + for (String attr : dom.getAttributeNames()) { + org = dom.getAttribute(attr); + val = interpolate(org); + if (org != val) { + dom.setAttribute(attr, val); + } + } + // Children + for (int i = 0, l = dom.getChildCount(); i < l; i++) { + visit(dom.getChild(i)); + } + } + } + + private void visit(Extension extension) { + if (extension != null) { + String org, val; + // GroupId + org = extension.getGroupId(); + val = interpolate(org); + if (org != val) { + extension.setGroupId(val); + } + // ArtifactId + org = extension.getArtifactId(); + val = interpolate(org); + if (org != val) { + extension.setArtifactId(val); + } + // Version + org = extension.getVersion(); + val = interpolate(org); + if (org != val) { + extension.setVersion(val); + } + } + } + + private void visit(Profile profile) { + if (profile != null) { + String org, val; + // ModelBase + visit((ModelBase) profile); + // Id + org = profile.getId(); + val = interpolate(org); + if (org != val) { + profile.setId(val); + } + // Activation + visit(profile.getActivation()); + // Build + visit(profile.getBuild()); + } + } + + private void visit(Activation activation) { + if (activation != null) { + String org, val; + // Jdk + org = activation.getJdk(); + val = interpolate(org); + if (org != val) { + activation.setJdk(val); + } + // OS + visit(activation.getOs()); + // Property + visit(activation.getProperty()); + // File + visit(activation.getFile()); + } + } + + private void visit(ActivationOS activationOS) { + if (activationOS != null) { + String org, val; + // Name + org = activationOS.getName(); + val = interpolate(org); + if (org != val) { + activationOS.setName(val); + } + // Family + org = activationOS.getFamily(); + val = interpolate(org); + if (org != val) { + activationOS.setFamily(val); + } + // Arch + org = activationOS.getArch(); + val = interpolate(org); + if (org != val) { + activationOS.setArch(val); + } + // Version + org = activationOS.getVersion(); + val = interpolate(org); + if (org != val) { + activationOS.setVersion(val); + } + } + } + + private void visit(ActivationProperty activationProperty) { + if (activationProperty != null) { + String org, val; + // Name + org = activationProperty.getName(); + val = interpolate(org); + if (org != val) { + activationProperty.setName(val); + } + // Value + org = activationProperty.getValue(); + val = interpolate(org); + if (org != val) { + activationProperty.setValue(val); + } + } + } + + private void visit(ActivationFile activationFile) { + if (activationFile != null) { + String org, val; + // Missing + org = activationFile.getMissing(); + val = interpolate(org); + if (org != val) { + activationFile.setMissing(val); + } + // Exists + org = activationFile.getExists(); + val = interpolate(org); + if (org != val) { + activationFile.setExists(val); + } + } + } + + private void visit(ModelBase modelBase) { + if (modelBase != null) { + visit(modelBase.getModules()); + visit(modelBase.getDistributionManagement()); + visit(modelBase.getProperties()); + visit(modelBase.getDependencyManagement()); + for (Dependency dependency : modelBase.getDependencies()) { + visit(dependency); + } + for (Repository repository : modelBase.getRepositories()) { + visit(repository); + } + for (Repository repository : modelBase.getPluginRepositories()) { + visit(repository); + } + visit(modelBase.getReporting()); + } + } + + private void visit(DistributionManagement distributionManagement) { + if (distributionManagement != null) { + String org, val; + // Repository + visit(distributionManagement.getRepository()); + // SnapshotRepository + visit(distributionManagement.getSnapshotRepository()); + // Site + visit(distributionManagement.getSite()); + // DownloadUrl + org = distributionManagement.getDownloadUrl(); + val = interpolate(org); + if (org != val) { + distributionManagement.setDownloadUrl(val); + } + // Relocation + visit(distributionManagement.getRelocation()); + } + } + + private void visit(Site site) { + if (site != null) { + String org, val; + // Id + org = site.getId(); + val = interpolate(org); + if (org != val) { + site.setId(val); + } + // Name + org = site.getName(); + val = interpolate(org); + if (org != val) { + site.setName(val); + } + // Url + org = site.getUrl(); + val = interpolate(org); + if (org != val) { + site.setUrl(val); + } + // ChildSiteUrlInheritAppendPath + org = site.getChildSiteUrlInheritAppendPath(); + val = interpolate(org); + if (org != val) { + site.setChildSiteUrlInheritAppendPath(val); + } + } + } + + private void visit(Relocation relocation) { + if (relocation != null) { + String org, val; + // GroupId + org = relocation.getGroupId(); + val = interpolate(org); + if (org != val) { + relocation.setGroupId(val); + } + // ArtifactId + org = relocation.getArtifactId(); + val = interpolate(org); + if (org != val) { + relocation.setArtifactId(val); + } + // Version + org = relocation.getVersion(); + val = interpolate(org); + if (org != val) { + relocation.setVersion(val); + } + // Message + org = relocation.getMessage(); + val = interpolate(org); + if (org != val) { + relocation.setMessage(val); + } + } + } + + private void visit(DependencyManagement dependencyManagement) { + if (dependencyManagement != null) { + // Dependencies + for (Dependency dependency : dependencyManagement.getDependencies()) { + visit(dependency); + } + } + } + + private void visit(Repository repository) { + if (repository != null) { + visit((RepositoryBase) repository); + visit(repository.getReleases()); + visit(repository.getSnapshots()); + } + } + + private void visit(RepositoryBase repositoryBase) { + if (repositoryBase != null) { + // Id + String orgId = repositoryBase.getId(); + String intId = interpolate(orgId); + if (orgId != intId) { + repositoryBase.setId(intId); + } + // Name + String orgName = repositoryBase.getName(); + String intName = interpolate(orgName); + if (orgName != intName) { + repositoryBase.setName(intName); + } + // Url + String orgUrl = repositoryBase.getUrl(); + String intUrl = interpolate(orgUrl); + if (orgUrl != intUrl) { + repositoryBase.setUrl(intUrl); + } + // Layout + String orgLayout = repositoryBase.getLayout(); + String intLayout = interpolate(orgLayout); + if (orgLayout != intLayout) { + repositoryBase.setLayout(intLayout); + } + } + } + + private void visit(RepositoryPolicy repositoryPolicy) { + if (repositoryPolicy != null) { + // Enabled + String orgEnabled = repositoryPolicy.getEnabled(); + String intEnabled = interpolate(orgEnabled); + if (orgEnabled != intEnabled) { + repositoryPolicy.setEnabled(intEnabled); + } + // UpdatePolicy + String orgUpdatePolicy = repositoryPolicy.getUpdatePolicy(); + String intUpdatePolicy = interpolate(orgUpdatePolicy); + if (orgUpdatePolicy != intUpdatePolicy) { + repositoryPolicy.setUpdatePolicy(intUpdatePolicy); + } + // ChecksumPolicy + String orgChecksumPolicy = repositoryPolicy.getChecksumPolicy(); + String intChecksumPolicy = interpolate(orgChecksumPolicy); + if (orgChecksumPolicy != intChecksumPolicy) { + repositoryPolicy.setChecksumPolicy(intChecksumPolicy); + } + } + } + + private void visit(Dependency dependency) { + if (dependency != null) { + String org, val; + // GroupId + org = dependency.getGroupId(); + val = interpolate(org); + if (org != val) { + dependency.setGroupId(val); + dependency.clearManagementKey(); + } + // ArtifactId + org = dependency.getArtifactId(); + val = interpolate(org); + if (org != val) { + dependency.setArtifactId(val); + dependency.clearManagementKey(); + } + // Version + org = dependency.getVersion(); + val = interpolate(org); + if (org != val) { + dependency.setVersion(val); + } + // Type + org = dependency.getType(); + val = interpolate(org); + if (org != val) { + dependency.setType(val); + dependency.clearManagementKey(); + } + // Classifier + org = dependency.getClassifier(); + val = interpolate(org); + if (org != val) { + dependency.setClassifier(val); + dependency.clearManagementKey(); + } + // Scope + org = dependency.getScope(); + val = interpolate(org); + if (org != val) { + dependency.setScope(val); + } + // SystemPath + org = dependency.getSystemPath(); + val = interpolate(org); + if (org != val) { + dependency.setSystemPath(val); + } + // Exclusions + for (Exclusion exclusion : dependency.getExclusions()) { + visit(exclusion); + } + // Optional + org = dependency.getOptional(); + val = interpolate(org); + if (org != val) { + dependency.setOptional(val); + } + } + } + + private void visit(Exclusion exclusion) { + if (exclusion != null) { + String org, val; + // GroupId + org = exclusion.getGroupId(); + val = interpolate(org); + if (org != val) { + exclusion.setGroupId(val); + } + // ArtifactId + org = exclusion.getArtifactId(); + val = interpolate(org); + if (org != val) { + exclusion.setArtifactId(val); + } + } + } + + private void visit(Reporting reporting) { + if (reporting != null) { + String org, val; + // ExcludeDefaults + org = reporting.getExcludeDefaults(); + val = interpolate(org); + if (org != val) { + reporting.setExcludeDefaults(val); + } + // OutputDirectory + org = reporting.getOutputDirectory(); + val = interpolate(org); + if (org != val) { + reporting.setOutputDirectory(val); + } + // Plugins + for (ReportPlugin plugin : reporting.getPlugins()) { + visit(plugin); + } + } + } + + private void visit(ReportPlugin plugin) { + if (plugin != null) { + String org, val; + // Inherited + org = plugin.getInherited(); + val = interpolate(org); + if (org != val) { + plugin.setInherited(val); + } + // Configuration + visit((Xpp3Dom) plugin.getConfiguration()); + // GroupId + org = plugin.getGroupId(); + val = interpolate(org); + if (org != val) { + plugin.setGroupId(val); + } + // ArtifactId + org = plugin.getArtifactId(); + val = interpolate(org); + if (org != val) { + plugin.setArtifactId(val); + } + // Version + org = plugin.getVersion(); + val = interpolate(org); + if (org != val) { + plugin.setVersion(val); + } + // ReportSets + for (ReportSet reportSet : plugin.getReportSets()) { + visit(reportSet); + } + } + } + + private void visit(ReportSet reportSet) { + if (reportSet != null) { + String org, val; + // Inherited + org = reportSet.getInherited(); + val = interpolate(org); + if (org != val) { + reportSet.setInherited(val); + } + // Configuration + visit((Xpp3Dom) reportSet.getConfiguration()); + // Id + org = reportSet.getId(); + val = interpolate(org); + if (org != val) { + reportSet.setId(val); + } + // Reports + visit(reportSet.getReports()); + } + } + + private void visit(Properties properties) { + if (properties != null) { + for (Map.Entry entry : properties.entrySet()) { + Object v = entry.getValue(); + if (v instanceof String) { + String value = (String) v; + String inter = interpolate(value); + if (value != inter && inter != null) { + entry.setValue(inter); + } + } + } + } + } + + private void visit(List list) { + if (list != null) { + ListIterator it = list.listIterator(); + while (it.hasNext()) { + String value = it.next(); + String inter = interpolate(value); + if (value != inter) { + it.set(inter); + } + } + } + } + + private String interpolate(String value) { + return interpolator.interpolate(value); + } + } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java index 2a305c31ea..2013b2b06d 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java @@ -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 options) throws IOException { Objects.requireNonNull(input, "input cannot be null"); - return read(input.toPath(), options); - } - @Override - public Model read(Path path, Map 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 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 options) { - Object value = (options != null) ? options.get(ROOT_DIRECTORY) : null; - return (Path) value; - } - - private Model read(InputStream input, Path pomFile, Map 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 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); } } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelWriter.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelWriter.java index 9b078bf248..d1d5bc54cd 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelWriter.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelWriter.java @@ -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 options, org.apache.maven.model.Model model) throws IOException { - write(output, options, model.getDelegate()); - } - - @Override - public void write(Writer output, Map options, org.apache.maven.model.Model model) - throws IOException { - write(output, options, model.getDelegate()); - } - - @Override - public void write(OutputStream output, Map options, org.apache.maven.model.Model model) - throws IOException { - write(output, options, model.getDelegate()); - } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelReader.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelReader.java index f591c3efe1..13477cf38f 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelReader.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelReader.java @@ -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 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 options) throws IOException, ModelParseException; - /** * Reads the model from the specified character reader. The reader will be automatically closed before the method * returns. diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelWriter.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelWriter.java index f8d6c7a2ca..d394a237f4 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelWriter.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelWriter.java @@ -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 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 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 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 options, org.apache.maven.model.Model model) throws IOException; } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/locator/DefaultModelLocator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/locator/DefaultModelLocator.java index 8b47539979..836021e15c 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/locator/DefaultModelLocator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/locator/DefaultModelLocator.java @@ -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"); } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/locator/ModelLocator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/locator/ModelLocator.java index f3529bd444..0200cafb62 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/locator/ModelLocator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/locator/ModelLocator.java @@ -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); } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultDependencyManagementInjector.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultDependencyManagementInjector.java index 1f6e869fa9..c93198a280 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultDependencyManagementInjector.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultDependencyManagementInjector.java @@ -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 dependencies = new HashMap<>(); Map 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 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 context) { + Dependency target, Dependency source, boolean sourceDominant, Map context) { // optional flag is not managed } @Override protected void mergeDependency_Exclusions( - Dependency.Builder builder, - Dependency target, - Dependency source, - boolean sourceDominant, - Map context) { + Dependency target, Dependency source, boolean sourceDominant, Map context) { List tgt = target.getExclusions(); if (tgt.isEmpty()) { List src = source.getExclusions(); - builder.exclusions(src); + + for (Exclusion element : src) { + Exclusion clone = element.clone(); + target.addExclusion(clone); + } } } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultPluginManagementInjector.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultPluginManagementInjector.java index 51809bb559..2bfcbd650a 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultPluginManagementInjector.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultPluginManagementInjector.java @@ -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 src = source.getPlugins(); if (!src.isEmpty()) { + List tgt = target.getPlugins(); + Map managedPlugins = new LinkedHashMap<>(src.size() * 2); Map context = Collections.emptyMap(); for (Plugin element : src) { - Object key = getPluginKey().apply(element); + Object key = getPluginKey(element); managedPlugins.put(key, element); } - List 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 context) { + Plugin target, Plugin source, boolean sourceDominant, Map context) { List src = source.getExecutions(); if (!src.isEmpty()) { List tgt = target.getExecutions(); @@ -112,20 +104,20 @@ public class DefaultPluginManagementInjector implements PluginManagementInjector Map 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())); } } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/merge/MavenModelMerger.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/merge/MavenModelMerger.java index 29204bae43..546e7d0eef 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/merge/MavenModelMerger.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/merge/MavenModelMerger.java @@ -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 - * null. - * @param source The (read-only) source object that should be merged into the target object, may be - * null. - * @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 null. + * 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 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 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 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 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 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 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 context) { + // neither inherited nor injected + } + + @Override + protected void mergeModel_ArtifactId( + Model target, Model source, boolean sourceDominant, Map context) { + // neither inherited nor injected + } + + @Override + protected void mergeModel_Profiles( + Model target, Model source, boolean sourceDominant, Map context) { + // neither inherited nor injected + } + + @Override + protected void mergeModel_Prerequisites( + Model target, Model source, boolean sourceDominant, Map context) { + // neither inherited nor injected + } + + @Override + protected void mergeModel_Licenses( + Model target, Model source, boolean sourceDominant, Map context) { + if (target.getLicenses().isEmpty()) { + target.setLicenses(new ArrayList<>(source.getLicenses())); + } + } + + @Override + protected void mergeModel_Developers( + Model target, Model source, boolean sourceDominant, Map context) { + if (target.getDevelopers().isEmpty()) { + target.setDevelopers(new ArrayList<>(source.getDevelopers())); + } + } + + @Override + protected void mergeModel_Contributors( + Model target, Model source, boolean sourceDominant, Map context) { + if (target.getContributors().isEmpty()) { + target.setContributors(new ArrayList<>(source.getContributors())); + } + } + + @Override + protected void mergeModel_MailingLists( + Model target, Model source, boolean sourceDominant, Map context) { + if (target.getMailingLists().isEmpty()) { + target.setMailingLists(new ArrayList<>(source.getMailingLists())); + } + } + + @Override + protected void mergeModelBase_Modules( + ModelBase target, ModelBase source, boolean sourceDominant, Map context) { + List src = source.getModules(); + if (!src.isEmpty() && sourceDominant) { + List indices = new ArrayList<>(); + List tgt = target.getModules(); + Set excludes = new LinkedHashSet<>(tgt); + List 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 context) { + List src = source.getRepositories(); + if (!src.isEmpty()) { + List tgt = target.getRepositories(); + Map merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2); + + List 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 context) { + List src = source.getPluginRepositories(); + if (!src.isEmpty()) { + List tgt = target.getPluginRepositories(); + Map merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2); + + List 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 context) { + List src = source.getFilters(); + if (!src.isEmpty()) { + List tgt = target.getFilters(); + Set excludes = new LinkedHashSet<>(tgt); + List 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 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 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 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 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 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 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 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 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 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 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 context) { + List src = source.getExecutions(); + if (!src.isEmpty()) { + List tgt = target.getExecutions(); + Map 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 context) { + List src = source.getGoals(); + if (!src.isEmpty()) { + List tgt = target.getGoals(); + Set excludes = new LinkedHashSet<>(tgt); + List 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 context) { + List src = source.getReportSets(); + if (!src.isEmpty()) { + List tgt = target.getReportSets(); + Map 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 context) { + return parentUrl; } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/normalization/DefaultModelNormalizer.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/normalization/DefaultModelNormalizer.java index db9894aaad..a6f89badcf 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/normalization/DefaultModelNormalizer.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/normalization/DefaultModelNormalizer.java @@ -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 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 List injectList(List list, Function modifer) { - List 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 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; } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/normalization/ModelNormalizer.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/normalization/ModelNormalizer.java index 7b25214d31..2d8190a9d3 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/normalization/ModelNormalizer.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/normalization/ModelNormalizer.java @@ -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); } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelPathTranslator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelPathTranslator.java index c3c2888d1b..2be81863e3 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelPathTranslator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelPathTranslator.java @@ -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 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 List map(List resources, Function mapper) { - List 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); } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelUrlNormalizer.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelUrlNormalizer.java index 5895a27462..b22c4e6a00 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelUrlNormalizer.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelUrlNormalizer.java @@ -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 diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultPathTranslator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultPathTranslator.java index c3b7f252b2..aa502caa95 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultPathTranslator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultPathTranslator.java @@ -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(); } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/ModelPathTranslator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/ModelPathTranslator.java index 4b23892504..4d375f38d9 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/ModelPathTranslator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/ModelPathTranslator.java @@ -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); } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/PathTranslator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/PathTranslator.java index ee82d21375..5fdc481f34 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/PathTranslator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/PathTranslator.java @@ -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); } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/ProfileActivationFilePathInterpolator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/ProfileActivationFilePathInterpolator.java index 5f517635d2..098d68bc46 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/ProfileActivationFilePathInterpolator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/path/ProfileActivationFilePathInterpolator.java @@ -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; } /** diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultPluginConfigurationExpander.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultPluginConfigurationExpander.java index 712b5f54a5..3105cd0558 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultPluginConfigurationExpander.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultPluginConfigurationExpander.java @@ -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 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); } } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportConfigurationExpander.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportConfigurationExpander.java index a6d7c76e14..05ad746988 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportConfigurationExpander.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportConfigurationExpander.java @@ -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); } } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportingConverter.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportingConverter.java index 132017ef58..e4bc0df160 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportingConverter.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportingConverter.java @@ -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 <reporting> 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 section, " + + "not in maven-site-plugin 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 section + if ( !reporting.getPlugins().isEmpty() + && request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_1 ) + { + + problems.add( new ModelProblemCollectorRequest( Severity.WARNING, Version.V31 ) + .setMessage( "The section is deprecated, please move the reports to the " + + " 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; + } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileActivationContext.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileActivationContext.java index 41ab5e4904..31741b00d9 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileActivationContext.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileActivationContext.java @@ -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 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 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 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 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 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 unmodifiable(List list) { - return list != null ? Collections.unmodifiableList(list) : Collections.emptyList(); - } - - private static Map unmodifiable(Map map) { - return map != null ? Collections.unmodifiableMap(map) : Collections.emptyMap(); - } - - private static Map 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; - } - } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java index 8b6d4f7058..953c281f7a 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java @@ -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>> 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 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 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 context) { + PluginContainer target, PluginContainer source, boolean sourceDominant, Map context) { List src = source.getPlugins(); if (!src.isEmpty()) { List tgt = target.getPlugins(); Map master = new LinkedHashMap<>(tgt.size() * 2); for (Plugin element : tgt) { - Object key = getPluginKey().apply(element); + Object key = getPluginKey(element); master.put(key, element); } Map> predecessors = new LinkedHashMap<>(); List 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 context) { + Plugin target, Plugin source, boolean sourceDominant, Map context) { List src = source.getExecutions(); if (!src.isEmpty()) { List tgt = target.getExecutions(); Map 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 context) { + Reporting target, Reporting source, boolean sourceDominant, Map context) { List src = source.getPlugins(); if (!src.isEmpty()) { List tgt = target.getPlugins(); Map 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 context) { + ReportPlugin target, ReportPlugin source, boolean sourceDominant, Map context) { List src = source.getReportSets(); if (!src.isEmpty()) { List tgt = target.getReportSets(); Map 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())); } } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileSelector.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileSelector.java index 766a461e95..773462a282 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileSelector.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileSelector.java @@ -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 activators; - - public DefaultProfileSelector() { - this.activators = new ArrayList<>(); - } - @Inject - public DefaultProfileSelector(List activators) { - this.activators = new ArrayList<>(activators); - } + private List 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 getActiveProfilesV4( - Collection 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 getActiveProfiles( Collection 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; diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileActivationContext.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileActivationContext.java index 217661cbdd..850f6c44bf 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileActivationContext.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileActivationContext.java @@ -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"; diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileInjector.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileInjector.java index d795b562d4..44c8a7a50a 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileInjector.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileInjector.java @@ -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 null. - * @param profile The (read-only) profile whose values should be injected, may be 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 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 null. - * @param profiles The (read-only) list of profiles whose values should be injected, must not be 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 org.apache.maven.api.model.Model injectProfiles( - org.apache.maven.api.model.Model model, - List 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; - } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileSelector.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileSelector.java index 91564746b2..cb30958493 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileSelector.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileSelector.java @@ -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 getActiveProfiles( Collection 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 getActiveProfilesV4( - Collection profiles, - ProfileActivationContext context, - ModelProblemCollector problems) { - return getActiveProfiles(profiles.stream().map(Profile::new).collect(Collectors.toList()), context, problems) - .stream() - .map(Profile::getDelegate) - .collect(Collectors.toList()); - } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java index 25880b5a68..cdecea130e 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java @@ -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; } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivator.java index f0294b49e3..8de7f8581f 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivator.java @@ -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 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)); } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivator.java index 481f59e057..641d1e7ab1 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivator.java @@ -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; } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/PropertyProfileActivator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/PropertyProfileActivator.java index 32476cc7a6..7adc38c30b 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/PropertyProfileActivator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/PropertyProfileActivator.java @@ -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; } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/resolution/InvalidRepositoryException.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/resolution/InvalidRepositoryException.java index 80edce2c1f..e423990bfd 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/resolution/InvalidRepositoryException.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/resolution/InvalidRepositoryException.java @@ -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. diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java index 53c30b23dd..7353257d95 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java @@ -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 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 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); - } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/superpom/DefaultSuperPomProvider.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/superpom/DefaultSuperPomProvider.java index 2bd85b8b25..f20b1bba6b 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/superpom/DefaultSuperPomProvider.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/superpom/DefaultSuperPomProvider.java @@ -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 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 options = new HashMap<>(2); - options.put("xml:" + version, "xml:" + version); + Map 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; } } diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java index 8c7128dbb3..697a5c5f74 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java @@ -24,8 +24,6 @@ import javax.inject.Singleton; import java.io.File; import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; import java.util.Deque; import java.util.HashMap; import java.util.HashSet; @@ -36,44 +34,39 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.function.Function; +import java.util.function.Consumer; import java.util.function.Supplier; -import java.util.function.UnaryOperator; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.StreamSupport; -import org.apache.maven.api.model.Activation; -import org.apache.maven.api.model.ActivationFile; -import org.apache.maven.api.model.ActivationOS; -import org.apache.maven.api.model.ActivationProperty; -import org.apache.maven.api.model.Build; -import org.apache.maven.api.model.BuildBase; -import org.apache.maven.api.model.Dependency; -import org.apache.maven.api.model.DependencyManagement; -import org.apache.maven.api.model.DistributionManagement; -import org.apache.maven.api.model.Exclusion; -import org.apache.maven.api.model.InputLocation; -import org.apache.maven.api.model.InputLocationTracker; -import org.apache.maven.api.model.Parent; -import org.apache.maven.api.model.Plugin; -import org.apache.maven.api.model.PluginExecution; -import org.apache.maven.api.model.PluginManagement; -import org.apache.maven.api.model.Profile; -import org.apache.maven.api.model.ReportPlugin; -import org.apache.maven.api.model.Reporting; -import org.apache.maven.api.model.Repository; -import org.apache.maven.api.model.Resource; +import org.apache.maven.model.Activation; +import org.apache.maven.model.Build; +import org.apache.maven.model.BuildBase; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.DependencyManagement; +import org.apache.maven.model.DistributionManagement; +import org.apache.maven.model.Exclusion; +import org.apache.maven.model.InputLocation; +import org.apache.maven.model.InputLocationTracker; import org.apache.maven.model.Model; +import org.apache.maven.model.Parent; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginExecution; +import org.apache.maven.model.PluginManagement; +import org.apache.maven.model.Profile; +import org.apache.maven.model.ReportPlugin; +import org.apache.maven.model.Reporting; +import org.apache.maven.model.Repository; +import org.apache.maven.model.Resource; 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.apache.maven.model.interpolation.ModelVersionProcessor; -import org.apache.maven.model.v4.MavenModelVersion; -import org.apache.maven.model.v4.MavenTransformer; +import org.codehaus.plexus.util.StringUtils; /** * @deprecated use {@link org.apache.maven.api.services.ModelBuilder} instead @@ -85,10 +78,7 @@ public class DefaultModelValidator implements ModelValidator { public static final String BUILD_ALLOW_EXPRESSION_IN_EFFECTIVE_PROJECT_VERSION = "maven.build.allowExpressionInEffectiveProjectVersion"; - public static final List VALID_MODEL_VERSIONS = - Collections.unmodifiableList(Arrays.asList("4.0.0", "4.1.0")); - - private static final Pattern EXPRESSION_NAME_PATTERN = Pattern.compile("\\$\\{(.+?)}"); + private static final Pattern CI_FRIENDLY_EXPRESSION = Pattern.compile("\\$\\{(.+?)}"); private static final Pattern EXPRESSION_PROJECT_NAME_PATTERN = Pattern.compile("\\$\\{(project.+?)}"); private static final String ILLEGAL_FS_CHARS = "\\/:\"<>|?*"; @@ -99,213 +89,18 @@ public class DefaultModelValidator implements ModelValidator { private static final String EMPTY = ""; - private record ActivationFrame(String location, Optional parent) {} + private final Set validIds = new HashSet<>(); - private static class ActivationWalker extends MavenTransformer { - - private final Deque stk; - - ActivationWalker(Deque stk, UnaryOperator transformer) { - super(transformer); - this.stk = stk; - } - - private ActivationFrame nextFrame(String property) { - return new ActivationFrame(property, Optional.empty()); - } - - private

ActivationFrame nextFrame(String property, Function child) { - @SuppressWarnings("unchecked") - final Optional

parent = (Optional

) stk.peek().parent; - return new ActivationFrame(property, parent.map(child)); - } - - @Override - public Activation transformActivation(Activation target) { - stk.push(new ActivationFrame("activation", Optional.of(target))); - try { - return super.transformActivation(target); - } finally { - stk.pop(); - } - } - - @Override - protected Activation.Builder transformActivation_ActiveByDefault( - Supplier creator, Activation.Builder builder, Activation target) { - return builder; - } - - @Override - protected Activation.Builder transformActivation_File( - Supplier creator, Activation.Builder builder, Activation target) { - stk.push(nextFrame("file", Activation::getFile)); - Optional.ofNullable(target.getFile()); - try { - return super.transformActivation_File(creator, builder, target); - } finally { - stk.pop(); - } - } - - @Override - protected ActivationFile.Builder transformActivationFile_Exists( - Supplier creator, - ActivationFile.Builder builder, - ActivationFile target) { - stk.push(nextFrame("exists")); - try { - return super.transformActivationFile_Exists(creator, builder, target); - } finally { - stk.pop(); - } - } - - @Override - protected ActivationFile.Builder transformActivationFile_Missing( - Supplier creator, - ActivationFile.Builder builder, - ActivationFile target) { - stk.push(nextFrame("missing")); - try { - return super.transformActivationFile_Missing(creator, builder, target); - } finally { - stk.pop(); - } - } - - @Override - protected Activation.Builder transformActivation_Jdk( - Supplier creator, Activation.Builder builder, Activation target) { - stk.push(nextFrame("jdk")); - try { - return super.transformActivation_Jdk(creator, builder, target); - } finally { - stk.pop(); - } - } - - @Override - protected Activation.Builder transformActivation_Os( - Supplier creator, Activation.Builder builder, Activation target) { - stk.push(nextFrame("os", Activation::getOs)); - try { - return super.transformActivation_Os(creator, builder, target); - } finally { - stk.pop(); - } - } - - @Override - protected ActivationOS.Builder transformActivationOS_Arch( - Supplier creator, ActivationOS.Builder builder, ActivationOS target) { - stk.push(nextFrame("arch")); - try { - return super.transformActivationOS_Arch(creator, builder, target); - } finally { - stk.pop(); - } - } - - @Override - protected ActivationOS.Builder transformActivationOS_Family( - Supplier creator, ActivationOS.Builder builder, ActivationOS target) { - stk.push(nextFrame("family")); - try { - return super.transformActivationOS_Family(creator, builder, target); - } finally { - stk.pop(); - } - } - - @Override - protected ActivationOS.Builder transformActivationOS_Name( - Supplier creator, ActivationOS.Builder builder, ActivationOS target) { - stk.push(nextFrame("name")); - try { - return super.transformActivationOS_Name(creator, builder, target); - } finally { - stk.pop(); - } - } - - @Override - protected ActivationOS.Builder transformActivationOS_Version( - Supplier creator, ActivationOS.Builder builder, ActivationOS target) { - stk.push(nextFrame("version")); - try { - return super.transformActivationOS_Version(creator, builder, target); - } finally { - stk.pop(); - } - } - - @Override - protected Activation.Builder transformActivation_Packaging( - Supplier creator, Activation.Builder builder, Activation target) { - stk.push(nextFrame("packaging")); - try { - return super.transformActivation_Packaging(creator, builder, target); - } finally { - stk.pop(); - } - } - - @Override - protected Activation.Builder transformActivation_Property( - Supplier creator, Activation.Builder builder, Activation target) { - stk.push(nextFrame("property", Activation::getProperty)); - try { - return super.transformActivation_Property(creator, builder, target); - } finally { - stk.pop(); - } - } - - @Override - protected ActivationProperty.Builder transformActivationProperty_Name( - Supplier creator, - ActivationProperty.Builder builder, - ActivationProperty target) { - stk.push(nextFrame("name")); - try { - return super.transformActivationProperty_Name(creator, builder, target); - } finally { - stk.pop(); - } - } - - @Override - protected ActivationProperty.Builder transformActivationProperty_Value( - Supplier creator, - ActivationProperty.Builder builder, - ActivationProperty target) { - stk.push(nextFrame("value")); - try { - return super.transformActivationProperty_Value(creator, builder, target); - } finally { - stk.pop(); - } - } - } - - private final Set validCoordinateIds = new HashSet<>(); - - private final Set validProfileIds = new HashSet<>(); - - private final ModelVersionProcessor versionProcessor; + private ModelVersionProcessor versionProcessor; @Inject public DefaultModelValidator(ModelVersionProcessor versionProcessor) { this.versionProcessor = versionProcessor; } + @SuppressWarnings("checkstyle:methodlength") @Override - @SuppressWarnings("checkstyle:MethodLength") - public void validateFileModel(Model ma, ModelBuildingRequest request, ModelProblemCollector problems) { - - org.apache.maven.api.model.Model m = ma.getDelegate(); - + public void validateRawModel(Model m, ModelBuildingRequest request, ModelProblemCollector problems) { Parent parent = m.getParent(); if (parent != null) { validateStringNotEmpty( @@ -314,6 +109,9 @@ public class DefaultModelValidator implements ModelValidator { validateStringNotEmpty( "parent.artifactId", problems, Severity.FATAL, Version.BASE, parent.getArtifactId(), parent); + validateStringNotEmpty( + "parent.version", problems, Severity.FATAL, Version.BASE, parent.getVersion(), parent); + if (equals(parent.getGroupId(), m.getGroupId()) && equals(parent.getArtifactId(), m.getArtifactId())) { addViolation( problems, @@ -338,29 +136,33 @@ public class DefaultModelValidator implements ModelValidator { } } - if (request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) { - Set modules = new HashSet<>(); - for (int i = 0, n = m.getModules().size(); i < n; i++) { - String module = m.getModules().get(i); - if (!modules.add(module)) { + if (request.getValidationLevel() == ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL) { + // profiles: they are essential for proper model building (may contribute profiles, dependencies...) + HashSet minProfileIds = new HashSet<>(); + for (Profile profile : m.getProfiles()) { + if (!minProfileIds.add(profile.getId())) { addViolation( problems, - Severity.ERROR, - Version.V20, - "modules.module[" + i + "]", + Severity.WARNING, + Version.BASE, + "profiles.profile.id", null, - "specifies duplicate child module " + module, - m.getLocation("modules")); + "Duplicate activation for profile " + profile.getId(), + profile); } } - + } else if (request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) { Severity errOn30 = getSeverity(request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_0); - // The file pom may not contain the modelVersion yet, as it may be set later by the - // ModelVersionXMLFilter. - if (m.getModelVersion() != null && !m.getModelVersion().isEmpty()) { - validateModelVersion(problems, m.getModelVersion(), m, VALID_MODEL_VERSIONS); - } + // [MNG-6074] Maven should produce an error if no model version has been set in a POM file used to build an + // effective model. + // + // As of 3.4, the model version is mandatory even in raw models. The XML element still is optional in the + // XML schema and this will not change anytime soon. We do not want to build effective models based on + // models without a version starting with 3.4. + validateStringNotEmpty("modelVersion", problems, Severity.ERROR, Version.V20, m.getModelVersion(), m); + + validateModelVersion(problems, m.getModelVersion(), m, "4.0.0"); validateStringNoExpression("groupId", problems, Severity.WARNING, Version.V20, m.getGroupId(), m); if (parent == null) { @@ -410,8 +212,6 @@ public class DefaultModelValidator implements ModelValidator { for (Profile profile : m.getProfiles()) { String prefix = "profiles.profile[" + profile.getId() + "]."; - validateProfileId(prefix, "id", problems, Severity.ERROR, Version.V40, profile.getId(), null, m); - if (!profileIds.add(profile.getId())) { addViolation( problems, @@ -461,50 +261,25 @@ public class DefaultModelValidator implements ModelValidator { } } - @Override - public void validateRawModel(Model ma, ModelBuildingRequest request, ModelProblemCollector problems) { - org.apache.maven.api.model.Model m = ma.getDelegate(); - - // [MNG-6074] Maven should produce an error if no model version has been set in a POM file used to build an - // effective model. - // - // As of 3.4, the model version is mandatory even in raw models. The XML element still is optional in the - // XML schema and this will not change anytime soon. We do not want to build effective models based on - // models without a version starting with 3.4. - validateStringNotEmpty("modelVersion", problems, Severity.ERROR, Version.V20, m.getModelVersion(), m); - - validateModelVersion(problems, m.getModelVersion(), m, VALID_MODEL_VERSIONS); - - String minVersion = new MavenModelVersion().getModelVersion(m); - if (m.getModelVersion() != null && compareModelVersions(minVersion, m.getModelVersion()) > 0) { - addViolation( - problems, - Severity.FATAL, - Version.V40, - "model", - null, - "the model contains elements that require a model version of " + minVersion, - m); - } - - Parent parent = m.getParent(); - - if (parent != null) { - validateStringNotEmpty( - "parent.version", problems, Severity.FATAL, Version.BASE, parent.getVersion(), parent); - } - } - private void validate30RawProfileActivation(ModelProblemCollector problems, Activation activation, String prefix) { if (activation == null) { return; } + class ActivationFrame { + String location; + Optional parent; + + ActivationFrame(String location, Optional parent) { + this.location = location; + this.parent = parent; + } + } final Deque stk = new LinkedList<>(); final Supplier pathSupplier = () -> { final boolean parallel = false; return StreamSupport.stream(((Iterable) stk::descendingIterator).spliterator(), parallel) - .map(ActivationFrame::location) + .map(f -> f.location) .collect(Collectors.joining(".")); }; final Supplier locationSupplier = () -> { @@ -518,7 +293,7 @@ public class DefaultModelValidator implements ModelValidator { return parent.parent.map(p -> p.getLocation(location)).orElse(null); }; - final UnaryOperator transformer = s -> { + final Consumer validator = s -> { if (hasProjectExpression(s)) { String path = pathSupplier.get(); Matcher matcher = EXPRESSION_PROJECT_NAME_PATTERN.matcher(s); @@ -539,9 +314,45 @@ public class DefaultModelValidator implements ModelValidator { locationSupplier.get()); } } - return s; }; - new ActivationWalker(stk, transformer).transformActivation(activation); + Optional root = Optional.of(activation); + stk.push(new ActivationFrame("activation", root)); + root.map(Activation::getFile).ifPresent(fa -> { + stk.push(new ActivationFrame("file", Optional.of(fa))); + stk.push(new ActivationFrame("exists", Optional.empty())); + validator.accept(fa.getExists()); + stk.peek().location = "missing"; + validator.accept(fa.getMissing()); + stk.pop(); + stk.pop(); + }); + root.map(Activation::getOs).ifPresent(oa -> { + stk.push(new ActivationFrame("os", Optional.of(oa))); + stk.push(new ActivationFrame("arch", Optional.empty())); + validator.accept(oa.getArch()); + stk.peek().location = "family"; + validator.accept(oa.getFamily()); + stk.peek().location = "name"; + validator.accept(oa.getName()); + stk.peek().location = "version"; + validator.accept(oa.getVersion()); + stk.pop(); + stk.pop(); + }); + root.map(Activation::getProperty).ifPresent(pa -> { + stk.push(new ActivationFrame("property", Optional.of(pa))); + stk.push(new ActivationFrame("name", Optional.empty())); + validator.accept(pa.getName()); + stk.peek().location = "value"; + validator.accept(pa.getValue()); + stk.pop(); + stk.pop(); + }); + root.map(Activation::getJdk).ifPresent(jdk -> { + stk.push(new ActivationFrame("jdk", Optional.empty())); + validator.accept(jdk); + stk.pop(); + }); } private void validate20RawPlugins( @@ -629,14 +440,12 @@ public class DefaultModelValidator implements ModelValidator { @Override @SuppressWarnings("checkstyle:MethodLength") - public void validateEffectiveModel(Model ma, ModelBuildingRequest request, ModelProblemCollector problems) { - org.apache.maven.api.model.Model m = ma.getDelegate(); - + public void validateEffectiveModel(Model m, ModelBuildingRequest request, ModelProblemCollector problems) { validateStringNotEmpty("modelVersion", problems, Severity.ERROR, Version.BASE, m.getModelVersion(), m); - validateCoordinateId("groupId", problems, m.getGroupId(), m); + validateId("groupId", problems, m.getGroupId(), m); - validateCoordinateId("artifactId", problems, m.getArtifactId(), m); + validateId("artifactId", problems, m.getArtifactId(), m); validateStringNotEmpty("packaging", problems, Severity.ERROR, Version.BASE, m.getPackaging(), m); @@ -655,17 +464,7 @@ public class DefaultModelValidator implements ModelValidator { for (int i = 0, n = m.getModules().size(); i < n; i++) { String module = m.getModules().get(i); - - boolean isBlankModule = true; - if (module != null) { - for (int j = 0; j < module.length(); j++) { - if (!Character.isWhitespace(module.charAt(j))) { - isBlankModule = false; - } - } - } - - if (isBlankModule) { + if (StringUtils.isBlank(module)) { addViolation( problems, Severity.ERROR, @@ -690,6 +489,21 @@ public class DefaultModelValidator implements ModelValidator { } if (request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) { + Set modules = new HashSet<>(); + for (int i = 0, n = m.getModules().size(); i < n; i++) { + String module = m.getModules().get(i); + if (!modules.add(module)) { + addViolation( + problems, + Severity.ERROR, + Version.V20, + "modules.module[" + i + "]", + null, + "specifies duplicate child module " + module, + m.getLocation("modules")); + } + } + Severity errOn31 = getSeverity(request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_1); validateBannedCharacters( @@ -697,9 +511,8 @@ public class DefaultModelValidator implements ModelValidator { validate20ProperSnapshotVersion("version", problems, errOn31, Version.V20, m.getVersion(), null, m); if (hasExpression(m.getVersion())) { Severity versionExpressionSeverity = Severity.ERROR; - if (m.getProperties() != null - && Boolean.parseBoolean( - m.getProperties().get(BUILD_ALLOW_EXPRESSION_IN_EFFECTIVE_PROJECT_VERSION))) { + if (Boolean.parseBoolean( + m.getProperties().getProperty(BUILD_ALLOW_EXPRESSION_IN_EFFECTIVE_PROJECT_VERSION))) { versionExpressionSeverity = Severity.WARNING; } addViolation( @@ -811,54 +624,6 @@ public class DefaultModelValidator implements ModelValidator { } } - @Override - public void validateExternalProfiles( - List activeExternalProfiles, - Model ma, - ModelBuildingRequest request, - ModelProblemCollector problems) { - org.apache.maven.api.model.Model m = ma.getDelegate(); - // check for id clashes in repositories - for (Profile profile : activeExternalProfiles.stream() - .map(org.apache.maven.model.Profile::getDelegate) - .collect(Collectors.toList())) { - String externalRepositoriesSource = "external profile with id '" + profile.getId() + "' in settings.xml"; - validateUniqueRepositoryIds( - false, m.getRepositories(), profile.getRepositories(), externalRepositoriesSource, problems); - validateUniqueRepositoryIds( - true, - m.getPluginRepositories(), - profile.getPluginRepositories(), - externalRepositoriesSource, - problems); - } - } - - private void validateUniqueRepositoryIds( - boolean isPluginRepository, - Collection pomRepositories, - Collection externalRepositories, - String externalRepositoriesSource, - ModelProblemCollector problems) { - for (Repository externalRepository : externalRepositories) { - Optional clashingPomRepository = pomRepositories.stream() - .filter(r -> Objects.equals(r.getId(), externalRepository.getId())) - .filter(r -> !Objects.equals(r.getUrl(), externalRepository.getUrl())) - .findFirst(); - if (clashingPomRepository.isPresent()) { - addViolation( - problems, - Severity.WARNING, - Version.BASE, - isPluginRepository ? "pluginRepositories.repository" : "repositories.repository", - clashingPomRepository.get().getId(), - "is overwritten by the repository with same id but having a different url from " - + externalRepositoriesSource, - clashingPomRepository.get()); - } - } - } - private void validate20RawDependencies( ModelProblemCollector problems, List dependencies, @@ -883,8 +648,7 @@ public class DefaultModelValidator implements ModelValidator { key, "must be 'pom' to import the managed dependencies.", dependency); - } else if (dependency.getClassifier() != null - && !dependency.getClassifier().isEmpty()) { + } else if (StringUtils.isNotEmpty(dependency.getClassifier())) { addViolation( problems, errOn30, @@ -908,7 +672,7 @@ public class DefaultModelValidator implements ModelValidator { } String sysPath = dependency.getSystemPath(); - if (sysPath != null && !sysPath.isEmpty()) { + if (StringUtils.isNotEmpty(sysPath)) { if (!hasExpression(sysPath)) { addViolation( problems, @@ -970,7 +734,7 @@ public class DefaultModelValidator implements ModelValidator { private void validate20RawDependenciesSelfReferencing( ModelProblemCollector problems, - org.apache.maven.api.model.Model m, + Model m, List dependencies, String prefix, ModelBuildingRequest request) { @@ -1001,7 +765,7 @@ public class DefaultModelValidator implements ModelValidator { private void validateEffectiveDependencies( ModelProblemCollector problems, - org.apache.maven.api.model.Model m, + Model m, List dependencies, boolean management, ModelBuildingRequest request) { @@ -1062,11 +826,7 @@ public class DefaultModelValidator implements ModelValidator { } private void validateEffectiveModelAgainstDependency( - String prefix, - ModelProblemCollector problems, - org.apache.maven.api.model.Model m, - Dependency d, - ModelBuildingRequest request) { + String prefix, ModelProblemCollector problems, Model m, Dependency d, ModelBuildingRequest request) { String key = d.getGroupId() + ":" + d.getArtifactId() + ":" + d.getVersion() + (d.getClassifier() != null ? ":" + d.getClassifier() : EMPTY); String mKey = m.getGroupId() + ":" + m.getArtifactId() + ":" + m.getVersion(); @@ -1116,7 +876,7 @@ public class DefaultModelValidator implements ModelValidator { boolean management, String prefix, ModelBuildingRequest request) { - validateCoordinateId( + validateId( prefix, "artifactId", problems, @@ -1126,8 +886,7 @@ public class DefaultModelValidator implements ModelValidator { d.getManagementKey(), d); - validateCoordinateId( - prefix, "groupId", problems, Severity.ERROR, Version.BASE, d.getGroupId(), d.getManagementKey(), d); + validateId(prefix, "groupId", problems, Severity.ERROR, Version.BASE, d.getGroupId(), d.getManagementKey(), d); if (!management) { validateStringNotEmpty( @@ -1139,7 +898,7 @@ public class DefaultModelValidator implements ModelValidator { if ("system".equals(d.getScope())) { String systemPath = d.getSystemPath(); - if (systemPath == null || systemPath.isEmpty()) { + if (StringUtils.isEmpty(systemPath)) { addViolation( problems, Severity.ERROR, @@ -1177,21 +936,21 @@ public class DefaultModelValidator implements ModelValidator { d); } } - } else if (d.getSystemPath() != null && !d.getSystemPath().isEmpty()) { + } else if (StringUtils.isNotEmpty(d.getSystemPath())) { addViolation( problems, Severity.ERROR, Version.BASE, prefix + "systemPath", d.getManagementKey(), - "must be omitted. This field may only be specified for a dependency with system scope.", + "must be omitted." + " This field may only be specified for a dependency with system scope.", d); } if (request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0) { for (Exclusion exclusion : d.getExclusions()) { if (request.getValidationLevel() < ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_0) { - validateCoordinateId( + validateId( prefix, "exclusions.exclusion.groupId", problems, @@ -1201,7 +960,7 @@ public class DefaultModelValidator implements ModelValidator { d.getManagementKey(), exclusion); - validateCoordinateId( + validateId( prefix, "exclusions.exclusion.artifactId", problems, @@ -1211,7 +970,7 @@ public class DefaultModelValidator implements ModelValidator { d.getManagementKey(), exclusion); } else { - validateCoordinateIdWithWildcards( + validateIdWithWildcards( prefix, "exclusions.exclusion.groupId", problems, @@ -1221,7 +980,7 @@ public class DefaultModelValidator implements ModelValidator { d.getManagementKey(), exclusion); - validateCoordinateIdWithWildcards( + validateIdWithWildcards( prefix, "exclusions.exclusion.artifactId", problems, @@ -1255,7 +1014,7 @@ public class DefaultModelValidator implements ModelValidator { validateStringNotEmpty( prefix, prefix2, "id", problems, Severity.ERROR, Version.V20, repository.getId(), null, repository); - if (validateStringNotEmpty( + validateStringNotEmpty( prefix, prefix2, "[" + repository.getId() + "].url", @@ -1264,24 +1023,7 @@ public class DefaultModelValidator implements ModelValidator { Version.V20, repository.getUrl(), null, - repository)) { - // only allow ${basedir}, ${project.basedir} or ${project.baseUri} - Matcher m = EXPRESSION_NAME_PATTERN.matcher(repository.getUrl()); - while (m.find()) { - if (!("basedir".equals(m.group(1)) - || "project.basedir".equals(m.group(1)) - || "project.baseUri".equals(m.group(1)))) { - validateStringNoExpression( - prefix + prefix2 + "[" + repository.getId() + "].url", - problems, - Severity.ERROR, - Version.V40, - repository.getUrl(), - repository); - break; - } - } - } + repository); String key = repository.getId(); @@ -1377,13 +1119,13 @@ public class DefaultModelValidator implements ModelValidator { // Field validation // ---------------------------------------------------------------------- - private boolean validateCoordinateId( + private boolean validateId( String fieldName, ModelProblemCollector problems, String id, InputLocationTracker tracker) { - return validateCoordinateId(EMPTY, fieldName, problems, Severity.ERROR, Version.BASE, id, null, tracker); + return validateId(EMPTY, fieldName, problems, Severity.ERROR, Version.BASE, id, null, tracker); } @SuppressWarnings("checkstyle:parameternumber") - private boolean validateCoordinateId( + private boolean validateId( String prefix, String fieldName, ModelProblemCollector problems, @@ -1392,86 +1134,44 @@ public class DefaultModelValidator implements ModelValidator { String id, String sourceHint, InputLocationTracker tracker) { - if (validCoordinateIds.contains(id)) { + if (validIds.contains(id)) { return true; } if (!validateStringNotEmpty(prefix, fieldName, problems, severity, version, id, sourceHint, tracker)) { return false; } else { - if (!isValidCoordinateId(id)) { + if (!isValidId(id)) { addViolation( problems, severity, version, prefix + fieldName, sourceHint, - "with value '" + id + "' does not match a valid coordinate id pattern.", + "with value '" + id + "' does not match a valid id pattern.", tracker); return false; } - validCoordinateIds.add(id); + validIds.add(id); return true; } } - private boolean isValidCoordinateId(String id) { + private boolean isValidId(String id) { for (int i = 0; i < id.length(); i++) { char c = id.charAt(i); - if (!isValidCoordinateIdCharacter(c)) { + if (!isValidIdCharacter(c)) { return false; } } return true; } - private boolean isValidCoordinateIdCharacter(char c) { + private boolean isValidIdCharacter(char c) { return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '-' || c == '_' || c == '.'; } @SuppressWarnings("checkstyle:parameternumber") - private boolean validateProfileId( - String prefix, - String fieldName, - ModelProblemCollector problems, - Severity severity, - Version version, - String id, - String sourceHint, - InputLocationTracker tracker) { - if (validProfileIds.contains(id)) { - return true; - } - if (!validateStringNotEmpty(prefix, fieldName, problems, severity, version, id, sourceHint, tracker)) { - return false; - } else { - if (!isValidProfileId(id)) { - addViolation( - problems, - severity, - version, - prefix + fieldName, - sourceHint, - "with value '" + id + "' does not match a valid profile id pattern.", - tracker); - return false; - } - validProfileIds.add(id); - return true; - } - } - - private boolean isValidProfileId(String id) { - return switch (id.charAt(0)) { // avoid first character that has special CLI meaning in "mvn -P xxx" - // +: activate - // -, !: deactivate - // ?: optional - case '+', '-', '!', '?' -> false; - default -> true; - }; - } - - @SuppressWarnings("checkstyle:parameternumber") - private boolean validateCoordinateIdWithWildcards( + private boolean validateIdWithWildcards( String prefix, String fieldName, ModelProblemCollector problems, @@ -1483,14 +1183,14 @@ public class DefaultModelValidator implements ModelValidator { if (!validateStringNotEmpty(prefix, fieldName, problems, severity, version, id, sourceHint, tracker)) { return false; } else { - if (!isValidCoordinateIdWithWildCards(id)) { + if (!isValidIdWithWildCards(id)) { addViolation( problems, severity, version, prefix + fieldName, sourceHint, - "with value '" + id + "' does not match a valid coordinate id pattern.", + "with value '" + id + "' does not match a valid id pattern.", tracker); return false; } @@ -1498,18 +1198,18 @@ public class DefaultModelValidator implements ModelValidator { } } - private boolean isValidCoordinateIdWithWildCards(String id) { + private boolean isValidIdWithWildCards(String id) { for (int i = 0; i < id.length(); i++) { char c = id.charAt(i); - if (!isValidCoordinateIdWithWildCardCharacter(c)) { + if (!isValidIdWithWildCardCharacter(c)) { return false; } } return true; } - private boolean isValidCoordinateIdWithWildCardCharacter(char c) { - return isValidCoordinateIdCharacter(c) || c == '?' || c == '*'; + private boolean isValidIdWithWildCardCharacter(char c) { + return isValidIdCharacter(c) || c == '?' || c == '*'; } private boolean validateStringNoExpression( @@ -1546,7 +1246,7 @@ public class DefaultModelValidator implements ModelValidator { return true; } - Matcher m = EXPRESSION_NAME_PATTERN.matcher(string.trim()); + Matcher m = CI_FRIENDLY_EXPRESSION.matcher(string.trim()); while (m.find()) { String property = m.group(1); if (!versionProcessor.isValidProperty(property)) { @@ -1558,7 +1258,6 @@ public class DefaultModelValidator implements ModelValidator { null, "contains an expression but should be a constant.", tracker); - return false; } } @@ -1638,7 +1337,7 @@ public class DefaultModelValidator implements ModelValidator { return false; } - if (!string.isEmpty()) { + if (string.length() > 0) { return true; } @@ -1710,7 +1409,7 @@ public class DefaultModelValidator implements ModelValidator { String string, String sourceHint, InputLocationTracker tracker) { - if (string == null || string.isEmpty()) { + if (string == null || string.length() <= 0) { return true; } @@ -1741,7 +1440,7 @@ public class DefaultModelValidator implements ModelValidator { String sourceHint, InputLocationTracker tracker, String... validValues) { - if (string == null || string.isEmpty()) { + if (string == null || string.length() <= 0) { return true; } @@ -1765,12 +1464,14 @@ public class DefaultModelValidator implements ModelValidator { @SuppressWarnings("checkstyle:parameternumber") private boolean validateModelVersion( - ModelProblemCollector problems, String string, InputLocationTracker tracker, List validVersions) { - if (string == null || string.isEmpty()) { + ModelProblemCollector problems, String string, InputLocationTracker tracker, String... validVersions) { + if (string == null || string.length() <= 0) { return true; } - if (validVersions.contains(string)) { + List values = Arrays.asList(validVersions); + + if (values.contains(string)) { return true; } @@ -1789,8 +1490,8 @@ public class DefaultModelValidator implements ModelValidator { Version.V20, "modelVersion", null, - "of '" + string + "' is newer than the versions supported by this version of Maven: " - + validVersions + ". Building this project requires a newer version of Maven.", + "of '" + string + "' is newer than the versions supported by this version of Maven: " + values + + ". Building this project requires a newer version of Maven.", tracker); } else if (olderThanAll) { @@ -1801,8 +1502,8 @@ public class DefaultModelValidator implements ModelValidator { Version.V20, "modelVersion", null, - "of '" + string + "' is older than the versions supported by this version of Maven: " - + validVersions + ". Building this project requires an older version of Maven.", + "of '" + string + "' is older than the versions supported by this version of Maven: " + values + + ". Building this project requires an older version of Maven.", tracker); } else { @@ -1812,7 +1513,7 @@ public class DefaultModelValidator implements ModelValidator { Version.V20, "modelVersion", null, - "must be one of " + validVersions + " but is '" + string + "'.", + "must be one of " + values + " but is '" + string + "'.", tracker); } @@ -1829,8 +1530,8 @@ public class DefaultModelValidator implements ModelValidator { */ private static int compareModelVersions(String first, String second) { // we use a dedicated comparator because we control our model version scheme. - String[] firstSegments = first.split("\\."); - String[] secondSegments = second.split("\\."); + String[] firstSegments = StringUtils.split(first, "."); + String[] secondSegments = StringUtils.split(second, "."); for (int i = 0; i < Math.max(firstSegments.length, secondSegments.length); i++) { int result = Long.valueOf(i < firstSegments.length ? firstSegments[i] : "0") .compareTo(Long.valueOf(i < secondSegments.length ? secondSegments[i] : "0")); @@ -1881,7 +1582,7 @@ public class DefaultModelValidator implements ModelValidator { String string, String sourceHint, InputLocationTracker tracker) { - if (string == null || string.isEmpty()) { + if (string == null || string.length() <= 0) { return true; } @@ -1909,7 +1610,7 @@ public class DefaultModelValidator implements ModelValidator { String string, String sourceHint, InputLocationTracker tracker) { - if (string == null || string.isEmpty()) { + if (string == null || string.length() <= 0) { return true; } @@ -1946,7 +1647,7 @@ public class DefaultModelValidator implements ModelValidator { return false; } - if (string.isEmpty() || "RELEASE".equals(string) || "LATEST".equals(string)) { + if (string.length() <= 0 || "RELEASE".equals(string) || "LATEST".equals(string)) { addViolation( problems, errOn30, @@ -1978,12 +1679,14 @@ public class DefaultModelValidator implements ModelValidator { buffer.append(' ').append(message); + // CHECKSTYLE_OFF: LineLength problems.add(new ModelProblemCollectorRequest(severity, version) .setMessage(buffer.toString()) .setLocation(getLocation(fieldName, tracker))); + // CHECKSTYLE_ON: LineLength } - private static org.apache.maven.model.InputLocation getLocation(String fieldName, InputLocationTracker tracker) { + private static InputLocation getLocation(String fieldName, InputLocationTracker tracker) { InputLocation location = null; if (tracker != null) { @@ -2013,13 +1716,11 @@ public class DefaultModelValidator implements ModelValidator { } } - return location != null ? new org.apache.maven.model.InputLocation(location) : null; + return location; } private static boolean equals(String s1, String s2) { - String c1 = s1 == null ? "" : s1.trim(); - String c2 = s2 == null ? "" : s2.trim(); - return c1.equals(c2); + return StringUtils.clean(s1).equals(StringUtils.clean(s2)); } private static Severity getSeverity(ModelBuildingRequest request, int errorThreshold) { diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/model/validation/ModelValidator.java b/compat/maven-model-builder/src/main/java/org/apache/maven/model/validation/ModelValidator.java index 0a0968845f..4e0382c177 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/model/validation/ModelValidator.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/model/validation/ModelValidator.java @@ -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 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. diff --git a/compat/maven-model-builder/src/main/java/org/apache/maven/utils/Os.java b/compat/maven-model-builder/src/main/java/org/apache/maven/utils/Os.java index f085eb32b4..19a442a617 100644 --- a/compat/maven-model-builder/src/main/java/org/apache/maven/utils/Os.java +++ b/compat/maven-model-builder/src/main/java/org/apache/maven/utils/Os.java @@ -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 diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/BuildModelSourceTransformerTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/BuildModelSourceTransformerTest.java deleted file mode 100644 index 7784cb4cce..0000000000 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/BuildModelSourceTransformerTest.java +++ /dev/null @@ -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); - } - } -} diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/ComplexActivationTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/ComplexActivationTest.java index de0963ed1b..da43f0ca33 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/ComplexActivationTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/ComplexActivationTest.java @@ -29,6 +29,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; /** */ +@Deprecated class ComplexActivationTest { private File getPom(String name) { diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderFactoryTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderFactoryTest.java index 08ef207d5d..ecb73cc029 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderFactoryTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderFactoryTest.java @@ -34,6 +34,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; /** */ +@Deprecated class DefaultModelBuilderFactoryTest { private static final String BASE_DIR = diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderTest.java index 332791b0ac..0ff1744c8a 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderTest.java @@ -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 = "\n" + " 4.0.0\n" + " thegroup\n" @@ -60,6 +56,7 @@ class DefaultModelBuilderTest { + "\n"; private static final String BASE2_ID = "thegroup:base2:pom"; + private static final String BASE2_ID2 = "thegroup:base2:1"; private static final String BASE2 = "\n" + " 4.0.0\n" + " thegroup\n" @@ -80,7 +77,7 @@ class DefaultModelBuilderTest { + "\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 modified) - throws UnresolvableModelException { + public ModelSource resolveModel(Parent parent) throws UnresolvableModelException { return null; } @Override - public ModelSource resolveModel(Dependency dependency, AtomicReference 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 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 currently 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 currently 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 currently 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 currently 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()); } } diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/FileModelSourceTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/FileModelSourceTest.java index 8f41bd9606..a03184de6b 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/FileModelSourceTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/FileModelSourceTest.java @@ -32,6 +32,7 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; * Test that validate the solution of MNG-6261 issue * */ +@Deprecated class FileModelSourceTest { /** diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/FileToRawModelMergerTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/FileToRawModelMergerTest.java index 920e8142c6..427aac072b 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/FileToRawModelMergerTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/FileToRawModelMergerTest.java @@ -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 { /** diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/GraphTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/GraphTest.java index f50ff6000f..c8050a9973 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/GraphTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/GraphTest.java @@ -29,6 +29,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertThrows; +@Deprecated public class GraphTest { @Test diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/ModelBuildingExceptionTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/ModelBuildingExceptionTest.java deleted file mode 100644 index 387056d7a7..0000000000 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/ModelBuildingExceptionTest.java +++ /dev/null @@ -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); - } -} diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/SimpleProblemCollector.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/SimpleProblemCollector.java index 9271005875..171a91f1c3 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/SimpleProblemCollector.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/building/SimpleProblemCollector.java @@ -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; diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java index 5f9dbde1c6..72d742a136 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java @@ -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"); diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/MergerTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/MergerTest.java deleted file mode 100644 index b3d3f8562a..0000000000 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/MergerTest.java +++ /dev/null @@ -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("\n" - + " \n" - + " my-value\n" - + " \n" - + ""), - 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")); - } - } -} diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/AbstractModelInterpolatorTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/AbstractModelInterpolatorTest.java index 78059ae707..12d6474961 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/AbstractModelInterpolatorTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/AbstractModelInterpolatorTest.java @@ -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 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 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 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 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 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; } diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/MavenBuildTimestampTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/MavenBuildTimestampTest.java index b72c1e13ad..cdc92814af 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/MavenBuildTimestampTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/MavenBuildTimestampTest.java @@ -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 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(); diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringVisitorModelInterpolatorTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringVisitorModelInterpolatorTest.java index 02ea9ba6bf..5df6c1673c 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringVisitorModelInterpolatorTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringVisitorModelInterpolatorTest.java @@ -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()); } } diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/reflection/ReflectionValueExtractorTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/reflection/ReflectionValueExtractorTest.java index 1c960c886d..861804ea84 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/reflection/ReflectionValueExtractorTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/reflection/ReflectionValueExtractorTest.java @@ -49,6 +49,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; /** * ReflectionValueExtractorTest class. */ +@Deprecated public class ReflectionValueExtractorTest { private Project project; diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/path/DefaultUrlNormalizerTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/path/DefaultUrlNormalizerTest.java index cffd9c3543..ed46f67fe9 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/path/DefaultUrlNormalizerTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/path/DefaultUrlNormalizerTest.java @@ -25,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; /** */ +@Deprecated class DefaultUrlNormalizerTest { private UrlNormalizer normalizer = new DefaultUrlNormalizer(); diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/DefaultProfileSelectorTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/DefaultProfileSelectorTest.java index 9b86ef8401..84f5d4390a 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/DefaultProfileSelectorTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/DefaultProfileSelectorTest.java @@ -34,6 +34,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; /** * Tests {@link DefaultProfileSelector}. */ +@Deprecated public class DefaultProfileSelectorTest { private Profile newProfile(String id) { Activation activation = new Activation(); diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/AbstractProfileActivatorTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/AbstractProfileActivatorTest.java index a706a1efc4..56f3543ba5 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/AbstractProfileActivatorTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/AbstractProfileActivatorTest.java @@ -33,6 +33,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; * Provides common services to test {@link ProfileActivator} implementations. * */ +@Deprecated public abstract class AbstractProfileActivatorTest { protected T activator; diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/FileProfileActivatorTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/FileProfileActivatorTest.java index 810dea6a65..35440a15cf 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/FileProfileActivatorTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/FileProfileActivatorTest.java @@ -28,6 +28,7 @@ import org.apache.maven.api.model.Profile; import org.apache.maven.model.path.DefaultPathTranslator; import org.apache.maven.model.path.ProfileActivationFilePathInterpolator; import org.apache.maven.model.profile.DefaultProfileActivationContext; +import org.apache.maven.model.root.DefaultRootLocator; import org.apache.maven.model.root.RootLocator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -40,6 +41,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; * Tests {@link FileProfileActivator}. * */ +@Deprecated class FileProfileActivatorTest extends AbstractProfileActivatorTest { @TempDir @@ -50,8 +52,15 @@ class FileProfileActivatorTest extends AbstractProfileActivatorTest true)); + activator = new FileProfileActivator() + .setProfileActivationFilePathInterpolator(new ProfileActivationFilePathInterpolator() + .setPathTranslator(new DefaultPathTranslator()) + .setRootLocator(new DefaultRootLocator() { + @Override + public Path findRoot(Path basedir) { + return basedir; + } + })); context.setProjectDirectory(tempDir.toFile()); diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivatorTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivatorTest.java index 111cc49a96..853d5d065f 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivatorTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivatorTest.java @@ -35,6 +35,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; * Tests {@link JdkVersionProfileActivator}. * */ +@Deprecated class JdkVersionProfileActivatorTest extends AbstractProfileActivatorTest { @Override diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivatorTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivatorTest.java index d2ab767d48..a7c49c3199 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivatorTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivatorTest.java @@ -30,6 +30,7 @@ import org.junit.jupiter.api.Test; * Tests {@link OperatingSystemProfileActivator}. * */ +@Deprecated class OperatingSystemProfileActivatorTest extends AbstractProfileActivatorTest { @Override diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/PropertyProfileActivatorTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/PropertyProfileActivatorTest.java index 12ac885783..82c9fcf3d0 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/PropertyProfileActivatorTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/PropertyProfileActivatorTest.java @@ -30,6 +30,7 @@ import org.junit.jupiter.api.Test; * Tests {@link PropertyProfileActivator}. * */ +@Deprecated class PropertyProfileActivatorTest extends AbstractProfileActivatorTest { @BeforeEach diff --git a/compat/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java b/compat/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java index 0fd9041929..181627cfe4 100644 --- a/compat/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java +++ b/compat/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java @@ -19,6 +19,7 @@ package org.apache.maven.model.validation; import java.io.InputStream; +import java.io.Serial; import java.util.List; import java.util.Properties; import java.util.function.UnaryOperator; @@ -39,6 +40,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; /** */ +@Deprecated class DefaultModelValidatorTest { private ModelValidator validator; @@ -59,6 +61,7 @@ class DefaultModelValidatorTest { return validateRaw(pom, UnaryOperator.identity()); } + @SuppressWarnings("SameParameterValue") private SimpleProblemCollector validateEffective(String pom, int level) throws Exception { return validateEffective(pom, mbr -> mbr.setValidationLevel(level)); } @@ -74,6 +77,7 @@ class DefaultModelValidatorTest { return problems; } + @SuppressWarnings("SameParameterValue") private SimpleProblemCollector validateRaw(String pom, int level) throws Exception { return validateRaw(pom, mbr -> mbr.setValidationLevel(level)); } @@ -86,8 +90,6 @@ class DefaultModelValidatorTest { ModelBuildingRequest request = requestConfigurer.apply(new DefaultModelBuildingRequest()); - validator.validateFileModel(model, request, problems); - validator.validateRawModel(model, request, problems); return problems; @@ -167,11 +169,11 @@ class DefaultModelValidatorTest { assertViolations(result, 0, 2, 0); assertEquals( - "'groupId' with value 'o/a/m' does not match a valid coordinate id pattern.", + "'groupId' with value 'o/a/m' does not match a valid id pattern.", result.getErrors().get(0)); assertEquals( - "'artifactId' with value 'm$-do$' does not match a valid coordinate id pattern.", + "'artifactId' with value 'm$-do$' does not match a valid id pattern.", result.getErrors().get(1)); } @@ -381,7 +383,7 @@ class DefaultModelValidatorTest { @Test void testDuplicateModule() throws Exception { - SimpleProblemCollector result = validateRaw("duplicate-module.xml"); + SimpleProblemCollector result = validate("duplicate-module.xml"); assertViolations(result, 0, 1, 0); @@ -389,18 +391,7 @@ class DefaultModelValidatorTest { } @Test - void testInvalidProfileId() throws Exception { - SimpleProblemCollector result = validateRaw("invalid-profile-ids.xml"); - - assertViolations(result, 0, 4, 0); - - assertTrue(result.getErrors().get(0).contains("+invalid-id")); - assertTrue(result.getErrors().get(1).contains("-invalid-id")); - assertTrue(result.getErrors().get(2).contains("!invalid-id")); - assertTrue(result.getErrors().get(3).contains("?invalid-id")); - } - - public void testDuplicateProfileId() throws Exception { + void testDuplicateProfileId() throws Exception { SimpleProblemCollector result = validateRaw("duplicate-profile-id.xml"); assertViolations(result, 0, 1, 0); @@ -448,16 +439,27 @@ class DefaultModelValidatorTest { void testHardCodedSystemPath() throws Exception { SimpleProblemCollector result = validateRaw("hard-coded-system-path.xml"); - assertViolations(result, 0, 0, 3); + assertViolations(result, 0, 0, 1); + + assertViolations(result, 0, 0, 1); assertContains( result.getWarnings().get(0), + "'dependencies.dependency.systemPath' for test:a:jar should use a variable instead of a hard-coded path"); + + SimpleProblemCollector result_31 = + validateRaw("hard-coded-system-path.xml", ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_1); + + assertViolations(result_31, 0, 0, 3); + + assertContains( + result_31.getWarnings().get(0), "'dependencies.dependency.scope' for test:a:jar declares usage of deprecated 'system' scope"); assertContains( - result.getWarnings().get(1), + result_31.getWarnings().get(1), "'dependencies.dependency.systemPath' for test:a:jar should use a variable instead of a hard-coded path"); assertContains( - result.getWarnings().get(2), + result_31.getWarnings().get(2), "'dependencies.dependency.scope' for test:b:jar declares usage of deprecated 'system' scope"); } @@ -474,12 +476,12 @@ class DefaultModelValidatorTest { void testDuplicatePlugin() throws Exception { SimpleProblemCollector result = validateRaw("duplicate-plugin.xml"); - assertViolations(result, 0, 4, 0); + assertViolations(result, 0, 0, 4); - assertTrue(result.getErrors().get(0).contains("duplicate declaration of plugin test:duplicate")); - assertTrue(result.getErrors().get(1).contains("duplicate declaration of plugin test:managed-duplicate")); - assertTrue(result.getErrors().get(2).contains("duplicate declaration of plugin profile:duplicate")); - assertTrue(result.getErrors().get(3).contains("duplicate declaration of plugin profile:managed-duplicate")); + assertTrue(result.getWarnings().get(0).contains("duplicate declaration of plugin test:duplicate")); + assertTrue(result.getWarnings().get(1).contains("duplicate declaration of plugin test:managed-duplicate")); + assertTrue(result.getWarnings().get(2).contains("duplicate declaration of plugin profile:duplicate")); + assertTrue(result.getWarnings().get(3).contains("duplicate declaration of plugin profile:managed-duplicate")); } @Test @@ -498,12 +500,13 @@ class DefaultModelValidatorTest { void testReservedRepositoryId() throws Exception { SimpleProblemCollector result = validate("reserved-repository-id.xml"); - assertViolations(result, 0, 4, 0); + assertViolations(result, 0, 0, 4); - assertContains(result.getErrors().get(0), "'repositories.repository.id'" + " must not be 'local'"); - assertContains(result.getErrors().get(1), "'pluginRepositories.pluginRepository.id' must not be 'local'"); - assertContains(result.getErrors().get(2), "'distributionManagement.repository.id' must not be 'local'"); - assertContains(result.getErrors().get(3), "'distributionManagement.snapshotRepository.id' must not be 'local'"); + assertContains(result.getWarnings().get(0), "'repositories.repository.id'" + " must not be 'local'"); + assertContains(result.getWarnings().get(1), "'pluginRepositories.pluginRepository.id' must not be 'local'"); + assertContains(result.getWarnings().get(2), "'distributionManagement.repository.id' must not be 'local'"); + assertContains( + result.getWarnings().get(3), "'distributionManagement.snapshotRepository.id' must not be 'local'"); } @Test @@ -546,36 +549,36 @@ class DefaultModelValidatorTest { void testBadVersion() throws Exception { SimpleProblemCollector result = validate("bad-version.xml"); - assertViolations(result, 0, 1, 0); + assertViolations(result, 0, 0, 1); - assertContains(result.getErrors().get(0), "'version' must not contain any of these characters"); + assertContains(result.getWarnings().get(0), "'version' must not contain any of these characters"); } @Test void testBadSnapshotVersion() throws Exception { SimpleProblemCollector result = validate("bad-snapshot-version.xml"); - assertViolations(result, 0, 1, 0); + assertViolations(result, 0, 0, 1); - assertContains(result.getErrors().get(0), "'version' uses an unsupported snapshot version format"); + assertContains(result.getWarnings().get(0), "'version' uses an unsupported snapshot version format"); } @Test void testBadRepositoryId() throws Exception { SimpleProblemCollector result = validate("bad-repository-id.xml"); - assertViolations(result, 0, 4, 0); + assertViolations(result, 0, 0, 4); assertContains( - result.getErrors().get(0), "'repositories.repository.id' must not contain any of these characters"); + result.getWarnings().get(0), "'repositories.repository.id' must not contain any of these characters"); assertContains( - result.getErrors().get(1), + result.getWarnings().get(1), "'pluginRepositories.pluginRepository.id' must not contain any of these characters"); assertContains( - result.getErrors().get(2), + result.getWarnings().get(2), "'distributionManagement.repository.id' must not contain any of these characters"); assertContains( - result.getErrors().get(3), + result.getWarnings().get(3), "'distributionManagement.snapshotRepository.id' must not contain any of these characters"); } @@ -639,19 +642,31 @@ class DefaultModelValidatorTest { void testSystemPathRefersToProjectBasedir() throws Exception { SimpleProblemCollector result = validateRaw("basedir-system-path.xml"); - assertViolations(result, 0, 0, 4); + assertViolations(result, 0, 0, 2); assertContains( result.getWarnings().get(0), - "'dependencies.dependency.scope' for test:a:jar declares usage of deprecated 'system' scope"); - assertContains( - result.getWarnings().get(1), "'dependencies.dependency.systemPath' for test:a:jar should not point at files within the project directory"); assertContains( - result.getWarnings().get(2), + result.getWarnings().get(1), + "'dependencies.dependency.systemPath' for test:b:jar should not point at files within the project directory"); + + SimpleProblemCollector result_31 = + validateRaw("basedir-system-path.xml", ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_1); + + assertViolations(result_31, 0, 0, 4); + + assertContains( + result_31.getWarnings().get(0), + "'dependencies.dependency.scope' for test:a:jar declares usage of deprecated 'system' scope"); + assertContains( + result_31.getWarnings().get(1), + "'dependencies.dependency.systemPath' for test:a:jar should not point at files within the project directory"); + assertContains( + result_31.getWarnings().get(2), "'dependencies.dependency.scope' for test:b:jar declares usage of deprecated 'system' scope"); assertContains( - result.getWarnings().get(3), + result_31.getWarnings().get(3), "'dependencies.dependency.systemPath' for test:b:jar should not point at files within the project directory"); } @@ -814,10 +829,7 @@ class DefaultModelValidatorTest { @Test void repositoryWithExpression() throws Exception { SimpleProblemCollector result = validateRaw("raw-model/repository-with-expression.xml"); - assertViolations(result, 0, 1, 0); - assertEquals( - "'repositories.repository.[repo].url' contains an expression but should be a constant.", - result.getErrors().get(0)); + assertViolations(result, 0, 0, 0); } @Test @@ -831,6 +843,7 @@ class DefaultModelValidatorTest { SimpleProblemCollector result = validateRaw( "raw-model/profile-activation-file-with-allowed-expressions.xml", mbr -> mbr.setUserProperties(new Properties() { + @Serial private static final long serialVersionUID = 1L; { diff --git a/compat/maven-model-builder/src/test/resources/poms/depmgmt/distant-import.xml b/compat/maven-model-builder/src/test/resources/poms/depmgmt/distant-import.xml index 2a19c7fed1..8ebfdfeae5 100644 --- a/compat/maven-model-builder/src/test/resources/poms/depmgmt/distant-import.xml +++ b/compat/maven-model-builder/src/test/resources/poms/depmgmt/distant-import.xml @@ -1,8 +1,8 @@ - - 4.1.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 test other diff --git a/compat/maven-model-builder/src/test/resources/poms/depmgmt/import.xml b/compat/maven-model-builder/src/test/resources/poms/depmgmt/import.xml index d4f2490cd3..c9505846ca 100644 --- a/compat/maven-model-builder/src/test/resources/poms/depmgmt/import.xml +++ b/compat/maven-model-builder/src/test/resources/poms/depmgmt/import.xml @@ -1,8 +1,8 @@ - - 4.1.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 test import diff --git a/compat/maven-model-builder/src/test/resources/poms/depmgmt/junit-0.1.xml b/compat/maven-model-builder/src/test/resources/poms/depmgmt/junit-0.1.xml index 344fc69a97..7565ab68b3 100644 --- a/compat/maven-model-builder/src/test/resources/poms/depmgmt/junit-0.1.xml +++ b/compat/maven-model-builder/src/test/resources/poms/depmgmt/junit-0.1.xml @@ -1,8 +1,8 @@ - - 4.1.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 org.junit bom diff --git a/compat/maven-model-builder/src/test/resources/poms/depmgmt/junit-0.2.xml b/compat/maven-model-builder/src/test/resources/poms/depmgmt/junit-0.2.xml index 58db6d80f8..63abd19819 100644 --- a/compat/maven-model-builder/src/test/resources/poms/depmgmt/junit-0.2.xml +++ b/compat/maven-model-builder/src/test/resources/poms/depmgmt/junit-0.2.xml @@ -1,8 +1,8 @@ - - 4.1.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 org.junit bom diff --git a/compat/maven-model-builder/src/test/resources/poms/depmgmt/other-import.xml b/compat/maven-model-builder/src/test/resources/poms/depmgmt/other-import.xml index b110091a03..24c31047e5 100644 --- a/compat/maven-model-builder/src/test/resources/poms/depmgmt/other-import.xml +++ b/compat/maven-model-builder/src/test/resources/poms/depmgmt/other-import.xml @@ -1,8 +1,8 @@ - - 4.1.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 test other-import diff --git a/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-dep-first.xml b/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-dep-first.xml index eb57c4549c..69e593d685 100644 --- a/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-dep-first.xml +++ b/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-dep-first.xml @@ -1,8 +1,8 @@ - - 4.1.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 test test diff --git a/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-dep-last.xml b/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-dep-last.xml index bac146e50e..613901dea4 100644 --- a/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-dep-last.xml +++ b/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-dep-last.xml @@ -1,8 +1,8 @@ - - 4.1.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 test test diff --git a/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-distance-explicit.xml b/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-distance-explicit.xml index 737cfd7fab..06b5253b76 100644 --- a/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-distance-explicit.xml +++ b/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-distance-explicit.xml @@ -1,8 +1,8 @@ - - 4.1.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 test test diff --git a/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-distance.xml b/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-distance.xml index d56bbee188..aa1e6eb772 100644 --- a/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-distance.xml +++ b/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-distance.xml @@ -1,8 +1,8 @@ - - 4.1.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 test test diff --git a/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-two-imports.xml b/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-two-imports.xml index 198a885610..6bb37b4b86 100644 --- a/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-two-imports.xml +++ b/compat/maven-model-builder/src/test/resources/poms/depmgmt/root-two-imports.xml @@ -1,8 +1,8 @@ - - 4.1.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 test test diff --git a/compat/maven-model/pom.xml b/compat/maven-model/pom.xml index 2935494b67..178d8bba2c 100644 --- a/compat/maven-model/pom.xml +++ b/compat/maven-model/pom.xml @@ -33,6 +33,11 @@ under the License. Maven Model Model for Maven POM (Project Object Model) + + + FileLength + + org.apache.maven @@ -133,10 +138,14 @@ under the License. org.apache.maven.model.Scm#setChildScmUrlInheritAppendPath(boolean):METHOD_REMOVED org.apache.maven.model.Site#setChildSiteUrlInheritAppendPath(boolean):METHOD_REMOVED org.apache.maven.model.io.xpp3.MavenXpp3Reader#contentTransformer + org.apache.maven.model.io.xpp3.MavenXpp3Reader#read(org.codehaus.plexus.util.xml.pull.XmlPullParser,boolean):METHOD_REMOVED org.apache.maven.model.io.xpp3.MavenXpp3ReaderEx#contentTransformer - org.apache.maven.model.io.xpp3.MavenXpp3WriterEx#stringFormatter + org.apache.maven.model.io.xpp3.MavenXpp3ReaderEx#read(org.codehaus.plexus.util.xml.pull.XmlPullParser,boolean):METHOD_REMOVED + org.apache.maven.model.io.xpp3.MavenXpp3ReaderEx#read(org.codehaus.plexus.util.xml.pull.XmlPullParser,boolean,org.apache.maven.model.InputSource):METHOD_REMOVED + org.apache.maven.model.io.xpp3.MavenXpp3ReaderEx:METHOD_REMOVED_IN_SUPERCLASS org.apache.maven.model.io.xpp3.MavenXpp3WriterEx#toString(org.apache.maven.model.InputLocation):METHOD_REMOVED org.apache.maven.model.io.xpp3.MavenXpp3WriterEx#writeXpp3DomToSerializer(org.codehaus.plexus.util.xml.Xpp3Dom,org.codehaus.plexus.util.xml.pull.XmlSerializer):METHOD_REMOVED + org.apache.maven.model.io.xpp3.MavenXpp3WriterEx#stringFormatter org.apache.maven.model.merge.ModelMerger diff --git a/compat/maven-model/src/main/java/org/apache/maven/model/merge/ModelMerger.java b/compat/maven-model/src/main/java/org/apache/maven/model/merge/ModelMerger.java new file mode 100644 index 0000000000..ac5694f8dc --- /dev/null +++ b/compat/maven-model/src/main/java/org/apache/maven/model/merge/ModelMerger.java @@ -0,0 +1,2498 @@ +/* + * 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.merge; + +import java.io.ObjectStreamException; +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Properties; + +import org.apache.maven.model.Activation; +import org.apache.maven.model.Build; +import org.apache.maven.model.BuildBase; +import org.apache.maven.model.CiManagement; +import org.apache.maven.model.ConfigurationContainer; +import org.apache.maven.model.Contributor; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.DependencyManagement; +import org.apache.maven.model.DeploymentRepository; +import org.apache.maven.model.Developer; +import org.apache.maven.model.DistributionManagement; +import org.apache.maven.model.Exclusion; +import org.apache.maven.model.Extension; +import org.apache.maven.model.FileSet; +import org.apache.maven.model.InputLocation; +import org.apache.maven.model.IssueManagement; +import org.apache.maven.model.License; +import org.apache.maven.model.MailingList; +import org.apache.maven.model.Model; +import org.apache.maven.model.ModelBase; +import org.apache.maven.model.Notifier; +import org.apache.maven.model.Organization; +import org.apache.maven.model.Parent; +import org.apache.maven.model.PatternSet; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginConfiguration; +import org.apache.maven.model.PluginContainer; +import org.apache.maven.model.PluginExecution; +import org.apache.maven.model.PluginManagement; +import org.apache.maven.model.Prerequisites; +import org.apache.maven.model.Profile; +import org.apache.maven.model.Relocation; +import org.apache.maven.model.ReportPlugin; +import org.apache.maven.model.ReportSet; +import org.apache.maven.model.Reporting; +import org.apache.maven.model.Repository; +import org.apache.maven.model.RepositoryBase; +import org.apache.maven.model.RepositoryPolicy; +import org.apache.maven.model.Resource; +import org.apache.maven.model.Scm; +import org.apache.maven.model.Site; +import org.codehaus.plexus.util.xml.Xpp3Dom; + +/** + * This is a hand-crafted prototype of the default model merger that should eventually be generated by Modello by a new + * Java plugin. Code structure to merge source (read-only) object into the target object is:

    + *
  • mergeClassname( Classname target, Classname source, boolean sourceDominant, + * Map<Object, Object> context ) for each model class
  • + *
  • mergeClassname_FieldName( Classname target, Classname source, boolean + * sourceDominant, Map<Object, Object> context ) for each field of each model class
  • + *
  • Object getClassnameKey( Classname classname ) + * for each class that is used in a list
  • + *
+ * Code is written like it could be generated, with default behaviour to be overridden when necessary. + * This is particularly the case for Object getClassnameKey( Classname classname ) + * method, which by default return the object itself and is expected to be overridden to calculate better suited key + * value. + * + * @author Benjamin Bentmann + */ +@SuppressWarnings({"checkstyle:methodname"}) +public class 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 + * null. + * @param source The (read-only) source object that should be merged into the target object, may be + * null. + * @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 null. + */ + public void merge(Model target, Model source, boolean sourceDominant, Map hints) { + Objects.requireNonNull(target, "target cannot be null"); + + if (source == null) { + return; + } + + Map context = new HashMap<>(); + if (hints != null) { + context.putAll(hints); + } + + mergeModel(target, source, sourceDominant, context); + } + + protected void mergeModel(Model target, Model source, boolean sourceDominant, Map context) { + mergeModelBase(target, source, sourceDominant, context); + + mergeModel_ChildProjectUrlInheritAppendPath(target, source, sourceDominant, context); + mergeModel_ModelVersion(target, source, sourceDominant, context); + mergeModel_Parent(target, source, sourceDominant, context); + mergeModel_GroupId(target, source, sourceDominant, context); + mergeModel_ArtifactId(target, source, sourceDominant, context); + mergeModel_Version(target, source, sourceDominant, context); + mergeModel_Packaging(target, source, sourceDominant, context); + mergeModel_Name(target, source, sourceDominant, context); + mergeModel_Description(target, source, sourceDominant, context); + mergeModel_Url(target, source, sourceDominant, context); + mergeModel_InceptionYear(target, source, sourceDominant, context); + mergeModel_Organization(target, source, sourceDominant, context); + mergeModel_Licenses(target, source, sourceDominant, context); + mergeModel_MailingLists(target, source, sourceDominant, context); + mergeModel_Developers(target, source, sourceDominant, context); + mergeModel_Contributors(target, source, sourceDominant, context); + mergeModel_IssueManagement(target, source, sourceDominant, context); + mergeModel_Scm(target, source, sourceDominant, context); + mergeModel_CiManagement(target, source, sourceDominant, context); + mergeModel_Prerequisites(target, source, sourceDominant, context); + mergeModel_Build(target, source, sourceDominant, context); + mergeModel_Profiles(target, source, sourceDominant, context); + } + + protected void mergeModel_ModelVersion( + Model target, Model source, boolean sourceDominant, Map context) { + String src = source.getModelVersion(); + if (src != null) { + if (sourceDominant || target.getModelVersion() == null) { + target.setModelVersion(src); + target.setLocation("modelVersion", source.getLocation("modelVersion")); + } + } + } + + protected void mergeModel_Parent(Model target, Model source, boolean sourceDominant, Map context) { + Parent src = source.getParent(); + if (src != null) { + Parent tgt = target.getParent(); + if (tgt == null) { + tgt = new Parent(); + tgt.setRelativePath(null); + target.setParent(tgt); + } + mergeParent(tgt, src, sourceDominant, context); + } + } + + protected void mergeModel_GroupId(Model target, Model source, boolean sourceDominant, Map context) { + String src = source.getGroupId(); + if (src != null) { + if (sourceDominant || target.getGroupId() == null) { + target.setGroupId(src); + target.setLocation("groupId", source.getLocation("groupId")); + } + } + } + + protected void mergeModel_ArtifactId( + Model target, Model source, boolean sourceDominant, Map context) { + String src = source.getArtifactId(); + if (src != null) { + if (sourceDominant || target.getArtifactId() == null) { + target.setArtifactId(src); + target.setLocation("artifactId", source.getLocation("artifactId")); + } + } + } + + protected void mergeModel_ChildProjectUrlInheritAppendPath( + Model target, Model source, boolean sourceDominant, Map context) { + String src = source.getChildProjectUrlInheritAppendPath(); + if (src != null) { + if (sourceDominant || target.getChildProjectUrlInheritAppendPath() == null) { + target.setChildProjectUrlInheritAppendPath(src); + target.setLocation( + "child.project.url.inherit.append.path", + source.getLocation("child.project.url.inherit.append.path")); + } + } + } + + protected void mergeModel_Version(Model target, Model source, boolean sourceDominant, Map context) { + String src = source.getVersion(); + if (src != null) { + if (sourceDominant || target.getVersion() == null) { + target.setVersion(src); + target.setLocation("version", source.getLocation("version")); + } + } + } + + protected void mergeModel_Packaging( + Model target, Model source, boolean sourceDominant, Map context) { + String src = source.getPackaging(); + if (src != null) { + if (sourceDominant || target.getPackaging() == null) { + target.setPackaging(src); + target.setLocation("packaging", source.getLocation("packaging")); + } + } + } + + protected void mergeModel_Name(Model target, Model source, boolean sourceDominant, Map context) { + String src = source.getName(); + if (src != null) { + if (sourceDominant || target.getName() == null) { + target.setName(src); + target.setLocation("name", source.getLocation("name")); + } + } + } + + protected void mergeModel_Description( + Model target, Model source, boolean sourceDominant, Map context) { + String src = source.getDescription(); + if (src != null) { + if (sourceDominant || target.getDescription() == null) { + target.setDescription(src); + target.setLocation("description", source.getLocation("description")); + } + } + } + + protected void mergeModel_Url(Model target, Model source, boolean sourceDominant, Map context) { + String src = source.getUrl(); + if (src != null) { + if (sourceDominant || target.getUrl() == null) { + target.setUrl(src); + target.setLocation("url", source.getLocation("url")); + } + } + } + + protected void mergeModel_InceptionYear( + Model target, Model source, boolean sourceDominant, Map context) { + String src = source.getInceptionYear(); + if (src != null) { + if (sourceDominant || target.getInceptionYear() == null) { + target.setInceptionYear(src); + target.setLocation("inceptionYear", source.getLocation("inceptionYear")); + } + } + } + + protected void mergeModel_Organization( + Model target, Model source, boolean sourceDominant, Map context) { + Organization src = source.getOrganization(); + if (src != null) { + Organization tgt = target.getOrganization(); + if (tgt == null) { + tgt = new Organization(); + target.setOrganization(tgt); + } + mergeOrganization(tgt, src, sourceDominant, context); + } + } + + protected void mergeModel_Licenses( + Model target, Model source, boolean sourceDominant, Map context) { + target.setLicenses(merge(target.getLicenses(), source.getLicenses(), sourceDominant, new LicenseKeyComputer())); + } + + protected void mergeModel_MailingLists( + Model target, Model source, boolean sourceDominant, Map context) { + target.setMailingLists(merge( + target.getMailingLists(), source.getMailingLists(), sourceDominant, new MailingListKeyComputer())); + } + + protected void mergeModel_Developers( + Model target, Model source, boolean sourceDominant, Map context) { + target.setDevelopers( + merge(target.getDevelopers(), source.getDevelopers(), sourceDominant, new DeveloperKeyComputer())); + } + + protected void mergeModel_Contributors( + Model target, Model source, boolean sourceDominant, Map context) { + target.setContributors(merge( + target.getContributors(), source.getContributors(), sourceDominant, new ContributorKeyComputer())); + } + + protected void mergeModel_IssueManagement( + Model target, Model source, boolean sourceDominant, Map context) { + IssueManagement src = source.getIssueManagement(); + if (src != null) { + IssueManagement tgt = target.getIssueManagement(); + if (tgt == null) { + tgt = new IssueManagement(); + target.setIssueManagement(tgt); + } + mergeIssueManagement(tgt, src, sourceDominant, context); + } + } + + protected void mergeModel_Scm(Model target, Model source, boolean sourceDominant, Map context) { + Scm src = source.getScm(); + if (src != null) { + Scm tgt = target.getScm(); + if (tgt == null) { + tgt = new Scm(); + tgt.setTag(null); + target.setScm(tgt); + } + mergeScm(tgt, src, sourceDominant, context); + } + } + + protected void mergeModel_CiManagement( + Model target, Model source, boolean sourceDominant, Map context) { + CiManagement src = source.getCiManagement(); + if (src != null) { + CiManagement tgt = target.getCiManagement(); + if (tgt == null) { + tgt = new CiManagement(); + target.setCiManagement(tgt); + } + mergeCiManagement(tgt, src, sourceDominant, context); + } + } + + protected void mergeModel_Prerequisites( + Model target, Model source, boolean sourceDominant, Map context) { + Prerequisites src = source.getPrerequisites(); + if (src != null) { + Prerequisites tgt = target.getPrerequisites(); + if (tgt == null) { + tgt = new Prerequisites(); + tgt.setMaven(null); + target.setPrerequisites(tgt); + } + mergePrerequisites(tgt, src, sourceDominant, context); + } + } + + protected void mergeModel_Build(Model target, Model source, boolean sourceDominant, Map context) { + Build src = source.getBuild(); + if (src != null) { + Build tgt = target.getBuild(); + if (tgt == null) { + tgt = new Build(); + target.setBuild(tgt); + } + mergeBuild(tgt, src, sourceDominant, context); + } + } + + protected void mergeModel_Profiles( + Model target, Model source, boolean sourceDominant, Map context) { + target.setProfiles(merge(target.getProfiles(), source.getProfiles(), sourceDominant, new ProfileKeyComputer())); + } + + protected void mergeModelBase( + ModelBase target, ModelBase source, boolean sourceDominant, Map context) { + mergeModelBase_DistributionManagement(target, source, sourceDominant, context); + mergeModelBase_Modules(target, source, sourceDominant, context); + mergeModelBase_Repositories(target, source, sourceDominant, context); + mergeModelBase_PluginRepositories(target, source, sourceDominant, context); + mergeModelBase_Dependencies(target, source, sourceDominant, context); + mergeModelBase_Reporting(target, source, sourceDominant, context); + mergeModelBase_DependencyManagement(target, source, sourceDominant, context); + mergeModelBase_Properties(target, source, sourceDominant, context); + } + + protected void mergeModelBase_Modules( + ModelBase target, ModelBase source, boolean sourceDominant, Map context) { + List src = source.getModules(); + if (!src.isEmpty()) { + List tgt = target.getModules(); + List merged = new ArrayList<>(tgt.size() + src.size()); + merged.addAll(tgt); + merged.addAll(src); + target.setModules(merged); + } + } + + protected void mergeModelBase_Dependencies( + ModelBase target, ModelBase source, boolean sourceDominant, Map context) { + target.setDependencies( + merge(target.getDependencies(), source.getDependencies(), sourceDominant, new DependencyKeyComputer())); + } + + protected void mergeModelBase_Repositories( + ModelBase target, ModelBase source, boolean sourceDominant, Map context) { + target.setRepositories( + merge(target.getRepositories(), source.getRepositories(), sourceDominant, new RepositoryKeyComputer())); + } + + protected void mergeModelBase_PluginRepositories( + ModelBase target, ModelBase source, boolean sourceDominant, Map context) { + target.setPluginRepositories(merge( + target.getPluginRepositories(), + source.getPluginRepositories(), + sourceDominant, + new RepositoryKeyComputer())); + } + + protected void mergeModelBase_DistributionManagement( + ModelBase target, ModelBase source, boolean sourceDominant, Map context) { + DistributionManagement src = source.getDistributionManagement(); + if (src != null) { + DistributionManagement tgt = target.getDistributionManagement(); + if (tgt == null) { + tgt = new DistributionManagement(); + target.setDistributionManagement(tgt); + } + mergeDistributionManagement(tgt, src, sourceDominant, context); + } + } + + protected void mergeModelBase_Reporting( + ModelBase target, ModelBase source, boolean sourceDominant, Map context) { + Reporting src = source.getReporting(); + if (src != null) { + Reporting tgt = target.getReporting(); + if (tgt == null) { + tgt = new Reporting(); + target.setReporting(tgt); + } + mergeReporting(tgt, src, sourceDominant, context); + } + } + + protected void mergeModelBase_DependencyManagement( + ModelBase target, ModelBase source, boolean sourceDominant, Map context) { + DependencyManagement src = source.getDependencyManagement(); + if (src != null) { + DependencyManagement tgt = target.getDependencyManagement(); + if (tgt == null) { + tgt = new DependencyManagement(); + target.setDependencyManagement(tgt); + } + mergeDependencyManagement(tgt, src, sourceDominant, context); + } + } + + protected void mergeModelBase_Properties( + ModelBase target, ModelBase source, boolean sourceDominant, Map context) { + Properties merged = new Properties(); + if (sourceDominant) { + merged.putAll(target.getProperties()); + merged.putAll(source.getProperties()); + } else { + merged.putAll(source.getProperties()); + merged.putAll(target.getProperties()); + } + target.setProperties(merged); + target.setLocation( + "properties", + InputLocation.merge( + target.getLocation("properties"), source.getLocation("properties"), sourceDominant)); + } + + protected void mergeDistributionManagement( + DistributionManagement target, + DistributionManagement source, + boolean sourceDominant, + Map context) { + mergeDistributionManagement_Repository(target, source, sourceDominant, context); + mergeDistributionManagement_SnapshotRepository(target, source, sourceDominant, context); + mergeDistributionManagement_Site(target, source, sourceDominant, context); + mergeDistributionManagement_Status(target, source, sourceDominant, context); + mergeDistributionManagement_DownloadUrl(target, source, sourceDominant, context); + } + + protected void mergeDistributionManagement_Repository( + DistributionManagement target, + DistributionManagement source, + boolean sourceDominant, + Map context) { + DeploymentRepository src = source.getRepository(); + if (src != null) { + DeploymentRepository tgt = target.getRepository(); + if (tgt == null) { + tgt = new DeploymentRepository(); + target.setRepository(tgt); + } + mergeDeploymentRepository(tgt, src, sourceDominant, context); + } + } + + protected void mergeDistributionManagement_SnapshotRepository( + DistributionManagement target, + DistributionManagement source, + boolean sourceDominant, + Map context) { + DeploymentRepository src = source.getSnapshotRepository(); + if (src != null) { + DeploymentRepository tgt = target.getSnapshotRepository(); + if (tgt == null) { + tgt = new DeploymentRepository(); + target.setSnapshotRepository(tgt); + } + mergeDeploymentRepository(tgt, src, sourceDominant, context); + } + } + + protected void mergeDistributionManagement_Site( + DistributionManagement target, + DistributionManagement source, + boolean sourceDominant, + Map context) { + Site src = source.getSite(); + if (src != null) { + Site tgt = target.getSite(); + if (tgt == null) { + tgt = new Site(); + target.setSite(tgt); + } + mergeSite(tgt, src, sourceDominant, context); + } + } + + protected void mergeDistributionManagement_Status( + DistributionManagement target, + DistributionManagement source, + boolean sourceDominant, + Map context) { + String src = source.getStatus(); + if (src != null) { + if (sourceDominant || target.getStatus() == null) { + target.setStatus(src); + target.setLocation("status", source.getLocation("status")); + } + } + } + + protected void mergeDistributionManagement_DownloadUrl( + DistributionManagement target, + DistributionManagement source, + boolean sourceDominant, + Map context) { + String src = source.getDownloadUrl(); + if (src != null) { + if (sourceDominant || target.getDownloadUrl() == null) { + target.setDownloadUrl(src); + target.setLocation("downloadUrl", source.getLocation("downloadUrl")); + } + } + } + + protected void mergeRelocation( + Relocation target, Relocation source, boolean sourceDominant, Map context) { + mergeRelocation_GroupId(target, source, sourceDominant, context); + mergeRelocation_ArtifactId(target, source, sourceDominant, context); + mergeRelocation_Version(target, source, sourceDominant, context); + mergeRelocation_Message(target, source, sourceDominant, context); + } + + protected void mergeRelocation_GroupId( + Relocation target, Relocation source, boolean sourceDominant, Map context) { + String src = source.getGroupId(); + if (src != null) { + if (sourceDominant || target.getGroupId() == null) { + target.setGroupId(src); + target.setLocation("groupId", source.getLocation("groupId")); + } + } + } + + protected void mergeRelocation_ArtifactId( + Relocation target, Relocation source, boolean sourceDominant, Map context) { + String src = source.getArtifactId(); + if (src != null) { + if (sourceDominant || target.getArtifactId() == null) { + target.setArtifactId(src); + target.setLocation("artifactId", source.getLocation("artifactId")); + } + } + } + + protected void mergeRelocation_Version( + Relocation target, Relocation source, boolean sourceDominant, Map context) { + String src = source.getVersion(); + if (src != null) { + if (sourceDominant || target.getVersion() == null) { + target.setVersion(src); + target.setLocation("version", source.getLocation("version")); + } + } + } + + protected void mergeRelocation_Message( + Relocation target, Relocation source, boolean sourceDominant, Map context) { + String src = source.getMessage(); + if (src != null) { + if (sourceDominant || target.getMessage() == null) { + target.setMessage(src); + target.setLocation("message", source.getLocation("message")); + } + } + } + + protected void mergeDeploymentRepository( + DeploymentRepository target, + DeploymentRepository source, + boolean sourceDominant, + Map context) { + mergeRepository(target, source, sourceDominant, context); + mergeDeploymentRepository_UniqueVersion(target, source, sourceDominant, context); + } + + protected void mergeDeploymentRepository_UniqueVersion( + DeploymentRepository target, + DeploymentRepository source, + boolean sourceDominant, + Map context) { + if (sourceDominant) { + target.setUniqueVersion(source.isUniqueVersion()); + target.setLocation("uniqueVersion", source.getLocation("uniqueVersion")); + } + } + + protected void mergeSite(Site target, Site source, boolean sourceDominant, Map context) { + mergeSite_ChildSiteUrlInheritAppendPath(target, source, sourceDominant, context); + mergeSite_Id(target, source, sourceDominant, context); + mergeSite_Name(target, source, sourceDominant, context); + mergeSite_Url(target, source, sourceDominant, context); + } + + protected void mergeSite_ChildSiteUrlInheritAppendPath( + Site target, Site source, boolean sourceDominant, Map context) { + String src = source.getChildSiteUrlInheritAppendPath(); + if (src != null) { + if (sourceDominant || target.getChildSiteUrlInheritAppendPath() == null) { + target.setChildSiteUrlInheritAppendPath(src); + target.setLocation( + "child.site.url.inherit.append.path", source.getLocation("child.site.url.inherit.append.path")); + } + } + } + + protected void mergeSite_Id(Site target, Site source, boolean sourceDominant, Map context) { + String src = source.getId(); + if (src != null) { + if (sourceDominant || target.getId() == null) { + target.setId(src); + target.setLocation("id", source.getLocation("id")); + } + } + } + + protected void mergeSite_Name(Site target, Site source, boolean sourceDominant, Map context) { + String src = source.getName(); + if (src != null) { + if (sourceDominant || target.getName() == null) { + target.setName(src); + target.setLocation("name", source.getLocation("name")); + } + } + } + + protected void mergeSite_Url(Site target, Site source, boolean sourceDominant, Map context) { + String src = source.getUrl(); + if (src != null) { + if (sourceDominant || target.getUrl() == null) { + target.setUrl(src); + target.setLocation("url", source.getLocation("url")); + } + } + } + + protected void mergeRepository( + Repository target, Repository source, boolean sourceDominant, Map context) { + mergeRepositoryBase(target, source, sourceDominant, context); + mergeRepository_Releases(target, source, sourceDominant, context); + mergeRepository_Snapshots(target, source, sourceDominant, context); + } + + protected void mergeRepository_Releases( + Repository target, Repository source, boolean sourceDominant, Map context) { + RepositoryPolicy src = source.getReleases(); + if (src != null) { + RepositoryPolicy tgt = target.getReleases(); + if (tgt == null) { + tgt = new RepositoryPolicy(); + target.setReleases(tgt); + } + mergeRepositoryPolicy(tgt, src, sourceDominant, context); + } + } + + protected void mergeRepository_Snapshots( + Repository target, Repository source, boolean sourceDominant, Map context) { + RepositoryPolicy src = source.getSnapshots(); + if (src != null) { + RepositoryPolicy tgt = target.getSnapshots(); + if (tgt == null) { + tgt = new RepositoryPolicy(); + target.setSnapshots(tgt); + } + mergeRepositoryPolicy(tgt, src, sourceDominant, context); + } + } + + protected void mergeRepositoryBase( + RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map context) { + mergeRepositoryBase_Id(target, source, sourceDominant, context); + mergeRepositoryBase_Name(target, source, sourceDominant, context); + mergeRepositoryBase_Url(target, source, sourceDominant, context); + mergeRepositoryBase_Layout(target, source, sourceDominant, context); + } + + protected void mergeRepositoryBase_Id( + RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map context) { + String src = source.getId(); + if (src != null) { + if (sourceDominant || target.getId() == null) { + target.setId(src); + target.setLocation("id", source.getLocation("id")); + } + } + } + + protected void mergeRepositoryBase_Url( + RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map context) { + String src = source.getUrl(); + if (src != null) { + if (sourceDominant || target.getUrl() == null) { + target.setUrl(src); + target.setLocation("url", source.getLocation("url")); + } + } + } + + protected void mergeRepositoryBase_Name( + RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map context) { + String src = source.getName(); + if (src != null) { + if (sourceDominant || target.getName() == null) { + target.setName(src); + target.setLocation("name", source.getLocation("name")); + } + } + } + + protected void mergeRepositoryBase_Layout( + RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map context) { + String src = source.getLayout(); + if (src != null) { + if (sourceDominant || target.getLayout() == null) { + target.setLayout(src); + target.setLocation("layout", source.getLocation("layout")); + } + } + } + + protected void mergeRepositoryPolicy( + RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant, Map context) { + mergeRepositoryPolicy_Enabled(target, source, sourceDominant, context); + mergeRepositoryPolicy_UpdatePolicy(target, source, sourceDominant, context); + mergeRepositoryPolicy_ChecksumPolicy(target, source, sourceDominant, context); + } + + protected void mergeRepositoryPolicy_Enabled( + RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant, Map context) { + String src = source.getEnabled(); + if (src != null) { + if (sourceDominant || target.getEnabled() == null) { + target.setEnabled(src); + target.setLocation("enabled", source.getLocation("enabled")); + } + } + } + + protected void mergeRepositoryPolicy_UpdatePolicy( + RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant, Map context) { + String src = source.getUpdatePolicy(); + if (src != null) { + if (sourceDominant || target.getUpdatePolicy() == null) { + target.setUpdatePolicy(src); + target.setLocation("updatePolicy", source.getLocation("updatePolicy")); + } + } + } + + protected void mergeRepositoryPolicy_ChecksumPolicy( + RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant, Map context) { + String src = source.getChecksumPolicy(); + if (src != null) { + if (sourceDominant || target.getChecksumPolicy() == null) { + target.setChecksumPolicy(src); + target.setLocation("checksumPolicy", source.getLocation("checksumPolicy")); + } + } + } + + protected void mergeDependency( + Dependency target, Dependency source, boolean sourceDominant, Map context) { + mergeDependency_GroupId(target, source, sourceDominant, context); + mergeDependency_ArtifactId(target, source, sourceDominant, context); + mergeDependency_Version(target, source, sourceDominant, context); + mergeDependency_Type(target, source, sourceDominant, context); + mergeDependency_Classifier(target, source, sourceDominant, context); + mergeDependency_Scope(target, source, sourceDominant, context); + mergeDependency_SystemPath(target, source, sourceDominant, context); + mergeDependency_Optional(target, source, sourceDominant, context); + mergeDependency_Exclusions(target, source, sourceDominant, context); + } + + protected void mergeDependency_GroupId( + Dependency target, Dependency source, boolean sourceDominant, Map context) { + String src = source.getGroupId(); + if (src != null) { + if (sourceDominant || target.getGroupId() == null) { + target.setGroupId(src); + target.setLocation("groupId", source.getLocation("groupId")); + } + } + } + + protected void mergeDependency_ArtifactId( + Dependency target, Dependency source, boolean sourceDominant, Map context) { + String src = source.getArtifactId(); + if (src != null) { + if (sourceDominant || target.getArtifactId() == null) { + target.setArtifactId(src); + target.setLocation("artifactId", source.getLocation("artifactId")); + } + } + } + + protected void mergeDependency_Version( + Dependency target, Dependency source, boolean sourceDominant, Map context) { + String src = source.getVersion(); + if (src != null) { + if (sourceDominant || target.getVersion() == null) { + target.setVersion(src); + target.setLocation("version", source.getLocation("version")); + } + } + } + + protected void mergeDependency_Type( + Dependency target, Dependency source, boolean sourceDominant, Map context) { + String src = source.getType(); + if (src != null) { + if (sourceDominant || target.getType() == null) { + target.setType(src); + target.setLocation("type", source.getLocation("type")); + } + } + } + + protected void mergeDependency_Classifier( + Dependency target, Dependency source, boolean sourceDominant, Map context) { + String src = source.getClassifier(); + if (src != null) { + if (sourceDominant || target.getClassifier() == null) { + target.setClassifier(src); + target.setLocation("classifier", source.getLocation("classifier")); + } + } + } + + protected void mergeDependency_Scope( + Dependency target, Dependency source, boolean sourceDominant, Map context) { + String src = source.getScope(); + if (src != null) { + if (sourceDominant || target.getScope() == null) { + target.setScope(src); + target.setLocation("scope", source.getLocation("scope")); + } + } + } + + protected void mergeDependency_SystemPath( + Dependency target, Dependency source, boolean sourceDominant, Map context) { + String src = source.getSystemPath(); + if (src != null) { + if (sourceDominant || target.getSystemPath() == null) { + target.setSystemPath(src); + target.setLocation("systemPath", source.getLocation("systemPath")); + } + } + } + + protected void mergeDependency_Optional( + Dependency target, Dependency source, boolean sourceDominant, Map context) { + String src = source.getOptional(); + if (src != null) { + if (sourceDominant || target.getOptional() == null) { + target.setOptional(src); + target.setLocation("optional", source.getLocation("optional")); + } + } + } + + protected void mergeDependency_Exclusions( + Dependency target, Dependency source, boolean sourceDominant, Map context) { + target.setExclusions( + merge(target.getExclusions(), source.getExclusions(), sourceDominant, new ExclusionKeyComputer())); + } + + protected void mergeExclusion( + Exclusion target, Exclusion source, boolean sourceDominant, Map context) { + mergeExclusion_GroupId(target, source, sourceDominant, context); + mergeExclusion_ArtifactId(target, source, sourceDominant, context); + } + + protected void mergeExclusion_GroupId( + Exclusion target, Exclusion source, boolean sourceDominant, Map context) { + String src = source.getGroupId(); + if (src != null) { + if (sourceDominant || target.getGroupId() == null) { + target.setGroupId(src); + target.setLocation("groupId", source.getLocation("groupId")); + } + } + } + + protected void mergeExclusion_ArtifactId( + Exclusion target, Exclusion source, boolean sourceDominant, Map context) { + String src = source.getArtifactId(); + if (src != null) { + if (sourceDominant || target.getArtifactId() == null) { + target.setArtifactId(src); + target.setLocation("artifactId", source.getLocation("artifactId")); + } + } + } + + protected void mergeReporting( + Reporting target, Reporting source, boolean sourceDominant, Map context) { + mergeReporting_OutputDirectory(target, source, sourceDominant, context); + mergeReporting_ExcludeDefaults(target, source, sourceDominant, context); + mergeReporting_Plugins(target, source, sourceDominant, context); + } + + protected void mergeReporting_OutputDirectory( + Reporting target, Reporting source, boolean sourceDominant, Map context) { + String src = source.getOutputDirectory(); + if (src != null) { + if (sourceDominant || target.getOutputDirectory() == null) { + target.setOutputDirectory(src); + target.setLocation("outputDirectory", source.getLocation("outputDirectory")); + } + } + } + + protected void mergeReporting_ExcludeDefaults( + Reporting target, Reporting source, boolean sourceDominant, Map context) { + String src = source.getExcludeDefaults(); + if (src != null) { + if (sourceDominant || target.getExcludeDefaults() == null) { + target.setExcludeDefaults(src); + target.setLocation("excludeDefaults", source.getLocation("excludeDefaults")); + } + } + } + + protected void mergeReporting_Plugins( + Reporting target, Reporting source, boolean sourceDominant, Map context) { + target.setPlugins( + merge(target.getPlugins(), source.getPlugins(), sourceDominant, new ReportPluginKeyComputer())); + } + + protected void mergeReportPlugin( + ReportPlugin target, ReportPlugin source, boolean sourceDominant, Map context) { + mergeConfigurationContainer(target, source, sourceDominant, context); + mergeReportPlugin_GroupId(target, source, sourceDominant, context); + mergeReportPlugin_ArtifactId(target, source, sourceDominant, context); + mergeReportPlugin_Version(target, source, sourceDominant, context); + mergeReportPlugin_ReportSets(target, source, sourceDominant, context); + } + + protected void mergeReportPlugin_GroupId( + ReportPlugin target, ReportPlugin source, boolean sourceDominant, Map context) { + String src = source.getGroupId(); + if (src != null) { + if (sourceDominant || target.getGroupId() == null) { + target.setGroupId(src); + target.setLocation("groupId", source.getLocation("groupId")); + } + } + } + + protected void mergeReportPlugin_ArtifactId( + ReportPlugin target, ReportPlugin source, boolean sourceDominant, Map context) { + String src = source.getArtifactId(); + if (src != null) { + if (sourceDominant || target.getArtifactId() == null) { + target.setArtifactId(src); + target.setLocation("artifactId", source.getLocation("artifactId")); + } + } + } + + protected void mergeReportPlugin_Version( + ReportPlugin target, ReportPlugin source, boolean sourceDominant, Map context) { + String src = source.getVersion(); + if (src != null) { + if (sourceDominant || target.getVersion() == null) { + target.setVersion(src); + target.setLocation("version", source.getLocation("version")); + } + } + } + + protected void mergeReportPlugin_ReportSets( + ReportPlugin target, ReportPlugin source, boolean sourceDominant, Map context) { + target.setReportSets( + merge(target.getReportSets(), source.getReportSets(), sourceDominant, new ReportSetKeyComputer())); + } + + protected void mergeReportSet( + ReportSet target, ReportSet source, boolean sourceDominant, Map context) { + mergeConfigurationContainer(target, source, sourceDominant, context); + mergeReportSet_Id(target, source, sourceDominant, context); + mergeReportSet_Reports(target, source, sourceDominant, context); + } + + protected void mergeReportSet_Id( + ReportSet target, ReportSet source, boolean sourceDominant, Map context) { + String src = source.getId(); + if (src != null) { + if (sourceDominant || target.getId() == null) { + target.setId(src); + target.setLocation("id", source.getLocation("id")); + } + } + } + + protected void mergeReportSet_Reports( + ReportSet target, ReportSet source, boolean sourceDominant, Map context) { + List src = source.getReports(); + if (!src.isEmpty()) { + List tgt = target.getReports(); + List merged = new ArrayList<>(tgt.size() + src.size()); + merged.addAll(tgt); + merged.addAll(src); + target.setReports(merged); + + InputLocation sourceLocation = source.getLocation("reports"); + if (sourceLocation != null) { + InputLocation targetLocation = target.getLocation("reports"); + if (targetLocation == null) { + target.setLocation("reports", sourceLocation); + } else { + for (int i = 0; i < src.size(); i++) { + targetLocation.setLocation( + Integer.valueOf(tgt.size() + i), sourceLocation.getLocation(Integer.valueOf(i))); + } + } + } + } + } + + protected void mergeDependencyManagement( + DependencyManagement target, + DependencyManagement source, + boolean sourceDominant, + Map context) { + mergeDependencyManagement_Dependencies(target, source, sourceDominant, context); + } + + protected void mergeDependencyManagement_Dependencies( + DependencyManagement target, + DependencyManagement source, + boolean sourceDominant, + Map context) { + target.setDependencies( + merge(target.getDependencies(), source.getDependencies(), sourceDominant, new DependencyKeyComputer())); + } + + protected void mergeParent(Parent target, Parent source, boolean sourceDominant, Map context) { + mergeParent_GroupId(target, source, sourceDominant, context); + mergeParent_ArtifactId(target, source, sourceDominant, context); + mergeParent_Version(target, source, sourceDominant, context); + mergeParent_RelativePath(target, source, sourceDominant, context); + } + + protected void mergeParent_GroupId( + Parent target, Parent source, boolean sourceDominant, Map context) { + String src = source.getGroupId(); + if (src != null) { + if (sourceDominant || target.getGroupId() == null) { + target.setGroupId(src); + target.setLocation("groupId", source.getLocation("groupId")); + } + } + } + + protected void mergeParent_ArtifactId( + Parent target, Parent source, boolean sourceDominant, Map context) { + String src = source.getArtifactId(); + if (src != null) { + if (sourceDominant || target.getArtifactId() == null) { + target.setArtifactId(src); + target.setLocation("artifactId", source.getLocation("artifactId")); + } + } + } + + protected void mergeParent_Version( + Parent target, Parent source, boolean sourceDominant, Map context) { + String src = source.getVersion(); + if (src != null) { + if (sourceDominant || target.getVersion() == null) { + target.setVersion(src); + target.setLocation("version", source.getLocation("version")); + } + } + } + + protected void mergeParent_RelativePath( + Parent target, Parent source, boolean sourceDominant, Map context) { + String src = source.getRelativePath(); + if (src != null) { + if (sourceDominant || target.getRelativePath() == null) { + target.setRelativePath(src); + target.setLocation("relativePath", source.getLocation("relativePath")); + } + } + } + + protected void mergeOrganization( + Organization target, Organization source, boolean sourceDominant, Map context) { + mergeOrganization_Name(target, source, sourceDominant, context); + mergeOrganization_Url(target, source, sourceDominant, context); + } + + protected void mergeOrganization_Name( + Organization target, Organization source, boolean sourceDominant, Map context) { + String src = source.getName(); + if (src != null) { + if (sourceDominant || target.getName() == null) { + target.setName(src); + target.setLocation("name", source.getLocation("name")); + } + } + } + + protected void mergeOrganization_Url( + Organization target, Organization source, boolean sourceDominant, Map context) { + String src = source.getUrl(); + if (src != null) { + if (sourceDominant || target.getUrl() == null) { + target.setUrl(src); + target.setLocation("url", source.getLocation("url")); + } + } + } + + protected void mergeLicense(License target, License source, boolean sourceDominant, Map context) { + mergeLicense_Name(target, source, sourceDominant, context); + mergeLicense_Url(target, source, sourceDominant, context); + mergeLicense_Distribution(target, source, sourceDominant, context); + mergeLicense_Comments(target, source, sourceDominant, context); + } + + protected void mergeLicense_Name( + License target, License source, boolean sourceDominant, Map context) { + String src = source.getName(); + if (src != null) { + if (sourceDominant || target.getName() == null) { + target.setName(src); + target.setLocation("name", source.getLocation("name")); + } + } + } + + protected void mergeLicense_Url( + License target, License source, boolean sourceDominant, Map context) { + String src = source.getUrl(); + if (src != null) { + if (sourceDominant || target.getUrl() == null) { + target.setUrl(src); + target.setLocation("url", source.getLocation("url")); + } + } + } + + protected void mergeLicense_Distribution( + License target, License source, boolean sourceDominant, Map context) { + String src = source.getDistribution(); + if (src != null) { + if (sourceDominant || target.getDistribution() == null) { + target.setDistribution(src); + target.setLocation("distribution", source.getLocation("distribution")); + } + } + } + + protected void mergeLicense_Comments( + License target, License source, boolean sourceDominant, Map context) { + String src = source.getComments(); + if (src != null) { + if (sourceDominant || target.getComments() == null) { + target.setComments(src); + target.setLocation("comments", source.getLocation("comments")); + } + } + } + + protected void mergeMailingList( + MailingList target, MailingList source, boolean sourceDominant, Map context) { + mergeMailingList_Name(target, source, sourceDominant, context); + mergeMailingList_Subscribe(target, source, sourceDominant, context); + mergeMailingList_Unsubscribe(target, source, sourceDominant, context); + mergeMailingList_Post(target, source, sourceDominant, context); + mergeMailingList_OtherArchives(target, source, sourceDominant, context); + } + + protected void mergeMailingList_Name( + MailingList target, MailingList source, boolean sourceDominant, Map context) { + String src = source.getName(); + if (src != null) { + if (sourceDominant || target.getName() == null) { + target.setName(src); + target.setLocation("name", source.getLocation("name")); + } + } + } + + protected void mergeMailingList_Subscribe( + MailingList target, MailingList source, boolean sourceDominant, Map context) { + String src = source.getSubscribe(); + if (src != null) { + if (sourceDominant || target.getSubscribe() == null) { + target.setSubscribe(src); + target.setLocation("subscribe", source.getLocation("subscribe")); + } + } + } + + protected void mergeMailingList_Unsubscribe( + MailingList target, MailingList source, boolean sourceDominant, Map context) { + String src = source.getUnsubscribe(); + if (src != null) { + if (sourceDominant || target.getUnsubscribe() == null) { + target.setUnsubscribe(src); + target.setLocation("unsubscribe", source.getLocation("unsubscribe")); + } + } + } + + protected void mergeMailingList_Post( + MailingList target, MailingList source, boolean sourceDominant, Map context) { + String src = source.getPost(); + if (src != null) { + if (sourceDominant || target.getPost() == null) { + target.setPost(src); + target.setLocation("post", source.getLocation("post")); + } + } + } + + protected void mergeMailingList_Archive( + MailingList target, MailingList source, boolean sourceDominant, Map context) { + String src = source.getArchive(); + if (src != null) { + if (sourceDominant || target.getArchive() == null) { + target.setArchive(src); + target.setLocation("archive", source.getLocation("archive")); + } + } + } + + protected void mergeMailingList_OtherArchives( + MailingList target, MailingList source, boolean sourceDominant, Map context) { + List src = source.getOtherArchives(); + if (!src.isEmpty()) { + List tgt = target.getOtherArchives(); + List merged = new ArrayList<>(tgt.size() + src.size()); + merged.addAll(tgt); + merged.addAll(src); + target.setOtherArchives(merged); + } + } + + protected void mergeDeveloper( + Developer target, Developer source, boolean sourceDominant, Map context) { + mergeContributor(target, source, sourceDominant, context); + mergeDeveloper_Id(target, source, sourceDominant, context); + } + + protected void mergeDeveloper_Id( + Developer target, Developer source, boolean sourceDominant, Map context) { + String src = source.getId(); + if (src != null) { + if (sourceDominant || target.getId() == null) { + target.setId(src); + target.setLocation("id", source.getLocation("id")); + } + } + } + + protected void mergeContributor( + Contributor target, Contributor source, boolean sourceDominant, Map context) { + mergeContributor_Name(target, source, sourceDominant, context); + mergeContributor_Email(target, source, sourceDominant, context); + mergeContributor_Url(target, source, sourceDominant, context); + mergeContributor_Organization(target, source, sourceDominant, context); + mergeContributor_OrganizationUrl(target, source, sourceDominant, context); + mergeContributor_Timezone(target, source, sourceDominant, context); + mergeContributor_Roles(target, source, sourceDominant, context); + mergeContributor_Properties(target, source, sourceDominant, context); + } + + protected void mergeContributor_Name( + Contributor target, Contributor source, boolean sourceDominant, Map context) { + String src = source.getName(); + if (src != null) { + if (sourceDominant || target.getName() == null) { + target.setName(src); + target.setLocation("name", source.getLocation("name")); + } + } + } + + protected void mergeContributor_Email( + Contributor target, Contributor source, boolean sourceDominant, Map context) { + String src = source.getEmail(); + if (src != null) { + if (sourceDominant || target.getEmail() == null) { + target.setEmail(src); + target.setLocation("email", source.getLocation("email")); + } + } + } + + protected void mergeContributor_Url( + Contributor target, Contributor source, boolean sourceDominant, Map context) { + String src = source.getUrl(); + if (src != null) { + if (sourceDominant || target.getUrl() == null) { + target.setUrl(src); + target.setLocation("url", source.getLocation("url")); + } + } + } + + protected void mergeContributor_Organization( + Contributor target, Contributor source, boolean sourceDominant, Map context) { + String src = source.getOrganization(); + if (src != null) { + if (sourceDominant || target.getOrganization() == null) { + target.setOrganization(src); + target.setLocation("organization", source.getLocation("organization")); + } + } + } + + protected void mergeContributor_OrganizationUrl( + Contributor target, Contributor source, boolean sourceDominant, Map context) { + String src = source.getOrganizationUrl(); + if (src != null) { + if (sourceDominant || target.getOrganizationUrl() == null) { + target.setOrganizationUrl(src); + target.setLocation("organizationUrl", source.getLocation("organizationUrl")); + } + } + } + + protected void mergeContributor_Timezone( + Contributor target, Contributor source, boolean sourceDominant, Map context) { + String src = source.getTimezone(); + if (src != null) { + if (sourceDominant || target.getTimezone() == null) { + target.setTimezone(src); + target.setLocation("timezone", source.getLocation("timezone")); + } + } + } + + protected void mergeContributor_Roles( + Contributor target, Contributor source, boolean sourceDominant, Map context) { + List src = source.getRoles(); + if (!src.isEmpty()) { + List tgt = target.getRoles(); + List merged = new ArrayList<>(tgt.size() + src.size()); + merged.addAll(tgt); + merged.addAll(src); + target.setRoles(merged); + } + } + + protected void mergeContributor_Properties( + Contributor target, Contributor source, boolean sourceDominant, Map context) { + Properties merged = new Properties(); + if (sourceDominant) { + merged.putAll(target.getProperties()); + merged.putAll(source.getProperties()); + } else { + merged.putAll(source.getProperties()); + merged.putAll(target.getProperties()); + } + target.setProperties(merged); + target.setLocation( + "properties", + InputLocation.merge( + target.getLocation("properties"), source.getLocation("properties"), sourceDominant)); + } + + protected void mergeIssueManagement( + IssueManagement target, IssueManagement source, boolean sourceDominant, Map context) { + mergeIssueManagement_Url(target, source, sourceDominant, context); + mergeIssueManagement_System(target, source, sourceDominant, context); + } + + protected void mergeIssueManagement_System( + IssueManagement target, IssueManagement source, boolean sourceDominant, Map context) { + String src = source.getSystem(); + if (src != null) { + if (sourceDominant || target.getSystem() == null) { + target.setSystem(src); + target.setLocation("system", source.getLocation("system")); + } + } + } + + protected void mergeIssueManagement_Url( + IssueManagement target, IssueManagement source, boolean sourceDominant, Map context) { + String src = source.getUrl(); + if (src != null) { + if (sourceDominant || target.getUrl() == null) { + target.setUrl(src); + target.setLocation("url", source.getLocation("url")); + } + } + } + + protected void mergeScm(Scm target, Scm source, boolean sourceDominant, Map context) { + mergeScm_ChildScmConnectionInheritAppendPath(target, source, sourceDominant, context); + mergeScm_ChildScmDeveloperConnectionInheritAppendPath(target, source, sourceDominant, context); + mergeScm_ChildScmUrlInheritAppendPath(target, source, sourceDominant, context); + mergeScm_Url(target, source, sourceDominant, context); + mergeScm_Connection(target, source, sourceDominant, context); + mergeScm_DeveloperConnection(target, source, sourceDominant, context); + mergeScm_Tag(target, source, sourceDominant, context); + } + + protected void mergeScm_ChildScmConnectionInheritAppendPath( + Scm target, Scm source, boolean sourceDominant, Map context) { + String src = source.getChildScmConnectionInheritAppendPath(); + if (src != null) { + if (sourceDominant || target.getChildScmConnectionInheritAppendPath() == null) { + target.setChildScmConnectionInheritAppendPath(src); + target.setLocation( + "child.scm.connection.inherit.append.path", + source.getLocation("child.scm.connection.inherit.append.path")); + } + } + } + + protected void mergeScm_ChildScmDeveloperConnectionInheritAppendPath( + Scm target, Scm source, boolean sourceDominant, Map context) { + String src = source.getChildScmDeveloperConnectionInheritAppendPath(); + if (src != null) { + if (sourceDominant || target.getChildScmDeveloperConnectionInheritAppendPath() == null) { + target.setChildScmDeveloperConnectionInheritAppendPath(src); + target.setLocation( + "child.scm.developerConnection.inherit.append.path", + source.getLocation("child.scm.developerConnection.inherit.append.path")); + } + } + } + + protected void mergeScm_ChildScmUrlInheritAppendPath( + Scm target, Scm source, boolean sourceDominant, Map context) { + String src = source.getChildScmUrlInheritAppendPath(); + if (src != null) { + if (sourceDominant || target.getChildScmUrlInheritAppendPath() == null) { + target.setChildScmUrlInheritAppendPath(src); + target.setLocation( + "child.scm.url.inherit.append.path", source.getLocation("child.scm.url.inherit.append.path")); + } + } + } + + protected void mergeScm_Url(Scm target, Scm source, boolean sourceDominant, Map context) { + String src = source.getUrl(); + if (src != null) { + if (sourceDominant || target.getUrl() == null) { + target.setUrl(src); + target.setLocation("url", source.getLocation("url")); + } + } + } + + protected void mergeScm_Connection(Scm target, Scm source, boolean sourceDominant, Map context) { + String src = source.getConnection(); + if (src != null) { + if (sourceDominant || target.getConnection() == null) { + target.setConnection(src); + target.setLocation("connection", source.getLocation("connection")); + } + } + } + + protected void mergeScm_DeveloperConnection( + Scm target, Scm source, boolean sourceDominant, Map context) { + String src = source.getDeveloperConnection(); + if (src != null) { + if (sourceDominant || target.getDeveloperConnection() == null) { + target.setDeveloperConnection(src); + target.setLocation("developerConnection", source.getLocation("developerConnection")); + } + } + } + + protected void mergeScm_Tag(Scm target, Scm source, boolean sourceDominant, Map context) { + String src = source.getTag(); + if (src != null) { + if (sourceDominant || target.getTag() == null) { + target.setTag(src); + target.setLocation("tag", source.getLocation("tag")); + } + } + } + + protected void mergeCiManagement( + CiManagement target, CiManagement source, boolean sourceDominant, Map context) { + mergeCiManagement_System(target, source, sourceDominant, context); + mergeCiManagement_Url(target, source, sourceDominant, context); + mergeCiManagement_Notifiers(target, source, sourceDominant, context); + } + + protected void mergeCiManagement_System( + CiManagement target, CiManagement source, boolean sourceDominant, Map context) { + String src = source.getSystem(); + if (src != null) { + if (sourceDominant || target.getSystem() == null) { + target.setSystem(src); + target.setLocation("system", source.getLocation("system")); + } + } + } + + protected void mergeCiManagement_Url( + CiManagement target, CiManagement source, boolean sourceDominant, Map context) { + String src = source.getUrl(); + if (src != null) { + if (sourceDominant || target.getUrl() == null) { + target.setUrl(src); + target.setLocation("url", source.getLocation("url")); + } + } + } + + protected void mergeCiManagement_Notifiers( + CiManagement target, CiManagement source, boolean sourceDominant, Map context) { + target.setNotifiers( + merge(target.getNotifiers(), source.getNotifiers(), sourceDominant, new NotifierKeyComputer())); + } + + protected void mergeNotifier( + Notifier target, Notifier source, boolean sourceDominant, Map context) { + mergeNotifier_Type(target, source, sourceDominant, context); + mergeNotifier_Address(target, source, sourceDominant, context); + mergeNotifier_Configuration(target, source, sourceDominant, context); + mergeNotifier_SendOnError(target, source, sourceDominant, context); + mergeNotifier_SendOnFailure(target, source, sourceDominant, context); + mergeNotifier_SendOnSuccess(target, source, sourceDominant, context); + mergeNotifier_SendOnWarning(target, source, sourceDominant, context); + } + + protected void mergeNotifier_Type( + Notifier target, Notifier source, boolean sourceDominant, Map context) { + String src = source.getType(); + if (src != null) { + if (sourceDominant || target.getType() == null) { + target.setType(src); + } + } + } + + protected void mergeNotifier_Address( + Notifier target, Notifier source, boolean sourceDominant, Map context) { + String src = source.getAddress(); + if (src != null) { + if (sourceDominant || target.getAddress() == null) { + target.setAddress(src); + } + } + } + + protected void mergeNotifier_Configuration( + Notifier target, Notifier source, boolean sourceDominant, Map context) { + Properties merged = new Properties(); + if (sourceDominant) { + merged.putAll(target.getConfiguration()); + merged.putAll(source.getConfiguration()); + } else { + merged.putAll(source.getConfiguration()); + merged.putAll(target.getConfiguration()); + } + target.setConfiguration(merged); + } + + protected void mergeNotifier_SendOnError( + Notifier target, Notifier source, boolean sourceDominant, Map context) { + if (sourceDominant) { + target.setSendOnError(source.isSendOnError()); + } + } + + protected void mergeNotifier_SendOnFailure( + Notifier target, Notifier source, boolean sourceDominant, Map context) { + if (sourceDominant) { + target.setSendOnFailure(source.isSendOnFailure()); + } + } + + protected void mergeNotifier_SendOnSuccess( + Notifier target, Notifier source, boolean sourceDominant, Map context) { + if (sourceDominant) { + target.setSendOnSuccess(source.isSendOnSuccess()); + } + } + + protected void mergeNotifier_SendOnWarning( + Notifier target, Notifier source, boolean sourceDominant, Map context) { + if (sourceDominant) { + target.setSendOnWarning(source.isSendOnWarning()); + } + } + + protected void mergePrerequisites( + Prerequisites target, Prerequisites source, boolean sourceDominant, Map context) { + mergePrerequisites_Maven(target, source, sourceDominant, context); + } + + protected void mergePrerequisites_Maven( + Prerequisites target, Prerequisites source, boolean sourceDominant, Map context) { + String src = source.getMaven(); + if (src != null) { + if (sourceDominant || target.getMaven() == null) { + target.setMaven(src); + target.setLocation("maven", source.getLocation("maven")); + } + } + } + + protected void mergeBuild(Build target, Build source, boolean sourceDominant, Map context) { + mergeBuildBase(target, source, sourceDominant, context); + mergeBuild_SourceDirectory(target, source, sourceDominant, context); + mergeBuild_ScriptSourceDirectory(target, source, sourceDominant, context); + mergeBuild_TestSourceDirectory(target, source, sourceDominant, context); + mergeBuild_OutputDirectory(target, source, sourceDominant, context); + mergeBuild_TestOutputDirectory(target, source, sourceDominant, context); + mergeBuild_Extensions(target, source, sourceDominant, context); + } + + protected void mergeBuild_SourceDirectory( + Build target, Build source, boolean sourceDominant, Map context) { + String src = source.getSourceDirectory(); + if (src != null) { + if (sourceDominant || target.getSourceDirectory() == null) { + target.setSourceDirectory(src); + target.setLocation("sourceDirectory", source.getLocation("sourceDirectory")); + } + } + } + + protected void mergeBuild_ScriptSourceDirectory( + Build target, Build source, boolean sourceDominant, Map context) { + String src = source.getScriptSourceDirectory(); + if (src != null) { + if (sourceDominant || target.getScriptSourceDirectory() == null) { + target.setScriptSourceDirectory(src); + target.setLocation("scriptSourceDirectory", source.getLocation("scriptSourceDirectory")); + } + } + } + + protected void mergeBuild_TestSourceDirectory( + Build target, Build source, boolean sourceDominant, Map context) { + String src = source.getTestSourceDirectory(); + if (src != null) { + if (sourceDominant || target.getTestSourceDirectory() == null) { + target.setTestSourceDirectory(src); + target.setLocation("testSourceDirectory", source.getLocation("testSourceDirectory")); + } + } + } + + protected void mergeBuild_OutputDirectory( + Build target, Build source, boolean sourceDominant, Map context) { + String src = source.getOutputDirectory(); + if (src != null) { + if (sourceDominant || target.getOutputDirectory() == null) { + target.setOutputDirectory(src); + target.setLocation("outputDirectory", source.getLocation("outputDirectory")); + } + } + } + + protected void mergeBuild_TestOutputDirectory( + Build target, Build source, boolean sourceDominant, Map context) { + String src = source.getTestOutputDirectory(); + if (src != null) { + if (sourceDominant || target.getTestOutputDirectory() == null) { + target.setTestOutputDirectory(src); + target.setLocation("testOutputDirectory", source.getLocation("testOutputDirectory")); + } + } + } + + protected void mergeBuild_Extensions( + Build target, Build source, boolean sourceDominant, Map context) { + target.setExtensions( + merge(target.getExtensions(), source.getExtensions(), sourceDominant, new ExtensionKeyComputer())); + } + + protected void mergeExtension( + Extension target, Extension source, boolean sourceDominant, Map context) { + mergeExtension_GroupId(target, source, sourceDominant, context); + mergeExtension_ArtifactId(target, source, sourceDominant, context); + mergeExtension_Version(target, source, sourceDominant, context); + } + + protected void mergeExtension_GroupId( + Extension target, Extension source, boolean sourceDominant, Map context) { + String src = source.getGroupId(); + if (src != null) { + if (sourceDominant || target.getGroupId() == null) { + target.setGroupId(src); + target.setLocation("groupId", source.getLocation("groupId")); + } + } + } + + protected void mergeExtension_ArtifactId( + Extension target, Extension source, boolean sourceDominant, Map context) { + String src = source.getArtifactId(); + if (src != null) { + if (sourceDominant || target.getArtifactId() == null) { + target.setArtifactId(src); + target.setLocation("artifactId", source.getLocation("artifactId")); + } + } + } + + protected void mergeExtension_Version( + Extension target, Extension source, boolean sourceDominant, Map context) { + String src = source.getVersion(); + if (src != null) { + if (sourceDominant || target.getVersion() == null) { + target.setVersion(src); + target.setLocation("version", source.getLocation("version")); + } + } + } + + protected void mergeBuildBase( + BuildBase target, BuildBase source, boolean sourceDominant, Map context) { + mergePluginConfiguration(target, source, sourceDominant, context); + mergeBuildBase_DefaultGoal(target, source, sourceDominant, context); + mergeBuildBase_FinalName(target, source, sourceDominant, context); + mergeBuildBase_Directory(target, source, sourceDominant, context); + mergeBuildBase_Resources(target, source, sourceDominant, context); + mergeBuildBase_TestResources(target, source, sourceDominant, context); + mergeBuildBase_Filters(target, source, sourceDominant, context); + } + + protected void mergeBuildBase_DefaultGoal( + BuildBase target, BuildBase source, boolean sourceDominant, Map context) { + String src = source.getDefaultGoal(); + if (src != null) { + if (sourceDominant || target.getDefaultGoal() == null) { + target.setDefaultGoal(src); + target.setLocation("defaultGoal", source.getLocation("defaultGoal")); + } + } + } + + protected void mergeBuildBase_Directory( + BuildBase target, BuildBase source, boolean sourceDominant, Map context) { + String src = source.getDirectory(); + if (src != null) { + if (sourceDominant || target.getDirectory() == null) { + target.setDirectory(src); + target.setLocation("directory", source.getLocation("directory")); + } + } + } + + protected void mergeBuildBase_FinalName( + BuildBase target, BuildBase source, boolean sourceDominant, Map context) { + String src = source.getFinalName(); + if (src != null) { + if (sourceDominant || target.getFinalName() == null) { + target.setFinalName(src); + target.setLocation("finalName", source.getLocation("finalName")); + } + } + } + + protected void mergeBuildBase_Filters( + BuildBase target, BuildBase source, boolean sourceDominant, Map context) { + List src = source.getFilters(); + if (!src.isEmpty()) { + List tgt = target.getFilters(); + List merged = new ArrayList<>(tgt.size() + src.size()); + merged.addAll(tgt); + merged.addAll(src); + target.setFilters(merged); + } + } + + protected void mergeBuildBase_Resources( + BuildBase target, BuildBase source, boolean sourceDominant, Map context) { + target.setResources( + merge(target.getResources(), source.getResources(), sourceDominant, new ResourceKeyComputer())); + } + + protected void mergeBuildBase_TestResources( + BuildBase target, BuildBase source, boolean sourceDominant, Map context) { + target.setTestResources( + merge(target.getTestResources(), source.getTestResources(), sourceDominant, new ResourceKeyComputer())); + } + + protected void mergePluginConfiguration( + PluginConfiguration target, + PluginConfiguration source, + boolean sourceDominant, + Map context) { + mergePluginContainer(target, source, sourceDominant, context); + mergePluginConfiguration_PluginManagement(target, source, sourceDominant, context); + } + + protected void mergePluginConfiguration_PluginManagement( + PluginConfiguration target, + PluginConfiguration source, + boolean sourceDominant, + Map context) { + PluginManagement src = source.getPluginManagement(); + if (src != null) { + PluginManagement tgt = target.getPluginManagement(); + if (tgt == null) { + tgt = new PluginManagement(); + target.setPluginManagement(tgt); + } + mergePluginManagement(tgt, src, sourceDominant, context); + } + } + + protected void mergePluginContainer( + PluginContainer target, PluginContainer source, boolean sourceDominant, Map context) { + mergePluginContainer_Plugins(target, source, sourceDominant, context); + } + + protected void mergePluginContainer_Plugins( + PluginContainer target, PluginContainer source, boolean sourceDominant, Map context) { + target.setPlugins(merge(target.getPlugins(), source.getPlugins(), sourceDominant, new PluginKeyComputer())); + } + + protected void mergePluginManagement( + PluginManagement target, PluginManagement source, boolean sourceDominant, Map context) { + mergePluginContainer(target, source, sourceDominant, context); + } + + protected void mergePlugin(Plugin target, Plugin source, boolean sourceDominant, Map context) { + mergeConfigurationContainer(target, source, sourceDominant, context); + 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); + } + + protected void mergePlugin_GroupId( + Plugin target, Plugin source, boolean sourceDominant, Map context) { + String src = source.getGroupId(); + if (src != null) { + if (sourceDominant || target.getGroupId() == null) { + target.setGroupId(src); + target.setLocation("groupId", source.getLocation("groupId")); + } + } + } + + protected void mergePlugin_ArtifactId( + Plugin target, Plugin source, boolean sourceDominant, Map context) { + String src = source.getArtifactId(); + if (src != null) { + if (sourceDominant || target.getArtifactId() == null) { + target.setArtifactId(src); + target.setLocation("artifactId", source.getLocation("artifactId")); + } + } + } + + protected void mergePlugin_Version( + Plugin target, Plugin source, boolean sourceDominant, Map context) { + String src = source.getVersion(); + if (src != null) { + if (sourceDominant || target.getVersion() == null) { + target.setVersion(src); + target.setLocation("version", source.getLocation("version")); + } + } + } + + protected void mergePlugin_Extensions( + Plugin target, Plugin source, boolean sourceDominant, Map context) { + String src = source.getExtensions(); + if (src != null) { + if (sourceDominant || target.getExtensions() == null) { + target.setExtensions(src); + target.setLocation("extensions", source.getLocation("extensions")); + } + } + } + + protected void mergePlugin_Dependencies( + Plugin target, Plugin source, boolean sourceDominant, Map context) { + target.setDependencies( + merge(target.getDependencies(), source.getDependencies(), sourceDominant, new DependencyKeyComputer())); + } + + protected void mergePlugin_Executions( + Plugin target, Plugin source, boolean sourceDominant, Map context) { + target.setExecutions( + merge(target.getExecutions(), source.getExecutions(), sourceDominant, new ExecutionKeyComputer())); + } + + protected void mergeConfigurationContainer( + ConfigurationContainer target, + ConfigurationContainer source, + boolean sourceDominant, + Map context) { + mergeConfigurationContainer_Inherited(target, source, sourceDominant, context); + mergeConfigurationContainer_Configuration(target, source, sourceDominant, context); + } + + protected void mergeConfigurationContainer_Inherited( + ConfigurationContainer target, + ConfigurationContainer source, + boolean sourceDominant, + Map context) { + String src = source.getInherited(); + if (src != null) { + if (sourceDominant || target.getInherited() == null) { + target.setInherited(src); + target.setLocation("inherited", source.getLocation("inherited")); + } + } + } + + protected void mergeConfigurationContainer_Configuration( + ConfigurationContainer target, + ConfigurationContainer source, + boolean sourceDominant, + Map context) { + Xpp3Dom src = (Xpp3Dom) source.getConfiguration(); + if (src != null) { + Xpp3Dom tgt = (Xpp3Dom) target.getConfiguration(); + if (sourceDominant || tgt == null) { + tgt = Xpp3Dom.mergeXpp3Dom(new Xpp3Dom(src), tgt); + } else { + tgt = Xpp3Dom.mergeXpp3Dom(tgt, src); + } + target.setConfiguration(tgt); + } + } + + protected void mergePluginExecution( + PluginExecution target, PluginExecution source, boolean sourceDominant, Map context) { + mergeConfigurationContainer(target, source, sourceDominant, context); + mergePluginExecution_Id(target, source, sourceDominant, context); + mergePluginExecution_Phase(target, source, sourceDominant, context); + mergePluginExecution_Goals(target, source, sourceDominant, context); + } + + protected void mergePluginExecution_Id( + PluginExecution target, PluginExecution source, boolean sourceDominant, Map context) { + String src = source.getId(); + if (src != null) { + if (sourceDominant || target.getId() == null) { + target.setId(src); + target.setLocation("id", source.getLocation("id")); + } + } + } + + protected void mergePluginExecution_Phase( + PluginExecution target, PluginExecution source, boolean sourceDominant, Map context) { + String src = source.getPhase(); + if (src != null) { + if (sourceDominant || target.getPhase() == null) { + target.setPhase(src); + target.setLocation("phase", source.getLocation("phase")); + } + } + } + + protected void mergePluginExecution_Goals( + PluginExecution target, PluginExecution source, boolean sourceDominant, Map context) { + List src = source.getGoals(); + if (!src.isEmpty()) { + List tgt = target.getGoals(); + List merged = new ArrayList<>(tgt.size() + src.size()); + merged.addAll(tgt); + merged.addAll(src); + target.setGoals(merged); + } + } + + protected void mergeResource( + Resource target, Resource source, boolean sourceDominant, Map context) { + mergeFileSet(target, source, sourceDominant, context); + mergeResource_TargetPath(target, source, sourceDominant, context); + mergeResource_Filtering(target, source, sourceDominant, context); + mergeResource_MergeId(target, source, sourceDominant, context); + } + + protected void mergeResource_TargetPath( + Resource target, Resource source, boolean sourceDominant, Map context) { + String src = source.getTargetPath(); + if (src != null) { + if (sourceDominant || target.getTargetPath() == null) { + target.setTargetPath(src); + target.setLocation("targetPath", source.getLocation("targetPath")); + } + } + } + + protected void mergeResource_Filtering( + Resource target, Resource source, boolean sourceDominant, Map context) { + String src = source.getFiltering(); + if (src != null) { + if (sourceDominant || target.getFiltering() == null) { + target.setFiltering(src); + target.setLocation("filtering", source.getLocation("filtering")); + } + } + } + + protected void mergeResource_MergeId( + Resource target, Resource source, boolean sourceDominant, Map context) { + String src = source.getMergeId(); + if (src != null) { + if (sourceDominant || target.getMergeId() == null) { + target.setMergeId(src); + } + } + } + + protected void mergeFileSet(FileSet target, FileSet source, boolean sourceDominant, Map context) { + mergePatternSet(target, source, sourceDominant, context); + mergeFileSet_Directory(target, source, sourceDominant, context); + } + + protected void mergeFileSet_Directory( + FileSet target, FileSet source, boolean sourceDominant, Map context) { + String src = source.getDirectory(); + if (src != null) { + if (sourceDominant || target.getDirectory() == null) { + target.setDirectory(src); + target.setLocation("directory", source.getLocation("directory")); + } + } + } + + protected void mergePatternSet( + PatternSet target, PatternSet source, boolean sourceDominant, Map context) { + mergePatternSet_Includes(target, source, sourceDominant, context); + mergePatternSet_Excludes(target, source, sourceDominant, context); + } + + protected void mergePatternSet_Includes( + PatternSet target, PatternSet source, boolean sourceDominant, Map context) { + List src = source.getIncludes(); + if (!src.isEmpty()) { + List tgt = target.getIncludes(); + List merged = new ArrayList<>(tgt.size() + src.size()); + merged.addAll(tgt); + merged.addAll(src); + target.setIncludes(merged); + } + } + + protected void mergePatternSet_Excludes( + PatternSet target, PatternSet source, boolean sourceDominant, Map context) { + List src = source.getExcludes(); + if (!src.isEmpty()) { + List tgt = target.getExcludes(); + List merged = new ArrayList<>(tgt.size() + src.size()); + merged.addAll(tgt); + merged.addAll(src); + target.setExcludes(merged); + } + } + + protected void mergeProfile(Profile target, Profile source, boolean sourceDominant, Map context) { + mergeModelBase(target, source, sourceDominant, context); + // TODO + } + + protected void mergeActivation( + Activation target, Activation source, boolean sourceDominant, Map context) { + // TODO + } + + protected Object getDependencyKey(Dependency dependency) { + return dependency; + } + + protected Object getPluginKey(Plugin plugin) { + return plugin; + } + + protected Object getPluginExecutionKey(PluginExecution pluginExecution) { + return pluginExecution; + } + + protected Object getReportPluginKey(ReportPlugin reportPlugin) { + return reportPlugin; + } + + protected Object getReportSetKey(ReportSet reportSet) { + return reportSet; + } + + protected Object getLicenseKey(License license) { + return license; + } + + protected Object getMailingListKey(MailingList mailingList) { + return mailingList; + } + + protected Object getDeveloperKey(Developer developer) { + return developer; + } + + protected Object getContributorKey(Contributor contributor) { + return contributor; + } + + protected Object getProfileKey(Profile profile) { + return profile; + } + + protected Object getRepositoryKey(Repository repository) { + return getRepositoryBaseKey(repository); + } + + protected Object getRepositoryBaseKey(RepositoryBase repositoryBase) { + return repositoryBase; + } + + protected Object getNotifierKey(Notifier notifier) { + return notifier; + } + + protected Object getResourceKey(Resource resource) { + return resource; + } + + protected Object getExtensionKey(Extension extension) { + return extension; + } + + protected Object getExclusionKey(Exclusion exclusion) { + return exclusion; + } + + /** + * Use to compute keys for data structures + * @param + */ + private interface KeyComputer { + Object key(T t); + } + + /** + * Remapping function + * @param + */ + private interface Remapping { + T merge(T u, T v); + } + + /** + * KeyComputer for Dependency + */ + private final class DependencyKeyComputer implements KeyComputer { + @Override + public Object key(Dependency dependency) { + return getDependencyKey(dependency); + } + } + + /** + * KeyComputer for License + */ + private class LicenseKeyComputer implements KeyComputer { + @Override + public Object key(License license) { + return getLicenseKey(license); + } + } + + /** + * KeyComputer for MailingList + */ + private class MailingListKeyComputer implements KeyComputer { + @Override + public Object key(MailingList mailingList) { + return getMailingListKey(mailingList); + } + } + + /** + * KeyComputer for Developer + */ + private class DeveloperKeyComputer implements KeyComputer { + @Override + public Object key(Developer developer) { + return getDeveloperKey(developer); + } + } + + /** + * KeyComputer for Contributor + */ + private class ContributorKeyComputer implements KeyComputer { + @Override + public Object key(Contributor contributor) { + return getContributorKey(contributor); + } + } + + /** + * KeyComputer for Profile + */ + private class ProfileKeyComputer implements KeyComputer { + @Override + public Object key(Profile profile) { + return getProfileKey(profile); + } + } + + /** + * KeyComputer for Repository + */ + private class RepositoryKeyComputer implements KeyComputer { + @Override + public Object key(Repository repository) { + return getRepositoryKey(repository); + } + } + + /** + * KeyComputer for ReportPlugin + */ + private class ReportPluginKeyComputer implements KeyComputer { + @Override + public Object key(ReportPlugin plugin) { + return getReportPluginKey(plugin); + } + } + + /** + * KeyComputer for Plugin + */ + private class PluginKeyComputer implements KeyComputer { + @Override + public Object key(Plugin plugin) { + return getPluginKey(plugin); + } + } + + /** + * KeyComputer for ReportSet + */ + private class ReportSetKeyComputer implements KeyComputer { + @Override + public Object key(ReportSet reportSet) { + return getReportSetKey(reportSet); + } + } + + /** + * KeyComputer for Notifier + */ + private class NotifierKeyComputer implements KeyComputer { + @Override + public Object key(Notifier notifier) { + return getNotifierKey(notifier); + } + } + + /** + * KeyComputer for Extension + */ + private class ExtensionKeyComputer implements KeyComputer { + @Override + public Object key(Extension extension) { + return getExtensionKey(extension); + } + } + + /** + * KeyComputer for Resource + */ + private class ResourceKeyComputer implements KeyComputer { + @Override + public Object key(Resource resource) { + return getResourceKey(resource); + } + } + + /** + * KeyComputer for PluginExecution + */ + private class ExecutionKeyComputer implements KeyComputer { + @Override + public Object key(PluginExecution pluginExecution) { + return getPluginExecutionKey(pluginExecution); + } + } + + /** + * KeyComputer for Exclusion + */ + private class ExclusionKeyComputer implements KeyComputer { + @Override + public Object key(Exclusion exclusion) { + return getExclusionKey(exclusion); + } + } + + /** + * Return the second value if sourceDominant is true, the first one otherwise. + * @param + */ + private static class SourceDominant implements Remapping { + private final boolean sourceDominant; + + SourceDominant(boolean sourceDominant) { + this.sourceDominant = sourceDominant; + } + + @Override + public T merge(T u, T v) { + return sourceDominant ? v : u; + } + } + + /** + * Merge two lists + */ + private static List merge(List tgt, List src, boolean sourceDominant, KeyComputer computer) { + return merge(tgt, src, computer, new SourceDominant(sourceDominant)); + } + + private static List merge(List tgt, List src, KeyComputer computer, Remapping remapping) { + if (src.isEmpty()) { + return tgt; + } + + MergingList list; + if (tgt instanceof MergingList) { + list = (MergingList) tgt; + } else { + list = new MergingList<>(computer, src.size() + tgt.size()); + list.mergeAll(tgt, new SourceDominant(true)); + } + + list.mergeAll(src, remapping); + return list; + } + + /** + * Merging list + * @param + */ + private static class MergingList extends AbstractList implements java.io.Serializable { + + private final KeyComputer keyComputer; + private Map map; + private List list; + + MergingList(KeyComputer keyComputer, int initialCapacity) { + this.map = new LinkedHashMap<>(initialCapacity); + this.keyComputer = keyComputer; + } + + Object writeReplace() throws ObjectStreamException { + return new ArrayList<>(this); + } + + @Override + public Iterator iterator() { + if (map != null) { + return map.values().iterator(); + } else { + return list.iterator(); + } + } + + void mergeAll(Collection vs, Remapping remapping) { + if (map == null) { + map = new LinkedHashMap<>(list.size() + vs.size()); + for (V v : list) { + map.put(keyComputer.key(v), v); + } + list = null; + } + if (vs instanceof MergingList && ((MergingList) vs).map != null) { + for (Map.Entry e : ((MergingList) vs).map.entrySet()) { + Object key = e.getKey(); + V oldValue = map.get(key); + // JDK8: this should be a call to map.merge( key, v, remapping ) + V newValue = (oldValue == null) ? e.getValue() : remapping.merge(oldValue, e.getValue()); + if (newValue == null) { + remove(key); + } else if (newValue != oldValue) { + map.put(key, newValue); + } + } + } else { + for (V v : vs) { + Object key = keyComputer.key(v); + // JDK8: this should be a call to map.merge( key, v, remapping ) + V oldValue = map.get(key); + V newValue = (oldValue == null) ? v : remapping.merge(oldValue, v); + if (newValue == null) { + remove(key); + } else { + map.put(key, newValue); + } + } + } + } + + @Override + public boolean contains(Object o) { + if (map != null) { + return map.containsValue(o); + } else { + return list.contains(o); + } + } + + private List asList() { + if (list == null) { + list = new ArrayList<>(map.values()); + map = null; + } + return list; + } + + @Override + public void add(int index, V element) { + asList().add(index, element); + } + + @Override + public V remove(int index) { + return asList().remove(index); + } + + @Override + public V get(int index) { + return asList().get(index); + } + + @Override + public int size() { + if (map != null) { + return map.size(); + } else { + return list.size(); + } + } + } +} diff --git a/compat/maven-plugin-api/pom.xml b/compat/maven-plugin-api/pom.xml index 08b0a16239..8d0c941071 100644 --- a/compat/maven-plugin-api/pom.xml +++ b/compat/maven-plugin-api/pom.xml @@ -156,7 +156,6 @@ under the License. - org.apache.maven.monitor.logging.DefaultLog org.apache.maven.plugin.lifecycle org.apache.maven.plugin.descriptor.PluginDescriptor#getLifecycleMapping(java.lang.String) diff --git a/compat/maven-plugin-api/src/main/java/org/apache/maven/monitor/logging/DefaultLog.java b/compat/maven-plugin-api/src/main/java/org/apache/maven/monitor/logging/DefaultLog.java new file mode 100644 index 0000000000..d36b6eba3b --- /dev/null +++ b/compat/maven-plugin-api/src/main/java/org/apache/maven/monitor/logging/DefaultLog.java @@ -0,0 +1,106 @@ +/* + * 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.monitor.logging; + +import org.apache.maven.plugin.logging.Log; +import org.codehaus.plexus.logging.Logger; + +/** + * @author jdcasey + */ +public class DefaultLog implements Log { + + private final Logger logger; + + public DefaultLog(Logger logger) { + this.logger = logger; + } + + public void debug(CharSequence content) { + logger.debug(toString(content)); + } + + private String toString(CharSequence content) { + if (content == null) { + return ""; + } else { + return content.toString(); + } + } + + public void debug(CharSequence content, Throwable error) { + logger.debug(toString(content), error); + } + + public void debug(Throwable error) { + logger.debug("", error); + } + + public void info(CharSequence content) { + logger.info(toString(content)); + } + + public void info(CharSequence content, Throwable error) { + logger.info(toString(content), error); + } + + public void info(Throwable error) { + logger.info("", error); + } + + public void warn(CharSequence content) { + logger.warn(toString(content)); + } + + public void warn(CharSequence content, Throwable error) { + logger.warn(toString(content), error); + } + + public void warn(Throwable error) { + logger.warn("", error); + } + + public void error(CharSequence content) { + logger.error(toString(content)); + } + + public void error(CharSequence content, Throwable error) { + logger.error(toString(content), error); + } + + public void error(Throwable error) { + logger.error("", error); + } + + public boolean isDebugEnabled() { + return logger.isDebugEnabled(); + } + + public boolean isInfoEnabled() { + return logger.isInfoEnabled(); + } + + public boolean isWarnEnabled() { + return logger.isWarnEnabled(); + } + + public boolean isErrorEnabled() { + return logger.isErrorEnabled(); + } +} diff --git a/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java b/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java index 2ba1695fe0..eaf189aa40 100644 --- a/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java +++ b/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java @@ -223,7 +223,7 @@ public class DefaultArtifactDescriptorReader implements ArtifactDescriptorReader remoteRepositoryManager, request.getRepositories())); if (resolveResult.getRepository() instanceof WorkspaceRepository) { - modelRequest.setPomPath(pomArtifact.getPath()); + modelRequest.setPomFile(pomArtifact.getFile()); } else { modelRequest.setModelSource(new ArtifactModelSource( pomArtifact.getPath(), diff --git a/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java b/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java index 213b6dc5a1..78d54a2aa6 100644 --- a/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java +++ b/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java @@ -18,94 +18,69 @@ */ package org.apache.maven.repository.internal; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.function.Supplier; - -import org.apache.maven.building.Source; import org.apache.maven.model.building.ModelCache; import org.eclipse.aether.RepositoryCache; import org.eclipse.aether.RepositorySystemSession; -import static java.util.Objects.requireNonNull; - /** * A model builder cache backed by the repository system cache. * * @deprecated since 4.0.0, use {@code maven-api-impl} jar instead */ @Deprecated(since = "4.0.0") -public class DefaultModelCache implements ModelCache { - private static final String KEY = DefaultModelCache.class.getName(); +class DefaultModelCache implements ModelCache { + + private final RepositorySystemSession session; + + private final RepositoryCache cache; - @SuppressWarnings("unchecked") public static ModelCache newInstance(RepositorySystemSession session) { - ConcurrentHashMap> cache; - RepositoryCache repositoryCache = session.getCache(); - if (repositoryCache == null) { - cache = new ConcurrentHashMap<>(); + if (session.getCache() == null) { + return null; } else { - cache = (ConcurrentHashMap>) - repositoryCache.computeIfAbsent(session, KEY, ConcurrentHashMap::new); + return new DefaultModelCache(session); } - return new DefaultModelCache(cache); } - private final ConcurrentMap> cache; - - private DefaultModelCache(ConcurrentMap> cache) { - this.cache = requireNonNull(cache); + private DefaultModelCache(RepositorySystemSession session) { + this.session = session; + this.cache = session.getCache(); } @Override - @SuppressWarnings({"unchecked"}) - public T computeIfAbsent(String groupId, String artifactId, String version, String tag, Supplier data) { - return (T) computeIfAbsent(new GavCacheKey(groupId, artifactId, version, tag), data); + public Object get(String groupId, String artifactId, String version, String tag) { + return cache.get(session, new Key(groupId, artifactId, version, tag)); } @Override - @SuppressWarnings({"unchecked"}) - public T computeIfAbsent(Source path, String tag, Supplier data) { - return (T) computeIfAbsent(new SourceCacheKey(path, tag), data); + public void put(String groupId, String artifactId, String version, String tag, Object data) { + cache.put(session, new Key(groupId, artifactId, version, tag), data); } - protected Object computeIfAbsent(Object key, Supplier data) { - return cache.computeIfAbsent(key, k -> new CachingSupplier<>(data)).get(); - } + static class Key { - static class GavCacheKey { + private final String groupId; - private final String gav; + private final String artifactId; + + private final String version; private final String tag; private final int hash; - GavCacheKey(String groupId, String artifactId, String version, String tag) { - this(gav(groupId, artifactId, version), tag); - } - - GavCacheKey(String gav, String tag) { - this.gav = gav; + Key(String groupId, String artifactId, String version, String tag) { + this.groupId = groupId; + this.artifactId = artifactId; + this.version = version; this.tag = tag; - this.hash = Objects.hash(gav, tag); - } - private static String gav(String groupId, String artifactId, String version) { - StringBuilder sb = new StringBuilder(); - if (groupId != null) { - sb.append(groupId); - } - sb.append(":"); - if (artifactId != null) { - sb.append(artifactId); - } - sb.append(":"); - if (version != null) { - sb.append(version); - } - return sb.toString(); + int h = 17; + h = h * 31 + this.groupId.hashCode(); + h = h * 31 + this.artifactId.hashCode(); + h = h * 31 + this.version.hashCode(); + h = h * 31 + this.tag.hashCode(); + hash = h; } @Override @@ -116,97 +91,17 @@ public class DefaultModelCache implements ModelCache { if (null == obj || !getClass().equals(obj.getClass())) { return false; } - GavCacheKey that = (GavCacheKey) obj; - return Objects.equals(this.gav, that.gav) && Objects.equals(this.tag, that.tag); + + Key that = (Key) obj; + return artifactId.equals(that.artifactId) + && groupId.equals(that.groupId) + && version.equals(that.version) + && tag.equals(that.tag); } @Override public int hashCode() { return hash; } - - @Override - public String toString() { - return "GavCacheKey{" + "gav='" + gav + '\'' + ", tag='" + tag + '\'' + '}'; - } - } - - private static final class SourceCacheKey { - private final Source source; - - private final String tag; - - private final int hash; - - SourceCacheKey(Source source, String tag) { - this.source = source; - this.tag = tag; - this.hash = Objects.hash(source, tag); - } - - @Override - public String toString() { - return "SourceCacheKey{" + "source=" + source + ", tag='" + tag + '\'' + '}'; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (null == obj || !getClass().equals(obj.getClass())) { - return false; - } - SourceCacheKey that = (SourceCacheKey) obj; - return Objects.equals(this.source, that.source) && Objects.equals(this.tag, that.tag); - } - - @Override - public int hashCode() { - return hash; - } - } - - static class CachingSupplier implements Supplier { - final Supplier supplier; - volatile Object value; - - CachingSupplier(Supplier supplier) { - this.supplier = supplier; - } - - @Override - @SuppressWarnings({"unchecked", "checkstyle:InnerAssignment"}) - public T get() { - Object v; - if ((v = value) == null) { - synchronized (this) { - if ((v = value) == null) { - try { - v = value = supplier.get(); - } catch (Exception e) { - v = value = new AltRes(e); - } - } - } - } - if (v instanceof AltRes) { - uncheckedThrow(((AltRes) v).t); - } - return (T) v; - } - - static class AltRes { - final Throwable t; - - AltRes(Throwable t) { - this.t = t; - } - } - } - - @SuppressWarnings("unchecked") - static void uncheckedThrow(Throwable t) throws T { - throw (T) t; // rely on vacuous cast } } diff --git a/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java b/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java index 66509f4773..2e5a22da03 100644 --- a/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java +++ b/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java @@ -18,18 +18,18 @@ */ package org.apache.maven.repository.internal; +import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; -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.building.ArtifactModelSource; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Parent; +import org.apache.maven.model.Repository; +import org.apache.maven.model.building.FileModelSource; import org.apache.maven.model.building.ModelSource; import org.apache.maven.model.resolution.InvalidRepositoryException; import org.apache.maven.model.resolution.ModelResolver; @@ -109,7 +109,7 @@ class DefaultModelResolver implements ModelResolver { } @Override - public void addRepository(Repository repository) throws InvalidRepositoryException { + public void addRepository(org.apache.maven.model.Repository repository) throws InvalidRepositoryException { addRepository(repository, false); } @@ -127,8 +127,8 @@ class DefaultModelResolver implements ModelResolver { removeMatchingRepository(repositories, repository.getId()); } - List newRepositories = Collections.singletonList( - ArtifactDescriptorUtils.toRemoteRepository(new org.apache.maven.model.Repository(repository))); + List newRepositories = + Collections.singletonList(ArtifactDescriptorUtils.toRemoteRepository(repository)); this.repositories = remoteRepositoryManager.aggregateRepositories(session, repositories, newRepositories, true); } @@ -161,12 +161,13 @@ class DefaultModelResolver implements ModelResolver { throw new UnresolvableModelException(e.getMessage(), groupId, artifactId, version, e); } - return new ArtifactModelSource(pomArtifact.getPath(), groupId, artifactId, version); + File pomFile = pomArtifact.getFile(); + + return new FileModelSource(pomFile); } @Override - public ModelSource resolveModel(final Parent parent, final AtomicReference modified) - throws UnresolvableModelException { + public ModelSource resolveModel(final Parent parent) throws UnresolvableModelException { try { final Artifact artifact = new DefaultArtifact(parent.getGroupId(), parent.getArtifactId(), "", "pom", parent.getVersion()); @@ -199,12 +200,9 @@ class DefaultModelResolver implements ModelResolver { parent.getVersion()); } - String newVersion = versionRangeResult.getHighestVersion().toString(); - if (!parent.getVersion().equals(newVersion)) { - modified.set(parent.withVersion(newVersion)); - } + parent.setVersion(versionRangeResult.getHighestVersion().toString()); - return resolveModel(parent.getGroupId(), parent.getArtifactId(), newVersion); + return resolveModel(parent.getGroupId(), parent.getArtifactId(), parent.getVersion()); } catch (final VersionRangeResolutionException e) { throw new UnresolvableModelException( e.getMessage(), parent.getGroupId(), parent.getArtifactId(), parent.getVersion(), e); @@ -212,8 +210,7 @@ class DefaultModelResolver implements ModelResolver { } @Override - public ModelSource resolveModel(final Dependency dependency, AtomicReference modified) - throws UnresolvableModelException { + public ModelSource resolveModel(final Dependency dependency) throws UnresolvableModelException { try { final Artifact artifact = new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), "", "pom", dependency.getVersion()); @@ -247,46 +244,12 @@ class DefaultModelResolver implements ModelResolver { dependency.getVersion()); } - String newVersion = versionRangeResult.getHighestVersion().toString(); - if (!dependency.getVersion().equals(newVersion)) { - modified.set(dependency.withVersion(newVersion)); - } + dependency.setVersion(versionRangeResult.getHighestVersion().toString()); - return resolveModel(dependency.getGroupId(), dependency.getArtifactId(), newVersion); + return resolveModel(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion()); } catch (VersionRangeResolutionException e) { throw new UnresolvableModelException( e.getMessage(), dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion(), e); } } - - @Override - public ModelSource resolveModel(org.apache.maven.model.Parent parent) throws UnresolvableModelException { - AtomicReference resolvedParent = new AtomicReference<>(); - ModelSource result = resolveModel(parent.getDelegate(), resolvedParent); - if (resolvedParent.get() != null) { - parent.setVersion(resolvedParent.get().getVersion()); - } - return result; - } - - @Override - public ModelSource resolveModel(org.apache.maven.model.Dependency dependency) throws UnresolvableModelException { - AtomicReference resolvedDependency = new AtomicReference<>(); - ModelSource result = resolveModel(dependency.getDelegate(), resolvedDependency); - if (resolvedDependency.get() != null) { - dependency.setVersion(resolvedDependency.get().getVersion()); - } - return result; - } - - @Override - public void addRepository(org.apache.maven.model.Repository repository) throws InvalidRepositoryException { - addRepository(repository.getDelegate()); - } - - @Override - public void addRepository(org.apache.maven.model.Repository repository, boolean replace) - throws InvalidRepositoryException { - addRepository(repository.getDelegate(), replace); - } } diff --git a/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/RelocatedArtifact.java b/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/RelocatedArtifact.java index 3c038eed92..bc4c48b690 100644 --- a/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/RelocatedArtifact.java +++ b/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/RelocatedArtifact.java @@ -19,7 +19,6 @@ package org.apache.maven.repository.internal; import java.io.File; -import java.nio.file.Path; import java.util.Map; import java.util.Objects; @@ -118,7 +117,6 @@ public final class RelocatedArtifact extends AbstractArtifact { return new RelocatedArtifact(artifact, groupId, artifactId, classifier, extension, version, message); } - @Deprecated @Override public Artifact setFile(File file) { File current = getFile(); @@ -129,16 +127,6 @@ public final class RelocatedArtifact extends AbstractArtifact { artifact.setFile(file), groupId, artifactId, classifier, extension, version, message); } - @Override - public Artifact setPath(Path path) { - Path current = getPath(); - if (Objects.equals(current, path)) { - return this; - } - return new RelocatedArtifact( - artifact.setPath(path), groupId, artifactId, classifier, extension, version, message); - } - @Override public Artifact setProperties(Map properties) { Map current = getProperties(); @@ -149,17 +137,11 @@ public final class RelocatedArtifact extends AbstractArtifact { artifact.setProperties(properties), groupId, artifactId, classifier, extension, version, message); } - @Deprecated @Override public File getFile() { return artifact.getFile(); } - @Override - public Path getPath() { - return artifact.getPath(); - } - @Override public String getProperty(String key, String defaultValue) { return artifact.getProperty(key, defaultValue); diff --git a/compat/maven-resolver-provider/src/test/java/org/apache/maven/repository/internal/DefaultModelResolverTest.java b/compat/maven-resolver-provider/src/test/java/org/apache/maven/repository/internal/DefaultModelResolverTest.java index 1fd832aca9..e9a1111490 100644 --- a/compat/maven-resolver-provider/src/test/java/org/apache/maven/repository/internal/DefaultModelResolverTest.java +++ b/compat/maven-resolver-provider/src/test/java/org/apache/maven/repository/internal/DefaultModelResolverTest.java @@ -20,10 +20,9 @@ package org.apache.maven.repository.internal; import java.net.MalformedURLException; import java.util.Arrays; -import java.util.concurrent.atomic.AtomicReference; -import org.apache.maven.api.model.Dependency; -import org.apache.maven.api.model.Parent; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Parent; import org.apache.maven.model.resolution.ModelResolver; import org.apache.maven.model.resolution.UnresolvableModelException; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; @@ -52,32 +51,30 @@ final class DefaultModelResolverTest extends AbstractRepositoryTestCase { } @Test - void testResolveParentThrowsUnresolvableModelExceptionWhenNotFound() throws Exception { - final Parent parent = Parent.newBuilder() - .groupId("ut.simple") - .artifactId("artifact") - .version("0") - .build(); + public void testResolveParentThrowsUnresolvableModelExceptionWhenNotFound() throws Exception { + final Parent parent = new Parent(); + parent.setGroupId("ut.simple"); + parent.setArtifactId("artifact"); + parent.setVersion("0"); UnresolvableModelException e = assertThrows( UnresolvableModelException.class, - () -> newModelResolver().resolveModel(parent, new AtomicReference<>()), + () -> newModelResolver().resolveModel(parent), "Expected 'UnresolvableModelException' not thrown."); assertNotNull(e.getMessage()); assertTrue(e.getMessage().contains("Could not find artifact ut.simple:artifact:pom:0 in repo")); } @Test - void testResolveParentThrowsUnresolvableModelExceptionWhenNoMatchingVersionFound() throws Exception { - final Parent parent = Parent.newBuilder() - .groupId("ut.simple") - .artifactId("artifact") - .version("[2.0,2.1)") - .build(); + public void testResolveParentThrowsUnresolvableModelExceptionWhenNoMatchingVersionFound() throws Exception { + final Parent parent = new Parent(); + parent.setGroupId("ut.simple"); + parent.setArtifactId("artifact"); + parent.setVersion("[2.0,2.1)"); UnresolvableModelException e = assertThrows( UnresolvableModelException.class, - () -> newModelResolver().resolveModel(parent, new AtomicReference<>()), + () -> newModelResolver().resolveModel(parent), "Expected 'UnresolvableModelException' not thrown."); assertNotNull(e.getMessage()); assertEquals("No versions matched the requested parent version range '[2.0,2.1)'", e.getMessage()); @@ -85,56 +82,50 @@ final class DefaultModelResolverTest extends AbstractRepositoryTestCase { @Test void testResolveParentThrowsUnresolvableModelExceptionWhenUsingRangesWithoutUpperBound() throws Exception { - final Parent parent = Parent.newBuilder() - .groupId("ut.simple") - .artifactId("artifact") - .version("[1.0,)") - .build(); + final Parent parent = new Parent(); + parent.setGroupId("ut.simple"); + parent.setArtifactId("artifact"); + parent.setVersion("[1.0,)"); UnresolvableModelException e = assertThrows( UnresolvableModelException.class, - () -> newModelResolver().resolveModel(parent, new AtomicReference<>()), + () -> newModelResolver().resolveModel(parent), "Expected 'UnresolvableModelException' not thrown."); assertEquals("The requested parent version range '[1.0,)' does not specify an upper bound", e.getMessage()); } @Test void testResolveParentSuccessfullyResolvesExistingParentWithoutRange() throws Exception { - final Parent parent = Parent.newBuilder() - .groupId("ut.simple") - .artifactId("artifact") - .version("1.0") - .build(); + final Parent parent = new Parent(); + parent.setGroupId("ut.simple"); + parent.setArtifactId("artifact"); + parent.setVersion("1.0"); - assertNotNull(this.newModelResolver().resolveModel(parent, new AtomicReference<>())); + assertNotNull(this.newModelResolver().resolveModel(parent)); assertEquals("1.0", parent.getVersion()); } @Test void testResolveParentSuccessfullyResolvesExistingParentUsingHighestVersion() throws Exception { - final Parent parent = Parent.newBuilder() - .groupId("ut.simple") - .artifactId("artifact") - .version("(,2.0)") - .build(); + final Parent parent = new Parent(); + parent.setGroupId("ut.simple"); + parent.setArtifactId("artifact"); + parent.setVersion("(,2.0)"); - AtomicReference modified = new AtomicReference<>(); - assertNotNull(this.newModelResolver().resolveModel(parent, modified)); - assertNotNull(modified.get()); - assertEquals("1.0", modified.get().getVersion()); + assertNotNull(this.newModelResolver().resolveModel(parent)); + assertEquals("1.0", parent.getVersion()); } @Test void testResolveDependencyThrowsUnresolvableModelExceptionWhenNotFound() throws Exception { - final Dependency dependency = Dependency.newBuilder() - .groupId("ut.simple") - .artifactId("artifact") - .version("0") - .build(); + final Dependency dependency = new Dependency(); + dependency.setGroupId("ut.simple"); + dependency.setArtifactId("artifact"); + dependency.setVersion("0"); UnresolvableModelException e = assertThrows( UnresolvableModelException.class, - () -> newModelResolver().resolveModel(dependency, new AtomicReference<>()), + () -> newModelResolver().resolveModel(dependency), "Expected 'UnresolvableModelException' not thrown."); assertNotNull(e.getMessage()); assertTrue(e.getMessage().contains("Could not find artifact ut.simple:artifact:pom:0 in repo")); @@ -142,58 +133,52 @@ final class DefaultModelResolverTest extends AbstractRepositoryTestCase { @Test void testResolveDependencyThrowsUnresolvableModelExceptionWhenNoMatchingVersionFound() throws Exception { - final Dependency dependency = Dependency.newBuilder() - .groupId("ut.simple") - .artifactId("artifact") - .version("[2.0,2.1)") - .build(); + final Dependency dependency = new Dependency(); + dependency.setGroupId("ut.simple"); + dependency.setArtifactId("artifact"); + dependency.setVersion("[2.0,2.1)"); UnresolvableModelException e = assertThrows( UnresolvableModelException.class, - () -> newModelResolver().resolveModel(dependency, new AtomicReference<>()), + () -> newModelResolver().resolveModel(dependency), "Expected 'UnresolvableModelException' not thrown."); assertEquals("No versions matched the requested dependency version range '[2.0,2.1)'", e.getMessage()); } @Test void testResolveDependencyThrowsUnresolvableModelExceptionWhenUsingRangesWithoutUpperBound() throws Exception { - final Dependency dependency = Dependency.newBuilder() - .groupId("ut.simple") - .artifactId("artifact") - .version("[1.0,)") - .build(); + final Dependency dependency = new Dependency(); + dependency.setGroupId("ut.simple"); + dependency.setArtifactId("artifact"); + dependency.setVersion("[1.0,)"); UnresolvableModelException e = assertThrows( UnresolvableModelException.class, - () -> newModelResolver().resolveModel(dependency, new AtomicReference<>()), + () -> newModelResolver().resolveModel(dependency), "Expected 'UnresolvableModelException' not thrown."); assertEquals("The requested dependency version range '[1.0,)' does not specify an upper bound", e.getMessage()); } @Test void testResolveDependencySuccessfullyResolvesExistingDependencyWithoutRange() throws Exception { - final Dependency dependency = Dependency.newBuilder() - .groupId("ut.simple") - .artifactId("artifact") - .version("1.0") - .build(); + final Dependency dependency = new Dependency(); + dependency.setGroupId("ut.simple"); + dependency.setArtifactId("artifact"); + dependency.setVersion("1.0"); - assertNotNull(this.newModelResolver().resolveModel(dependency, new AtomicReference<>())); + assertNotNull(this.newModelResolver().resolveModel(dependency)); assertEquals("1.0", dependency.getVersion()); } @Test void testResolveDependencySuccessfullyResolvesExistingDependencyUsingHighestVersion() throws Exception { - final Dependency dependency = Dependency.newBuilder() - .groupId("ut.simple") - .artifactId("artifact") - .version("(,2.0)") - .build(); + final Dependency dependency = new Dependency(); + dependency.setGroupId("ut.simple"); + dependency.setArtifactId("artifact"); + dependency.setVersion("(,2.0)"); - AtomicReference modified = new AtomicReference<>(); - assertNotNull(this.newModelResolver().resolveModel(dependency, modified)); - assertNotNull(modified.get()); - assertEquals("1.0", modified.get().getVersion()); + assertNotNull(this.newModelResolver().resolveModel(dependency)); + assertEquals("1.0", dependency.getVersion()); } private ModelResolver newModelResolver() throws ComponentLookupException, MalformedURLException { diff --git a/compat/maven-settings-builder/pom.xml b/compat/maven-settings-builder/pom.xml index 1e9ec2bf81..4d510935e3 100644 --- a/compat/maven-settings-builder/pom.xml +++ b/compat/maven-settings-builder/pom.xml @@ -40,6 +40,10 @@ under the License. + + org.codehaus.plexus + plexus-interpolation + org.apache.maven maven-api-settings @@ -90,12 +94,12 @@ under the License. - org.apache.maven.settings.validation.SettingsValidator#validate(org.apache.maven.settings.Settings,boolean,org.apache.maven.settings.building.SettingsProblemCollector):METHOD_NEW_DEFAULT - org.apache.maven.settings.building.DefaultSettingsBuilder#setSettingsReader(org.apache.maven.settings.io.SettingsReader):METHOD_REMOVED - org.apache.maven.settings.building.DefaultSettingsBuilder#setSettingsValidator(org.apache.maven.settings.validation.SettingsValidator):METHOD_REMOVED - org.apache.maven.settings.building.DefaultSettingsBuilder#setSettingsWriter(org.apache.maven.settings.io.SettingsWriter):METHOD_REMOVED - org.apache.maven.settings.building.DefaultSettingsBuilder#DefaultSettingsBuilder(org.apache.maven.settings.io.SettingsReader,org.apache.maven.settings.io.SettingsWriter,org.apache.maven.settings.validation.SettingsValidator):CONSTRUCTOR_REMOVED - org.apache.maven.settings.validation.DefaultSettingsValidator#DefaultSettingsValidator():CONSTRUCTOR_REMOVED + + + + + + org.apache.maven.settings.crypto.DefaultSettingsDecrypter#DefaultSettingsDecrypter(org.sonatype.plexus.components.sec.dispatcher.SecDispatcher):CONSTRUCTOR_REMOVED diff --git a/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilder.java b/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilder.java index 29c93ee483..051b8f4472 100644 --- a/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilder.java +++ b/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilder.java @@ -24,21 +24,26 @@ import javax.inject.Singleton; import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Method; -import java.nio.file.Path; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; +import java.util.Map; -import org.apache.maven.api.Session; -import org.apache.maven.api.services.BuilderProblem; -import org.apache.maven.api.services.SettingsBuilderException; -import org.apache.maven.api.services.SettingsBuilderRequest; -import org.apache.maven.api.services.SettingsBuilderResult; -import org.apache.maven.api.services.xml.SettingsXmlFactory; import org.apache.maven.building.FileSource; import org.apache.maven.building.Source; import org.apache.maven.settings.Settings; +import org.apache.maven.settings.TrackableBase; +import org.apache.maven.settings.io.SettingsParseException; +import org.apache.maven.settings.io.SettingsReader; +import org.apache.maven.settings.io.SettingsWriter; +import org.apache.maven.settings.merge.MavenSettingsMerger; +import org.apache.maven.settings.validation.SettingsValidator; +import org.codehaus.plexus.interpolation.EnvarBasedValueSource; +import org.codehaus.plexus.interpolation.InterpolationException; +import org.codehaus.plexus.interpolation.InterpolationPostProcessor; +import org.codehaus.plexus.interpolation.PropertiesBasedValueSource; +import org.codehaus.plexus.interpolation.RegexBasedInterpolator; /** * Builds the effective settings from a user settings file and/or a global settings file. @@ -50,102 +55,200 @@ import org.apache.maven.settings.Settings; @Deprecated(since = "4.0.0") public class DefaultSettingsBuilder implements SettingsBuilder { - private final org.apache.maven.internal.impl.DefaultSettingsBuilder builder; - private final org.apache.maven.internal.impl.DefaultSettingsXmlFactory settingsXmlFactory; + private SettingsReader settingsReader; + + private SettingsWriter settingsWriter; + + private SettingsValidator settingsValidator; + + private final MavenSettingsMerger settingsMerger = new MavenSettingsMerger(); @Inject public DefaultSettingsBuilder( - org.apache.maven.internal.impl.DefaultSettingsBuilder builder, - org.apache.maven.internal.impl.DefaultSettingsXmlFactory settingsXmlFactory) { - this.builder = builder; - this.settingsXmlFactory = settingsXmlFactory; + SettingsReader settingsReader, SettingsWriter settingsWriter, SettingsValidator settingsValidator) { + this.settingsReader = settingsReader; + this.settingsWriter = settingsWriter; + this.settingsValidator = settingsValidator; + } + + public DefaultSettingsBuilder setSettingsReader(SettingsReader settingsReader) { + this.settingsReader = settingsReader; + return this; + } + + public DefaultSettingsBuilder setSettingsWriter(SettingsWriter settingsWriter) { + this.settingsWriter = settingsWriter; + return this; + } + + public DefaultSettingsBuilder setSettingsValidator(SettingsValidator settingsValidator) { + this.settingsValidator = settingsValidator; + return this; } @Override public SettingsBuildingResult build(SettingsBuildingRequest request) throws SettingsBuildingException { + DefaultSettingsProblemCollector problems = new DefaultSettingsProblemCollector(null); + + Source globalSettingsSource = + getSettingsSource(request.getGlobalSettingsFile(), request.getGlobalSettingsSource()); + Settings globalSettings = readSettings(globalSettingsSource, request, problems); + + Source userSettingsSource = getSettingsSource(request.getUserSettingsFile(), request.getUserSettingsSource()); + Settings userSettings = readSettings(userSettingsSource, request, problems); + + settingsMerger.merge(userSettings, globalSettings, TrackableBase.GLOBAL_LEVEL); + + problems.setSource(""); + + userSettings = interpolate(userSettings, request, problems); + + // for the special case of a drive-relative Windows path, make sure it's absolute to save plugins from trouble + String localRepository = userSettings.getLocalRepository(); + if (localRepository != null && localRepository.length() > 0) { + File file = new File(localRepository); + if (!file.isAbsolute() && file.getPath().startsWith(File.separator)) { + userSettings.setLocalRepository(file.getAbsolutePath()); + } + } + + if (hasErrors(problems.getProblems())) { + throw new SettingsBuildingException(problems.getProblems()); + } + + return new DefaultSettingsBuildingResult(userSettings, problems.getProblems()); + } + + private boolean hasErrors(List problems) { + if (problems != null) { + for (SettingsProblem problem : problems) { + if (SettingsProblem.Severity.ERROR.compareTo(problem.getSeverity()) >= 0) { + return true; + } + } + } + + return false; + } + + private Source getSettingsSource(File settingsFile, Source settingsSource) { + if (settingsSource != null) { + return settingsSource; + } else if (settingsFile != null && settingsFile.exists()) { + return new FileSource(settingsFile); + } + return null; + } + + private Settings readSettings( + Source settingsSource, SettingsBuildingRequest request, DefaultSettingsProblemCollector problems) { + if (settingsSource == null) { + return new Settings(); + } + + problems.setSource(settingsSource.getLocation()); + + Settings settings; try { - SettingsBuilderResult result = builder.build(SettingsBuilderRequest.builder() - .session((Session) java.lang.reflect.Proxy.newProxyInstance( - Session.class.getClassLoader(), - new Class[] {Session.class}, - (Object proxy, Method method, Object[] args) -> { - if ("getSystemProperties".equals(method.getName())) { - return request.getSystemProperties().entrySet().stream() - .collect(Collectors.toMap( - e -> e.getKey().toString(), - e -> e.getValue().toString())); - } else if ("getUserProperties".equals(method.getName())) { - return request.getUserProperties().entrySet().stream() - .collect(Collectors.toMap( - e -> e.getKey().toString(), - e -> e.getValue().toString())); - } else if ("getService".equals(method.getName())) { - if (args[0] == SettingsXmlFactory.class) { - return settingsXmlFactory; - } - } - return null; - })) - .installationSettingsSource( - toSource(request.getGlobalSettingsFile(), request.getGlobalSettingsSource())) - .projectSettingsSource( - toSource(request.getProjectSettingsFile(), request.getProjectSettingsSource())) - .userSettingsSource(toSource(request.getUserSettingsFile(), request.getUserSettingsSource())) - .build()); + Map options = Collections.singletonMap(SettingsReader.IS_STRICT, Boolean.TRUE); - return new DefaultSettingsBuildingResult( - new Settings(result.getEffectiveSettings()), - convert(result.getProblems().problems().toList())); - } catch (SettingsBuilderException e) { - throw new SettingsBuildingException( - convert(e.getProblemCollector().problems().toList())); + try { + settings = settingsReader.read(settingsSource.getInputStream(), options); + } catch (SettingsParseException e) { + options = Collections.singletonMap(SettingsReader.IS_STRICT, Boolean.FALSE); + + settings = settingsReader.read(settingsSource.getInputStream(), options); + + problems.add( + SettingsProblem.Severity.WARNING, e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e); + } + } catch (SettingsParseException e) { + problems.add( + SettingsProblem.Severity.FATAL, + "Non-parseable settings " + settingsSource.getLocation() + ": " + e.getMessage(), + e.getLineNumber(), + e.getColumnNumber(), + e); + return new Settings(); + } catch (IOException e) { + problems.add( + SettingsProblem.Severity.FATAL, + "Non-readable settings " + settingsSource.getLocation() + ": " + e.getMessage(), + -1, + -1, + e); + return new Settings(); } + + settingsValidator.validate(settings, problems); + + return settings; } - private org.apache.maven.api.services.Source toSource(File file, Source source) { - if (file != null && file.exists()) { - return org.apache.maven.api.services.Source.fromPath(file.toPath()); - } else if (source instanceof FileSource fs) { - return org.apache.maven.api.services.Source.fromPath(fs.getPath()); - } else if (source != null) { - return new org.apache.maven.api.services.Source() { - @Override - public Path getPath() { - return null; - } + private Settings interpolate( + Settings settings, SettingsBuildingRequest request, SettingsProblemCollector problems) { + StringWriter writer = new StringWriter(1024 * 4); - @Override - public InputStream openStream() throws IOException { - return source.getInputStream(); - } - - @Override - public String getLocation() { - return source.getLocation(); - } - - @Override - public org.apache.maven.api.services.Source resolve(String relative) { - return null; - } - }; - } else { - return null; + try { + settingsWriter.write(writer, null, settings); + } catch (IOException e) { + throw new IllegalStateException("Failed to serialize settings to memory", e); } - } - private List convert(List problems) { - return problems.stream().map(this::convert).toList(); - } + String serializedSettings = writer.toString(); - private SettingsProblem convert(BuilderProblem problem) { - return new DefaultSettingsProblem( - problem.getMessage(), - SettingsProblem.Severity.valueOf(problem.getSeverity().name()), - problem.getSource(), - problem.getLineNumber(), - problem.getColumnNumber(), - problem.getException()); + RegexBasedInterpolator interpolator = new RegexBasedInterpolator(); + + interpolator.addValueSource(new PropertiesBasedValueSource(request.getUserProperties())); + + interpolator.addValueSource(new PropertiesBasedValueSource(request.getSystemProperties())); + + try { + interpolator.addValueSource(new EnvarBasedValueSource()); + } catch (IOException e) { + problems.add( + SettingsProblem.Severity.WARNING, + "Failed to use environment variables for interpolation: " + e.getMessage(), + -1, + -1, + e); + } + + interpolator.addPostProcessor(new InterpolationPostProcessor() { + @Override + public Object execute(String expression, Object value) { + if (value != null) { + // we're going to parse this back in as XML so we need to escape XML markup + value = value.toString() + .replace("&", "&") + .replace("<", "<") + .replace(">", ">"); + return value; + } + return null; + } + }); + + try { + serializedSettings = interpolator.interpolate(serializedSettings, "settings"); + } catch (InterpolationException e) { + problems.add( + SettingsProblem.Severity.ERROR, "Failed to interpolate settings: " + e.getMessage(), -1, -1, e); + + return settings; + } + + Settings result; + try { + Map options = Collections.singletonMap(SettingsReader.IS_STRICT, Boolean.FALSE); + result = settingsReader.read(new StringReader(serializedSettings), options); + } catch (IOException e) { + problems.add( + SettingsProblem.Severity.ERROR, "Failed to interpolate settings: " + e.getMessage(), -1, -1, e); + return settings; + } + + return result; } } diff --git a/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactory.java b/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactory.java index 9acae5306f..b473e1b967 100644 --- a/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactory.java +++ b/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactory.java @@ -45,7 +45,7 @@ public class DefaultSettingsBuilderFactory { } protected SettingsValidator newSettingsValidator() { - return new DefaultSettingsValidator(new org.apache.maven.internal.impl.DefaultSettingsBuilder()); + return new DefaultSettingsValidator(); } /** @@ -55,7 +55,6 @@ public class DefaultSettingsBuilderFactory { */ public DefaultSettingsBuilder newInstance() { return new DefaultSettingsBuilder( - new org.apache.maven.internal.impl.DefaultSettingsBuilder(), - new org.apache.maven.internal.impl.DefaultSettingsXmlFactory()); + new DefaultSettingsReader(), new DefaultSettingsWriter(), new DefaultSettingsValidator()); } } diff --git a/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/DefaultSettingsValidator.java b/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/DefaultSettingsValidator.java index fa323a6763..8141108786 100644 --- a/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/DefaultSettingsValidator.java +++ b/compat/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/DefaultSettingsValidator.java @@ -18,15 +18,19 @@ */ package org.apache.maven.settings.validation; -import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.regex.Pattern; -import org.apache.maven.api.services.BuilderProblem; -import org.apache.maven.api.services.ProblemCollector; -import org.apache.maven.api.services.SettingsBuilder; +import org.apache.maven.settings.Mirror; +import org.apache.maven.settings.Profile; +import org.apache.maven.settings.Proxy; +import org.apache.maven.settings.Repository; +import org.apache.maven.settings.Server; import org.apache.maven.settings.Settings; import org.apache.maven.settings.building.SettingsProblem.Severity; import org.apache.maven.settings.building.SettingsProblemCollector; @@ -42,23 +46,162 @@ public class DefaultSettingsValidator implements SettingsValidator { private static final String ID = "[\\w.-]+"; private static final Pattern ID_REGEX = Pattern.compile(ID); - private final SettingsBuilder settingsBuilder; - - @Inject - public DefaultSettingsValidator(SettingsBuilder settingsBuilder) { - this.settingsBuilder = settingsBuilder; - } + private static final String ILLEGAL_REPO_ID_CHARS = "\\/:\"<>|?*"; // ILLEGAL_FS_CHARS @Override public void validate(Settings settings, SettingsProblemCollector problems) { - validate(settings, false, problems); + if (settings.isUsePluginRegistry()) { + addViolation(problems, Severity.WARNING, "usePluginRegistry", null, "is deprecated and has no effect."); + } + + List pluginGroups = settings.getPluginGroups(); + + if (pluginGroups != null) { + for (int i = 0; i < pluginGroups.size(); i++) { + String pluginGroup = pluginGroups.get(i).trim(); + + if (pluginGroup.isEmpty()) { + addViolation( + problems, Severity.ERROR, "pluginGroups.pluginGroup[" + i + "]", null, "must not be empty"); + } else if (!ID_REGEX.matcher(pluginGroup).matches()) { + addViolation( + problems, + Severity.ERROR, + "pluginGroups.pluginGroup[" + i + "]", + null, + "must denote a valid group id and match the pattern " + ID); + } + } + } + + List servers = settings.getServers(); + + if (servers != null) { + Set serverIds = new HashSet<>(); + + for (int i = 0; i < servers.size(); i++) { + Server server = servers.get(i); + + validateStringNotEmpty(problems, "servers.server[" + i + "].id", server.getId(), null); + + if (!serverIds.add(server.getId())) { + addViolation( + problems, + Severity.WARNING, + "servers.server.id", + null, + "must be unique but found duplicate server with id " + server.getId()); + } + } + } + + List mirrors = settings.getMirrors(); + + if (mirrors != null) { + for (Mirror mirror : mirrors) { + validateStringNotEmpty(problems, "mirrors.mirror.id", mirror.getId(), mirror.getUrl()); + + validateBannedCharacters( + problems, "mirrors.mirror.id", Severity.WARNING, mirror.getId(), null, ILLEGAL_REPO_ID_CHARS); + + if ("local".equals(mirror.getId())) { + addViolation( + problems, + Severity.WARNING, + "mirrors.mirror.id", + null, + "must not be 'local'" + + ", this identifier is reserved for the local repository" + + ", using it for other repositories will corrupt your repository metadata."); + } + + validateStringNotEmpty(problems, "mirrors.mirror.url", mirror.getUrl(), mirror.getId()); + + validateStringNotEmpty(problems, "mirrors.mirror.mirrorOf", mirror.getMirrorOf(), mirror.getId()); + } + } + + List profiles = settings.getProfiles(); + + if (profiles != null) { + Set profileIds = new HashSet<>(); + + for (Profile profile : profiles) { + if (!profileIds.add(profile.getId())) { + addViolation( + problems, + Severity.WARNING, + "profiles.profile.id", + null, + "must be unique but found duplicate profile with id " + profile.getId()); + } + + String prefix = "profiles.profile[" + profile.getId() + "]."; + + validateRepositories(problems, profile.getRepositories(), prefix + "repositories.repository"); + validateRepositories( + problems, profile.getPluginRepositories(), prefix + "pluginRepositories.pluginRepository"); + } + } + + List proxies = settings.getProxies(); + + if (proxies != null) { + Set proxyIds = new HashSet<>(); + + for (Proxy proxy : proxies) { + if (!proxyIds.add(proxy.getId())) { + addViolation( + problems, + Severity.WARNING, + "proxies.proxy.id", + null, + "must be unique but found duplicate proxy with id " + proxy.getId()); + } + validateStringNotEmpty(problems, "proxies.proxy.host", proxy.getHost(), proxy.getId()); + } + } } - @Override - public void validate(Settings settings, boolean isProjectSettings, SettingsProblemCollector problems) { - ProblemCollector list = settingsBuilder.validate(settings.getDelegate(), isProjectSettings); - for (BuilderProblem problem : list.problems().toList()) { - addViolation(problems, Severity.valueOf(problem.getSeverity().name()), problem.getMessage()); + private void validateRepositories(SettingsProblemCollector problems, List repositories, String prefix) { + Set repoIds = new HashSet<>(); + + for (Repository repository : repositories) { + validateStringNotEmpty(problems, prefix + ".id", repository.getId(), repository.getUrl()); + + validateBannedCharacters( + problems, prefix + ".id", Severity.WARNING, repository.getId(), null, ILLEGAL_REPO_ID_CHARS); + + if ("local".equals(repository.getId())) { + addViolation( + problems, + Severity.WARNING, + prefix + ".id", + null, + "must not be 'local'" + + ", this identifier is reserved for the local repository" + + ", using it for other repositories will corrupt your repository metadata."); + } + + if (!repoIds.add(repository.getId())) { + addViolation( + problems, + Severity.WARNING, + prefix + ".id", + null, + "must be unique but found duplicate repository with id " + repository.getId()); + } + + validateStringNotEmpty(problems, prefix + ".url", repository.getUrl(), repository.getId()); + + if ("legacy".equals(repository.getLayout())) { + addViolation( + problems, + Severity.WARNING, + prefix + ".layout", + repository.getId(), + "uses the unsupported value 'legacy', artifact resolution might fail."); + } } } @@ -66,7 +209,82 @@ public class DefaultSettingsValidator implements SettingsValidator { // Field validation // ---------------------------------------------------------------------- - private static void addViolation(SettingsProblemCollector problems, Severity severity, String message) { - problems.add(severity, message, -1, -1, null); + /** + * Asserts: + *

+ *

    + *
  • string.length != null + *
  • string.length > 0 + *
+ */ + private static boolean validateStringNotEmpty( + SettingsProblemCollector problems, String fieldName, String string, String sourceHint) { + if (!validateNotNull(problems, fieldName, string, sourceHint)) { + return false; + } + + if (string.length() > 0) { + return true; + } + + addViolation(problems, Severity.ERROR, fieldName, sourceHint, "is missing"); + + return false; + } + + /** + * Asserts: + *

+ *

    + *
  • string != null + *
+ */ + private static boolean validateNotNull( + SettingsProblemCollector problems, String fieldName, Object object, String sourceHint) { + if (object != null) { + return true; + } + + addViolation(problems, Severity.ERROR, fieldName, sourceHint, "is missing"); + + return false; + } + + private static boolean validateBannedCharacters( + SettingsProblemCollector problems, + String fieldName, + Severity severity, + String string, + String sourceHint, + String banned) { + if (string != null) { + for (int i = string.length() - 1; i >= 0; i--) { + if (banned.indexOf(string.charAt(i)) >= 0) { + addViolation( + problems, + severity, + fieldName, + sourceHint, + "must not contain any of these characters " + banned + " but found " + string.charAt(i)); + return false; + } + } + } + + return true; + } + + private static void addViolation( + SettingsProblemCollector problems, Severity severity, String fieldName, String sourceHint, String message) { + StringBuilder buffer = new StringBuilder(256); + buffer.append('\'').append(fieldName).append('\''); + + if (sourceHint != null) { + buffer.append(" for ").append(sourceHint); + } + + buffer.append(' ').append(message); + + problems.add(severity, buffer.toString(), -1, -1, null); } } diff --git a/compat/maven-settings-builder/src/test/java/org/apache/maven/settings/validation/DefaultSettingsValidatorTest.java b/compat/maven-settings-builder/src/test/java/org/apache/maven/settings/validation/DefaultSettingsValidatorTest.java index 31219e345b..c92b4afecb 100644 --- a/compat/maven-settings-builder/src/test/java/org/apache/maven/settings/validation/DefaultSettingsValidatorTest.java +++ b/compat/maven-settings-builder/src/test/java/org/apache/maven/settings/validation/DefaultSettingsValidatorTest.java @@ -21,7 +21,6 @@ package org.apache.maven.settings.validation; import java.util.ArrayList; import java.util.List; -import org.apache.maven.internal.impl.DefaultSettingsBuilder; import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Profile; import org.apache.maven.settings.Proxy; @@ -45,7 +44,7 @@ class DefaultSettingsValidatorTest { @BeforeEach void setUp() throws Exception { - validator = new DefaultSettingsValidator(new DefaultSettingsBuilder()); + validator = new DefaultSettingsValidator(); } @AfterEach @@ -99,10 +98,9 @@ class DefaultSettingsValidatorTest { SimpleProblemCollector problems = new SimpleProblemCollector(); validator.validate(settings, problems); assertEquals(4, problems.messages.size()); - // errors are now by severity descending - assertContains(problems.messages.get(0), "'mirrors.mirror.url' for local is missing"); - assertContains(problems.messages.get(1), "'mirrors.mirror.mirrorOf' for local is missing"); - assertContains(problems.messages.get(2), "'mirrors.mirror.id' must not be 'local'"); + assertContains(problems.messages.get(0), "'mirrors.mirror.id' must not be 'local'"); + assertContains(problems.messages.get(1), "'mirrors.mirror.url' for local is missing"); + assertContains(problems.messages.get(2), "'mirrors.mirror.mirrorOf' for local is missing"); assertContains(problems.messages.get(3), "'mirrors.mirror.id' must not contain any of these characters"); } @@ -122,12 +120,11 @@ class DefaultSettingsValidatorTest { SimpleProblemCollector problems = new SimpleProblemCollector(); validator.validate(settings, problems); assertEquals(3, problems.messages.size()); - // errors are now by severity descending assertContains( - problems.messages.get(0), + problems.messages.get(0), "'profiles.profile[default].repositories.repository.id' must not be 'local'"); + assertContains( + problems.messages.get(1), "'profiles.profile[default].repositories.repository.url' for local is missing"); - assertContains( - problems.messages.get(1), "'profiles.profile[default].repositories.repository.id' must not be 'local'"); assertContains( problems.messages.get(2), "'profiles.profile[default].repositories.repository.id' must not contain any of these characters"); diff --git a/compat/maven-settings/pom.xml b/compat/maven-settings/pom.xml index 4d43e9fe7a..0386d7a807 100644 --- a/compat/maven-settings/pom.xml +++ b/compat/maven-settings/pom.xml @@ -129,8 +129,7 @@ under the License. org.apache.maven.settings.io.xpp3.SettingsXpp3Reader#contentTransformer - org.apache.maven.settings.RuntimeInfo - org.apache.maven.settings.Settings#setModelEncoding(java.lang.String):METHOD_REMOVED + org.apache.maven.settings.io.xpp3.SettingsXpp3Reader#read(org.codehaus.plexus.util.xml.pull.XmlPullParser,boolean):METHOD_REMOVED
diff --git a/compat/maven-settings/src/main/java/org/apache/maven/settings/RuntimeInfo.java b/compat/maven-settings/src/main/java/org/apache/maven/settings/RuntimeInfo.java new file mode 100644 index 0000000000..91cd3960e7 --- /dev/null +++ b/compat/maven-settings/src/main/java/org/apache/maven/settings/RuntimeInfo.java @@ -0,0 +1,50 @@ +/* + * 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.settings; + +import java.io.File; + +/** + * To handle runtime informations like local repository or profiles. + * + */ +@Deprecated +public class RuntimeInfo { + @SuppressWarnings("checkstyle:constantname") + public static final String userHome = System.getProperty("user.home"); + + @SuppressWarnings("checkstyle:constantname") + public static final File userMavenConfigurationHome = new File(userHome, ".m2"); + + public static final File DEFAULT_USER_SETTINGS_FILE = new File(userMavenConfigurationHome, "settings.xml"); + + private File settings; + + public RuntimeInfo() { + this.settings = DEFAULT_USER_SETTINGS_FILE; + } + + public RuntimeInfo(File settings) { + this.settings = settings; + } + + public File getFile() { + return settings; + } +} diff --git a/compat/maven-toolchain-builder/pom.xml b/compat/maven-toolchain-builder/pom.xml index 4b5d4a7ecc..62e13aecea 100644 --- a/compat/maven-toolchain-builder/pom.xml +++ b/compat/maven-toolchain-builder/pom.xml @@ -53,6 +53,10 @@ under the License. org.apache.maven maven-builder-support
+ + org.codehaus.plexus + plexus-xml + org.codehaus.plexus plexus-interpolation @@ -63,11 +67,6 @@ under the License. provided - - org.codehaus.plexus - plexus-xml - test - org.junit.jupiter junit-jupiter-api @@ -103,9 +102,9 @@ under the License. org.apache.maven.toolchain.merge - org.apache.maven.toolchain.building.DefaultToolchainsBuilder#DefaultToolchainsBuilder():CONSTRUCTOR_REMOVED - org.apache.maven.toolchain.merge.MavenToolchainMerger#getToolchainModelKey(org.apache.maven.toolchain.model.ToolchainModel):METHOD_REMOVED - org.apache.maven.toolchain.merge.MavenToolchainMerger#mergeToolchainModelConfiguration(org.apache.maven.toolchain.model.ToolchainModel,org.apache.maven.toolchain.model.ToolchainModel):METHOD_REMOVED + + +
diff --git a/compat/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilder.java b/compat/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilder.java index 52471e96ee..114fc37d37 100644 --- a/compat/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilder.java +++ b/compat/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilder.java @@ -23,27 +23,26 @@ import javax.inject.Named; import javax.inject.Singleton; import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Method; -import java.nio.file.Path; -import java.util.HashMap; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Properties; -import org.apache.maven.api.Session; -import org.apache.maven.api.services.BuilderProblem; -import org.apache.maven.api.services.Source; -import org.apache.maven.api.services.ToolchainsBuilderException; -import org.apache.maven.api.services.ToolchainsBuilderRequest; -import org.apache.maven.api.services.ToolchainsBuilderResult; -import org.apache.maven.api.services.xml.ToolchainsXmlFactory; -import org.apache.maven.building.FileSource; import org.apache.maven.building.Problem; import org.apache.maven.building.ProblemCollector; import org.apache.maven.building.ProblemCollectorFactory; +import org.apache.maven.building.Source; +import org.apache.maven.toolchain.io.ToolchainsParseException; +import org.apache.maven.toolchain.io.ToolchainsReader; +import org.apache.maven.toolchain.io.ToolchainsWriter; +import org.apache.maven.toolchain.merge.MavenToolchainMerger; import org.apache.maven.toolchain.model.PersistedToolchains; -import org.codehaus.plexus.interpolation.os.OperatingSystemUtils; +import org.apache.maven.toolchain.model.TrackableBase; +import org.codehaus.plexus.interpolation.EnvarBasedValueSource; +import org.codehaus.plexus.interpolation.InterpolationException; +import org.codehaus.plexus.interpolation.InterpolationPostProcessor; +import org.codehaus.plexus.interpolation.RegexBasedInterpolator; /** * @@ -54,90 +53,144 @@ import org.codehaus.plexus.interpolation.os.OperatingSystemUtils; @Singleton @Deprecated(since = "4.0.0") public class DefaultToolchainsBuilder implements ToolchainsBuilder { - private final org.apache.maven.api.services.ToolchainsBuilder builder; - private final ToolchainsXmlFactory toolchainsXmlFactory; + private MavenToolchainMerger toolchainsMerger = new MavenToolchainMerger(); @Inject - public DefaultToolchainsBuilder( - org.apache.maven.api.services.ToolchainsBuilder builder, ToolchainsXmlFactory toolchainsXmlFactory) { - this.builder = builder; - this.toolchainsXmlFactory = toolchainsXmlFactory; - } + private ToolchainsWriter toolchainsWriter; + + @Inject + private ToolchainsReader toolchainsReader; @Override public ToolchainsBuildingResult build(ToolchainsBuildingRequest request) throws ToolchainsBuildingException { + ProblemCollector problems = ProblemCollectorFactory.newInstance(null); + + PersistedToolchains globalToolchains = readToolchains(request.getGlobalToolchainsSource(), request, problems); + + PersistedToolchains userToolchains = readToolchains(request.getUserToolchainsSource(), request, problems); + + toolchainsMerger.merge(userToolchains, globalToolchains, TrackableBase.GLOBAL_LEVEL); + + problems.setSource(""); + + userToolchains = interpolate(userToolchains, problems); + + if (hasErrors(problems.getProblems())) { + throw new ToolchainsBuildingException(problems.getProblems()); + } + + return new DefaultToolchainsBuildingResult(userToolchains, problems.getProblems()); + } + + private PersistedToolchains interpolate(PersistedToolchains toolchains, ProblemCollector problems) { + + StringWriter stringWriter = new StringWriter(1024 * 4); try { - ToolchainsBuilderResult result = builder.build(ToolchainsBuilderRequest.builder() - .session((Session) java.lang.reflect.Proxy.newProxyInstance( - Session.class.getClassLoader(), - new Class[] {Session.class}, - (Object proxy, Method method, Object[] args) -> { - if ("getSystemProperties".equals(method.getName())) { - Map properties = new HashMap<>(); - Properties env = OperatingSystemUtils.getSystemEnvVars(); - env.stringPropertyNames() - .forEach(k -> properties.put("env." + k, env.getProperty(k))); - return properties; - } else if ("getUserProperties".equals(method.getName())) { - return Map.of(); - } else if ("getService".equals(method.getName())) { - if (args[0] == ToolchainsXmlFactory.class) { - return toolchainsXmlFactory; - } - } - return null; - })) - .installationToolchainsSource(convert(request.getGlobalToolchainsSource())) - .userToolchainsSource(convert(request.getUserToolchainsSource())) - .build()); - - return new DefaultToolchainsBuildingResult( - new PersistedToolchains(result.getEffectiveToolchains()), - convert(result.getProblems().problems().toList())); - } catch (ToolchainsBuilderException e) { - throw new ToolchainsBuildingException( - convert(e.getProblemCollector().problems().toList())); + toolchainsWriter.write(stringWriter, null, toolchains); + } catch (IOException e) { + throw new IllegalStateException("Failed to serialize toolchains to memory", e); } + + String serializedToolchains = stringWriter.toString(); + + RegexBasedInterpolator interpolator = new RegexBasedInterpolator(); + + try { + interpolator.addValueSource(new EnvarBasedValueSource()); + } catch (IOException e) { + problems.add( + Problem.Severity.WARNING, + "Failed to use environment variables for interpolation: " + e.getMessage(), + -1, + -1, + e); + } + + interpolator.addPostProcessor(new InterpolationPostProcessor() { + @Override + public Object execute(String expression, Object value) { + if (value != null) { + // we're going to parse this back in as XML so we need to escape XML markup + value = value.toString() + .replace("&", "&") + .replace("<", "<") + .replace(">", ">"); + return value; + } + return null; + } + }); + + try { + serializedToolchains = interpolator.interpolate(serializedToolchains); + } catch (InterpolationException e) { + problems.add(Problem.Severity.ERROR, "Failed to interpolate toolchains: " + e.getMessage(), -1, -1, e); + return toolchains; + } + + PersistedToolchains result; + try { + Map options = Collections.singletonMap(ToolchainsReader.IS_STRICT, Boolean.FALSE); + + result = toolchainsReader.read(new StringReader(serializedToolchains), options); + } catch (IOException e) { + problems.add(Problem.Severity.ERROR, "Failed to interpolate toolchains: " + e.getMessage(), -1, -1, e); + return toolchains; + } + + return result; } - private Source convert(org.apache.maven.building.Source source) { - if (source instanceof FileSource fs) { - return Source.fromPath(fs.getPath()); - } else if (source != null) { - return new Source() { - @Override - public Path getPath() { - return null; - } - - @Override - public InputStream openStream() throws IOException { - return source.getInputStream(); - } - - @Override - public String getLocation() { - return source.getLocation(); - } - - @Override - public Source resolve(String relative) { - return null; - } - }; - } else { - return null; + private PersistedToolchains readToolchains( + Source toolchainsSource, ToolchainsBuildingRequest request, ProblemCollector problems) { + if (toolchainsSource == null) { + return new PersistedToolchains(); } + + PersistedToolchains toolchains; + + try { + Map options = Collections.singletonMap(ToolchainsReader.IS_STRICT, Boolean.TRUE); + + try { + toolchains = toolchainsReader.read(toolchainsSource.getInputStream(), options); + } catch (ToolchainsParseException e) { + options = Collections.singletonMap(ToolchainsReader.IS_STRICT, Boolean.FALSE); + + toolchains = toolchainsReader.read(toolchainsSource.getInputStream(), options); + + problems.add(Problem.Severity.WARNING, e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e); + } + } catch (ToolchainsParseException e) { + problems.add( + Problem.Severity.FATAL, + "Non-parseable toolchains " + toolchainsSource.getLocation() + ": " + e.getMessage(), + e.getLineNumber(), + e.getColumnNumber(), + e); + return new PersistedToolchains(); + } catch (IOException e) { + problems.add( + Problem.Severity.FATAL, + "Non-readable toolchains " + toolchainsSource.getLocation() + ": " + e.getMessage(), + -1, + -1, + e); + return new PersistedToolchains(); + } + + return toolchains; } - private List convert(List problems) { - ProblemCollector collector = ProblemCollectorFactory.newInstance(null); - problems.forEach(p -> collector.add( - Problem.Severity.valueOf(p.getSeverity().name()), - p.getMessage(), - p.getLineNumber(), - p.getColumnNumber(), - p.getException())); - return collector.getProblems(); + private boolean hasErrors(List problems) { + if (problems != null) { + for (Problem problem : problems) { + if (Problem.Severity.ERROR.compareTo(problem.getSeverity()) >= 0) { + return true; + } + } + } + + return false; } } diff --git a/compat/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/merge/MavenToolchainMerger.java b/compat/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/merge/MavenToolchainMerger.java index 7a21b9b0c6..6f895bdc55 100644 --- a/compat/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/merge/MavenToolchainMerger.java +++ b/compat/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/merge/MavenToolchainMerger.java @@ -18,7 +18,13 @@ */ package org.apache.maven.toolchain.merge; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + import org.apache.maven.toolchain.model.PersistedToolchains; +import org.apache.maven.toolchain.model.ToolchainModel; +import org.codehaus.plexus.util.xml.Xpp3Dom; /** * @@ -35,7 +41,46 @@ public class MavenToolchainMerger { recessive.setSourceLevel(recessiveSourceLevel); - dominant.update(new org.apache.maven.toolchain.v4.MavenToolchainsMerger() - .merge(dominant.getDelegate(), recessive.getDelegate(), true, null)); + shallowMerge(dominant.getToolchains(), recessive.getToolchains(), recessiveSourceLevel); + } + + private void shallowMerge( + List dominant, List recessive, String recessiveSourceLevel) { + Map merged = new LinkedHashMap<>(); + + for (ToolchainModel dominantModel : dominant) { + Object key = getToolchainModelKey(dominantModel); + + merged.put(key, dominantModel); + } + + for (ToolchainModel recessiveModel : recessive) { + Object key = getToolchainModelKey(recessiveModel); + + ToolchainModel dominantModel = merged.get(key); + if (dominantModel == null) { + recessiveModel.setSourceLevel(recessiveSourceLevel); + dominant.add(recessiveModel); + } else { + mergeToolchainModelConfiguration(dominantModel, recessiveModel); + } + } + } + + protected void mergeToolchainModelConfiguration(ToolchainModel target, ToolchainModel source) { + Xpp3Dom src = (Xpp3Dom) source.getConfiguration(); + if (src != null) { + Xpp3Dom tgt = (Xpp3Dom) target.getConfiguration(); + if (tgt == null) { + tgt = Xpp3Dom.mergeXpp3Dom(new Xpp3Dom(src), tgt); + } else { + tgt = Xpp3Dom.mergeXpp3Dom(tgt, src); + } + target.setConfiguration(tgt); + } + } + + protected Object getToolchainModelKey(ToolchainModel model) { + return model; } } diff --git a/compat/maven-toolchain-builder/src/test/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilderTest.java b/compat/maven-toolchain-builder/src/test/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilderTest.java index a41e49a1e4..76d10e9051 100644 --- a/compat/maven-toolchain-builder/src/test/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilderTest.java +++ b/compat/maven-toolchain-builder/src/test/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilderTest.java @@ -18,21 +18,19 @@ */ package org.apache.maven.toolchain.building; -import javax.xml.stream.Location; -import javax.xml.stream.XMLStreamException; - import java.io.IOException; +import java.io.InputStream; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Properties; -import org.apache.maven.api.services.xml.XmlReaderException; -import org.apache.maven.api.services.xml.XmlReaderRequest; import org.apache.maven.building.Source; import org.apache.maven.building.StringSource; import org.apache.maven.internal.impl.DefaultToolchainsXmlFactory; -import org.apache.maven.internal.impl.model.DefaultInterpolator; +import org.apache.maven.toolchain.io.DefaultToolchainsReader; +import org.apache.maven.toolchain.io.DefaultToolchainsWriter; +import org.apache.maven.toolchain.io.ToolchainsParseException; import org.apache.maven.toolchain.model.PersistedToolchains; import org.apache.maven.toolchain.model.ToolchainModel; import org.codehaus.plexus.interpolation.os.OperatingSystemUtils; @@ -40,25 +38,27 @@ import org.codehaus.plexus.util.xml.Xpp3Dom; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentMatchers; import org.mockito.InjectMocks; import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; -import static org.apache.maven.internal.impl.StaxLocation.getLocation; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class DefaultToolchainsBuilderTest { private static final String LS = System.lineSeparator(); @Spy - private DefaultToolchainsXmlFactory toolchainsXmlFactory; + private DefaultToolchainsReader toolchainsReader; + + @Spy + private DefaultToolchainsWriter toolchainsWriter; @InjectMocks private DefaultToolchainsBuilder toolchainBuilder; @@ -71,11 +71,6 @@ class DefaultToolchainsBuilderTest { envVarMap.put("testKey", "testValue"); envVarMap.put("testSpecialCharactersKey", ""); OperatingSystemUtils.setEnvVarSource(new TestEnvVarSource(envVarMap)); - - toolchainBuilder = new DefaultToolchainsBuilder( - new org.apache.maven.internal.impl.DefaultToolchainsBuilder( - new DefaultInterpolator(), toolchainsXmlFactory), - toolchainsXmlFactory); } @Test @@ -198,15 +193,12 @@ class DefaultToolchainsBuilderTest { @Test void testStrictToolchainsParseException() throws Exception { - Location loc = mock(Location.class); - when(loc.getLineNumber()).thenReturn(4); - when(loc.getColumnNumber()).thenReturn(2); - XMLStreamException parseException = new XMLStreamException("MESSAGE", loc); - doThrow(new XmlReaderException("MESSAGE", getLocation(parseException), parseException)) - .when(toolchainsXmlFactory) - .read(any(XmlReaderRequest.class)); ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest(); request.setGlobalToolchainsSource(new StringSource("")); + ToolchainsParseException parseException = new ToolchainsParseException("MESSAGE", 4, 2); + doThrow(parseException) + .when(toolchainsReader) + .read(any(InputStream.class), ArgumentMatchers.anyMap()); try { toolchainBuilder.build(request); diff --git a/compat/maven-toolchain-model/pom.xml b/compat/maven-toolchain-model/pom.xml index f5bca964ba..a08ff1a404 100644 --- a/compat/maven-toolchain-model/pom.xml +++ b/compat/maven-toolchain-model/pom.xml @@ -49,6 +49,14 @@ under the License. org.codehaus.plexus plexus-xml
+ + org.apache.maven + maven-impl + + + org.apache.maven + maven-xml + @@ -93,7 +101,7 @@ under the License. org.apache.maven.toolchain.model - org.apache.maven.toolchain.model.PersistedToolchains#setModelEncoding(java.lang.String):METHOD_REMOVED + true diff --git a/impl/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java b/impl/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java index ff52d0b0c0..29e1379a80 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java +++ b/impl/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java @@ -28,15 +28,14 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; -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.lifecycle.LifeCyclePluginAnalyzer; +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.ModelProblem.Severity; import org.apache.maven.model.building.ModelProblem.Version; @@ -61,25 +60,21 @@ public class DefaultLifecycleBindingsInjector implements LifecycleBindingsInject this.lifecycle = lifecycle; } - public void injectLifecycleBindings( - org.apache.maven.model.Model model, ModelBuildingRequest request, ModelProblemCollector problems) { + public void injectLifecycleBindings(Model model, ModelBuildingRequest request, ModelProblemCollector problems) { String packaging = model.getPackaging(); - Collection defaultPlugins = - lifecycle.getPluginsBoundByDefaultToAllLifecycles(packaging); + Collection defaultPlugins = lifecycle.getPluginsBoundByDefaultToAllLifecycles(packaging); if (defaultPlugins == null) { problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE) .setMessage("Unknown packaging: " + packaging) .setLocation(model.getLocation("packaging"))); } else if (!defaultPlugins.isEmpty()) { - List plugins = defaultPlugins.stream() - .map(org.apache.maven.model.Plugin::getDelegate) - .collect(Collectors.toList()); - Model lifecycleModel = Model.newBuilder() - .build(Build.newBuilder().plugins(plugins).build()) - .build(); - model.update(merger.merge(model.getDelegate(), lifecycleModel)); + Model lifecycleModel = new Model(); + lifecycleModel.setBuild(new Build()); + lifecycleModel.getBuild().getPlugins().addAll(defaultPlugins); + + merger.merge(model, lifecycleModel); } } @@ -90,29 +85,21 @@ public class DefaultLifecycleBindingsInjector implements LifecycleBindingsInject private static final String PLUGIN_MANAGEMENT = "plugin-management"; - public Model merge(Model target, Model source) { - Build targetBuild = target.getBuild(); - if (targetBuild == null) { - targetBuild = Build.newInstance(); + public void merge(Model target, Model source) { + if (target.getBuild() == null) { + target.setBuild(new Build()); } - Map context = - Collections.singletonMap(PLUGIN_MANAGEMENT, targetBuild.getPluginManagement()); + Map context = Collections.singletonMap( + PLUGIN_MANAGEMENT, target.getBuild().getPluginManagement()); - Build.Builder builder = Build.newBuilder(targetBuild); - mergePluginContainer_Plugins(builder, targetBuild, source.getBuild(), false, context); - - return target.withBuild(builder.build()); + mergePluginContainer_Plugins(target.getBuild(), source.getBuild(), false, context); } @SuppressWarnings({"checkstyle:methodname"}) @Override protected void mergePluginContainer_Plugins( - PluginContainer.Builder builder, - PluginContainer target, - PluginContainer source, - boolean sourceDominant, - Map context) { + PluginContainer target, PluginContainer source, boolean sourceDominant, Map context) { List src = source.getPlugins(); if (!src.isEmpty()) { List tgt = target.getPlugins(); @@ -120,32 +107,32 @@ public class DefaultLifecycleBindingsInjector implements LifecycleBindingsInject Map merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2); for (Plugin element : tgt) { - Object key = getPluginKey().apply(element); + Object key = getPluginKey(element); merged.put(key, element); } Map added = new LinkedHashMap<>(); for (Plugin element : src) { - Object key = getPluginKey().apply(element); + Object key = getPluginKey(element); Plugin existing = merged.get(key); if (existing != null) { - element = mergePlugin(existing, element, sourceDominant, context); + mergePlugin(existing, element, sourceDominant, context); } else { + merged.put(key, element); added.put(key, element); } - merged.put(key, element); } if (!added.isEmpty()) { PluginManagement pluginMgmt = (PluginManagement) context.get(PLUGIN_MANAGEMENT); if (pluginMgmt != null) { for (Plugin managedPlugin : pluginMgmt.getPlugins()) { - Object key = getPluginKey().apply(managedPlugin); + Object key = getPluginKey(managedPlugin); Plugin addedPlugin = added.get(key); if (addedPlugin != null) { - Plugin plugin = - mergePlugin(managedPlugin, addedPlugin, sourceDominant, Collections.emptyMap()); + Plugin plugin = managedPlugin.clone(); + mergePlugin(plugin, addedPlugin, sourceDominant, Collections.emptyMap()); merged.put(key, plugin); } } @@ -154,23 +141,16 @@ public class DefaultLifecycleBindingsInjector implements LifecycleBindingsInject List result = new ArrayList<>(merged.values()); - builder.plugins(result); + target.setPlugins(result); } } @Override - protected void mergePluginExecution_Priority( - PluginExecution.Builder builder, - PluginExecution target, - PluginExecution source, - boolean sourceDominant, - Map context) { - if (target.getPriority() > source.getPriority()) { - builder.priority(source.getPriority()); - builder.location("priority", source.getLocation("priority")); - } - } - // mergePluginExecution_Priority( builder, target, source, sourceDominant, context ); + protected void mergePluginExecution( + PluginExecution target, PluginExecution source, boolean sourceDominant, Map context) { + super.mergePluginExecution(target, source, sourceDominant, context); + target.setPriority(Math.min(target.getPriority(), source.getPriority())); + } } } diff --git a/impl/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java b/impl/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java index 0761273ffc..2f39f226a1 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java +++ b/impl/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java @@ -55,8 +55,15 @@ public interface PluginDescriptorCache { PluginDescriptor get(Key key); - PluginDescriptor get(Key key, PluginDescriptorSupplier supplier) - throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException; + default PluginDescriptor get(Key key, PluginDescriptorSupplier supplier) + throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException { + PluginDescriptor pd = get(key); + if (pd == null) { + pd = supplier.load(); + put(key, pd); + } + return pd; + } void flush(); } diff --git a/impl/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java b/impl/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java index 2c73a00b07..7fcbd87949 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java +++ b/impl/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java @@ -80,7 +80,15 @@ public interface PluginRealmCache { CacheRecord get(Key key); - CacheRecord get(Key key, PluginRealmSupplier supplier) throws PluginResolutionException, PluginContainerException; + default CacheRecord get(Key key, PluginRealmSupplier supplier) + throws PluginResolutionException, PluginContainerException { + CacheRecord cr = get(key); + if (cr == null) { + CacheRecord tcr = supplier.load(); + cr = put(key, tcr.getRealm(), tcr.getArtifacts()); + } + return cr; + } CacheRecord put(Key key, ClassRealm pluginRealm, List pluginArtifacts); diff --git a/impl/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java b/impl/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java index 583a2294be..e2d43f0dbc 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java +++ b/impl/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java @@ -79,7 +79,6 @@ import org.apache.maven.model.building.DefaultModelProblem; import org.apache.maven.model.building.FileModelSource; import org.apache.maven.model.building.ModelBuildingRequest; import org.apache.maven.model.building.ModelSource2; -import org.apache.maven.model.building.ModelSource3; import org.apache.maven.model.root.RootLocator; import org.apache.maven.plugin.PluginManagerException; import org.apache.maven.plugin.PluginResolutionException; @@ -247,26 +246,6 @@ public class DefaultProjectBuilder implements ProjectBuilder { @Override public ModelSource resolve(ModelLocator modelLocator, String relative) { - if (modelSource instanceof ModelSource3 ms) { - return toSource(ms.getRelatedSource( - new org.apache.maven.model.locator.ModelLocator() { - @Override - public File locatePom(File projectDirectory) { - return null; - } - - @Override - public Path locatePom(Path projectDirectory) { - return null; - } - - @Override - public Path locateExistingPom(Path project) { - return modelLocator.locateExistingPom(project); - } - }, - relative)); - } return null; } diff --git a/impl/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java b/impl/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java index 756d80b7f1..7de2e9c7c1 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java +++ b/impl/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java @@ -18,25 +18,18 @@ */ package org.apache.maven.project; +import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ForkJoinPool; -import java.util.concurrent.ForkJoinTask; -import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicReference; -import org.apache.maven.api.model.Dependency; -import org.apache.maven.api.model.Model; -import org.apache.maven.api.model.Parent; -import org.apache.maven.api.model.Repository; import org.apache.maven.internal.impl.resolver.ArtifactDescriptorUtils; -import org.apache.maven.model.building.ArtifactModelSource; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Parent; +import org.apache.maven.model.Repository; import org.apache.maven.model.building.FileModelSource; import org.apache.maven.model.building.ModelSource; import org.apache.maven.model.resolution.InvalidRepositoryException; @@ -58,12 +51,9 @@ import org.eclipse.aether.resolution.VersionRangeResult; /** * A model resolver to assist building of projects. This resolver gives priority to those repositories that have been * declared in the POM. - * */ public class ProjectModelResolver implements ModelResolver { - private static final int MAX_CAP = 0x7fff; - private final RepositorySystemSession session; private final RequestTrace trace; @@ -86,9 +76,6 @@ public class ProjectModelResolver implements ModelResolver { private final ProjectBuildingRequest.RepositoryMerging repositoryMerging; - private final Map> parentCache; - - @SuppressWarnings("checkstyle:ParameterNumber") public ProjectModelResolver( RepositorySystemSession session, RequestTrace trace, @@ -96,8 +83,7 @@ public class ProjectModelResolver implements ModelResolver { RemoteRepositoryManager remoteRepositoryManager, List repositories, ProjectBuildingRequest.RepositoryMerging repositoryMerging, - ReactorModelPool modelPool, - Map parentCache) { + ReactorModelPool modelPool) { this.session = session; this.trace = trace; this.resolver = resolver; @@ -109,7 +95,6 @@ public class ProjectModelResolver implements ModelResolver { this.repositoryMerging = repositoryMerging; this.repositoryIds = new HashSet<>(); this.modelPool = modelPool; - this.parentCache = parentCache != null ? (Map) parentCache : new ConcurrentHashMap<>(); } private ProjectModelResolver(ProjectModelResolver original) { @@ -123,7 +108,6 @@ public class ProjectModelResolver implements ModelResolver { this.repositoryMerging = original.repositoryMerging; this.repositoryIds = new HashSet<>(original.repositoryIds); this.modelPool = original.modelPool; - this.parentCache = original.parentCache; } public void addRepository(Repository repository) throws InvalidRepositoryException { @@ -143,7 +127,7 @@ public class ProjectModelResolver implements ModelResolver { } List newRepositories = - Collections.singletonList(ArtifactDescriptorUtils.toRemoteRepository(repository)); + Collections.singletonList(ArtifactDescriptorUtils.toRemoteRepository(repository.getDelegate())); if (ProjectBuildingRequest.RepositoryMerging.REQUEST_DOMINANT.equals(repositoryMerging)) { repositories = remoteRepositoryManager.aggregateRepositories(session, repositories, newRepositories, true); @@ -156,9 +140,9 @@ public class ProjectModelResolver implements ModelResolver { } private static void removeMatchingRepository(Iterable repositories, final String id) { - Iterator iterator = repositories.iterator(); + Iterator iterator = repositories.iterator(); while (iterator.hasNext()) { - RemoteRepository next = iterator.next(); + RemoteRepository next = (RemoteRepository) iterator.next(); if (next.getId().equals(id)) { iterator.remove(); } @@ -171,79 +155,31 @@ public class ProjectModelResolver implements ModelResolver { public ModelSource resolveModel(String groupId, String artifactId, String version) throws UnresolvableModelException { - Artifact pomArtifact = new DefaultArtifact(groupId, artifactId, "", "pom", version); + File pomFile = null; - try { - ArtifactRequest request = new ArtifactRequest(pomArtifact, repositories, context); - request.setTrace(trace); - pomArtifact = resolver.resolveArtifact(session, request).getArtifact(); - } catch (ArtifactResolutionException e) { - throw new UnresolvableModelException(e.getMessage(), groupId, artifactId, version, e); + if (modelPool != null) { + pomFile = modelPool.get(groupId, artifactId, version); } - return new ArtifactModelSource(pomArtifact.getFile(), groupId, artifactId, version); - } + if (pomFile == null) { + Artifact pomArtifact = new DefaultArtifact(groupId, artifactId, "", "pom", version); - record Result(ModelSource source, Parent parent, Exception e) {} + try { + ArtifactRequest request = new ArtifactRequest(pomArtifact, repositories, context); + request.setTrace(trace); + pomArtifact = resolver.resolveArtifact(session, request).getArtifact(); + } catch (ArtifactResolutionException e) { + throw new UnresolvableModelException(e.getMessage(), groupId, artifactId, version, e); + } + + pomFile = pomArtifact.getFile(); + } + + return new FileModelSource(pomFile); + } @Override - public ModelSource resolveModel(final Parent parent, AtomicReference modified) - throws UnresolvableModelException { - Result result; - try { - Future future = parentCache.computeIfAbsent(parent.getId(), id -> { - ForkJoinPool pool = new ForkJoinPool(MAX_CAP); - ForkJoinTask task = new ForkJoinTask<>() { - Result result; - - @Override - public Result getRawResult() { - return result; - } - - @Override - protected void setRawResult(Result result) { - this.result = result; - } - - @Override - protected boolean exec() { - try { - AtomicReference modified = new AtomicReference<>(); - ModelSource source = doResolveModel(parent, modified); - result = new Result(source, modified.get(), null); - } catch (Exception e) { - result = new Result(null, null, e); - } finally { - pool.shutdown(); - } - return true; - } - }; - pool.submit(task); - return task; - }); - result = future.get(); - } catch (Exception e) { - throw new UnresolvableModelException(e, parent.getGroupId(), parent.getArtifactId(), parent.getVersion()); - } - if (result.e != null) { - uncheckedThrow(result.e); - return null; - } else { - if (result.parent != null && modified != null) { - modified.set(result.parent); - } - return result.source; - } - } - - static void uncheckedThrow(Throwable t) throws T { - throw (T) t; // rely on vacuous cast - } - - private ModelSource doResolveModel(Parent parent, AtomicReference modified) - throws UnresolvableModelException { + public ModelSource resolveModel(final Parent parent) throws UnresolvableModelException { try { final Artifact artifact = new DefaultArtifact(parent.getGroupId(), parent.getArtifactId(), "", "pom", parent.getVersion()); @@ -275,12 +211,9 @@ public class ProjectModelResolver implements ModelResolver { parent.getVersion()); } - String newVersion = versionRangeResult.getHighestVersion().toString(); - if (!parent.getVersion().equals(newVersion)) { - modified.set(parent.withVersion(newVersion)); - } + parent.setVersion(versionRangeResult.getHighestVersion().toString()); - return resolveModel(parent.getGroupId(), parent.getArtifactId(), newVersion); + return resolveModel(parent.getGroupId(), parent.getArtifactId(), parent.getVersion()); } catch (final VersionRangeResolutionException e) { throw new UnresolvableModelException( e.getMessage(), parent.getGroupId(), parent.getArtifactId(), parent.getVersion(), e); @@ -288,8 +221,7 @@ public class ProjectModelResolver implements ModelResolver { } @Override - public ModelSource resolveModel(final Dependency dependency, AtomicReference modified) - throws UnresolvableModelException { + public ModelSource resolveModel(final Dependency dependency) throws UnresolvableModelException { try { final Artifact artifact = new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), "", "pom", dependency.getVersion()); @@ -322,54 +254,12 @@ public class ProjectModelResolver implements ModelResolver { dependency.getVersion()); } - String newVersion = versionRangeResult.getHighestVersion().toString(); - if (!dependency.getVersion().equals(newVersion)) { - modified.set(dependency.withVersion(newVersion)); - } + dependency.setVersion(versionRangeResult.getHighestVersion().toString()); - if (modelPool != null) { - Model model = modelPool.get(dependency.getGroupId(), dependency.getArtifactId(), newVersion); - - if (model != null) { - return new FileModelSource(model.getPomFile()); - } - } - - return resolveModel(dependency.getGroupId(), dependency.getArtifactId(), newVersion); + return resolveModel(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion()); } catch (VersionRangeResolutionException e) { throw new UnresolvableModelException( e.getMessage(), dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion(), e); } } - - @Override - public ModelSource resolveModel(org.apache.maven.model.Parent parent) throws UnresolvableModelException { - AtomicReference resolvedParent = new AtomicReference<>(); - ModelSource result = resolveModel(parent.getDelegate(), resolvedParent); - if (resolvedParent.get() != null) { - parent.setVersion(resolvedParent.get().getVersion()); - } - return result; - } - - @Override - public ModelSource resolveModel(org.apache.maven.model.Dependency dependency) throws UnresolvableModelException { - AtomicReference resolvedDependency = new AtomicReference<>(); - ModelSource result = resolveModel(dependency.getDelegate(), resolvedDependency); - if (resolvedDependency.get() != null) { - dependency.setVersion(resolvedDependency.get().getVersion()); - } - return result; - } - - @Override - public void addRepository(org.apache.maven.model.Repository repository) throws InvalidRepositoryException { - addRepository(repository.getDelegate()); - } - - @Override - public void addRepository(org.apache.maven.model.Repository repository, boolean replace) - throws InvalidRepositoryException { - addRepository(repository.getDelegate(), replace); - } } diff --git a/impl/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java b/impl/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java index 078ce850ed..f438369252 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java +++ b/impl/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java @@ -18,83 +18,46 @@ */ package org.apache.maven.project; -import java.nio.file.Path; -import java.util.Collections; -import java.util.HashSet; +import java.io.File; +import java.util.HashMap; import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.maven.api.model.Model; /** - * Holds all Models that are known to the reactor. This allows the project builder to resolve imported Models from the + * Holds all POM files that are known to the reactor. This allows the project builder to resolve imported POMs from the * reactor when building another project's effective model. - * */ class ReactorModelPool { - private final Map> modelsByGa = new ConcurrentHashMap<>(); - private final Map modelsByPath = new ConcurrentHashMap<>(); + private final Map pomFiles = new HashMap<>(); - /** - * Get the model by its GAV or (since 4.0.0) by its GA if there is only one. - * - * @param groupId never {@code null} - * @param artifactId never {@code null} - * @param version can be {@code null} - * @return the matching model or {@code null} - * @throws IllegalStateException if version was null and multiple modules share the same groupId + artifactId - */ - public Model get(String groupId, String artifactId, String version) { - return modelsByGa.getOrDefault(new GAKey(groupId, artifactId), Collections.emptySet()).stream() - .filter(m -> version == null || version.equals(getVersion(m))) - .reduce((a, b) -> { - throw new IllegalStateException( - "Multiple modules with key " + a.getGroupId() + ':' + a.getArtifactId()); - }) - .orElse(null); + public File get(String groupId, String artifactId, String version) { + return pomFiles.get(new CacheKey(groupId, artifactId, version)); } - private String getVersion(Model model) { - String version = model.getVersion(); - if (version == null && model.getParent() != null) { - version = model.getParent().getVersion(); - } - return version; + public void put(String groupId, String artifactId, String version, File pomFile) { + pomFiles.put(new CacheKey(groupId, artifactId, version), pomFile); } - void put(Path pomFile, Model model) { - if (pomFile != null) { - modelsByPath.put(pomFile, model); - } - modelsByGa - .computeIfAbsent(new GAKey(getGroupId(model), model.getArtifactId()), k -> new HashSet<>()) - .add(model); - } - - private static String getGroupId(Model model) { - String groupId = model.getGroupId(); - if (groupId == null && model.getParent() != null) { - groupId = model.getParent().getGroupId(); - } - return groupId; - } - - private static final class GAKey { + private static final class CacheKey { private final String groupId; private final String artifactId; + private final String version; + private final int hashCode; - GAKey(String groupId, String artifactId) { + CacheKey(String groupId, String artifactId, String version) { this.groupId = (groupId != null) ? groupId : ""; this.artifactId = (artifactId != null) ? artifactId : ""; + this.version = (version != null) ? version : ""; - hashCode = Objects.hash(this.groupId, this.artifactId); + int hash = 17; + hash = hash * 31 + this.groupId.hashCode(); + hash = hash * 31 + this.artifactId.hashCode(); + hash = hash * 31 + this.version.hashCode(); + hashCode = hash; } @Override @@ -102,11 +65,14 @@ class ReactorModelPool { if (this == obj) { return true; } - if (!(obj instanceof GAKey)) { + + if (!(obj instanceof CacheKey)) { return false; } - GAKey that = (GAKey) obj; - return artifactId.equals(that.artifactId) && groupId.equals(that.groupId); + + CacheKey that = (CacheKey) obj; + + return artifactId.equals(that.artifactId) && groupId.equals(that.groupId) && version.equals(that.version); } @Override @@ -116,7 +82,9 @@ class ReactorModelPool { @Override public String toString() { - return groupId + ':' + artifactId; + StringBuilder buffer = new StringBuilder(128); + buffer.append(groupId).append(':').append(artifactId).append(':').append(version); + return buffer.toString(); } } } diff --git a/impl/maven-core/src/main/java/org/apache/maven/project/collector/MultiModuleCollectionStrategy.java b/impl/maven-core/src/main/java/org/apache/maven/project/collector/MultiModuleCollectionStrategy.java index 91c0a494aa..f3570d5ae3 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/project/collector/MultiModuleCollectionStrategy.java +++ b/impl/maven-core/src/main/java/org/apache/maven/project/collector/MultiModuleCollectionStrategy.java @@ -30,10 +30,10 @@ import java.util.List; import java.util.Objects; import java.util.function.Predicate; +import org.apache.maven.api.services.model.ModelProcessor; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.model.Plugin; import org.apache.maven.model.building.ModelProblem; -import org.apache.maven.model.locator.ModelLocator; import org.apache.maven.plugin.PluginManagerException; import org.apache.maven.plugin.PluginResolutionException; import org.apache.maven.project.MavenProject; @@ -51,12 +51,12 @@ import org.slf4j.LoggerFactory; @Singleton public class MultiModuleCollectionStrategy implements ProjectCollectionStrategy { private static final Logger LOGGER = LoggerFactory.getLogger(MultiModuleCollectionStrategy.class); - private final ModelLocator modelLocator; + private final ModelProcessor modelProcessor; private final ProjectsSelector projectsSelector; @Inject - public MultiModuleCollectionStrategy(ModelLocator modelLocator, ProjectsSelector projectsSelector) { - this.modelLocator = modelLocator; + public MultiModuleCollectionStrategy(ModelProcessor modelProcessor, ProjectsSelector projectsSelector) { + this.modelProcessor = modelProcessor; this.projectsSelector = projectsSelector; } @@ -102,7 +102,7 @@ public class MultiModuleCollectionStrategy implements ProjectCollectionStrategy if (request.getPom().getParentFile().toPath().equals(rootDirectory)) { return request.getPom(); } else { - Path rootProjectPom = modelLocator.locateExistingPom(rootDirectory); + Path rootProjectPom = modelProcessor.locateExistingPom(rootDirectory); if (rootProjectPom == null) { LOGGER.info( "Maven detected that the requested POM file is part of a multi-module project, " diff --git a/impl/maven-core/src/test/java/org/apache/maven/graph/DefaultGraphBuilderTest.java b/impl/maven-core/src/test/java/org/apache/maven/graph/DefaultGraphBuilderTest.java index 6d49955a5d..a553b7ff4c 100644 --- a/impl/maven-core/src/test/java/org/apache/maven/graph/DefaultGraphBuilderTest.java +++ b/impl/maven-core/src/test/java/org/apache/maven/graph/DefaultGraphBuilderTest.java @@ -19,6 +19,7 @@ package org.apache.maven.graph; import java.io.File; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -28,16 +29,16 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.maven.MavenExecutionException; +import org.apache.maven.api.services.model.ModelProcessor; import org.apache.maven.execution.BuildResumptionDataRepository; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.ProjectActivation; import org.apache.maven.execution.ProjectDependencyGraph; +import org.apache.maven.internal.impl.model.DefaultModelProcessor; import org.apache.maven.model.Dependency; import org.apache.maven.model.Parent; import org.apache.maven.model.building.Result; -import org.apache.maven.model.locator.DefaultModelLocator; -import org.apache.maven.model.locator.ModelLocator; import org.apache.maven.project.MavenProject; import org.apache.maven.project.ProjectBuilder; import org.apache.maven.project.ProjectBuildingException; @@ -103,10 +104,10 @@ class DefaultGraphBuilderTest { // Not using mocks for these strategies - a mock would just copy the actual implementation. - private final ModelLocator modelLocator = new DefaultModelLocator(); + private final ModelProcessor modelProcessor = new DefaultModelProcessor(null, List.of()); private final PomlessCollectionStrategy pomlessCollectionStrategy = new PomlessCollectionStrategy(projectBuilder); private final MultiModuleCollectionStrategy multiModuleCollectionStrategy = - new MultiModuleCollectionStrategy(modelLocator, projectsSelector); + new MultiModuleCollectionStrategy(modelProcessor, projectsSelector); private final RequestPomCollectionStrategy requestPomCollectionStrategy = new RequestPomCollectionStrategy(projectsSelector); @@ -298,6 +299,7 @@ class DefaultGraphBuilderTest { parameterInactiveRequiredProjects.forEach(projectActivation::deactivateRequiredProject); parameterInactiveOptionalProjects.forEach(projectActivation::deactivateOptionalProject); + when(mavenExecutionRequest.getRootDirectory()).thenReturn(Paths.get(".")); when(mavenExecutionRequest.getProjectActivation()).thenReturn(projectActivation); when(mavenExecutionRequest.getMakeBehavior()).thenReturn(parameterMakeBehavior); when(mavenExecutionRequest.getPom()).thenReturn(parameterRequestedPom); diff --git a/impl/maven-core/src/test/java/org/apache/maven/internal/transformation/impl/ConsumerPomArtifactTransformerTest.java b/impl/maven-core/src/test/java/org/apache/maven/internal/transformation/impl/ConsumerPomArtifactTransformerTest.java index 5dd3835376..ed002978e9 100644 --- a/impl/maven-core/src/test/java/org/apache/maven/internal/transformation/impl/ConsumerPomArtifactTransformerTest.java +++ b/impl/maven-core/src/test/java/org/apache/maven/internal/transformation/impl/ConsumerPomArtifactTransformerTest.java @@ -25,7 +25,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import org.apache.maven.model.Model; -import org.apache.maven.model.building.TransformerContext; import org.apache.maven.model.v4.MavenStaxReader; import org.apache.maven.project.MavenProject; import org.eclipse.aether.RepositorySystemSession; @@ -35,7 +34,6 @@ import org.mockito.Mockito; import org.xmlunit.assertj.XmlAssert; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; class ConsumerPomArtifactTransformerTest { @@ -45,7 +43,6 @@ class ConsumerPomArtifactTransformerTest { RepositorySystemSession systemSessionMock = Mockito.mock(RepositorySystemSession.class); SessionData sessionDataMock = Mockito.mock(SessionData.class); when(systemSessionMock.getData()).thenReturn(sessionDataMock); - when(sessionDataMock.get(any())).thenReturn(new NoTransformerContext()); Path beforePomFile = Paths.get("src/test/resources/projects/transform/before.pom").toAbsolutePath(); @@ -73,7 +70,6 @@ class ConsumerPomArtifactTransformerTest { RepositorySystemSession systemSessionMock = Mockito.mock(RepositorySystemSession.class); SessionData sessionDataMock = Mockito.mock(SessionData.class); when(systemSessionMock.getData()).thenReturn(sessionDataMock); - when(sessionDataMock.get(any())).thenReturn(new NoTransformerContext()); Path beforePomFile = Paths.get("src/test/resources/projects/transform/jar/before.pom") .toAbsolutePath(); @@ -103,33 +99,10 @@ class ConsumerPomArtifactTransformerTest { RepositorySystemSession systemSessionMock = Mockito.mock(RepositorySystemSession.class); SessionData sessionDataMock = Mockito.mock(SessionData.class); when(systemSessionMock.getData()).thenReturn(sessionDataMock); - when(sessionDataMock.get(any())).thenReturn(new NoTransformerContext()); new DefaultConsumerPomArtifactTransformer((session, project, src) -> null) .injectTransformedArtifacts(systemSessionMock, emptyProject); assertThat(emptyProject.getAttachedArtifacts()).isEmpty(); } - - private static class NoTransformerContext implements TransformerContext { - @Override - public String getUserProperty(String key) { - return null; - } - - @Override - public Model getRawModel(Path from, String groupId, String artifactId) throws IllegalStateException { - throw new UnsupportedOperationException(); - } - - @Override - public Model getRawModel(Path from, Path p) { - throw new UnsupportedOperationException(); - } - - @Override - public Path locate(Path path) { - throw new UnsupportedOperationException(); - } - } } diff --git a/impl/maven-core/src/test/java/org/apache/maven/project/ProjectModelResolverTest.java b/impl/maven-core/src/test/java/org/apache/maven/project/ProjectModelResolverTest.java index f9621b23fc..37e4a7cb8a 100644 --- a/impl/maven-core/src/test/java/org/apache/maven/project/ProjectModelResolverTest.java +++ b/impl/maven-core/src/test/java/org/apache/maven/project/ProjectModelResolverTest.java @@ -21,7 +21,6 @@ package org.apache.maven.project; import java.io.File; import java.util.Collections; import java.util.List; -import java.util.concurrent.atomic.AtomicReference; import org.apache.maven.artifact.InvalidRepositoryException; import org.apache.maven.bridge.MavenRepositorySystem; @@ -65,7 +64,7 @@ class ProjectModelResolverTest extends AbstractMavenProjectTestCase { UnresolvableModelException e = assertThrows( UnresolvableModelException.class, - () -> newModelResolver().resolveModel(parent.getDelegate(), new AtomicReference<>()), + () -> newModelResolver().resolveModel(parent), "Expected 'UnresolvableModelException' not thrown."); assertNotNull(e.getMessage()); assertThat(e.getMessage(), containsString("Could not find artifact org.apache:apache:pom:0 in central")); @@ -80,7 +79,7 @@ class ProjectModelResolverTest extends AbstractMavenProjectTestCase { UnresolvableModelException e = assertThrows( UnresolvableModelException.class, - () -> newModelResolver().resolveModel(parent.getDelegate(), new AtomicReference<>()), + () -> newModelResolver().resolveModel(parent), "Expected 'UnresolvableModelException' not thrown."); assertEquals("No versions matched the requested parent version range '[2.0,2.1)'", e.getMessage()); } @@ -94,7 +93,7 @@ class ProjectModelResolverTest extends AbstractMavenProjectTestCase { UnresolvableModelException e = assertThrows( UnresolvableModelException.class, - () -> newModelResolver().resolveModel(parent.getDelegate(), new AtomicReference<>()), + () -> newModelResolver().resolveModel(parent), "Expected 'UnresolvableModelException' not thrown."); assertEquals("The requested parent version range '[1,)' does not specify an upper bound", e.getMessage()); } @@ -106,7 +105,7 @@ class ProjectModelResolverTest extends AbstractMavenProjectTestCase { parent.setArtifactId("apache"); parent.setVersion("1"); - assertNotNull(this.newModelResolver().resolveModel(parent.getDelegate(), new AtomicReference<>())); + assertNotNull(this.newModelResolver().resolveModel(parent)); assertEquals("1", parent.getVersion()); } @@ -117,9 +116,8 @@ class ProjectModelResolverTest extends AbstractMavenProjectTestCase { parent.setArtifactId("apache"); parent.setVersion("(,2.0)"); - AtomicReference modified = new AtomicReference<>(); - assertNotNull(this.newModelResolver().resolveModel(parent.getDelegate(), modified)); - assertEquals("1", modified.get().getVersion()); + assertNotNull(this.newModelResolver().resolveModel(parent)); + assertEquals("1", parent.getVersion()); } @Test @@ -131,7 +129,7 @@ class ProjectModelResolverTest extends AbstractMavenProjectTestCase { UnresolvableModelException e = assertThrows( UnresolvableModelException.class, - () -> newModelResolver().resolveModel(dependency.getDelegate(), new AtomicReference<>()), + () -> newModelResolver().resolveModel(dependency), "Expected 'UnresolvableModelException' not thrown."); assertNotNull(e.getMessage()); assertThat(e.getMessage(), containsString("Could not find artifact org.apache:apache:pom:0 in central")); @@ -146,7 +144,7 @@ class ProjectModelResolverTest extends AbstractMavenProjectTestCase { UnresolvableModelException e = assertThrows( UnresolvableModelException.class, - () -> newModelResolver().resolveModel(dependency.getDelegate(), new AtomicReference<>()), + () -> newModelResolver().resolveModel(dependency), "Expected 'UnresolvableModelException' not thrown."); assertEquals("No versions matched the requested dependency version range '[2.0,2.1)'", e.getMessage()); } @@ -160,7 +158,7 @@ class ProjectModelResolverTest extends AbstractMavenProjectTestCase { UnresolvableModelException e = assertThrows( UnresolvableModelException.class, - () -> newModelResolver().resolveModel(dependency.getDelegate(), new AtomicReference<>()), + () -> newModelResolver().resolveModel(dependency), "Expected 'UnresolvableModelException' not thrown."); assertEquals("The requested dependency version range '[1,)' does not specify an upper bound", e.getMessage()); } @@ -172,7 +170,7 @@ class ProjectModelResolverTest extends AbstractMavenProjectTestCase { dependency.setArtifactId("apache"); dependency.setVersion("1"); - assertNotNull(this.newModelResolver().resolveModel(dependency.getDelegate(), new AtomicReference<>())); + assertNotNull(this.newModelResolver().resolveModel(dependency)); assertEquals("1", dependency.getVersion()); } @@ -183,9 +181,8 @@ class ProjectModelResolverTest extends AbstractMavenProjectTestCase { dependency.setArtifactId("apache"); dependency.setVersion("(,2.0)"); - AtomicReference modified = new AtomicReference<>(); - assertNotNull(this.newModelResolver().resolveModel(dependency.getDelegate(), modified)); - assertEquals("1", modified.get().getVersion()); + assertNotNull(this.newModelResolver().resolveModel(dependency)); + assertEquals("1", dependency.getVersion()); } private ModelResolver newModelResolver() throws Exception { @@ -200,7 +197,6 @@ class ProjectModelResolverTest extends AbstractMavenProjectTestCase { getContainer().lookup(RemoteRepositoryManager.class), this.getRemoteRepositories(), ProjectBuildingRequest.RepositoryMerging.REQUEST_DOMINANT, - null, null); } diff --git a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng6090CIFriendlyTest.java b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng6090CIFriendlyTest.java index 8b975b40cd..3b7ab90f17 100644 --- a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng6090CIFriendlyTest.java +++ b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng6090CIFriendlyTest.java @@ -54,7 +54,7 @@ public class MavenITmng6090CIFriendlyTest extends AbstractMavenIntegrationTestCa verifier.setAutoclean(false); verifier.addCliArgument("-Drevision=1.2"); - verifier.addCliArgument("-Dmaven.consumerpom=false"); + verifier.addCliArgument("-Dmaven.consumer.pom=false"); verifier.setLogFileName("install-log.txt"); verifier.addCliArguments("clean", "install"); verifier.execute(); @@ -80,7 +80,7 @@ public class MavenITmng6090CIFriendlyTest extends AbstractMavenIntegrationTestCa verifier.setForkJvm(true); // TODO: why? verifier.addCliArgument("-Drevision=1.2"); - verifier.addCliArgument("-Dmaven.consumerpom=true"); + verifier.addCliArgument("-Dmaven.consumer.pom=true"); verifier.setLogFileName("install-log.txt"); verifier.addCliArguments("clean", "install"); verifier.execute(); diff --git a/pom.xml b/pom.xml index de984a9199..669f14e537 100644 --- a/pom.xml +++ b/pom.xml @@ -134,7 +134,7 @@ under the License. ${javaVersion} full true - 3.8.8 + 3.9.8 apache-maven Maven diff --git a/src/mdo/java/WrapperProperties.java b/src/mdo/java/WrapperProperties.java index 851459c4a6..d6e431de70 100644 --- a/src/mdo/java/WrapperProperties.java +++ b/src/mdo/java/WrapperProperties.java @@ -26,10 +26,12 @@ import java.io.PrintStream; import java.io.PrintWriter; import java.io.Reader; import java.io.Writer; +import java.util.AbstractSet; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.InvalidPropertiesFormatException; +import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.Set; @@ -136,7 +138,45 @@ class WrapperProperties extends Properties { @Override public Set> entrySet() { - return (Set) getter.get().entrySet(); + Set> set = getter.get().entrySet(); + return new AbstractSet>() { + @Override + public Iterator> iterator() { + Iterator> it = set.iterator(); + return new Iterator>() { + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public Map.Entry next() { + Map.Entry entry = it.next(); + return new Map.Entry() { + @Override + public Object getKey() { + return entry.getKey(); + } + + @Override + public Object getValue() { + return entry.getValue(); + } + + @Override + public Object setValue(Object value) { + return writeOperation(p -> p.put(entry.getKey(), value)); + } + }; + } + }; + } + + @Override + public int size() { + return set.size(); + } + }; } @Override diff --git a/src/mdo/model-v3.vm b/src/mdo/model-v3.vm index 168d352d2c..3619fff027 100644 --- a/src/mdo/model-v3.vm +++ b/src/mdo/model-v3.vm @@ -280,7 +280,7 @@ public class ${class.name} public void setLocation(Object key, InputLocation location) { update(${packageModelV4}.${class.name}.newBuilder(getDelegate(), true) - .location(key, location.toApiLocation()).build()); + .location(key, location != null ? location.toApiLocation() : null).build()); } public InputLocation getImportedFrom() { @@ -290,7 +290,7 @@ public class ${class.name} public void setImportedFrom(InputLocation location) { update(${packageModelV4}.${class.name}.newBuilder(getDelegate(), true) - .importedFrom(location.toApiLocation()).build()); + .importedFrom(location != null ? location.toApiLocation() : null).build()); } public Set getLocationKeys() {