1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.impl;
18
19 import java.lang.invoke.MethodHandle;
20 import java.lang.invoke.MethodHandles;
21 import java.lang.invoke.MethodType;
22 import java.util.Map;
23 import java.util.Map.Entry;
24
25 import org.apache.logging.log4j.core.ContextDataInjector;
26 import org.apache.logging.log4j.core.LogEvent;
27 import org.apache.logging.log4j.core.util.Loader;
28 import org.apache.logging.log4j.util.IndexedStringMap;
29 import org.apache.logging.log4j.util.PropertiesUtil;
30 import org.apache.logging.log4j.util.ReadOnlyStringMap;
31 import org.apache.logging.log4j.util.SortedArrayStringMap;
32 import org.apache.logging.log4j.util.StringMap;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 public class ContextDataFactory {
51 private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
52 private static final String CLASS_NAME = PropertiesUtil.getProperties().getStringProperty("log4j2.ContextData");
53 private static final Class<? extends StringMap> CACHED_CLASS = createCachedClass(CLASS_NAME);
54 private static final MethodHandle DEFAULT_CONSTRUCTOR = createDefaultConstructor(CACHED_CLASS);
55 private static final MethodHandle INITIAL_CAPACITY_CONSTRUCTOR = createInitialCapacityConstructor(CACHED_CLASS);
56
57 private static final StringMap EMPTY_STRING_MAP = createContextData(0);
58
59 static {
60 EMPTY_STRING_MAP.freeze();
61 }
62
63 private static Class<? extends StringMap> createCachedClass(final String className) {
64 if (className == null) {
65 return null;
66 }
67 try {
68 return Loader.loadClass(className).asSubclass(IndexedStringMap.class);
69 } catch (final Exception any) {
70 return null;
71 }
72 }
73
74 private static MethodHandle createDefaultConstructor(final Class<? extends StringMap> cachedClass) {
75 if (cachedClass == null) {
76 return null;
77 }
78 try {
79 return LOOKUP.findConstructor(cachedClass, MethodType.methodType(void.class));
80 } catch (final NoSuchMethodException | IllegalAccessException ignored) {
81 return null;
82 }
83 }
84
85 private static MethodHandle createInitialCapacityConstructor(final Class<? extends StringMap> cachedClass) {
86 if (cachedClass == null) {
87 return null;
88 }
89 try {
90 return LOOKUP.findConstructor(cachedClass, MethodType.methodType(void.class, int.class));
91 } catch (final NoSuchMethodException | IllegalAccessException ignored) {
92 return null;
93 }
94 }
95
96 public static StringMap createContextData() {
97 if (DEFAULT_CONSTRUCTOR == null) {
98 return new SortedArrayStringMap();
99 }
100 try {
101 return (IndexedStringMap) DEFAULT_CONSTRUCTOR.invoke();
102 } catch (final Throwable ignored) {
103 return new SortedArrayStringMap();
104 }
105 }
106
107 public static StringMap createContextData(final int initialCapacity) {
108 if (INITIAL_CAPACITY_CONSTRUCTOR == null) {
109 return new SortedArrayStringMap(initialCapacity);
110 }
111 try {
112 return (IndexedStringMap) INITIAL_CAPACITY_CONSTRUCTOR.invoke(initialCapacity);
113 } catch (final Throwable ignored) {
114 return new SortedArrayStringMap(initialCapacity);
115 }
116 }
117
118 public static StringMap createContextData(final Map<String, String> context) {
119 final StringMap contextData = createContextData(context.size());
120 for (final Entry<String, String> entry : context.entrySet()) {
121 contextData.putValue(entry.getKey(), entry.getValue());
122 }
123 return contextData;
124 }
125
126 public static StringMap createContextData(final ReadOnlyStringMap readOnlyStringMap) {
127 final StringMap contextData = createContextData(readOnlyStringMap.size());
128 contextData.putAll(readOnlyStringMap);
129 return contextData;
130 }
131
132
133
134
135
136
137 public static StringMap emptyFrozenContextData() {
138 return EMPTY_STRING_MAP;
139 }
140
141 }