This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven.git

commit 8d483f922bacab8b6b774812c570c973d8a53eca
Author: Guillaume Nodet <[email protected]>
AuthorDate: Mon Jun 10 08:58:25 2024 +0200

    [MNG-8152] Implement @SessionScoped and @MojoExecutionScoped from the DI API
---
 .../org/apache/maven/api/di/MojoExecutionScoped.java  |  2 --
 .../java/org/apache/maven/api/di/SessionScoped.java   |  2 --
 .../execution/scope/internal/MojoExecutionScope.java  | 16 +++++++++++++++-
 .../maven/internal/impl/SisuDiBridgeModule.java       | 19 +++++++++++++++++++
 .../maven/session/scope/internal/SessionScope.java    | 16 +++++++++++++++-
 .../src/main/java/org/apache/maven/di/Injector.java   |  3 +++
 .../java/org/apache/maven/di/impl/InjectorImpl.java   |  9 +++++++--
 7 files changed, 59 insertions(+), 8 deletions(-)

diff --git 
a/api/maven-api-di/src/main/java/org/apache/maven/api/di/MojoExecutionScoped.java
 
b/api/maven-api-di/src/main/java/org/apache/maven/api/di/MojoExecutionScoped.java
index b12f9a4159..a3fec5ca81 100644
--- 
a/api/maven-api-di/src/main/java/org/apache/maven/api/di/MojoExecutionScoped.java
+++ 
b/api/maven-api-di/src/main/java/org/apache/maven/api/di/MojoExecutionScoped.java
@@ -30,8 +30,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
  * Indicates that the annotated bean has a lifespan limited to a given mojo 
execution,
  * which means each mojo execution will result in a different instance being 
injected.
  *
- * TODO: this is currently not implemented
- *
  * @since 4.0.0
  */
 @Scope
diff --git 
a/api/maven-api-di/src/main/java/org/apache/maven/api/di/SessionScoped.java 
b/api/maven-api-di/src/main/java/org/apache/maven/api/di/SessionScoped.java
index ec4d5a8ea7..eae72f8e2b 100644
--- a/api/maven-api-di/src/main/java/org/apache/maven/api/di/SessionScoped.java
+++ b/api/maven-api-di/src/main/java/org/apache/maven/api/di/SessionScoped.java
@@ -30,8 +30,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
  * Indicates that annotated component should be instantiated before session 
execution starts
  * and discarded after session execution completes.
  *
- * TODO: this is currently not implemented
- *
  * @since 4.0.0
  */
 @Scope
diff --git 
a/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScope.java
 
b/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScope.java
index b650912f25..a9d9feb65f 100644
--- 
a/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScope.java
+++ 
b/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScope.java
@@ -18,16 +18,19 @@
  */
 package org.apache.maven.execution.scope.internal;
 
+import java.lang.annotation.Annotation;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.IdentityHashMap;
 import java.util.LinkedList;
 import java.util.Map;
+import java.util.function.Supplier;
 
 import com.google.inject.Key;
 import com.google.inject.OutOfScopeException;
 import com.google.inject.Provider;
 import com.google.inject.Scope;
+import com.google.inject.name.Names;
 import com.google.inject.util.Providers;
 import org.apache.maven.execution.MojoExecutionEvent;
 import org.apache.maven.execution.MojoExecutionListener;
@@ -37,7 +40,7 @@ import org.apache.maven.plugin.MojoExecutionException;
 /**
  * MojoExecutionScope
  */
