You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2020/03/22 22:14:48 UTC

[logging-log4j2] 02/02: Clean up use of Variable

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

mattsicker pushed a commit to branch mean-bean-machine
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit a7fbac6f9e80fd628b6c214452dc78fdb2c8cc7d
Author: Matt Sicker <bo...@gmail.com>
AuthorDate: Sun Mar 22 17:14:16 2020 -0500

    Clean up use of Variable
    
    This now avoids some hacks from previous commits.
    
    Signed-off-by: Matt Sicker <bo...@gmail.com>
---
 .../log4j/plugins/defaults/bean/AbstractBean.java  |  5 --
 .../plugins/defaults/bean/DefaultBeanManager.java  | 77 ++++++++++------------
 .../log4j/plugins/defaults/bean/OptionalBean.java  | 63 +++++++++++++++---
 .../log4j/plugins/defaults/bean/SystemBean.java    |  5 --
 .../defaults/model/DefaultElementManager.java      |  6 --
 .../plugins/defaults/model/DefaultVariable.java    |  5 --
 .../log4j/plugins/spi/model/ElementManager.java    |  5 --
 .../logging/log4j/plugins/spi/model/Variable.java  |  2 -
 .../log4j/plugins/util/ParameterizedTypeImpl.java  |  2 +-
 .../logging/log4j/plugins/util/TypeUtil.java       |  4 ++
 10 files changed, 94 insertions(+), 80 deletions(-)

diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/AbstractBean.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/AbstractBean.java
index 1798af1..74f75c7 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/AbstractBean.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/AbstractBean.java
@@ -47,11 +47,6 @@ abstract class AbstractBean<T> implements Bean<T> {
     }
 
     @Override
-    public Variable withTypes(final Collection<Type> types) {
-        return variable.withTypes(types);
-    }
-
-    @Override
     public Qualifiers getQualifiers() {
         return variable.getQualifiers();
     }
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/DefaultBeanManager.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/DefaultBeanManager.java
index 5de7ec8..93196fe 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/DefaultBeanManager.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/DefaultBeanManager.java
@@ -46,7 +46,7 @@ import org.apache.logging.log4j.plugins.spi.model.MetaMethod;
 import org.apache.logging.log4j.plugins.spi.model.MetaParameter;
 import org.apache.logging.log4j.plugins.spi.model.Qualifiers;
 import org.apache.logging.log4j.plugins.spi.model.Variable;
-import org.apache.logging.log4j.plugins.util.ParameterizedTypeImpl;
+import org.apache.logging.log4j.plugins.util.LazyValue;
 import org.apache.logging.log4j.plugins.util.TypeUtil;
 
 import java.lang.annotation.Annotation;
