1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.spi;
18
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.Map;
22
23 import org.apache.logging.log4j.util.PropertiesUtil;
24
25
26
27
28
29
30
31 public class DefaultThreadContextMap implements ThreadContextMap {
32
33
34
35
36 public static final String INHERITABLE_MAP = "isThreadContextMapInheritable";
37
38 private final boolean useMap;
39 private final ThreadLocal<Map<String, String>> localMap;
40
41 public DefaultThreadContextMap(final boolean useMap) {
42 this.useMap = useMap;
43 this.localMap = createThreadLocalMap(useMap);
44 }
45
46
47
48 static ThreadLocal<Map<String, String>> createThreadLocalMap(final boolean isMapEnabled) {
49 final PropertiesUtil managerProps = PropertiesUtil.getProperties();
50 final boolean inheritable = managerProps.getBooleanProperty(INHERITABLE_MAP);
51 if (inheritable) {
52 return new InheritableThreadLocal<Map<String, String>>() {
53 @Override
54 protected Map<String, String> childValue(final Map<String, String> parentValue) {
55 return parentValue != null && isMapEnabled
56 ? Collections.unmodifiableMap(new HashMap<String, String>(parentValue))
57 : null;
58 }
59 };
60 }
61
62 return new ThreadLocal<Map<String, String>>();
63 }
64
65
66
67
68
69
70
71
72
73
74
75 @Override
76 public void put(final String key, final String value) {
77 if (!useMap) {
78 return;
79 }
80 Map<String, String> map = localMap.get();
81 map = map == null ? new HashMap<String, String>() : new HashMap<String, String>(map);
82 map.put(key, value);
83 localMap.set(Collections.unmodifiableMap(map));
84 }
85
86
87
88
89
90
91
92
93 @Override
94 public String get(final String key) {
95 final Map<String, String> map = localMap.get();
96 return map == null ? null : map.get(key);
97 }
98
99
100
101
102
103
104 @Override
105 public void remove(final String key) {
106 final Map<String, String> map = localMap.get();
107 if (map != null) {
108 final Map<String, String> copy = new HashMap<String, String>(map);
109 copy.remove(key);
110 localMap.set(Collections.unmodifiableMap(copy));
111 }
112 }
113
114
115
116
117 @Override
118 public void clear() {
119 localMap.remove();
120 }
121
122
123
124
125
126
127 @Override
128 public boolean containsKey(final String key) {
129 final Map<String, String> map = localMap.get();
130 return map != null && map.containsKey(key);
131 }
132
133
134
135
136
137 @Override
138 public Map<String, String> getCopy() {
139 final Map<String, String> map = localMap.get();
140 return map == null ? new HashMap<String, String>() : new HashMap<String, String>(map);
141 }
142
143
144
145
146
147 @Override
148 public Map<String, String> getImmutableMapOrNull() {
149 return localMap.get();
150 }
151
152
153
154
155
156 @Override
157 public boolean isEmpty() {
158 final Map<String, String> map = localMap.get();
159 return map == null || map.size() == 0;
160 }
161
162 @Override
163 public String toString() {
164 Map<String, String> map = localMap.get();
165 return map == null ? "{}" : map.toString();
166 }
167 }