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/14 17:45:06 UTC

[logging-log4j2] 03/05: Add support for default @Named value

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 eba942153b31eafe4acc8521aa57e1907a06020e
Author: Matt Sicker <bo...@gmail.com>
AuthorDate: Sat Mar 14 12:05:36 2020 -0500

    Add support for default @Named value
    
    Signed-off-by: Matt Sicker <bo...@gmail.com>
---
 .../defaults/model/DefaultElementManager.java      | 20 ++++++++-
 .../log4j/plugins/spi/model/Qualifiers.java        | 47 ++++++++++++++--------
 .../defaults/bean/DefaultBeanManagerTest.java      | 26 +++++++++++-
 3 files changed, 75 insertions(+), 18 deletions(-)

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 82b7369..a481e11 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
@@ -28,21 +28,27 @@ import org.apache.logging.log4j.plugins.spi.model.MetaClass;
 import org.apache.logging.log4j.plugins.spi.model.MetaElement;
 import org.apache.logging.log4j.plugins.spi.model.MetaExecutable;
 import org.apache.logging.log4j.plugins.spi.model.MetaField;
+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.Cache;
 import org.apache.logging.log4j.plugins.util.WeakCache;
 
+import java.beans.Introspector;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 public class DefaultElementManager implements ElementManager {
 
+    private static final Pattern BEAN_METHOD = Pattern.compile("^(is|get|set)([A-Z].*)$");
+
     private enum AnnotationType {
         QUALIFIER, SCOPE, UNKNOWN
     }
@@ -77,7 +83,19 @@ public class DefaultElementManager implements ElementManager {
 
     @Override
     public Qualifiers getQualifiers(final MetaElement<?> element) {
-        return Qualifiers.fromQualifierAnnotations(filterQualifiers(element.getAnnotations()));
+        final String elementName = element.getName();
+        final String defaultName;
+        if (element instanceof MetaMethod<?, ?>) {
+            final Matcher matcher = BEAN_METHOD.matcher(elementName);
+            if (matcher.matches()) {
+                defaultName = Introspector.decapitalize(matcher.group(2));
+            } else {
+                defaultName = elementName;
+            }
+        } else {
+            defaultName = elementName;
+        }
+        return Qualifiers.fromQualifierAnnotations(filterQualifiers(element.getAnnotations()), defaultName);
     }
 
     private Collection<Annotation> filterQualifiers(final Collection<Annotation> annotations) {
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/spi/model/Qualifiers.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/spi/model/Qualifiers.java
index 74c8d0c..409890c 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/spi/model/Qualifiers.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/spi/model/Qualifiers.java
@@ -22,6 +22,7 @@ import org.apache.logging.log4j.plugins.api.Default;
 import org.apache.logging.log4j.plugins.api.Ignore;
 import org.apache.logging.log4j.plugins.api.Named;
 import org.apache.logging.log4j.plugins.spi.InjectionException;
+import org.apache.logging.log4j.util.Strings;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationTargetException;
@@ -68,12 +69,20 @@ public final class Qualifiers {
      * Creates a normalized Qualifiers instance from a collection of qualifier annotation instances.
      */
     public static Qualifiers fromQualifierAnnotations(final Collection<Annotation> annotations) {
+        return fromQualifierAnnotations(annotations, Strings.EMPTY);
+    }
+
+    /**
+     * Creates a normalized Qualifiers instance from a collection of qualifier annotation instances and a default name
+     * to use when {@linkplain Named named qualifiers} do not specify a value.
+     */
+    public static Qualifiers fromQualifierAnnotations(final Collection<Annotation> annotations, final String defaultName) {
         final Map<Class<? extends Annotation>, Map<String, Object>> qualifiers = new HashMap<>(annotations.size());
         for (final Annotation annotation : annotations) {
             final Class<? extends Annotation> annotationType = annotation.annotationType();
             final AliasFor alias = annotationType.getAnnotation(AliasFor.class);
             final Class<? extends Annotation> qualifierType = alias != null ? alias.value() : annotationType;
-            qualifiers.put(qualifierType, getQualifierAttributes(annotation));
+            qualifiers.put(qualifierType, getQualifierAttributes(annotation, defaultName));
         }
         if (needsDefaultQualifier(qualifiers.keySet())) {
             qualifiers.put(Default.class, Collections.emptyMap());
@@ -81,31 +90,25 @@ public final class Qualifiers {
         return new Qualifiers(Collections.unmodifiableMap(qualifiers));
     }
 
-    private static boolean needsDefaultQualifier(final Collection<Class<? extends Annotation>> qualifierTypes) {
-        if (qualifierTypes.contains(Default.class)) {
-            return false;
-        }
-        for (final Class<? extends Annotation> qualifierType : qualifierTypes) {
-            if (qualifierType != Named.class) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private static Map<String, Object> getQualifierAttributes(final Annotation annotation) {
+    private static Map<String, Object> getQualifierAttributes(final Annotation annotation, final String defaultName) {
         final Class<? extends Annotation> annotationType = annotation.annotationType();
         final Method[] elements = annotationType.getDeclaredMethods();
         final Map<String, Object> attributes = new HashMap<>(elements.length);
         for (final Method element : elements) {
             if (!element.isAnnotationPresent(Ignore.class)) {
-                attributes.put(element.getName(), getAnnotationElement(annotation, element));
+                final String name = element.getName();
+                final Object value = getAnnotationElementValue(annotation, element);
+                if (annotationType == Named.class && name.equals("value") && value.toString().isEmpty()) {
+                    attributes.put("value", defaultName);
+                } else {
+                    attributes.put(name, value);
+                }
             }
         }
         return Collections.unmodifiableMap(attributes);
     }
 
-    private static Object getAnnotationElement(final Annotation annotation, final Method element) {
+    private static Object getAnnotationElementValue(final Annotation annotation, final Method element) {
         try {
             return element.invoke(annotation);
         } catch (final IllegalAccessException e) {
@@ -115,4 +118,16 @@ public final class Qualifiers {
                     e.getCause());
         }
     }
+
+    private static boolean needsDefaultQualifier(final Collection<Class<? extends Annotation>> qualifierTypes) {
+        if (qualifierTypes.contains(Default.class)) {
+            return false;
+        }
+        for (final Class<? extends Annotation> qualifierType : qualifierTypes) {
+            if (qualifierType != Named.class) {
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/defaults/bean/DefaultBeanManagerTest.java b/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/defaults/bean/DefaultBeanManagerTest.java
index 07fd6f6..96e7d46 100644
--- a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/defaults/bean/DefaultBeanManagerTest.java
+++ b/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/defaults/bean/DefaultBeanManagerTest.java
@@ -19,6 +19,7 @@ package org.apache.logging.log4j.plugins.defaults.bean;
 
 import org.apache.logging.log4j.plugins.api.Default;
 import org.apache.logging.log4j.plugins.api.Inject;
+import org.apache.logging.log4j.plugins.api.Named;
 import org.apache.logging.log4j.plugins.api.PostConstruct;
 import org.apache.logging.log4j.plugins.api.Produces;
 import org.apache.logging.log4j.plugins.api.Provider;
@@ -271,8 +272,31 @@ public class DefaultBeanManagerTest {
         assertEquals(6, instance.six);
     }
 
+    public static class DefaultNamedQualifier {
+        @Produces
+        @Named
+        public String methodProducer() {
+            return "foobar";
+        }
+
+        @Produces
+        @Named
+        public short getAnswer() {
+            return 42;
+        }
+    }
+
+    @WithBeans(DefaultNamedQualifier.class)
+    @Test
+    public void testDefaultNamedQualifier(@Named final String methodProducer,
+                                          @Named("methodProducer") final String alternative,
+                                          @Named final short answer) {
+        assertEquals("foobar", methodProducer);
+        assertEquals(methodProducer, alternative);
+        assertEquals(42, answer);
+    }
+
     // TODO: add tests for other supported injection scenarios
     // TODO: add tests for hierarchical scopes
-    // TODO: add tests for default @Named value calculation
     // TODO: add tests for @Named alias annotations like @PluginAttribute == @Named
 }
\ No newline at end of file