diff --git a/api/maven-api-core/pom.xml b/api/maven-api-core/pom.xml index ac94ace4ac84..31002afab608 100644 --- a/api/maven-api-core/pom.xml +++ b/api/maven-api-core/pom.xml @@ -51,6 +51,15 @@ maven-api-toolchain 4.0.0-alpha-9-SNAPSHOT + + org.apache.maven + maven-api-plugin + 4.0.0-alpha-9-SNAPSHOT + + + jakarta.inject + jakarta.inject-api + 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 d5d1fa4e3d9c..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 @@ -22,23 +22,37 @@ import org.apache.maven.api.annotations.Experimental; import org.apache.maven.api.annotations.Nonnull; -import org.apache.maven.api.model.Plugin; +import org.apache.maven.api.model.PluginExecution; +import org.apache.maven.api.plugin.descriptor.MojoDescriptor; import org.apache.maven.api.xml.XmlNode; /** - * A {@code MojoExecution} + * A {@code MojoExecution} represents a single execution of a Maven Plugin during a given build. + * An instance of this object is bound to the {@link org.apache.maven.api.di.MojoExecutionScoped} + * and available as {@code mojoExecution} within {@link org.apache.maven.api.plugin.annotations.Parameter} + * expressions. */ @Experimental public interface MojoExecution { + @Nonnull Plugin getPlugin(); + @Nonnull + PluginExecution getModel(); + + @Nonnull + MojoDescriptor getDescriptor(); + @Nonnull String getExecutionId(); @Nonnull String getGoal(); + @Nonnull + String getLifecyclePhase(); + @Nonnull Optional getConfiguration(); } 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 new file mode 100644 index 000000000000..66f93d204a9f --- /dev/null +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Plugin.java @@ -0,0 +1,58 @@ +/* + * 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.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; +import org.apache.maven.api.plugin.descriptor.PluginDescriptor; +import org.apache.maven.api.plugin.descriptor.lifecycle.Lifecycle; + +/** + * Represents a maven plugin runtime + */ +@Experimental +public interface Plugin { + + @Nonnull + org.apache.maven.api.model.Plugin getModel(); + + @Nonnull + PluginDescriptor getDescriptor(); + + @Nonnull + List getLifecycles(); + + @Nonnull + ClassLoader getClassLoader(); + + @Nonnull + Artifact getArtifact(); + + @Nonnull + default Collection getDependencies() { + return getDependenciesMap().values(); + } + + @Nonnull + Map getDependenciesMap(); +} 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/api/maven-api-core/src/main/java/org/apache/maven/api/VersionRange.java b/api/maven-api-core/src/main/java/org/apache/maven/api/VersionRange.java index 2dc3e224a5d9..375ac5f9f9ae 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/VersionRange.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/VersionRange.java @@ -29,7 +29,7 @@ @Experimental public interface VersionRange { - // TODO: add access to the version information + // TODO: v4: add access to the version information /** * Determines whether the specified version is contained within this range. diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/plugin/annotations/Component.java b/api/maven-api-core/src/main/java/org/apache/maven/api/di/MojoExecutionScoped.java similarity index 51% rename from api/maven-api-core/src/main/java/org/apache/maven/api/plugin/annotations/Component.java rename to api/maven-api-core/src/main/java/org/apache/maven/api/di/MojoExecutionScoped.java index 305d3cc3929d..2fcbe07991ce 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/plugin/annotations/Component.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/di/MojoExecutionScoped.java @@ -16,42 +16,26 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.maven.api.plugin.annotations; +package org.apache.maven.api.di; import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import org.apache.maven.api.annotations.Experimental; -import org.apache.maven.api.annotations.Nonnull; +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; /** - * Used to configure injection of Plexus components by - * - * MavenPluginManager.getConfiguredMojo(...). + * 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 */ -@Experimental +@Scope @Documented -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Inherited -public @interface Component { - /** - * role of the component to inject. - * @return the role - */ - @Nonnull - Class role() default Object.class; - - /** - * hint of the component to inject. - * @return the hint - */ - @Nonnull - String hint() default ""; -} +@Retention(RUNTIME) +@Target({TYPE, METHOD}) +public @interface MojoExecutionScoped {} diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/plugin/annotations/InstantiationStrategy.java b/api/maven-api-core/src/main/java/org/apache/maven/api/di/SessionScoped.java similarity index 58% rename from api/maven-api-core/src/main/java/org/apache/maven/api/plugin/annotations/InstantiationStrategy.java rename to api/maven-api-core/src/main/java/org/apache/maven/api/di/SessionScoped.java index 29cec2649a3d..d5e9a0ddbe53 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/plugin/annotations/InstantiationStrategy.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/di/SessionScoped.java @@ -16,29 +16,26 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.maven.api.plugin.annotations; +package org.apache.maven.api.di; -import org.apache.maven.api.annotations.Experimental; +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; /** - * Component instantiation strategy. + * Indicates that annotated component should be instantiated before session execution starts + * and discarded after session execution completes. * * @since 4.0.0 */ -@Experimental -public enum InstantiationStrategy { - PER_LOOKUP("per-lookup"), - SINGLETON("singleton"), - KEEP_ALIVE("keep-alive"), - POOLABLE("poolable"); - - private final String id; - - InstantiationStrategy(String id) { - this.id = id; - } - - public String id() { - return this.id; - } -} +@Scope +@Documented +@Retention(RUNTIME) +@Target({TYPE, METHOD}) +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/api/maven-api-core/src/main/java/org/apache/maven/api/plugin/LifecycleProvider.java b/api/maven-api-core/src/main/java/org/apache/maven/api/plugin/LifecycleProvider.java new file mode 100644 index 000000000000..05046da6a223 --- /dev/null +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/plugin/LifecycleProvider.java @@ -0,0 +1,39 @@ +/* + * 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.api.plugin; + +import java.util.List; + +import org.apache.maven.api.annotations.Consumer; +import org.apache.maven.api.annotations.Experimental; +import org.apache.maven.api.plugin.descriptor.lifecycle.Lifecycle; + +/** + * Interface that can be provided by the plugin to wire in custom lifecycles + * leveraged using the {@link org.apache.maven.api.plugin.annotations.Execute} + * annotation. If a {@code META-INF/maven/lifecycle.xml} file is packaged + * in the plugin, Maven will provide a default implementation that will parse + * the file and return the contained lifecycle definitions. + */ +@Experimental +@Consumer +public interface LifecycleProvider { + + List getLifecycles(); +} diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/plugin/annotations/Mojo.java b/api/maven-api-core/src/main/java/org/apache/maven/api/plugin/annotations/Mojo.java index de5f7b016af3..11245b5adad5 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/plugin/annotations/Mojo.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/plugin/annotations/Mojo.java @@ -31,6 +31,9 @@ /** * This annotation will mark your class as a Mojo (ie. goal in a Maven plugin). + * The mojo can be annotated with {@code jakarta.inject.*} annotations. + * The {@link Parameter} annotation can be added on fields to inject data + * from the plugin configuration or from other components. * * @since 4.0.0 */ @@ -59,27 +62,20 @@ * @return the required dependency resolution scope */ @Nonnull - ResolutionScope requiresDependencyResolution() default ResolutionScope.NONE; + ResolutionScope dependencyResolutionRequired() default ResolutionScope.NONE; /** * the required dependency collection scope. * @return the required dependency collection scope */ @Nonnull - ResolutionScope requiresDependencyCollection() default ResolutionScope.NONE; - - /** - * your Mojo instantiation strategy. (Only per-lookup and singleton are supported) - * @return the instantiation strategy - */ - @Nonnull - InstantiationStrategy instantiationStrategy() default InstantiationStrategy.PER_LOOKUP; + ResolutionScope dependencyCollectionRequired() default ResolutionScope.NONE; /** * does your mojo requires a project to be executed? * @return requires a project */ - boolean requiresProject() default true; + boolean projectRequired() default true; /** * if the Mojo uses the Maven project and its child modules. @@ -91,9 +87,10 @@ * does this Mojo need to be online to be executed? * @return need to be online */ - boolean requiresOnline() default false; + boolean onlineRequired() default false; /** + * TODO: v4: add a SPI for the configurator * configurator bean name. * @return the configurator bean name */ diff --git a/api/maven-api-plugin/pom.xml b/api/maven-api-plugin/pom.xml new file mode 100644 index 000000000000..b5b4713ea510 --- /dev/null +++ b/api/maven-api-plugin/pom.xml @@ -0,0 +1,105 @@ + + + + 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..019236dec8cb 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 + @@ -428,12 +476,6 @@ under the License. full of Strings. ]]> - - implementation - 1.0.0+ - String - - description 1.0.0+ @@ -455,31 +497,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 +514,7 @@ under the License. Requirement - 1.0.0+ + 1.0.0/1.1.0 Describes a component requirement. @@ -517,7 +543,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/DefaultMaven.java b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java index 19475a8af85f..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; @@ -60,8 +59,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; @@ -215,18 +214,18 @@ 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); sessionScope.seed(Session.class, session.getSession()); - sessionScope.seed(DefaultSession.class, (DefaultSession) session.getSession()); + sessionScope.seed(InternalSession.class, InternalSession.from(session.getSession())); 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/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/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/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..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,26 +24,30 @@ 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.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 { @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; } @@ -73,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); @@ -87,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()) 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..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; @@ -41,7 +42,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,27 +58,32 @@ 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() - .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/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..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 @@ -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; } @@ -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/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/DefaultMojoExecution.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultMojoExecution.java index 84e1cd8d8e47..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,17 +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.model.Plugin; +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; } @@ -38,7 +55,71 @@ public org.apache.maven.plugin.MojoExecution getDelegate() { @Override public Plugin getPlugin() { - return delegate.getPlugin().getDelegate(); + 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 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 getDescriptor() { + return delegate.getMojoDescriptor().getMojoDescriptorV4(); + } + + @Override + public String getLifecyclePhase() { + return delegate.getLifecyclePhase(); } @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 7cd27ae9052b..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 @@ -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; @@ -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/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..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 { @@ -73,7 +75,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 +131,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/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/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/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java index 1fb3c176ef13..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 @@ -24,16 +24,10 @@ 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 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 +49,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; @@ -340,7 +332,11 @@ private void finalizeMojoConfiguration(MojoExecution mojoExecution) { } private XmlNode getMojoConfiguration(MojoDescriptor mojoDescriptor) { - return MojoDescriptorCreator.convert(mojoDescriptor).getDom(); + if (mojoDescriptor.isV4Api()) { + return MojoDescriptorCreator.convert(mojoDescriptor.getMojoDescriptorV4()); + } else { + return MojoDescriptorCreator.convert(mojoDescriptor).getDom(); + } } @Override @@ -459,7 +455,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 +487,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 +497,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/lifecycle/internal/MojoDescriptorCreator.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java index ec0baabf2c50..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,6 +26,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import org.apache.maven.api.xml.XmlNode; import org.apache.maven.execution.MavenSession; @@ -91,6 +92,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() + .filter(p -> p.getDefaultValue() != null || p.getExpression() != null) + .map(p -> new XmlNodeImpl( + p.getName(), + p.getExpression(), + p.getDefaultValue() != null + ? Collections.singletonMap("default-value", p.getDefaultValue()) + : null, + null, + null)) + .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(); 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..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 @@ -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,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, ((DefaultSession) 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 0eaa801c204b..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.DefaultSession; 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 = ((DefaultSession) session) - .getProject(((DefaultSession) 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 ef1322d2fac6..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; @@ -39,13 +38,16 @@ 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; 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.DefaultMojoExecution; +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; @@ -220,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()); } } @@ -259,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); @@ -410,6 +413,7 @@ private void createPluginRealm( discoverPluginComponents(pluginRealm, plugin, pluginDescriptor); + pluginDescriptor.setDependencyNode(root); pluginDescriptor.setClassRealm(pluginRealm); pluginDescriptor.setArtifacts(pluginArtifacts); } @@ -419,15 +423,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())); @@ -584,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(), - ((DefaultSession) 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/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/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 a677f09d287b..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 @@ -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; @@ -52,10 +52,17 @@ 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); - bind(Session.class).toProvider(SessionScope.seededKeyProvider()).in(scope); - bind(DefaultSession.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); } } 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.* +