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.ArrayList;
20 import java.util.Collection;
21 import java.util.Map;
22 import java.util.Objects;
23 import java.util.WeakHashMap;
24 import java.util.concurrent.ConcurrentHashMap;
25 import java.util.concurrent.ConcurrentMap;
26
27 import org.apache.logging.log4j.message.MessageFactory;
28
29
30
31
32 public class LoggerRegistry<T extends ExtendedLogger> {
33 private static final String DEFAULT_FACTORY_KEY = AbstractLogger.DEFAULT_MESSAGE_FACTORY_CLASS.getName();
34 private final MapFactory<T> factory;
35 private final Map<String, Map<String, T>> map;
36
37
38
39
40
41 public interface MapFactory<T extends ExtendedLogger> {
42 Map<String, T> createInnerMap();
43
44 Map<String, Map<String, T>> createOuterMap();
45
46 void putIfAbsent(Map<String, T> innerMap, String name, T logger);
47 }
48
49
50
51
52
53 public static class ConcurrentMapFactory<T extends ExtendedLogger> implements MapFactory<T> {
54 @Override
55 public Map<String, T> createInnerMap() {
56 return new ConcurrentHashMap<>();
57 }
58
59 @Override
60 public Map<String, Map<String, T>> createOuterMap() {
61 return new ConcurrentHashMap<>();
62 }
63
64 @Override
65 public void putIfAbsent(final Map<String, T> innerMap, final String name, final T logger) {
66 ((ConcurrentMap<String, T>) innerMap).putIfAbsent(name, logger);
67 }
68 }
69
70
71
72
73
74 public static class WeakMapFactory<T extends ExtendedLogger> implements MapFactory<T> {
75 @Override
76 public Map<String, T> createInnerMap() {
77 return new WeakHashMap<>();
78 }
79
80 @Override
81 public Map<String, Map<String, T>> createOuterMap() {
82 return new WeakHashMap<>();
83 }
84
85 @Override
86 public void putIfAbsent(final Map<String, T> innerMap, final String name, final T logger) {
87 innerMap.put(name, logger);
88 }
89 }
90
91 public LoggerRegistry() {
92 this(new ConcurrentMapFactory<T>());
93 }
94
95 public LoggerRegistry(final MapFactory<T> factory) {
96 this.factory = Objects.requireNonNull(factory, "factory");
97 this.map = factory.createOuterMap();
98 }
99
100 private static String factoryClassKey(final Class<? extends MessageFactory> messageFactoryClass) {
101 return messageFactoryClass == null ? DEFAULT_FACTORY_KEY : messageFactoryClass.getName();
102 }
103
104 private static String factoryKey(final MessageFactory messageFactory) {
105 return messageFactory == null ? DEFAULT_FACTORY_KEY : messageFactory.getClass().getName();
106 }
107
108
109
110
111
112
113 public T getLogger(final String name) {
114 return getOrCreateInnerMap(DEFAULT_FACTORY_KEY).get(name);
115 }
116
117
118
119
120
121
122
123
124 public T getLogger(final String name, final MessageFactory messageFactory) {
125 return getOrCreateInnerMap(factoryKey(messageFactory)).get(name);
126 }
127
128 public Collection<T> getLoggers() {
129 return getLoggers(new ArrayList<T>());
130 }
131
132 public Collection<T> getLoggers(final Collection<T> destination) {
133 for (final Map<String, T> inner : map.values()) {
134 destination.addAll(inner.values());
135 }
136 return destination;
137 }
138
139 private Map<String, T> getOrCreateInnerMap(final String factoryName) {
140 Map<String, T> inner = map.get(factoryName);
141 if (inner == null) {
142 inner = factory.createInnerMap();
143 map.put(factoryName, inner);
144 }
145 return inner;
146 }
147
148
149
150
151
152
153 public boolean hasLogger(final String name) {
154 return getOrCreateInnerMap(DEFAULT_FACTORY_KEY).containsKey(name);
155 }
156
157
158
159
160
161
162
163
164 public boolean hasLogger(final String name, final MessageFactory messageFactory) {
165 return getOrCreateInnerMap(factoryKey(messageFactory)).containsKey(name);
166 }
167
168
169
170
171
172
173
174
175 public boolean hasLogger(final String name, final Class<? extends MessageFactory> messageFactoryClass) {
176 return getOrCreateInnerMap(factoryClassKey(messageFactoryClass)).containsKey(name);
177 }
178
179 public void putIfAbsent(final String name, final MessageFactory messageFactory, final T logger) {
180 factory.putIfAbsent(getOrCreateInnerMap(factoryKey(messageFactory)), name, logger);
181 }
182 }