[ 
https://issues.apache.org/jira/browse/MNG-7954?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17810949#comment-17810949
 ] 

ASF GitHub Bot commented on MNG-7954:
-------------------------------------

rmannibucau commented on code in PR #1393:
URL: https://github.com/apache/maven/pull/1393#discussion_r1466553837


##########
api/maven-api-di/src/main/java/org/apache/maven/api/di/Transient.java:
##########
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api.di;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface Transient {}

Review Comment:
   Needed? why not use a scope (prototype, default, whatever name)



##########
maven-di/src/main/java/org/apache/maven/api/di/ProvidesIntoSet.java:
##########
@@ -0,0 +1,38 @@
+/*
+ * 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.di;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import org.apache.maven.di.binding.Multibinders;
+import org.apache.maven.di.module.AbstractModule;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * This is a built-in shortcut for {@link Provides provider method} that 
provides its result as a singleton set
+ * and adds a {@link Multibinders#toSet() set multibinder} for the provided 
set key to the module.
+ *
+ * @see AbstractModule
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+public @interface ProvidesIntoSet {}

Review Comment:
   guice leak? not sure we need this one



##########
maven-di/src/main/java/org/apache/maven/di/module/UniqueQualifierImpl.java:
##########
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.di.module;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.maven.api.annotations.Nullable;
+
+@SuppressWarnings("ClassExplicitlyAnnotation")
+public final class UniqueQualifierImpl implements UniqueQualifier {

Review Comment:
   cant we reuse it as binding too? (a bit like cdi does with annotation 
literals)



##########
api/maven-api-di/src/main/java/org/apache/maven/api/di/Scope.java:
##########
@@ -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.
+ */
+package org.apache.maven.api.di;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Target(ANNOTATION_TYPE)
+@Retention(RUNTIME)
+@Documented
+public @interface Scope {
+    boolean threadsafe() default true;

Review Comment:
   Needed?



##########
maven-di/src/main/java/org/apache/maven/di/ResourceLocator.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.di;
+
+import java.util.function.Supplier;
+
+import org.apache.maven.api.annotations.Nullable;
+
+public interface ResourceLocator {
+    <T> T getInstance(Key<T> key);
+
+    default <T> T getInstance(Class<T> type) {
+        return getInstance(Key.of(type));
+    }
+
+    <T> @Nullable T getInstanceOrNull(Key<T> key);

Review Comment:
   guess all the next getInstances can be replaced by getOptionalInstance and 
the cases be managed by `Optional` directly instead of duplicating API?



##########
maven-di/src/main/java/org/apache/maven/di/Injector.java:
##########
@@ -0,0 +1,613 @@
+/*
+ * 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.di;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+
+import org.apache.maven.api.annotations.Nullable;
+import org.apache.maven.di.binding.*;
+import org.apache.maven.di.impl.CompiledBinding;
+import org.apache.maven.di.impl.CompiledBindingLocator;
+import org.apache.maven.di.impl.Preprocessor;
+import org.apache.maven.di.module.Module;
+import org.apache.maven.di.module.Modules;
+import org.apache.maven.di.util.Trie;
+import org.apache.maven.di.util.Utils;
+
+import static java.util.stream.Collectors.toMap;
+import static org.apache.maven.di.Scope.UNSCOPED;
+import static org.apache.maven.di.util.Types.parameterizedType;
+
+/**
+ * Injector is the main working component of the ActiveJ Inject.
+ * <p>
+ * It stores a trie of binding graphs and a cache of already made singletons.
+ * <p>
+ * Each injector is associated with exactly zero or one instance per {@link 
Key}.
+ * <p>
+ * Injector uses binding graph at the root of the trie to recursively create 
and then store instances of objects
+ * associated with some {@link Key keys}.
+ * Branches of the trie are used to {@link #enterScope enter scopes}.
+ */
+@SuppressWarnings({"unused", "WeakerAccess", "rawtypes"})
+public final class Injector implements ResourceLocator {
+    static class ScopeLocalData {
+        final Scope[] scope;
+        final Map<Key<?>, Binding<?>> bindings;
+        final Map<Key<?>, CompiledBinding<?>> compiledBindings;
+        final Map<Key<?>, Integer> slotMapping;
+        final int slots;
+        final CompiledBinding<?>[] eagerSingletons;
+
+        ScopeLocalData(
+                Scope[] scope,
+                Map<Key<?>, Binding<?>> bindings,
+                Map<Key<?>, CompiledBinding<?>> compiledBindings,
+                Map<Key<?>, Integer> slotMapping,
+                int slots,
+                CompiledBinding<?>[] eagerSingletons) {
+            this.scope = scope;
+            this.bindings = bindings;
+            this.compiledBindings = compiledBindings;
+            this.slotMapping = slotMapping;
+            this.slots = slots;
+            this.eagerSingletons = eagerSingletons;
+        }
+    }
+
+    final @Nullable Injector parent;
+    final Trie<Scope, ScopeLocalData> scopeDataTree;
+
+    final Map<Key<?>, Integer> localSlotMapping;
+    final Map<Key<?>, CompiledBinding<?>> localCompiledBindings;
+
+    final AtomicReferenceArray[] scopeCaches;
+
+    private static Supplier<UnaryOperator<CompiledBinding<?>>> 
bytecodePostprocessorFactory = UnaryOperator::identity;
+
+    /**
+     * Enables specialization of compiled bindings. <b>Depends on {@code 
ActiveJ-Specializer} module</b>
+     */
+    @SuppressWarnings("unchecked")
+    public static void useSpecializer() {

Review Comment:
   do we use it? if so we should either require it (no reflection) or drop it 
no?



##########
maven-di/src/main/java/org/apache/maven/api/di/Scopes.java:
##########
@@ -0,0 +1,38 @@
+/*
+ * 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.di;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * This is a special annotation that allows you to declare bindings in nested 
scopes
+ * using {@link Provides provider methods}.
+ * <p>
+ * Note that it does not allow you to use stateful scope annotations.
+ */
+@Retention(RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Scopes {

Review Comment:
   needed?



##########
maven-di/src/main/java/org/apache/maven/di/impl/AbstractCompiledBinding.java:
##########
@@ -0,0 +1,60 @@
+/*
+ * 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.di.impl;
+
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+@SuppressWarnings("rawtypes")
+public abstract class AbstractCompiledBinding<R> implements CompiledBinding<R> 
{
+    protected final int scope;
+
+    protected final int index;
+
+    protected AbstractCompiledBinding(int scope, int index) {
+        this.scope = scope;
+        this.index = index;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public final R getInstance(AtomicReferenceArray[] scopedInstances, int 
synchronizedScope) {
+        AtomicReferenceArray array = scopedInstances[scope];
+        R instance = (R) array.get(index);
+        if (instance != null) {
+            return instance;
+        }
+        if (synchronizedScope == scope) {

Review Comment:
   im tempted to drop this notion and just always lock, wdyt?



##########
maven-di/src/main/java/org/apache/maven/di/binding/Bindings.java:
##########
@@ -0,0 +1,609 @@
+/*
+ * 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.di.binding;
+
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+import org.apache.maven.api.annotations.Nullable;
+import org.apache.maven.di.Key;
+import org.apache.maven.di.impl.*;
+import org.apache.maven.di.module.Tuples.*;
+
+@SuppressWarnings({"unchecked", "rawtypes", "Convert2Lambda"})
+public class Bindings {
+
+    public static class BindingToInstance<T> extends Binding<T> {
+        final T instance;
+
+        BindingToInstance(T instance) {
+            super(Collections.emptySet());
+            this.instance = instance;
+        }
+
+        @Override
+        public CompiledBinding<T> compile(
+                CompiledBindingLocator compiledBindings, boolean threadsafe, 
int scope, @Nullable Integer slot) {
+            final T instance = this.instance;
+            return slot != null
+                    ? new CompiledBinding<T>() {
+                        @Override
+                        public T getInstance(AtomicReferenceArray[] 
scopedInstances, int synchronizedScope) {
+                            scopedInstances[scope].lazySet(slot, instance);
+                            return instance;
+                        }
+                    }
+                    : new CompiledBinding<T>() {
+                        @Override
+                        public T getInstance(AtomicReferenceArray[] 
scopedInstances, int synchronizedScope) {
+                            return instance;
+                        }
+                    };
+        }
+    }
+
+    public static class BindingToConstructorN<R> extends Binding<R> {
+        final TupleConstructorN<R> constructor;
+        final Key<?>[] dependencies;
+
+        BindingToConstructorN(TupleConstructorN<R> constructor, Key<?>[] 
dependencies) {
+            super(new HashSet<>(Arrays.asList(dependencies)));
+            this.constructor = constructor;
+            this.dependencies = dependencies;
+        }
+
+        @Override
+        public CompiledBinding<R> compile(
+                CompiledBindingLocator compiledBindings, boolean threadsafe, 
int scope, @Nullable Integer slot) {
+            final TupleConstructorN<R> constructor = this.constructor;
+            final CompiledBinding<?>[] bindings =
+                    
Arrays.stream(dependencies).map(compiledBindings::get).toArray(CompiledBinding[]::new);
+            return slot != null
+                    ? threadsafe
+                            ? scope == 0
+                                    ? new AbstractRootCompiledBinding<R>(slot) 
{
+                                        @Override
+                                        protected R doCreateInstance(
+                                                AtomicReferenceArray[] 
scopedInstances, int synchronizedScope) {
+                                            Object[] args = new 
Object[bindings.length];
+                                            for (int i = 0; i < 
bindings.length; i++) {
+                                                args[i] = 
bindings[i].getInstance(scopedInstances, synchronizedScope);
+                                            }
+                                            return constructor.create(args);
+                                        }
+                                    }
+                                    : new AbstractCompiledBinding<R>(scope, 
slot) {
+                                        @Override
+                                        protected R doCreateInstance(
+                                                AtomicReferenceArray[] 
scopedInstances, int synchronizedScope) {
+                                            Object[] args = new 
Object[bindings.length];
+                                            for (int i = 0; i < 
bindings.length; i++) {
+                                                args[i] = 
bindings[i].getInstance(scopedInstances, synchronizedScope);
+                                            }
+                                            return constructor.create(args);
+                                        }
+                                    }
+                            : new AbstractUnsyncCompiledBinding<R>(scope, 
slot) {
+                                @Override
+                                protected R doCreateInstance(
+                                        AtomicReferenceArray[] 
scopedInstances, int synchronizedScope) {
+                                    Object[] args = new 
Object[bindings.length];
+                                    for (int i = 0; i < bindings.length; i++) {
+                                        args[i] = 
bindings[i].getInstance(scopedInstances, synchronizedScope);
+                                    }
+                                    return constructor.create(args);
+                                }
+                            }
+                    : new CompiledBinding<R>() {
+                        @Override
+                        public R getInstance(AtomicReferenceArray[] 
scopedInstances, int synchronizedScope) {
+                            Object[] args = new Object[bindings.length];
+                            for (int i = 0; i < bindings.length; i++) {
+                                args[i] = 
bindings[i].getInstance(scopedInstances, synchronizedScope);
+                            }
+                            return constructor.create(args);
+                        }
+                    };
+        }
+    }
+
+    public static class BindingToConstructor0<R> extends Binding<R> {
+        final TupleConstructor0<R> constructor;
+
+        BindingToConstructor0(TupleConstructor0<R> constructor) {
+            super(Collections.emptySet());
+            this.constructor = constructor;
+        }
+
+        @Override
+        public CompiledBinding<R> compile(
+                CompiledBindingLocator compiledBindings, boolean threadsafe, 
int scope, @Nullable Integer slot) {
+            final TupleConstructor0<R> constructor = this.constructor;
+            return slot != null
+                    ? threadsafe
+                            ? scope == 0
+                                    ? new AbstractRootCompiledBinding<R>(slot) 
{
+                                        @Override
+                                        protected R doCreateInstance(
+                                                AtomicReferenceArray[] 
scopedInstances, int synchronizedScope) {
+                                            return constructor.create();
+                                        }
+                                    }
+                                    : new AbstractCompiledBinding<R>(scope, 
slot) {
+                                        @Override
+                                        protected R doCreateInstance(
+                                                AtomicReferenceArray[] 
scopedInstances, int synchronizedScope) {
+                                            return constructor.create();
+                                        }
+                                    }
+                            : new AbstractUnsyncCompiledBinding<R>(scope, 
slot) {
+                                @Override
+                                protected R doCreateInstance(
+                                        AtomicReferenceArray[] 
scopedInstances, int synchronizedScope) {
+                                    return constructor.create();
+                                }
+                            }
+                    : new CompiledBinding<R>() {
+                        @Override
+                        public R getInstance(AtomicReferenceArray[] 
scopedInstances, int synchronizedScope) {
+                            return constructor.create();
+                        }
+                    };
+        }
+    }
+
+    public static class BindingToConstructor1<R, T1> extends Binding<R> {

Review Comment:
   do we need all these flavors?





> Provide a cleaner DI api
> ------------------------
>
>                 Key: MNG-7954
>                 URL: https://issues.apache.org/jira/browse/MNG-7954
>             Project: Maven
>          Issue Type: New Feature
>          Components: API
>            Reporter: Guillaume Nodet
>            Priority: Major
>             Fix For: 4.0.0
>
>
> With https://issues.apache.org/jira/browse/MNG-7947  the {{jakarta.inject}} 
> package has been brought into the API.
> We need a cleaner way and not depend on any third party library if possible.
> The 
> [{{SessionScope}}|https://github.com/apache/maven/blob/23bca281fcd084ac21d80f5a2950dcee30a19080/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScope.java#L123-L125]
>  would also require some cleaning to avoid having to rely on 
> {{{}(org.eclipse.sisu|javax.enterprise.inject|jakarta.enterprise.inject).Typed{}}}.
> For complete DI, we may also miss the sisu annotations 
> ({{{}PostConstruct{}}}, {{PreDestroy}} and {{Priority}} and 
> {{{}EagerSingleton{}}}.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to