1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.appender;
18
19 import java.util.HashMap;
20 import java.util.Map;
21 import java.util.concurrent.TimeUnit;
22 import java.util.concurrent.locks.Lock;
23 import java.util.concurrent.locks.ReentrantLock;
24
25 import org.apache.logging.log4j.Level;
26 import org.apache.logging.log4j.Logger;
27 import org.apache.logging.log4j.core.AbstractLifeCycle;
28 import org.apache.logging.log4j.core.LoggerContext;
29 import org.apache.logging.log4j.core.config.ConfigurationException;
30 import org.apache.logging.log4j.message.Message;
31 import org.apache.logging.log4j.status.StatusLogger;
32
33
34
35
36
37
38
39
40
41
42 public abstract class AbstractManager implements AutoCloseable {
43
44
45
46
47 protected static final Logger LOGGER = StatusLogger.getLogger();
48
49
50
51 private static final Map<String, AbstractManager> MAP = new HashMap<>();
52
53 private static final Lock LOCK = new ReentrantLock();
54
55
56
57
58 protected int count;
59
60 private final String name;
61
62 private final LoggerContext loggerContext;
63
64 protected AbstractManager(final LoggerContext loggerContext, final String name) {
65 this.loggerContext = loggerContext;
66 this.name = name;
67 LOGGER.debug("Starting {} {}", this.getClass().getSimpleName(), name);
68 }
69
70
71
72
73 @Override
74 public void close() {
75 stop(AbstractLifeCycle.DEFAULT_STOP_TIMEOUT, AbstractLifeCycle.DEFAULT_STOP_TIMEUNIT);
76 }
77
78 public boolean stop(final long timeout, final TimeUnit timeUnit) {
79 boolean stopped = true;
80 LOCK.lock();
81 try {
82 --count;
83 if (count <= 0) {
84 MAP.remove(name);
85 LOGGER.debug("Shutting down {} {}", this.getClass().getSimpleName(), getName());
86 stopped = releaseSub(timeout, timeUnit);
87 LOGGER.debug("Shut down {} {}, all resources released: {}", this.getClass().getSimpleName(), getName(), stopped);
88 }
89 } finally {
90 LOCK.unlock();
91 }
92 return stopped;
93 }
94
95
96
97
98
99
100
101
102
103
104
105 @SuppressWarnings("resource")
106 public static <M extends AbstractManager, T> M getManager(final String name, final ManagerFactory<M, T> factory,
107 final T data) {
108 LOCK.lock();
109 try {
110 @SuppressWarnings("unchecked")
111 M manager = (M) MAP.get(name);
112 if (manager == null) {
113 manager = factory.createManager(name, data);
114 if (manager == null) {
115 throw new IllegalStateException("ManagerFactory [" + factory + "] unable to create manager for ["
116 + name + "] with data [" + data + "]");
117 }
118 MAP.put(name, manager);
119 } else {
120 manager.updateData(data);
121 }
122 manager.count++;
123 return manager;
124 } finally {
125 LOCK.unlock();
126 }
127 }
128
129
130
131
132
133
134 public void updateData(final Object data) {
135
136 }
137
138
139
140
141
142
143 public static boolean hasManager(final String name) {
144 LOCK.lock();
145 try {
146 return MAP.containsKey(name);
147 } finally {
148 LOCK.unlock();
149 }
150 }
151
152
153
154
155
156
157
158
159
160
161
162
163 protected static <M extends AbstractManager> M narrow(final Class<M> narrowClass, final AbstractManager manager) {
164 if (narrowClass.isAssignableFrom(manager.getClass())) {
165 return (M) manager;
166 }
167 throw new ConfigurationException(
168 "Configuration has multiple incompatible Appenders pointing to the same resource '" +
169 manager.getName() + "'");
170 }
171
172 protected static StatusLogger logger() {
173 return StatusLogger.getLogger();
174 }
175
176
177
178
179
180
181
182
183 protected boolean releaseSub(final long timeout, final TimeUnit timeUnit) {
184
185 return true;
186 }
187
188 protected int getCount() {
189 return count;
190 }
191
192
193
194
195
196
197
198
199 public LoggerContext getLoggerContext() {
200 return loggerContext;
201 }
202
203
204
205
206
207 @Deprecated
208 public void release() {
209 close();
210 }
211
212
213
214
215
216 public String getName() {
217 return name;
218 }
219
220
221
222
223
224
225
226
227 public Map<String, String> getContentFormat() {
228 return new HashMap<>();
229 }
230
231 protected void log(final Level level, final String message, final Throwable throwable) {
232 final Message m = LOGGER.getMessageFactory().newMessage("{} {} {}: {}",
233 getClass().getSimpleName(), getName(), message, throwable);
234 LOGGER.log(level, m, throwable);
235 }
236
237 protected void logDebug(final String message, final Throwable throwable) {
238 log(Level.DEBUG, message, throwable);
239 }
240
241 protected void logError(final String message, final Throwable throwable) {
242 log(Level.ERROR, message, throwable);
243 }
244
245 protected void logWarn(final String message, final Throwable throwable) {
246 log(Level.WARN, message, throwable);
247 }
248
249 }