1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core;
15
16 import static ch.qos.logback.core.CoreConstants.CONTEXT_NAME_KEY;
17 import static ch.qos.logback.core.CoreConstants.FA_FILENAME_COLLISION_MAP;
18 import static ch.qos.logback.core.CoreConstants.HOSTNAME_KEY;
19 import static ch.qos.logback.core.CoreConstants.RFA_FILENAME_PATTERN_COLLISION_MAP;
20
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.concurrent.ConcurrentHashMap;
26 import java.util.concurrent.ExecutorService;
27 import java.util.concurrent.ScheduledExecutorService;
28 import java.util.concurrent.ScheduledFuture;
29
30 import ch.qos.logback.core.rolling.helper.FileNamePattern;
31 import ch.qos.logback.core.spi.LifeCycle;
32 import ch.qos.logback.core.spi.LogbackLock;
33 import ch.qos.logback.core.spi.SequenceNumberGenerator;
34 import ch.qos.logback.core.status.InfoStatus;
35 import ch.qos.logback.core.status.StatusManager;
36 import ch.qos.logback.core.util.ExecutorServiceUtil;
37 import ch.qos.logback.core.util.NetworkAddressUtil;
38
39 public class ContextBase implements Context, LifeCycle {
40
41 private long birthTime = System.currentTimeMillis();
42
43 private String name;
44 private StatusManager sm = new BasicStatusManager();
45
46
47
48 Map<String, String> propertyMap = new HashMap<String, String>();
49 Map<String, Object> objectMap = new ConcurrentHashMap<>();
50
51 LogbackLock configurationLock = new LogbackLock();
52
53 private ScheduledExecutorService scheduledExecutorService;
54 protected List<ScheduledFuture<?>> scheduledFutures = new ArrayList<ScheduledFuture<?>>(1);
55 private LifeCycleManager lifeCycleManager;
56 private SequenceNumberGenerator sequenceNumberGenerator;
57
58 private boolean started;
59
60 public ContextBase() {
61 initCollisionMaps();
62 }
63
64 public StatusManager getStatusManager() {
65 return sm;
66 }
67
68
69
70
71
72
73
74
75
76
77
78
79 public void setStatusManager(StatusManager statusManager) {
80
81 if (statusManager == null) {
82 throw new IllegalArgumentException("null StatusManager not allowed");
83 }
84 this.sm = statusManager;
85 }
86
87 public Map<String, String> getCopyOfPropertyMap() {
88 return new HashMap<String, String>(propertyMap);
89 }
90
91 public void putProperty(String key, String val) {
92 if (HOSTNAME_KEY.equalsIgnoreCase(key)) {
93 putHostnameProperty(val);
94 } else {
95 this.propertyMap.put(key, val);
96 }
97 }
98
99 protected void initCollisionMaps() {
100 putObject(FA_FILENAME_COLLISION_MAP, new HashMap<String, String>());
101 putObject(RFA_FILENAME_PATTERN_COLLISION_MAP, new HashMap<String, FileNamePattern>());
102 }
103
104
105
106
107
108
109
110
111 public String getProperty(String key) {
112 if (CONTEXT_NAME_KEY.equals(key))
113 return getName();
114 if (HOSTNAME_KEY.equalsIgnoreCase(key)) {
115 return lazyGetHostname();
116 }
117
118 return (String) this.propertyMap.get(key);
119 }
120
121 private String lazyGetHostname() {
122 String hostname = (String) this.propertyMap.get(HOSTNAME_KEY);
123 if (hostname == null) {
124 hostname = new NetworkAddressUtil(this).safelyGetLocalHostName();
125 putHostnameProperty(hostname);
126 }
127 return hostname;
128 }
129
130 private void putHostnameProperty(String hostname) {
131 String existingHostname = (String) this.propertyMap.get(HOSTNAME_KEY);
132 if (existingHostname == null) {
133 this.propertyMap.put(CoreConstants.HOSTNAME_KEY, hostname);
134 } else {
135
136 }
137 }
138
139 public Object getObject(String key) {
140 return objectMap.get(key);
141 }
142
143 public void putObject(String key, Object value) {
144 objectMap.put(key, value);
145 }
146
147 public void removeObject(String key) {
148 objectMap.remove(key);
149 }
150
151 public String getName() {
152 return name;
153 }
154
155 @Override
156 public void start() {
157
158
159
160 started = true;
161 }
162
163 public void stop() {
164
165
166 stopExecutorService();
167
168 started = false;
169 }
170
171 public boolean isStarted() {
172 return started;
173 }
174
175
176
177
178
179 public void reset() {
180
181 removeShutdownHook();
182 getLifeCycleManager().reset();
183 propertyMap.clear();
184 objectMap.clear();
185 }
186
187
188
189
190
191
192
193
194
195 public void setName(String name) throws IllegalStateException {
196 if (name != null && name.equals(this.name)) {
197 return;
198 }
199 if (this.name == null || CoreConstants.DEFAULT_CONTEXT_NAME.equals(this.name)) {
200 this.name = name;
201 } else {
202 throw new IllegalStateException("Context has been already given a name");
203 }
204 }
205
206 public long getBirthTime() {
207 return birthTime;
208 }
209
210 public Object getConfigurationLock() {
211 return configurationLock;
212 }
213
214 @Override
215
216
217
218 public synchronized ExecutorService getExecutorService() {
219 return getScheduledExecutorService();
220 }
221
222 @Override
223 public synchronized ScheduledExecutorService getScheduledExecutorService() {
224 if (scheduledExecutorService == null) {
225 scheduledExecutorService = ExecutorServiceUtil.newScheduledExecutorService();
226 }
227 return scheduledExecutorService;
228 }
229
230 private synchronized void stopExecutorService() {
231 if (scheduledExecutorService != null) {
232 ExecutorServiceUtil.shutdown(scheduledExecutorService);
233 scheduledExecutorService = null;
234 }
235 }
236
237 private void removeShutdownHook() {
238 Thread hook = (Thread) getObject(CoreConstants.SHUTDOWN_HOOK_THREAD);
239 if (hook != null) {
240 removeObject(CoreConstants.SHUTDOWN_HOOK_THREAD);
241
242 try {
243 sm.add(new InfoStatus("Removing shutdownHook " + hook, this));
244 Runtime runtime = Runtime.getRuntime();
245 boolean result = runtime.removeShutdownHook(hook);
246 sm.add(new InfoStatus("ShutdownHook removal result: " + result, this));
247 } catch (IllegalStateException e) {
248
249
250 }
251 }
252 }
253
254 public void register(LifeCycle component) {
255 getLifeCycleManager().register(component);
256 }
257
258
259
260
261
262
263
264
265
266
267
268
269
270 synchronized LifeCycleManager getLifeCycleManager() {
271 if (lifeCycleManager == null) {
272 lifeCycleManager = new LifeCycleManager();
273 }
274 return lifeCycleManager;
275 }
276
277 @Override
278 public String toString() {
279 return name;
280 }
281
282 @Override
283 public void addScheduledFuture(ScheduledFuture<?> scheduledFuture) {
284 scheduledFutures.add(scheduledFuture);
285 }
286
287
288
289
290 @Deprecated
291 public List<ScheduledFuture<?>> getScheduledFutures() {
292 return getCopyOfScheduledFutures();
293 }
294
295 public List<ScheduledFuture<?>> getCopyOfScheduledFutures() {
296 return new ArrayList<ScheduledFuture<?>>(scheduledFutures);
297 }
298
299 public SequenceNumberGenerator getSequenceNumberGenerator() {
300 return sequenceNumberGenerator;
301 }
302
303 public void setSequenceNumberGenerator(SequenceNumberGenerator sequenceNumberGenerator) {
304 this.sequenceNumberGenerator = sequenceNumberGenerator;
305 }
306
307 }