-public class MojoExecutionScope implements Scope, MojoExecutionListener {
+public class MojoExecutionScope implements Scope, org.apache.maven.di.Scope, 
MojoExecutionListener {
     private static final Provider<Object> SEEDED_KEY_PROVIDER = () -> {
         throw new IllegalStateException();
     };
@@ -113,6 +116,17 @@ public class MojoExecutionScope implements Scope, 
MojoExecutionListener {
         };
     }
 
+    @Override
+    public <T> Supplier<T> scope(org.apache.maven.di.Key<T> key, Annotation 
scope, Supplier<T> unscoped) {
+        Object qualifier = key.getQualifier();
+        Key k = qualifier != null
+                ? Key.get(key.getType(), qualifier instanceof String s ? 
Names.named(s) : (Annotation) qualifier)
+                : Key.get(key.getType());
+        Provider<T> up = unscoped::get;
+        Provider<T> p = scope(k, up);
+        return p::get;
+    }
+
     @SuppressWarnings({"unchecked"})
     public static <T> Provider<T> seededKeyProvider() {
         return (Provider<T>) SEEDED_KEY_PROVIDER;
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/SisuDiBridgeModule.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/SisuDiBridgeModule.java
index ed569ba420..30423b2c10 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/SisuDiBridgeModule.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/SisuDiBridgeModule.java
@@ -41,13 +41,18 @@ import java.util.stream.Collectors;
 import com.google.inject.AbstractModule;
 import com.google.inject.binder.AnnotatedBindingBuilder;
 import com.google.inject.name.Names;
+import org.apache.maven.api.di.MojoExecutionScoped;
+import org.apache.maven.api.di.SessionScoped;
 import org.apache.maven.api.services.MavenException;
 import org.apache.maven.di.Injector;
 import org.apache.maven.di.Key;
 import org.apache.maven.di.impl.Binding;
 import org.apache.maven.di.impl.DIException;
 import org.apache.maven.di.impl.InjectorImpl;
+import org.apache.maven.execution.scope.internal.MojoExecutionScope;
+import org.apache.maven.session.scope.internal.SessionScope;
 import org.codehaus.plexus.PlexusContainer;
+import 
org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 
 @Named
 class SisuDiBridgeModule extends AbstractModule {
@@ -121,6 +126,20 @@ class SisuDiBridgeModule extends AbstractModule {
                                 .collect(Collectors.joining("\n - ", " - ", 
"")));
             }
         };
+        injector.bindScope(SessionScoped.class, () -> {
+            try {
+                return containerProvider.get().lookup(SessionScope.class);
+            } catch (ComponentLookupException e) {
+                throw new RuntimeException(e);
+            }
+        });
+        injector.bindScope(MojoExecutionScoped.class, () -> {
+            try {
+                return 
containerProvider.get().lookup(MojoExecutionScope.class);
+            } catch (ComponentLookupException e) {
+                throw new RuntimeException(e);
+            }
+        });
         injector.bindInstance(Injector.class, injector);
         bind(Injector.class).toInstance(injector);
         ClassLoader classLoader = 
Thread.currentThread().getContextClassLoader();
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 ef60843d9d..71c2add405 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
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -33,11 +34,12 @@ import com.google.inject.Key;
 import com.google.inject.OutOfScopeException;
 import com.google.inject.Provider;
 import com.google.inject.Scope;
+import com.google.inject.name.Names;
 
 /**
  * SessionScope
  */
-public class SessionScope implements Scope {
+public class SessionScope implements Scope, org.apache.maven.di.Scope {
 
     private static final Provider<Object> SEEDED_KEY_PROVIDER = () -> {
         throw new IllegalStateException();
@@ -103,6 +105,18 @@ public class SessionScope implements Scope {
         };
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> Supplier<T> scope(org.apache.maven.di.Key<T> key, Annotation 
scope, Supplier<T> unscoped) {
+        Object qualifier = key.getQualifier();
+        Key<?> k = qualifier != null
+                ? Key.get(key.getType(), qualifier instanceof String s ? 
Names.named(s) : (Annotation) qualifier)
+                : Key.get(key.getType());
+        Provider<T> up = unscoped::get;
+        Provider<T> p = scope((Key<T>) k, up);
+        return p::get;
+    }
+
     @SuppressWarnings("unchecked")
     private <T> T createProxy(Key<T> key, Provider<T> unscoped) {
         InvocationHandler dispatcher = (proxy, method, args) -> {
diff --git a/maven-di/src/main/java/org/apache/maven/di/Injector.java 
b/maven-di/src/main/java/org/apache/maven/di/Injector.java
index 3b2d56d204..9ccc1b698c 100644
--- a/maven-di/src/main/java/org/apache/maven/di/Injector.java
+++ b/maven-di/src/main/java/org/apache/maven/di/Injector.java
@@ -19,6 +19,7 @@
 package org.apache.maven.di;
 
 import java.lang.annotation.Annotation;
+import java.util.function.Supplier;
 
 import org.apache.maven.di.impl.InjectorImpl;
 
@@ -36,6 +37,8 @@ public interface Injector {
 
     Injector bindScope(Class<? extends Annotation> scopeAnnotation, Scope 
scope);
 
+    Injector bindScope(Class<? extends Annotation> scopeAnnotation, 
Supplier<Scope> scope);
+
     Injector bindImplicit(Class<?> cls);
 
     <T> Injector bindInstance(Class<T> cls, T instance);
diff --git a/maven-di/src/main/java/org/apache/maven/di/impl/InjectorImpl.java 
b/maven-di/src/main/java/org/apache/maven/di/impl/InjectorImpl.java
index 142d2bae96..a92a5765d3 100644
--- a/maven-di/src/main/java/org/apache/maven/di/impl/InjectorImpl.java
+++ b/maven-di/src/main/java/org/apache/maven/di/impl/InjectorImpl.java
@@ -44,7 +44,7 @@ import org.apache.maven.di.Scope;
 public class InjectorImpl implements Injector {
 
     private final Map<Key<?>, Set<Binding<?>>> bindings = new HashMap<>();
-    private final Map<Class<? extends Annotation>, Scope> scopes = new 
HashMap<>();
+    private final Map<Class<? extends Annotation>, Supplier<Scope>> scopes = 
new HashMap<>();
 
     public InjectorImpl() {
         bindScope(Singleton.class, new SingletonScope());
@@ -87,6 +87,10 @@ public class InjectorImpl implements Injector {
     }
 
     public Injector bindScope(Class<? extends Annotation> scopeAnnotation, 
Scope scope) {
+        return bindScope(scopeAnnotation, () -> scope);
+    }
+
+    public Injector bindScope(Class<? extends Annotation> scopeAnnotation, 
Supplier<Scope> scope) {
         if (scopes.put(scopeAnnotation, scope) != null) {
             throw new DIException(
                     "Cannot rebind scope annotation class to a different 
implementation: " + scopeAnnotation);
@@ -204,7 +208,8 @@ public class InjectorImpl implements Injector {
                     .map(Map.Entry::getValue)
                     .findFirst()
                     .orElseThrow(() -> new DIException("Scope not bound for 
annotation "
-                            + binding.getScope().getClass()));
+                            + binding.getScope().annotationType()))
+                    .get();
             compiled = scope.scope((Key<Q>) binding.getOriginalKey(), 
binding.getScope(), compiled);
         }
         return compiled;

Reply via email to