@@ -64,7 +64,6 @@ import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -75,7 +74,6 @@ public class DefaultBeanManager implements BeanManager {
 
     private final Collection<Bean<?>> enabledBeans = ConcurrentHashMap.newKeySet();
     private final Map<Type, Collection<Bean<?>>> beansByType = new ConcurrentHashMap<>();
-    private final Collection<Bean<?>> sharedBeans = ConcurrentHashMap.newKeySet();
     private final Collection<DisposesMethod<?>> disposesMethods = Collections.synchronizedCollection(new ArrayList<>());
     private final Map<Class<? extends Annotation>, ScopeContext> scopes = new ConcurrentHashMap<>();
 
@@ -121,9 +119,6 @@ public class DefaultBeanManager implements BeanManager {
     private <T> Bean<T> addBean(final Bean<T> bean) {
         if (enabledBeans.add(bean)) {
             addBeanTypes(bean);
-            if (!bean.isDependentScoped() && !isSystemBean(bean)) {
-                sharedBeans.add(bean);
-            }
         }
         return bean;
     }
@@ -144,11 +139,7 @@ public class DefaultBeanManager implements BeanManager {
     }
 
     private void addBeanType(final Bean<?> bean, final Type type) {
-        beansByType.computeIfAbsent(type, ignored -> new HashSet<>()).add(bean);
-    }
-
-    private boolean isSystemBean(final Bean<?> bean) {
-        return bean instanceof SystemBean<?>;
+        beansByType.computeIfAbsent(type, ignored -> ConcurrentHashMap.newKeySet()).add(bean);
     }
 
     private <T> void loadDisposerMethods(final MetaClass<T> metaClass, final Bean<T> bean) {
@@ -257,7 +248,7 @@ public class DefaultBeanManager implements BeanManager {
                 validateBeanInjectionPoint(point, ((ProducerBean<?>) bean).getType());
             }
         }
-        final Optional<Bean<?>> bean = getBeanForInjectionPoint(point);
+        final Optional<Bean<Object>> bean = getBeanForInjectionPoint(point);
         if (!bean.isPresent() && !rawType.equals(Optional.class)) {
             throw new UnsatisfiedBeanException(point);
         }
@@ -282,13 +273,12 @@ public class DefaultBeanManager implements BeanManager {
         }
     }
 
-    private Optional<Bean<?>> getBeanForInjectionPoint(final InjectionPoint point) {
+    private <T> Optional<Bean<T>> getBeanForInjectionPoint(final InjectionPoint point) {
         // TODO: this will need to allow for TypeConverter usage somehow
         // first, look for an existing bean
         final Type type = point.getType();
         final Qualifiers qualifiers = point.getQualifiers();
-        final Optional<Bean<?>> existingBean = getExistingOrProvidedBean(type, qualifiers,
-                () -> elementManager.createVariable(point));
+        final Optional<Bean<T>> existingBean = getExistingOrProvidedBean(type, qualifiers);
         if (existingBean.isPresent()) {
             return existingBean;
         }
@@ -297,34 +287,30 @@ public class DefaultBeanManager implements BeanManager {
             if (rawType == Provider.class) {
                 final Type actualType = ((ParameterizedType) type).getActualTypeArguments()[0];
                 // if a Provider<T> is requested, we can convert an existing Bean<T> into a Bean<Provider<T>>
-                return getExistingBean(actualType, qualifiers)
-                        .map(bean -> new ProviderBean<>(
-                                elementManager.createVariable(point), context -> getValue(bean, context)))
-                        .map(this::addBean);
+                final Optional<Bean<T>> actualExistingBean = getExistingBean(actualType, qualifiers);
+                return actualExistingBean.map(bean -> new ProviderBean<>(bean, context -> getValue(bean, context)))
+                        .map(this::addBean)
+                        .map(TypeUtil::cast);
             } else if (rawType == Optional.class) {
                 final Type actualType = ((ParameterizedType) type).getActualTypeArguments()[0];
-                final Variable variable = elementManager.createVariable(point);
-                return Optional.of(createOptionalBean(actualType, qualifiers, variable));
+                // fake T like in Provider above
+                final Bean<Optional<T>> optionalBean = createOptionalBean(type, actualType, qualifiers);
+                return Optional.of(optionalBean).map(TypeUtil::cast);
             }
         }
         return Optional.empty();
     }
 
-    private Optional<Bean<?>> getExistingOrProvidedBean(final Type type, final Qualifiers qualifiers,
-                                                        final Supplier<Variable> variableSupplier) {
-        final Optional<Bean<?>> existingBean = getExistingBean(type, qualifiers);
+    private <T> Optional<Bean<T>> getExistingOrProvidedBean(final Type type, final Qualifiers qualifiers) {
+        final Optional<Bean<T>> existingBean = getExistingBean(type, qualifiers);
         if (existingBean.isPresent()) {
             return existingBean;
         }
-        final Type providerType = new ParameterizedTypeImpl(null, Provider.class, type);
-        return getExistingBean(providerType, qualifiers)
-                .<Bean<Provider<?>>>map(TypeUtil::cast)
-                .map(bean -> new ProvidedBean<>(variableSupplier.get(), context -> getValue(bean, context).get()))
-                .map(this::addBean);
+        return getProvidedBean(type, qualifiers);
     }
 
-    private Optional<Bean<?>> getExistingBean(final Type type, final Qualifiers qualifiers) {
-        final Set<Bean<?>> beans = beansWithType(type)
+    private <T> Optional<Bean<T>> getExistingBean(final Type type, final Qualifiers qualifiers) {
+        final Set<Bean<T>> beans = this.<T>beansWithType(type)
                 .filter(bean -> qualifiers.equals(bean.getQualifiers()))
                 .collect(Collectors.toSet());
         if (beans.size() > 1) {
@@ -333,24 +319,30 @@ public class DefaultBeanManager implements BeanManager {
         return beans.isEmpty() ? Optional.empty() : Optional.of(beans.iterator().next());
     }
 
-    private Stream<Bean<?>> beansWithType(final Type requiredType) {
+    private <T> Optional<Bean<T>> getProvidedBean(final Type providedType, final Qualifiers qualifiers) {
+        return getExistingBean(TypeUtil.getParameterizedType(Provider.class, providedType), qualifiers)
+                .<Bean<Provider<T>>>map(TypeUtil::cast)
+                .map(bean -> new ProvidedBean<>(bean, context -> getValue(bean, context).get()))
+                .map(this::addBean);
+    }
+
+    private <T> Stream<Bean<T>> beansWithType(final Type requiredType) {
         if (beansByType.containsKey(requiredType)) {
-            return beansByType.get(requiredType).stream();
+            return beansByType.get(requiredType).stream().map(TypeUtil::cast);
         }
         if (requiredType instanceof ParameterizedType) {
             return beansByType.getOrDefault(((ParameterizedType) requiredType).getRawType(), Collections.emptySet())
                     .stream()
-                    .filter(bean -> bean.hasMatchingType(requiredType));
+                    .filter(bean -> bean.hasMatchingType(requiredType))
+                    .map(TypeUtil::cast);
         }
         return Stream.empty();
     }
 
-    private Bean<?> createOptionalBean(final Type actualType, final Qualifiers qualifiers, final Variable variable) {
-        final Supplier<Variable> variableSupplier = () -> variable.withTypes(TypeUtil.getTypeClosure(actualType));
-        final Bean<?> optionalBean = new OptionalBean<>(variable, context ->
-                getExistingOrProvidedBean(actualType, qualifiers, variableSupplier)
-                        .map(bean -> getValue(bean, context)));
-        return addBean(optionalBean);
+    private <T> Bean<Optional<T>> createOptionalBean(final Type type, final Type typeArgument, final Qualifiers qualifiers) {
+        return addBean(new OptionalBean<>(type, qualifiers,
+                LazyValue.forSupplier(() -> getExistingOrProvidedBean(typeArgument, qualifiers)),
+                this::getValue));
     }
 
     @Override
@@ -376,8 +368,8 @@ public class DefaultBeanManager implements BeanManager {
 
     @Override
     public <T> Optional<T> getInjectableValue(final InjectionPoint point, final InitializationContext<?> parentContext) {
-        final Optional<Bean<T>> optionalResolvedBean = getBeanForInjectionPoint(point).map(TypeUtil::cast);
-        final Bean<T> resolvedBean = optionalResolvedBean.orElseThrow(() -> new UnsatisfiedBeanException(point));
+        final Bean<T> resolvedBean = this.<T>getBeanForInjectionPoint(point)
+                .orElseThrow(() -> new UnsatisfiedBeanException(point));
         final Optional<T> existingValue = point.getBean()
                 .filter(bean -> !bean.equals(resolvedBean))
                 .flatMap(bean -> getExistingValue(resolvedBean, bean, parentContext));
@@ -406,7 +398,6 @@ public class DefaultBeanManager implements BeanManager {
     public void close() {
         beansByType.clear();
         enabledBeans.clear();
-        sharedBeans.clear();
         disposesMethods.clear();
         scopes.values().forEach(ScopeContext::close);
         scopes.clear();
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/OptionalBean.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/OptionalBean.java
index d98ce88..a0d6feb 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/OptionalBean.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/OptionalBean.java
@@ -17,22 +17,69 @@
 
 package org.apache.logging.log4j.plugins.defaults.bean;
 
-import org.apache.logging.log4j.plugins.spi.model.Variable;
+import org.apache.logging.log4j.plugins.api.DependentScoped;
+import org.apache.logging.log4j.plugins.spi.bean.Bean;
 import org.apache.logging.log4j.plugins.spi.bean.InitializationContext;
+import org.apache.logging.log4j.plugins.spi.model.InjectionPoint;
+import org.apache.logging.log4j.plugins.spi.model.MetaClass;
+import org.apache.logging.log4j.plugins.spi.model.Qualifiers;
+import org.apache.logging.log4j.plugins.util.TypeUtil;
+import org.apache.logging.log4j.plugins.util.Value;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Optional;
-import java.util.function.Function;
+import java.util.function.BiFunction;
 
-class OptionalBean<T> extends SystemBean<Optional<T>> {
-    private final Function<InitializationContext<?>, Optional<T>> optionalValueFactory;
+class OptionalBean<T> implements Bean<Optional<T>> {
+    private final Type type;
+    private final Qualifiers qualifiers;
+    private final Value<Optional<Bean<T>>> optionalBean;
+    private final BiFunction<Bean<T>, InitializationContext<?>, T> getBeanValue;
 
-    OptionalBean(final Variable variable, final Function<InitializationContext<?>, Optional<T>> optionalValueFactory) {
-        super(variable);
-        this.optionalValueFactory = optionalValueFactory;
+    OptionalBean(final Type type, final Qualifiers qualifiers, final Value<Optional<Bean<T>>> optionalBean,
+                 final BiFunction<Bean<T>, InitializationContext<?>, T> getBeanValue) {
+        this.type = type;
+        this.qualifiers = qualifiers;
+        this.optionalBean = optionalBean;
+        this.getBeanValue = getBeanValue;
+    }
+
+    @Override
+    public Collection<Type> getTypes() {
+        return TypeUtil.getTypeClosure(type);
+    }
+
+    @Override
+    public Qualifiers getQualifiers() {
+        return qualifiers;
+    }
+
+    @Override
+    public Class<? extends Annotation> getScopeType() {
+        final Optional<Class<? extends Annotation>> scopeType = optionalBean.get().map(Bean::getScopeType);
+        return scopeType.orElse(DependentScoped.class);
     }
 
     @Override
     public Optional<T> create(final InitializationContext<Optional<T>> context) {
-        return optionalValueFactory.apply(context);
+        return optionalBean.get().map(bean -> getBeanValue.apply(bean, context));
+    }
+
+    @Override
+    public void destroy(final Optional<T> instance, final InitializationContext<Optional<T>> context) {
+        context.close();
+    }
+
+    @Override
+    public Collection<InjectionPoint> getInjectionPoints() {
+        return optionalBean.get().map(Bean::getInjectionPoints).orElse(Collections.emptySet());
+    }
+
+    @Override
+    public MetaClass<?> getDeclaringClass() {
+        return optionalBean.get().map(Bean::getDeclaringClass).orElse(null);
     }
 }
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/SystemBean.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/SystemBean.java
index 00771f8..c00eab6 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/SystemBean.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/bean/SystemBean.java
@@ -42,11 +42,6 @@ abstract class SystemBean<T> implements Bean<T> {
     }
 
     @Override
-    public Variable withTypes(final Collection<Type> types) {
-        return variable.withTypes(types);
-    }
-
-    @Override
     public Qualifiers getQualifiers() {
         return variable.getQualifiers();
     }
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/model/DefaultElementManager.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/model/DefaultElementManager.java
index 9fed171..79fa0e1 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/model/DefaultElementManager.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/model/DefaultElementManager.java
@@ -184,12 +184,6 @@ public class DefaultElementManager implements ElementManager {
         return createVariable(element, getQualifiers(element));
     }
 
-    @Override
-    public Variable createVariable(final InjectionPoint point) {
-        Objects.requireNonNull(point);
-        return createVariable(point.getElement(), point.getQualifiers());
-    }
-
     private Variable createVariable(final MetaElement element, final Qualifiers qualifiers) {
         final Collection<Type> types = element.getTypeClosure();
         final Class<? extends Annotation> scopeType = getScopeType(element);
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/model/DefaultVariable.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/model/DefaultVariable.java
index 8fd2160..cc7cf4a 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/model/DefaultVariable.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/defaults/model/DefaultVariable.java
@@ -44,11 +44,6 @@ public class DefaultVariable implements Variable {
     }
 
     @Override
-    public Variable withTypes(final Collection<Type> types) {
-        return new DefaultVariable(types, getQualifiers(), getScopeType());
-    }
-
-    @Override
     public Qualifiers getQualifiers() {
         return qualifiers;
     }
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/spi/model/ElementManager.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/spi/model/ElementManager.java
index 32d94e2..5c98901 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/spi/model/ElementManager.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/spi/model/ElementManager.java
@@ -147,11 +147,6 @@ public interface ElementManager extends AutoCloseable {
      */
     Variable createVariable(final MetaElement element);
 
-    /**
-     * Creates a variable for an injection point.
-     */
-    Variable createVariable(final InjectionPoint point);
-
     @Override
     void close();
 }
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/spi/model/Variable.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/spi/model/Variable.java
index 31b379a..789c886 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/spi/model/Variable.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/spi/model/Variable.java
@@ -27,8 +27,6 @@ import java.util.Collection;
 public interface Variable {
     Collection<Type> getTypes();
 
-    Variable withTypes(final Collection<Type> types);
-
     default boolean hasMatchingType(final Type requiredType) {
         for (final Type type : getTypes()) {
             if (TypeUtil.typesMatch(requiredType, type)) {
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/ParameterizedTypeImpl.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/ParameterizedTypeImpl.java
index 682a16a..b9a66e8 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/ParameterizedTypeImpl.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/ParameterizedTypeImpl.java
@@ -27,7 +27,7 @@ public class ParameterizedTypeImpl implements ParameterizedType {
     private final Type rawType;
     private final Type[] actualTypeArguments;
 
-    public ParameterizedTypeImpl(final Type ownerType, final Type rawType, final Type... actualTypeArguments) {
+    ParameterizedTypeImpl(final Type ownerType, final Type rawType, final Type... actualTypeArguments) {
         this.ownerType = ownerType;
         this.rawType = rawType;
         this.actualTypeArguments = actualTypeArguments;
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/TypeUtil.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/TypeUtil.java
index bd125dc..8f53575 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/TypeUtil.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/TypeUtil.java
@@ -538,4 +538,8 @@ public final class TypeUtil {
         return t;
     }
 
+    public static ParameterizedType getParameterizedType(final Type rawType, final Type... typeArguments) {
+        return new ParameterizedTypeImpl(null, rawType, typeArguments);
+    }
+
 }