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

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

commit c88538c81e785d71c39199478046e217d453d41e
Author: Matt Sicker <[email protected]>
AuthorDate: Sun May 22 13:49:42 2022 -0500

    Rename PluginOrder to Ordered
    
    Signed-off-by: Matt Sicker <[email protected]>
---
 .../plugins/test/validation/generic/BetaBean.java  |  4 +-
 .../plugins/convert/TypeConverterRegistryTest.java |  4 +-
 .../apache/logging/log4j/plugins/di/KeyTest.java   | 99 ++++++++++++++++++++++
 .../plugins/{PluginOrder.java => Ordered.java}     | 24 +-----
 .../org/apache/logging/log4j/plugins/di/Key.java   | 60 +++++++------
 .../log4j/plugins/util/OrderedComparator.java      | 73 ++++++++++++++++
 .../log4j/plugins/util/PluginNamespace.java        |  6 +-
 7 files changed, 218 insertions(+), 52 deletions(-)

diff --git 
a/log4j-plugins-test/src/main/java/org/apache/logging/log4j/plugins/test/validation/generic/BetaBean.java
 
b/log4j-plugins-test/src/main/java/org/apache/logging/log4j/plugins/test/validation/generic/BetaBean.java
index b4b4991715..66eafa0ff0 100644
--- 
a/log4j-plugins-test/src/main/java/org/apache/logging/log4j/plugins/test/validation/generic/BetaBean.java
+++ 
b/log4j-plugins-test/src/main/java/org/apache/logging/log4j/plugins/test/validation/generic/BetaBean.java
@@ -18,13 +18,13 @@
 package org.apache.logging.log4j.plugins.test.validation.generic;
 
 import org.apache.logging.log4j.plugins.Namespace;
+import org.apache.logging.log4j.plugins.Ordered;
 import org.apache.logging.log4j.plugins.Plugin;
-import org.apache.logging.log4j.plugins.PluginOrder;
 import org.apache.logging.log4j.plugins.Singleton;
 
 @Namespace("Bean")
 @Plugin("Beta")
-@PluginOrder(PluginOrder.FIRST)
+@Ordered(Ordered.FIRST)
 @Singleton
 public class BetaBean implements BaseBean {
 }
diff --git 
a/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/convert/TypeConverterRegistryTest.java
 
b/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/convert/TypeConverterRegistryTest.java
index 4f1e780be2..b3892cd1e4 100644
--- 
a/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/convert/TypeConverterRegistryTest.java
+++ 
b/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/convert/TypeConverterRegistryTest.java
@@ -17,8 +17,8 @@
 
 package org.apache.logging.log4j.plugins.convert;
 
+import org.apache.logging.log4j.plugins.Ordered;
 import org.apache.logging.log4j.plugins.Plugin;
-import org.apache.logging.log4j.plugins.PluginOrder;
 import org.apache.logging.log4j.plugins.di.DI;
 import org.apache.logging.log4j.plugins.di.Injector;
 import org.junit.jupiter.api.Test;
