diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/BasicMDCAdapter.java b/slf4j-api/src/main/java/org/slf4j/helpers/BasicMDCAdapter.java index 95cb904a2..81284b338 100644 --- a/slf4j-api/src/main/java/org/slf4j/helpers/BasicMDCAdapter.java +++ b/slf4j-api/src/main/java/org/slf4j/helpers/BasicMDCAdapter.java @@ -38,7 +38,7 @@ * @author Ceki Gulcu * @author Maarten Bosteels * @author Lukasz Cwik - * + * * @since 1.5.0 */ public class BasicMDCAdapter implements MDCAdapter { @@ -156,9 +156,14 @@ public void pushByKey(String key, String value) { @Override public String popByKey(String key) { - return threadLocalMapOfDeques.popByKey(key); + return threadLocalMapOfDeques.popByKey(key); } + @Override + public String peekByKey(String key) { + return threadLocalMapOfDeques.peekByKey(key); + } + @Override public Deque getCopyOfDequeByKey(String key) { return threadLocalMapOfDeques.getCopyOfDequeByKey(key); diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/ThreadLocalMapOfStacks.java b/slf4j-api/src/main/java/org/slf4j/helpers/ThreadLocalMapOfStacks.java index 89ddee0ea..286d0f3d0 100644 --- a/slf4j-api/src/main/java/org/slf4j/helpers/ThreadLocalMapOfStacks.java +++ b/slf4j-api/src/main/java/org/slf4j/helpers/ThreadLocalMapOfStacks.java @@ -9,7 +9,7 @@ /** * A simple implementation of ThreadLocal backed Map containing values of type * Deque. - * + * * @author Ceki Guuml;cü * @since 2.0.0 */ @@ -40,50 +40,53 @@ public void pushByKey(String key, String value) { } public String popByKey(String key) { - if (key == null) + Deque deque = getDeque(key); + if (deque == null) return null; - Map> map = tlMapOfStacks.get(); - if (map == null) - return null; - Deque deque = map.get(key); + return deque.pop(); + } + + public String peekByKey(String key) { + Deque deque = getDeque(key); if (deque == null) return null; - return deque.pop(); + + return deque.peek(); } public Deque getCopyOfDequeByKey(String key) { + Deque deque = getDeque(key); + if (deque == null) + return null; + + return new ArrayDeque(deque); + } + + private Deque getDeque(String key) { if (key == null) return null; Map> map = tlMapOfStacks.get(); if (map == null) return null; - Deque deque = map.get(key); - if (deque == null) - return null; - return new ArrayDeque(deque); + return map.get(key); } - + /** - * Clear the deque(stack) referenced by 'key'. - * + * Clear the deque(stack) referenced by 'key'. + * * @param key identifies the stack - * + * * @since 2.0.0 */ public void clearDequeByKey(String key) { - if (key == null) - return; - - Map> map = tlMapOfStacks.get(); - if (map == null) - return; - Deque deque = map.get(key); + Deque deque = getDeque(key); if (deque == null) return; + deque.clear(); } -} +} \ No newline at end of file diff --git a/slf4j-api/src/main/java/org/slf4j/spi/MDCAdapter.java b/slf4j-api/src/main/java/org/slf4j/spi/MDCAdapter.java index 924849d14..7ba5d5558 100644 --- a/slf4j-api/src/main/java/org/slf4j/spi/MDCAdapter.java +++ b/slf4j-api/src/main/java/org/slf4j/spi/MDCAdapter.java @@ -110,6 +110,19 @@ public interface MDCAdapter { */ public String popByKey(String key); + /** + * peek the stack referenced by 'key' and return the value possibly null. + * + * @param key identifies the deque(stack) + * @return the value just peeked. May be null/ + * @since 2.0.18 + */ + default public String peekByKey(String key){ + Deque deque = getCopyOfDequeByKey(key); + if(deque == null) + return null; + return deque.peek(); + } /** * Returns a copy of the deque(stack) referenced by 'key'. May be null. * diff --git a/slf4j-api/src/test/java/org/slf4j/helpers/MDCAdapterTestBase.java b/slf4j-api/src/test/java/org/slf4j/helpers/MDCAdapterTestBase.java index cd97b1c37..b1c1abc51 100644 --- a/slf4j-api/src/test/java/org/slf4j/helpers/MDCAdapterTestBase.java +++ b/slf4j-api/src/test/java/org/slf4j/helpers/MDCAdapterTestBase.java @@ -24,18 +24,16 @@ package org.slf4j.helpers; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; - import java.lang.Thread.UncaughtExceptionHandler; import java.util.Map; +import java.util.NoSuchElementException; import org.junit.After; import org.junit.Test; import org.slf4j.spi.MDCAdapter; +import static org.junit.Assert.*; + /** * Tests for {@link BasicMDCAdapter} * @@ -64,6 +62,25 @@ public void testSettingAndGettingWithMDC() { assertEquals(mdc.get("testKey"), "testValue"); } + @Test + public void testPushingAndPoppingWithMDC() { + assertNull(mdc.popByKey("testKey")); + mdc.pushByKey("testKey", "testValue"); + mdc.pushByKey("testKey", "differentTestValue"); + assertEquals(mdc.popByKey("testKey"), "differentTestValue"); + assertEquals(mdc.popByKey("testKey"), "testValue"); + assertThrows(NoSuchElementException.class, () -> mdc.popByKey("testKey")); + } + + @Test + public void testPushingAndPeekingWithMDC() { + assertNull(mdc.peekByKey("testKey")); + mdc.pushByKey("testKey", "testValue"); + mdc.pushByKey("testKey", "differentTestValue"); + assertEquals(mdc.peekByKey("testKey"), "differentTestValue"); + assertEquals(mdc.peekByKey("testKey"), "differentTestValue"); + } + @Test public void testOverwritingAKeyInMDC() { assertNull(mdc.get("testKey")); diff --git a/slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jMDCAdapter.java b/slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jMDCAdapter.java index 8c874a680..b6f6e7ec3 100644 --- a/slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jMDCAdapter.java +++ b/slf4j-reload4j/src/main/java/org/slf4j/reload4j/Reload4jMDCAdapter.java @@ -114,6 +114,11 @@ public String popByKey(String key) { return threadLocalMapOfDeques.popByKey(key); } + @Override + public String peekByKey(String key) { + return threadLocalMapOfDeques.peekByKey(key); + } + @Override public Deque getCopyOfDequeByKey(String key) { return threadLocalMapOfDeques.getCopyOfDequeByKey(key);