1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.log4j;
29
30
31 import java.util.Hashtable;
32 import java.util.Enumeration;
33 import java.util.Vector;
34
35 import org.apache.log4j.spi.LoggerFactory;
36 import org.apache.log4j.spi.HierarchyEventListener;
37 import org.apache.log4j.spi.LoggerRepository;
38 import org.apache.log4j.spi.RendererSupport;
39 import org.apache.log4j.or.RendererMap;
40 import org.apache.log4j.or.ObjectRenderer;
41 import org.apache.log4j.helpers.LogLog;
42 import org.apache.log4j.spi.ThrowableRendererSupport;
43 import org.apache.log4j.spi.ThrowableRenderer;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public class Hierarchy implements LoggerRepository, RendererSupport, ThrowableRendererSupport {
67
68 private LoggerFactory defaultFactory;
69 private Vector listeners;
70
71 Hashtable ht;
72 Logger root;
73 RendererMap rendererMap;
74
75 int thresholdInt;
76 Level threshold;
77
78 boolean emittedNoAppenderWarning = false;
79 boolean emittedNoResourceBundleWarning = false;
80
81 private ThrowableRenderer throwableRenderer = null;
82
83
84
85
86
87
88
89 public
90 Hierarchy(Logger root) {
91 ht = new Hashtable();
92 listeners = new Vector(1);
93 this.root = root;
94
95 setThreshold(Level.ALL);
96 this.root.setHierarchy(this);
97 rendererMap = new RendererMap();
98 defaultFactory = new DefaultCategoryFactory();
99 }
100
101
102
103
104 public
105 void addRenderer(Class classToRender, ObjectRenderer or) {
106 rendererMap.put(classToRender, or);
107 }
108
109 public
110 void addHierarchyEventListener(HierarchyEventListener listener) {
111 if(listeners.contains(listener)) {
112 LogLog.warn("Ignoring attempt to add an existent listener.");
113 } else {
114 listeners.addElement(listener);
115 }
116 }
117
118
119
120
121
122
123
124
125
126
127 public
128 void clear() {
129
130 ht.clear();
131 }
132
133 public
134 void emitNoAppenderWarning(Category cat) {
135
136 if(!this.emittedNoAppenderWarning) {
137 LogLog.warn("No appenders could be found for logger (" +
138 cat.getName() + ").");
139 LogLog.warn("Please initialize the log4j system properly.");
140 LogLog.warn("See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.");
141 this.emittedNoAppenderWarning = true;
142 }
143 }
144
145
146
147
148
149
150
151
152 public
153 Logger exists(String name) {
154 Object o = ht.get(new CategoryKey(name));
155 if(o instanceof Logger) {
156 return (Logger) o;
157 } else {
158 return null;
159 }
160 }
161
162
163
164
165 public
166 void setThreshold(String levelStr) {
167 Level l = (Level) Level.toLevel(levelStr, null);
168 if(l != null) {
169 setThreshold(l);
170 } else {
171 LogLog.warn("Could not convert ["+levelStr+"] to Level.");
172 }
173 }
174
175
176
177
178
179
180
181
182 public
183 void setThreshold(Level l) {
184 if(l != null) {
185 thresholdInt = l.level;
186 threshold = l;
187 }
188 }
189
190 public
191 void fireAddAppenderEvent(Category logger, Appender appender) {
192 if(listeners != null) {
193 int size = listeners.size();
194 HierarchyEventListener listener;
195 for(int i = 0; i < size; i++) {
196 listener = (HierarchyEventListener) listeners.elementAt(i);
197 listener.addAppenderEvent(logger, appender);
198 }
199 }
200 }
201
202 void fireRemoveAppenderEvent(Category logger, Appender appender) {
203 if(listeners != null) {
204 int size = listeners.size();
205 HierarchyEventListener listener;
206 for(int i = 0; i < size; i++) {
207 listener = (HierarchyEventListener) listeners.elementAt(i);
208 listener.removeAppenderEvent(logger, appender);
209 }
210 }
211 }
212
213
214
215
216
217
218 public
219 Level getThreshold() {
220 return threshold;
221 }
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245 public
246 Logger getLogger(String name) {
247 return getLogger(name, defaultFactory);
248 }
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263 public
264 Logger getLogger(String name, LoggerFactory factory) {
265
266 CategoryKey key = new CategoryKey(name);
267
268
269
270 Logger logger;
271
272 synchronized(ht) {
273 Object o = ht.get(key);
274 if(o == null) {
275 logger = factory.makeNewLoggerInstance(name);
276 logger.setHierarchy(this);
277 ht.put(key, logger);
278 updateParents(logger);
279 return logger;
280 } else if(o instanceof Logger) {
281 return (Logger) o;
282 } else if (o instanceof ProvisionNode) {
283
284 logger = factory.makeNewLoggerInstance(name);
285 logger.setHierarchy(this);
286 ht.put(key, logger);
287 updateChildren((ProvisionNode) o, logger);
288 updateParents(logger);
289 return logger;
290 }
291 else {
292
293 return null;
294 }
295 }
296 }
297
298
299
300
301
302
303
304 public
305 Enumeration getCurrentLoggers() {
306
307
308
309 Vector v = new Vector(ht.size());
310
311 Enumeration elems = ht.elements();
312 while(elems.hasMoreElements()) {
313 Object o = elems.nextElement();
314 if(o instanceof Logger) {
315 v.addElement(o);
316 }
317 }
318 return v.elements();
319 }
320
321
322
323
324 public
325 Enumeration getCurrentCategories() {
326 return getCurrentLoggers();
327 }
328
329
330
331
332
333 public
334 RendererMap getRendererMap() {
335 return rendererMap;
336 }
337
338
339
340
341
342
343
344 public
345 Logger getRootLogger() {
346 return root;
347 }
348
349
350
351
352
353
354 public
355 boolean isDisabled(int level) {
356 return thresholdInt > level;
357 }
358
359
360
361
362 public
363 void overrideAsNeeded(String override) {
364 LogLog.warn("The Hiearchy.overrideAsNeeded method has been deprecated.");
365 }
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381 public
382 void resetConfiguration() {
383
384 getRootLogger().setLevel((Level) Level.DEBUG);
385 root.setResourceBundle(null);
386 setThreshold(Level.ALL);
387
388
389
390 synchronized(ht) {
391 shutdown();
392
393 Enumeration cats = getCurrentLoggers();
394 while(cats.hasMoreElements()) {
395 Logger c = (Logger) cats.nextElement();
396 c.setLevel(null);
397 c.setAdditivity(true);
398 c.setResourceBundle(null);
399 }
400 }
401 rendererMap.clear();
402 throwableRenderer = null;
403 }
404
405
406
407
408
409
410 public
411 void setDisableOverride(String override) {
412 LogLog.warn("The Hiearchy.setDisableOverride method has been deprecated.");
413 }
414
415
416
417
418
419
420 public
421 void setRenderer(Class renderedClass, ObjectRenderer renderer) {
422 rendererMap.put(renderedClass, renderer);
423 }
424
425
426
427
428 public void setThrowableRenderer(final ThrowableRenderer renderer) {
429 throwableRenderer = renderer;
430 }
431
432
433
434
435 public ThrowableRenderer getThrowableRenderer() {
436 return throwableRenderer;
437 }
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456 public
457 void shutdown() {
458 Logger root = getRootLogger();
459
460
461 root.closeNestedAppenders();
462
463 synchronized(ht) {
464 Enumeration cats = this.getCurrentLoggers();
465 while(cats.hasMoreElements()) {
466 Logger c = (Logger) cats.nextElement();
467 c.closeNestedAppenders();
468 }
469
470
471 root.removeAllAppenders();
472 cats = this.getCurrentLoggers();
473 while(cats.hasMoreElements()) {
474 Logger c = (Logger) cats.nextElement();
475 c.removeAllAppenders();
476 }
477 }
478 }
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501 final
502 private
503 void updateParents(Logger cat) {
504 String name = cat.name;
505 int length = name.length();
506 boolean parentFound = false;
507
508
509
510
511 for(int i = name.lastIndexOf('.', length-1); i >= 0;
512 i = name.lastIndexOf('.', i-1)) {
513 String substr = name.substring(0, i);
514
515
516 CategoryKey key = new CategoryKey(substr);
517 Object o = ht.get(key);
518
519 if(o == null) {
520
521 ProvisionNode pn = new ProvisionNode(cat);
522 ht.put(key, pn);
523 } else if(o instanceof Category) {
524 parentFound = true;
525 cat.parent = (Category) o;
526
527 break;
528 } else if(o instanceof ProvisionNode) {
529 ((ProvisionNode) o).addElement(cat);
530 } else {
531 Exception e = new IllegalStateException("unexpected object type " +
532 o.getClass() + " in ht.");
533 e.printStackTrace();
534 }
535 }
536
537 if(!parentFound)
538 cat.parent = root;
539 }
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556 final
557 private
558 void updateChildren(ProvisionNode pn, Logger logger) {
559
560 final int last = pn.size();
561
562 for(int i = 0; i < last; i++) {
563 Logger l = (Logger) pn.elementAt(i);
564
565
566
567
568 if(!l.parent.name.startsWith(logger.name)) {
569 logger.parent = l.parent;
570 l.parent = logger;
571 }
572 }
573 }
574
575 }
576
577