@@ -49,7 +49,7 @@ class TypeConverterRegistryTest {
     @SuppressWarnings("ComparableType")
     @TypeConverters
     @Plugin
-    @PluginOrder(PluginOrder.FIRST)
+    @Ordered(Ordered.FIRST)
     public static final class CustomTestClass1Converter2
             implements TypeConverter<CustomTestClass1>, 
Comparable<TypeConverter<?>> {
 
diff --git 
a/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/di/KeyTest.java
 
b/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/di/KeyTest.java
new file mode 100644
index 0000000000..4ae4dc6f1f
--- /dev/null
+++ 
b/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/di/KeyTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.logging.log4j.plugins.di;
+
+import org.apache.logging.log4j.plugins.Named;
+import org.apache.logging.log4j.plugins.Namespace;
+import org.apache.logging.log4j.plugins.Ordered;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+// TODO: add tests for meta namespace annotations
+// TODO: add tests for more complex types with generics etc
+class KeyTest {
+
+    @Namespace("namespace")
+    @Named("name")
+    @Ordered(42)
+    static class AnnotatedClass {
+    }
+
+    @Test
+    void forClass() {
+        final Key<AnnotatedClass> key = Key.forClass(AnnotatedClass.class);
+        assertEquals("namespace", key.getNamespace());
+        assertEquals("name", key.getName());
+        assertEquals(42, key.getOrder());
+        assertEquals(AnnotatedClass.class, key.getType());
+        assertEquals(AnnotatedClass.class, key.getRawType());
+    }
+
+    interface AnnotatedMethod {
+        @Namespace("foo")
+        @Named("bar")
+        @Ordered(10)
+        String string();
+    }
+
+    @Test
+    void forMethod() {
+        final Key<String> key = assertDoesNotThrow(() -> 
Key.forMethod(AnnotatedMethod.class.getMethod("string")));
+        assertEquals("foo", key.getNamespace());
+        assertEquals("bar", key.getName());
+        assertEquals(10, key.getOrder());
+        assertEquals(String.class, key.getType());
+        assertEquals(String.class, key.getRawType());
+    }
+
+    interface AnnotatedParameter {
+        void method(@Namespace("foo") @Named String bar);
+    }
+
+    @Test
+    void forParameter() {
+        final Method method = assertDoesNotThrow(() -> 
AnnotatedParameter.class.getMethod("method", String.class));
+        final Key<String> key = Key.forParameter(method.getParameters()[0]);
+        assertEquals("foo", key.getNamespace());
+        assertEquals("bar", key.getName());
+        assertEquals(0, key.getOrder());
+        assertEquals(String.class, key.getType());
+        assertEquals(String.class, key.getRawType());
+    }
+
+    static class AnnotatedField {
+        @Namespace("foo")
+        @Named("bar")
+        public String string;
+    }
+
+    @Test
+    void forField() {
+        final Field field = assertDoesNotThrow(() -> 
AnnotatedField.class.getField("string"));
+        final Key<String> key = Key.forField(field);
+        assertEquals("foo", key.getNamespace());
+        assertEquals("bar", key.getName());
+        assertEquals(0, key.getOrder());
+        assertEquals(String.class, key.getType());
+        assertEquals(String.class, key.getRawType());
+    }
+}
diff --git 
a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginOrder.java 
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/Ordered.java
similarity index 60%
rename from 
log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginOrder.java
rename to 
log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/Ordered.java
index f13e6dc950..b044223120 100644
--- 
a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginOrder.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/Ordered.java
@@ -22,35 +22,17 @@ import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
-import java.util.Comparator;
 
 /**
- * Specifies the order in which the annotated class should be considered in 
when processing plugins.
+ * Specifies the order in which the annotated element should be considered for 
dependency injection.
  */
-@Target(ElementType.TYPE)
+@Target({ ElementType.TYPE, ElementType.METHOD })
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
-public @interface PluginOrder {
+public @interface Ordered {
     int value();
 
     int FIRST = Integer.MIN_VALUE;
 
     int LAST = Integer.MAX_VALUE;
-
-    Comparator<Class<?>> COMPARATOR = (lhs, rhs) -> {
-        if (lhs == rhs) {
-            return 0;
-        }
-        final PluginOrder lhsOrder = lhs.getAnnotation(PluginOrder.class);
-        final PluginOrder rhsOrder = rhs.getAnnotation(PluginOrder.class);
-        if (lhsOrder != null && rhsOrder != null) {
-            return Integer.compare(lhsOrder.value(), rhsOrder.value());
-        } else if (lhsOrder != null) {
-            return -1;
-        } else if (rhsOrder != null) {
-            return 1;
-        } else {
-            return lhs.getName().compareTo(rhs.getName());
-        }
-    };
 }
diff --git 
a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/Key.java 
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/Key.java
index 09967452d8..b060376424 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/Key.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/Key.java
@@ -17,9 +17,11 @@
 
 package org.apache.logging.log4j.plugins.di;
 
+import org.apache.logging.log4j.plugins.Ordered;
 import org.apache.logging.log4j.plugins.QualifierType;
 import org.apache.logging.log4j.plugins.util.AnnotationUtil;
 import org.apache.logging.log4j.plugins.util.TypeUtil;
+import org.apache.logging.log4j.util.Strings;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.AnnotatedElement;
@@ -34,7 +36,7 @@ import java.util.Objects;
 import java.util.function.Supplier;
 
 /**
- * Type with an optional {@link QualifierType} type, name, and category. Keys 
are used for binding to and looking up instance
+ * Type with an optional {@link QualifierType} type, name, and namespace. Keys 
are used for binding to and looking up instance
  * factories via {@link Injector}.
  *
  * @param <T> type of key
@@ -45,6 +47,7 @@ public class Key<T> {
     private final Class<? extends Annotation> qualifierType;
     private final String name;
     private final String namespace;
+    private final int order;
     private final int hashCode;
     private String toString;
 
@@ -67,21 +70,23 @@ public class Key<T> {
         qualifierType = qualifier != null ? qualifier.annotationType() : null;
         name = Keys.getName(superclass);
         namespace = Keys.getNamespace(superclass);
+        order = getOrder(superclass);
         hashCode = Objects.hash(type, qualifierType, 
name.toLowerCase(Locale.ROOT), namespace.toLowerCase(Locale.ROOT));
     }
 
     private Key(
             final Type type, final Class<T> rawType, final Class<? extends 
Annotation> qualifierType, final String name,
-            final String namespace) {
+            final String namespace, final int order) {
         this.type = type;
         this.rawType = rawType;
         this.qualifierType = qualifierType;
         this.name = name;
         this.namespace = namespace;
+        this.order = order;
         hashCode = Objects.hash(type, qualifierType, 
name.toLowerCase(Locale.ROOT), namespace.toLowerCase(Locale.ROOT));
     }
 
-    public Type getType() {
+    public final Type getType() {
         return type;
     }
 
@@ -89,34 +94,34 @@ public class Key<T> {
         return rawType;
     }
 
-    public String getName() {
+    public final String getName() {
         return name;
     }
 
-    public String getNamespace() {
+    public final String getNamespace() {
         return namespace;
     }
 
-    public Class<? extends Annotation> getQualifierType() {
-        return qualifierType;
+    public final int getOrder() {
+        return order;
     }
 
     /**
      * Returns a new key using the provided name and the same type and 
qualifier type as this instance.
      */
     public final Key<T> withName(final String name) {
-        return new Key<>(type, rawType, qualifierType, name, namespace);
+        return new Key<>(type, rawType, qualifierType, name, namespace, order);
     }
 
     public final Key<T> withNamespace(final String namespace) {
-        return new Key<>(type, rawType, qualifierType, name, namespace);
+        return new Key<>(type, rawType, qualifierType, name, namespace, order);
     }
 
     /**
      * Returns a new key using the provided qualifier type and the same type 
and name as this instance.
      */
     public final Key<T> withQualifierType(final Class<? extends Annotation> 
qualifierType) {
-        return new Key<>(type, rawType, qualifierType, name, namespace);
+        return new Key<>(type, rawType, qualifierType, name, namespace, order);
     }
 
     /**
@@ -125,7 +130,8 @@ public class Key<T> {
      */
     public final <P> Key<P> getSuppliedType() {
         if (type instanceof ParameterizedType && 
Supplier.class.isAssignableFrom(rawType)) {
-            return forQualifiedNamedType(qualifierType, name, 
((ParameterizedType) type).getActualTypeArguments()[0], namespace);
+            return forQualifiedNamedType(qualifierType, name, 
((ParameterizedType) type).getActualTypeArguments()[0], namespace,
+                    order);
         }
         return null;
     }
@@ -133,7 +139,7 @@ public class Key<T> {
     public final <P> Key<P> getParameterizedTypeArgument(final int arg) {
         if (type instanceof ParameterizedType) {
             return forQualifiedNamedType(qualifierType, name, 
((ParameterizedType) type).getActualTypeArguments()[arg],
-                    namespace);
+                    namespace, order);
         }
         return null;
     }
@@ -162,12 +168,8 @@ public class Key<T> {
     public final String toString() {
         String string = toString;
         if (string == null) {
-            toString = string = "Key{" +
-                    "type=" + type.getTypeName() +
-                    (qualifierType != null ? ", qualifierType=" + 
qualifierType.getSimpleName() : "") +
-                    ", name='" + name + '\'' +
-                    ", category='" + namespace + '\'' +
-                    '}';
+            toString = string = String.format("Key{namespace='%s', name='%s', 
type=%s, qualifierType=%s}",
+                    namespace, name, type.getTypeName(), qualifierType != null 
? qualifierType.getSimpleName() : Strings.EMPTY);
         }
         return string;
     }
@@ -179,7 +181,8 @@ public class Key<T> {
         return forQualifiedNamedType(getQualifierType(clazz),
                 Keys.getName(clazz),
                 clazz,
-                Keys.getNamespace(clazz));
+                Keys.getNamespace(clazz),
+                getOrder(clazz));
     }
 
     /**
@@ -189,7 +192,8 @@ public class Key<T> {
         return forQualifiedNamedType(getQualifierType(method),
                 Keys.getName(method),
                 method.getGenericReturnType(),
-                Keys.getNamespace(method));
+                Keys.getNamespace(method),
+                getOrder(method));
     }
 
     /**
@@ -199,7 +203,8 @@ public class Key<T> {
         return forQualifiedNamedType(getQualifierType(parameter),
                 Keys.getName(parameter),
                 parameter.getParameterizedType(),
-                Keys.getNamespace(parameter));
+                Keys.getNamespace(parameter),
+                0);
     }
 
     /**
@@ -209,17 +214,24 @@ public class Key<T> {
         return forQualifiedNamedType(getQualifierType(field),
                 Keys.getName(field),
                 field.getGenericType(),
-                Keys.getNamespace(field));
+                Keys.getNamespace(field),
+                0);
     }
 
     private static <T> Key<T> forQualifiedNamedType(
-            final Class<? extends Annotation> qualifierType, final String 
name, final Type type, final String category) {
+            final Class<? extends Annotation> qualifierType, final String 
name, final Type type, final String namespace,
+            final int order) {
         final Class<T> rawType = TypeUtil.cast(TypeUtil.getRawType(type));
-        return new Key<>(type, rawType, qualifierType, name, category);
+        return new Key<>(type, rawType, qualifierType, name, namespace, order);
     }
 
     private static Class<? extends Annotation> getQualifierType(final 
AnnotatedElement element) {
         final Annotation qualifierAnnotation = 
AnnotationUtil.getMetaAnnotation(element, QualifierType.class);
         return qualifierAnnotation != null ? 
qualifierAnnotation.annotationType() : null;
     }
+
+    private static int getOrder(final AnnotatedElement element) {
+        final Ordered annotation = element.getAnnotation(Ordered.class);
+        return annotation != null ? annotation.value() : 0;
+    }
 }
diff --git 
a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/OrderedComparator.java
 
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/OrderedComparator.java
new file mode 100644
index 0000000000..cf19faa4be
--- /dev/null
+++ 
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/OrderedComparator.java
@@ -0,0 +1,73 @@
+/*
+ * 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.logging.log4j.plugins.util;
+
+import org.apache.logging.log4j.plugins.Ordered;
+import org.apache.logging.log4j.plugins.di.Keys;
+import org.apache.logging.log4j.util.Strings;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.AnnotatedType;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.Comparator;
+
+/**
+ * Comparator for annotated elements using {@link Ordered} followed by their 
name from {@link Keys#getName}.
+ */
+public class OrderedComparator implements Comparator<AnnotatedElement> {
+    public static final OrderedComparator INSTANCE = new OrderedComparator();
+
+    @Override
+    public int compare(final AnnotatedElement lhs, final AnnotatedElement rhs) 
{
+        if (lhs == rhs) {
+            return 0;
+        }
+        final Ordered lhsOrder = lhs.getAnnotation(Ordered.class);
+        final Ordered rhsOrder = rhs.getAnnotation(Ordered.class);
+        if (lhsOrder != null && rhsOrder != null) {
+            return Integer.compare(lhsOrder.value(), rhsOrder.value());
+        } else if (lhsOrder != null) {
+            return -1;
+        } else if (rhsOrder != null) {
+            return 1;
+        } else {
+            return getName(lhs).compareToIgnoreCase(getName(rhs));
+        }
+    }
+
+    private static String getName(final AnnotatedElement element) {
+        if (element instanceof Class<?>) {
+            return Keys.getName((Class<?>) element);
+        }
+        if (element instanceof Field) {
+            return Keys.getName((Field) element);
+        }
+        if (element instanceof Parameter) {
+            return Keys.getName((Parameter) element);
+        }
+        if (element instanceof Method) {
+            return Keys.getName((Method) element);
+        }
+        if (element instanceof AnnotatedType) {
+            return Keys.getName((AnnotatedType) element);
+        }
+        return Strings.EMPTY;
+    }
+}
diff --git 
a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/PluginNamespace.java
 
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/PluginNamespace.java
index 938d9828b7..bb6856eac8 100644
--- 
a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/PluginNamespace.java
+++ 
b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/util/PluginNamespace.java
@@ -18,7 +18,7 @@
 package org.apache.logging.log4j.plugins.util;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.plugins.PluginOrder;
+import org.apache.logging.log4j.plugins.Ordered;
 import org.apache.logging.log4j.plugins.Singleton;
 import org.apache.logging.log4j.status.StatusLogger;
 
@@ -109,12 +109,12 @@ public class PluginNamespace extends 
AbstractCollection<PluginType<?>> {
 
     /**
      * Merges the provided plugin type into this namespace using the given key 
and returns the merged result.
-     * Merging is done by preferring plugins according to {@link PluginOrder} 
where a conflict occurs with the
+     * Merging is done by preferring plugins according to {@link Ordered} 
where a conflict occurs with the
      * same key.
      */
     public PluginType<?> merge(final String key, final PluginType<?> 
pluginType) {
         final PluginType<?> result = plugins.merge(key, pluginType, (lhs, rhs) 
-> {
-            final int compare = 
PluginOrder.COMPARATOR.compare(lhs.getPluginClass(), rhs.getPluginClass());
+            final int compare = 
OrderedComparator.INSTANCE.compare(lhs.getPluginClass(), rhs.getPluginClass());
             LOGGER.debug("PluginNamespace merge for key {} with comparison 
result {}", key, compare);
             return compare <= 0 ? lhs : rhs;
         });

Reply via email to