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 2022/10/31 00:53:10 UTC

[logging-log4j2] 02/13: Flatten ThreadContextMap API

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 37d2d5d834055e5c4c980e52063007a11fafe7f5
Author: Matt Sicker <ma...@apache.org>
AuthorDate: Tue Oct 25 23:24:30 2022 -0500

    Flatten ThreadContextMap API
    
    This combines the historical ThreadContextMap extensions into default methods on ThreadContextMap.
    
    Signed-off-by: Matt Sicker <ma...@apache.org>
---
 .../log4j/spi/CleanableThreadContextMap.java       | 18 +----
 .../logging/log4j/spi/NoOpThreadContextMap.java    | 21 +++++
 .../logging/log4j/spi/ObjectThreadContextMap.java  | 36 +--------
 .../apache/logging/log4j/spi/ThreadContextMap.java | 92 +++++++++++++++++++++-
 .../logging/log4j/spi/ThreadContextMap2.java       | 32 +-------
 .../logging/log4j/perf/nogc/OpenHashStringMap.java | 19 +++--
 6 files changed, 132 insertions(+), 86 deletions(-)

diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/CleanableThreadContextMap.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/CleanableThreadContextMap.java
index f32a06e6e0..c2aeb77807 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/CleanableThreadContextMap.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/CleanableThreadContextMap.java
@@ -17,23 +17,13 @@
 package org.apache.logging.log4j.spi;
 
 /**
- * Extension service provider interface to implement additional custom MDC behavior for
- * {@link org.apache.logging.log4j.ThreadContext}.
+ * Legacy interface extension for ThreadContextMap. These methods have been moved to ThreadContextMap
+ * using default interface methods.
  *
  * @see ThreadContextMap
  * @since 2.8
+ * @deprecated use {@link ThreadContextMap} directly
  */
+@Deprecated(since = "3.0.0")
 public interface CleanableThreadContextMap extends ThreadContextMap2 {
-
-    /**
-     * Removes all given context map keys from the current thread's context map.
-     *
-     * <p>If the current thread does not have a context map it is
-     * created as a side effect.</p>
-
-     * @param keys The keys.
-     * @since 2.8
-     */
-    void removeAll(final Iterable<String> keys);
-
 }
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/NoOpThreadContextMap.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/NoOpThreadContextMap.java
index 2f858fce32..f46ffec06b 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/NoOpThreadContextMap.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/NoOpThreadContextMap.java
@@ -62,4 +62,25 @@ public class NoOpThreadContextMap implements ThreadContextMap {
     @Override
     public void remove(final String key) {
     }
+
+    @Override
+    public void putAll(final Map<String, String> map) {
+    }
+
+    @Override
+    public void removeAll(final Iterable<String> keys) {
+    }
+
+    @Override
+    public <V> V getValue(final String key) {
+        return null;
+    }
+
+    @Override
+    public <V> void putValue(final String key, final V value) {
+    }
+
+    @Override
+    public <V> void putAllValues(final Map<String, V> values) {
+    }
 }
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/ObjectThreadContextMap.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/ObjectThreadContextMap.java
index c4bc014d3a..2711dd01f8 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/ObjectThreadContextMap.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/ObjectThreadContextMap.java
@@ -16,42 +16,14 @@
  */
 package org.apache.logging.log4j.spi;
 
-import java.util.Map;
-
 /**
- * Extension service provider interface to allow putting Object values in the
- * {@link org.apache.logging.log4j.ThreadContext}.
+ * Legacy interface extension for ThreadContextMap. These methods have been moved to ThreadContextMap
+ * using default interface methods.
  *
  * @see ThreadContextMap
  * @since 2.8
+ * @deprecated use {@link ThreadContextMap} directly
  */
+@Deprecated(since = "3.0.0")
 public interface ObjectThreadContextMap extends CleanableThreadContextMap {
-
-    /**
-     * Returns the Object value for the specified key, or {@code null} if the specified key does not exist in this
-     * collection.
-     *
-     * @param key the key whose value to return
-     * @param <V> The type of the returned value.
-     * @return the value for the specified key or {@code null}
-     */
-    <V> V getValue(String key);
-
-    /**
-     * Puts the specified key-value pair into the collection.
-     *
-     * @param key the key to add or remove. Keys may be {@code null}.
-     * @param <V> The type of the stored and returned value.
-     * @param value the value to add. Values may be {@code null}.
-     */
-    <V> void putValue(String key, V value);
-
-    /**
-     * Puts all given key-value pairs into the collection.
-     *
-     * @param values the map of key-value pairs to add
-     * @param <V> The type of the value being added.
-     */
-    <V> void putAllValues(Map<String, V> values);
-
 }
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/ThreadContextMap.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/ThreadContextMap.java
index 5040bb928e..95edcdbc86 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/ThreadContextMap.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/ThreadContextMap.java
@@ -16,9 +16,12 @@
  */
 package org.apache.logging.log4j.spi;
 
-import java.util.Map;
-
 import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.util.SortedArrayStringMap;
+import org.apache.logging.log4j.util.StringMap;
+import org.apache.logging.log4j.util3.Cast;
+
+import java.util.Map;
 
 /**
  * Service provider interface to implement custom MDC behavior for {@link org.apache.logging.log4j.ThreadContext}.
@@ -86,4 +89,89 @@ public interface ThreadContextMap {
      * @param key The key to remove.
      */
     void remove(final String key);
