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 public void updateData(final Object data) {
130
131 }
132
133
134
135
136
137
138 public static boolean hasManager(final String name) {
139 LOCK.lock();
140 try {
141 return MAP.containsKey(name);
142 } finally {
143 LOCK.unlock();
144 }
145 }
146
147
148
149
150
151
152
153
154
155
156
157
158 protected static <M extends AbstractManager> M narrow(final Class<M> narrowClass, final AbstractManager manager) {
159 if (narrowClass.isAssignableFrom(manager.getClass())) {
160 return (M) manager;
161 }
162 throw new ConfigurationException(
163 "Configuration has multiple incompatible Appenders pointing to the same resource '" +
164 manager.getName() + "'");
165 }
166
167
168
169
170
171
172
173
174 protected boolean releaseSub(final long timeout, final TimeUnit timeUnit) {
175
176 return true;
177 }
178
179 protected int getCount() {
180 return count;
181 }
182
183
184
185
186
187
188
189
190 public LoggerContext getLoggerContext() {
191 return loggerContext;
192 }
193
194
195
196
197
198 @Deprecated
199 public void release() {
200 close();
201 }
202
203
204
205
206
207 public String getName() {
208 return name;
209 }
210
211
212
213
214
215
216
217
218 public Map<String, String> getContentFormat() {
219 return new HashMap<>();
220 }
221
222 protected void log(final Level level, final String message, final Throwable throwable) {
223 final Message m = LOGGER.getMessageFactory().newMessage("{} {} {}: {}",
224 getClass().getSimpleName(), getName(), message, throwable);
225 LOGGER.log(level, m, throwable);
226 }
227
228 protected void logDebug(final String message, final Throwable throwable) {
229 log(Level.DEBUG, message, throwable);
230 }
231
232 protected void logError(final String message, final Throwable throwable) {
233 log(Level.ERROR, message, throwable);
234 }
235
236 protected void logWarn(final String message, final Throwable throwable) {
237 log(Level.WARN, message, throwable);
238 }
239
240 }