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