diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/Interpolator.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/Interpolator.java index 4e553f805f..18b6924b2f 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/Interpolator.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/Interpolator.java @@ -20,6 +20,7 @@ package org.apache.maven.api.services; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.BiFunction; @@ -138,6 +139,11 @@ public interface Interpolator extends Service { }; } + @SafeVarargs + static Function chain(Function... functions) { + return chain(List.of(functions)); + } + /** * Memoizes a given function that takes a String input and produces a String output. * This method creates a new function that caches the results of the original function, diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/SettingsBuilderRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/SettingsBuilderRequest.java index 09f7bcb341..5c028e1e64 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/SettingsBuilderRequest.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/SettingsBuilderRequest.java @@ -21,6 +21,7 @@ package org.apache.maven.api.services; import java.nio.file.Files; import java.nio.file.Path; import java.util.Optional; +import java.util.function.Function; import org.apache.maven.api.Session; import org.apache.maven.api.annotations.Experimental; @@ -65,6 +66,14 @@ public interface SettingsBuilderRequest { @Nonnull Optional getUserSettingsSource(); + /** + * The optional interpolation source used for interpolation. + * + * @return the interpolation source for interpolation + */ + @Nonnull + Optional> getInterpolationSource(); + @Nonnull static SettingsBuilderRequest build( @Nonnull Session session, @Nonnull Source installationSettingsSource, @Nonnull Source userSettingsSource) { @@ -125,6 +134,7 @@ public interface SettingsBuilderRequest { Source installationSettingsSource; Source projectSettingsSource; Source userSettingsSource; + Function interpolationSource; public SettingsBuilderRequestBuilder session(Session session) { this.session = session; @@ -146,26 +156,38 @@ public interface SettingsBuilderRequest { return this; } + public SettingsBuilderRequestBuilder interpolationSource(Function interpolationSource) { + this.interpolationSource = interpolationSource; + return this; + } + public SettingsBuilderRequest build() { return new DefaultSettingsBuilderRequest( - session, installationSettingsSource, projectSettingsSource, userSettingsSource); + session, + installationSettingsSource, + projectSettingsSource, + userSettingsSource, + interpolationSource); } private static class DefaultSettingsBuilderRequest extends BaseRequest implements SettingsBuilderRequest { private final Source installationSettingsSource; private final Source projectSettingsSource; private final Source userSettingsSource; + private final Function interpolationSource; @SuppressWarnings("checkstyle:ParameterNumber") DefaultSettingsBuilderRequest( @Nonnull Session session, @Nullable Source installationSettingsSource, @Nullable Source projectSettingsSource, - @Nullable Source userSettingsSource) { + @Nullable Source userSettingsSource, + @Nullable Function interpolationSource) { super(session); this.installationSettingsSource = installationSettingsSource; this.projectSettingsSource = projectSettingsSource; this.userSettingsSource = userSettingsSource; + this.interpolationSource = interpolationSource; } @Nonnull @@ -185,6 +207,12 @@ public interface SettingsBuilderRequest { public Optional getUserSettingsSource() { return Optional.ofNullable(userSettingsSource); } + + @Nonnull + @Override + public Optional> getInterpolationSource() { + return Optional.ofNullable(interpolationSource); + } } } } diff --git a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultSettingsBuilder.java b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultSettingsBuilder.java index 8b849a08a9..1dc9635cdb 100644 --- a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultSettingsBuilder.java +++ b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultSettingsBuilder.java @@ -225,9 +225,14 @@ public class DefaultSettingsBuilder implements SettingsBuilder { } private Settings interpolate(Settings settings, SettingsBuilderRequest request, List problems) { - Map userProperties = request.getSession().getUserProperties(); - Map systemProperties = request.getSession().getSystemProperties(); - Function src = Interpolator.chain(List.of(userProperties::get, systemProperties::get)); + Function src; + if (request.getInterpolationSource().isPresent()) { + src = request.getInterpolationSource().get(); + } else { + Map userProperties = request.getSession().getUserProperties(); + Map systemProperties = request.getSession().getSystemProperties(); + src = Interpolator.chain(userProperties::get, systemProperties::get); + } return new SettingsTransformer(value -> value != null ? interpolator.interpolate(value, src) : null) .visit(settings); } diff --git a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultToolchainsBuilder.java b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultToolchainsBuilder.java index 55caa92fce..4cdbdfc7c6 100644 --- a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultToolchainsBuilder.java +++ b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultToolchainsBuilder.java @@ -56,13 +56,16 @@ public class DefaultToolchainsBuilder implements ToolchainsBuilder { private final Interpolator interpolator; + private final ToolchainsXmlFactory toolchainsXmlFactory; + public DefaultToolchainsBuilder() { - this(new DefaultInterpolator()); + this(new DefaultInterpolator(), new DefaultToolchainsXmlFactory()); } @Inject - public DefaultToolchainsBuilder(Interpolator interpolator) { + public DefaultToolchainsBuilder(Interpolator interpolator, ToolchainsXmlFactory toolchainsXmlFactory) { this.interpolator = interpolator; + this.toolchainsXmlFactory = toolchainsXmlFactory; } @Override @@ -110,25 +113,21 @@ public class DefaultToolchainsBuilder implements ToolchainsBuilder { if (is == null) { return PersistedToolchains.newInstance(); } - toolchains = request.getSession() - .getService(ToolchainsXmlFactory.class) - .read(XmlReaderRequest.builder() - .inputStream(is) - .location(toolchainsSource.getLocation()) - .strict(true) - .build()); + toolchains = toolchainsXmlFactory.read(XmlReaderRequest.builder() + .inputStream(is) + .location(toolchainsSource.getLocation()) + .strict(true) + .build()); } catch (XmlReaderException e) { InputStream is = toolchainsSource.openStream(); if (is == null) { return PersistedToolchains.newInstance(); } - toolchains = request.getSession() - .getService(ToolchainsXmlFactory.class) - .read(XmlReaderRequest.builder() - .inputStream(is) - .location(toolchainsSource.getLocation()) - .strict(false) - .build()); + toolchains = toolchainsXmlFactory.read(XmlReaderRequest.builder() + .inputStream(is) + .location(toolchainsSource.getLocation()) + .strict(false) + .build()); Location loc = e.getCause() instanceof XMLStreamException xe ? xe.getLocation() : null; problems.add(new DefaultBuilderProblem( toolchainsSource.getLocation(), @@ -168,7 +167,7 @@ public class DefaultToolchainsBuilder implements ToolchainsBuilder { PersistedToolchains toolchains, ToolchainsBuilderRequest request, List problems) { Map userProperties = request.getSession().getUserProperties(); Map systemProperties = request.getSession().getSystemProperties(); - Function src = Interpolator.chain(List.of(userProperties::get, systemProperties::get)); + Function src = Interpolator.chain(userProperties::get, systemProperties::get); return new MavenToolchainsTransformer(value -> value != null ? interpolator.interpolate(value, src) : null) .visit(toolchains); } diff --git a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/model/DefaultModelBuilder.java b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/model/DefaultModelBuilder.java index 9a13ca9627..bcb3d622c8 100644 --- a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/model/DefaultModelBuilder.java +++ b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/model/DefaultModelBuilder.java @@ -1741,7 +1741,7 @@ public class DefaultModelBuilder implements ModelBuilder { try { Map map1 = context.getUserProperties(); Map map2 = context.getSystemProperties(); - return interpolator.interpolate(s, Interpolator.chain(List.of(map1::get, map2::get))); + return interpolator.interpolate(s, Interpolator.chain(map1::get, map2::get)); } catch (InterpolatorException e) { problems.add(Severity.ERROR, Version.BASE, e.getMessage(), e); } @@ -1873,7 +1873,7 @@ public class DefaultModelBuilder implements ModelBuilder { Map map1 = request.getSession().getUserProperties(); Map map2 = model.getProperties(); Map map3 = request.getSession().getSystemProperties(); - Function cb = Interpolator.chain(List.of(map1::get, map2::get, map3::get)); + Function cb = Interpolator.chain(map1::get, map2::get, map3::get); try { String interpolated = interpolator.interpolate(interpolatedModel.getParent().getVersion(), cb); diff --git a/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java b/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java index 8b55406214..e4f6b092a6 100644 --- a/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java +++ b/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java @@ -352,6 +352,7 @@ public class ApiRunner { // local repository String localRepository = settings.getLocalRepository() != null + && !settings.getLocalRepository().isEmpty() ? settings.getLocalRepository() : mavenUserHome.resolve("repository").toString(); LocalRepositoryManager llm = system.newLocalRepositoryManager(rsession, new LocalRepository(localRepository)); diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java index 095a2c0226..2530b1d0cf 100644 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java +++ b/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java @@ -25,6 +25,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; @@ -33,14 +34,27 @@ import java.util.Properties; import java.util.function.Function; import org.apache.maven.api.Constants; +import org.apache.maven.api.Session; import org.apache.maven.api.cli.Invoker; import org.apache.maven.api.cli.InvokerException; import org.apache.maven.api.cli.InvokerRequest; import org.apache.maven.api.cli.Logger; import org.apache.maven.api.cli.Options; +import org.apache.maven.api.services.BuilderProblem; +import org.apache.maven.api.services.Interpolator; import org.apache.maven.api.services.Lookup; import org.apache.maven.api.services.MavenException; import org.apache.maven.api.services.MessageBuilder; +import org.apache.maven.api.services.SettingsBuilder; +import org.apache.maven.api.services.SettingsBuilderRequest; +import org.apache.maven.api.services.SettingsBuilderResult; +import org.apache.maven.api.services.Source; +import org.apache.maven.api.settings.Mirror; +import org.apache.maven.api.settings.Profile; +import org.apache.maven.api.settings.Proxy; +import org.apache.maven.api.settings.Repository; +import org.apache.maven.api.settings.Server; +import org.apache.maven.api.settings.Settings; import org.apache.maven.artifact.InvalidRepositoryException; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; @@ -54,7 +68,9 @@ import org.apache.maven.cli.transfer.ConsoleMavenTransferListener; import org.apache.maven.cli.transfer.QuietMavenTransferListener; import org.apache.maven.cli.transfer.SimplexTransferListener; import org.apache.maven.cli.transfer.Slf4jMavenTransferListener; +import org.apache.maven.cling.invoker.mvn.ProtoSession; import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.internal.impl.SettingsUtilsV4; import org.apache.maven.jline.FastTerminal; import org.apache.maven.jline.MessageUtils; import org.apache.maven.logging.BuildEventListener; @@ -62,18 +78,6 @@ import org.apache.maven.logging.LoggingOutputStream; import org.apache.maven.logging.ProjectBuildLogAppender; import org.apache.maven.logging.SimpleBuildEventListener; import org.apache.maven.logging.api.LogLevelRecorder; -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.SettingsUtils; -import org.apache.maven.settings.building.DefaultSettingsBuildingRequest; -import org.apache.maven.settings.building.SettingsBuilder; -import org.apache.maven.settings.building.SettingsBuildingRequest; -import org.apache.maven.settings.building.SettingsBuildingResult; -import org.apache.maven.settings.building.SettingsProblem; import org.apache.maven.slf4j.MavenSimpleLogger; import org.eclipse.aether.transfer.TransferListener; import org.jline.jansi.AnsiConsole; @@ -84,7 +88,6 @@ import org.slf4j.LoggerFactory; import org.slf4j.spi.LocationAwareLogger; import static java.util.Objects.requireNonNull; -import static org.apache.maven.cling.invoker.Utils.toFile; import static org.apache.maven.cling.invoker.Utils.toMavenExecutionRequestLoggingLevel; import static org.apache.maven.cling.invoker.Utils.toProperties; @@ -122,6 +125,7 @@ public abstract class LookupInvoker< public final Function cwdResolver; public final Function installationResolver; public final Function userResolver; + public final Session session; protected LookupInvokerContext(LookupInvoker invoker, R invokerRequest) { this.invoker = invoker; @@ -136,6 +140,12 @@ public abstract class LookupInvoker< this.userResolver = s -> invokerRequest.userHomeDirectory().resolve(s).normalize().toAbsolutePath(); this.logger = invokerRequest.parserRequest().logger(); + + Map user = new HashMap<>(invokerRequest.userProperties()); + user.put("session.rootDirectory", invokerRequest.rootDirectory().toString()); + user.put("session.topDirectory", invokerRequest.topDirectory().toString()); + Map system = new HashMap<>(invokerRequest.systemProperties()); + this.session = ProtoSession.create(user, system); } public Logger logger; @@ -535,36 +545,32 @@ public abstract class LookupInvoker< context.projectSettingsPath = projectSettingsFile; context.userSettingsPath = userSettingsFile; - SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest(); - settingsRequest.setGlobalSettingsFile(toFile(installationSettingsFile)); - settingsRequest.setProjectSettingsFile(toFile(projectSettingsFile)); - settingsRequest.setUserSettingsFile(toFile(userSettingsFile)); - settingsRequest.setSystemProperties(toProperties(context.invokerRequest.systemProperties())); - Properties props = toProperties(context.invokerRequest.userProperties()); - props.put( - "session.rootDirectory", context.invokerRequest.rootDirectory().toString()); - props.put("session.topDirectory", context.invokerRequest.topDirectory().toString()); + Function interpolationSource = Interpolator.chain( + context.invokerRequest.userProperties()::get, context.invokerRequest.systemProperties()::get); + SettingsBuilderRequest settingsRequest = SettingsBuilderRequest.builder() + .session(context.session) + .installationSettingsSource( + installationSettingsFile != null && Files.exists(installationSettingsFile) + ? Source.fromPath(installationSettingsFile) + : null) + .projectSettingsSource( + projectSettingsFile != null && Files.exists(projectSettingsFile) + ? Source.fromPath(projectSettingsFile) + : null) + .userSettingsSource( + userSettingsFile != null && Files.exists(userSettingsFile) + ? Source.fromPath(userSettingsFile) + : null) + .interpolationSource(interpolationSource) + .build(); - settingsRequest.setUserProperties(props); customizeSettingsRequest(context, settingsRequest); - context.logger.debug("Reading installation settings from '" - + (settingsRequest.getGlobalSettingsSource() != null - ? settingsRequest.getGlobalSettingsSource().getLocation() - : settingsRequest.getGlobalSettingsFile()) - + "'"); - context.logger.debug("Reading project settings from '" - + (settingsRequest.getProjectSettingsSource() != null - ? settingsRequest.getProjectSettingsSource().getLocation() - : settingsRequest.getProjectSettingsFile()) - + "'"); - context.logger.debug("Reading user settings from '" - + (settingsRequest.getUserSettingsSource() != null - ? settingsRequest.getUserSettingsSource().getLocation() - : settingsRequest.getUserSettingsFile()) - + "'"); + context.logger.debug("Reading installation settings from '" + installationSettingsFile + "'"); + context.logger.debug("Reading project settings from '" + projectSettingsFile + "'"); + context.logger.debug("Reading user settings from '" + userSettingsFile + "'"); - SettingsBuildingResult settingsResult = settingsBuilder.build(settingsRequest); + SettingsBuilderResult settingsResult = settingsBuilder.build(settingsRequest); customizeSettingsResult(context, settingsResult); context.effectiveSettings = settingsResult.getEffectiveSettings(); @@ -575,17 +581,17 @@ public abstract class LookupInvoker< context.logger.warn(""); context.logger.warn("Some problems were encountered while building the effective settings"); - for (SettingsProblem problem : settingsResult.getProblems()) { + for (BuilderProblem problem : settingsResult.getProblems()) { context.logger.warn(problem.getMessage() + " @ " + problem.getLocation()); } context.logger.warn(""); } } - protected void customizeSettingsRequest(C context, SettingsBuildingRequest settingsBuildingRequest) + protected void customizeSettingsRequest(C context, SettingsBuilderRequest settingsBuilderRequest) throws Exception {} - protected void customizeSettingsResult(C context, SettingsBuildingResult settingsBuildingResult) throws Exception {} + protected void customizeSettingsResult(C context, SettingsBuilderResult settingsBuilderResult) throws Exception {} protected boolean mayDisableInteractiveMode(C context, boolean proposedInteractive) { if (!context.invokerRequest.options().forceInteractive().orElse(false)) { @@ -676,7 +682,7 @@ public abstract class LookupInvoker< request.setPluginGroups(settings.getPluginGroups()); request.setLocalRepositoryPath(settings.getLocalRepository()); for (Server server : settings.getServers()) { - request.addServer(server); + request.addServer(new org.apache.maven.settings.Server(server)); } // @@ -695,7 +701,7 @@ public abstract class LookupInvoker< if (!proxy.isActive()) { continue; } - request.addProxy(proxy); + request.addProxy(new org.apache.maven.settings.Proxy(proxy)); } // @@ -707,12 +713,13 @@ public abstract class LookupInvoker< // for (Mirror mirror : settings.getMirrors()) { - request.addMirror(mirror); + request.addMirror(new org.apache.maven.settings.Mirror(mirror)); } for (Repository remoteRepository : settings.getRepositories()) { try { - request.addRemoteRepository(MavenRepositorySystem.buildArtifactRepository(remoteRepository)); + request.addRemoteRepository(MavenRepositorySystem.buildArtifactRepository( + new org.apache.maven.settings.Repository(remoteRepository))); } catch (InvalidRepositoryException e) { // do nothing for now } @@ -720,7 +727,8 @@ public abstract class LookupInvoker< for (Repository pluginRepository : settings.getPluginRepositories()) { try { - request.addPluginArtifactRepository(MavenRepositorySystem.buildArtifactRepository(pluginRepository)); + request.addPluginArtifactRepository(MavenRepositorySystem.buildArtifactRepository( + new org.apache.maven.settings.Repository(pluginRepository))); } catch (InvalidRepositoryException e) { // do nothing for now } @@ -728,13 +736,15 @@ public abstract class LookupInvoker< request.setActiveProfiles(settings.getActiveProfiles()); for (Profile rawProfile : settings.getProfiles()) { - request.addProfile(SettingsUtils.convertFromSettingsProfile(rawProfile)); + request.addProfile( + new org.apache.maven.model.Profile(SettingsUtilsV4.convertFromSettingsProfile(rawProfile))); if (settings.getActiveProfiles().contains(rawProfile.getId())) { List remoteRepositories = rawProfile.getRepositories(); for (Repository remoteRepository : remoteRepositories) { try { - request.addRemoteRepository(MavenRepositorySystem.buildArtifactRepository(remoteRepository)); + request.addRemoteRepository(MavenRepositorySystem.buildArtifactRepository( + new org.apache.maven.settings.Repository(remoteRepository))); } catch (InvalidRepositoryException e) { // do nothing for now } @@ -743,8 +753,8 @@ public abstract class LookupInvoker< List pluginRepositories = rawProfile.getPluginRepositories(); for (Repository pluginRepository : pluginRepositories) { try { - request.addPluginArtifactRepository( - MavenRepositorySystem.buildArtifactRepository(pluginRepository)); + request.addPluginArtifactRepository(MavenRepositorySystem.buildArtifactRepository( + new org.apache.maven.settings.Repository(pluginRepository))); } catch (InvalidRepositoryException e) { // do nothing for now } diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/PlexusContainerCapsuleFactory.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/PlexusContainerCapsuleFactory.java index 49b2c7c9e5..54bbe0c9e5 100644 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/PlexusContainerCapsuleFactory.java +++ b/maven-cli/src/main/java/org/apache/maven/cling/invoker/PlexusContainerCapsuleFactory.java @@ -36,6 +36,7 @@ import org.apache.maven.api.cli.Logger; import org.apache.maven.api.cli.Options; import org.apache.maven.api.cli.extensions.CoreExtension; import org.apache.maven.api.services.MessageBuilderFactory; +import org.apache.maven.api.services.SettingsBuilder; import org.apache.maven.cli.ExtensionConfigurationModule; import org.apache.maven.cli.internal.BootstrapCoreExtensionManager; import org.apache.maven.cli.logging.Slf4jLoggerManager; @@ -49,7 +50,6 @@ import org.apache.maven.extension.internal.CoreExports; import org.apache.maven.extension.internal.CoreExtensionEntry; import org.apache.maven.session.scope.internal.SessionScope; import org.apache.maven.session.scope.internal.SessionScopeModule; -import org.apache.maven.settings.building.SettingsBuilder; import org.codehaus.plexus.ContainerConfiguration; import org.codehaus.plexus.DefaultContainerConfiguration; import org.codehaus.plexus.DefaultPlexusContainer; diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/DefaultMavenInvoker.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/DefaultMavenInvoker.java index 0b6a4fca32..6bfb5121f5 100644 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/DefaultMavenInvoker.java +++ b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/DefaultMavenInvoker.java @@ -37,8 +37,14 @@ import org.apache.maven.api.cli.Logger; import org.apache.maven.api.cli.mvn.MavenInvoker; import org.apache.maven.api.cli.mvn.MavenInvokerRequest; import org.apache.maven.api.cli.mvn.MavenOptions; -import org.apache.maven.building.FileSource; -import org.apache.maven.building.Problem; +import org.apache.maven.api.services.BuilderProblem; +import org.apache.maven.api.services.SettingsBuilderRequest; +import org.apache.maven.api.services.SettingsBuilderResult; +import org.apache.maven.api.services.Source; +import org.apache.maven.api.services.ToolchainsBuilder; +import org.apache.maven.api.services.ToolchainsBuilderRequest; +import org.apache.maven.api.services.ToolchainsBuilderResult; +import org.apache.maven.api.services.model.ModelProcessor; import org.apache.maven.cli.CLIReportingUtils; import org.apache.maven.cli.event.ExecutionEventLogger; import org.apache.maven.cling.invoker.LookupInvoker; @@ -59,13 +65,7 @@ import org.apache.maven.jline.MessageUtils; import org.apache.maven.lifecycle.LifecycleExecutionException; import org.apache.maven.logging.LoggingExecutionListener; import org.apache.maven.logging.MavenTransferListener; -import org.apache.maven.model.building.ModelProcessor; import org.apache.maven.project.MavenProject; -import org.apache.maven.settings.building.SettingsBuildingRequest; -import org.apache.maven.settings.building.SettingsBuildingResult; -import org.apache.maven.toolchain.building.DefaultToolchainsBuildingRequest; -import org.apache.maven.toolchain.building.ToolchainsBuilder; -import org.apache.maven.toolchain.building.ToolchainsBuildingResult; import org.codehaus.plexus.PlexusContainer; import org.eclipse.aether.DefaultRepositoryCache; import org.eclipse.aether.transfer.TransferListener; @@ -162,16 +162,16 @@ public abstract class DefaultMavenInvoker< } @Override - protected void customizeSettingsRequest(C context, SettingsBuildingRequest settingsBuildingRequest) { + protected void customizeSettingsRequest(C context, SettingsBuilderRequest settingsBuilderRequest) { if (context.eventSpyDispatcher != null) { - context.eventSpyDispatcher.onEvent(settingsBuildingRequest); + context.eventSpyDispatcher.onEvent(settingsBuilderRequest); } } @Override - protected void customizeSettingsResult(C context, SettingsBuildingResult settingsBuildingResult) { + protected void customizeSettingsResult(C context, SettingsBuilderResult settingsBuilderResult) throws Exception { if (context.eventSpyDispatcher != null) { - context.eventSpyDispatcher.onEvent(settingsBuildingResult); + context.eventSpyDispatcher.onEvent(settingsBuilderResult); } } @@ -217,39 +217,36 @@ public abstract class DefaultMavenInvoker< context.mavenExecutionRequest.setUserToolchainsFile( userToolchainsFile != null ? userToolchainsFile.toFile() : null); - DefaultToolchainsBuildingRequest toolchainsRequest = new DefaultToolchainsBuildingRequest(); - if (installationToolchainsFile != null && Files.isRegularFile(installationToolchainsFile)) { - toolchainsRequest.setGlobalToolchainsSource(new FileSource(installationToolchainsFile)); - } - if (userToolchainsFile != null && Files.isRegularFile(userToolchainsFile)) { - toolchainsRequest.setUserToolchainsSource(new FileSource(userToolchainsFile)); - } + ToolchainsBuilderRequest toolchainsRequest = ToolchainsBuilderRequest.builder() + .session(context.session) + .installationToolchainsSource( + installationToolchainsFile != null && Files.isRegularFile(installationToolchainsFile) + ? Source.fromPath(installationToolchainsFile) + : null) + .userToolchainsSource( + userToolchainsFile != null && Files.isRegularFile(userToolchainsFile) + ? Source.fromPath(userToolchainsFile) + : null) + .build(); context.eventSpyDispatcher.onEvent(toolchainsRequest); - context.logger.debug("Reading installation toolchains from '" - + (toolchainsRequest.getGlobalToolchainsSource() != null - ? toolchainsRequest.getGlobalToolchainsSource().getLocation() - : installationToolchainsFile) - + "'"); - context.logger.debug("Reading user toolchains from '" - + (toolchainsRequest.getUserToolchainsSource() != null - ? toolchainsRequest.getUserToolchainsSource().getLocation() - : userToolchainsFile) - + "'"); + context.logger.debug("Reading installation toolchains from '" + installationToolchainsFile + "'"); + context.logger.debug("Reading user toolchains from '" + userToolchainsFile + "'"); - ToolchainsBuildingResult toolchainsResult = context.toolchainsBuilder.build(toolchainsRequest); + ToolchainsBuilderResult toolchainsResult = context.toolchainsBuilder.build(toolchainsRequest); context.eventSpyDispatcher.onEvent(toolchainsResult); context.mavenExecutionRequestPopulator.populateFromToolchains( - context.mavenExecutionRequest, toolchainsResult.getEffectiveToolchains()); + context.mavenExecutionRequest, + new org.apache.maven.toolchain.model.PersistedToolchains(toolchainsResult.getEffectiveToolchains())); if (!toolchainsResult.getProblems().isEmpty()) { context.logger.warn(""); context.logger.warn("Some problems were encountered while building the effective toolchains"); - for (Problem problem : toolchainsResult.getProblems()) { + for (BuilderProblem problem : toolchainsResult.getProblems()) { context.logger.warn(problem.getMessage() + " @ " + problem.getLocation()); } diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/ProtoSession.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/ProtoSession.java new file mode 100644 index 0000000000..9a19c21eb8 --- /dev/null +++ b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/ProtoSession.java @@ -0,0 +1,409 @@ +/* + * 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.cling.invoker.mvn; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.Instant; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.maven.api.Artifact; +import org.apache.maven.api.Lifecycle; +import org.apache.maven.api.Packaging; +import org.apache.maven.api.ProducedArtifact; +import org.apache.maven.api.Project; +import org.apache.maven.api.RemoteRepository; +import org.apache.maven.api.Session; +import org.apache.maven.api.Type; +import org.apache.maven.api.Version; +import org.apache.maven.api.di.Provides; +import org.apache.maven.api.di.SessionScoped; +import org.apache.maven.api.model.PluginContainer; +import org.apache.maven.api.model.Profile; +import org.apache.maven.api.services.ArtifactManager; +import org.apache.maven.api.services.LifecycleRegistry; +import org.apache.maven.api.services.Lookup; +import org.apache.maven.api.services.MavenException; +import org.apache.maven.api.services.PackagingRegistry; +import org.apache.maven.api.services.RepositoryFactory; +import org.apache.maven.api.services.SettingsBuilder; +import org.apache.maven.api.services.TypeRegistry; +import org.apache.maven.api.settings.Settings; +import org.apache.maven.api.spi.TypeProvider; +import org.apache.maven.di.Injector; +import org.apache.maven.di.Key; +import org.apache.maven.di.impl.DIException; +import org.apache.maven.internal.impl.AbstractSession; +import org.apache.maven.internal.impl.InternalSession; +import org.apache.maven.internal.impl.di.SessionScope; +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.impl.RemoteRepositoryManager; +import org.eclipse.aether.repository.LocalRepository; +import org.eclipse.aether.repository.LocalRepositoryManager; + +public class ProtoSession extends AbstractSession { + + private final Map userProperties; + private final Map systemProperties; + private final Instant startTime = Instant.now(); + + ProtoSession(RepositorySystemSession session, RepositorySystem repositorySystem, Lookup lookup) { + this(session, repositorySystem, Collections.emptyList(), null, lookup, new Context(Map.of(), Map.of())); + } + + protected ProtoSession( + RepositorySystemSession session, + RepositorySystem repositorySystem, + List repositories, + List resolverRepositories, + Lookup lookup, + Context context) { + super(session, repositorySystem, repositories, resolverRepositories, lookup); + userProperties = context.userProperties; + systemProperties = context.systemProperties; + } + + /** + * + */ + public static Session create() { + Map properties = new HashMap<>(); + // Env variables prefixed with "env." + System.getenv().forEach((k, v) -> properties.put("env." + k, v)); + // Java System properties + System.getProperties().forEach((k, v) -> properties.put(k.toString(), v.toString())); + // create session + return create(Map.of(), properties); + } + + /** + * Create a new session. + */ + public static Session create(Map userProperties, Map systemProperties) { + Injector injector = Injector.create(); + injector.bindInstance(Injector.class, injector); + injector.bindInstance(Context.class, new Context(userProperties, systemProperties)); + injector.bindImplicit(Providers.class); + injector.discover(ProtoSession.class.getClassLoader()); + Session session = injector.getInstance(Session.class); + SessionScope scope = new SessionScope(); + scope.enter(); + scope.seed(Session.class, session); + injector.bindScope(SessionScoped.class, scope); + return session; + } + + record Context(Map userProperties, Map systemProperties) {} + + @Override + protected Session newSession(RepositorySystemSession session, List repositories) { + return new ProtoSession( + session, repositorySystem, repositories, null, lookup, new Context(userProperties, systemProperties)); + } + + @Override + public Settings getSettings() { + return Settings.newInstance(); + } + + @Override + public Map getUserProperties() { + return Map.of(); + } + + @Override + public Map getSystemProperties() { + return systemProperties; + } + + @Override + public Map getEffectiveProperties(Project project) { + HashMap result = new HashMap<>(getSystemProperties()); + if (project != null) { + result.putAll(project.getModel().getProperties()); + } + result.putAll(getUserProperties()); + return result; + } + + @Override + public Version getMavenVersion() { + return null; + } + + @Override + public int getDegreeOfConcurrency() { + return 0; + } + + @Override + public Instant getStartTime() { + return startTime; + } + + @Override + public Path getTopDirectory() { + return null; + } + + @Override + public Path getRootDirectory() { + throw new IllegalStateException(); + } + + @Override + public List getProjects() { + return List.of(); + } + + @Override + public Map getPluginContext(Project project) { + throw new UnsupportedInStandaloneModeException(); + } + + static class Providers { + + @Provides + @SuppressWarnings("unused") + static Lookup newLookup(Injector injector) { + return new Lookup() { + @Override + public T lookup(Class type) { + try { + return injector.getInstance(type); + } catch (DIException e) { + throw new MavenException("Unable to locate instance of type " + type, e); + } + } + + @Override + public T lookup(Class type, String name) { + try { + return injector.getInstance(Key.of(type, name)); + } catch (DIException e) { + throw new MavenException("Unable to locate instance of type " + type, e); + } + } + + @Override + public Optional lookupOptional(Class type) { + try { + return Optional.of(injector.getInstance(type)); + } catch (DIException e) { + return Optional.empty(); + } + } + + @Override + public Optional lookupOptional(Class type, String name) { + try { + return Optional.of(injector.getInstance(Key.of(type, name))); + } catch (DIException e) { + return Optional.empty(); + } + } + + @Override + public List lookupList(Class type) { + return injector.getInstance(new Key>() {}); + } + + @Override + public Map lookupMap(Class type) { + return injector.getInstance(new Key>() {}); + } + }; + } + + @Provides + @SuppressWarnings("unused") + static ArtifactManager newArtifactManager() { + return new ArtifactManager() { + private final Map paths = new ConcurrentHashMap<>(); + + @Override + public Optional getPath(Artifact artifact) { + return Optional.ofNullable(paths.get(artifact)); + } + + @Override + public void setPath(ProducedArtifact artifact, Path path) { + paths.put(artifact, path); + } + }; + } + + @Provides + @SuppressWarnings("unused") + static PackagingRegistry newPackagingRegistry(TypeRegistry typeRegistry) { + return id -> Optional.of(new DumbPackaging(id, typeRegistry.require(id), Map.of())); + } + + @Provides + @SuppressWarnings("unused") + static TypeRegistry newTypeRegistry(List providers) { + return new TypeRegistry() { + @Override + public Optional lookup(String id) { + return providers.stream() + .flatMap(p -> p.provides().stream()) + .filter(t -> Objects.equals(id, t.id())) + .findAny(); + } + }; + } + + @Provides + @SuppressWarnings("unused") + static LifecycleRegistry newLifecycleRegistry() { + return new LifecycleRegistry() { + + @Override + public Iterator iterator() { + return Collections.emptyIterator(); + } + + @Override + public Optional lookup(String id) { + return Optional.empty(); + } + + @Override + public List computePhases(Lifecycle lifecycle) { + return List.of(); + } + }; + } + + @Provides + @SuppressWarnings("unused") + static RepositorySystemSupplier newRepositorySystemSupplier() { + return new RepositorySystemSupplier(); + } + + @Provides + @SuppressWarnings("unused") + static RepositorySystem newRepositorySystem(RepositorySystemSupplier repositorySystemSupplier) { + return repositorySystemSupplier.getRepositorySystem(); + } + + @Provides + @SuppressWarnings("unused") + static RemoteRepositoryManager newRemoteRepositoryManager(RepositorySystemSupplier repositorySystemSupplier) { + return repositorySystemSupplier.getRemoteRepositoryManager(); + } + + @Provides + @SuppressWarnings("unused") + static Session newSession(RepositorySystem system, Lookup lookup, Context context) { + + // SettingsDecrypter settingsDecrypter = + // (SettingsDecrypter)Objects.requireNonNull(this.createSettingsDecrypter(preBoot)); + // new DefaultProfileSelector(List.of( + // new JdkVersionProfileActivator(), + // new PropertyProfileActivator(), + // new OperatingSystemProfileActivator(), + // new FileProfileActivator(new ProfileActivationFilePathInterpolator( + // new DefaultPathTranslator(), new DefaultRootLocator())))); + Map properties = context.systemProperties; + + Path userHome = Paths.get(properties.get("user.home")); + Path mavenUserHome = userHome.resolve(".m2"); + Path mavenSystemHome = properties.containsKey("maven.home") + ? Paths.get(properties.get("maven.home")) + : properties.containsKey("env.MAVEN_HOME") ? Paths.get(properties.get("env.MAVEN_HOME")) : null; + + DefaultRepositorySystemSession rsession = new DefaultRepositorySystemSession(h -> false); + rsession.setSystemProperties(properties); + rsession.setConfigProperties(properties); + + ProtoSession session = new ProtoSession( + rsession, + system, + List.of(lookup.lookup(RepositoryFactory.class) + .createRemote("central", "https://repo.maven.apache.org/maven2")), + null, + lookup, + context); + + Settings settings = session.getService(SettingsBuilder.class) + .build( + session, + mavenSystemHome != null ? mavenSystemHome.resolve("settings.xml") : null, + mavenUserHome.resolve("settings.xml")) + .getEffectiveSettings(); + + settings.getProfiles(); + + // local repository + String localRepository = settings.getLocalRepository() != null + ? settings.getLocalRepository() + : mavenUserHome.resolve("repository").toString(); + LocalRepositoryManager llm = + system.newLocalRepositoryManager(rsession, new LocalRepository(localRepository)); + rsession.setLocalRepositoryManager(llm); + // active proxies + // TODO + // active profiles + + // DefaultSession defaultSession = new DefaultSession( + // rsession, + // system, + // List.of(lookup.lookup(RepositoryFactory.class) + // .createRemote("central", "https://repo.maven.apache.org/maven2")), + // null, + // lookup); + + Profile profile = session.getService(SettingsBuilder.class) + .convert(org.apache.maven.api.settings.Profile.newBuilder() + .repositories(settings.getRepositories()) + .pluginRepositories(settings.getPluginRepositories()) + .build()); + RepositoryFactory repositoryFactory = session.getService(RepositoryFactory.class); + List repositories = profile.getRepositories().stream() + .map(repositoryFactory::createRemote) + .toList(); + InternalSession s = (InternalSession) session.withRemoteRepositories(repositories); + InternalSession.associate(rsession, s); + return s; + + // List repositories = repositoryFactory.createRemote(); + + // session.getService(SettingsBuilder.class).convert() + + // settings.getDelegate().getRepositories().stream() + // .map(r -> SettingsUtilsV4.) + // defaultSession.getService(RepositoryFactory.class).createRemote() + // return defaultSession; + } + } + + static class UnsupportedInStandaloneModeException extends MavenException {} + + record DumbPackaging(String id, Type type, Map plugins) implements Packaging {} +} diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/RepositorySystemSupplier.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/RepositorySystemSupplier.java new file mode 100644 index 0000000000..b4188631ca --- /dev/null +++ b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/RepositorySystemSupplier.java @@ -0,0 +1,1098 @@ +/* + * 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.cling.invoker.mvn; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Supplier; + +import org.apache.maven.api.services.ModelBuilder; +import org.apache.maven.internal.impl.DefaultModelUrlNormalizer; +import org.apache.maven.internal.impl.DefaultModelVersionParser; +import org.apache.maven.internal.impl.DefaultModelXmlFactory; +import org.apache.maven.internal.impl.DefaultPluginConfigurationExpander; +import org.apache.maven.internal.impl.DefaultSuperPomProvider; +import org.apache.maven.internal.impl.DefaultUrlNormalizer; +import org.apache.maven.internal.impl.model.DefaultDependencyManagementImporter; +import org.apache.maven.internal.impl.model.DefaultDependencyManagementInjector; +import org.apache.maven.internal.impl.model.DefaultInheritanceAssembler; +import org.apache.maven.internal.impl.model.DefaultInterpolator; +import org.apache.maven.internal.impl.model.DefaultModelBuilder; +import org.apache.maven.internal.impl.model.DefaultModelCacheFactory; +import org.apache.maven.internal.impl.model.DefaultModelInterpolator; +import org.apache.maven.internal.impl.model.DefaultModelNormalizer; +import org.apache.maven.internal.impl.model.DefaultModelPathTranslator; +import org.apache.maven.internal.impl.model.DefaultModelProcessor; +import org.apache.maven.internal.impl.model.DefaultModelValidator; +import org.apache.maven.internal.impl.model.DefaultPathTranslator; +import org.apache.maven.internal.impl.model.DefaultPluginManagementInjector; +import org.apache.maven.internal.impl.model.DefaultProfileInjector; +import org.apache.maven.internal.impl.model.DefaultProfileSelector; +import org.apache.maven.internal.impl.model.ProfileActivationFilePathInterpolator; +import org.apache.maven.internal.impl.model.rootlocator.DefaultRootLocator; +import org.apache.maven.internal.impl.resolver.DefaultArtifactDescriptorReader; +import org.apache.maven.internal.impl.resolver.DefaultModelResolver; +import org.apache.maven.internal.impl.resolver.DefaultVersionRangeResolver; +import org.apache.maven.internal.impl.resolver.DefaultVersionResolver; +import org.apache.maven.internal.impl.resolver.MavenArtifactRelocationSource; +import org.apache.maven.internal.impl.resolver.PluginsMetadataGeneratorFactory; +import org.apache.maven.internal.impl.resolver.SnapshotMetadataGeneratorFactory; +import org.apache.maven.internal.impl.resolver.VersionsMetadataGeneratorFactory; +import org.apache.maven.internal.impl.resolver.relocation.DistributionManagementArtifactRelocationSource; +import org.apache.maven.internal.impl.resolver.relocation.UserPropertiesArtifactRelocationSource; +import org.eclipse.aether.RepositoryListener; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.impl.ArtifactDescriptorReader; +import org.eclipse.aether.impl.ArtifactResolver; +import org.eclipse.aether.impl.DependencyCollector; +import org.eclipse.aether.impl.Deployer; +import org.eclipse.aether.impl.Installer; +import org.eclipse.aether.impl.LocalRepositoryProvider; +import org.eclipse.aether.impl.MetadataGeneratorFactory; +import org.eclipse.aether.impl.MetadataResolver; +import org.eclipse.aether.impl.OfflineController; +import org.eclipse.aether.impl.RemoteRepositoryFilterManager; +import org.eclipse.aether.impl.RemoteRepositoryManager; +import org.eclipse.aether.impl.RepositoryConnectorProvider; +import org.eclipse.aether.impl.RepositoryEventDispatcher; +import org.eclipse.aether.impl.RepositorySystemLifecycle; +import org.eclipse.aether.impl.UpdateCheckManager; +import org.eclipse.aether.impl.UpdatePolicyAnalyzer; +import org.eclipse.aether.impl.VersionRangeResolver; +import org.eclipse.aether.impl.VersionResolver; +import org.eclipse.aether.internal.impl.DefaultArtifactPredicateFactory; +import org.eclipse.aether.internal.impl.DefaultArtifactResolver; +import org.eclipse.aether.internal.impl.DefaultChecksumPolicyProvider; +import org.eclipse.aether.internal.impl.DefaultChecksumProcessor; +import org.eclipse.aether.internal.impl.DefaultDeployer; +import org.eclipse.aether.internal.impl.DefaultInstaller; +import org.eclipse.aether.internal.impl.DefaultLocalPathComposer; +import org.eclipse.aether.internal.impl.DefaultLocalPathPrefixComposerFactory; +import org.eclipse.aether.internal.impl.DefaultLocalRepositoryProvider; +import org.eclipse.aether.internal.impl.DefaultMetadataResolver; +import org.eclipse.aether.internal.impl.DefaultOfflineController; +import org.eclipse.aether.internal.impl.DefaultPathProcessor; +import org.eclipse.aether.internal.impl.DefaultRemoteRepositoryManager; +import org.eclipse.aether.internal.impl.DefaultRepositoryConnectorProvider; +import org.eclipse.aether.internal.impl.DefaultRepositoryEventDispatcher; +import org.eclipse.aether.internal.impl.DefaultRepositoryLayoutProvider; +import org.eclipse.aether.internal.impl.DefaultRepositorySystem; +import org.eclipse.aether.internal.impl.DefaultRepositorySystemLifecycle; +import org.eclipse.aether.internal.impl.DefaultTrackingFileManager; +import org.eclipse.aether.internal.impl.DefaultTransporterProvider; +import org.eclipse.aether.internal.impl.DefaultUpdateCheckManager; +import org.eclipse.aether.internal.impl.DefaultUpdatePolicyAnalyzer; +import org.eclipse.aether.internal.impl.EnhancedLocalRepositoryManagerFactory; +import org.eclipse.aether.internal.impl.LocalPathComposer; +import org.eclipse.aether.internal.impl.LocalPathPrefixComposerFactory; +import org.eclipse.aether.internal.impl.Maven2RepositoryLayoutFactory; +import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; +import org.eclipse.aether.internal.impl.TrackingFileManager; +import org.eclipse.aether.internal.impl.checksum.DefaultChecksumAlgorithmFactorySelector; +import org.eclipse.aether.internal.impl.checksum.Md5ChecksumAlgorithmFactory; +import org.eclipse.aether.internal.impl.checksum.Sha1ChecksumAlgorithmFactory; +import org.eclipse.aether.internal.impl.checksum.Sha256ChecksumAlgorithmFactory; +import org.eclipse.aether.internal.impl.checksum.Sha512ChecksumAlgorithmFactory; +import org.eclipse.aether.internal.impl.checksum.SparseDirectoryTrustedChecksumsSource; +import org.eclipse.aether.internal.impl.checksum.SummaryFileTrustedChecksumsSource; +import org.eclipse.aether.internal.impl.checksum.TrustedToProvidedChecksumsSourceAdapter; +import org.eclipse.aether.internal.impl.collect.DefaultDependencyCollector; +import org.eclipse.aether.internal.impl.collect.DependencyCollectorDelegate; +import org.eclipse.aether.internal.impl.collect.bf.BfDependencyCollector; +import org.eclipse.aether.internal.impl.collect.df.DfDependencyCollector; +import org.eclipse.aether.internal.impl.filter.DefaultRemoteRepositoryFilterManager; +import org.eclipse.aether.internal.impl.filter.GroupIdRemoteRepositoryFilterSource; +import org.eclipse.aether.internal.impl.filter.PrefixesRemoteRepositoryFilterSource; +import org.eclipse.aether.internal.impl.resolution.TrustedChecksumsArtifactResolverPostProcessor; +import org.eclipse.aether.internal.impl.synccontext.DefaultSyncContextFactory; +import org.eclipse.aether.internal.impl.synccontext.named.NameMapper; +import org.eclipse.aether.internal.impl.synccontext.named.NameMappers; +import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactory; +import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactoryImpl; +import org.eclipse.aether.internal.impl.transport.http.DefaultChecksumExtractor; +import org.eclipse.aether.internal.impl.transport.http.Nx2ChecksumExtractor; +import org.eclipse.aether.internal.impl.transport.http.XChecksumExtractor; +import org.eclipse.aether.named.NamedLockFactory; +import org.eclipse.aether.named.providers.FileLockNamedLockFactory; +import org.eclipse.aether.named.providers.LocalReadWriteLockNamedLockFactory; +import org.eclipse.aether.named.providers.LocalSemaphoreNamedLockFactory; +import org.eclipse.aether.named.providers.NoopNamedLockFactory; +import org.eclipse.aether.spi.artifact.ArtifactPredicateFactory; +import org.eclipse.aether.spi.artifact.decorator.ArtifactDecoratorFactory; +import org.eclipse.aether.spi.artifact.generator.ArtifactGeneratorFactory; +import org.eclipse.aether.spi.checksums.ProvidedChecksumsSource; +import org.eclipse.aether.spi.checksums.TrustedChecksumsSource; +import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; +import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactory; +import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactorySelector; +import org.eclipse.aether.spi.connector.checksum.ChecksumPolicyProvider; +import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilterSource; +import org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory; +import org.eclipse.aether.spi.connector.layout.RepositoryLayoutProvider; +import org.eclipse.aether.spi.connector.transport.TransporterFactory; +import org.eclipse.aether.spi.connector.transport.TransporterProvider; +import org.eclipse.aether.spi.connector.transport.http.ChecksumExtractor; +import org.eclipse.aether.spi.connector.transport.http.ChecksumExtractorStrategy; +import org.eclipse.aether.spi.io.ChecksumProcessor; +import org.eclipse.aether.spi.io.PathProcessor; +import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory; +import org.eclipse.aether.spi.resolution.ArtifactResolverPostProcessor; +import org.eclipse.aether.spi.synccontext.SyncContextFactory; +import org.eclipse.aether.util.version.GenericVersionScheme; +import org.eclipse.aether.version.VersionScheme; + +/** + * A simple memorizing {@link Supplier} of {@link RepositorySystem} instance, that on first call + * supplies lazily constructed instance, and on each subsequent call same instance. Hence, this instance should be + * thrown away immediately once repository system was created and there is no need for more instances. If new + * repository system instance needed, new instance of this class must be created. For proper shut down of returned + * repository system instance(s) use {@link RepositorySystem#shutdown()} method on supplied instance(s). + *

+ * Since Resolver 2.0 this class offers access to various components via public getters, and allows even partial object + * graph construction. + *

+ * Extend this class {@code createXXX()} methods and override to customize, if needed. The contract of this class makes + * sure that these (potentially overridden) methods are invoked only once, and instance created by those methods are + * memorized and kept as long as supplier instance is kept open. + *

+ * This class is not thread safe and must be used from one thread only, while the constructed {@link RepositorySystem} + * is thread safe. + *

+ * Important: Given the instance of supplier memorizes the supplier {@link RepositorySystem} instance it supplies, + * their lifecycle is shared as well: once supplied repository system is shut-down, this instance becomes closed as + * well. Any subsequent {@code getXXX} method invocation attempt will fail with {@link IllegalStateException}. + */ +public class RepositorySystemSupplier implements Supplier { + private final AtomicBoolean closed = new AtomicBoolean(false); + + public RepositorySystemSupplier() {} + + private void checkClosed() { + if (closed.get()) { + throw new IllegalStateException("Supplier is closed"); + } + } + + private PathProcessor pathProcessor; + + public final PathProcessor getPathProcessor() { + checkClosed(); + if (pathProcessor == null) { + pathProcessor = createPathProcessor(); + } + return pathProcessor; + } + + protected PathProcessor createPathProcessor() { + return new DefaultPathProcessor(); + } + + private ChecksumProcessor checksumProcessor; + + public final ChecksumProcessor getChecksumProcessor() { + checkClosed(); + if (checksumProcessor == null) { + checksumProcessor = createChecksumProcessor(); + } + return checksumProcessor; + } + + protected ChecksumProcessor createChecksumProcessor() { + return new DefaultChecksumProcessor(getPathProcessor()); + } + + private TrackingFileManager trackingFileManager; + + public final TrackingFileManager getTrackingFileManager() { + checkClosed(); + if (trackingFileManager == null) { + trackingFileManager = createTrackingFileManager(); + } + return trackingFileManager; + } + + protected TrackingFileManager createTrackingFileManager() { + return new DefaultTrackingFileManager(); + } + + private LocalPathComposer localPathComposer; + + public final LocalPathComposer getLocalPathComposer() { + checkClosed(); + if (localPathComposer == null) { + localPathComposer = createLocalPathComposer(); + } + return localPathComposer; + } + + protected LocalPathComposer createLocalPathComposer() { + return new DefaultLocalPathComposer(); + } + + private LocalPathPrefixComposerFactory localPathPrefixComposerFactory; + + public final LocalPathPrefixComposerFactory getLocalPathPrefixComposerFactory() { + checkClosed(); + if (localPathPrefixComposerFactory == null) { + localPathPrefixComposerFactory = createLocalPathPrefixComposerFactory(); + } + return localPathPrefixComposerFactory; + } + + protected LocalPathPrefixComposerFactory createLocalPathPrefixComposerFactory() { + return new DefaultLocalPathPrefixComposerFactory(); + } + + private RepositorySystemLifecycle repositorySystemLifecycle; + + public final RepositorySystemLifecycle getRepositorySystemLifecycle() { + checkClosed(); + if (repositorySystemLifecycle == null) { + repositorySystemLifecycle = createRepositorySystemLifecycle(); + repositorySystemLifecycle.addOnSystemEndedHandler(() -> closed.set(true)); + } + return repositorySystemLifecycle; + } + + protected RepositorySystemLifecycle createRepositorySystemLifecycle() { + return new DefaultRepositorySystemLifecycle(); + } + + private OfflineController offlineController; + + public final OfflineController getOfflineController() { + checkClosed(); + if (offlineController == null) { + offlineController = createOfflineController(); + } + return offlineController; + } + + protected OfflineController createOfflineController() { + return new DefaultOfflineController(); + } + + private UpdatePolicyAnalyzer updatePolicyAnalyzer; + + public final UpdatePolicyAnalyzer getUpdatePolicyAnalyzer() { + checkClosed(); + if (updatePolicyAnalyzer == null) { + updatePolicyAnalyzer = createUpdatePolicyAnalyzer(); + } + return updatePolicyAnalyzer; + } + + protected UpdatePolicyAnalyzer createUpdatePolicyAnalyzer() { + return new DefaultUpdatePolicyAnalyzer(); + } + + private ChecksumPolicyProvider checksumPolicyProvider; + + public final ChecksumPolicyProvider getChecksumPolicyProvider() { + checkClosed(); + if (checksumPolicyProvider == null) { + checksumPolicyProvider = createChecksumPolicyProvider(); + } + return checksumPolicyProvider; + } + + protected ChecksumPolicyProvider createChecksumPolicyProvider() { + return new DefaultChecksumPolicyProvider(); + } + + private UpdateCheckManager updateCheckManager; + + public final UpdateCheckManager getUpdateCheckManager() { + checkClosed(); + if (updateCheckManager == null) { + updateCheckManager = createUpdateCheckManager(); + } + return updateCheckManager; + } + + protected UpdateCheckManager createUpdateCheckManager() { + return new DefaultUpdateCheckManager(getTrackingFileManager(), getUpdatePolicyAnalyzer(), getPathProcessor()); + } + + private Map namedLockFactories; + + public final Map getNamedLockFactories() { + checkClosed(); + if (namedLockFactories == null) { + namedLockFactories = createNamedLockFactories(); + } + return namedLockFactories; + } + + protected Map createNamedLockFactories() { + HashMap result = new HashMap<>(); + result.put(NoopNamedLockFactory.NAME, new NoopNamedLockFactory()); + result.put(LocalReadWriteLockNamedLockFactory.NAME, new LocalReadWriteLockNamedLockFactory()); + result.put(LocalSemaphoreNamedLockFactory.NAME, new LocalSemaphoreNamedLockFactory()); + result.put(FileLockNamedLockFactory.NAME, new FileLockNamedLockFactory()); + return result; + } + + private Map nameMappers; + + public final Map getNameMappers() { + checkClosed(); + if (nameMappers == null) { + nameMappers = createNameMappers(); + } + return nameMappers; + } + + protected Map createNameMappers() { + HashMap result = new HashMap<>(); + result.put(NameMappers.STATIC_NAME, NameMappers.staticNameMapper()); + result.put(NameMappers.GAV_NAME, NameMappers.gavNameMapper()); + result.put(NameMappers.DISCRIMINATING_NAME, NameMappers.discriminatingNameMapper()); + result.put(NameMappers.FILE_GAV_NAME, NameMappers.fileGavNameMapper()); + result.put(NameMappers.FILE_HGAV_NAME, NameMappers.fileHashingGavNameMapper()); + return result; + } + + private NamedLockFactoryAdapterFactory namedLockFactoryAdapterFactory; + + public final NamedLockFactoryAdapterFactory getNamedLockFactoryAdapterFactory() { + checkClosed(); + if (namedLockFactoryAdapterFactory == null) { + namedLockFactoryAdapterFactory = createNamedLockFactoryAdapterFactory(); + } + return namedLockFactoryAdapterFactory; + } + + protected NamedLockFactoryAdapterFactory createNamedLockFactoryAdapterFactory() { + return new NamedLockFactoryAdapterFactoryImpl( + getNamedLockFactories(), getNameMappers(), getRepositorySystemLifecycle()); + } + + private SyncContextFactory syncContextFactory; + + public final SyncContextFactory getSyncContextFactory() { + checkClosed(); + if (syncContextFactory == null) { + syncContextFactory = createSyncContextFactory(); + } + return syncContextFactory; + } + + protected SyncContextFactory createSyncContextFactory() { + return new DefaultSyncContextFactory(getNamedLockFactoryAdapterFactory()); + } + + private Map checksumAlgorithmFactories; + + public final Map getChecksumAlgorithmFactories() { + checkClosed(); + if (checksumAlgorithmFactories == null) { + checksumAlgorithmFactories = createChecksumAlgorithmFactories(); + } + return checksumAlgorithmFactories; + } + + protected Map createChecksumAlgorithmFactories() { + HashMap result = new HashMap<>(); + result.put(Sha512ChecksumAlgorithmFactory.NAME, new Sha512ChecksumAlgorithmFactory()); + result.put(Sha256ChecksumAlgorithmFactory.NAME, new Sha256ChecksumAlgorithmFactory()); + result.put(Sha1ChecksumAlgorithmFactory.NAME, new Sha1ChecksumAlgorithmFactory()); + result.put(Md5ChecksumAlgorithmFactory.NAME, new Md5ChecksumAlgorithmFactory()); + return result; + } + + private ChecksumAlgorithmFactorySelector checksumAlgorithmFactorySelector; + + public final ChecksumAlgorithmFactorySelector getChecksumAlgorithmFactorySelector() { + checkClosed(); + if (checksumAlgorithmFactorySelector == null) { + checksumAlgorithmFactorySelector = createChecksumAlgorithmFactorySelector(); + } + return checksumAlgorithmFactorySelector; + } + + protected ChecksumAlgorithmFactorySelector createChecksumAlgorithmFactorySelector() { + return new DefaultChecksumAlgorithmFactorySelector(getChecksumAlgorithmFactories()); + } + + private ArtifactPredicateFactory artifactPredicateFactory; + + public final ArtifactPredicateFactory getArtifactPredicateFactory() { + checkClosed(); + if (artifactPredicateFactory == null) { + artifactPredicateFactory = createArtifactPredicateFactory(); + } + return artifactPredicateFactory; + } + + protected ArtifactPredicateFactory createArtifactPredicateFactory() { + return new DefaultArtifactPredicateFactory(getChecksumAlgorithmFactorySelector()); + } + + private Map repositoryLayoutFactories; + + public final Map getRepositoryLayoutFactories() { + checkClosed(); + if (repositoryLayoutFactories == null) { + repositoryLayoutFactories = createRepositoryLayoutFactories(); + } + return repositoryLayoutFactories; + } + + protected Map createRepositoryLayoutFactories() { + HashMap result = new HashMap<>(); + result.put( + Maven2RepositoryLayoutFactory.NAME, + new Maven2RepositoryLayoutFactory( + getChecksumAlgorithmFactorySelector(), getArtifactPredicateFactory())); + return result; + } + + private RepositoryLayoutProvider repositoryLayoutProvider; + + public final RepositoryLayoutProvider getRepositoryLayoutProvider() { + checkClosed(); + if (repositoryLayoutProvider == null) { + repositoryLayoutProvider = createRepositoryLayoutProvider(); + } + return repositoryLayoutProvider; + } + + protected RepositoryLayoutProvider createRepositoryLayoutProvider() { + return new DefaultRepositoryLayoutProvider(getRepositoryLayoutFactories()); + } + + private LocalRepositoryProvider localRepositoryProvider; + + public final LocalRepositoryProvider getLocalRepositoryProvider() { + checkClosed(); + if (localRepositoryProvider == null) { + localRepositoryProvider = createLocalRepositoryProvider(); + } + return localRepositoryProvider; + } + + protected LocalRepositoryProvider createLocalRepositoryProvider() { + LocalPathComposer localPathComposer = getLocalPathComposer(); + HashMap localRepositoryProviders = new HashMap<>(2); + localRepositoryProviders.put( + SimpleLocalRepositoryManagerFactory.NAME, new SimpleLocalRepositoryManagerFactory(localPathComposer)); + localRepositoryProviders.put( + EnhancedLocalRepositoryManagerFactory.NAME, + new EnhancedLocalRepositoryManagerFactory( + localPathComposer, getTrackingFileManager(), getLocalPathPrefixComposerFactory())); + return new DefaultLocalRepositoryProvider(localRepositoryProviders); + } + + private RemoteRepositoryManager remoteRepositoryManager; + + public final RemoteRepositoryManager getRemoteRepositoryManager() { + checkClosed(); + if (remoteRepositoryManager == null) { + remoteRepositoryManager = createRemoteRepositoryManager(); + } + return remoteRepositoryManager; + } + + protected RemoteRepositoryManager createRemoteRepositoryManager() { + return new DefaultRemoteRepositoryManager(getUpdatePolicyAnalyzer(), getChecksumPolicyProvider()); + } + + private Map remoteRepositoryFilterSources; + + public final Map getRemoteRepositoryFilterSources() { + checkClosed(); + if (remoteRepositoryFilterSources == null) { + remoteRepositoryFilterSources = createRemoteRepositoryFilterSources(); + } + return remoteRepositoryFilterSources; + } + + protected Map createRemoteRepositoryFilterSources() { + HashMap result = new HashMap<>(); + result.put( + GroupIdRemoteRepositoryFilterSource.NAME, + new GroupIdRemoteRepositoryFilterSource(getRepositorySystemLifecycle())); + result.put( + PrefixesRemoteRepositoryFilterSource.NAME, + new PrefixesRemoteRepositoryFilterSource(getRepositoryLayoutProvider())); + return result; + } + + private RemoteRepositoryFilterManager remoteRepositoryFilterManager; + + public final RemoteRepositoryFilterManager getRemoteRepositoryFilterManager() { + checkClosed(); + if (remoteRepositoryFilterManager == null) { + remoteRepositoryFilterManager = createRemoteRepositoryFilterManager(); + } + return remoteRepositoryFilterManager; + } + + protected RemoteRepositoryFilterManager createRemoteRepositoryFilterManager() { + return new DefaultRemoteRepositoryFilterManager(getRemoteRepositoryFilterSources()); + } + + private Map repositoryListeners; + + public final Map getRepositoryListeners() { + checkClosed(); + if (repositoryListeners == null) { + repositoryListeners = createRepositoryListeners(); + } + return repositoryListeners; + } + + protected Map createRepositoryListeners() { + return new HashMap<>(); + } + + private RepositoryEventDispatcher repositoryEventDispatcher; + + public final RepositoryEventDispatcher getRepositoryEventDispatcher() { + checkClosed(); + if (repositoryEventDispatcher == null) { + repositoryEventDispatcher = createRepositoryEventDispatcher(); + } + return repositoryEventDispatcher; + } + + protected RepositoryEventDispatcher createRepositoryEventDispatcher() { + return new DefaultRepositoryEventDispatcher(getRepositoryListeners()); + } + + private Map trustedChecksumsSources; + + public final Map getTrustedChecksumsSources() { + checkClosed(); + if (trustedChecksumsSources == null) { + trustedChecksumsSources = createTrustedChecksumsSources(); + } + return trustedChecksumsSources; + } + + protected Map createTrustedChecksumsSources() { + HashMap result = new HashMap<>(); + result.put( + SparseDirectoryTrustedChecksumsSource.NAME, + new SparseDirectoryTrustedChecksumsSource(getChecksumProcessor(), getLocalPathComposer())); + result.put( + SummaryFileTrustedChecksumsSource.NAME, + new SummaryFileTrustedChecksumsSource(getLocalPathComposer(), getRepositorySystemLifecycle())); + return result; + } + + private Map providedChecksumsSources; + + public final Map getProvidedChecksumsSources() { + checkClosed(); + if (providedChecksumsSources == null) { + providedChecksumsSources = createProvidedChecksumsSources(); + } + return providedChecksumsSources; + } + + protected Map createProvidedChecksumsSources() { + HashMap result = new HashMap<>(); + result.put( + TrustedToProvidedChecksumsSourceAdapter.NAME, + new TrustedToProvidedChecksumsSourceAdapter(getTrustedChecksumsSources())); + return result; + } + + private Map checksumExtractorStrategies; + + public final Map getChecksumExtractorStrategies() { + checkClosed(); + if (checksumExtractorStrategies == null) { + checksumExtractorStrategies = createChecksumExtractorStrategies(); + } + return checksumExtractorStrategies; + } + + protected Map createChecksumExtractorStrategies() { + HashMap result = new HashMap<>(); + result.put(XChecksumExtractor.NAME, new XChecksumExtractor()); + result.put(Nx2ChecksumExtractor.NAME, new Nx2ChecksumExtractor()); + return result; + } + + private ChecksumExtractor checksumExtractor; + + public final ChecksumExtractor getChecksumExtractor() { + checkClosed(); + if (checksumExtractor == null) { + checksumExtractor = createChecksumExtractor(); + } + return checksumExtractor; + } + + protected ChecksumExtractor createChecksumExtractor() { + return new DefaultChecksumExtractor(getChecksumExtractorStrategies()); + } + + private Map transporterFactories; + + public final Map getTransporterFactories() { + checkClosed(); + if (transporterFactories == null) { + transporterFactories = createTransporterFactories(); + } + return transporterFactories; + } + + protected Map createTransporterFactories() { + HashMap result = new HashMap<>(); + // result.put(FileTransporterFactory.NAME, new FileTransporterFactory()); + // result.put( + // ApacheTransporterFactory.NAME, + // new ApacheTransporterFactory(getChecksumExtractor(), getPathProcessor())); + return result; + } + + private TransporterProvider transporterProvider; + + public final TransporterProvider getTransporterProvider() { + checkClosed(); + if (transporterProvider == null) { + transporterProvider = createTransporterProvider(); + } + return transporterProvider; + } + + protected TransporterProvider createTransporterProvider() { + return new DefaultTransporterProvider(getTransporterFactories()); + } + + // private BasicRepositoryConnectorFactory basicRepositoryConnectorFactory; + // + // public final BasicRepositoryConnectorFactory getBasicRepositoryConnectorFactory() { + // checkClosed(); + // if (basicRepositoryConnectorFactory == null) { + // basicRepositoryConnectorFactory = createBasicRepositoryConnectorFactory(); + // } + // return basicRepositoryConnectorFactory; + // } + // + // protected BasicRepositoryConnectorFactory createBasicRepositoryConnectorFactory() { + // return new BasicRepositoryConnectorFactory( + // getTransporterProvider(), + // getRepositoryLayoutProvider(), + // getChecksumPolicyProvider(), + // getChecksumProcessor(), + // getProvidedChecksumsSources()); + // } + + private Map repositoryConnectorFactories; + + public final Map getRepositoryConnectorFactories() { + checkClosed(); + if (repositoryConnectorFactories == null) { + repositoryConnectorFactories = createRepositoryConnectorFactories(); + } + return repositoryConnectorFactories; + } + + protected Map createRepositoryConnectorFactories() { + HashMap result = new HashMap<>(); + // result.put(BasicRepositoryConnectorFactory.NAME, getBasicRepositoryConnectorFactory()); + return result; + } + + private RepositoryConnectorProvider repositoryConnectorProvider; + + public final RepositoryConnectorProvider getRepositoryConnectorProvider() { + checkClosed(); + if (repositoryConnectorProvider == null) { + repositoryConnectorProvider = createRepositoryConnectorProvider(); + } + return repositoryConnectorProvider; + } + + protected RepositoryConnectorProvider createRepositoryConnectorProvider() { + return new DefaultRepositoryConnectorProvider( + getRepositoryConnectorFactories(), getRemoteRepositoryFilterManager()); + } + + private Installer installer; + + public final Installer getInstaller() { + checkClosed(); + if (installer == null) { + installer = createInstaller(); + } + return installer; + } + + protected Installer createInstaller() { + return new DefaultInstaller( + getPathProcessor(), + getRepositoryEventDispatcher(), + getArtifactGeneratorFactories(), + getMetadataGeneratorFactories(), + getSyncContextFactory()); + } + + private Deployer deployer; + + public final Deployer getDeployer() { + checkClosed(); + if (deployer == null) { + deployer = createDeployer(); + } + return deployer; + } + + protected Deployer createDeployer() { + return new DefaultDeployer( + getPathProcessor(), + getRepositoryEventDispatcher(), + getRepositoryConnectorProvider(), + getRemoteRepositoryManager(), + getUpdateCheckManager(), + getArtifactGeneratorFactories(), + getMetadataGeneratorFactories(), + getSyncContextFactory(), + getOfflineController()); + } + + private Map dependencyCollectorDelegates; + + public final Map getDependencyCollectorDelegates() { + checkClosed(); + if (dependencyCollectorDelegates == null) { + dependencyCollectorDelegates = createDependencyCollectorDelegates(); + } + return dependencyCollectorDelegates; + } + + protected Map createDependencyCollectorDelegates() { + RemoteRepositoryManager remoteRepositoryManager = getRemoteRepositoryManager(); + ArtifactDescriptorReader artifactDescriptorReader = getArtifactDescriptorReader(); + VersionRangeResolver versionRangeResolver = getVersionRangeResolver(); + HashMap result = new HashMap<>(); + result.put( + DfDependencyCollector.NAME, + new DfDependencyCollector( + remoteRepositoryManager, + artifactDescriptorReader, + versionRangeResolver, + getArtifactDecoratorFactories())); + result.put( + BfDependencyCollector.NAME, + new BfDependencyCollector( + remoteRepositoryManager, + artifactDescriptorReader, + versionRangeResolver, + getArtifactDecoratorFactories())); + return result; + } + + private DependencyCollector dependencyCollector; + + public final DependencyCollector getDependencyCollector() { + checkClosed(); + if (dependencyCollector == null) { + dependencyCollector = createDependencyCollector(); + } + return dependencyCollector; + } + + protected DependencyCollector createDependencyCollector() { + return new DefaultDependencyCollector(getDependencyCollectorDelegates()); + } + + private Map artifactResolverPostProcessors; + + public final Map getArtifactResolverPostProcessors() { + checkClosed(); + if (artifactResolverPostProcessors == null) { + artifactResolverPostProcessors = createArtifactResolverPostProcessors(); + } + return artifactResolverPostProcessors; + } + + protected Map createArtifactResolverPostProcessors() { + HashMap result = new HashMap<>(); + result.put( + TrustedChecksumsArtifactResolverPostProcessor.NAME, + new TrustedChecksumsArtifactResolverPostProcessor( + getChecksumAlgorithmFactorySelector(), getTrustedChecksumsSources())); + return result; + } + + private ArtifactResolver artifactResolver; + + public final ArtifactResolver getArtifactResolver() { + checkClosed(); + if (artifactResolver == null) { + artifactResolver = createArtifactResolver(); + } + return artifactResolver; + } + + protected ArtifactResolver createArtifactResolver() { + return new DefaultArtifactResolver( + getPathProcessor(), + getRepositoryEventDispatcher(), + getVersionResolver(), + getUpdateCheckManager(), + getRepositoryConnectorProvider(), + getRemoteRepositoryManager(), + getSyncContextFactory(), + getOfflineController(), + getArtifactResolverPostProcessors(), + getRemoteRepositoryFilterManager()); + } + + private MetadataResolver metadataResolver; + + public final MetadataResolver getMetadataResolver() { + checkClosed(); + if (metadataResolver == null) { + metadataResolver = createMetadataResolver(); + } + return metadataResolver; + } + + protected MetadataResolver createMetadataResolver() { + return new DefaultMetadataResolver( + getRepositoryEventDispatcher(), + getUpdateCheckManager(), + getRepositoryConnectorProvider(), + getRemoteRepositoryManager(), + getSyncContextFactory(), + getOfflineController(), + getRemoteRepositoryFilterManager(), + getPathProcessor()); + } + + private VersionScheme versionScheme; + + public final VersionScheme getVersionScheme() { + checkClosed(); + if (versionScheme == null) { + versionScheme = createVersionScheme(); + } + return versionScheme; + } + + protected VersionScheme createVersionScheme() { + return new GenericVersionScheme(); + } + + private Map artifactGeneratorFactories; + + public final Map getArtifactGeneratorFactories() { + checkClosed(); + if (artifactGeneratorFactories == null) { + artifactGeneratorFactories = createArtifactGeneratorFactories(); + } + return artifactGeneratorFactories; + } + + protected Map createArtifactGeneratorFactories() { + // by default none, this is extension point + return new HashMap<>(); + } + + private Map artifactDecoratorFactories; + + public final Map getArtifactDecoratorFactories() { + checkClosed(); + if (artifactDecoratorFactories == null) { + artifactDecoratorFactories = createArtifactDecoratorFactories(); + } + return artifactDecoratorFactories; + } + + protected Map createArtifactDecoratorFactories() { + // by default none, this is extension point + return new HashMap<>(); + } + + // Maven provided + + private Map metadataGeneratorFactories; + + public final Map getMetadataGeneratorFactories() { + checkClosed(); + if (metadataGeneratorFactories == null) { + metadataGeneratorFactories = createMetadataGeneratorFactories(); + } + return metadataGeneratorFactories; + } + + protected Map createMetadataGeneratorFactories() { + // from maven-resolver-provider + HashMap result = new HashMap<>(); + result.put(PluginsMetadataGeneratorFactory.NAME, new PluginsMetadataGeneratorFactory()); + result.put(VersionsMetadataGeneratorFactory.NAME, new VersionsMetadataGeneratorFactory()); + result.put(SnapshotMetadataGeneratorFactory.NAME, new SnapshotMetadataGeneratorFactory()); + return result; + } + + private LinkedHashMap artifactRelocationSources; + + public final LinkedHashMap getMavenArtifactRelocationSources() { + checkClosed(); + if (artifactRelocationSources == null) { + artifactRelocationSources = createMavenArtifactRelocationSources(); + } + return artifactRelocationSources; + } + + protected LinkedHashMap createMavenArtifactRelocationSources() { + // from maven-resolver-provider + LinkedHashMap result = new LinkedHashMap<>(); + result.put(UserPropertiesArtifactRelocationSource.NAME, new UserPropertiesArtifactRelocationSource()); + result.put( + DistributionManagementArtifactRelocationSource.NAME, + new DistributionManagementArtifactRelocationSource()); + return result; + } + + private ArtifactDescriptorReader artifactDescriptorReader; + + public final ArtifactDescriptorReader getArtifactDescriptorReader() { + checkClosed(); + if (artifactDescriptorReader == null) { + artifactDescriptorReader = createArtifactDescriptorReader(); + } + return artifactDescriptorReader; + } + + protected ArtifactDescriptorReader createArtifactDescriptorReader() { + // from maven-resolver-provider + return new DefaultArtifactDescriptorReader( + getVersionResolver(), + getArtifactResolver(), + getModelBuilder(), + getRepositoryEventDispatcher(), + getMavenArtifactRelocationSources()); + } + + private VersionResolver versionResolver; + + public final VersionResolver getVersionResolver() { + checkClosed(); + if (versionResolver == null) { + versionResolver = createVersionResolver(); + } + return versionResolver; + } + + protected VersionResolver createVersionResolver() { + // from maven-resolver-provider + return new DefaultVersionResolver( + getMetadataResolver(), getSyncContextFactory(), getRepositoryEventDispatcher()); + } + + private VersionRangeResolver versionRangeResolver; + + public final VersionRangeResolver getVersionRangeResolver() { + checkClosed(); + if (versionRangeResolver == null) { + versionRangeResolver = createVersionRangeResolver(); + } + return versionRangeResolver; + } + + protected VersionRangeResolver createVersionRangeResolver() { + // from maven-resolver-provider + return new DefaultVersionRangeResolver( + getMetadataResolver(), getSyncContextFactory(), getRepositoryEventDispatcher(), getVersionScheme()); + } + + private ModelBuilder modelBuilder; + + public final ModelBuilder getModelBuilder() { + checkClosed(); + if (modelBuilder == null) { + modelBuilder = createModelBuilder(); + } + return modelBuilder; + } + + protected ModelBuilder createModelBuilder() { + // from maven-model-builder + DefaultModelProcessor modelProcessor = new DefaultModelProcessor(new DefaultModelXmlFactory(), List.of()); + return new DefaultModelBuilder( + modelProcessor, + new DefaultModelValidator(), + new DefaultModelNormalizer(), + new DefaultModelInterpolator( + new DefaultPathTranslator(), + new DefaultUrlNormalizer(), + new DefaultRootLocator(), + new DefaultInterpolator()), + new DefaultModelPathTranslator(new DefaultPathTranslator()), + new DefaultModelUrlNormalizer(new DefaultUrlNormalizer()), + new DefaultSuperPomProvider(modelProcessor), + new DefaultInheritanceAssembler(), + new DefaultProfileSelector(), + new DefaultProfileInjector(), + new DefaultPluginManagementInjector(), + new DefaultDependencyManagementInjector(), + new DefaultDependencyManagementImporter(), + new DefaultPluginConfigurationExpander(), + new ProfileActivationFilePathInterpolator( + new DefaultPathTranslator(), new DefaultRootLocator(), new DefaultInterpolator()), + new DefaultModelVersionParser(getVersionScheme()), + List.of(), + new DefaultModelCacheFactory(), + new DefaultModelResolver(), + new DefaultInterpolator()); + } + + private RepositorySystem repositorySystem; + + public final RepositorySystem getRepositorySystem() { + checkClosed(); + if (repositorySystem == null) { + repositorySystem = createRepositorySystem(); + } + return repositorySystem; + } + + protected RepositorySystem createRepositorySystem() { + return new DefaultRepositorySystem( + getVersionResolver(), + getVersionRangeResolver(), + getArtifactResolver(), + getMetadataResolver(), + getArtifactDescriptorReader(), + getDependencyCollector(), + getInstaller(), + getDeployer(), + getLocalRepositoryProvider(), + getSyncContextFactory(), + getRemoteRepositoryManager(), + getRepositorySystemLifecycle(), + getArtifactDecoratorFactories()); + } + + @Override + public RepositorySystem get() { + return getRepositorySystem(); + } +} diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/forked/DefaultForkedMavenInvoker.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/forked/DefaultForkedMavenInvoker.java index bd303fa673..647c4a44d9 100644 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/forked/DefaultForkedMavenInvoker.java +++ b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/forked/DefaultForkedMavenInvoker.java @@ -27,7 +27,7 @@ import org.apache.maven.api.cli.InvokerException; import org.apache.maven.api.cli.mvn.MavenOptions; import org.apache.maven.api.cli.mvn.forked.ForkedMavenInvoker; import org.apache.maven.api.cli.mvn.forked.ForkedMavenInvokerRequest; -import org.apache.maven.utils.Os; +import org.apache.maven.internal.impl.model.profile.Os; import static java.util.Objects.requireNonNull; diff --git a/maven-toolchain-builder/src/test/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilderTest.java b/maven-toolchain-builder/src/test/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilderTest.java index 6ae5d2cd3a..a41e49a1e4 100644 --- a/maven-toolchain-builder/src/test/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilderTest.java +++ b/maven-toolchain-builder/src/test/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilderTest.java @@ -32,6 +32,7 @@ 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.model.PersistedToolchains; import org.apache.maven.toolchain.model.ToolchainModel; import org.codehaus.plexus.interpolation.os.OperatingSystemUtils; @@ -72,7 +73,9 @@ class DefaultToolchainsBuilderTest { OperatingSystemUtils.setEnvVarSource(new TestEnvVarSource(envVarMap)); toolchainBuilder = new DefaultToolchainsBuilder( - new org.apache.maven.internal.impl.DefaultToolchainsBuilder(), toolchainsXmlFactory); + new org.apache.maven.internal.impl.DefaultToolchainsBuilder( + new DefaultInterpolator(), toolchainsXmlFactory), + toolchainsXmlFactory); } @Test