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
29
30
31
32 package org.apache.log4j;
33
34 import org.apache.log4j.spi.AppenderAttachable;
35 import org.apache.log4j.spi.LoggingEvent;
36 import org.apache.log4j.spi.LoggerRepository;
37 import org.apache.log4j.spi.HierarchyEventListener;
38 import org.apache.log4j.helpers.NullEnumeration;
39 import org.apache.log4j.helpers.AppenderAttachableImpl;
40
41 import java.util.Enumeration;
42 import java.util.MissingResourceException;
43 import java.util.ResourceBundle;
44 import java.util.Vector;
45
46
47 /***
48 * <font color="#AA2222"><b>This class has been deprecated and
49 * replaced by the {@link Logger} <em>subclass</em></b></font>. It
50 * will be kept around to preserve backward compatibility until mid
51 * 2003.
52 *
53 * <p><code>Logger</code> is a subclass of Category, i.e. it extends
54 * Category. In other words, a logger <em>is</em> a category. Thus,
55 * all operations that can be performed on a category can be
56 * performed on a logger. Internally, whenever log4j is asked to
57 * produce a Category object, it will instead produce a Logger
58 * object. Log4j 1.2 will <em>never</em> produce Category objects but
59 * only <code>Logger</code> instances. In order to preserve backward
60 * compatibility, methods that previously accepted category objects
61 * still continue to accept category objects.
62 *
63 * <p>For example, the following are all legal and will work as
64 * expected.
65 *
66 <pre>
67 // Deprecated form:
68 Category cat = Category.getInstance("foo.bar")
69
70 // Preferred form for retrieving loggers:
71 Logger logger = Logger.getLogger("foo.bar")
72 </pre>
73
74 * <p>The first form is deprecated and should be avoided.
75 *
76 * <p><b>There is absolutely no need for new client code to use or
77 * refer to the <code>Category</code> class.</b> Whenever possible,
78 * please avoid referring to it or using it.
79 *
80 * <p>See the <a href="../../../../manual.html">short manual</a> for an
81 * introduction on this class.
82 * <p>
83 * See the document entitled <a href="http://www.qos.ch/logging/preparingFor13.html">preparing
84 * for log4j 1.3</a> for a more detailed discussion.
85 *
86 * @author Ceki Gülcü
87 * @author Anders Kristensen
88 */
89 public class Category implements AppenderAttachable {
90
91 /***
92 The hierarchy where categories are attached to by default.
93 */
94
95
96
97
98
99 /***
100 The name of this category.
101 */
102 protected String name;
103
104 /***
105 The assigned level of this category. The
106 <code>level</code> variable need not be assigned a value in
107 which case it is inherited form the hierarchy. */
108 volatile protected Level level;
109
110 /***
111 The parent of this category. All categories have at least one
112 ancestor which is the root category. */
113 volatile protected Category parent;
114
115 /***
116 The fully qualified name of the Category class. See also the
117 getFQCN method. */
118 private static final String FQCN = Category.class.getName();
119
120 protected ResourceBundle resourceBundle;
121
122
123 protected LoggerRepository repository;
124
125
126 AppenderAttachableImpl aai;
127
128 /*** Additivity is set to true by default, that is children inherit
129 the appenders of their ancestors by default. If this variable is
130 set to <code>false</code> then the appenders found in the
131 ancestors of this category are not used. However, the children
132 of this category will inherit its appenders, unless the children
133 have their additivity flag set to <code>false</code> too. See
134 the user manual for more details. */
135 protected boolean additive = true;
136
137 /***
138 This constructor created a new <code>Category</code> instance and
139 sets its name.
140
141 <p>It is intended to be used by sub-classes only. You should not
142 create categories directly.
143
144 @param name The name of the category.
145 */
146 protected
147 Category(String name) {
148 this.name = name;
149 }
150
151 /***
152 Add <code>newAppender</code> to the list of appenders of this
153 Category instance.
154
155 <p>If <code>newAppender</code> is already in the list of
156 appenders, then it won't be added again.
157 */
158 synchronized
159 public
160 void addAppender(Appender newAppender) {
161 if(aai == null) {
162 aai = new AppenderAttachableImpl();
163 }
164 aai.addAppender(newAppender);
165 repository.fireAddAppenderEvent(this, newAppender);
166 }
167
168 /***
169 If <code>assertion</code> parameter is <code>false</code>, then
170 logs <code>msg</code> as an {@link #error(Object) error} statement.
171
172 <p>The <code>assert</code> method has been renamed to
173 <code>assertLog</code> because <code>assert</code> is a language
174 reserved word in JDK 1.4.
175
176 @param assertion
177 @param msg The message to print if <code>assertion</code> is
178 false.
179
180 @since 1.2 */
181 public
182 void assertLog(boolean assertion, String msg) {
183 if(!assertion)
184 this.error(msg);
185 }
186
187
188 /***
189 Call the appenders in the hierrachy starting at
190 <code>this</code>. If no appenders could be found, emit a
191 warning.
192
193 <p>This method calls all the appenders inherited from the
194 hierarchy circumventing any evaluation of whether to log or not
195 to log the particular log request.
196
197 @param event the event to log. */
198 public
199 void callAppenders(LoggingEvent event) {
200 int writes = 0;
201
202 for(Category c = this; c != null; c=c.parent) {
203
204 synchronized(c) {
205 if(c.aai != null) {
206 writes += c.aai.appendLoopOnAppenders(event);
207 }
208 if(!c.additive) {
209 break;
210 }
211 }
212 }
213
214 if(writes == 0) {
215 repository.emitNoAppenderWarning(this);
216 }
217 }
218
219 /***
220 Close all attached appenders implementing the AppenderAttachable
221 interface.
222 @since 1.0
223 */
224 synchronized
225 void closeNestedAppenders() {
226 Enumeration enumeration = this.getAllAppenders();
227 if(enumeration != null) {
228 while(enumeration.hasMoreElements()) {
229 Appender a = (Appender) enumeration.nextElement();
230 if(a instanceof AppenderAttachable) {
231 a.close();
232 }
233 }
234 }
235 }
236
237 /***
238 Log a message object with the {@link Level#DEBUG DEBUG} level.
239
240 <p>This method first checks if this category is <code>DEBUG</code>
241 enabled by comparing the level of this category with the {@link
242 Level#DEBUG DEBUG} level. If this category is
243 <code>DEBUG</code> enabled, then it converts the message object
244 (passed as parameter) to a string by invoking the appropriate
245 {@link org.apache.log4j.or.ObjectRenderer}. It then proceeds to call all the
246 registered appenders in this category and also higher in the
247 hierarchy depending on the value of the additivity flag.
248
249 <p><b>WARNING</b> Note that passing a {@link Throwable} to this
250 method will print the name of the <code>Throwable</code> but no
251 stack trace. To print a stack trace use the {@link #debug(Object,
252 Throwable)} form instead.
253
254 @param message the message object to log. */
255 public
256 void debug(Object message) {
257 if(repository.isDisabled(Level.DEBUG_INT))
258 return;
259 if(Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) {
260 forcedLog(FQCN, Level.DEBUG, message, null);
261 }
262 }
263
264
265 /***
266 Log a message object with the <code>DEBUG</code> level including
267 the stack trace of the {@link Throwable} <code>t</code> passed as
268 parameter.
269
270 <p>See {@link #debug(Object)} form for more detailed information.
271
272 @param message the message object to log.
273 @param t the exception to log, including its stack trace. */
274 public
275 void debug(Object message, Throwable t) {
276 if(repository.isDisabled(Level.DEBUG_INT))
277 return;
278 if(Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel()))
279 forcedLog(FQCN, Level.DEBUG, message, t);
280 }
281
282 /***
283 Log a message object with the {@link Level#ERROR ERROR} Level.
284
285 <p>This method first checks if this category is <code>ERROR</code>
286 enabled by comparing the level of this category with {@link
287 Level#ERROR ERROR} Level. If this category is <code>ERROR</code>
288 enabled, then it converts the message object passed as parameter
289 to a string by invoking the appropriate {@link
290 org.apache.log4j.or.ObjectRenderer}. It proceeds to call all the
291 registered appenders in this category and also higher in the
292 hierarchy depending on the value of the additivity flag.
293
294 <p><b>WARNING</b> Note that passing a {@link Throwable} to this
295 method will print the name of the <code>Throwable</code> but no
296 stack trace. To print a stack trace use the {@link #error(Object,
297 Throwable)} form instead.
298
299 @param message the message object to log */
300 public
301 void error(Object message) {
302 if(repository.isDisabled(Level.ERROR_INT))
303 return;
304 if(Level.ERROR.isGreaterOrEqual(this.getEffectiveLevel()))
305 forcedLog(FQCN, Level.ERROR, message, null);
306 }
307
308 /***
309 Log a message object with the <code>ERROR</code> level including
310 the stack trace of the {@link Throwable} <code>t</code> passed as
311 parameter.
312
313 <p>See {@link #error(Object)} form for more detailed information.
314
315 @param message the message object to log.
316 @param t the exception to log, including its stack trace. */
317 public
318 void error(Object message, Throwable t) {
319 if(repository.isDisabled(Level.ERROR_INT))
320 return;
321 if(Level.ERROR.isGreaterOrEqual(this.getEffectiveLevel()))
322 forcedLog(FQCN, Level.ERROR, message, t);
323
324 }
325
326
327 /***
328 If the named category exists (in the default hierarchy) then it
329 returns a reference to the category, otherwise it returns
330 <code>null</code>.
331
332 @deprecated Please use {@link LogManager#exists} instead.
333
334 @since 0.8.5 */
335 public
336 static
337 Logger exists(String name) {
338 return LogManager.exists(name);
339 }
340
341 /***
342 Log a message object with the {@link Level#FATAL FATAL} Level.
343
344 <p>This method first checks if this category is <code>FATAL</code>
345 enabled by comparing the level of this category with {@link
346 Level#FATAL FATAL} Level. If the category is <code>FATAL</code>
347 enabled, then it converts the message object passed as parameter
348 to a string by invoking the appropriate
349 {@link org.apache.log4j.or.ObjectRenderer}. It
350 proceeds to call all the registered appenders in this category and
351 also higher in the hierarchy depending on the value of the
352 additivity flag.
353
354 <p><b>WARNING</b> Note that passing a {@link Throwable} to this
355 method will print the name of the Throwable but no stack trace. To
356 print a stack trace use the {@link #fatal(Object, Throwable)} form
357 instead.
358
359 @param message the message object to log */
360 public
361 void fatal(Object message) {
362 if(repository.isDisabled(Level.FATAL_INT))
363 return;
364 if(Level.FATAL.isGreaterOrEqual(this.getEffectiveLevel()))
365 forcedLog(FQCN, Level.FATAL, message, null);
366 }
367
368 /***
369 Log a message object with the <code>FATAL</code> level including
370 the stack trace of the {@link Throwable} <code>t</code> passed as
371 parameter.
372
373 <p>See {@link #fatal(Object)} for more detailed information.
374
375 @param message the message object to log.
376 @param t the exception to log, including its stack trace. */
377 public
378 void fatal(Object message, Throwable t) {
379 if(repository.isDisabled(Level.FATAL_INT))
380 return;
381 if(Level.FATAL.isGreaterOrEqual(this.getEffectiveLevel()))
382 forcedLog(FQCN, Level.FATAL, message, t);
383 }
384
385
386 /***
387 This method creates a new logging event and logs the event
388 without further checks. */
389 protected
390 void forcedLog(String fqcn, Priority level, Object message, Throwable t) {
391 callAppenders(new LoggingEvent(fqcn, this, level, message, t));
392 }
393
394
395 /***
396 Get the additivity flag for this Category instance.
397 */
398 public
399 boolean getAdditivity() {
400 return additive;
401 }
402
403 /***
404 Get the appenders contained in this category as an {@link
405 Enumeration}. If no appenders can be found, then a {@link NullEnumeration}
406 is returned.
407
408 @return Enumeration An enumeration of the appenders in this category. */
409 synchronized
410 public
411 Enumeration getAllAppenders() {
412 if(aai == null)
413 return NullEnumeration.getInstance();
414 else
415 return aai.getAllAppenders();
416 }
417
418 /***
419 Look for the appender named as <code>name</code>.
420
421 <p>Return the appender with that name if in the list. Return
422 <code>null</code> otherwise. */
423 synchronized
424 public
425 Appender getAppender(String name) {
426 if(aai == null || name == null)
427 return null;
428
429 return aai.getAppender(name);
430 }
431
432 /***
433 Starting from this category, search the category hierarchy for a
434 non-null level and return it. Otherwise, return the level of the
435 root category.
436
437 <p>The Category class is designed so that this method executes as
438 quickly as possible.
439 */
440 public
441 Level getEffectiveLevel() {
442 for(Category c = this; c != null; c=c.parent) {
443 if(c.level != null)
444 return c.level;
445 }
446 return null;
447 }
448
449 /***
450 *
451 * @deprecated Please use the the {@link #getEffectiveLevel} method
452 * instead.
453 * */
454 public
455 Priority getChainedPriority() {
456 for(Category c = this; c != null; c=c.parent) {
457 if(c.level != null)
458 return c.level;
459 }
460 return null;
461 }
462
463
464 /***
465 Returns all the currently defined categories in the default
466 hierarchy as an {@link java.util.Enumeration Enumeration}.
467
468 <p>The root category is <em>not</em> included in the returned
469 {@link Enumeration}.
470
471 @deprecated Please use {@link LogManager#getCurrentLoggers()} instead.
472 */
473 public
474 static
475 Enumeration getCurrentCategories() {
476 return LogManager.getCurrentLoggers();
477 }
478
479
480 /***
481 Return the default Hierarchy instance.
482
483 @deprecated Please use {@link LogManager#getLoggerRepository()} instead.
484
485 @since 1.0
486 */
487 public
488 static
489 LoggerRepository getDefaultHierarchy() {
490 return LogManager.getLoggerRepository();
491 }
492
493 /***
494 Return the the {@link Hierarchy} where this <code>Category</code>
495 instance is attached.
496
497 @deprecated Please use {@link #getLoggerRepository} instead.
498
499 @since 1.1 */
500 public
501 LoggerRepository getHierarchy() {
502 return repository;
503 }
504
505 /***
506 Return the the {@link LoggerRepository} where this
507 <code>Category</code> is attached.
508
509 @since 1.2 */
510 public
511 LoggerRepository getLoggerRepository() {
512 return repository;
513 }
514
515
516 /***
517 * @deprecated Make sure to use {@link Logger#getLogger(String)} instead.
518 */
519 public
520 static
521 Category getInstance(String name) {
522 return LogManager.getLogger(name);
523 }
524
525 /***
526 * @deprecated Please make sure to use {@link Logger#getLogger(Class)} instead.
527 */
528 public
529 static
530 Category getInstance(Class clazz) {
531 return LogManager.getLogger(clazz);
532 }
533
534
535 /***
536 Return the category name. */
537 public
538 final
539 String getName() {
540 return name;
541 }
542
543
544 /***
545 Returns the parent of this category. Note that the parent of a
546 given category may change during the lifetime of the category.
547
548 <p>The root category will return <code>null</code>.
549
550 @since 1.2
551 */
552 final
553 public
554 Category getParent() {
555 return this.parent;
556 }
557
558
559 /***
560 Returns the assigned {@link Level}, if any, for this Category.
561
562 @return Level - the assigned Level, can be <code>null</code>.
563 */
564 final
565 public
566 Level getLevel() {
567 return this.level;
568 }
569
570 /***
571 @deprecated Please use {@link #getLevel} instead.
572 */
573 final
574 public
575 Level getPriority() {
576 return this.level;
577 }
578
579
580 /***
581 * @deprecated Please use {@link Logger#getRootLogger()} instead.
582 */
583 final
584 public
585 static
586 Category getRoot() {
587 return LogManager.getRootLogger();
588 }
589
590 /***
591 Return the <em>inherited</em> {@link ResourceBundle} for this
592 category.
593
594 <p>This method walks the hierarchy to find the appropriate
595 resource bundle. It will return the resource bundle attached to
596 the closest ancestor of this category, much like the way
597 priorities are searched. In case there is no bundle in the
598 hierarchy then <code>null</code> is returned.
599
600 @since 0.9.0 */
601 public
602 ResourceBundle getResourceBundle() {
603 for(Category c = this; c != null; c=c.parent) {
604 if(c.resourceBundle != null)
605 return c.resourceBundle;
606 }
607
608 return null;
609 }
610
611 /***
612 Returns the string resource coresponding to <code>key</code> in
613 this category's inherited resource bundle. See also {@link
614 #getResourceBundle}.
615
616 <p>If the resource cannot be found, then an {@link #error error}
617 message will be logged complaining about the missing resource.
618 */
619 protected
620 String getResourceBundleString(String key) {
621 ResourceBundle rb = getResourceBundle();
622
623
624 if(rb == null) {
625
626
627
628
629 return null;
630 }
631 else {
632 try {
633 return rb.getString(key);
634 }
635 catch(MissingResourceException mre) {
636 error("No resource is associated with key \""+key+"\".");
637 return null;
638 }
639 }
640 }
641
642 /***
643 Log a message object with the {@link Level#INFO INFO} Level.
644
645 <p>This method first checks if this category is <code>INFO</code>
646 enabled by comparing the level of this category with {@link
647 Level#INFO INFO} Level. If the category is <code>INFO</code>
648 enabled, then it converts the message object passed as parameter
649 to a string by invoking the appropriate
650 {@link org.apache.log4j.or.ObjectRenderer}. It
651 proceeds to call all the registered appenders in this category and
652 also higher in the hierarchy depending on the value of the
653 additivity flag.
654
655 <p><b>WARNING</b> Note that passing a {@link Throwable} to this
656 method will print the name of the Throwable but no stack trace. To
657 print a stack trace use the {@link #info(Object, Throwable)} form
658 instead.
659
660 @param message the message object to log */
661 public
662 void info(Object message) {
663 if(repository.isDisabled(Level.INFO_INT))
664 return;
665 if(Level.INFO.isGreaterOrEqual(this.getEffectiveLevel()))
666 forcedLog(FQCN, Level.INFO, message, null);
667 }
668
669 /***
670 Log a message object with the <code>INFO</code> level including
671 the stack trace of the {@link Throwable} <code>t</code> passed as
672 parameter.
673
674 <p>See {@link #info(Object)} for more detailed information.
675
676 @param message the message object to log.
677 @param t the exception to log, including its stack trace. */
678 public
679 void info(Object message, Throwable t) {
680 if(repository.isDisabled(Level.INFO_INT))
681 return;
682 if(Level.INFO.isGreaterOrEqual(this.getEffectiveLevel()))
683 forcedLog(FQCN, Level.INFO, message, t);
684 }
685
686 /***
687 Is the appender passed as parameter attached to this category?
688 */
689 public
690 boolean isAttached(Appender appender) {
691 if(appender == null || aai == null)
692 return false;
693 else {
694 return aai.isAttached(appender);
695 }
696 }
697
698 /***
699 * Check whether this category is enabled for the <code>DEBUG</code>
700 * Level.
701 *
702 * <p> This function is intended to lessen the computational cost of
703 * disabled log debug statements.
704 *
705 * <p> For some <code>cat</code> Category object, when you write,
706 * <pre>
707 * cat.debug("This is entry number: " + i );
708 * </pre>
709 *
710 * <p>You incur the cost constructing the message, concatenatiion in
711 * this case, regardless of whether the message is logged or not.
712 *
713 * <p>If you are worried about speed, then you should write
714 * <pre>
715 * if(cat.isDebugEnabled()) {
716 * cat.debug("This is entry number: " + i );
717 * }
718 * </pre>
719 *
720 * <p>This way you will not incur the cost of parameter
721 * construction if debugging is disabled for <code>cat</code>. On
722 * the other hand, if the <code>cat</code> is debug enabled, you
723 * will incur the cost of evaluating whether the category is debug
724 * enabled twice. Once in <code>isDebugEnabled</code> and once in
725 * the <code>debug</code>. This is an insignificant overhead
726 * since evaluating a category takes about 1%% of the time it
727 * takes to actually log.
728 *
729 * @return boolean - <code>true</code> if this category is debug
730 * enabled, <code>false</code> otherwise.
731 * */
732 public
733 boolean isDebugEnabled() {
734 if(repository.isDisabled( Level.DEBUG_INT))
735 return false;
736 return Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel());
737 }
738
739 /***
740 Check whether this category is enabled for a given {@link
741 Level} passed as parameter.
742
743 See also {@link #isDebugEnabled}.
744
745 @return boolean True if this category is enabled for <code>level</code>.
746 */
747 public
748 boolean isEnabledFor(Priority level) {
749 if(repository.isDisabled(level.level))
750 return false;
751 return level.isGreaterOrEqual(this.getEffectiveLevel());
752 }
753
754 /***
755 Check whether this category is enabled for the info Level.
756 See also {@link #isDebugEnabled}.
757
758 @return boolean - <code>true</code> if this category is enabled
759 for level info, <code>false</code> otherwise.
760 */
761 public
762 boolean isInfoEnabled() {
763 if(repository.isDisabled(Level.INFO_INT))
764 return false;
765 return Level.INFO.isGreaterOrEqual(this.getEffectiveLevel());
766 }
767
768
769 /***
770 Log a localized message. The user supplied parameter
771 <code>key</code> is replaced by its localized version from the
772 resource bundle.
773
774 @see #setResourceBundle
775
776 @since 0.8.4 */
777 public
778 void l7dlog(Priority priority, String key, Throwable t) {
779 if(repository.isDisabled(priority.level)) {
780 return;
781 }
782 if(priority.isGreaterOrEqual(this.getEffectiveLevel())) {
783 String msg = getResourceBundleString(key);
784
785
786 if(msg == null) {
787 msg = key;
788 }
789 forcedLog(FQCN, priority, msg, t);
790 }
791 }
792 /***
793 Log a localized and parameterized message. First, the user
794 supplied <code>key</code> is searched in the resource
795 bundle. Next, the resulting pattern is formatted using
796 {@link java.text.MessageFormat#format(String,Object[])} method with the
797 user supplied object array <code>params</code>.
798
799 @since 0.8.4
800 */
801 public
802 void l7dlog(Priority priority, String key, Object[] params, Throwable t) {
803 if(repository.isDisabled(priority.level)) {
804 return;
805 }
806 if(priority.isGreaterOrEqual(this.getEffectiveLevel())) {
807 String pattern = getResourceBundleString(key);
808 String msg;
809 if(pattern == null)
810 msg = key;
811 else
812 msg = java.text.MessageFormat.format(pattern, params);
813 forcedLog(FQCN, priority, msg, t);
814 }
815 }
816
817 /***
818 This generic form is intended to be used by wrappers.
819 */
820 public
821 void log(Priority priority, Object message, Throwable t) {
822 if(repository.isDisabled(priority.level)) {
823 return;
824 }
825 if(priority.isGreaterOrEqual(this.getEffectiveLevel()))
826 forcedLog(FQCN, priority, message, t);
827 }
828
829 /***
830 This generic form is intended to be used by wrappers.
831 */
832 public
833 void log(Priority priority, Object message) {
834 if(repository.isDisabled(priority.level)) {
835 return;
836 }
837 if(priority.isGreaterOrEqual(this.getEffectiveLevel()))
838 forcedLog(FQCN, priority, message, null);
839 }
840
841 /***
842
843 This is the most generic printing method. It is intended to be
844 invoked by <b>wrapper</b> classes.
845
846 @param callerFQCN The wrapper class' fully qualified class name.
847 @param level The level of the logging request.
848 @param message The message of the logging request.
849 @param t The throwable of the logging request, may be null. */
850 public
851 void log(String callerFQCN, Priority level, Object message, Throwable t) {
852 if(repository.isDisabled(level.level)) {
853 return;
854 }
855 if(level.isGreaterOrEqual(this.getEffectiveLevel())) {
856 forcedLog(callerFQCN, level, message, t);
857 }
858 }
859
860 /***
861 * LoggerRepository forgot the fireRemoveAppenderEvent method,
862 * if using the stock Hierarchy implementation, then call its fireRemove.
863 * Custom repositories can implement HierarchyEventListener if they
864 * want remove notifications.
865 * @param appender appender, may be null.
866 */
867 private void fireRemoveAppenderEvent(final Appender appender) {
868 if (appender != null) {
869 if (repository instanceof Hierarchy) {
870 ((Hierarchy) repository).fireRemoveAppenderEvent(this, appender);
871 } else if (repository instanceof HierarchyEventListener) {
872 ((HierarchyEventListener) repository).removeAppenderEvent(this, appender);
873 }
874 }
875 }
876
877 /***
878 Remove all previously added appenders from this Category
879 instance.
880
881 <p>This is useful when re-reading configuration information.
882 */
883 synchronized
884 public
885 void removeAllAppenders() {
886 if(aai != null) {
887 Vector appenders = new Vector();
888 for (Enumeration iter = aai.getAllAppenders(); iter.hasMoreElements();) {
889 appenders.add(iter.nextElement());
890 }
891 aai.removeAllAppenders();
892 for(Enumeration iter = appenders.elements(); iter.hasMoreElements();) {
893 fireRemoveAppenderEvent((Appender) iter.nextElement());
894 }
895 aai = null;
896 }
897 }
898
899
900 /***
901 Remove the appender passed as parameter form the list of appenders.
902
903 @since 0.8.2
904 */
905 synchronized
906 public
907 void removeAppender(Appender appender) {
908 if(appender == null || aai == null)
909 return;
910 boolean wasAttached = aai.isAttached(appender);
911 aai.removeAppender(appender);
912 if (wasAttached) {
913 fireRemoveAppenderEvent(appender);
914 }
915 }
916
917 /***
918 Remove the appender with the name passed as parameter form the
919 list of appenders.
920
921 @since 0.8.2 */
922 synchronized
923 public
924 void removeAppender(String name) {
925 if(name == null || aai == null) return;
926 Appender appender = aai.getAppender(name);
927 aai.removeAppender(name);
928 if (appender != null) {
929 fireRemoveAppenderEvent(appender);
930 }
931 }
932
933 /***
934 Set the additivity flag for this Category instance.
935 @since 0.8.1
936 */
937 public
938 void setAdditivity(boolean additive) {
939 this.additive = additive;
940 }
941
942 /***
943 Only the Hiearchy class can set the hiearchy of a
944 category. Default package access is MANDATORY here. */
945 final
946 void setHierarchy(LoggerRepository repository) {
947 this.repository = repository;
948 }
949
950 /***
951 Set the level of this Category. If you are passing any of
952 <code>Level.DEBUG</code>, <code>Level.INFO</code>,
953 <code>Level.WARN</code>, <code>Level.ERROR</code>,
954 <code>Level.FATAL</code> as a parameter, you need to case them as
955 Level.
956
957 <p>As in <pre> logger.setLevel((Level) Level.DEBUG); </pre>
958
959
960 <p>Null values are admitted. */
961 public
962 void setLevel(Level level) {
963 this.level = level;
964 }
965
966
967 /***
968 Set the level of this Category.
969
970 <p>Null values are admitted.
971
972 @deprecated Please use {@link #setLevel} instead.
973 */
974 public
975 void setPriority(Priority priority) {
976 this.level = (Level) priority;
977 }
978
979
980 /***
981 Set the resource bundle to be used with localized logging
982 methods {@link #l7dlog(Priority,String,Throwable)} and {@link
983 #l7dlog(Priority,String,Object[],Throwable)}.
984
985 @since 0.8.4
986 */
987 public
988 void setResourceBundle(ResourceBundle bundle) {
989 resourceBundle = bundle;
990 }
991
992 /***
993 Calling this method will <em>safely</em> close and remove all
994 appenders in all the categories including root contained in the
995 default hierachy.
996
997 <p>Some appenders such as {@link org.apache.log4j.net.SocketAppender}
998 and {@link AsyncAppender} need to be closed before the
999 application exists. Otherwise, pending logging events might be
1000 lost.
1001
1002 <p>The <code>shutdown</code> method is careful to close nested
1003 appenders before closing regular appenders. This is allows
1004 configurations where a regular appender is attached to a category
1005 and again to a nested appender.
1006
1007 @deprecated Please use {@link LogManager#shutdown()} instead.
1008
1009 @since 1.0
1010 */
1011 public
1012 static
1013 void shutdown() {
1014 LogManager.shutdown();
1015 }
1016
1017
1018 /***
1019 Log a message object with the {@link Level#WARN WARN} Level.
1020
1021 <p>This method first checks if this category is <code>WARN</code>
1022 enabled by comparing the level of this category with {@link
1023 Level#WARN WARN} Level. If the category is <code>WARN</code>
1024 enabled, then it converts the message object passed as parameter
1025 to a string by invoking the appropriate
1026 {@link org.apache.log4j.or.ObjectRenderer}. It
1027 proceeds to call all the registered appenders in this category and
1028 also higher in the hieararchy depending on the value of the
1029 additivity flag.
1030
1031 <p><b>WARNING</b> Note that passing a {@link Throwable} to this
1032 method will print the name of the Throwable but no stack trace. To
1033 print a stack trace use the {@link #warn(Object, Throwable)} form
1034 instead. <p>
1035
1036 @param message the message object to log. */
1037 public
1038 void warn(Object message) {
1039 if(repository.isDisabled( Level.WARN_INT))
1040 return;
1041
1042 if(Level.WARN.isGreaterOrEqual(this.getEffectiveLevel()))
1043 forcedLog(FQCN, Level.WARN, message, null);
1044 }
1045
1046 /***
1047 Log a message with the <code>WARN</code> level including the
1048 stack trace of the {@link Throwable} <code>t</code> passed as
1049 parameter.
1050
1051 <p>See {@link #warn(Object)} for more detailed information.
1052
1053 @param message the message object to log.
1054 @param t the exception to log, including its stack trace. */
1055 public
1056 void warn(Object message, Throwable t) {
1057 if(repository.isDisabled(Level.WARN_INT))
1058 return;
1059 if(Level.WARN.isGreaterOrEqual(this.getEffectiveLevel()))
1060 forcedLog(FQCN, Level.WARN, message, t);
1061 }
1062 }