+
+    /**
+     * Puts all given context map entries into the current thread's
+     * context map.
+     *
+     * <p>If the current thread does not have a context map it is
+     * created as a side effect.</p>
+     * @param map The map.
+     * @since 3.0.0
+     */
+    default void putAll(Map<String, String> map) {
+        map.forEach(this::put);
+    }
+
+    /**
+     * Removes all given context map keys from the current thread's context map.
+     *
+     * <p>If the current thread does not have a context map it is
+     * created as a side effect.</p>
+
+     * @param keys The keys.
+     * @since 3.0.0
+     */
+    default void removeAll(Iterable<String> keys) {
+        keys.forEach(this::remove);
+    }
+
+    /**
+     * Returns the context data for reading. Note that regardless of whether the returned context data has been
+     * {@linkplain StringMap#freeze() frozen} (made read-only) or not, callers should not attempt to modify
+     * the returned data structure.
+     *
+     * @return the {@code StringMap}
+     * @since 3.0.0
+     */
+    default StringMap getReadOnlyContextData() {
+        final Map<String, String> copy = getCopy();
+        StringMap map = new SortedArrayStringMap(copy.size());
+        copy.forEach(map::putValue);
+        map.freeze();
+        return map;
+    }
+
+    /**
+     * Returns the Object value for the specified key, or {@code null} if the specified key does not exist in this
+     * collection.
+     *
+     * @param key the key whose value to return
+     * @param <V> The type of the returned value.
+     * @return the value for the specified key or {@code null}
+     * @since 3.0.0
+     */
+    default <V> V getValue(String key) {
+        return Cast.cast(get(key));
+    }
+
+    /**
+     * Puts the specified key-value pair into the collection.
+     *
+     * @param key the key to add or remove. Keys may be {@code null}.
+     * @param <V> The type of the stored and returned value.
+     * @param value the value to add. Values may be {@code null}.
+     * @since 3.0.0
+     */
+    default <V> void putValue(String key, V value) {
+        put(key, value != null ? value.toString() : null);
+    }
+
+    /**
+     * Puts all given key-value pairs into the collection.
+     *
+     * @param values the map of key-value pairs to add
+     * @param <V> The type of the value being added.
+     * @since 3.0.0
+     */
+    default <V> void putAllValues(Map<String, V> values) {
+        values.forEach(this::putValue);
+    }
+
+    interface Factory {
+        /**
+         * Creates a new ThreadContextMap.
+         */
+        ThreadContextMap createThreadContextMap();
+    }
 }
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/ThreadContextMap2.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/ThreadContextMap2.java
index b48d5ab90b..f3e2481631 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/ThreadContextMap2.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/ThreadContextMap2.java
@@ -16,38 +16,14 @@
  */
 package org.apache.logging.log4j.spi;
 
-import java.util.Map;
-
-import org.apache.logging.log4j.util.StringMap;
-
 /**
- * Extension service provider interface to implement additional custom MDC behavior for
- * {@link org.apache.logging.log4j.ThreadContext}.
- *
- * Consider implementing {@link CleanableThreadContextMap} instead.
+ * Legacy interface extension for ThreadContextMap. These methods have been moved to ThreadContextMap
+ * using default interface methods.
  *
  * @see ThreadContextMap
  * @since 2.7
+ * @deprecated use {@link ThreadContextMap} directly
  */
+@Deprecated(since = "3.0.0")
 public interface ThreadContextMap2 extends ThreadContextMap {
-
-    /**
-     * Puts all given context map entries into the current thread's
-     * context map.
-     *
-     * <p>If the current thread does not have a context map it is
-     * created as a side effect.</p>
-     * @param map The map.
-     * @since 2.7
-     */
-    void putAll(final Map<String, String> map);
-
-    /**
-     * Returns the context data for reading. Note that regardless of whether the returned context data has been
-     * {@linkplain StringMap#freeze() frozen} (made read-only) or not, callers should not attempt to modify
-     * the returned data structure.
-     *
-     * @return the {@code StringMap}
-     */
-    StringMap getReadOnlyContextData();
 }
diff --git a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/nogc/OpenHashStringMap.java b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/nogc/OpenHashStringMap.java
index f976869278..942641506e 100644
--- a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/nogc/OpenHashStringMap.java
+++ b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/nogc/OpenHashStringMap.java
@@ -16,6 +16,12 @@
  */
 package org.apache.logging.log4j.perf.nogc;
 
+import org.apache.logging.log4j.spi.ThreadContextMap;
+import org.apache.logging.log4j.util.BiConsumer;
+import org.apache.logging.log4j.util.ReadOnlyStringMap;
+import org.apache.logging.log4j.util.StringMap;
+import org.apache.logging.log4j.util.TriConsumer;
+
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
@@ -26,12 +32,6 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 
-import org.apache.logging.log4j.util.ReadOnlyStringMap;
-import org.apache.logging.log4j.util.StringMap;
-import org.apache.logging.log4j.spi.ThreadContextMap;
-import org.apache.logging.log4j.util.BiConsumer;
-import org.apache.logging.log4j.util.TriConsumer;
-
 /**
  * Open hash map-based implementation of the {@code ReadOnlyStringMap} interface.
  * Implementation based on <a href="http://fastutil.di.unimi.it/">fastutil</a>'s
@@ -485,7 +485,8 @@ public class OpenHashStringMap<K, V> implements StringMap, ThreadContextMap {
     }
 
     /** {@inheritDoc} */
-    public void putAll(final Map<? extends K, ? extends V> map) {
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public void putAll(final Map map) {
         if (loadFactor <= .5) {
             // The resulting map will be sized for m.size() elements
             ensureCapacity(map.size());
@@ -493,9 +494,7 @@ public class OpenHashStringMap<K, V> implements StringMap, ThreadContextMap {
             // The resulting map will be tentatively sized for size() +  m.size() elements
             tryCapacity(size() + map.size());
         }
-        for (final Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
-            putObjectValue(entry.getKey(), entry.getValue());
-        }
+        map.forEach((key, value) -> putObjectValue((K) key, (V) value));
     }
 
     private V putObjectValue(final K k, final V v) {