View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements. See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache license, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License. You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the license for the specific language governing permissions and
    15   * limitations under the license.
    16   */
    17  package org.apache.log4j;
    18
    19  import java.util.Enumeration;
    20  import java.util.Map;
    21  import java.util.ResourceBundle;
    22  import java.util.WeakHashMap;
    23  import java.util.concurrent.ConcurrentHashMap;
    24  import java.util.concurrent.ConcurrentMap;
    25
    26  import org.apache.log4j.helpers.NullEnumeration;
    27  import org.apache.log4j.spi.LoggerFactory;
    28  import org.apache.log4j.spi.LoggingEvent;
    29  import org.apache.logging.log4j.core.LoggerContext;
    30  import org.apache.logging.log4j.core.util.NameUtil;
    31  import org.apache.logging.log4j.message.LocalizedMessage;
    32  import org.apache.logging.log4j.message.Message;
    33  import org.apache.logging.log4j.message.ObjectMessage;
    34  import org.apache.logging.log4j.util.Strings;
    35
    36
    37  /**
    38   * Implementation of the Category class for compatibility, despite it having been deprecated a long, long time ago.
    39   */
    40  public class Category {
    41
    42      private static LoggerFactory loggerFactory = new PrivateFactory();
    43
    44      private static final Map<LoggerContext, ConcurrentMap<String, Logger>> CONTEXT_MAP =
    45          new WeakHashMap<LoggerContext, ConcurrentMap<String, Logger>>();
    46
    47      private static final String FQCN = Category.class.getName();
    48
    49      /**
    50       * Resource bundle for localized messages.
    51       */
    52      protected ResourceBundle bundle = null;
    53
    54      private final org.apache.logging.log4j.core.Logger logger;
    55
    56      /**
    57       * Constructor used by Logger to specify a LoggerContext.
    58       * @param context The LoggerContext.
    59       * @param name The name of the Logger.
    60       */
    61      protected Category(final LoggerContext context, final String name) {
    62          this.logger = context.getLogger(name);
    63      }
    64
    65      /**
    66       * Constructor exposed by Log4j 1.2.
    67       * @param name The name of the Logger.
    68       */
    69      protected Category(final String name) {
    70          this((LoggerContext) PrivateManager.getContext(), name);
    71      }
    72
    73      private Category(final org.apache.logging.log4j.core.Logger logger) {
    74          this.logger = logger;
    75      }
    76
    77      public static Category getInstance(final String name) {
    78          return getInstance((LoggerContext) PrivateManager.getContext(), name, loggerFactory);
    79      }
    80
    81      static Category getInstance(final LoggerContext context, final String name) {
    82          return getInstance(context, name, loggerFactory);
    83      }
    84
    85      static Category getInstance(final LoggerContext context, final String name, final LoggerFactory factory) {
    86          final ConcurrentMap<String, Logger> loggers = getLoggersMap(context);
    87          Logger logger = loggers.get(name);
    88          if (logger != null) {
    89              return logger;
    90          }
    91          logger = factory.makeNewLoggerInstance(context, name);
    92          final Logger prev = loggers.putIfAbsent(name, logger);
    93          return prev == null ? logger : prev;
    94      }
    95
    96      public static Category getInstance(@SuppressWarnings("rawtypes") final Class clazz) {
    97          return getInstance(clazz.getName());
    98      }
    99
    100     static Category getInstance(final LoggerContext context, @SuppressWarnings("rawtypes") final Class clazz) {
    101         return getInstance(context, clazz.getName());
    102     }
    103
    104     public final String getName() {
    105         return logger.getName();
    106     }
    107
    108     org.apache.logging.log4j.core.Logger getLogger() {
    109         return logger;
    110     }
    111
    112     public final Category getParent() {
    113         final org.apache.logging.log4j.core.Logger parent = logger.getParent();
    114         if (parent == null) {
    115             return null;
    116         }
    117         final ConcurrentMap<String, Logger> loggers = getLoggersMap(logger.getContext());
    118         final Logger l = loggers.get(parent.getName());
    119         return l == null ? new Category(parent) : l;
    120     }
    121
    122     public static Category getRoot() {
    123         return getInstance(Strings.EMPTY);
    124     }
    125
    126
    127     static Category getRoot(final LoggerContext context) {
    128         return getInstance(context, Strings.EMPTY);
    129     }
    130
    131     private static ConcurrentMap<String, Logger> getLoggersMap(final LoggerContext context) {
    132         synchronized (CONTEXT_MAP) {
    133             ConcurrentMap<String, Logger> map = CONTEXT_MAP.get(context);
    134             if (map == null) {
    135                 map = new ConcurrentHashMap<String, Logger>();
    136                 CONTEXT_MAP.put(context, map);
    137             }
    138             return map;
    139         }
    140     }
    141
    142     /**
    143      Returns all the currently defined categories in the default
    144      hierarchy as an {@link java.util.Enumeration Enumeration}.
    145
    146      <p>The root category is <em>not</em> included in the returned
    147      {@link Enumeration}.
    148      @return and Enumeration of the Categories.
    149
    150      @deprecated Please use {@link LogManager#getCurrentLoggers()} instead.
    151      */
    152     @SuppressWarnings("rawtypes")
    153     @Deprecated
    154     public static Enumeration getCurrentCategories() {
    155         return LogManager.getCurrentLoggers();
    156     }
    157
    158     public final Level getEffectiveLevel() {
    159         switch (logger.getLevel().getStandardLevel()) {
    160         case ALL:
    161             return Level.ALL;
    162         case TRACE:
    163             return Level.TRACE;
    164         case DEBUG:
    165             return Level.DEBUG;
    166         case INFO:
    167             return Level.INFO;
    168         case WARN:
    169             return Level.WARN;
    170         case ERROR:
    171             return Level.ERROR;
    172         case FATAL:
    173             return Level.FATAL;
    174         case OFF:
    175             return Level.OFF;
    176         default:
    177             // TODO Should this be an IllegalStateException?
    178             return Level.OFF;
    179         }
    180     }
    181
    182     public final Priority getChainedPriority() {
    183         return getEffectiveLevel();
    184     }
    185
    186     public final Level getLevel() {
    187         return getEffectiveLevel();
    188     }
    189
    190     public void setLevel(final Level level) {
    191         logger.setLevel(org.apache.logging.log4j.Level.toLevel(level.levelStr));
    192     }
    193
    194     public final Level getPriority() {
    195         return getEffectiveLevel();
    196     }
    197
    198     public void setPriority(final Priority priority) {
    199         logger.setLevel(org.apache.logging.log4j.Level.toLevel(priority.levelStr));
    200     }
    201
    202     public void debug(final Object message) {
    203         maybeLog(FQCN, org.apache.logging.log4j.Level.DEBUG, message, null);
    204     }
    205
    206     public void debug(final Object message, final Throwable t) {
    207         maybeLog(FQCN, org.apache.logging.log4j.Level.DEBUG, message, t);
    208     }
    209
    210     public boolean isDebugEnabled() {
    211         return logger.isDebugEnabled();
    212     }
    213
    214     public void error(final Object message) {
    215         maybeLog(FQCN, org.apache.logging.log4j.Level.ERROR, message, null);
    216     }
    217
    218     public void error(final Object message, final Throwable t) {
    219         maybeLog(FQCN, org.apache.logging.log4j.Level.ERROR, message, t);
    220     }
    221
    222     public boolean isErrorEnabled() {
    223         return logger.isErrorEnabled();
    224     }
    225
    226     public void warn(final Object message) {
    227         maybeLog(FQCN, org.apache.logging.log4j.Level.WARN, message, null);
    228     }
    229
    230     public void warn(final Object message, final Throwable t) {
    231         maybeLog(FQCN, org.apache.logging.log4j.Level.WARN, message, t);
    232     }
    233
    234     public boolean isWarnEnabled() {
    235         return logger.isWarnEnabled();
    236     }
    237
    238     public void fatal(final Object message) {
    239         maybeLog(FQCN, org.apache.logging.log4j.Level.FATAL, message, null);
    240     }
    241
    242     public void fatal(final Object message, final Throwable t) {
    243         maybeLog(FQCN, org.apache.logging.log4j.Level.FATAL, message, t);
    244     }
    245
    246     public boolean isFatalEnabled() {
    247         return logger.isFatalEnabled();
    248     }
    249
    250     public void info(final Object message) {
    251         maybeLog(FQCN, org.apache.logging.log4j.Level.INFO, message, null);
    252     }
    253
    254     public void info(final Object message, final Throwable t) {
    255         maybeLog(FQCN, org.apache.logging.log4j.Level.INFO, message, t);
    256     }
    257
    258     public boolean isInfoEnabled() {
    259         return logger.isInfoEnabled();
    260     }
    261
    262     public void trace(final Object message) {
    263         maybeLog(FQCN, org.apache.logging.log4j.Level.TRACE, message, null);
    264     }
    265
    266     public void trace(final Object message, final Throwable t) {
    267         maybeLog(FQCN, org.apache.logging.log4j.Level.TRACE, message, t);
    268     }
    269
    270     public boolean isTraceEnabled() {
    271         return logger.isTraceEnabled();
    272     }
    273
    274     public boolean isEnabledFor(final Priority level) {
    275         final org.apache.logging.log4j.Level lvl = org.apache.logging.log4j.Level.toLevel(level.toString());
    276         return isEnabledFor(lvl);
    277     }
    278
    279     /**
    280      * No-op implementation.
    281      * @param appender The Appender to add.
    282      */
    283     public void addAppender(final Appender appender) {
    284     }
    285
    286     /**
    287      * No-op implementation.
    288      * @param event The logging event.
    289      */
    290     public void callAppenders(final LoggingEvent event) {
    291     }
    292
    293     @SuppressWarnings("rawtypes")
    294     public Enumeration getAllAppenders() {
    295         return NullEnumeration.getInstance();
    296     }
    297
    298     /**
    299      * No-op implementation.
    300      * @param name The name of the Appender.
    301      * @return null.
    302      */
    303     public Appender getAppender(final String name) {
    304         return null;
    305     }
    306
    307     /**
    308      Is the appender passed as parameter attached to this category?
    309      * @param appender The Appender to add.
    310      * @return true if the appender is attached.
    311      */
    312     public boolean isAttached(final Appender appender) {
    313         return false;
    314     }
    315
    316     /**
    317      * No-op implementation.
    318      */
    319     public void removeAllAppenders() {
    320     }
    321
    322     /**
    323      * No-op implementation.
    324      * @param appender The Appender to remove.
    325      */
    326     public void removeAppender(final Appender appender) {
    327     }
    328
    329     /**
    330      * No-op implementation.
    331      * @param name The Appender to remove.
    332      */
    333     public void removeAppender(final String name) {
    334     }
    335
    336     /**
    337      * No-op implementation.
    338      */
    339     public static void shutdown() {
    340     }
    341
    342
    343     public void forcedLog(final String fqcn, final Priority level, final Object message, final Throwable t) {
    344         final org.apache.logging.log4j.Level lvl = org.apache.logging.log4j.Level.toLevel(level.toString());
    345         final Message msg = message instanceof Message ? (Message) message : new ObjectMessage(message);
    346         logger.logMessage(fqcn, lvl, null, msg, t);
    347     }
    348
    349     public boolean exists(final String name) {
    350         return PrivateManager.getContext().hasLogger(name);
    351     }
    352
    353     public boolean getAdditivity() {
    354         return logger.isAdditive();
    355     }
    356
    357     public void setAdditivity(final boolean additivity) {
    358         logger.setAdditive(additivity);
    359     }
    360
    361     public void setResourceBundle(final ResourceBundle bundle) {
    362         this.bundle = bundle;
    363     }
    364
    365     public ResourceBundle getResourceBundle() {
    366         if (bundle != null) {
    367             return bundle;
    368         }
    369         String name = logger.getName();
    370         final ConcurrentMap<String, Logger> loggers = getLoggersMap(logger.getContext());
    371         while ((name = NameUtil.getSubName(name)) != null) {
    372             if (loggers.containsKey(name)) {
    373                 final ResourceBundle rb = loggers.get(name).bundle;
    374                 if (rb != null) {
    375                     return rb;
    376                 }
    377             }
    378         }
    379         return null;
    380     }
    381
    382     /**
    383      If <code>assertion</code> parameter is {@code false}, then
    384      logs <code>msg</code> as an {@link #error(Object) error} statement.
    385
    386      <p>The <code>assert</code> method has been renamed to
    387      <code>assertLog</code> because <code>assert</code> is a language
    388      reserved word in JDK 1.4.
    389
    390      @param assertion The assertion.
    391      @param msg The message to print if <code>assertion</code> is
    392      false.
    393
    394      @since 1.2
    395      */
    396     public void assertLog(final boolean assertion, final String msg) {
    397         if (!assertion) {
    398             this.error(msg);
    399         }
    400     }
    401
    402     public void l7dlog(final Priority priority, final String key, final Throwable t) {
    403         if (isEnabledFor(priority)) {
    404             final Message msg = new LocalizedMessage(bundle, key, null);
    405             forcedLog(FQCN, priority, msg, t);
    406         }
    407     }
    408
    409     public void l7dlog(final Priority priority, final String key, final Object[] params, final Throwable t) {
    410         if (isEnabledFor(priority)) {
    411             final Message msg = new LocalizedMessage(bundle, key, params);
    412             forcedLog(FQCN, priority, msg, t);
    413         }
    414     }
    415
    416     public void log(final Priority priority, final Object message, final Throwable t) {
    417         if (isEnabledFor(priority)) {
    418             final Message msg = new ObjectMessage(message);
    419             forcedLog(FQCN, priority, msg, t);
    420         }
    421     }
    422
    423     public void log(final Priority priority, final Object message) {
    424         if (isEnabledFor(priority)) {
    425             final Message msg = new ObjectMessage(message);
    426             forcedLog(FQCN, priority, msg, null);
    427         }
    428     }
    429
    430     public void log(final String fqcn, final Priority priority, final Object message, final Throwable t) {
    431         if (isEnabledFor(priority)) {
    432             final Message msg = new ObjectMessage(message);
    433             forcedLog(fqcn, priority, msg, t);
    434         }
    435     }
    436
    437     private void maybeLog(final String fqcn, final org.apache.logging.log4j.Level level,
    438             final Object message, final Throwable throwable) {
    439         if (logger.isEnabled(level, null, message, throwable)) {
    440             logger.logMessage(FQCN, level, null, new ObjectMessage(message), throwable);
    441         }
    442     }
    443
    444     /**
    445      * Private logger factory.
    446      */
    447     private static class PrivateFactory implements LoggerFactory {
    448
    449         @Override
    450         public Logger makeNewLoggerInstance(final LoggerContext context, final String name) {
    451             return new Logger(context, name);
    452         }
    453     }
    454
    455     /**
    456      * Private LogManager.
    457      */
    458     private static class PrivateManager extends org.apache.logging.log4j.LogManager {
    459         private static final String FQCN = Category.class.getName();
    460
    461         public static org.apache.logging.log4j.spi.LoggerContext getContext() {
    462             return getContext(FQCN, false);
    463         }
    464
    465         public static org.apache.logging.log4j.Logger getLogger(final String name) {
    466             return getLogger(FQCN, name);
    467         }
    468     }
    469
    470     private boolean isEnabledFor(final org.apache.logging.log4j.Level level) {
    471         return logger.isEnabled(level, null, null);
    472     }
    473
    474 }