From ea488c69a0b8fc69e68558a5249d62b897df2445 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Mon, 20 Nov 2023 19:29:37 +0100 Subject: [PATCH 01/11] Add an InternalSession interface to avoid casting to the implementation in various places --- .../java/org/apache/maven/api/Session.java | 7 ++ .../java/org/apache/maven/DefaultMaven.java | 4 +- .../maven/internal/impl/AbstractSession.java | 2 +- .../maven/internal/impl/DefaultArtifact.java | 4 +- .../impl/DefaultArtifactCoordinate.java | 4 +- .../DefaultArtifactCoordinateFactory.java | 4 +- .../impl/DefaultArtifactDeployer.java | 4 +- .../internal/impl/DefaultArtifactFactory.java | 4 +- .../impl/DefaultArtifactInstaller.java | 4 +- .../internal/impl/DefaultArtifactManager.java | 4 +- .../impl/DefaultArtifactResolver.java | 4 +- .../internal/impl/DefaultDependency.java | 6 +- .../impl/DefaultDependencyCollector.java | 4 +- .../impl/DefaultDependencyCoordinate.java | 4 +- .../DefaultDependencyCoordinateFactory.java | 4 +- .../maven/internal/impl/DefaultEvent.java | 4 +- .../impl/DefaultLocalRepositoryManager.java | 6 +- .../maven/internal/impl/DefaultNode.java | 4 +- .../maven/internal/impl/DefaultProject.java | 6 +- .../internal/impl/DefaultProjectBuilder.java | 2 +- .../internal/impl/DefaultProjectManager.java | 6 +- .../internal/impl/DefaultSessionFactory.java | 2 +- .../internal/impl/DefaultSettingsBuilder.java | 2 +- .../impl/DefaultToolchainManager.java | 8 +- .../impl/DefaultTransportProvider.java | 2 +- .../maven/internal/impl/EventSpyImpl.java | 2 +- .../maven/internal/impl/InternalSession.java | 88 +++++++++++++++++++ .../plugin/DefaultBuildPluginManager.java | 4 +- .../PluginParameterExpressionEvaluatorV4.java | 6 +- .../internal/DefaultMavenPluginManager.java | 4 +- .../maven/project/DefaultProjectBuilder.java | 4 +- .../scope/internal/SessionScopeModule.java | 4 +- .../apache/maven/internal/impl/TestApi.java | 2 +- 33 files changed, 150 insertions(+), 69 deletions(-) create mode 100644 maven-core/src/main/java/org/apache/maven/internal/impl/InternalSession.java diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java index c9835deb6a46..ed396b857b0f 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java @@ -214,6 +214,13 @@ ArtifactCoordinate createArtifactCoordinate( @Nonnull DependencyCoordinate createDependencyCoordinate(@Nonnull ArtifactCoordinate coordinate); + /** + * Shortcut for getService(DependencyFactory.class).create(...) + * @see DependencyCoordinateFactory#create(Session, Dependency) + */ + @Nonnull + DependencyCoordinate createDependencyCoordinate(@Nonnull Dependency dependency); + /** * Shortcut for getService(ArtifactFactory.class).create(...) * @see org.apache.maven.api.services.ArtifactFactory#create(Session, String, String, String, String) diff --git a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java index 19475a8af85f..85aee3f98eed 100644 --- a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java +++ b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java @@ -60,8 +60,8 @@ import org.apache.maven.graph.ProjectSelector; import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory; import org.apache.maven.internal.aether.MavenChainedWorkspaceReader; -import org.apache.maven.internal.impl.DefaultSession; import org.apache.maven.internal.impl.DefaultSessionFactory; +import org.apache.maven.internal.impl.InternalSession; import org.apache.maven.lifecycle.LifecycleExecutionException; import org.apache.maven.lifecycle.internal.ExecutionEventCatapult; import org.apache.maven.lifecycle.internal.LifecycleStarter; @@ -222,7 +222,7 @@ private MavenExecutionResult doExecute(MavenExecutionRequest request) { sessionScope.seed(MavenSession.class, session); sessionScope.seed(Session.class, session.getSession()); - sessionScope.seed(DefaultSession.class, (DefaultSession) session.getSession()); + sessionScope.seed(InternalSession.class, InternalSession.from(session.getSession())); legacySupport.setSession(session); diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/AbstractSession.java b/maven-core/src/main/java/org/apache/maven/internal/impl/AbstractSession.java index 619b56a15817..62b0bfe7ba97 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/AbstractSession.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/AbstractSession.java @@ -66,7 +66,7 @@ import static org.apache.maven.internal.impl.Utils.nonNull; -public abstract class AbstractSession implements Session { +public abstract class AbstractSession implements InternalSession { private final List listeners = new CopyOnWriteArrayList<>(); private final Map allNodes = diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifact.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifact.java index ed865b81b196..b12ef94b3c8b 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifact.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifact.java @@ -31,11 +31,11 @@ * A wrapper class around a maven resolver artifact. */ public class DefaultArtifact implements Artifact { - private final @Nonnull AbstractSession session; + private final @Nonnull InternalSession session; private final @Nonnull org.eclipse.aether.artifact.Artifact artifact; private final String id; - public DefaultArtifact(@Nonnull AbstractSession session, @Nonnull org.eclipse.aether.artifact.Artifact artifact) { + public DefaultArtifact(@Nonnull InternalSession session, @Nonnull org.eclipse.aether.artifact.Artifact artifact) { this.session = nonNull(session, "session can not be null"); this.artifact = nonNull(artifact, "artifact can not be null"); this.id = getGroupId() diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinate.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinate.java index d76b161766ce..18bc1b029e35 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinate.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinate.java @@ -30,11 +30,11 @@ * A wrapper class around a maven resolver artifact. */ public class DefaultArtifactCoordinate implements ArtifactCoordinate { - private final @Nonnull AbstractSession session; + private final @Nonnull InternalSession session; private final @Nonnull org.eclipse.aether.artifact.Artifact coordinate; public DefaultArtifactCoordinate( - @Nonnull AbstractSession session, @Nonnull org.eclipse.aether.artifact.Artifact coordinate) { + @Nonnull InternalSession session, @Nonnull org.eclipse.aether.artifact.Artifact coordinate) { this.session = nonNull(session, "session can not be null"); this.coordinate = nonNull(coordinate, "coordinate can not be null"); } diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinateFactory.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinateFactory.java index 3b2a1658476c..161afb8ec46c 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinateFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactCoordinateFactory.java @@ -27,7 +27,6 @@ import org.apache.maven.api.services.ArtifactCoordinateFactoryRequest; import org.eclipse.aether.artifact.ArtifactType; -import static org.apache.maven.internal.impl.Utils.cast; import static org.apache.maven.internal.impl.Utils.nonNull; @Named @@ -36,8 +35,7 @@ public class DefaultArtifactCoordinateFactory implements ArtifactCoordinateFacto @Override public ArtifactCoordinate create(@Nonnull ArtifactCoordinateFactoryRequest request) { nonNull(request, "request can not be null"); - DefaultSession session = - cast(DefaultSession.class, request.getSession(), "request.session should be a " + DefaultSession.class); + InternalSession session = InternalSession.from(request.getSession()); ArtifactType type = null; if (request.getType() != null) { type = session.getSession().getArtifactTypeRegistry().get(request.getType()); diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactDeployer.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactDeployer.java index 1f48abc05985..b2afdc4ad9dd 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactDeployer.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactDeployer.java @@ -35,7 +35,6 @@ import org.eclipse.aether.deployment.DeployResult; import org.eclipse.aether.deployment.DeploymentException; -import static org.apache.maven.internal.impl.Utils.cast; import static org.apache.maven.internal.impl.Utils.nonNull; /** @@ -54,8 +53,7 @@ public class DefaultArtifactDeployer implements ArtifactDeployer { @Override public void deploy(@Nonnull ArtifactDeployerRequest request) { nonNull(request, "request can not be null"); - DefaultSession session = - cast(DefaultSession.class, request.getSession(), "request.session should be a " + DefaultSession.class); + InternalSession session = InternalSession.from(request.getSession()); Collection artifacts = nonNull(request.getArtifacts(), "request.artifacts can not be null"); RemoteRepository repository = nonNull(request.getRepository(), "request.repository can not be null"); try { diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactFactory.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactFactory.java index 2788b77284d6..26a4b60b3bbf 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactFactory.java @@ -27,7 +27,6 @@ import org.apache.maven.api.services.ArtifactFactoryRequest; import org.eclipse.aether.artifact.ArtifactType; -import static org.apache.maven.internal.impl.Utils.cast; import static org.apache.maven.internal.impl.Utils.nonNull; @Named @@ -36,8 +35,7 @@ public class DefaultArtifactFactory implements ArtifactFactory { @Override public Artifact create(@Nonnull ArtifactFactoryRequest request) { nonNull(request, "request can not be null"); - DefaultSession session = - cast(DefaultSession.class, request.getSession(), "request.session should be a " + DefaultSession.class); + InternalSession session = InternalSession.from(request.getSession()); ArtifactType type = null; if (request.getType() != null) { type = session.getSession().getArtifactTypeRegistry().get(request.getType()); diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactInstaller.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactInstaller.java index 58b7b7e37621..6107d7840a49 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactInstaller.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactInstaller.java @@ -31,7 +31,6 @@ import org.eclipse.aether.installation.InstallResult; import org.eclipse.aether.installation.InstallationException; -import static org.apache.maven.internal.impl.Utils.cast; import static org.apache.maven.internal.impl.Utils.nonNull; @Named @@ -48,8 +47,7 @@ public class DefaultArtifactInstaller implements ArtifactInstaller { @Override public void install(ArtifactInstallerRequest request) throws ArtifactInstallerException, IllegalArgumentException { nonNull(request, "request can not be null"); - DefaultSession session = - cast(DefaultSession.class, request.getSession(), "request.session should be a " + DefaultSession.class); + InternalSession session = InternalSession.from(request.getSession()); try { InstallRequest installRequest = new InstallRequest().setArtifacts(session.toArtifacts(request.getArtifacts())); diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactManager.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactManager.java index a80be4f29663..4336527aa860 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactManager.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactManager.java @@ -38,12 +38,12 @@ public class DefaultArtifactManager implements ArtifactManager { @Nonnull - private final DefaultSession session; + private final InternalSession session; private final Map paths = new ConcurrentHashMap<>(); @Inject - public DefaultArtifactManager(@Nonnull DefaultSession session) { + public DefaultArtifactManager(@Nonnull InternalSession session) { this.session = session; } diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactResolver.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactResolver.java index 136655d4a110..cc1f93d5d244 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactResolver.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactResolver.java @@ -41,7 +41,6 @@ import org.eclipse.aether.resolution.ArtifactResolutionException; import org.eclipse.aether.resolution.ArtifactResult; -import static org.apache.maven.internal.impl.Utils.cast; import static org.apache.maven.internal.impl.Utils.nonNull; @Named @@ -58,8 +57,7 @@ public class DefaultArtifactResolver implements ArtifactResolver { public ArtifactResolverResult resolve(ArtifactResolverRequest request) throws ArtifactResolverException, IllegalArgumentException { nonNull(request, "request can not be null"); - DefaultSession session = - cast(DefaultSession.class, request.getSession(), "request.session should be a " + DefaultSession.class); + InternalSession session = InternalSession.from(request.getSession()); try { List repositories = session.toRepositories(session.getRemoteRepositories()); List requests = request.getCoordinates().stream() diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependency.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependency.java index 8a67eb3e3323..fd4145c04d6a 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependency.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependency.java @@ -33,12 +33,12 @@ import static org.apache.maven.internal.impl.Utils.nonNull; public class DefaultDependency implements Dependency { - private final AbstractSession session; + private final InternalSession session; private final org.eclipse.aether.graph.Dependency dependency; private final String key; public DefaultDependency( - @Nonnull AbstractSession session, @Nonnull org.eclipse.aether.graph.Dependency dependency) { + @Nonnull InternalSession session, @Nonnull org.eclipse.aether.graph.Dependency dependency) { this.session = nonNull(session, "session"); this.dependency = nonNull(dependency, "dependency"); this.key = getGroupId() @@ -46,7 +46,7 @@ public DefaultDependency( + getArtifactId() + ':' + getExtension() - + (getClassifier().length() > 0 ? ":" + getClassifier() : "") + + (!getClassifier().isEmpty() ? ":" + getClassifier() : "") + ':' + getVersion(); } diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCollector.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCollector.java index 36f75fa68bae..d40bc72062b4 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCollector.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCollector.java @@ -41,7 +41,6 @@ import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; import org.eclipse.aether.util.graph.transformer.ConflictResolver; -import static org.apache.maven.internal.impl.Utils.cast; import static org.apache.maven.internal.impl.Utils.nonNull; @Named @@ -60,8 +59,7 @@ public class DefaultDependencyCollector implements DependencyCollector { public DependencyCollectorResult collect(@Nonnull DependencyCollectorRequest request) throws DependencyCollectorException, IllegalArgumentException { nonNull(request, "request can not be null"); - DefaultSession session = - cast(DefaultSession.class, request.getSession(), "request.session should be a " + DefaultSession.class); + InternalSession session = InternalSession.from(request.getSession()); Artifact rootArtifact = request.getRootArtifact().map(session::toArtifact).orElse(null); diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCoordinate.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCoordinate.java index 9d2bfaab3867..64c2939e98e6 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCoordinate.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCoordinate.java @@ -33,11 +33,11 @@ import static org.apache.maven.internal.impl.Utils.nonNull; public class DefaultDependencyCoordinate implements DependencyCoordinate { - private final AbstractSession session; + private final InternalSession session; private final org.eclipse.aether.graph.Dependency dependency; public DefaultDependencyCoordinate( - @Nonnull AbstractSession session, @Nonnull org.eclipse.aether.graph.Dependency dependency) { + @Nonnull InternalSession session, @Nonnull org.eclipse.aether.graph.Dependency dependency) { this.session = nonNull(session, "session"); this.dependency = nonNull(dependency, "dependency"); } diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCoordinateFactory.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCoordinateFactory.java index 11e94aa8c1c7..eb8d34630338 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCoordinateFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCoordinateFactory.java @@ -30,7 +30,6 @@ import org.apache.maven.api.services.DependencyCoordinateFactoryRequest; import org.eclipse.aether.artifact.ArtifactType; -import static org.apache.maven.internal.impl.Utils.cast; import static org.apache.maven.internal.impl.Utils.nonNull; @Named @@ -41,8 +40,7 @@ public class DefaultDependencyCoordinateFactory implements DependencyCoordinateF @Override public DependencyCoordinate create(@Nonnull DependencyCoordinateFactoryRequest request) { nonNull(request, "request can not be null"); - DefaultSession session = - cast(DefaultSession.class, request.getSession(), "request.session should be a " + DefaultSession.class); + InternalSession session = InternalSession.from(request.getSession()); ArtifactType type = null; if (request.getType() != null) { diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultEvent.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultEvent.java index b8db69e1de8e..cf73b00d9406 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultEvent.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultEvent.java @@ -28,10 +28,10 @@ import org.apache.maven.execution.ExecutionEvent; public class DefaultEvent implements Event { - private final AbstractSession session; + private final InternalSession session; private final ExecutionEvent delegate; - public DefaultEvent(AbstractSession session, ExecutionEvent delegate) { + public DefaultEvent(InternalSession session, ExecutionEvent delegate) { this.session = session; this.delegate = delegate; } diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultLocalRepositoryManager.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultLocalRepositoryManager.java index 4217e4e682d6..43ba78660a1b 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultLocalRepositoryManager.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultLocalRepositoryManager.java @@ -35,7 +35,7 @@ public class DefaultLocalRepositoryManager implements LocalRepositoryManager { @Override public Path getPathForLocalArtifact(Session session, LocalRepository local, Artifact artifact) { - DefaultSession s = (DefaultSession) session; + InternalSession s = InternalSession.from(session); String path = getManager(s, local).getPathForLocalArtifact(s.toArtifact(artifact)); return local.getPath().resolve(path); } @@ -43,14 +43,14 @@ public Path getPathForLocalArtifact(Session session, LocalRepository local, Arti @Override public Path getPathForRemoteArtifact( Session session, LocalRepository local, RemoteRepository remote, Artifact artifact) { - DefaultSession s = (DefaultSession) session; + InternalSession s = InternalSession.from(session); String path = getManager(s, local).getPathForRemoteArtifact(s.toArtifact(artifact), s.toRepository(remote), null); return local.getPath().resolve(path); } private org.eclipse.aether.repository.LocalRepositoryManager getManager( - DefaultSession session, LocalRepository local) { + InternalSession session, LocalRepository local) { org.eclipse.aether.repository.LocalRepository repository = session.toRepository(local); if ("enhanced".equals(repository.getContentType())) { repository = new org.eclipse.aether.repository.LocalRepository(repository.getBasedir(), ""); diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultNode.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultNode.java index 7cd27ae9052b..7137389aec8a 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultNode.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultNode.java @@ -33,12 +33,12 @@ public class DefaultNode extends AbstractNode { - protected final @Nonnull AbstractSession session; + protected final @Nonnull InternalSession session; protected final @Nonnull org.eclipse.aether.graph.DependencyNode node; protected final boolean verbose; public DefaultNode( - @Nonnull AbstractSession session, @Nonnull org.eclipse.aether.graph.DependencyNode node, boolean verbose) { + @Nonnull InternalSession session, @Nonnull org.eclipse.aether.graph.DependencyNode node, boolean verbose) { this.session = session; this.node = node; this.verbose = verbose; diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java index c234608ffbd7..c92b060f4bf6 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java @@ -44,15 +44,15 @@ public class DefaultProject implements Project { - private final AbstractSession session; + private final InternalSession session; private final MavenProject project; - public DefaultProject(AbstractSession session, MavenProject project) { + public DefaultProject(InternalSession session, MavenProject project) { this.session = session; this.project = project; } - public AbstractSession getSession() { + public InternalSession getSession() { return session; } diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java index fc45b7919248..d291c24d82a8 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java @@ -69,7 +69,7 @@ public DefaultProjectBuilder(org.apache.maven.project.ProjectBuilder builder) { @Override public ProjectBuilderResult build(ProjectBuilderRequest request) throws ProjectBuilderException, IllegalArgumentException { - DefaultSession session = (DefaultSession) request.getSession(); + InternalSession session = InternalSession.from(request.getSession()); try { List repositories = session.toArtifactRepositories(session.getRemoteRepositories()); ProjectBuildingRequest req = new DefaultProjectBuildingRequest() diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java index c35c7717db32..f329ba83eba1 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java @@ -73,7 +73,7 @@ public Optional getPath(Project project) { @Nonnull @Override public Collection getAttachedArtifacts(Project project) { - AbstractSession session = ((DefaultProject) project).getSession(); + InternalSession session = ((DefaultProject) project).getSession(); Collection attached = getMavenProject(project).getAttachedArtifacts().stream() .map(RepositoryUtils::toArtifact) .map(session::getArtifact) @@ -129,12 +129,12 @@ public List getResolvedDependencies(Project project, ResolutionScope s getMavenProject(project), toResolve, toResolve, - ((DefaultSession) session).getMavenSession(), + InternalSession.from(session).getMavenSession(), false, Collections.emptySet()); return artifacts.stream() .map(RepositoryUtils::toArtifact) - .map(((DefaultSession) session)::getArtifact) + .map(InternalSession.from(session)::getArtifact) .collect(Collectors.toList()); } catch (LifecycleExecutionException | ComponentLookupException e) { throw new MavenException("Unable to resolve project dependencies", e); diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSessionFactory.java index bbcd53f89c34..e727a345d338 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSessionFactory.java @@ -53,7 +53,7 @@ public DefaultSessionFactory( public Session getSession(MavenSession mavenSession) { SessionData data = mavenSession.getRepositorySession().getData(); - return (Session) data.computeIfAbsent(DefaultSession.class, () -> newSession(mavenSession)); + return (Session) data.computeIfAbsent(InternalSession.class, () -> newSession(mavenSession)); } private Session newSession(MavenSession mavenSession) { diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSettingsBuilder.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSettingsBuilder.java index a21c5b0ea543..39d196188544 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSettingsBuilder.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSettingsBuilder.java @@ -57,7 +57,7 @@ public DefaultSettingsBuilder(org.apache.maven.settings.building.SettingsBuilder @Override public SettingsBuilderResult build(SettingsBuilderRequest request) throws SettingsBuilderException, IllegalArgumentException { - DefaultSession session = (DefaultSession) request.getSession(); + InternalSession session = InternalSession.from(request.getSession()); try { DefaultSettingsBuildingRequest req = new DefaultSettingsBuildingRequest(); req.setUserProperties(toProperties(session.getUserProperties())); diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultToolchainManager.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultToolchainManager.java index 2ccbbba29db5..b22f813299dd 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultToolchainManager.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultToolchainManager.java @@ -49,7 +49,7 @@ public DefaultToolchainManager(DefaultToolchainManagerPrivate toolchainManagerPr @Override public List getToolchains(Session session, String type, Map requirements) throws ToolchainManagerException { - MavenSession s = ((DefaultSession) session).getMavenSession(); + MavenSession s = InternalSession.from(session).getMavenSession(); List toolchains = toolchainManagerPrivate.getToolchains(s, type, requirements); return new MappedList<>(toolchains, this::toToolchain); @@ -58,7 +58,7 @@ public List getToolchains(Session session, String type, Map getToolchainFromBuildContext(Session session, String type) throws ToolchainManagerException { - MavenSession s = ((DefaultSession) session).getMavenSession(); + MavenSession s = InternalSession.from(session).getMavenSession(); return Optional.ofNullable(toolchainManagerPrivate.getToolchainFromBuildContext(type, s)) .map(this::toToolchain); } @@ -66,7 +66,7 @@ public Optional getToolchainFromBuildContext(Session session, String @Override public List getToolchainsForType(Session session, String type) throws ToolchainManagerException { try { - MavenSession s = ((DefaultSession) session).getMavenSession(); + MavenSession s = InternalSession.from(session).getMavenSession(); ToolchainPrivate[] toolchains = toolchainManagerPrivate.getToolchainsForType(type, s); return new MappedList<>(Arrays.asList(toolchains), this::toToolchain); } catch (MisconfiguredToolchainException e) { @@ -76,7 +76,7 @@ public List getToolchainsForType(Session session, String type) throws @Override public void storeToolchainToBuildContext(Session session, Toolchain toolchain) throws ToolchainManagerException { - MavenSession s = ((DefaultSession) session).getMavenSession(); + MavenSession s = InternalSession.from(session).getMavenSession(); org.apache.maven.toolchain.ToolchainPrivate tc = (org.apache.maven.toolchain.ToolchainPrivate) ((ToolchainWrapper) toolchain).toolchain; toolchainManagerPrivate.storeToolchainToBuildContext(tc, s); diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultTransportProvider.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultTransportProvider.java index a7ab392c29a1..e3ba885c1631 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultTransportProvider.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultTransportProvider.java @@ -52,7 +52,7 @@ public Transport transport(Session session, RemoteRepository repository) { return new DefaultTransport( baseURI, transporterProvider.newTransporter( - ((DefaultSession) session).getSession(), + InternalSession.from(session).getSession(), ((DefaultRemoteRepository) repository).getRepository())); } catch (URISyntaxException e) { throw new TransportProviderException("Remote repository URL invalid", e); diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/EventSpyImpl.java b/maven-core/src/main/java/org/apache/maven/internal/impl/EventSpyImpl.java index 0cd80c60f043..6d1dd78ce586 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/EventSpyImpl.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/EventSpyImpl.java @@ -47,7 +47,7 @@ public void init(Context context) throws Exception {} public void onEvent(Object arg) throws Exception { if (arg instanceof ExecutionEvent) { ExecutionEvent ee = (ExecutionEvent) arg; - AbstractSession session = (AbstractSession) sessionFactory.getSession(ee.getSession()); + InternalSession session = InternalSession.from(sessionFactory.getSession(ee.getSession())); Collection listeners = session.getListeners(); if (!listeners.isEmpty()) { Event event = new DefaultEvent(session, ee); diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/InternalSession.java b/maven-core/src/main/java/org/apache/maven/internal/impl/InternalSession.java new file mode 100644 index 000000000000..d13acfb30ac1 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/InternalSession.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.internal.impl; + +import java.util.Collection; +import java.util.List; + +import org.apache.maven.api.Artifact; +import org.apache.maven.api.ArtifactCoordinate; +import org.apache.maven.api.Dependency; +import org.apache.maven.api.DependencyCoordinate; +import org.apache.maven.api.LocalRepository; +import org.apache.maven.api.Node; +import org.apache.maven.api.Project; +import org.apache.maven.api.RemoteRepository; +import org.apache.maven.api.Session; +import org.apache.maven.api.annotations.Nonnull; +import org.apache.maven.execution.MavenSession; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; + +import static org.apache.maven.internal.impl.Utils.cast; + +public interface InternalSession extends Session { + + static InternalSession from(Session session) { + return cast(InternalSession.class, session, "session should be an " + InternalSession.class); + } + + RemoteRepository getRemoteRepository(org.eclipse.aether.repository.RemoteRepository repository); + + Node getNode(org.eclipse.aether.graph.DependencyNode node); + + Node getNode(org.eclipse.aether.graph.DependencyNode node, boolean verbose); + + @Nonnull + Artifact getArtifact(@Nonnull org.eclipse.aether.artifact.Artifact artifact); + + @Nonnull + Dependency getDependency(@Nonnull org.eclipse.aether.graph.Dependency dependency); + + List getProjects(List projects); + + Project getProject(org.apache.maven.project.MavenProject project); + + List toRepositories(List repositories); + + org.eclipse.aether.repository.RemoteRepository toRepository(RemoteRepository repository); + + org.eclipse.aether.repository.LocalRepository toRepository(LocalRepository repository); + + List toArtifactRepositories( + List repositories); + + org.apache.maven.artifact.repository.ArtifactRepository toArtifactRepository(RemoteRepository repository); + + List toDependencies(Collection dependencies); + + org.eclipse.aether.graph.Dependency toDependency(DependencyCoordinate dependency); + + List toArtifacts(Collection artifacts); + + org.eclipse.aether.artifact.Artifact toArtifact(Artifact artifact); + + org.eclipse.aether.artifact.Artifact toArtifact(ArtifactCoordinate coord); + + MavenSession getMavenSession(); + + RepositorySystemSession getSession(); + + RepositorySystem getRepositorySystem(); +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java index a2cb6a5e722a..3c26360acd09 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java @@ -34,7 +34,7 @@ import org.apache.maven.execution.scope.internal.MojoExecutionScope; import org.apache.maven.internal.impl.DefaultLog; import org.apache.maven.internal.impl.DefaultMojoExecution; -import org.apache.maven.internal.impl.DefaultSession; +import org.apache.maven.internal.impl.InternalSession; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; @@ -121,7 +121,7 @@ public void executeMojo(MavenSession session, MojoExecution mojoExecution) org.apache.maven.api.plugin.Log.class, new DefaultLog(LoggerFactory.getLogger( mojoExecution.getMojoDescriptor().getFullGoalName()))); - scope.seed(Project.class, ((DefaultSession) session.getSession()).getProject(project)); + scope.seed(Project.class, InternalSession.from(session.getSession()).getProject(project)); scope.seed(org.apache.maven.api.MojoExecution.class, new DefaultMojoExecution(mojoExecution)); if (mojoDescriptor.isV4Api()) { diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4.java index 0eaa801c204b..179002bb052a 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4.java @@ -27,7 +27,7 @@ import org.apache.maven.api.Project; import org.apache.maven.api.Session; import org.apache.maven.internal.impl.DefaultMojoExecution; -import org.apache.maven.internal.impl.DefaultSession; +import org.apache.maven.internal.impl.InternalSession; import org.apache.maven.model.interpolation.reflection.ReflectionValueExtractor; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; @@ -198,8 +198,8 @@ public Object evaluate(String expr, Class type) throws ExpressionEvaluationEx } else if ("project".equals(expression)) { value = project; } else if ("executedProject".equals(expression)) { - value = ((DefaultSession) session) - .getProject(((DefaultSession) session) + value = InternalSession.from(session) + .getProject(InternalSession.from(session) .getMavenSession() .getCurrentProject() .getExecutionProject()); diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java index ef1322d2fac6..5b9ed4bd0203 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java @@ -45,7 +45,7 @@ import org.apache.maven.classrealm.ClassRealmManager; import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule; -import org.apache.maven.internal.impl.DefaultSession; +import org.apache.maven.internal.impl.InternalSession; import org.apache.maven.internal.xml.XmlPlexusConfiguration; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.ContextEnabled; @@ -587,7 +587,7 @@ public T getConfiguredMojo(Class mojoInterface, MavenSession session, Moj if (mojoDescriptor.isV4Api()) { expressionEvaluator = new PluginParameterExpressionEvaluatorV4( session.getSession(), - ((DefaultSession) session.getSession()).getProject(session.getCurrentProject()), + InternalSession.from(session.getSession()).getProject(session.getCurrentProject()), mojoExecution); } else { expressionEvaluator = new PluginParameterExpressionEvaluator(session, mojoExecution); diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java index 878b98963311..be9e14c50030 100644 --- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java +++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java @@ -39,7 +39,7 @@ import org.apache.maven.artifact.InvalidRepositoryException; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.bridge.MavenRepositorySystem; -import org.apache.maven.internal.impl.DefaultSession; +import org.apache.maven.internal.impl.InternalSession; import org.apache.maven.model.Build; import org.apache.maven.model.Dependency; import org.apache.maven.model.DependencyManagement; @@ -860,7 +860,7 @@ private ModelBuildingRequest getModelBuildingRequest() { modelBuildingRequest.setModelCache(modelCacheFactory.createCache(session)); } modelBuildingRequest.setTransformerContextBuilder(transformerContextBuilder); - DefaultSession session = (DefaultSession) this.session.getData().get(DefaultSession.class); + InternalSession session = (InternalSession) this.session.getData().get(InternalSession.class); if (session != null) { try { modelBuildingRequest.setRootDirectory(session.getRootDirectory()); diff --git a/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java b/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java index a677f09d287b..c06b45e7cf5f 100644 --- a/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java +++ b/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java @@ -25,7 +25,7 @@ import org.apache.maven.SessionScoped; import org.apache.maven.api.Session; import org.apache.maven.execution.MavenSession; -import org.apache.maven.internal.impl.DefaultSession; +import org.apache.maven.internal.impl.InternalSession; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; @@ -56,6 +56,6 @@ protected void configure() { bind(MavenSession.class).toProvider(SessionScope.seededKeyProvider()).in(scope); bind(Session.class).toProvider(SessionScope.seededKeyProvider()).in(scope); - bind(DefaultSession.class).toProvider(SessionScope.seededKeyProvider()).in(scope); + bind(InternalSession.class).toProvider(SessionScope.seededKeyProvider()).in(scope); } } diff --git a/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java b/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java index 9f17cd5f615b..c09bba12af52 100644 --- a/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java +++ b/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java @@ -114,7 +114,7 @@ void setup() { .withRemoteRepositories(Collections.singletonList(remoteRepository)); sessionScope.enter(); - sessionScope.seed(DefaultSession.class, (DefaultSession) this.session); + sessionScope.seed(InternalSession.class, InternalSession.from(this.session)); } @Test From ff79e9ac7813f4a16a8ee5ac31fc8dd1ca75fc38 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Wed, 15 Nov 2023 14:24:44 +0100 Subject: [PATCH 02/11] Upgrade to Guice 6.0.0 and add support for jakarta.inject annotations --- .../src/main/resources/META-INF/maven/extension.xml | 3 +++ pom.xml | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/maven-core/src/main/resources/META-INF/maven/extension.xml b/maven-core/src/main/resources/META-INF/maven/extension.xml index d4936cf40579..1823336d837c 100644 --- a/maven-core/src/main/resources/META-INF/maven/extension.xml +++ b/maven-core/src/main/resources/META-INF/maven/extension.xml @@ -111,6 +111,9 @@ under the License. javax.annotation.* javax.annotation.security.* + jakarta.inject.* + jakarta.annotation.* + + + 4.0.0 + + org.apache.maven + maven-api + 4.0.0-alpha-9-SNAPSHOT + + + maven-api-plugin + + Maven 4 API :: Plugin + Maven 4 API - Immutable Plugin model. + + + + org.apache.maven + maven-api-xml + 4.0.0-alpha-9-SNAPSHOT + + + + + + + org.codehaus.modello + modello-maven-plugin + + + plugin + + velocity + xdoc + xsd + + generate-resources + + ${project.basedir}/../../src/mdo + 2.0.0 + + src/main/mdo/plugin.mdo + + + + + + packageModelV4=org.apache.maven.api.plugin.descriptor + + + + + lifecycle + + velocity + xdoc + xsd + + generate-resources + + ${project.basedir}/../../src/mdo + 1.0.0 + + src/main/mdo/lifecycle.mdo + + + + + + packageModelV4=org.apache.maven.api.plugin.descriptor.lifecycle + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + **/package-info.java + + + + + + + diff --git a/api/maven-api-plugin/src/main/java/org/apache/maven/api/plugin/descriptor/lifecycle/package-info.java b/api/maven-api-plugin/src/main/java/org/apache/maven/api/plugin/descriptor/lifecycle/package-info.java new file mode 100644 index 000000000000..eec9c505362c --- /dev/null +++ b/api/maven-api-plugin/src/main/java/org/apache/maven/api/plugin/descriptor/lifecycle/package-info.java @@ -0,0 +1,5 @@ +// CHECKSTYLE_OFF: RegexpHeader +/** + * Maven Plugin forked lifecycle model. + */ +package org.apache.maven.api.plugin.descriptor.lifecycle; diff --git a/api/maven-api-plugin/src/main/java/org/apache/maven/api/plugin/descriptor/package-info.java b/api/maven-api-plugin/src/main/java/org/apache/maven/api/plugin/descriptor/package-info.java new file mode 100644 index 000000000000..0435496d0b46 --- /dev/null +++ b/api/maven-api-plugin/src/main/java/org/apache/maven/api/plugin/descriptor/package-info.java @@ -0,0 +1,5 @@ +// CHECKSTYLE_OFF: RegexpHeader +/** + * Maven Plugin descriptor model. + */ +package org.apache.maven.api.plugin.descriptor; diff --git a/maven-plugin-api/src/main/mdo/lifecycle.mdo b/api/maven-api-plugin/src/main/mdo/lifecycle.mdo similarity index 91% rename from maven-plugin-api/src/main/mdo/lifecycle.mdo rename to api/maven-api-plugin/src/main/mdo/lifecycle.mdo index 7dfce74be9bf..db51be62cd52 100644 --- a/maven-plugin-api/src/main/mdo/lifecycle.mdo +++ b/api/maven-api-plugin/src/main/mdo/lifecycle.mdo @@ -17,22 +17,16 @@ specific language governing permissions and limitations under the License. --> - - lifecycle-mappings - LifecycleMappings + lifecycle + Lifecycle META-INF/maven/lifecycle.xml in a plugin's jar artifact. ]]> - - - package - org.apache.maven.plugin.lifecycle - - LifecycleConfiguration diff --git a/maven-plugin-api/src/main/mdo/plugin.mdo b/api/maven-api-plugin/src/main/mdo/plugin.mdo similarity index 83% rename from maven-plugin-api/src/main/mdo/plugin.mdo rename to api/maven-api-plugin/src/main/mdo/plugin.mdo index ad1006df26b1..6f21b017c51e 100644 --- a/maven-plugin-api/src/main/mdo/plugin.mdo +++ b/api/maven-api-plugin/src/main/mdo/plugin.mdo @@ -24,26 +24,15 @@ under the License. plugin PluginDescriptor META-INF/maven/plugin.xml in a plugin's jar artifact. - This descriptor is generally generated from plugin sources, using - maven-plugin-plugin. -

Notice: this documentation is generated from a Modello model but the - PluginDescriptor/MojoDescriptor - code executed is not generated from this model. Please report if you find anything wrong this documentation.

-

An XSD is available at https://maven.apache.org/xsd/plugin-1.1.0.xsd

+ Maven 4 Plugin descriptor, stored in META-INF/maven/plugin.xml in a plugin's jar artifact. + This descriptor is generally using the information contained in the annotations of the plugin api. +

An XSD is available at https://maven.apache.org/xsd/plugin-2.0.0.xsd

]]>
- - - package - plugin descriptor XML documentation (no java generation) - - PluginDescriptor 1.0.0+ plugin.xml file.]]> - name @@ -120,7 +109,7 @@ under the License. dependencies - 1.0.0+ + 1.0.0/1.1.0 Dependency * @@ -131,6 +120,21 @@ under the License. + + + 2.0.0+ + + + @@ -139,7 +143,6 @@ under the License. - goal @@ -203,7 +206,18 @@ under the License. requiresDependencyResolution - 1.0.0+ + 1.0.0/1.1.0 + String + runtime + compile, runtime, test, + compile+runtime (since Maven 3.0) or runtime+system (since Maven 3.0) + ]]> + + + dependencyResolution + 2.0.0+ String runtime requiresDependencyCollection - 1.0.0+ + 1.0.0/1.1.0 + String + + + + dependencyCollection + 2.0.0+ String requiresDirectInvocation - 1.0.0+ + 1.0.0/1.1.0 + boolean + Flags this Mojo to be invoked directly only. + false + + + directInvocationOnly + 2.0.0+ boolean Flags this Mojo to be invoked directly only. false requiresProject - 1.0.0+ + 1.0.0/1.1.0 + boolean + Flags this Mojo to require running inside of a project. + true + + + projectRequired + 2.0.0+ boolean Flags this Mojo to require running inside of a project. true @@ -248,7 +289,14 @@ under the License. requiresOnline - 1.0.0+ + 1.0.0/1.1.0 + boolean + Flags this Mojo to require online mode for its operation. + false + + + onlineRequired + 2.0.0+ boolean Flags this Mojo to require online mode for its operation. false @@ -272,7 +320,7 @@ under the License. threadSafe - 1.0.0+ + 1.0.0/1.1.0 boolean Marks this Mojo as being thread-safe, i.e. the Mojo safely supports concurrent execution during parallel @@ -283,21 +331,21 @@ under the License. v4Api - 1.1.0+ + 1.1.0 boolean Marks this Mojo as using Maven 4 API. This makes the plugin implicitly incompatible with earlier Maven versions. Only evaluated since Maven 4. false instantiationStrategy - 1.0.0+ + 1.0.0/1.1.0 String per-lookup Specify the instantiation strategy. executionStrategy - 1.0.0+ + 1.0.0/1.1.0 String once-per-session, always. @@ -331,7 +379,7 @@ under the License. composer - 1.0.0+ + 1.0.0/1.1.0 String @@ -344,27 +392,27 @@ under the License. * - - configuration - 1.0.0+ - Specifies default values of parameters (with attribute "default-value") as well as how they can be overwritten by Maven properties (in the element content). - - DOM - - requirements - 1.0.0+ + 1.0.0/1.1.0 Requirement * + + id + 2.0.0+ + String + the id of the mojo, based on the goal name + + + fullGoalName + 2.0.0+ + String + the full goal name + @@ -455,31 +503,15 @@ under the License. This will trigger a warning when a user tries to configure a parameter marked as deprecated. ]]> - -
- - - Configuration - 1.0.0+ - A parameter configuration. - - - + expression - true - 1.0.0+ + 2.0.0+ String Parameter expression, to let user override default value with a user property, system property or project property. - - implementation - 1.0.0+ - String - - - + defaultValue - 1.0.0+ + 2.0.0+ String The default value, as an expression that will be evaluated at injection or run-time. @@ -488,7 +520,7 @@ under the License. Requirement - 1.0.0+ + 1.0.0/1.1.0 Describes a component requirement. @@ -517,7 +549,7 @@ under the License. Dependency - 1.0.0+ + 1.0.0/1.1.0 Definition of a dependency, needed by the plugin at runtime. diff --git a/api/maven-api-plugin/src/site/apt/index.apt b/api/maven-api-plugin/src/site/apt/index.apt new file mode 100644 index 000000000000..f229c29d8a8e --- /dev/null +++ b/api/maven-api-plugin/src/site/apt/index.apt @@ -0,0 +1,33 @@ +~~ 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. + + ----- + Introduction + ----- + Guillaume Nodet + ----- + 2023-11-15 + ----- + +Maven 4 API - Plugin Descriptor Model + + This is the immutable model for Maven Plugin Descriptor in <<>> package. + + The following are generated from this model: + + * {{{./apidocs/index.html}Java sources}} with <<>> inner classes for immutable instances creation. + diff --git a/api/maven-api-plugin/src/site/site.xml b/api/maven-api-plugin/src/site/site.xml new file mode 100644 index 000000000000..8ffe43d07c30 --- /dev/null +++ b/api/maven-api-plugin/src/site/site.xml @@ -0,0 +1,38 @@ + + + + + + + ${project.scm.url} + + + + + + + + + + + + + \ No newline at end of file diff --git a/api/pom.xml b/api/pom.xml index 6489ee1704d5..16116d462002 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -35,6 +35,7 @@ maven-api-meta maven-api-xml maven-api-model + maven-api-plugin maven-api-settings maven-api-toolchain maven-api-core diff --git a/maven-bom/pom.xml b/maven-bom/pom.xml index 85eb8170a721..e6503924538a 100644 --- a/maven-bom/pom.xml +++ b/maven-bom/pom.xml @@ -122,6 +122,11 @@ under the License. maven-api-toolchain ${project.version} + + org.apache.maven + maven-api-plugin + ${project.version} + org.apache.maven maven-api-xml diff --git a/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeModule.java b/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeModule.java index ed3625fafe2d..f574e43c8c6c 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeModule.java +++ b/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeModule.java @@ -43,6 +43,7 @@ protected MojoExecutionScopeModule(MojoExecutionScope scope) { @Override protected void configure() { bindScope(MojoExecutionScoped.class, scope); + bindScope(org.apache.maven.api.di.MojoExecutionScoped.class, scope); bind(MojoExecutionScope.class).toInstance(scope); bind(MavenProject.class) .toProvider(MojoExecutionScope.seededKeyProvider()) diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultMojoExecution.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultMojoExecution.java index 84e1cd8d8e47..a5ef26663fb7 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultMojoExecution.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultMojoExecution.java @@ -21,7 +21,9 @@ import java.util.Optional; import org.apache.maven.api.MojoExecution; -import org.apache.maven.api.model.Plugin; +import org.apache.maven.api.Plugin; +import org.apache.maven.api.model.PluginExecution; +import org.apache.maven.api.plugin.descriptor.MojoDescriptor; import org.apache.maven.api.xml.XmlNode; import org.codehaus.plexus.util.xml.Xpp3Dom; @@ -38,7 +40,22 @@ public org.apache.maven.plugin.MojoExecution getDelegate() { @Override public Plugin getPlugin() { - return delegate.getPlugin().getDelegate(); + return null; + } + + @Override + public PluginExecution getPluginExecutionModel() { + return null; + } + + @Override + public MojoDescriptor getMojoDescriptor() { + return null; + } + + @Override + public String getLifecyclePhase() { + return delegate.getLifecyclePhase(); } @Override diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java index 1fb3c176ef13..03a511a589d1 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java @@ -34,6 +34,8 @@ import java.util.Map; import java.util.Set; +import org.apache.maven.api.plugin.descriptor.lifecycle.Execution; +import org.apache.maven.api.plugin.descriptor.lifecycle.Phase; import org.apache.maven.api.xml.XmlNode; import org.apache.maven.execution.MavenSession; import org.apache.maven.internal.xml.XmlNodeImpl; @@ -55,8 +57,6 @@ import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.Parameter; import org.apache.maven.plugin.descriptor.PluginDescriptor; -import org.apache.maven.plugin.lifecycle.Execution; -import org.apache.maven.plugin.lifecycle.Phase; import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; import org.apache.maven.plugin.version.PluginVersionResolutionException; import org.apache.maven.project.MavenProject; @@ -459,7 +459,7 @@ private void injectLifecycleOverlay( return; } - org.apache.maven.plugin.lifecycle.Lifecycle lifecycleOverlay; + org.apache.maven.api.plugin.descriptor.lifecycle.Lifecycle lifecycleOverlay; try { lifecycleOverlay = pluginDescriptor.getLifecycleMapping(forkedLifecycle); @@ -491,7 +491,7 @@ private void injectLifecycleOverlay( MojoExecution forkedExecution = new MojoExecution(forkedMojoDescriptor, mojoExecution.getExecutionId()); - XmlNodeImpl forkedConfiguration = (XmlNodeImpl) execution.getConfiguration(); + XmlNode forkedConfiguration = execution.getConfiguration(); forkedExecution.setConfiguration(forkedConfiguration); @@ -501,7 +501,7 @@ private void injectLifecycleOverlay( } } - XmlNodeImpl phaseConfiguration = (XmlNodeImpl) phase.getConfiguration(); + XmlNode phaseConfiguration = phase.getConfiguration(); if (phaseConfiguration != null) { for (MojoExecution forkedExecution : forkedExecutions) { diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java index 5b9ed4bd0203..781ae70032fd 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java @@ -39,6 +39,8 @@ import java.util.stream.Collectors; import java.util.zip.ZipEntry; +import com.google.inject.AbstractModule; +import com.google.inject.name.Names; import org.apache.maven.RepositoryUtils; import org.apache.maven.api.xml.XmlNode; import org.apache.maven.artifact.Artifact; @@ -419,15 +421,40 @@ private void discoverPluginComponents( throws PluginContainerException { try { if (pluginDescriptor != null) { - for (ComponentDescriptor componentDescriptor : pluginDescriptor.getComponents()) { - componentDescriptor.setRealm(pluginRealm); - container.addComponentDescriptor(componentDescriptor); + for (MojoDescriptor mojo : pluginDescriptor.getMojos()) { + if (!mojo.isV4Api()) { + mojo.setRealm(pluginRealm); + container.addComponentDescriptor(mojo); + } } } ((DefaultPlexusContainer) container) .discoverComponents( pluginRealm, + new AbstractModule() { + @Override + protected void configure() { + if (pluginDescriptor != null) { + for (MojoDescriptor mojo : pluginDescriptor.getMojos()) { + if (mojo.isV4Api()) { + try { + mojo.setRealm(pluginRealm); + Class cl = mojo.getImplementationClass(); + if (cl == null) { + cl = pluginRealm.loadClass(mojo.getImplementation()); + } + bind(org.apache.maven.api.plugin.Mojo.class) + .annotatedWith(Names.named(mojo.getId())) + .to((Class) cl); + } catch (ClassNotFoundException e) { + throw new IllegalStateException("Unable to load mojo class", e); + } + } + } + } + } + }, new SessionScopeModule(container), new MojoExecutionScopeModule(container), new PluginConfigurationModule(plugin.getDelegate())); diff --git a/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java b/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java index c06b45e7cf5f..98ad4c9e61f3 100644 --- a/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java +++ b/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java @@ -52,6 +52,7 @@ private SessionScopeModule(SessionScope scope) { @Override protected void configure() { bindScope(SessionScoped.class, scope); + bindScope(org.apache.maven.api.di.SessionScoped.class, scope); bind(SessionScope.class).toInstance(scope); bind(MavenSession.class).toProvider(SessionScope.seededKeyProvider()).in(scope); diff --git a/maven-core/src/test/java/org/apache/maven/session/scope/SessionScopeProxyTest.java b/maven-core/src/test/java/org/apache/maven/session/scope/SessionScopeProxyTest.java index 5988c64c9e32..fd3efe8aca7a 100644 --- a/maven-core/src/test/java/org/apache/maven/session/scope/SessionScopeProxyTest.java +++ b/maven-core/src/test/java/org/apache/maven/session/scope/SessionScopeProxyTest.java @@ -23,8 +23,8 @@ import javax.inject.Singleton; import com.google.inject.OutOfScopeException; -import org.apache.maven.SessionScoped; import org.apache.maven.api.Session; +import org.apache.maven.api.di.SessionScoped; import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; diff --git a/maven-plugin-api/pom.xml b/maven-plugin-api/pom.xml index 8efff2ff2482..fa8a7a6bf9b7 100644 --- a/maven-plugin-api/pom.xml +++ b/maven-plugin-api/pom.xml @@ -32,6 +32,10 @@ under the License. The API for plugins - Mojos - development. + + org.apache.maven + maven-api-plugin + org.apache.maven maven-model @@ -63,44 +67,55 @@ under the License. modello-maven-plugin ${project.basedir}/../src/mdo - - src/main/mdo/lifecycle.mdo - - 1.0.0 - velocity + velocity-lifecycle velocity generate-sources - - packageModelV3=org.apache.maven.plugin.lifecycle - packageModelV4=org.apache.maven.plugin.lifecycle + packageModelV4=org.apache.maven.api.plugin.descriptor.lifecycle packageToolV4=org.apache.maven.plugin.lifecycle.io + + ../api/maven-api-plugin/src/main/mdo/lifecycle.mdo + + 1.0.0 - modello-site-docs2 + velocity-plugin - xdoc + velocity - pre-site + generate-sources + + + + + + packageModelV3=org.apache.maven.plugin.descriptor + packageModelV4=org.apache.maven.api.plugin.descriptor + packageToolV4=org.apache.maven.plugin.descriptor.io + - src/main/mdo/plugin.mdo + ../api/maven-api-plugin/src/main/mdo/plugin.mdo - 1.1.0 + 2.0.0 + + modello-site-docs + none + @@ -110,32 +125,8 @@ under the License. org.apache.maven.monitor.logging.DefaultLog - org.apache.maven.plugin.lifecycle.Execution#addGoal(java.lang.String):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.Execution#getConfiguration():METHOD_RETURN_TYPE_CHANGED - org.apache.maven.plugin.lifecycle.Execution#removeGoal(java.lang.String):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.Execution#setConfiguration(java.lang.Object):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.Execution#setGoals(java.util.List):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.Execution#Execution():CONSTRUCTOR_REMOVED - org.apache.maven.plugin.lifecycle.io.xpp3.LifecycleMappingsXpp3Reader#contentTransformer - org.apache.maven.plugin.lifecycle.Lifecycle#addPhase(org.apache.maven.plugin.lifecycle.Phase):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.Lifecycle#removePhase(org.apache.maven.plugin.lifecycle.Phase):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.Lifecycle#setId(java.lang.String):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.Lifecycle#setPhases(java.util.List):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.Lifecycle#Lifecycle():CONSTRUCTOR_REMOVED - org.apache.maven.plugin.lifecycle.LifecycleConfiguration#addLifecycle(org.apache.maven.plugin.lifecycle.Lifecycle):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.LifecycleConfiguration#removeLifecycle(org.apache.maven.plugin.lifecycle.Lifecycle):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.LifecycleConfiguration#setLifecycles(java.util.List):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.LifecycleConfiguration#setModelEncoding(java.lang.String):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.LifecycleConfiguration#LifecycleConfiguration():CONSTRUCTOR_REMOVED - org.apache.maven.plugin.lifecycle.Phase#addExecution(org.apache.maven.plugin.lifecycle.Execution):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.Phase#getConfiguration():METHOD_RETURN_TYPE_CHANGED - org.apache.maven.plugin.lifecycle.Phase#removeExecution(org.apache.maven.plugin.lifecycle.Execution):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.Phase#setConfiguration(java.lang.Object):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.Phase#setExecutions(java.util.List):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.Phase#setId(java.lang.String):METHOD_REMOVED - org.apache.maven.plugin.lifecycle.Phase#Phase():CONSTRUCTOR_REMOVED - org.apache.maven.plugin.lifecycle.io.xpp3.LifecycleMappingsXpp3Reader - org.apache.maven.plugin.lifecycle.io.xpp3.LifecycleMappingsXpp3Writer + org.apache.maven.plugin.lifecycle + org.apache.maven.plugin.descriptor.PluginDescriptor#getLifecycleMapping(java.lang.String) diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java index 4f43506fc657..e19ef1f6804b 100644 --- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java +++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java @@ -33,12 +33,12 @@ import java.util.Set; import java.util.regex.Pattern; +import org.apache.maven.api.plugin.descriptor.lifecycle.Lifecycle; +import org.apache.maven.api.plugin.descriptor.lifecycle.LifecycleConfiguration; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.model.Plugin; -import org.apache.maven.plugin.lifecycle.Lifecycle; -import org.apache.maven.plugin.lifecycle.LifecycleConfiguration; -import org.apache.maven.plugin.lifecycle.io.LifecycleMappingsStaxReader; +import org.apache.maven.plugin.lifecycle.io.LifecycleStaxReader; import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.component.repository.ComponentSetDescriptor; @@ -330,7 +330,7 @@ public Lifecycle getLifecycleMapping(String lifecycleId) throws IOException, XML LifecycleConfiguration lifecycleConfiguration; try (InputStream input = getDescriptorStream(LIFECYCLE_DESCRIPTOR)) { - lifecycleConfiguration = new LifecycleMappingsStaxReader().read(input); + lifecycleConfiguration = new LifecycleStaxReader().read(input); } lifecycleMappings = new HashMap<>(); diff --git a/src/mdo/reader-stax.vm b/src/mdo/reader-stax.vm index 61bd8428fe71..f4b5f03d938d 100644 --- a/src/mdo/reader-stax.vm +++ b/src/mdo/reader-stax.vm @@ -27,6 +27,16 @@ #set ( $rootUcapName = $Helper.capitalise( $root.name ) ) #set ( $rootLcapName = $Helper.uncapitalise( $root.name ) ) # +#set ( $needXmlContext = false ) +#foreach ( $class in $model.allClasses ) + #set ( $allFields = $Helper.xmlFields( $class ) ) + #foreach ( $field in $allFields ) + #if ( $Helper.xmlFieldMetadata( $field ).format ) + #set ( $needXmlContext = true ) + #end + #end +#end +# #MODELLO-VELOCITY#SAVE-OUTPUT-TO ${package.replace('.','/')}/${className}.java // =================== DO NOT EDIT THIS FILE ==================== // Generated by Modello Velocity from ${template} @@ -38,9 +48,15 @@ import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.text.DateFormat; +#if ( $needXmlContext ) +import java.util.ArrayDeque; +#end import java.util.ArrayList; import java.util.Collections; import java.util.Date; +#if ( $needXmlContext ) +import java.util.Deque; +#end import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -470,6 +486,9 @@ public class ${className} { public ${root.name} read(XMLStreamReader parser, boolean strict, InputSource source) throws XMLStreamException { #else public ${root.name} read(XMLStreamReader parser, boolean strict) throws XMLStreamException { +#end +#if ( $needXmlContext ) + Deque context = new ArrayDeque<>(); #end $rootUcapName $rootLcapName = null; int eventType = parser.getEventType(); @@ -484,6 +503,8 @@ public class ${className} { } #if ( $locationTracking ) $rootLcapName = parse${rootUcapName}(parser, strict, source); +#elseif ( $needXmlContext ) + $rootLcapName = parse${rootUcapName}(parser, strict, context); #else $rootLcapName = parse${rootUcapName}(parser, strict); #end @@ -505,6 +526,8 @@ public class ${className} { #set ( $allFields = $Helper.xmlFields( $class ) ) #if ( $locationTracking ) private ${classUcapName} parse${classUcapName}(XMLStreamReader parser, boolean strict, InputSource source) throws XMLStreamException { + #elseif ( $needXmlContext ) + private ${classUcapName} parse${classUcapName}(XMLStreamReader parser, boolean strict, Deque context) throws XMLStreamException { #else private ${classUcapName} parse${classUcapName}(XMLStreamReader parser, boolean strict) throws XMLStreamException { #end @@ -553,6 +576,9 @@ public class ${className} { #if ( $Helper.isFlatItems( $field ) ) List<$field.to> ${field.name} = new ArrayList<>(); #end + #end + #if ( $needXmlContext ) + context.addLast( ${classLcapName} ); #end while ((strict ? parser.nextTag() : nextTag(parser)) == XMLStreamReader.START_ELEMENT) { String childName = checkDuplicate(parser.getLocalName(), parser, parsed); @@ -564,7 +590,7 @@ public class ${className} { switch (childName) { #set( $ift = "if" ) #foreach ( $field in $allFields ) - #if ( ! $Helper.xmlFieldMetadata( $field ).attribute && ! $Helper.xmlFieldMetadata( $field ).transient ) + #if ( ! $Helper.xmlFieldMetadata( $field ).attribute && ! $Helper.xmlFieldMetadata( $field ).transient && ! $Helper.xmlFieldMetadata( $field ).format ) #set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName ) #if ( ! $fieldTagName ) #set ( $fieldTagName = $field.name ) @@ -629,6 +655,8 @@ public class ${className} { #elseif ( $field.to && $field.multiplicity == "1" ) #if ( $locationTracking ) ${classLcapName}.${field.name}(parse${field.toClass.name}(parser, strict, source)); + #elseif ( $needXmlContext ) + ${classLcapName}.${field.name}(parse${field.toClass.name}(parser, strict, context)); #else ${classLcapName}.${field.name}(parse${field.toClass.name}(parser, strict)); #end @@ -642,6 +670,8 @@ public class ${className} { if ("${Helper.singular($fieldTagName)}".equals(parser.getLocalName())) { #if ( $locationTracking ) ${field.name}.add(parse${field.toClass.name}(parser, strict, source)); + #elseif ( $needXmlContext ) + ${field.name}.add(parse${field.toClass.name}(parser, strict, context)); #else ${field.name}.add(parse${field.toClass.name}(parser, strict)); #end @@ -670,11 +700,19 @@ public class ${className} { } #end } + #if ( $needXmlContext ) + context.removeLast(); + #end #foreach ( $field in $allFields ) #if ( $Helper.isFlatItems( $field ) ) ${classLcapName}.${field.name}(${field.name}); #end #end + #foreach ( $field in $allFields ) + #if ( $Helper.xmlFieldMetadata( $field ).format ) + ${classLcapName}.${field.name}($Helper.xmlFieldMetadata( $field ).format); + #end + #end #if ( $class == $root ) ${classLcapName}.namespaceUri(parser.getNamespaceURI()); ${classLcapName}.modelEncoding(parser.getEncoding()); diff --git a/src/mdo/writer-stax.vm b/src/mdo/writer-stax.vm index cebaa44787b3..dc30f61446ec 100644 --- a/src/mdo/writer-stax.vm +++ b/src/mdo/writer-stax.vm @@ -224,7 +224,7 @@ public class ${className} { serializer.writeStartElement(namespace, tagName); #end #foreach ( $field in $allFields ) - #if ( $Helper.xmlFieldMetadata( $field ).attribute ) + #if ( $Helper.xmlFieldMetadata( $field ).attribute && ! $Helper.xmlFieldMetadata( $field ).format ) #set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName ) #set ( $fieldCapName = $Helper.capitalise( $field.name ) ) #if ( $field.type == "String" ) @@ -242,7 +242,8 @@ public class ${className} { #end #end #foreach ( $field in $allFields ) - #if ( ! $Helper.xmlFieldMetadata( $field ).attribute && ! $Helper.xmlFieldMetadata( $field ).transient ) + #if ( ! $Helper.xmlFieldMetadata( $field ).attribute && ! $Helper.xmlFieldMetadata( $field ).transient + && ! $Helper.xmlFieldMetadata( $field ).format ) #set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName ) #if ( ! $fieldTagName ) #set ( $fieldTagName = $field.name ) From c65142a5d581fc3079729b337e21182df72457c8 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Fri, 17 Nov 2023 13:07:17 +0100 Subject: [PATCH 04/11] Implements the new plugin API --- .../org/apache/maven/api/MojoExecution.java | 4 +- .../java/org/apache/maven/api/Plugin.java | 9 +- .../maven/api/di/MojoExecutionScoped.java | 6 + .../apache/maven/api/di/SessionScoped.java | 9 + .../apache/maven/api/feature/Features.java | 2 + .../maven/internal/impl/DefaultEvent.java | 4 +- .../internal/impl/DefaultMojoExecution.java | 76 ++++++- .../maven/internal/impl/DefaultNode.java | 2 +- .../plugin/DefaultBuildPluginManager.java | 5 +- .../plugin/DefaultPluginDescriptorCache.java | 47 +---- .../PluginParameterExpressionEvaluatorV4.java | 178 +++-------------- .../internal/DefaultMavenPluginManager.java | 25 ++- ...luginParameterExpressionEvaluatorTest.java | 10 +- ...ginParameterExpressionEvaluatorV4Test.java | 188 ++++++++---------- maven-plugin-api/pom.xml | 4 + .../plugin/descriptor/MojoDescriptor.java | 38 ++++ .../maven/plugin/descriptor/Parameter.java | 16 ++ .../plugin/descriptor/PluginDescriptor.java | 108 +++++++++- .../descriptor/PluginDescriptorBuilder.java | 102 +++++++++- 19 files changed, 502 insertions(+), 331 deletions(-) diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/MojoExecution.java b/api/maven-api-core/src/main/java/org/apache/maven/api/MojoExecution.java index 78c3e2c6ea67..2aa5d8a2eb08 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/MojoExecution.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/MojoExecution.java @@ -39,10 +39,10 @@ public interface MojoExecution { Plugin getPlugin(); @Nonnull - PluginExecution getPluginExecutionModel(); + PluginExecution getModel(); @Nonnull - MojoDescriptor getMojoDescriptor(); + MojoDescriptor getDescriptor(); @Nonnull String getExecutionId(); diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Plugin.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Plugin.java index cc78f43c4339..66f93d204a9f 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/Plugin.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Plugin.java @@ -18,7 +18,9 @@ */ package org.apache.maven.api; +import java.util.Collection; import java.util.List; +import java.util.Map; import org.apache.maven.api.annotations.Experimental; import org.apache.maven.api.annotations.Nonnull; @@ -47,5 +49,10 @@ public interface Plugin { Artifact getArtifact(); @Nonnull - List getDependencies(); + default Collection getDependencies() { + return getDependenciesMap().values(); + } + + @Nonnull + Map getDependenciesMap(); } diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/di/MojoExecutionScoped.java b/api/maven-api-core/src/main/java/org/apache/maven/api/di/MojoExecutionScoped.java index 19f8cc18af49..42f39b2d6e64 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/di/MojoExecutionScoped.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/di/MojoExecutionScoped.java @@ -25,6 +25,12 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; +/** + * Indicates that the annotated bean has a lifespan limited to a given mojo execution, + * which means each mojo execution will result in a different instance being injected. + * + * @since 4.0.0 + */ @Scope @Documented @Retention(RUNTIME) diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/di/SessionScoped.java b/api/maven-api-core/src/main/java/org/apache/maven/api/di/SessionScoped.java index 59965c9068bd..5a6485ea6e39 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/di/SessionScoped.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/di/SessionScoped.java @@ -19,13 +19,22 @@ package org.apache.maven.api.di; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; +import java.lang.annotation.Target; import jakarta.inject.Scope; import static java.lang.annotation.RetentionPolicy.RUNTIME; +/** + * Indicates that annotated component should be instantiated before session execution starts + * and discarded after session execution completes. + * + * @since 4.0.0 + */ @Scope @Documented @Retention(RUNTIME) +@Target(ElementType.TYPE) public @interface SessionScoped {} diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/feature/Features.java b/api/maven-api-core/src/main/java/org/apache/maven/api/feature/Features.java index 04ab33d8643c..027591c4dfb3 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/feature/Features.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/feature/Features.java @@ -34,6 +34,8 @@ public final class Features { /** * Name of the Maven user property to enable or disable the build/consumer POM feature. + * + * TODO: v4: remove experimental bit */ public static final String BUILDCONSUMER = "maven.experimental.buildconsumer"; diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultEvent.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultEvent.java index cf73b00d9406..86ec498dfba3 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultEvent.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultEvent.java @@ -53,11 +53,11 @@ public Optional getProject() { @Override public Optional getMojoExecution() { - return Optional.ofNullable(delegate.getMojoExecution()).map(DefaultMojoExecution::new); + return Optional.ofNullable(delegate.getMojoExecution()).map(me -> new DefaultMojoExecution(session, me)); } @Override public Optional getException() { - return Optional.empty(); + return Optional.ofNullable(delegate.getException()); } } diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultMojoExecution.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultMojoExecution.java index a5ef26663fb7..f6f86c30abc8 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultMojoExecution.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultMojoExecution.java @@ -18,19 +18,34 @@ */ package org.apache.maven.internal.impl; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; +import org.apache.maven.RepositoryUtils; +import org.apache.maven.api.Artifact; +import org.apache.maven.api.Dependency; import org.apache.maven.api.MojoExecution; +import org.apache.maven.api.Node; import org.apache.maven.api.Plugin; import org.apache.maven.api.model.PluginExecution; import org.apache.maven.api.plugin.descriptor.MojoDescriptor; +import org.apache.maven.api.plugin.descriptor.PluginDescriptor; +import org.apache.maven.api.plugin.descriptor.lifecycle.Lifecycle; import org.apache.maven.api.xml.XmlNode; import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.eclipse.aether.graph.DependencyNode; public class DefaultMojoExecution implements MojoExecution { + private final InternalSession session; private final org.apache.maven.plugin.MojoExecution delegate; - public DefaultMojoExecution(org.apache.maven.plugin.MojoExecution delegate) { + public DefaultMojoExecution(InternalSession session, org.apache.maven.plugin.MojoExecution delegate) { + this.session = session; this.delegate = delegate; } @@ -40,17 +55,66 @@ public org.apache.maven.plugin.MojoExecution getDelegate() { @Override public Plugin getPlugin() { - return null; + return new Plugin() { + @Override + public org.apache.maven.api.model.Plugin getModel() { + return delegate.getPlugin().getDelegate(); + } + + @Override + public PluginDescriptor getDescriptor() { + return delegate.getMojoDescriptor().getPluginDescriptor().getPluginDescriptorV4(); + } + + @Override + public List getLifecycles() { + try { + return Collections.unmodifiableList(new ArrayList<>(delegate.getMojoDescriptor() + .getPluginDescriptor() + .getLifecycleMappings() + .values())); + } catch (Exception e) { + throw new RuntimeException("Unable to load plugin lifecycles", e); + } + } + + @Override + public ClassLoader getClassLoader() { + return delegate.getMojoDescriptor().getRealm(); + } + + @Override + public Artifact getArtifact() { + org.apache.maven.artifact.Artifact artifact = + delegate.getMojoDescriptor().getPluginDescriptor().getPluginArtifact(); + org.eclipse.aether.artifact.Artifact resolverArtifact = RepositoryUtils.toArtifact(artifact); + return resolverArtifact != null ? session.getArtifact(resolverArtifact) : null; + } + + @Override + public Map getDependenciesMap() { + DependencyNode resolverNode = + delegate.getMojoDescriptor().getPluginDescriptor().getDependencyNode(); + DefaultNode node = new DefaultNode(session, resolverNode, false); + return Collections.unmodifiableMap(node.stream() + .map(Node::getDependency) + .collect(Collectors.toMap(d -> d.getGroupId() + ":" + d.getArtifactId(), d -> d))); + } + }; } @Override - public PluginExecution getPluginExecutionModel() { - return null; + public PluginExecution getModel() { + return delegate.getPlugin().getExecutions().stream() + .filter(pe -> Objects.equals(pe.getId(), getExecutionId())) + .findFirst() + .map(org.apache.maven.model.PluginExecution::getDelegate) + .orElse(null); } @Override - public MojoDescriptor getMojoDescriptor() { - return null; + public MojoDescriptor getDescriptor() { + return delegate.getMojoDescriptor().getMojoDescriptorV4(); } @Override diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultNode.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultNode.java index 7137389aec8a..2efc4c09da67 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultNode.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultNode.java @@ -66,7 +66,7 @@ public List getRemoteRepositories() { @Override public Optional getRepository() { - // TODO + // TODO: v4: implement throw new UnsupportedOperationException("Not implemented yet"); } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java index 3c26360acd09..3c812348bca9 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java @@ -121,8 +121,9 @@ public void executeMojo(MavenSession session, MojoExecution mojoExecution) org.apache.maven.api.plugin.Log.class, new DefaultLog(LoggerFactory.getLogger( mojoExecution.getMojoDescriptor().getFullGoalName()))); - scope.seed(Project.class, InternalSession.from(session.getSession()).getProject(project)); - scope.seed(org.apache.maven.api.MojoExecution.class, new DefaultMojoExecution(mojoExecution)); + InternalSession sessionV4 = InternalSession.from(session.getSession()); + scope.seed(Project.class, sessionV4.getProject(project)); + scope.seed(org.apache.maven.api.MojoExecution.class, new DefaultMojoExecution(sessionV4, mojoExecution)); if (mojoDescriptor.isV4Api()) { org.apache.maven.api.plugin.Mojo mojoV4 = mavenPluginManager.getConfiguredMojo( diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java index 855ad0c47729..3e5f8e8ccbe0 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java @@ -28,11 +28,8 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.maven.RepositoryUtils; -import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.model.Plugin; -import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; -import org.codehaus.plexus.component.repository.ComponentDescriptor; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.RemoteRepository; @@ -97,49 +94,7 @@ public void put(Key cacheKey, PluginDescriptor pluginDescriptor) { } protected static PluginDescriptor clone(PluginDescriptor original) { - PluginDescriptor clone = null; - - if (original != null) { - clone = new PluginDescriptor(); - - clone.setGroupId(original.getGroupId()); - clone.setArtifactId(original.getArtifactId()); - clone.setVersion(original.getVersion()); - clone.setGoalPrefix(original.getGoalPrefix()); - clone.setInheritedByDefault(original.isInheritedByDefault()); - - clone.setName(original.getName()); - clone.setDescription(original.getDescription()); - clone.setRequiredMavenVersion(original.getRequiredMavenVersion()); - clone.setRequiredJavaVersion(original.getRequiredJavaVersion()); - - clone.setPluginArtifact(ArtifactUtils.copyArtifactSafe(original.getPluginArtifact())); - - clone.setComponents(clone(original.getMojos(), clone)); - clone.setId(original.getId()); - clone.setIsolatedRealm(original.isIsolatedRealm()); - clone.setSource(original.getSource()); - - clone.setDependencies(original.getDependencies()); - } - - return clone; - } - - private static List> clone(List mojos, PluginDescriptor pluginDescriptor) { - List> clones = null; - - if (mojos != null) { - clones = new ArrayList<>(mojos.size()); - - for (MojoDescriptor mojo : mojos) { - MojoDescriptor clone = mojo.clone(); - clone.setPluginDescriptor(pluginDescriptor); - clones.add(clone); - } - } - - return clones; + return new PluginDescriptor(original); } private static final class CacheKey implements Key { diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4.java index 179002bb052a..d3620c6c2fef 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4.java @@ -21,16 +21,15 @@ import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; import java.util.Properties; +import org.apache.maven.api.MojoExecution; import org.apache.maven.api.Project; import org.apache.maven.api.Session; -import org.apache.maven.internal.impl.DefaultMojoExecution; -import org.apache.maven.internal.impl.InternalSession; import org.apache.maven.model.interpolation.reflection.ReflectionValueExtractor; -import org.apache.maven.plugin.descriptor.MojoDescriptor; -import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException; import org.codehaus.plexus.component.configurator.expression.TypeAwareExpressionEvaluator; @@ -40,36 +39,18 @@ * * * - * - * - * - * - * - * - * + * * - * - * - * - * * - * - * - * - * - * - * - * - * + * * * * *
Expression matrix
expression evaluation result
session the actual {@link Session}
session.* (since Maven 3)
localRepository {@link Session#getLocalRepository()}
reactorProjects {@link Session#getProjects()}
project {@link org.apache.maven.execution.MavenSession#getCurrentProject()}
session.*
project.*
pom.* (since Maven 3)same as project.*
executedProject {@link org.apache.maven.project.MavenProject#getExecutionProject()}
settings {@link Session#getSettings()}
settings.*
basedir {@link Session#getTopDirectory()} or - * System.getProperty( "user.dir" ) if null
mojoExecution the actual {@link MojoExecution}
mojo (since Maven 3)same as mojoExecution
mojo.* (since Maven 3)
plugin (since Maven 3){@link MojoExecution#getMojoDescriptor()}.{@link MojoDescriptor#getPluginDescriptor() - * getPluginDescriptor()}
plugin.*
mojo.* the actual {@link MojoExecution}
* user properties
* system properties
* project properties
- * Notice: reports was supported in Maven 2.x but was removed in Maven 3 * * @see Session + * @see Project + * @see org.apache.maven.api.settings.Settings * @see MojoExecution */ public class PluginParameterExpressionEvaluatorV4 implements TypeAwareExpressionEvaluator { @@ -165,129 +146,34 @@ public Object evaluate(String expr, Class type) throws ExpressionEvaluationEx return expression.replace("$$", "$"); } - if ("localRepository".equals(expression)) { - // TODO: v4 - value = session.getLocalRepository(); - } else if ("session".equals(expression)) { - value = session; - } else if (expression.startsWith("session")) { - // TODO: v4 - try { - int pathSeparator = expression.indexOf('/'); - - if (pathSeparator > 0) { - String pathExpression = expression.substring(0, pathSeparator); - value = ReflectionValueExtractor.evaluate(pathExpression, session); - if (pathSeparator < expression.length() - 1) { - if (value instanceof Path) { - value = ((Path) value).resolve(expression.substring(pathSeparator + 1)); - } else { - value = value + expression.substring(pathSeparator); + Map objects = new HashMap<>(); + objects.put("session.", session); + objects.put("project.", project); + objects.put("mojo.", mojoExecution); + objects.put("settings.", session.getSettings()); + for (Map.Entry ctx : objects.entrySet()) { + if (expression.startsWith(ctx.getKey())) { + try { + int pathSeparator = expression.indexOf('/'); + if (pathSeparator > 0) { + String pathExpression = expression.substring(0, pathSeparator); + value = ReflectionValueExtractor.evaluate(pathExpression, ctx.getValue()); + if (pathSeparator < expression.length() - 1) { + if (value instanceof Path) { + value = ((Path) value).resolve(expression.substring(pathSeparator + 1)); + } else { + value = value + expression.substring(pathSeparator); + } } + } else { + value = ReflectionValueExtractor.evaluate(expression, ctx.getValue()); } - } else { - value = ReflectionValueExtractor.evaluate(expression, session); - } - } catch (Exception e) { - // TODO don't catch exception - throw new ExpressionEvaluationException( - "Error evaluating plugin parameter expression: " + expression, e); - } - } else if ("reactorProjects".equals(expression)) { - value = session.getProjects(); - } else if ("project".equals(expression)) { - value = project; - } else if ("executedProject".equals(expression)) { - value = InternalSession.from(session) - .getProject(InternalSession.from(session) - .getMavenSession() - .getCurrentProject() - .getExecutionProject()); - } else if (expression.startsWith("project") || expression.startsWith("pom")) { - // TODO: v4 - try { - int pathSeparator = expression.indexOf('/'); - - if (pathSeparator > 0) { - String pathExpression = expression.substring(0, pathSeparator); - value = ReflectionValueExtractor.evaluate(pathExpression, project); - value = value + expression.substring(pathSeparator); - } else { - value = ReflectionValueExtractor.evaluate(expression, project); - } - } catch (Exception e) { - // TODO don't catch exception - throw new ExpressionEvaluationException( - "Error evaluating plugin parameter expression: " + expression, e); - } - } else if (expression.equals("repositorySystemSession")) { - // TODO: v4 - } else if (expression.equals("mojo") || expression.equals("mojoExecution")) { - value = new DefaultMojoExecution(mojoExecution); - } else if (expression.startsWith("mojo")) { - // TODO: v4 - try { - int pathSeparator = expression.indexOf('/'); - - if (pathSeparator > 0) { - String pathExpression = expression.substring(0, pathSeparator); - value = ReflectionValueExtractor.evaluate(pathExpression, mojoExecution); - value = value + expression.substring(pathSeparator); - } else { - value = ReflectionValueExtractor.evaluate(expression, mojoExecution); + break; + } catch (Exception e) { + // TODO don't catch exception + throw new ExpressionEvaluationException( + "Error evaluating plugin parameter expression: " + expression, e); } - } catch (Exception e) { - // TODO don't catch exception - throw new ExpressionEvaluationException( - "Error evaluating plugin parameter expression: " + expression, e); - } - } else if (expression.equals("plugin")) { - // TODO: v4 - value = mojoExecution.getMojoDescriptor().getPluginDescriptor(); - } else if (expression.startsWith("plugin")) { - // TODO: v4 - try { - int pathSeparator = expression.indexOf('/'); - - PluginDescriptor pluginDescriptor = - mojoExecution.getMojoDescriptor().getPluginDescriptor(); - - if (pathSeparator > 0) { - String pathExpression = expression.substring(0, pathSeparator); - value = ReflectionValueExtractor.evaluate(pathExpression, pluginDescriptor); - value = value + expression.substring(pathSeparator); - } else { - value = ReflectionValueExtractor.evaluate(expression, pluginDescriptor); - } - } catch (Exception e) { - throw new ExpressionEvaluationException( - "Error evaluating plugin parameter expression: " + expression, e); - } - } else if ("settings".equals(expression)) { - value = session.getSettings(); - } else if (expression.startsWith("settings")) { - try { - int pathSeparator = expression.indexOf('/'); - - if (pathSeparator > 0) { - String pathExpression = expression.substring(0, pathSeparator); - value = ReflectionValueExtractor.evaluate(pathExpression, session.getSettings()); - value = value + expression.substring(pathSeparator); - } else { - value = ReflectionValueExtractor.evaluate(expression, session.getSettings()); - } - } catch (Exception e) { - // TODO don't catch exception - throw new ExpressionEvaluationException( - "Error evaluating plugin parameter expression: " + expression, e); - } - } else if ("basedir".equals(expression)) { - value = basedir.toString(); - } else if (expression.startsWith("basedir")) { - int pathSeparator = expression.indexOf('/'); - - if (pathSeparator > 0) { - value = basedir.toString() + expression.substring(pathSeparator); } } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java index 781ae70032fd..6fa005b58a6d 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java @@ -25,7 +25,6 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.io.PrintStream; import java.nio.file.Files; import java.util.ArrayList; @@ -47,6 +46,7 @@ import org.apache.maven.classrealm.ClassRealmManager; import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule; +import org.apache.maven.internal.impl.DefaultMojoExecution; import org.apache.maven.internal.impl.InternalSession; import org.apache.maven.internal.xml.XmlPlexusConfiguration; import org.apache.maven.model.Plugin; @@ -222,18 +222,18 @@ private PluginDescriptor extractPluginDescriptor(Artifact pluginArtifact, Plugin ZipEntry pluginDescriptorEntry = pluginJar.getEntry(getPluginDescriptorLocation()); if (pluginDescriptorEntry != null) { - InputStream is = pluginJar.getInputStream(pluginDescriptorEntry); - - pluginDescriptor = parsePluginDescriptor(is, plugin, pluginFile.getAbsolutePath()); + pluginDescriptor = parsePluginDescriptor( + () -> pluginJar.getInputStream(pluginDescriptorEntry), + plugin, + pluginFile.getAbsolutePath()); } } } else { File pluginXml = new File(pluginFile, getPluginDescriptorLocation()); if (pluginXml.isFile()) { - try (InputStream is = Files.newInputStream(pluginXml.toPath())) { - pluginDescriptor = parsePluginDescriptor(is, plugin, pluginXml.getAbsolutePath()); - } + pluginDescriptor = parsePluginDescriptor( + () -> Files.newInputStream(pluginXml.toPath()), plugin, pluginXml.getAbsolutePath()); } } @@ -261,7 +261,8 @@ private String getPluginDescriptorLocation() { return "META-INF/maven/plugin.xml"; } - private PluginDescriptor parsePluginDescriptor(InputStream is, Plugin plugin, String descriptorLocation) + private PluginDescriptor parsePluginDescriptor( + PluginDescriptorBuilder.StreamSupplier is, Plugin plugin, String descriptorLocation) throws PluginDescriptorParsingException { try { return builder.build(is, descriptorLocation); @@ -412,6 +413,7 @@ private void createPluginRealm( discoverPluginComponents(pluginRealm, plugin, pluginDescriptor); + pluginDescriptor.setDependencyNode(root); pluginDescriptor.setClassRealm(pluginRealm); pluginDescriptor.setArtifacts(pluginArtifacts); } @@ -611,11 +613,12 @@ public T getConfiguredMojo(Class mojoInterface, MavenSession session, Moj } ExpressionEvaluator expressionEvaluator; + InternalSession sessionV4 = InternalSession.from(session.getSession()); if (mojoDescriptor.isV4Api()) { expressionEvaluator = new PluginParameterExpressionEvaluatorV4( - session.getSession(), - InternalSession.from(session.getSession()).getProject(session.getCurrentProject()), - mojoExecution); + sessionV4, + sessionV4.getProject(session.getCurrentProject()), + new DefaultMojoExecution(sessionV4, mojoExecution)); } else { expressionEvaluator = new PluginParameterExpressionEvaluator(session, mojoExecution); } diff --git a/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorTest.java b/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorTest.java index 582dfb739ce2..ce2388002357 100644 --- a/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorTest.java +++ b/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorTest.java @@ -401,7 +401,7 @@ public void testUri() throws Exception { mavenSession.getRequest().setTopDirectory(path); mavenSession.getRequest().setRootDirectory(path); - Object result = new PluginParameterExpressionEvaluatorV4(mavenSession.getSession(), null) + Object result = new PluginParameterExpressionEvaluator(mavenSession, new MojoExecution(null)) .evaluate("${session.rootDirectory.uri}"); assertEquals(path.toUri(), result); } @@ -414,7 +414,7 @@ public void testPath() throws Exception { mavenSession.getRequest().setTopDirectory(path); mavenSession.getRequest().setRootDirectory(path); - Object result = new PluginParameterExpressionEvaluatorV4(mavenSession.getSession(), null) + Object result = new PluginParameterExpressionEvaluator(mavenSession, new MojoExecution(null)) .evaluate("${session.rootDirectory/target}"); assertEquals(path.resolve("target"), result); } @@ -428,8 +428,8 @@ public void testPluginInjection() throws Exception { mavenSession.getRequest().setRootDirectory(path); DefaultModelBuildingRequest mbr = new DefaultModelBuildingRequest(); - PluginParameterExpressionEvaluatorV4 evaluator = - new PluginParameterExpressionEvaluatorV4(mavenSession.getSession(), null); + PluginParameterExpressionEvaluator evaluator = + new PluginParameterExpressionEvaluator(mavenSession, new MojoExecution(null)); DefaultPlexusConfiguration configuration = new DefaultPlexusConfiguration("config"); configuration.addChild("uri", "${session.rootDirectory.uri}"); @@ -438,7 +438,7 @@ public void testPluginInjection() throws Exception { configuration.addChild("uriAsciiString", "${session.rootDirectory.uri.ASCIIString}"); configuration.addChild("pathString", "${session.rootDirectory.string}"); - PluginParameterExpressionEvaluatorV4Test.Mojo mojo = new PluginParameterExpressionEvaluatorV4Test.Mojo(); + Mojo mojo = new Mojo(); new EnhancedComponentConfigurator().configureComponent(mojo, configuration, evaluator, null); assertEquals( diff --git a/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4Test.java b/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4Test.java index cc1c73173536..eb676599130a 100644 --- a/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4Test.java +++ b/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorV4Test.java @@ -24,17 +24,19 @@ import java.net.URI; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Properties; import org.apache.maven.AbstractCoreMavenComponentTestCase; +import org.apache.maven.RepositoryUtils; +import org.apache.maven.api.Artifact; +import org.apache.maven.api.MojoExecution; import org.apache.maven.api.Session; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.ArtifactUtils; +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.artifact.handler.DefaultArtifactHandler; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.bridge.MavenRepositorySystem; import org.apache.maven.configuration.internal.EnhancedComponentConfigurator; @@ -42,10 +44,11 @@ import org.apache.maven.execution.DefaultMavenExecutionResult; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenSession; +import org.apache.maven.internal.impl.AbstractSession; +import org.apache.maven.internal.impl.DefaultMojoExecution; import org.apache.maven.internal.impl.DefaultProject; import org.apache.maven.internal.impl.DefaultSession; import org.apache.maven.model.Build; -import org.apache.maven.model.Dependency; import org.apache.maven.model.Model; import org.apache.maven.model.building.DefaultModelBuildingRequest; import org.apache.maven.model.interpolation.reflection.IntrospectionException; @@ -62,6 +65,7 @@ import org.codehaus.plexus.util.Os; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.graph.DefaultDependencyNode; import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.NoLocalRepositoryManagerException; @@ -82,6 +86,9 @@ public class PluginParameterExpressionEvaluatorV4Test extends AbstractCoreMavenComponentTestCase { private static final String FS = File.separator; + @Inject + PlexusContainer container; + @Inject private MavenRepositorySystem factory; @@ -89,83 +96,74 @@ public class PluginParameterExpressionEvaluatorV4Test extends AbstractCoreMavenC @Test public void testPluginDescriptorExpressionReference() throws Exception { - MojoExecution exec = newMojoExecution(); - Session session = newSession(); + MojoExecution exec = newMojoExecution(session); - Object result = new PluginParameterExpressionEvaluatorV4(session, null, exec).evaluate("${plugin}"); + Object result = + new PluginParameterExpressionEvaluatorV4(session, null, exec).evaluate("${mojo.plugin.descriptor}"); System.out.println("Result: " + result); assertSame( - exec.getMojoDescriptor().getPluginDescriptor(), + exec.getPlugin().getDescriptor(), result, - "${plugin} expression does not return plugin descriptor."); + "${mojo.plugin.descriptor} expression does not return plugin descriptor."); } @Test public void testPluginArtifactsExpressionReference() throws Exception { - MojoExecution exec = newMojoExecution(); - - Artifact depArtifact = createArtifact("group", "artifact", "1"); - - List deps = new ArrayList<>(); - deps.add(depArtifact); - - exec.getMojoDescriptor().getPluginDescriptor().setArtifacts(deps); - Session session = newSession(); + MojoExecution exec = newMojoExecution(session); @SuppressWarnings("unchecked") - List depResults = (List) - new PluginParameterExpressionEvaluatorV4(session, null, exec).evaluate("${plugin.artifacts}"); + Collection depResults = (Collection) + new PluginParameterExpressionEvaluatorV4(session, null, exec).evaluate("${mojo.plugin.dependencies}"); System.out.println("Result: " + depResults); assertNotNull(depResults); assertEquals(1, depResults.size()); - assertSame(depArtifact, depResults.get(0), "dependency artifact is wrong."); + assertEquals( + exec.getPlugin().getArtifact().key(), + depResults.iterator().next().key(), + "dependency artifact is wrong."); } @Test public void testPluginArtifactMapExpressionReference() throws Exception { - MojoExecution exec = newMojoExecution(); - - Artifact depArtifact = createArtifact("group", "artifact", "1"); - - List deps = new ArrayList<>(); - deps.add(depArtifact); - - exec.getMojoDescriptor().getPluginDescriptor().setArtifacts(deps); - Session session = newSession(); + MojoExecution exec = newMojoExecution(session); + @SuppressWarnings("unchecked") - Map depResults = (Map) - new PluginParameterExpressionEvaluatorV4(session, null, exec).evaluate("${plugin.artifactMap}"); + Map depResults = (Map) + new PluginParameterExpressionEvaluatorV4(session, null, exec) + .evaluate("${mojo.plugin.dependenciesMap}"); System.out.println("Result: " + depResults); assertNotNull(depResults); assertEquals(1, depResults.size()); - assertSame( - depArtifact, - depResults.get(ArtifactUtils.versionlessKey(depArtifact)), + assertTrue(depResults.containsKey("org.myco.plugins:my-plugin")); + assertEquals( + exec.getPlugin().getArtifact().key(), + depResults.get("org.myco.plugins:my-plugin").key(), "dependency artifact is wrong."); } @Test public void testPluginArtifactIdExpressionReference() throws Exception { - MojoExecution exec = newMojoExecution(); - Session session = newSession(); - Object result = new PluginParameterExpressionEvaluatorV4(session, null, exec).evaluate("${plugin.artifactId}"); + MojoExecution exec = newMojoExecution(session); + + Object result = new PluginParameterExpressionEvaluatorV4(session, null, exec) + .evaluate("${mojo.plugin.artifact.artifactId}"); System.out.println("Result: " + result); assertSame( - exec.getMojoDescriptor().getPluginDescriptor().getArtifactId(), + exec.getPlugin().getArtifact().getArtifactId(), result, "${plugin.artifactId} expression does not return plugin descriptor's artifactId."); } @@ -183,7 +181,7 @@ public void testValueExtractionWithAPomValueContainingAPath() throws Exception { MavenProject project = new MavenProject(model); project.setFile(new File("pom.xml").getCanonicalFile()); - ExpressionEvaluator expressionEvaluator = createExpressionEvaluator(project, null, new Properties()); + ExpressionEvaluator expressionEvaluator = createExpressionEvaluator(project, new Properties()); Object value = expressionEvaluator.evaluate("${project.build.directory}/classes"); String actual = new File(value.toString()).getCanonicalPath(); @@ -200,7 +198,7 @@ public void testEscapedVariablePassthrough() throws Exception { MavenProject project = new MavenProject(model); - ExpressionEvaluator ee = createExpressionEvaluator(project, null, new Properties()); + ExpressionEvaluator ee = createExpressionEvaluator(project, new Properties()); Object value = ee.evaluate("$" + var); @@ -217,7 +215,7 @@ public void testEscapedVariablePassthroughInLargerExpression() throws Exception MavenProject project = new MavenProject(model); - ExpressionEvaluator ee = createExpressionEvaluator(project, null, new Properties()); + ExpressionEvaluator ee = createExpressionEvaluator(project, new Properties()); Object value = ee.evaluate("$" + key); @@ -234,7 +232,7 @@ public void testMultipleSubExpressionsInLargerExpression() throws Exception { MavenProject project = new MavenProject(model); - ExpressionEvaluator ee = createExpressionEvaluator(project, null, new Properties()); + ExpressionEvaluator ee = createExpressionEvaluator(project, new Properties()); Object value = ee.evaluate(key); @@ -247,7 +245,7 @@ public void testMissingPOMPropertyRefInLargerExpression() throws Exception { MavenProject project = new MavenProject(new Model()); - ExpressionEvaluator ee = createExpressionEvaluator(project, null, new Properties()); + ExpressionEvaluator ee = createExpressionEvaluator(project, new Properties()); Object value = ee.evaluate(expr); @@ -267,22 +265,13 @@ public void testPOMPropertyExtractionWithMissingProject_WithDotNotation() throws MavenProject project = new MavenProject(model); - ExpressionEvaluator ee = createExpressionEvaluator(project, null, new Properties()); + ExpressionEvaluator ee = createExpressionEvaluator(project, new Properties()); Object value = ee.evaluate("${" + key + "}"); assertEquals(checkValue, value); } - @Test - public void testBasedirExtractionWithMissingProject() throws Exception { - ExpressionEvaluator ee = createExpressionEvaluator(null, null, new Properties()); - - Object value = ee.evaluate("${basedir}"); - - assertEquals(System.getProperty("user.dir"), value); - } - @Test public void testValueExtractionFromSystemPropertiesWithMissingProject() throws Exception { String sysprop = "PPEET_sysprop1"; @@ -293,7 +282,7 @@ public void testValueExtractionFromSystemPropertiesWithMissingProject() throws E executionProperties.setProperty(sysprop, "value"); } - ExpressionEvaluator ee = createExpressionEvaluator(null, null, executionProperties); + ExpressionEvaluator ee = createExpressionEvaluator(null, executionProperties); Object value = ee.evaluate("${" + sysprop + "}"); @@ -310,7 +299,7 @@ public void testValueExtractionFromSystemPropertiesWithMissingProject_WithDotNot executionProperties.setProperty(sysprop, "value"); } - ExpressionEvaluator ee = createExpressionEvaluator(null, null, executionProperties); + ExpressionEvaluator ee = createExpressionEvaluator(null, executionProperties); Object value = ee.evaluate("${" + sysprop + "}"); @@ -335,15 +324,6 @@ private static MavenSession createSession(PlexusContainer container, ArtifactRep return session; } - @Test - public void testLocalRepositoryExtraction() throws Exception { - ExpressionEvaluator expressionEvaluator = - createExpressionEvaluator(createDefaultProject(), null, new Properties()); - Object value = expressionEvaluator.evaluate("${localRepository}"); - - assertEquals("local", ((org.apache.maven.api.LocalRepository) value).getId()); - } - @Test public void testTwoExpressions() throws Exception { Build build = new Build(); @@ -353,8 +333,7 @@ public void testTwoExpressions() throws Exception { Model model = new Model(); model.setBuild(build); - ExpressionEvaluator expressionEvaluator = - createExpressionEvaluator(new MavenProject(model), null, new Properties()); + ExpressionEvaluator expressionEvaluator = createExpressionEvaluator(new MavenProject(model), new Properties()); Object value = expressionEvaluator.evaluate("${project.build.directory}" + FS + "${project.build.finalName}"); @@ -363,37 +342,31 @@ public void testTwoExpressions() throws Exception { @Test public void testShouldExtractPluginArtifacts() throws Exception { - PluginDescriptor pd = new PluginDescriptor(); - - Artifact artifact = createArtifact("testGroup", "testArtifact", "1.0"); - - pd.setArtifacts(Collections.singletonList(artifact)); - - ExpressionEvaluator ee = createExpressionEvaluator(createDefaultProject(), pd, new Properties()); + ExpressionEvaluator ee = createExpressionEvaluator(createDefaultProject(), new Properties()); - Object value = ee.evaluate("${plugin.artifacts}"); + Object value = ee.evaluate("${mojo.plugin.dependencies}"); - assertTrue(value instanceof List); + assertTrue(value instanceof Collection); @SuppressWarnings("unchecked") - List artifacts = (List) value; + Collection artifacts = (Collection) value; assertEquals(1, artifacts.size()); - Artifact result = artifacts.get(0); + Artifact result = artifacts.iterator().next(); - assertEquals("testGroup", result.getGroupId()); + assertEquals("org.myco.plugins", result.getGroupId()); } @Test void testRootDirectoryNotPrefixed() throws Exception { - ExpressionEvaluator ee = createExpressionEvaluator(createDefaultProject(), null, new Properties()); + ExpressionEvaluator ee = createExpressionEvaluator(createDefaultProject(), new Properties()); assertNull(ee.evaluate("${rootDirectory}")); } @Test void testRootDirectoryWithNull() throws Exception { - ExpressionEvaluator ee = createExpressionEvaluator(createDefaultProject(), null, new Properties()); + ExpressionEvaluator ee = createExpressionEvaluator(createDefaultProject(), new Properties()); Exception e = assertThrows(Exception.class, () -> ee.evaluate("${session.rootDirectory}")); e = assertInstanceOf(IntrospectionException.class, e.getCause()); e = assertInstanceOf(IllegalStateException.class, e.getCause()); @@ -403,7 +376,7 @@ void testRootDirectoryWithNull() throws Exception { @Test void testRootDirectory() throws Exception { this.rootDirectory = Paths.get("myRootDirectory"); - ExpressionEvaluator ee = createExpressionEvaluator(createDefaultProject(), null, new Properties()); + ExpressionEvaluator ee = createExpressionEvaluator(createDefaultProject(), new Properties()); assertInstanceOf(Path.class, ee.evaluate("${session.rootDirectory}")); } @@ -411,54 +384,59 @@ private MavenProject createDefaultProject() { return new MavenProject(new Model()); } - private ExpressionEvaluator createExpressionEvaluator( - MavenProject project, PluginDescriptor pluginDescriptor, Properties executionProperties) throws Exception { + private ExpressionEvaluator createExpressionEvaluator(MavenProject project, Properties executionProperties) + throws Exception { ArtifactRepository repo = getLocalRepository(); MutablePlexusContainer container = (MutablePlexusContainer) getContainer(); MavenSession mavenSession = createSession(container, repo, executionProperties); mavenSession.setCurrentProject(project); mavenSession.getRequest().setRootDirectory(rootDirectory); + mavenSession.getRequest().setTopDirectory(rootDirectory); - DefaultSession session = new DefaultSession(mavenSession, mock(RepositorySystem.class), null, null, null, null); - - MojoDescriptor mojo = new MojoDescriptor(); - mojo.setPluginDescriptor(pluginDescriptor); - mojo.setGoal("goal"); + DefaultSession session = + new DefaultSession(mavenSession, mock(RepositorySystem.class), null, null, container, null); - MojoExecution mojoExecution = new MojoExecution(mojo); + MojoExecution mojoExecution = newMojoExecution(session); return new PluginParameterExpressionEvaluatorV4( session, project != null ? new DefaultProject(session, project) : null, mojoExecution); } - protected Artifact createArtifact(String groupId, String artifactId, String version) throws Exception { - Dependency dependency = new Dependency(); - dependency.setGroupId(groupId); - dependency.setArtifactId(artifactId); - dependency.setVersion(version); - dependency.setType("jar"); - dependency.setScope("compile"); - - return factory.createDependencyArtifact(dependency); - } - - private MojoExecution newMojoExecution() { + private MojoExecution newMojoExecution(Session session) { PluginDescriptor pd = new PluginDescriptor(); pd.setArtifactId("my-plugin"); pd.setGroupId("org.myco.plugins"); pd.setVersion("1"); + DefaultArtifact artifact = new DefaultArtifact( + pd.getGroupId(), + pd.getArtifactId(), + pd.getVersion(), + "compile", + "maven-plugin", + "", + new DefaultArtifactHandler("maven-plugin")); + pd.setPluginArtifact(artifact); + + pd.setArtifacts(Collections.singletonList(artifact)); + DefaultDependencyNode node = new DefaultDependencyNode( + new org.eclipse.aether.graph.Dependency(RepositoryUtils.toArtifact(artifact), "compile")); + pd.setDependencyNode(node); + MojoDescriptor md = new MojoDescriptor(); + md.setGoal("my-goal"); md.setPluginDescriptor(pd); pd.addComponentDescriptor(md); - return new MojoExecution(md); + return new DefaultMojoExecution((AbstractSession) session, new org.apache.maven.plugin.MojoExecution(md)); } private DefaultSession newSession() throws Exception { - return new DefaultSession(newMavenSession(), mock(RepositorySystem.class), null, null, null, null); + DefaultSession session = + new DefaultSession(newMavenSession(), mock(RepositorySystem.class), null, null, container, null); + return session; } private MavenSession newMavenSession() throws Exception { diff --git a/maven-plugin-api/pom.xml b/maven-plugin-api/pom.xml index fa8a7a6bf9b7..a5f8a862bacb 100644 --- a/maven-plugin-api/pom.xml +++ b/maven-plugin-api/pom.xml @@ -58,6 +58,10 @@ under the License. org.codehaus.plexus plexus-classworlds
+ + org.apache.maven.resolver + maven-resolver-api + diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/MojoDescriptor.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/MojoDescriptor.java index e3999c7b21ed..2dd55e2a35ec 100644 --- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/MojoDescriptor.java +++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/MojoDescriptor.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; import org.apache.maven.plugin.Mojo; import org.codehaus.plexus.component.repository.ComponentDescriptor; @@ -608,4 +609,41 @@ public MojoDescriptor clone() { throw new UnsupportedOperationException(e); } } + + private volatile org.apache.maven.api.plugin.descriptor.MojoDescriptor mojoDescriptorV4; + + public org.apache.maven.api.plugin.descriptor.MojoDescriptor getMojoDescriptorV4() { + if (mojoDescriptorV4 == null) { + synchronized (this) { + if (mojoDescriptorV4 == null) { + mojoDescriptorV4 = org.apache.maven.api.plugin.descriptor.MojoDescriptor.newBuilder() + .goal(goal) + .description(getDescription()) + .implementation(getImplementation()) + .language(getLanguage()) + .phase(phase) + .executeGoal(executeGoal) + .executeLifecycle(executeLifecycle) + .executePhase(executePhase) + .aggregator(aggregator) + .dependencyResolution(dependencyResolutionRequired) + .dependencyCollection(dependencyCollectionRequired) + .projectRequired(projectRequired) + .onlineRequired(onlineRequired) + .inheritedByDefault(inheritedByDefault) + .since(since) + .deprecated(deprecated) + .configurator(getComponentConfigurator()) + .parameters(getParameters().stream() + .filter(p -> p.getRequirement() == null) + .map(Parameter::getParameterV4) + .collect(Collectors.toList())) + .id(getId()) + .fullGoalName(getFullGoalName()) + .build(); + } + } + } + return mojoDescriptorV4; + } } diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Parameter.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Parameter.java index 184c7e9786be..dd68ac4d6d60 100644 --- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Parameter.java +++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Parameter.java @@ -168,4 +168,20 @@ public Parameter clone() { throw new UnsupportedOperationException(e); } } + + public org.apache.maven.api.plugin.descriptor.Parameter getParameterV4() { + return org.apache.maven.api.plugin.descriptor.Parameter.newBuilder() + .alias(alias) + .name(name) + .type(type) + .required(required) + .editable(editable) + .description(description) + .expression(expression) + .deprecated(deprecated) + .defaultValue(defaultValue) + .implementation(implementation) + .since(since) + .build(); + } } diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java index e19ef1f6804b..1d0ad619621f 100644 --- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java +++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java @@ -26,12 +26,14 @@ import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Files; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.apache.maven.api.plugin.descriptor.lifecycle.Lifecycle; import org.apache.maven.api.plugin.descriptor.lifecycle.LifecycleConfiguration; @@ -40,7 +42,9 @@ import org.apache.maven.model.Plugin; import org.apache.maven.plugin.lifecycle.io.LifecycleStaxReader; import org.codehaus.plexus.classworlds.realm.ClassRealm; +import org.codehaus.plexus.component.repository.ComponentDescriptor; import org.codehaus.plexus.component.repository.ComponentSetDescriptor; +import org.eclipse.aether.graph.DependencyNode; /** */ @@ -64,6 +68,8 @@ public class PluginDescriptor extends ComponentSetDescriptor implements Cloneabl private List artifacts; + private DependencyNode dependencyNode; + private ClassRealm classRealm; // calculated on-demand. @@ -89,6 +95,64 @@ public class PluginDescriptor extends ComponentSetDescriptor implements Cloneabl // // ---------------------------------------------------------------------- + public PluginDescriptor() {} + + public PluginDescriptor(PluginDescriptor original) { + this.setGroupId(original.getGroupId()); + this.setArtifactId(original.getArtifactId()); + this.setVersion(original.getVersion()); + this.setGoalPrefix(original.getGoalPrefix()); + this.setInheritedByDefault(original.isInheritedByDefault()); + this.setName(original.getName()); + this.setDescription(original.getDescription()); + this.setRequiredMavenVersion(original.getRequiredMavenVersion()); + this.setRequiredJavaVersion(original.getRequiredJavaVersion()); + this.setPluginArtifact(ArtifactUtils.copyArtifactSafe(original.getPluginArtifact())); + this.setComponents(clone(original.getMojos(), this)); + this.setId(original.getId()); + this.setIsolatedRealm(original.isIsolatedRealm()); + this.setSource(original.getSource()); + this.setDependencies(original.getDependencies()); + this.setDependencyNode(original.getDependencyNode()); + } + + private static List> clone(List mojos, PluginDescriptor pluginDescriptor) { + List> clones = null; + if (mojos != null) { + clones = new ArrayList<>(mojos.size()); + for (MojoDescriptor mojo : mojos) { + MojoDescriptor clone = mojo.clone(); + clone.setPluginDescriptor(pluginDescriptor); + clones.add(clone); + } + } + return clones; + } + + public PluginDescriptor(org.apache.maven.api.plugin.descriptor.PluginDescriptor original) { + this.setGroupId(original.getGroupId()); + this.setArtifactId(original.getArtifactId()); + this.setVersion(original.getVersion()); + this.setGoalPrefix(original.getGoalPrefix()); + this.setInheritedByDefault(original.isInheritedByDefault()); + this.setName(original.getName()); + this.setDescription(original.getDescription()); + this.setRequiredMavenVersion(original.getRequiredMavenVersion()); + this.setRequiredJavaVersion(original.getRequiredJavaVersion()); + this.setPluginArtifact(null); // TODO: v4 + this.setComponents(Collections.emptyList()); // TODO: v4 + this.setId(original.getId()); + this.setIsolatedRealm(original.isIsolatedRealm()); + this.setSource(null); + this.setDependencies(Collections.emptyList()); // TODO: v4 + this.setDependencyNode(null); // TODO: v4 + this.pluginDescriptorV4 = original; + } + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + @SuppressWarnings({"unchecked", "rawtypes"}) public List getMojos() { return (List) getComponents(); @@ -220,6 +284,14 @@ public void setArtifacts(List artifacts) { artifactMap = null; } + public DependencyNode getDependencyNode() { + return dependencyNode; + } + + public void setDependencyNode(DependencyNode dependencyNode) { + this.dependencyNode = dependencyNode; + } + /** * The map of artifacts accessible by the versionlessKey, i.e. groupId:artifactId * @@ -326,6 +398,10 @@ public void setPluginArtifact(Artifact pluginArtifact) { } public Lifecycle getLifecycleMapping(String lifecycleId) throws IOException, XMLStreamException { + return getLifecycleMappings().get(lifecycleId); + } + + public Map getLifecycleMappings() throws IOException, XMLStreamException { if (lifecycleMappings == null) { LifecycleConfiguration lifecycleConfiguration; @@ -339,8 +415,7 @@ public Lifecycle getLifecycleMapping(String lifecycleId) throws IOException, XML lifecycleMappings.put(lifecycle.getId(), lifecycle); } } - - return lifecycleMappings.get(lifecycleId); + return lifecycleMappings; } private InputStream getDescriptorStream(String descriptor) throws IOException { @@ -377,4 +452,33 @@ public void addMojos(List mojos) throws DuplicateMojoDescriptorE addMojo(mojoDescriptor); } } + + private volatile org.apache.maven.api.plugin.descriptor.PluginDescriptor pluginDescriptorV4; + + public org.apache.maven.api.plugin.descriptor.PluginDescriptor getPluginDescriptorV4() { + if (pluginDescriptorV4 == null) { + synchronized (this) { + if (pluginDescriptorV4 == null) { + pluginDescriptorV4 = org.apache.maven.api.plugin.descriptor.PluginDescriptor.newBuilder() + .namespaceUri(null) + .modelEncoding(null) + .name(name) + .description(description) + .groupId(groupId) + .artifactId(artifactId) + .version(version) + .goalPrefix(goalPrefix) + .isolatedRealm(isIsolatedRealm()) + .inheritedByDefault(inheritedByDefault) + .requiredJavaVersion(requiredJavaVersion) + .requiredMavenVersion(requiredMavenVersion) + .mojos(getMojos().stream() + .map(MojoDescriptor::getMojoDescriptorV4) + .collect(Collectors.toList())) + .build(); + } + } + } + return pluginDescriptorV4; + } } diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilder.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilder.java index 13a5a08b1f10..89d31b7df422 100644 --- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilder.java +++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilder.java @@ -21,6 +21,9 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.util.ArrayList; @@ -28,8 +31,10 @@ import java.util.Optional; import com.ctc.wstx.stax.WstxInputFactory; +import org.apache.maven.api.xml.XmlNode; import org.apache.maven.internal.xml.XmlNodeBuilder; import org.apache.maven.internal.xml.XmlPlexusConfiguration; +import org.apache.maven.plugin.descriptor.io.PluginDescriptorStaxReader; import org.codehaus.plexus.component.repository.ComponentDependency; import org.codehaus.plexus.component.repository.ComponentRequirement; import org.codehaus.plexus.configuration.PlexusConfiguration; @@ -38,16 +43,109 @@ /** */ public class PluginDescriptorBuilder { + + public static final String PLUGIN_2_0_0 = "http://maven.apache.org/PLUGIN/2.0.0"; + private static final int BUFFER_SIZE = 8192; + + public interface StreamSupplier { + InputStream open() throws IOException; + } + + public interface ReaderSupplier { + Reader open() throws IOException; + } + + /** + * @deprecated use {@link #build(ReaderSupplier)} + */ + @Deprecated public PluginDescriptor build(Reader reader) throws PlexusConfigurationException { return build(reader, null); } + /** + * @deprecated use {@link #build(ReaderSupplier, String)} + */ + @Deprecated public PluginDescriptor build(Reader reader, String source) throws PlexusConfigurationException { - return build(source, buildConfiguration(reader)); + return build(() -> reader, source); + } + + public PluginDescriptor build(ReaderSupplier readerSupplier) throws PlexusConfigurationException { + return build(readerSupplier, null); } + public PluginDescriptor build(ReaderSupplier readerSupplier, String source) throws PlexusConfigurationException { + try (BufferedReader br = new BufferedReader(readerSupplier.open(), BUFFER_SIZE)) { + br.mark(BUFFER_SIZE); + XMLStreamReader xsr = WstxInputFactory.newFactory().createXMLStreamReader(br); + xsr.nextTag(); + String nsUri = xsr.getNamespaceURI(); + try (BufferedReader br2 = reset(readerSupplier, br)) { + xsr = WstxInputFactory.newFactory().createXMLStreamReader(br2); + return build(source, nsUri, xsr); + } + } catch (XMLStreamException | IOException e) { + throw new PlexusConfigurationException(e.getMessage(), e); + } + } + + /** + * @deprecated use {@link #build(StreamSupplier, String)} + */ + @Deprecated public PluginDescriptor build(InputStream input, String source) throws PlexusConfigurationException { - return build(source, buildConfiguration(input)); + return build(() -> input, source); + } + + public PluginDescriptor build(StreamSupplier inputSupplier) throws PlexusConfigurationException { + return build(inputSupplier, null); + } + + public PluginDescriptor build(StreamSupplier inputSupplier, String source) throws PlexusConfigurationException { + try (BufferedInputStream bis = new BufferedInputStream(inputSupplier.open(), BUFFER_SIZE)) { + bis.mark(BUFFER_SIZE); + XMLStreamReader xsr = WstxInputFactory.newFactory().createXMLStreamReader(bis); + xsr.nextTag(); + String nsUri = xsr.getNamespaceURI(); + try (BufferedInputStream bis2 = reset(inputSupplier, bis)) { + xsr = WstxInputFactory.newFactory().createXMLStreamReader(bis2); + return build(source, nsUri, xsr); + } + } catch (XMLStreamException | IOException e) { + throw new PlexusConfigurationException(e.getMessage(), e); + } + } + + private static BufferedInputStream reset(StreamSupplier inputSupplier, BufferedInputStream bis) throws IOException { + try { + bis.reset(); + return bis; + } catch (IOException e) { + return new BufferedInputStream(inputSupplier.open(), BUFFER_SIZE); + } + } + + private static BufferedReader reset(ReaderSupplier readerSupplier, BufferedReader br) throws IOException { + try { + br.reset(); + return br; + } catch (IOException e) { + return new BufferedReader(readerSupplier.open(), BUFFER_SIZE); + } + } + + private PluginDescriptor build(String source, String nsUri, XMLStreamReader xsr) + throws XMLStreamException, PlexusConfigurationException { + if (PLUGIN_2_0_0.equals(nsUri)) { + org.apache.maven.api.plugin.descriptor.PluginDescriptor pd = + new PluginDescriptorStaxReader().read(xsr, true); + return new PluginDescriptor(pd); + } else { + XmlNode node = XmlNodeBuilder.build(xsr, true, null); + PlexusConfiguration cfg = XmlPlexusConfiguration.toPlexusConfiguration(node); + return build(source, cfg); + } } private PluginDescriptor build(String source, PlexusConfiguration c) throws PlexusConfigurationException { From 775a5fe8a79163f53a842cb9c1f79d774d929eac Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Tue, 28 Nov 2023 06:05:36 +0100 Subject: [PATCH 05/11] Fix scopes, support session scoped proxies defined using providers --- .../maven/api/di/MojoExecutionScoped.java | 4 ++ .../apache/maven/api/di/SessionScoped.java | 5 +- .../internal/impl/DefaultArtifactManager.java | 4 +- .../internal/impl/DefaultProjectManager.java | 4 +- .../session/scope/internal/SessionScope.java | 58 ++++++++++++------- .../scope/internal/SessionScopeModule.java | 12 +++- 6 files changed, 59 insertions(+), 28 deletions(-) diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/di/MojoExecutionScoped.java b/api/maven-api-core/src/main/java/org/apache/maven/api/di/MojoExecutionScoped.java index 42f39b2d6e64..2fcbe07991ce 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/di/MojoExecutionScoped.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/di/MojoExecutionScoped.java @@ -20,9 +20,12 @@ import java.lang.annotation.Documented; import java.lang.annotation.Retention; +import java.lang.annotation.Target; import jakarta.inject.Scope; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** @@ -34,4 +37,5 @@ @Scope @Documented @Retention(RUNTIME) +@Target({TYPE, METHOD}) public @interface MojoExecutionScoped {} diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/di/SessionScoped.java b/api/maven-api-core/src/main/java/org/apache/maven/api/di/SessionScoped.java index 5a6485ea6e39..d5e9a0ddbe53 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/di/SessionScoped.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/di/SessionScoped.java @@ -19,12 +19,13 @@ package org.apache.maven.api.di; import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.Target; import jakarta.inject.Scope; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** @@ -36,5 +37,5 @@ @Scope @Documented @Retention(RUNTIME) -@Target(ElementType.TYPE) +@Target({TYPE, METHOD}) public @interface SessionScoped {} diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactManager.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactManager.java index 4336527aa860..2895efd831fb 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactManager.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactManager.java @@ -27,13 +27,15 @@ import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; -import org.apache.maven.SessionScoped; import org.apache.maven.api.Artifact; import org.apache.maven.api.annotations.Nonnull; +import org.apache.maven.api.di.SessionScoped; import org.apache.maven.api.services.ArtifactManager; import org.apache.maven.project.MavenProject; +import org.eclipse.sisu.Typed; @Named +@Typed @SessionScoped public class DefaultArtifactManager implements ArtifactManager { diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java index f329ba83eba1..a08d3a2253a6 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectManager.java @@ -30,7 +30,6 @@ import java.util.stream.Collectors; import org.apache.maven.RepositoryUtils; -import org.apache.maven.SessionScoped; import org.apache.maven.api.Artifact; import org.apache.maven.api.Node; import org.apache.maven.api.Project; @@ -39,6 +38,7 @@ import org.apache.maven.api.Scope; import org.apache.maven.api.Session; import org.apache.maven.api.annotations.Nonnull; +import org.apache.maven.api.di.SessionScoped; import org.apache.maven.api.services.ArtifactManager; import org.apache.maven.api.services.MavenException; import org.apache.maven.api.services.ProjectManager; @@ -47,8 +47,10 @@ import org.apache.maven.project.MavenProject; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.eclipse.sisu.Typed; @Named +@Typed @SessionScoped public class DefaultProjectManager implements ProjectManager { diff --git a/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScope.java b/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScope.java index aa8e45116ba9..a29b16fb2d1b 100644 --- a/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScope.java +++ b/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScope.java @@ -110,31 +110,41 @@ private T createProxy(Key key, Provider unscoped) { return method.invoke(getScopeState().scope(key, unscoped).get(), args); }; Class superType = (Class) key.getTypeLiteral().getRawType(); - for (Annotation a : superType.getAnnotations()) { - Class annotationType = a.annotationType(); - if ("org.eclipse.sisu.Typed".equals(annotationType.getName()) - || "javax.enterprise.inject.Typed".equals(annotationType.getName())) { - try { - Class[] value = - (Class[]) annotationType.getMethod("value").invoke(a); - if (value.length == 0) { - value = superType.getInterfaces(); - } - List> nonInterfaces = - Stream.of(value).filter(c -> !c.isInterface()).collect(Collectors.toList()); - if (!nonInterfaces.isEmpty()) { - throw new IllegalArgumentException( - "The Typed annotation must contain only interfaces but the following types are not: " - + nonInterfaces); + Class[] interfaces = getInterfaces(superType); + return (T) java.lang.reflect.Proxy.newProxyInstance(superType.getClassLoader(), interfaces, dispatcher); + } + + private Class[] getInterfaces(Class superType) { + if (superType.isInterface()) { + return new Class[] {superType}; + } else { + for (Annotation a : superType.getAnnotations()) { + Class annotationType = a.annotationType(); + if ("org.eclipse.sisu.Typed".equals(annotationType.getName()) + || "javax.enterprise.inject.Typed".equals(annotationType.getName()) + || "jakarta.enterprise.inject.Typed".equals(annotationType.getName())) { + try { + Class[] value = + (Class[]) annotationType.getMethod("value").invoke(a); + if (value.length == 0) { + value = superType.getInterfaces(); + } + List> nonInterfaces = + Stream.of(value).filter(c -> !c.isInterface()).collect(Collectors.toList()); + if (!nonInterfaces.isEmpty()) { + throw new IllegalArgumentException( + "The Typed annotation must contain only interfaces but the following types are not: " + + nonInterfaces); + } + return value; + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + throw new IllegalStateException(e); } - return (T) java.lang.reflect.Proxy.newProxyInstance(superType.getClassLoader(), value, dispatcher); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - throw new IllegalStateException(e); } } + throw new IllegalArgumentException("The use of session scoped proxies require " + + "a org.eclipse.sisu.Typed or javax.enterprise.inject.Typed annotation"); } - throw new IllegalArgumentException("The use of session scoped proxies require " - + "a org.eclipse.sisu.Typed or javax.enterprise.inject.Typed annotation"); } /** @@ -170,4 +180,10 @@ public T get() { public static Provider seededKeyProvider() { return (Provider) SEEDED_KEY_PROVIDER; } + + public static Provider seededKeyProvider(Class clazz) { + return () -> { + throw new IllegalStateException("No instance of " + clazz.getName() + " is bound to the session scope."); + }; + } } diff --git a/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java b/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java index 98ad4c9e61f3..7325dfccd7b1 100644 --- a/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java +++ b/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java @@ -55,8 +55,14 @@ protected void configure() { bindScope(org.apache.maven.api.di.SessionScoped.class, scope); bind(SessionScope.class).toInstance(scope); - bind(MavenSession.class).toProvider(SessionScope.seededKeyProvider()).in(scope); - bind(Session.class).toProvider(SessionScope.seededKeyProvider()).in(scope); - bind(InternalSession.class).toProvider(SessionScope.seededKeyProvider()).in(scope); + bind(MavenSession.class) + .toProvider(SessionScope.seededKeyProvider(MavenSession.class)) + .in(scope); + bind(Session.class) + .toProvider(SessionScope.seededKeyProvider(Session.class)) + .in(scope); + bind(InternalSession.class) + .toProvider(SessionScope.seededKeyProvider(InternalSession.class)) + .in(scope); } } From 695b7a8c965e7a982ed857726b213b100948c8dd Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Tue, 28 Nov 2023 06:05:51 +0100 Subject: [PATCH 06/11] Automatically convert optionals --- .../interpolation/reflection/ReflectionValueExtractor.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/ReflectionValueExtractor.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/ReflectionValueExtractor.java index e36094cbb66c..205405614f9a 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/ReflectionValueExtractor.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/ReflectionValueExtractor.java @@ -26,6 +26,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.WeakHashMap; import org.apache.maven.api.annotations.Nonnull; @@ -213,6 +214,9 @@ public static Object evaluate(@Nonnull String expression, @Nullable Object root, } } + if (value instanceof Optional) { + value = ((Optional) value).orElse(null); + } return value; } From 00fb11ab656d68c8bbd49c81d3bd3236def1ef1d Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Wed, 29 Nov 2023 11:51:53 +0100 Subject: [PATCH 07/11] Complete implementation for v4 plugins --- api/maven-api-plugin/src/main/mdo/plugin.mdo | 6 ---- ...faultLifecycleExecutionPlanCalculator.java | 28 ++++++++++++------- .../plugin/descriptor/MojoDescriptor.java | 28 +++++++++++++++++++ .../maven/plugin/descriptor/Parameter.java | 20 ++++++++++++- .../plugin/descriptor/PluginDescriptor.java | 3 ++ 5 files changed, 68 insertions(+), 17 deletions(-) diff --git a/api/maven-api-plugin/src/main/mdo/plugin.mdo b/api/maven-api-plugin/src/main/mdo/plugin.mdo index 6f21b017c51e..019236dec8cb 100644 --- a/api/maven-api-plugin/src/main/mdo/plugin.mdo +++ b/api/maven-api-plugin/src/main/mdo/plugin.mdo @@ -476,12 +476,6 @@ under the License. full of Strings. ]]> - - implementation - 1.0.0+ - String - - description 1.0.0+ diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java index 03a511a589d1..3c8d6e8bed6b 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java @@ -24,15 +24,8 @@ import javax.xml.stream.XMLStreamException; import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; +import java.util.stream.Collectors; import org.apache.maven.api.plugin.descriptor.lifecycle.Execution; import org.apache.maven.api.plugin.descriptor.lifecycle.Phase; @@ -340,7 +333,22 @@ private void finalizeMojoConfiguration(MojoExecution mojoExecution) { } private XmlNode getMojoConfiguration(MojoDescriptor mojoDescriptor) { - return MojoDescriptorCreator.convert(mojoDescriptor).getDom(); + if (mojoDescriptor.isV4Api()) { + List children = mojoDescriptor.getMojoDescriptorV4().getParameters().stream() + .map(p -> new XmlNodeImpl( + p.getName(), + p.getExpression(), + p.getDefaultValue() != null + ? Collections.singletonMap("default-value", p.getDefaultValue()) + : null, + null, + null)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + return new XmlNodeImpl("configuration", null, null, children, null); + } else { + return MojoDescriptorCreator.convert(mojoDescriptor).getDom(); + } } @Override diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/MojoDescriptor.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/MojoDescriptor.java index 2dd55e2a35ec..12fe5471e22e 100644 --- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/MojoDescriptor.java +++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/MojoDescriptor.java @@ -147,6 +147,34 @@ public MojoDescriptor() { setComponentFactory(DEFAULT_LANGUAGE); } + public MojoDescriptor(PluginDescriptor pd, org.apache.maven.api.plugin.descriptor.MojoDescriptor md) { + this(); + this.setPluginDescriptor(pd); + this.setGoal(md.getGoal()); + this.setExecuteGoal(md.getExecuteGoal()); + this.setExecuteLifecycle(md.getExecuteLifecycle()); + this.setExecutePhase(md.getExecutePhase()); + this.setDeprecated(md.getDeprecated()); + this.setLanguage(md.getLanguage()); + this.setAggregator(md.isAggregator()); + this.setDependencyCollectionRequired(md.getDependencyCollection()); + this.setDependencyResolutionRequired(md.getDependencyResolution()); + this.setComponentConfigurator(md.getConfigurator()); + this.setInheritedByDefault(md.isInheritedByDefault()); + this.setPhase(md.getPhase()); + this.setOnlineRequired(md.isOnlineRequired()); + this.setProjectRequired(md.isProjectRequired()); + this.setSince(md.getSince()); + this.setThreadSafe(true); + this.setV4Api(true); + this.setImplementation(md.getImplementation()); + try { + this.setParameters(md.getParameters().stream().map(Parameter::new).collect(Collectors.toList())); + } catch (DuplicateParameterException e) { + throw new IllegalArgumentException(e); + } + this.mojoDescriptorV4 = md; + } // ---------------------------------------------------------------------- // // ---------------------------------------------------------------------- diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Parameter.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Parameter.java index dd68ac4d6d60..0249b1d19c27 100644 --- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Parameter.java +++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Parameter.java @@ -49,6 +49,25 @@ public class Parameter implements Cloneable { // // ---------------------------------------------------------------------- + public Parameter() {} + + public Parameter(org.apache.maven.api.plugin.descriptor.Parameter p) { + this.setAlias(p.getAlias()); + this.setName(p.getName()); + this.setRequired(p.isRequired()); + this.setEditable(p.isEditable()); + this.setDescription(p.getDescription()); + this.setExpression(p.getExpression()); + this.setDeprecated(p.getDeprecated()); + this.setDefaultValue(p.getDefaultValue()); + this.setType(p.getType()); + this.setSince(p.getSince()); + } + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + public String getName() { return name; } @@ -180,7 +199,6 @@ public org.apache.maven.api.plugin.descriptor.Parameter getParameterV4() { .expression(expression) .deprecated(deprecated) .defaultValue(defaultValue) - .implementation(implementation) .since(since) .build(); } diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java index 1d0ad619621f..482fcdab7a51 100644 --- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java +++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java @@ -141,6 +141,9 @@ public PluginDescriptor(org.apache.maven.api.plugin.descriptor.PluginDescriptor this.setRequiredJavaVersion(original.getRequiredJavaVersion()); this.setPluginArtifact(null); // TODO: v4 this.setComponents(Collections.emptyList()); // TODO: v4 + this.setComponents(original.getMojos().stream() + .map(m -> new MojoDescriptor(this, m)) + .collect(Collectors.toList())); this.setId(original.getId()); this.setIsolatedRealm(original.isIsolatedRealm()); this.setSource(null); From a7d539c2cd610fc35ae6dca10a2797651c6aed20 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Thu, 30 Nov 2023 16:56:56 +0100 Subject: [PATCH 08/11] Small refactor --- ...DefaultLifecycleExecutionPlanCalculator.java | 14 +------------- .../internal/MojoDescriptorCreator.java | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java index 3c8d6e8bed6b..71355f3af0a3 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java @@ -25,7 +25,6 @@ import java.io.IOException; import java.util.*; -import java.util.stream.Collectors; import org.apache.maven.api.plugin.descriptor.lifecycle.Execution; import org.apache.maven.api.plugin.descriptor.lifecycle.Phase; @@ -334,18 +333,7 @@ private void finalizeMojoConfiguration(MojoExecution mojoExecution) { private XmlNode getMojoConfiguration(MojoDescriptor mojoDescriptor) { if (mojoDescriptor.isV4Api()) { - List children = mojoDescriptor.getMojoDescriptorV4().getParameters().stream() - .map(p -> new XmlNodeImpl( - p.getName(), - p.getExpression(), - p.getDefaultValue() != null - ? Collections.singletonMap("default-value", p.getDefaultValue()) - : null, - null, - null)) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - return new XmlNodeImpl("configuration", null, null, children, null); + return MojoDescriptorCreator.convert(mojoDescriptor.getMojoDescriptorV4()); } else { return MojoDescriptorCreator.convert(mojoDescriptor).getDom(); } diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java index ec0baabf2c50..a31f52f6d0b7 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java @@ -26,6 +26,8 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; import org.apache.maven.api.xml.XmlNode; import org.apache.maven.execution.MavenSession; @@ -91,6 +93,21 @@ private Plugin findPlugin(String groupId, String artifactId, Collection return null; } + public static XmlNode convert(org.apache.maven.api.plugin.descriptor.MojoDescriptor mojoDescriptor) { + List children = mojoDescriptor.getParameters().stream() + .map(p -> new XmlNodeImpl( + p.getName(), + p.getExpression(), + p.getDefaultValue() != null + ? Collections.singletonMap("default-value", p.getDefaultValue()) + : null, + null, + null)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + return new XmlNodeImpl("configuration", null, null, children, null); + } + public static org.codehaus.plexus.util.xml.Xpp3Dom convert(MojoDescriptor mojoDescriptor) { PlexusConfiguration c = mojoDescriptor.getMojoConfiguration(); From 1169fc844e00ffa0813783829f5d3754fc691c6d Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Thu, 30 Nov 2023 17:56:45 +0100 Subject: [PATCH 09/11] Do not include empty elements --- .../apache/maven/lifecycle/internal/MojoDescriptorCreator.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java index a31f52f6d0b7..1557879dca76 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java @@ -26,7 +26,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Objects; import java.util.stream.Collectors; import org.apache.maven.api.xml.XmlNode; @@ -95,6 +94,7 @@ private Plugin findPlugin(String groupId, String artifactId, Collection public static XmlNode convert(org.apache.maven.api.plugin.descriptor.MojoDescriptor mojoDescriptor) { List children = mojoDescriptor.getParameters().stream() + .filter(p -> p.getDefaultValue() != null || p.getExpression() != null) .map(p -> new XmlNodeImpl( p.getName(), p.getExpression(), @@ -103,7 +103,6 @@ public static XmlNode convert(org.apache.maven.api.plugin.descriptor.MojoDescrip : null, null, null)) - .filter(Objects::nonNull) .collect(Collectors.toList()); return new XmlNodeImpl("configuration", null, null, children, null); } From 60adb18b84424c9370abd856b542b24d229dcaab Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Fri, 1 Dec 2023 14:28:53 +0100 Subject: [PATCH 10/11] Use a mutable WorkspaceReader instead of mutating the session --- .../java/org/apache/maven/DefaultMaven.java | 42 ++++---- .../apache/maven/execution/MavenSession.java | 15 ++- .../aether/MavenChainedWorkspaceReader.java | 95 +++++++++++++++---- .../impl/DefaultArtifactResolver.java | 39 ++++---- .../maven/internal/impl/DefaultSession.java | 7 +- .../apache/maven/internal/impl/TestApi.java | 2 +- 6 files changed, 131 insertions(+), 69 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java index 85aee3f98eed..10d28bc438a7 100644 --- a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java +++ b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java @@ -36,7 +36,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.stream.Stream; @@ -215,9 +214,9 @@ private MavenExecutionResult doExecute(MavenExecutionRequest request) { // so that @SessionScoped components can be @Injected into AbstractLifecycleParticipants. // sessionScope.enter(); - try (CloseableSession closeableSession = newCloseableSession(request)) { - AtomicReference closeableSessionRef = new AtomicReference<>(closeableSession); - MavenSession session = new MavenSession(closeableSessionRef::get, request, result); + MavenChainedWorkspaceReader chainedWorkspaceReader = new MavenChainedWorkspaceReader(); + try (CloseableSession closeableSession = newCloseableSession(request, chainedWorkspaceReader)) { + MavenSession session = new MavenSession(closeableSession, request, result); session.setSession(defaultSessionFactory.getSession(session)); sessionScope.seed(MavenSession.class, session); @@ -226,7 +225,7 @@ private MavenExecutionResult doExecute(MavenExecutionRequest request) { legacySupport.setSession(session); - return doExecute(request, session, result, closeableSessionRef); + return doExecute(request, session, result, chainedWorkspaceReader); } finally { sessionScope.exit(); } @@ -236,7 +235,7 @@ private MavenExecutionResult doExecute( MavenExecutionRequest request, MavenSession session, MavenExecutionResult result, - AtomicReference closeableSessionRef) { + MavenChainedWorkspaceReader chainedWorkspaceReader) { try { afterSessionStart(session); } catch (MavenExecutionException e) { @@ -245,11 +244,7 @@ private MavenExecutionResult doExecute( try { WorkspaceReader reactorReader = container.lookup(WorkspaceReader.class, ReactorReader.HINT); - closeableSessionRef.set(closeableSessionRef - .get() - .copy() - .setWorkspaceReader(reactorReader) - .build()); + chainedWorkspaceReader.setReaders(Collections.singletonList(reactorReader)); } catch (ComponentLookupException e) { return addExceptionToResult(result, e); } @@ -270,7 +265,7 @@ private MavenExecutionResult doExecute( } try { - closeableSessionRef.set(setupWorkspaceReader(session, closeableSessionRef.get())); + setupWorkspaceReader(session, chainedWorkspaceReader); } catch (ComponentLookupException e) { return addExceptionToResult(result, e); } @@ -340,7 +335,7 @@ private MavenExecutionResult doExecute( return result; } - private CloseableSession setupWorkspaceReader(MavenSession session, CloseableSession repoSession) + private void setupWorkspaceReader(MavenSession session, MavenChainedWorkspaceReader chainedWorkspaceReader) throws ComponentLookupException { // Desired order of precedence for workspace readers before querying the local artifact repositories Set workspaceReaders = new LinkedHashSet<>(); @@ -348,16 +343,14 @@ private CloseableSession setupWorkspaceReader(MavenSession session, CloseableSes WorkspaceReader reactorReader = container.lookup(WorkspaceReader.class, ReactorReader.HINT); workspaceReaders.add(reactorReader); // 2) Repository system session-scoped workspace reader - WorkspaceReader repoWorkspaceReader = repoSession.getWorkspaceReader(); - if (repoWorkspaceReader != null && repoWorkspaceReader != reactorReader) { - workspaceReaders.add(repoWorkspaceReader); + for (WorkspaceReader repoWorkspaceReader : chainedWorkspaceReader.getReaders()) { + if (repoWorkspaceReader != null && repoWorkspaceReader != reactorReader) { + workspaceReaders.add(repoWorkspaceReader); + } } // 3) .. n) Project-scoped workspace readers workspaceReaders.addAll(getProjectScopedExtensionComponents(session.getProjects(), WorkspaceReader.class)); - return repoSession - .copy() - .setWorkspaceReader(MavenChainedWorkspaceReader.of(workspaceReaders)) - .build(); + chainedWorkspaceReader.setReaders(workspaceReaders); } private void afterSessionStart(MavenSession session) throws MavenExecutionException { @@ -418,11 +411,14 @@ private void persistResumptionData(MavenExecutionResult result, MavenSession ses */ @Deprecated public RepositorySystemSession newRepositorySession(MavenExecutionRequest request) { - return newCloseableSession(request); + return newCloseableSession(request, new MavenChainedWorkspaceReader()); } - private CloseableSession newCloseableSession(MavenExecutionRequest request) { - return repositorySessionFactory.newRepositorySessionBuilder(request).build(); + private CloseableSession newCloseableSession(MavenExecutionRequest request, WorkspaceReader workspaceReader) { + return repositorySessionFactory + .newRepositorySessionBuilder(request) + .setWorkspaceReader(workspaceReader) + .build(); } private void validateLocalRepository(MavenExecutionRequest request) throws IOException { diff --git a/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java b/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java index 6e1818b7fad0..ac6c1eddbc50 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java +++ b/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java @@ -27,7 +27,6 @@ import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.function.Supplier; import java.util.stream.Collectors; import org.apache.maven.api.Session; @@ -58,7 +57,7 @@ public class MavenSession implements Cloneable { private final MavenExecutionResult result; - private final Supplier repositorySystemSessionSupplier; + private final RepositorySystemSession repositorySystemSession; private final Properties executionProperties; @@ -260,7 +259,7 @@ public void setParallel(boolean parallel) { } public RepositorySystemSession getRepositorySession() { - return repositorySystemSessionSupplier.get(); + return repositorySystemSession; } private Map projectMap; @@ -298,14 +297,14 @@ public Map getProjectMap() { } public MavenSession( - Supplier repositorySystemSessionSupplier, + RepositorySystemSession repositorySystemSession, MavenExecutionRequest request, MavenExecutionResult result) { this.container = null; this.request = requireNonNull(request); this.result = requireNonNull(result); this.settings = adaptSettings(request); - this.repositorySystemSessionSupplier = requireNonNull(repositorySystemSessionSupplier); + this.repositorySystemSession = requireNonNull(repositorySystemSession); Properties executionProperties = new Properties(); executionProperties.putAll(request.getSystemProperties()); executionProperties.putAll(request.getUserProperties()); @@ -322,7 +321,7 @@ public MavenSession( this.request = request; this.result = result; this.settings = adaptSettings(request); - this.repositorySystemSessionSupplier = () -> repositorySession; + this.repositorySystemSession = repositorySession; Properties executionProperties = new Properties(); executionProperties.putAll(request.getSystemProperties()); executionProperties.putAll(request.getUserProperties()); @@ -386,7 +385,7 @@ public MavenSession( this.request.setBaseDirectory((executionRootDir != null) ? new File(executionRootDir) : null); this.request.setStartTime(startTime); this.result = null; - this.repositorySystemSessionSupplier = () -> null; + this.repositorySystemSession = null; } @Deprecated @@ -404,7 +403,7 @@ public MavenSession( executionProperties.putAll(request.getUserProperties()); this.executionProperties = executionProperties; setProjects(projects); - this.repositorySystemSessionSupplier = () -> null; + this.repositorySystemSession = null; } /** diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/MavenChainedWorkspaceReader.java b/maven-core/src/main/java/org/apache/maven/internal/aether/MavenChainedWorkspaceReader.java index 6cf9ed8b62d4..f23a3dba004b 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/MavenChainedWorkspaceReader.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/MavenChainedWorkspaceReader.java @@ -19,61 +19,122 @@ package org.apache.maven.internal.aether; import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; import java.util.List; +import java.util.stream.Collectors; import org.apache.maven.model.Model; import org.apache.maven.repository.internal.MavenWorkspaceReader; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.repository.WorkspaceReader; import org.eclipse.aether.repository.WorkspaceRepository; -import org.eclipse.aether.util.repository.ChainedWorkspaceReader; + +import static java.util.Objects.requireNonNull; /** * A maven workspace reader that delegates to a chain of other readers, effectively aggregating their contents. */ -public final class MavenChainedWorkspaceReader implements MavenWorkspaceReader { - - private ChainedWorkspaceReader delegate; +public class MavenChainedWorkspaceReader implements MavenWorkspaceReader { - private WorkspaceReader[] readers; + protected List readers; + protected WorkspaceRepository repository; /** * Creates a new workspace reader by chaining the specified readers. * * @param readers The readers to chain must not be {@code null}. */ - private MavenChainedWorkspaceReader(WorkspaceReader... readers) { - this.delegate = new ChainedWorkspaceReader(readers); - this.readers = readers; + public MavenChainedWorkspaceReader(WorkspaceReader... readers) { + setReaders(Arrays.asList(readers)); + } + + @Override + public WorkspaceRepository getRepository() { + return this.repository; } @Override public Model findModel(Artifact artifact) { + requireNonNull(artifact, "artifact cannot be null"); + Model model = null; + for (WorkspaceReader workspaceReader : readers) { if (workspaceReader instanceof MavenWorkspaceReader) { - Model model = ((MavenWorkspaceReader) workspaceReader).findModel(artifact); + model = ((MavenWorkspaceReader) workspaceReader).findModel(artifact); if (model != null) { - return model; + break; } } } - return null; - } - @Override - public WorkspaceRepository getRepository() { - return delegate.getRepository(); + return model; } @Override public File findArtifact(Artifact artifact) { - return delegate.findArtifact(artifact); + requireNonNull(artifact, "artifact cannot be null"); + File file = null; + + for (WorkspaceReader reader : readers) { + file = reader.findArtifact(artifact); + if (file != null) { + break; + } + } + + return file; } @Override public List findVersions(Artifact artifact) { - return delegate.findVersions(artifact); + requireNonNull(artifact, "artifact cannot be null"); + Collection versions = new LinkedHashSet<>(); + + for (WorkspaceReader reader : readers) { + versions.addAll(reader.findVersions(artifact)); + } + + return Collections.unmodifiableList(new ArrayList<>(versions)); + } + + public void setReaders(Collection readers) { + this.readers = Collections.unmodifiableList(new ArrayList<>(readers)); + Key key = new Key(this.readers); + this.repository = new WorkspaceRepository(key.getContentType(), key); + } + + public List getReaders() { + return readers; + } + + private static class Key { + private final List keys; + private final String type; + + Key(Collection readers) { + keys = readers.stream().map(r -> r.getRepository().getKey()).collect(Collectors.toList()); + type = readers.stream().map(r -> r.getRepository().getContentType()).collect(Collectors.joining("+")); + } + + public String getContentType() { + return type; + } + + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else { + return obj != null && this.getClass().equals(obj.getClass()) && this.keys.equals(((Key) obj).keys); + } + } + + public int hashCode() { + return this.keys.hashCode(); + } } /** diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactResolver.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactResolver.java index cc1f93d5d244..6d0299110d51 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactResolver.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactResolver.java @@ -23,12 +23,13 @@ import javax.inject.Singleton; import java.nio.file.Path; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import org.apache.maven.api.Artifact; +import org.apache.maven.api.ArtifactCoordinate; import org.apache.maven.api.annotations.Nonnull; import org.apache.maven.api.services.ArtifactManager; import org.apache.maven.api.services.ArtifactResolver; @@ -59,24 +60,30 @@ public ArtifactResolverResult resolve(ArtifactResolverRequest request) nonNull(request, "request can not be null"); InternalSession session = InternalSession.from(request.getSession()); try { - List repositories = session.toRepositories(session.getRemoteRepositories()); - List requests = request.getCoordinates().stream() - .map(coord -> new ArtifactRequest(session.toArtifact(coord), repositories, null)) - .collect(Collectors.toList()); - List results = repositorySystem.resolveArtifacts(session.getSession(), requests); Map paths = new HashMap<>(); - for (ArtifactResult result : results) { - Artifact artifact = session.getArtifact(result.getArtifact()); - Path path = result.getArtifact().getFile().toPath(); - session.getService(ArtifactManager.class).setPath(artifact, path); - paths.put(artifact, path); + ArtifactManager artifactManager = session.getService(ArtifactManager.class); + List repositories = session.toRepositories(session.getRemoteRepositories()); + List requests = new ArrayList<>(); + for (ArtifactCoordinate coord : request.getCoordinates()) { + org.eclipse.aether.artifact.Artifact aetherArtifact = session.toArtifact(coord); + Artifact artifact = session.getArtifact(aetherArtifact); + Path path = artifactManager.getPath(artifact).orElse(null); + if (path != null) { + paths.put(artifact, path); + } else { + requests.add(new ArtifactRequest(aetherArtifact, repositories, null)); + } } - return new ArtifactResolverResult() { - @Override - public Map getArtifacts() { - return paths; + if (!requests.isEmpty()) { + List results = repositorySystem.resolveArtifacts(session.getSession(), requests); + for (ArtifactResult result : results) { + Artifact artifact = session.getArtifact(result.getArtifact()); + Path path = result.getArtifact().getFile().toPath(); + artifactManager.setPath(artifact, path); + paths.put(artifact, path); } - }; + } + return () -> paths; } catch (ArtifactResolutionException e) { throw new ArtifactResolverException("Unable to resolve artifact", e); } diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java index 942565c9e07c..4b381769778e 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java @@ -21,11 +21,11 @@ import java.nio.file.Path; import java.time.Instant; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -65,7 +65,7 @@ public class DefaultSession extends AbstractSession { private final MavenRepositorySystem mavenRepositorySystem; private final PlexusContainer container; private final RuntimeInformation runtimeInformation; - private final Map, Service> services = new HashMap<>(); + private final Map, Service> services = new ConcurrentHashMap<>(); @SuppressWarnings("checkstyle:ParameterNumber") public DefaultSession( @@ -213,8 +213,7 @@ public Session withLocalRepository(@Nonnull LocalRepository localRepository) { RepositorySystemSession repoSession = new DefaultRepositorySystemSession(session).setLocalRepositoryManager(localRepositoryManager); - MavenSession newSession = - new MavenSession(() -> repoSession, mavenSession.getRequest(), mavenSession.getResult()); + MavenSession newSession = new MavenSession(repoSession, mavenSession.getRequest(), mavenSession.getResult()); return new DefaultSession( newSession, repositorySystem, repositories, mavenRepositorySystem, container, runtimeInformation); } diff --git a/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java b/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java index c09bba12af52..bac881ac0889 100644 --- a/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java +++ b/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java @@ -98,7 +98,7 @@ void setup() { RepositorySystemSession rss = MavenRepositorySystemUtils.newSession(); DefaultMavenExecutionRequest mer = new DefaultMavenExecutionRequest(); DefaultMavenExecutionResult meres = new DefaultMavenExecutionResult(); - MavenSession ms = new MavenSession(() -> rss, mer, meres); + MavenSession ms = new MavenSession(rss, mer, meres); DefaultSession session = new DefaultSession( ms, repositorySystem, From af84ca98460250f077af6da8e94d623446c1e1cd Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Fri, 1 Dec 2023 17:58:28 +0100 Subject: [PATCH 11/11] Fix artifacts path not being correctly set --- .../internal/impl/DefaultArtifactManager.java | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactManager.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactManager.java index 2895efd831fb..f0d521bb08a3 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactManager.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultArtifactManager.java @@ -24,8 +24,10 @@ import java.io.File; import java.nio.file.Path; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Stream; import org.apache.maven.api.Artifact; import org.apache.maven.api.annotations.Nonnull; @@ -75,12 +77,10 @@ public Optional getPath(@Nonnull Artifact artifact) { public void setPath(@Nonnull Artifact artifact, Path path) { String id = id(artifact); if (session.getMavenSession().getAllProjects() != null) { - for (MavenProject project : session.getMavenSession().getAllProjects()) { - if (id.equals(id(project.getArtifact()))) { - project.getArtifact().setFile(path != null ? path.toFile() : null); - break; - } - } + session.getMavenSession().getAllProjects().stream() + .flatMap(this::getProjectArtifacts) + .filter(a -> Objects.equals(id, id(a))) + .forEach(a -> a.setFile(path != null ? path.toFile() : null)); } if (path == null) { paths.remove(id); @@ -89,10 +89,18 @@ public void setPath(@Nonnull Artifact artifact, Path path) { } } + /** + * Retrieve a stream of the project's artifacts. + * Do not include the POM artifact as the file can't be set anyway. + */ + private Stream getProjectArtifacts(MavenProject project) { + return Stream.concat(Stream.of(project.getArtifact()), project.getAttachedArtifacts().stream()); + } + private String id(org.apache.maven.artifact.Artifact artifact) { return artifact.getGroupId() + ":" + artifact.getArtifactId() - + ":" + artifact.getType() + + ":" + artifact.getArtifactHandler().getExtension() + (artifact.getClassifier() == null || artifact.getClassifier().isEmpty() ? "" : ":" + artifact.getClassifier())