You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rp...@apache.org on 2016/08/22 15:40:17 UTC
[03/16] logging-log4j2 git commit: LOG4J2-1349 GC-free ThreadContext
initial commit
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-api/src/test/java/org/apache/logging/log4j/spi/ArrayContextDataTest.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/spi/ArrayContextDataTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/spi/ArrayContextDataTest.java
new file mode 100644
index 0000000..f85db8a
--- /dev/null
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/spi/ArrayContextDataTest.java
@@ -0,0 +1,569 @@
+package org.apache.logging.log4j.spi;/*
+ * 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.logging.log4j.spi.ArrayContextData;
+import org.apache.logging.log4j.util.BiConsumer;
+import org.apache.logging.log4j.util.TriConsumer;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests the ArrayContextData class.
+ */
+public class ArrayContextDataTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConstructorDisallowsNegativeCapacity() throws Exception {
+ new ArrayContextData(-1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConstructorDisallowsZeroCapacity() throws Exception {
+ new ArrayContextData(0);
+ }
+
+ @Test
+ public void testConstructorIgnoresNull() throws Exception {
+ assertEquals(0, new ArrayContextData(null).size());
+ }
+
+ @Test
+ public void testToString() {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+ assertEquals("{3=3value, B=Bvalue, a=avalue}", original.toString());
+ }
+
+ @Test
+ public void testSerialization() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+
+ final byte[] binary = serialize(original);
+ final ArrayContextData copy = deserialize(binary);
+ assertEquals(original, copy);
+ }
+
+ private byte[] serialize(final ArrayContextData data) throws IOException {
+ final ByteArrayOutputStream arr = new ByteArrayOutputStream();
+ final ObjectOutputStream out = new ObjectOutputStream(arr);
+ out.writeObject(data);
+ return arr.toByteArray();
+ }
+
+ private ArrayContextData deserialize(final byte[] binary) throws IOException, ClassNotFoundException {
+ final ByteArrayInputStream inArr = new ByteArrayInputStream(binary);
+ final ObjectInputStream in = new ObjectInputStream(inArr);
+ final ArrayContextData result = (ArrayContextData) in.readObject();
+ return result;
+ }
+
+ @Test
+ public void testPutAll() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+
+ final ArrayContextData other = new ArrayContextData();
+ other.putAll(original);
+ assertEquals(original, other);
+
+ other.putValue("3", "otherValue");
+ assertNotEquals(original, other);
+
+ other.putValue("3", null);
+ assertNotEquals(original, other);
+
+ other.putValue("3", "3value");
+ assertEquals(original, other);
+ }
+
+ @Test
+ public void testEquals() {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+ assertEquals(original, original); // equal to itself
+
+ final ArrayContextData other = new ArrayContextData();
+ other.putValue("a", "avalue");
+ assertNotEquals(original, other);
+
+ other.putValue("B", "Bvalue");
+ assertNotEquals(original, other);
+
+ other.putValue("3", "3value");
+ assertEquals(original, other);
+
+ other.putValue("3", "otherValue");
+ assertNotEquals(original, other);
+
+ other.putValue("3", null);
+ assertNotEquals(original, other);
+
+ other.putValue("3", "3value");
+ assertEquals(original, other);
+ }
+
+ @Test
+ public void testAsMap() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+
+ final Map<String, Object> expected = new HashMap<>();
+ expected.put("a", "avalue");
+ expected.put("B", "Bvalue");
+ expected.put("3", "3value");
+
+ assertEquals(expected, original.asMap());
+ }
+
+ @Test
+ public void testGetCopyDelegatesToAsMap() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ assertEquals(original.getCopy(), original.asMap());
+
+ original.putValue("B", "Bvalue");
+ assertEquals(original.getCopy(), original.asMap());
+
+ original.putValue("3", "3value");
+ assertEquals(original.getCopy(), original.asMap());
+ }
+
+ @Test
+ public void testGetImmutableMapOrNull() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ assertEquals(original.getImmutableMapOrNull(), original.asMap());
+
+ original.putValue("B", "Bvalue");
+ assertEquals(original.getImmutableMapOrNull(), original.asMap());
+
+ original.putValue("3", "3value");
+ assertEquals(original.getImmutableMapOrNull(), original.asMap());
+
+ try {
+ original.getImmutableMapOrNull().put("abc", "xyz");
+ fail("Expected map to be immutable");
+ } catch (final UnsupportedOperationException ok) {
+ //ok
+ }
+ }
+
+ @Test
+ public void testPutInsertsInAlphabeticOrder() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ original.put("a", "avalue");
+ original.put("B", "Bvalue");
+ original.put("3", "3value");
+ original.put("c", "cvalue");
+ original.put("d", "dvalue");
+
+ assertEquals("avalue", original.getValue("a"));
+ assertEquals("avalue", original.getValueAt(2));
+
+ assertEquals("Bvalue", original.getValue("B"));
+ assertEquals("Bvalue", original.getValueAt(1));
+
+ assertEquals("3value", original.getValue("3"));
+ assertEquals("3value", original.getValueAt(0));
+
+ assertEquals("cvalue", original.getValue("c"));
+ assertEquals("cvalue", original.getValueAt(3));
+
+ assertEquals("dvalue", original.getValue("d"));
+ assertEquals("dvalue", original.getValueAt(4));
+ }
+
+ @Test
+ public void testPutValueInsertsInAlphabeticOrder() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+ original.putValue("c", "cvalue");
+ original.putValue("d", "dvalue");
+
+ assertEquals("avalue", original.getValue("a"));
+ assertEquals("avalue", original.getValueAt(2));
+
+ assertEquals("Bvalue", original.getValue("B"));
+ assertEquals("Bvalue", original.getValueAt(1));
+
+ assertEquals("3value", original.getValue("3"));
+ assertEquals("3value", original.getValueAt(0));
+
+ assertEquals("cvalue", original.getValue("c"));
+ assertEquals("cvalue", original.getValueAt(3));
+
+ assertEquals("dvalue", original.getValue("d"));
+ assertEquals("dvalue", original.getValueAt(4));
+ }
+
+ @Test
+ public void testNullKeysAllowed() {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+ original.putValue("c", "cvalue");
+ original.putValue("d", "dvalue");
+ assertEquals(5, original.size());
+ assertEquals("{3=3value, B=Bvalue, a=avalue, c=cvalue, d=dvalue}", original.toString());
+
+ original.putValue(null, "nullvalue");
+ assertEquals(6, original.size());
+ assertEquals("{null=nullvalue, 3=3value, B=Bvalue, a=avalue, c=cvalue, d=dvalue}", original.toString());
+
+ original.putValue(null, "otherNullvalue");
+ assertEquals("{null=otherNullvalue, 3=3value, B=Bvalue, a=avalue, c=cvalue, d=dvalue}", original.toString());
+ assertEquals(6, original.size());
+
+ original.putValue(null, "nullvalue");
+ assertEquals(6, original.size());
+ assertEquals("{null=nullvalue, 3=3value, B=Bvalue, a=avalue, c=cvalue, d=dvalue}", original.toString());
+
+ original.putValue(null, "abc");
+ assertEquals(6, original.size());
+ assertEquals("{null=abc, 3=3value, B=Bvalue, a=avalue, c=cvalue, d=dvalue}", original.toString());
+ }
+
+ @Test
+ public void testNullKeysCopiedToAsMap() {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+ original.putValue("c", "cvalue");
+ original.putValue("d", "dvalue");
+ assertEquals(5, original.size());
+
+ HashMap<String, String> expected = new HashMap<>();
+ expected.put("a", "avalue");
+ expected.put("B", "Bvalue");
+ expected.put("3", "3value");
+ expected.put("c", "cvalue");
+ expected.put("d", "dvalue");
+ assertEquals("initial", expected, original.asMap());
+
+ original.putValue(null, "nullvalue");
+ expected.put(null, "nullvalue");
+ assertEquals(6, original.size());
+ assertEquals("with null key", expected, original.asMap());
+
+ original.putValue(null, "otherNullvalue");
+ expected.put(null, "otherNullvalue");
+ assertEquals(6, original.size());
+ assertEquals("with null key value2", expected, original.asMap());
+
+ original.putValue(null, "nullvalue");
+ expected.put(null, "nullvalue");
+ assertEquals(6, original.size());
+ assertEquals("with null key value1 again", expected, original.asMap());
+
+ original.putValue(null, "abc");
+ expected.put(null, "abc");
+ assertEquals(6, original.size());
+ assertEquals("with null key value3", expected, original.asMap());
+ }
+
+ @Test
+ public void testRemove() {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ assertEquals(1, original.size());
+ assertEquals("avalue", original.getValue("a"));
+
+ original.remove("a");
+ assertEquals(0, original.size());
+ assertNull("no a val", original.getValue("a"));
+
+ original.remove("B");
+ assertEquals(0, original.size());
+ assertNull("no B val", original.getValue("B"));
+ }
+
+ @Test
+ public void testNullValuesArePreserved() {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ assertEquals(1, original.size());
+ assertEquals("avalue", original.getValue("a"));
+
+ original.putValue("a", null);
+ assertEquals(1, original.size());
+ assertNull("no a val", original.getValue("a"));
+
+ original.putValue("B", null);
+ assertEquals(2, original.size());
+ assertNull("no B val", original.getValue("B"));
+ }
+
+ @Test
+ public void testGet() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ original.put("a", "avalue");
+ original.put("B", "Bvalue");
+ original.put("3", "3value");
+
+ assertEquals("avalue", original.get("a"));
+ assertEquals("Bvalue", original.get("B"));
+ assertEquals("3value", original.get("3"));
+
+ original.putValue("0", "0value");
+ assertEquals("0value", original.get("0"));
+ assertEquals("3value", original.get("3"));
+ assertEquals("Bvalue", original.get("B"));
+ assertEquals("avalue", original.get("a"));
+ }
+
+ @Test
+ public void testGetValue_GetValueAt() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+
+ assertEquals("avalue", original.getValue("a"));
+ assertEquals("avalue", original.getValueAt(2));
+
+ assertEquals("Bvalue", original.getValue("B"));
+ assertEquals("Bvalue", original.getValueAt(1));
+
+ assertEquals("3value", original.getValue("3"));
+ assertEquals("3value", original.getValueAt(0));
+
+ original.putValue("0", "0value");
+ assertEquals("0value", original.getValue("0"));
+ assertEquals("0value", original.getValueAt(0));
+ assertEquals("3value", original.getValue("3"));
+ assertEquals("3value", original.getValueAt(1));
+ assertEquals("Bvalue", original.getValue("B"));
+ assertEquals("Bvalue", original.getValueAt(2));
+ assertEquals("avalue", original.getValue("a"));
+ assertEquals("avalue", original.getValueAt(3));
+ }
+
+ @Test
+ public void testClear() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+ assertEquals(3, original.size());
+
+ original.clear();
+ assertEquals(0, original.size());
+
+ // ensure slots in the values array are nulled out
+ Field f = ArrayContextData.class.getDeclaredField("values");
+ f.setAccessible(true);
+ Object[] values = (Object[]) f.get(original);
+ for (int i = 0; i < values.length; i++) {
+ assertNull(values[i]);
+ }
+ }
+
+ @Test
+ public void testIndexOfKey() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ assertEquals(0, original.indexOfKey("a"));
+
+ original.putValue("B", "Bvalue");
+ assertEquals(1, original.indexOfKey("a"));
+ assertEquals(0, original.indexOfKey("B"));
+
+ original.putValue("3", "3value");
+ assertEquals(2, original.indexOfKey("a"));
+ assertEquals(1, original.indexOfKey("B"));
+ assertEquals(0, original.indexOfKey("3"));
+
+ original.putValue("A", "AAA");
+ assertEquals(3, original.indexOfKey("a"));
+ assertEquals(2, original.indexOfKey("B"));
+ assertEquals(1, original.indexOfKey("A"));
+ assertEquals(0, original.indexOfKey("3"));
+
+ original.putValue("C", "CCC");
+ assertEquals(4, original.indexOfKey("a"));
+ assertEquals(3, original.indexOfKey("C"));
+ assertEquals(2, original.indexOfKey("B"));
+ assertEquals(1, original.indexOfKey("A"));
+ assertEquals(0, original.indexOfKey("3"));
+
+ original.putValue("2", "222");
+ assertEquals(5, original.indexOfKey("a"));
+ assertEquals(4, original.indexOfKey("C"));
+ assertEquals(3, original.indexOfKey("B"));
+ assertEquals(2, original.indexOfKey("A"));
+ assertEquals(1, original.indexOfKey("3"));
+ assertEquals(0, original.indexOfKey("2"));
+ }
+
+ @Test
+ public void testContainsKey() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ assertFalse("a", original.containsKey("a"));
+ assertFalse("B", original.containsKey("B"));
+ assertFalse("3", original.containsKey("3"));
+ assertFalse("A", original.containsKey("A"));
+
+ original.putValue("a", "avalue");
+ assertTrue("a", original.containsKey("a"));
+ assertFalse("B", original.containsKey("B"));
+ assertFalse("3", original.containsKey("3"));
+ assertFalse("A", original.containsKey("A"));
+
+ original.putValue("B", "Bvalue");
+ assertTrue("a", original.containsKey("a"));
+ assertTrue("B", original.containsKey("B"));
+ assertFalse("3", original.containsKey("3"));
+ assertFalse("A", original.containsKey("A"));
+
+ original.putValue("3", "3value");
+ assertTrue("a", original.containsKey("a"));
+ assertTrue("B", original.containsKey("B"));
+ assertTrue("3", original.containsKey("3"));
+ assertFalse("A", original.containsKey("A"));
+
+ original.putValue("A", "AAA");
+ assertTrue("a", original.containsKey("a"));
+ assertTrue("B", original.containsKey("B"));
+ assertTrue("3", original.containsKey("3"));
+ assertTrue("A", original.containsKey("A"));
+ }
+
+ @Test
+ public void testGetValueAt() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ assertEquals("a", original.getKeyAt(0));
+ assertEquals("avalue", original.getValueAt(0));
+
+ original.putValue("B", "Bvalue");
+ assertEquals("B", original.getKeyAt(0));
+ assertEquals("Bvalue", original.getValueAt(0));
+ assertEquals("a", original.getKeyAt(1));
+ assertEquals("avalue", original.getValueAt(1));
+
+ original.putValue("3", "3value");
+ assertEquals("3", original.getKeyAt(0));
+ assertEquals("3value", original.getValueAt(0));
+ assertEquals("B", original.getKeyAt(1));
+ assertEquals("Bvalue", original.getValueAt(1));
+ assertEquals("a", original.getKeyAt(2));
+ assertEquals("avalue", original.getValueAt(2));
+ }
+
+ @Test
+ public void testSizeAndIsEmpty() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ assertEquals(0, original.size());
+ assertTrue("initial", original.isEmpty());
+
+ original.putValue("a", "avalue");
+ assertEquals(1, original.size());
+ assertFalse("size=" + original.size(), original.isEmpty());
+
+ original.putValue("B", "Bvalue");
+ assertEquals(2, original.size());
+ assertFalse("size=" + original.size(), original.isEmpty());
+
+ original.putValue("3", "3value");
+ assertEquals(3, original.size());
+ assertFalse("size=" + original.size(), original.isEmpty());
+
+ original.remove("B");
+ assertEquals(2, original.size());
+ assertFalse("size=" + original.size(), original.isEmpty());
+
+ original.remove("3");
+ assertEquals(1, original.size());
+ assertFalse("size=" + original.size(), original.isEmpty());
+
+ original.remove("a");
+ assertEquals(0, original.size());
+ assertTrue("size=" + original.size(), original.isEmpty());
+ }
+
+ @Test
+ public void testForEachBiConsumer() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+
+ original.forEach(new BiConsumer<String, String>() {
+ int count = 0;
+ @Override
+ public void accept(final String key, final String value) {
+ assertEquals("key", key, original.getKeyAt(count));
+ assertEquals("val", value, original.getValueAt(count));
+ count++;
+ assertTrue("count should not exceed size but was " + count, count <= original.size());
+ }
+ });
+ }
+
+ static class State {
+ ArrayContextData data;
+ int count;
+ }
+ static TriConsumer<String, String, State> COUNTER = new TriConsumer<String, String, State>() {
+ @Override
+ public void accept(final String key, final String value, final State state) {
+ assertEquals("key", key, state.data.getKeyAt(state.count));
+ assertEquals("val", value, state.data.getValueAt(state.count));
+ state.count++;
+ assertTrue("count should not exceed size but was " + state.count,
+ state.count <= state.data.size());
+ }
+ };
+
+ @Test
+ public void testForEachTriConsumer() throws Exception {
+ final ArrayContextData original = new ArrayContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+
+ final State state = new State();
+ state.data = original;
+ original.forEach(COUNTER, state);
+ assertEquals(state.count, original.size());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-api/src/test/java/org/apache/logging/log4j/spi/OpenHashMapContextDataTest.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/spi/OpenHashMapContextDataTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/spi/OpenHashMapContextDataTest.java
new file mode 100644
index 0000000..a49ca81
--- /dev/null
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/spi/OpenHashMapContextDataTest.java
@@ -0,0 +1,507 @@
+package org.apache.logging.log4j.spi;/*
+ * 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.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.logging.log4j.spi.ContextData;
+import org.apache.logging.log4j.spi.OpenHashMapContextData;
+import org.apache.logging.log4j.util.BiConsumer;
+import org.apache.logging.log4j.util.TriConsumer;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests the OpenHashMapContextData class.
+ */
+public class OpenHashMapContextDataTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConstructorDisallowsNegativeCapacity() throws Exception {
+ new OpenHashMapContextData(-1);
+ }
+
+ @Test
+ public void testConstructorAllowsZeroCapacity() throws Exception {
+ OpenHashMapContextData data = new OpenHashMapContextData(0);
+ assertEquals(2, data.arraySize);
+ }
+
+ @Test(expected = NullPointerException.class)
+ @SuppressWarnings("unchecked")
+ public void testConstructorDisallowsNullMap() throws Exception {
+ assertEquals(0, new OpenHashMapContextData((Map) null).size());
+ }
+
+ @Test(expected = NullPointerException.class)
+ @SuppressWarnings("unchecked")
+ public void testConstructorDisallowsNullContextData() throws Exception {
+ assertEquals(0, new OpenHashMapContextData((ContextData) null).size());
+ }
+
+ @Test
+ public void testToString() {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+ assertEquals("{B=Bvalue, a=avalue, 3=3value}", original.toString());
+ }
+
+ @Test
+ public void testSerialization() throws Exception {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+
+ final byte[] binary = serialize(original);
+ final OpenHashMapContextData copy = deserialize(binary);
+ assertEquals(original, copy);
+ }
+
+ private byte[] serialize(final OpenHashMapContextData data) throws IOException {
+ final ByteArrayOutputStream arr = new ByteArrayOutputStream();
+ final ObjectOutputStream out = new ObjectOutputStream(arr);
+ out.writeObject(data);
+ return arr.toByteArray();
+ }
+
+ private OpenHashMapContextData deserialize(final byte[] binary) throws IOException, ClassNotFoundException {
+ final ByteArrayInputStream inArr = new ByteArrayInputStream(binary);
+ final ObjectInputStream in = new ObjectInputStream(inArr);
+ final OpenHashMapContextData result = (OpenHashMapContextData) in.readObject();
+ return result;
+ }
+
+ @Test
+ public void testPutAll() throws Exception {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+
+ final OpenHashMapContextData other = new OpenHashMapContextData();
+ other.putAll(original);
+ assertEquals(original, other);
+
+ other.putValue("3", "otherValue");
+ assertNotEquals(original, other);
+
+ other.putValue("3", null);
+ assertNotEquals(original, other);
+
+ other.putValue("3", "3value");
+ assertEquals(original, other);
+ }
+
+ @Test
+ public void testEquals() {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+ assertEquals(original, original); // equal to itself
+
+ final OpenHashMapContextData other = new OpenHashMapContextData();
+ other.putValue("a", "avalue");
+ assertNotEquals(original, other);
+
+ other.putValue("B", "Bvalue");
+ assertNotEquals(original, other);
+
+ other.putValue("3", "3value");
+ assertEquals(original, other);
+
+ other.putValue("3", "otherValue");
+ assertNotEquals(original, other);
+
+ other.putValue("3", null);
+ assertNotEquals(original, other);
+
+ other.putValue("3", "3value");
+ assertEquals(original, other);
+ }
+
+ @Test
+ public void testAsMap() throws Exception {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+
+ final Map<String, Object> expected = new HashMap<>();
+ expected.put("a", "avalue");
+ expected.put("B", "Bvalue");
+ expected.put("3", "3value");
+
+ assertEquals(expected, original.asMap());
+ }
+
+ @Test
+ public void testGetCopyDelegatesToAsMap() throws Exception {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.putValue("a", "avalue");
+ assertEquals(original.getCopy(), original.asMap());
+
+ original.putValue("B", "Bvalue");
+ assertEquals(original.getCopy(), original.asMap());
+
+ original.putValue("3", "3value");
+ assertEquals(original.getCopy(), original.asMap());
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testGetImmutableMapOrNull() throws Exception {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.putValue("a", "avalue");
+ assertEquals(original.getImmutableMapOrNull(), original.asMap());
+
+ original.putValue("B", "Bvalue");
+ assertEquals(original.getImmutableMapOrNull(), original.asMap());
+
+ original.putValue("3", "3value");
+ assertEquals(original.getImmutableMapOrNull(), original.asMap());
+
+ try {
+ original.getImmutableMapOrNull().put("abc", "xyz");
+ fail("Expected map to be immutable");
+ } catch (final UnsupportedOperationException ok) {
+ //ok
+ }
+ }
+
+ @Test
+ public void testPutInsertsInAlphabeticOrder() throws Exception {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.put("a", "avalue");
+ original.put("B", "Bvalue");
+ original.put("3", "3value");
+ original.put("c", "cvalue");
+ original.put("d", "dvalue");
+
+ assertEquals("avalue", original.getValue("a"));
+ assertEquals("Bvalue", original.getValue("B"));
+ assertEquals("3value", original.getValue("3"));
+ assertEquals("cvalue", original.getValue("c"));
+ assertEquals("dvalue", original.getValue("d"));
+ }
+
+ @Test
+ public void testPutValueInsertsInAlphabeticOrder() throws Exception {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+ original.putValue("c", "cvalue");
+ original.putValue("d", "dvalue");
+
+ assertEquals("avalue", original.getValue("a"));
+ assertEquals("Bvalue", original.getValue("B"));
+ assertEquals("3value", original.getValue("3"));
+ assertEquals("cvalue", original.getValue("c"));
+ assertEquals("dvalue", original.getValue("d"));
+ }
+
+ @Test
+ public void testNullKeysAllowed() {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+ original.putValue("c", "cvalue");
+ original.putValue("d", "dvalue");
+ assertEquals(5, original.size());
+ assertEquals("{B=Bvalue, a=avalue, 3=3value, d=dvalue, c=cvalue}", original.toString());
+
+ original.putValue(null, "nullvalue");
+ assertEquals(6, original.size());
+ assertEquals("{null=nullvalue, B=Bvalue, a=avalue, 3=3value, d=dvalue, c=cvalue}", original.toString());
+
+ original.putValue(null, "otherNullvalue");
+ assertEquals("{null=otherNullvalue, B=Bvalue, a=avalue, 3=3value, d=dvalue, c=cvalue}", original.toString());
+ assertEquals(6, original.size());
+
+ original.putValue(null, "nullvalue");
+ assertEquals(6, original.size());
+ assertEquals("{null=nullvalue, B=Bvalue, a=avalue, 3=3value, d=dvalue, c=cvalue}", original.toString());
+
+ original.putValue(null, "abc");
+ assertEquals(6, original.size());
+ assertEquals("{null=abc, B=Bvalue, a=avalue, 3=3value, d=dvalue, c=cvalue}", original.toString());
+ }
+
+ @Test
+ public void testNullKeysCopiedToAsMap() {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+ original.putValue("c", "cvalue");
+ original.putValue("d", "dvalue");
+ assertEquals(5, original.size());
+
+ HashMap<String, String> expected = new HashMap<>();
+ expected.put("a", "avalue");
+ expected.put("B", "Bvalue");
+ expected.put("3", "3value");
+ expected.put("c", "cvalue");
+ expected.put("d", "dvalue");
+ assertEquals("initial", expected, original.asMap());
+
+ original.putValue(null, "nullvalue");
+ expected.put(null, "nullvalue");
+ assertEquals(6, original.size());
+ assertEquals("with null key", expected, original.asMap());
+
+ original.putValue(null, "otherNullvalue");
+ expected.put(null, "otherNullvalue");
+ assertEquals(6, original.size());
+ assertEquals("with null key value2", expected, original.asMap());
+
+ original.putValue(null, "nullvalue");
+ expected.put(null, "nullvalue");
+ assertEquals(6, original.size());
+ assertEquals("with null key value1 again", expected, original.asMap());
+
+ original.putValue(null, "abc");
+ expected.put(null, "abc");
+ assertEquals(6, original.size());
+ assertEquals("with null key value3", expected, original.asMap());
+ }
+
+ @Test
+ public void testRemove() {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.putValue("a", "avalue");
+ assertEquals(1, original.size());
+ assertEquals("avalue", original.getValue("a"));
+
+ original.remove("a");
+ assertEquals(0, original.size());
+ assertNull("no a val", original.getValue("a"));
+
+ original.remove("B");
+ assertEquals(0, original.size());
+ assertNull("no B val", original.getValue("B"));
+ }
+
+ @Test
+ public void testNullValuesArePreserved() {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.putValue("a", "avalue");
+ assertEquals(1, original.size());
+ assertEquals("avalue", original.getValue("a"));
+
+ original.putValue("a", null);
+ assertEquals(1, original.size());
+ assertNull("no a val", original.getValue("a"));
+
+ original.putValue("B", null);
+ assertEquals(2, original.size());
+ assertNull("no B val", original.getValue("B"));
+ }
+
+ @Test
+ public void testGet() throws Exception {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.put("a", "avalue");
+ original.put("B", "Bvalue");
+ original.put("3", "3value");
+
+ assertEquals("avalue", original.get("a"));
+ assertEquals("Bvalue", original.get("B"));
+ assertEquals("3value", original.get("3"));
+
+ original.putValue("0", "0value");
+ assertEquals("0value", original.get("0"));
+ assertEquals("3value", original.get("3"));
+ assertEquals("Bvalue", original.get("B"));
+ assertEquals("avalue", original.get("a"));
+ }
+
+ @Test
+ public void testGetValue_GetValueAt() throws Exception {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+
+ assertEquals("avalue", original.getValue("a"));
+ assertEquals("Bvalue", original.getValue("B"));
+ assertEquals("3value", original.getValue("3"));
+ original.putValue("0", "0value");
+ assertEquals("0value", original.getValue("0"));
+ assertEquals("3value", original.getValue("3"));
+ assertEquals("Bvalue", original.getValue("B"));
+ assertEquals("avalue", original.getValue("a"));
+ }
+
+ @Test
+ public void testClear() throws Exception {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ original.putValue("a", "avalue");
+ original.putValue("B", "Bvalue");
+ original.putValue("3", "3value");
+ assertEquals(3, original.size());
+
+ original.clear();
+ assertEquals(0, original.size());
+
+ // ensure slots in the values array are nulled out
+ Field f = OpenHashMapContextData.class.getDeclaredField("values");
+ f.setAccessible(true);
+ Object[] values = (Object[]) f.get(original);
+ for (int i = 0; i < values.length; i++) {
+ assertNull(values[i]);
+ }
+ }
+
+ @Test
+ public void testContainsKey() throws Exception {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ assertFalse("a", original.containsKey("a"));
+ assertFalse("B", original.containsKey("B"));
+ assertFalse("3", original.containsKey("3"));
+ assertFalse("A", original.containsKey("A"));
+
+ original.putValue("a", "avalue");
+ assertTrue("a", original.containsKey("a"));
+ assertFalse("B", original.containsKey("B"));
+ assertFalse("3", original.containsKey("3"));
+ assertFalse("A", original.containsKey("A"));
+
+ original.putValue("B", "Bvalue");
+ assertTrue("a", original.containsKey("a"));
+ assertTrue("B", original.containsKey("B"));
+ assertFalse("3", original.containsKey("3"));
+ assertFalse("A", original.containsKey("A"));
+
+ original.putValue("3", "3value");
+ assertTrue("a", original.containsKey("a"));
+ assertTrue("B", original.containsKey("B"));
+ assertTrue("3", original.containsKey("3"));
+ assertFalse("A", original.containsKey("A"));
+
+ original.putValue("A", "AAA");
+ assertTrue("a", original.containsKey("a"));
+ assertTrue("B", original.containsKey("B"));
+ assertTrue("3", original.containsKey("3"));
+ assertTrue("A", original.containsKey("A"));
+ }
+
+ @Test
+ public void testSizeAndIsEmpty() throws Exception {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ assertEquals(0, original.size());
+ assertTrue("initial", original.isEmpty());
+
+ original.putValue("a", "avalue");
+ assertEquals(1, original.size());
+ assertFalse("size=" + original.size(), original.isEmpty());
+
+ original.putValue("B", "Bvalue");
+ assertEquals(2, original.size());
+ assertFalse("size=" + original.size(), original.isEmpty());
+
+ original.putValue("3", "3value");
+ assertEquals(3, original.size());
+ assertFalse("size=" + original.size(), original.isEmpty());
+
+ original.remove("B");
+ assertEquals(2, original.size());
+ assertFalse("size=" + original.size(), original.isEmpty());
+
+ original.remove("3");
+ assertEquals(1, original.size());
+ assertFalse("size=" + original.size(), original.isEmpty());
+
+ original.remove("a");
+ assertEquals(0, original.size());
+ assertTrue("size=" + original.size(), original.isEmpty());
+ }
+
+ @Test
+ public void testForEachBiConsumer() throws Exception {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ final List<String> keys = new ArrayList<>(Arrays.asList("a", "B", "3", null));
+ final List<String> values = new ArrayList<>(Arrays.asList("aValue", "Bvalue", "3Value", "nullValue"));
+ for (int i = 0; i < keys.size(); i++) {
+ original.put(keys.get(i), values.get(i));
+ }
+
+ original.forEach(new BiConsumer<String, String>() {
+ int count = 0;
+ @Override
+ public void accept(final String key, final String value) {
+ assertTrue("key exists", keys.remove(key));
+ assertTrue("val exists", values.remove(value));
+ assertEquals("val", value, original.getValue(key));
+ count++;
+ assertTrue("count should not exceed size but was " + count, count <= original.size());
+ }
+ });
+ }
+
+ static class State<K, V> {
+ OpenHashMapContextData data;
+ int count;
+ List<K> keys;
+ List<V> values;
+ }
+ private static TriConsumer<String, String, State> COUNTER = new TriConsumer<String, String, State>() {
+ @Override
+ public void accept(final String key, final String value, final State state) {
+ assertTrue("key exists", state.keys.remove(key));
+ assertTrue("val exists", state.values.remove(value));
+ assertEquals("val", value, state.data.getValue(key));
+ state.count++;
+ assertTrue("count should not exceed size but was " + state.count,
+ state.count <= state.data.size());
+ }
+ };
+
+ @Test
+ public void testForEachTriConsumer() throws Exception {
+ final OpenHashMapContextData original = new OpenHashMapContextData();
+ final List<String> keys = Arrays.asList("a", "B", "3", null);
+ final List<String> values = Arrays.asList("aValue", "Bvalue", "3Value", "nullValue");
+ for (int i = 0; i < keys.size(); i++) {
+ original.put(keys.get(i), values.get(i));
+ }
+ final State state = new State();
+ state.data = original;
+ state.keys = new ArrayList(keys);
+ state.values = new ArrayList(values);
+
+ original.forEach(COUNTER, state);
+ assertEquals(state.count, original.size());
+ assertTrue("all keys", state.keys.isEmpty());
+ assertTrue("all values", state.values.isEmpty());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractLogEvent.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractLogEvent.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractLogEvent.java
index d2a3b0a..01b2883 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractLogEvent.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractLogEvent.java
@@ -25,6 +25,7 @@ import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.ThreadContext.ContextStack;
import org.apache.logging.log4j.core.impl.ThrowableProxy;
import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.spi.ContextData;
/**
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/ContextData.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/ContextData.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/ContextData.java
deleted file mode 100644
index 9c50255..0000000
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/ContextData.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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.core;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import org.apache.logging.log4j.core.util.BiConsumer;
-import org.apache.logging.log4j.core.util.TriConsumer;
-
-/**
- * A read-only collection of context data. Context data items are String keys and values of arbitrary type that are
- * set by the application to be included in all subsequent log events. A typical source of context data is the
- * {@code ThreadContextMap} and the {@code Properties} defined in the configuration.
- * <p>
- * Applications can put custom data in this collection by installing a custom {@code ContextDataInjector}.
- * </p>
- *
- * @see org.apache.logging.log4j.spi.ThreadContextMap
- * @see org.apache.logging.log4j.core.config.Property
- * @see org.apache.logging.log4j.core.impl.ContextDataInjector
- * @see org.apache.logging.log4j.core.impl.ContextDataInjectorFactory
- * @since 2.7
- */
-public interface ContextData extends Serializable {
- /**
- * Returns a map view of this context data.
- * Called to implement {@link LogEvent#getContextMap()}.
- *
- * @return a map view of this context data
- */
- Map<String, String> asMap();
-
- /**
- * Returns {@code true} if this context data contains the specified key, {@code false} otherwise.
- *
- * @param key the key whose presence to check. May be {@code null}.
- * @return {@code true} if this context data contains the specified key, {@code false} otherwise
- */
- boolean containsKey(String key);
-
- /**
- * Performs the given action for each key-value pair in this data structure
- * until all entries have been processed or the action throws an exception.
- * <p>
- * Some implementations may not support structural modifications (adding new elements or removing elements) while
- * iterating over the contents. In such implementations, attempts to add or remove elements from the
- * {@code BiConsumer}'s {@link BiConsumer#accept(Object, Object)} accept} method may cause a
- * {@code ConcurrentModificationException} to be thrown.
- * </p>
- *
- * @param action The action to be performed for each key-value pair in this collection
- * @param <V> type of the value
- * @throws java.util.ConcurrentModificationException some implementations may not support structural modifications
- * to this context data while iterating over the contents with {@link #forEach(BiConsumer)} or
- * {@link #forEach(TriConsumer, Object)}.
- */
- <V> void forEach(final BiConsumer<String, ? super V> action);
-
- /**
- * Performs the given action for each key-value pair in this data structure
- * until all entries have been processed or the action throws an exception.
- * <p>
- * The third parameter lets callers pass in a stateful object to be modified with the key-value pairs,
- * so the TriConsumer implementation itself can be stateless and potentially reusable.
- * </p>
- * <p>
- * Some implementations may not support structural modifications (adding new elements or removing elements) while
- * iterating over the contents. In such implementations, attempts to add or remove elements from the
- * {@code TriConsumer}'s {@link TriConsumer#accept(Object, Object, Object) accept} method may cause a
- * {@code ConcurrentModificationException} to be thrown.
- * </p>
- *
- * @param action The action to be performed for each key-value pair in this collection
- * @param state the object to be passed as the third parameter to each invocation on the specified
- * triconsumer
- * @param <V> type of the value
- * @param <S> type of the third parameter
- * @throws java.util.ConcurrentModificationException some implementations may not support structural modifications
- * to this context data while iterating over the contents with {@link #forEach(BiConsumer)} or
- * {@link #forEach(TriConsumer, Object)}.
- */
- <V, S> void forEach(final TriConsumer<String, ? super V, S> action, final S state);
-
- /**
- * Returns the 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
- * @return the value for the specified key or {@code null}
- */
- <V> V getValue(final String key);
-
- /**
- * Returns {@code true} if this collection is empty (size is zero), {@code false} otherwise.
- * @return {@code true} if this collection is empty (size is zero)
- */
- boolean isEmpty();
-
- /**
- * Returns the number of key-value pairs in this collection.
- *
- * @return the number of key-value pairs in this collection
- */
- int size();
-}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/LogEvent.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/LogEvent.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/LogEvent.java
index 20b2c3a..872793d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/LogEvent.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/LogEvent.java
@@ -25,6 +25,7 @@ import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.impl.ThrowableProxy;
import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.spi.ContextData;
/**
* Provides contextual information about a logged message. A LogEvent must be {@link java.io.Serializable} so that it
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/AbstractLogEventWrapperEntity.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/AbstractLogEventWrapperEntity.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/AbstractLogEventWrapperEntity.java
index 80e1d62..661beab 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/AbstractLogEventWrapperEntity.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/AbstractLogEventWrapperEntity.java
@@ -26,7 +26,7 @@ import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.AbstractLogEvent;
-import org.apache.logging.log4j.core.ContextData;
+import org.apache.logging.log4j.spi.ContextData;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.db.jpa.converter.ContextDataAttributeConverter;
import org.apache.logging.log4j.message.Message;
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataAttributeConverter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataAttributeConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataAttributeConverter.java
index a25fca8..9441ec1 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataAttributeConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataAttributeConverter.java
@@ -19,7 +19,7 @@ package org.apache.logging.log4j.core.appender.db.jpa.converter;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
-import org.apache.logging.log4j.core.ContextData;
+import org.apache.logging.log4j.spi.ContextData;
/**
* A JPA 2.1 attribute converter for {@link ContextData ContextData<Object>}s in
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataJsonAttributeConverter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataJsonAttributeConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataJsonAttributeConverter.java
index 93fe95a..03ae801 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataJsonAttributeConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataJsonAttributeConverter.java
@@ -23,10 +23,10 @@ import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import javax.persistence.PersistenceException;
-import org.apache.logging.log4j.core.ContextData;
+import org.apache.logging.log4j.spi.ContextData;
import org.apache.logging.log4j.core.impl.ContextDataFactory;
-import org.apache.logging.log4j.core.impl.MutableContextData;
-import org.apache.logging.log4j.core.util.BiConsumer;
+import org.apache.logging.log4j.spi.MutableContextData;
+import org.apache.logging.log4j.util.BiConsumer;
import org.apache.logging.log4j.util.Strings;
import com.fasterxml.jackson.databind.JsonNode;
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
index 895def7..c9a0c68 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
@@ -30,7 +30,7 @@ import org.apache.logging.log4j.core.config.ReliabilityStrategy;
import org.apache.logging.log4j.core.impl.ContextDataInjector;
import org.apache.logging.log4j.core.impl.ContextDataInjectorFactory;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.core.impl.MutableContextData;
+import org.apache.logging.log4j.spi.MutableContextData;
import org.apache.logging.log4j.core.util.Clock;
import org.apache.logging.log4j.core.util.ClockFactory;
import org.apache.logging.log4j.core.util.Constants;
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java
index 8c873ff..d20be14 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java
@@ -23,11 +23,11 @@ import java.util.Map;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext.ContextStack;
-import org.apache.logging.log4j.core.ContextData;
+import org.apache.logging.log4j.spi.ContextData;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.impl.ContextDataFactory;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.core.impl.MutableContextData;
+import org.apache.logging.log4j.spi.MutableContextData;
import org.apache.logging.log4j.core.impl.ThrowableProxy;
import org.apache.logging.log4j.core.util.Constants;
import org.apache.logging.log4j.message.Message;
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java
index d95a5b7..04d9ce1 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java
@@ -21,7 +21,7 @@ import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext.ContextStack;
import org.apache.logging.log4j.core.impl.ContextDataInjector;
import org.apache.logging.log4j.core.impl.ContextDataInjectorFactory;
-import org.apache.logging.log4j.core.impl.MutableContextData;
+import org.apache.logging.log4j.spi.MutableContextData;
import org.apache.logging.log4j.message.Message;
import com.lmax.disruptor.EventTranslator;
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ArrayContextData.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ArrayContextData.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ArrayContextData.java
deleted file mode 100644
index a1580a2..0000000
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ArrayContextData.java
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * 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.core.impl;
-
-import java.io.IOException;
-import java.io.InvalidObjectException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-import org.apache.logging.log4j.core.ContextData;
-import org.apache.logging.log4j.core.util.BiConsumer;
-import org.apache.logging.log4j.core.util.Integers;
-import org.apache.logging.log4j.core.util.TriConsumer;
-import org.apache.logging.log4j.spi.ThreadContextMap;
-
-/**
- * Array-based implementation of the {@code ContextData} interface. Keys are held in a sorted array.
- * <p>
- * This is not a generic collection, but makes some trade-offs to optimize for the Log4j ContextData use case:
- * </p>
- * <ul>
- * <li>Garbage-free iteration over key-value pairs with {@code BiConsumer} and {@code TriConsumer}.</li>
- * <li>Fast copy. If the ThreadContextMap is also an instance of {@code ArrayContextData}, the full thread context
- * data can be transferred with two array copies and two field updates.</li>
- * <li>Acceptable performance for small data sets. The current implementation stores keys in a sorted array, values
- * are stored in a separate array at the same index.
- * Worst-case performance of {@code get} and {@code containsKey} is O(log N),
- * worst-case performance of {@code put} and {@code remove} is O(N log N).
- * The expectation is that for the small values of {@code N} (less than 100) that are the vast majority of
- * ThreadContext use cases, the constants dominate performance more than the asymptotic performance of the
- * algorithms used.
- * </li>
- * <li>Compact representation.</li>
- * </ul>
- *
- * @see ThreadContextDataInjector
- * @since 2.7
- */
-public class ArrayContextData implements MutableContextData, ThreadContextMap {
-
- /**
- * The default initial capacity.
- */
- private static final int DEFAULT_INITIAL_CAPACITY = 4;
- private static final long serialVersionUID = -5748905872274478116L;
- private static final int HASHVAL = 31;
-
- private static final TriConsumer<String, Object, MutableContextData> PUT_ALL = new TriConsumer<String, Object, MutableContextData>() {
- @Override
- public void accept(final String key, final Object value, final MutableContextData contextData) {
- contextData.putValue(key, value);
- }
- };
-
- /**
- * An empty array instance to share when the table is not inflated.
- */
- private static final String[] EMPTY = {};
-
- private transient String[] keys = EMPTY;
- private transient Object[] values = EMPTY;
-
- /**
- * The number of key-value mappings contained in this map.
- */
- private transient int size;
-
- /**
- * The next size value at which to resize (capacity * load factor).
- * @serial
- */
- // If table == EMPTY_TABLE then this is the initial capacity at which the
- // table will be created when inflated.
- private int threshold;
-
- public ArrayContextData() {
- this(DEFAULT_INITIAL_CAPACITY);
- }
-
- public ArrayContextData(final int initialCapacity) {
- if (initialCapacity < 1) {
- throw new IllegalArgumentException("Initial capacity must be at least one but was " + initialCapacity);
- }
- threshold = Integers.ceilingNextPowerOfTwo(initialCapacity);
- }
-
- public ArrayContextData(final ContextData other) {
- if (other instanceof ArrayContextData) {
- initFrom0((ArrayContextData) other);
- } else if (other != null) {
- resize(Integers.ceilingNextPowerOfTwo(other.size()));
- other.forEach(PUT_ALL, this);
- }
- }
-
- @Override
- public void clear() {
- Arrays.fill(keys, 0, size, null);
- Arrays.fill(values, 0, size, null);
- size = 0;
- }
-
- @Override
- public boolean containsKey(final String key) {
- return indexOfKey(key) >= 0;
- }
-
- @Override
- public Map<String, String> asMap() {
- final Map<String, String> result = new HashMap<>(size());
- for (int i = 0; i < size(); i++) {
- final Object value = getValueAt(i);
- result.put(getKeyAt(i), value == null ? null : String.valueOf(value));
- }
- return result;
- }
-
- @Override
- public Map<String, String> getCopy() {
- return asMap();
- }
-
- @Override
- public Map<String, String> getImmutableMapOrNull() {
- return isEmpty() ? null : Collections.unmodifiableMap(asMap());
- }
-
- @Override
- public String get(final String key) {
- final Object result = getValue(key);
- return result == null ? null : String.valueOf(result);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public <V> V getValue(final String key) {
- final int index = indexOfKey(key);
- if (index < 0) {
- return null;
- }
- return (V) values[index];
- }
-
- @Override
- public boolean isEmpty() {
- return size == 0;
- }
-
- int indexOfKey(final String key) {
- if (keys == EMPTY) {
- return -1;
- }
- if (key == null) { // null key is located at the start of the array
- return nullKeyIndex(); // insert at index zero
- }
- final int start = size > 0 && keys[0] == null ? 1 : 0;
- return Arrays.binarySearch(keys, start, size, key);
- }
-
- private int nullKeyIndex() {
- return size > 0 && keys[0] == null ? 0 : ~0;
- }
-
- @Override
- public void put(final String key, final String value) {
- putValue(key, value);
- }
-
- @Override
- public void putValue(final String key, final Object value) {
- if (keys == EMPTY) {
- inflateTable(threshold);
- }
- final int index = indexOfKey(key);
- if (index >= 0) {
- keys[index] = key;
- values[index] = value;
- } else { // not found, so insert.
- insertAt(~index, key, value);
- }
- }
-
- private void insertAt(final int index, final String key, final Object value) {
- ensureCapacity();
- System.arraycopy(keys, index, keys, index + 1, size - index);
- System.arraycopy(values, index, values, index + 1, size - index);
- keys[index] = key;
- values[index] = value;
- size++;
- }
-
- @Override
- public void putAll(final ContextData source) {
- if (source instanceof ArrayContextData) {
- initFrom0((ArrayContextData) source);
- } else if (source != null) {
- source.forEach(PUT_ALL, this);
- }
- }
-
- public void initFrom(final ArrayContextData other) {
- initFrom0(other);
- }
-
- private void initFrom0(final ArrayContextData other) {
- if (keys.length < other.size) {
- keys = new String[other.threshold];
- values = new Object[other.threshold];
- }
- System.arraycopy(other.keys, 0, keys, 0, other.size);
- System.arraycopy(other.values, 0, values, 0, other.size);
-
- size = other.size;
- threshold = other.threshold;
- }
-
- private void ensureCapacity() {
- if (size >= threshold) {
- resize(threshold * 2);
- }
- }
-
- private void resize(final int newCapacity) {
- final String[] oldKeys = keys;
- final Object[] oldValues = values;
-
- keys = new String[newCapacity];
- values = new Object[newCapacity];
-
- System.arraycopy(oldKeys, 0, keys, 0, size);
- System.arraycopy(oldValues, 0, values, 0, size);
-
- threshold = newCapacity;
- }
-
- /**
- * Inflates the table.
- */
- private void inflateTable(int toSize) {
- threshold = toSize;
- keys = new String[toSize];
- values = new Object[toSize];
- }
-
- @Override
- public void remove(final String key) {
- if (keys == EMPTY) {
- return;
- }
- final int index = indexOfKey(key);
- if (index >= 0) {
- System.arraycopy(keys, index + 1, keys, index, size - index);
- System.arraycopy(values, index + 1, values, index, size - index);
- size--;
- }
- }
-
- String getKeyAt(final int index) {
- if (index < 0 || index >= size) {
- return null;
- }
- return keys[index];
- }
-
- @SuppressWarnings("unchecked")
- <V> V getValueAt(final int index) {
- if (index < 0 || index >= size) {
- return null;
- }
- return (V) values[index];
- }
-
- @Override
- public int size() {
- return size;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public <V> void forEach(BiConsumer<String, ? super V> action) {
- for (int i = 0; i < size; i++) {
- action.accept(keys[i], (V) values[i]);
- }
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public <V, T> void forEach(TriConsumer<String, ? super V, T> action, T state) {
- for (int i = 0; i < size; i++) {
- action.accept(keys[i], (V) values[i], state);
- }
- }
-
- @Override
- public boolean equals(final Object obj) {
- if (obj == this) {
- return true;
- }
- if (!(obj instanceof ArrayContextData)) {
- return false;
- }
- ArrayContextData other = (ArrayContextData) obj;
- if (this.size() != other.size()) {
- return false;
- }
- for (int i = 0; i < size(); i++) {
- if (!Objects.equals(keys[i], other.keys[i])) {
- return false;
- }
- if (!Objects.equals(values[i], other.values[i])) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = 37;
- result = HASHVAL * result + size;
- result = HASHVAL * result + hashCode(keys, size);
- result = HASHVAL * result + hashCode(values, size);
- return result;
- }
-
- private static int hashCode(Object[] values, int length) {
- int result = 1;
- for (int i = 0; i < length; i++) {
- result = HASHVAL * result + (values[i] == null ? 0 : values[i].hashCode());
- }
- return result;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder(256);
- sb.append('{');
- for (int i = 0; i < size; i++) {
- if (i > 0) {
- sb.append(", ");
- }
- sb.append(keys[i]).append('=');
- sb.append(values[i] == this ? "(this map)" : values[i]);
- }
- sb.append('}');
- return sb.toString();
- }
-
- /**
- * Save the state of the {@code ArrayContextData} instance to a stream (i.e.,
- * serialize it).
- *
- * @serialData The <i>capacity</i> of the ArrayContextData (the length of the
- * bucket array) is emitted (int), followed by the
- * <i>size</i> (an int, the number of key-value
- * mappings), followed by the key (Object) and value (Object)
- * for each key-value mapping. The key-value mappings are
- * emitted in no particular order.
- */
- private void writeObject(java.io.ObjectOutputStream s) throws IOException {
- // Write out the threshold, and any hidden stuff
- s.defaultWriteObject();
-
- // Write out number of buckets
- if (keys == EMPTY) {
- s.writeInt(Integers.ceilingNextPowerOfTwo(threshold));
- } else {
- s.writeInt(keys.length);
- }
-
- // Write out size (number of Mappings)
- s.writeInt(size);
-
- // Write out keys and values (alternating)
- if (size > 0) {
- for (int i = 0; i < size; i++) {
- s.writeObject(keys[i]);
- s.writeObject(values[i]);
- }
- }
- }
-
- /**
- * Reconstitute the {@code ArrayContextData} instance from a stream (i.e.,
- * deserialize it).
- */
- private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
- // Read in the threshold (ignored), and any hidden stuff
- s.defaultReadObject();
-
- // set other fields that need values
- keys = EMPTY;
- values = EMPTY;
-
- // Read in number of buckets
- int capacity = s.readInt();
- if (capacity < 0) {
- throw new InvalidObjectException("Illegal capacity: " + capacity);
- }
-
- // Read number of mappings
- int mappings = s.readInt();
- if (mappings < 0) {
- throw new InvalidObjectException("Illegal mappings count: " + mappings);
- }
-
- // allocate the bucket array;
- if (mappings > 0) {
- inflateTable(capacity);
- } else {
- threshold = capacity;
- }
-
- // Read the keys and values, and put the mappings in the arrays
- for (int i = 0; i < mappings; i++) {
- keys[i] = (String) s.readObject();
- values[i] = s.readObject();
- }
- size = mappings;
- }
-}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataFactory.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataFactory.java
index 6cf5ad1..340298a 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataFactory.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataFactory.java
@@ -16,6 +16,9 @@
*/
package org.apache.logging.log4j.core.impl;
+import org.apache.logging.log4j.spi.ArrayContextData;
+import org.apache.logging.log4j.spi.MutableContextData;
+import org.apache.logging.log4j.spi.OpenHashMapContextData;
import org.apache.logging.log4j.util.PropertiesUtil;
/**
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataInjector.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataInjector.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataInjector.java
index 5b74968..0c77b9c 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataInjector.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataInjector.java
@@ -19,6 +19,8 @@ package org.apache.logging.log4j.core.impl;
import java.util.List;
import org.apache.logging.log4j.core.config.Property;
+import org.apache.logging.log4j.spi.ContextData;
+import org.apache.logging.log4j.spi.MutableContextData;
/**
* Responsible for initializing the ContextData of LogEvents. Context data is data that is set by the application to be
@@ -32,6 +34,7 @@ import org.apache.logging.log4j.core.config.Property;
* any arbitrary context.
* </p>
*
+ * @see ContextData
* @see ContextDataInjectorFactory
* @see org.apache.logging.log4j.core.ContextData
* @see org.apache.logging.log4j.ThreadContext
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataInjectorFactory.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataInjectorFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataInjectorFactory.java
index ac5c38c..51b17cd 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataInjectorFactory.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ContextDataInjectorFactory.java
@@ -18,6 +18,7 @@ package org.apache.logging.log4j.core.impl;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.spi.ContextData;
import org.apache.logging.log4j.spi.ThreadContextMap;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.LoaderUtil;
@@ -31,6 +32,7 @@ import org.apache.logging.log4j.util.PropertiesUtil;
* {@code ThreadContextDataInjector}.
*
* @see ContextDataInjector
+ * @see ContextData
* @see ThreadContextDataInjector
* @see org.apache.logging.log4j.core.ContextData
* @see LogEvent#getContextData()
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java
index 81af731..e45a405 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java
@@ -26,7 +26,8 @@ import java.util.Objects;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.core.ContextData;
+import org.apache.logging.log4j.spi.ArrayContextData;
+import org.apache.logging.log4j.spi.ContextData;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.async.RingBufferLogEvent;
import org.apache.logging.log4j.core.config.LoggerConfig;
@@ -40,6 +41,7 @@ import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.ReusableMessage;
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.message.TimestampMessage;
+import org.apache.logging.log4j.spi.MutableContextData;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.Strings;
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableContextData.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableContextData.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableContextData.java
deleted file mode 100644
index 739f043..0000000
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableContextData.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.core.impl;
-
-import org.apache.logging.log4j.core.ContextData;
-import org.apache.logging.log4j.core.util.BiConsumer;
-import org.apache.logging.log4j.core.util.TriConsumer;
-
-/**
- * Exposes methods to add and remove key-value pairs to and from {@code ContextData}.
- *
- * @see ContextData
- * @since 2.7
- */
-public interface MutableContextData extends ContextData {
-
- /**
- * Removes all key-value pairs from this collection.
- * @throws java.util.ConcurrentModificationException some implementations may not support structural modifications
- * to this context data while iterating over the contents with {@link #forEach(BiConsumer)} or
- * {@link #forEach(TriConsumer, Object)}.
- */
- void clear();
-
- /**
- * Puts the specified key-value pair into the collection.
- *
- * @param key the key to add or remove. Keys may be {@code null}.
- * @param value the value to add. Values may be {@code null}.
- * @throws java.util.ConcurrentModificationException some implementations may not support structural modifications
- * to this context data while iterating over the contents with {@link #forEach(BiConsumer)} or
- * {@link #forEach(TriConsumer, Object)}.
- */
- void putValue(final String key, final Object value);
-
- /**
- * Copy all key-value pairs from the specified {@code ContextData} into this {@code MutableContextData}.
- * @param source the {@code ContextData} to copy key-value pairs from
- * @throws java.util.ConcurrentModificationException some implementations may not support structural modifications
- * to this context data while iterating over the contents with {@link #forEach(BiConsumer)} or
- * {@link #forEach(TriConsumer, Object)}.
- */
- void putAll(final ContextData source);
-
- /**
- * Removes the key-value pair for the specified key from this context data collection.
- *
- * @param key the key to remove. May be {@code null}.
- * @throws java.util.ConcurrentModificationException some implementations may not support structural modifications
- * to this context data while iterating over the contents with {@link #forEach(BiConsumer)} or
- * {@link #forEach(TriConsumer, Object)}.
- */
- void remove(final String key);
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableLogEvent.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableLogEvent.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableLogEvent.java
index 08423c6..bcdc40d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableLogEvent.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableLogEvent.java
@@ -24,13 +24,14 @@ import java.util.Map;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.core.ContextData;
+import org.apache.logging.log4j.spi.ContextData;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.util.Constants;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.ParameterizedMessage;
import org.apache.logging.log4j.message.ReusableMessage;
import org.apache.logging.log4j.message.SimpleMessage;
+import org.apache.logging.log4j.spi.MutableContextData;
import org.apache.logging.log4j.util.Strings;
/**