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 TRACE:
161                 return Level.TRACE;
162             case DEBUG:
163                 return Level.DEBUG;
164             case INFO:
165                 return Level.INFO;
166             case WARN:
167                 return Level.WARN;
168             case ERROR:
169                 return Level.ERROR;
170             case FATAL:
171                 return Level.FATAL;
172             default:
173                 return Level.OFF;
174         }
175     }
176 
177     public final Priority getChainedPriority() {
178         return getEffectiveLevel();
179     }
180 
181     public final Level getLevel() {
182         return getEffectiveLevel();
183     }
184 
185     public void setLevel(final Level level) {
186         logger.setLevel(org.apache.logging.log4j.Level.toLevel(level.levelStr));
187     }
188 
189     public final Level getPriority() {
190         return getEffectiveLevel();
191     }
192 
193     public void setPriority(final Priority priority) {
194         logger.setLevel(org.apache.logging.log4j.Level.toLevel(priority.levelStr));
195     }
196 
197     public void debug(final Object message) {
198         maybeLog(FQCN, org.apache.logging.log4j.Level.DEBUG, message, null);
199     }
200 
201     public void debug(final Object message, final Throwable t) {
202         maybeLog(FQCN, org.apache.logging.log4j.Level.DEBUG, message, t);
203     }
204 
205     public boolean isDebugEnabled() {
206         return logger.isDebugEnabled();
207     }
208 
209     public void error(final Object message) {
210         maybeLog(FQCN, org.apache.logging.log4j.Level.ERROR, message, null);
211     }
212 
213     public void error(final Object message, final Throwable t) {
214         maybeLog(FQCN, org.apache.logging.log4j.Level.ERROR, message, t);
215     }
216 
217     public boolean isErrorEnabled() {
218         return logger.isErrorEnabled();
219     }
220 
221     public void warn(final Object message) {
222         maybeLog(FQCN, org.apache.logging.log4j.Level.WARN, message, null);
223     }
224 
225     public void warn(final Object message, final Throwable t) {
226         maybeLog(FQCN, org.apache.logging.log4j.Level.WARN, message, t);
227     }
228 
229     public boolean isWarnEnabled() {
230         return logger.isWarnEnabled();
231     }
232 
233     public void fatal(final Object message) {
234         maybeLog(FQCN, org.apache.logging.log4j.Level.FATAL, message, null);
235     }
236 
237     public void fatal(final Object message, final Throwable t) {
238         maybeLog(FQCN, org.apache.logging.log4j.Level.FATAL, message, t);
239     }
240 
241     public boolean isFatalEnabled() {
242         return logger.isFatalEnabled();
243     }
244 
245     public void info(final Object message) {
246         maybeLog(FQCN, org.apache.logging.log4j.Level.INFO, message, null);
247     }
248 
249     public void info(final Object message, final Throwable t) {
250         maybeLog(FQCN, org.apache.logging.log4j.Level.INFO, message, t);
251     }
252 
253     public boolean isInfoEnabled() {
254         return logger.isInfoEnabled();
255     }
256 
257     public void trace(final Object message) {
258         maybeLog(FQCN, org.apache.logging.log4j.Level.TRACE, message, null);
259     }
260 
261     public void trace(final Object message, final Throwable t) {
262         maybeLog(FQCN, org.apache.logging.log4j.Level.TRACE, message, t);
263     }
264 
265     public boolean isTraceEnabled() {
266         return logger.isTraceEnabled();
267     }
268 
269     public boolean isEnabledFor(final Priority level) {
270         final org.apache.logging.log4j.Level lvl = org.apache.logging.log4j.Level.toLevel(level.toString());
271         return isEnabledFor(lvl);
272     }
273 
274     /**
275      * No-op implementation.
276      * @param appender The Appender to add.
277      */
278     public void addAppender(final Appender appender) {
279     }
280 
281     /**
282      * No-op implementation.
283      * @param event The logging event.
284      */
285     public void callAppenders(final LoggingEvent event) {
286     }
287 
288     @SuppressWarnings("rawtypes")
289     public Enumeration getAllAppenders() {
290         return NullEnumeration.getInstance();
291     }
292 
293     /**
294      * No-op implementation.
295      * @param name The name of the Appender.
296      * @return null.
297      */
298     public Appender getAppender(final String name) {
299         return null;
300     }
301 
302     /**
303      Is the appender passed as parameter attached to this category?
304      * @param appender The Appender to add.
305      * @return true if the appender is attached.
306      */
307     public boolean isAttached(final Appender appender) {
308         return false;
309     }
310 
311     /**
312      * No-op implementation.
313      */
314     public void removeAllAppenders() {
315     }
316 
317     /**
318      * No-op implementation.
319      * @param appender The Appender to remove.
320      */
321     public void removeAppender(final Appender appender) {
322     }
323 
324     /**
325      * No-op implementation.
326      * @param name The Appender to remove.
327      */
328     public void removeAppender(final String name) {
329     }
330 
331     /**
332      * No-op implementation.
333      */
334     public static void shutdown() {
335     }
336 
337 
338     public void forcedLog(final String fqcn, final Priority level, final Object message, final Throwable t) {
339         final org.apache.logging.log4j.Level lvl = org.apache.logging.log4j.Level.toLevel(level.toString());
340         final Message msg = message instanceof Message ? (Message) message : new ObjectMessage(message);
341         logger.logMessage(fqcn, lvl, null, msg, t);
342     }
343 
344     public boolean exists(final String name) {
345         return PrivateManager.getContext().hasLogger(name);
346     }
347 
348     public boolean getAdditivity() {
349         return logger.isAdditive();
350     }
351 
352     public void setAdditivity(final boolean additivity) {
353         logger.setAdditive(additivity);
354     }
355 
356     public void setResourceBundle(final ResourceBundle bundle) {
357         this.bundle = bundle;
358     }
359 
360     public ResourceBundle getResourceBundle() {
361         if (bundle != null) {
362             return bundle;
363         }
364         String name = logger.getName();
365         final ConcurrentMap<String, Logger> loggers = getLoggersMap(logger.getContext());
366         while ((name = NameUtil.getSubName(name)) != null) {
367             if (loggers.containsKey(name)) {
368                 final ResourceBundle rb = loggers.get(name).bundle;
369                 if (rb != null) {
370                     return rb;
371                 }
372             }
373         }
374         return null;
375     }
376 
377     /**
378      If <code>assertion</code> parameter is {@code false}, then
379      logs <code>msg</code> as an {@link #error(Object) error} statement.
380 
381      <p>The <code>assert</code> method has been renamed to
382      <code>assertLog</code> because <code>assert</code> is a language
383      reserved word in JDK 1.4.
384 
385      @param assertion The assertion.
386      @param msg The message to print if <code>assertion</code> is
387      false.
388 
389      @since 1.2
390      */
391     public void assertLog(final boolean assertion, final String msg) {
392         if (!assertion) {
393             this.error(msg);
394         }
395     }
396 
397     public void l7dlog(final Priority priority, final String key, final Throwable t) {
398         if (isEnabledFor(priority)) {
399             final Message msg = new LocalizedMessage(bundle, key, null);
400             forcedLog(FQCN, priority, msg, t);
401         }
402     }
403 
404     public void l7dlog(final Priority priority, final String key, final Object[] params, final Throwable t) {
405         if (isEnabledFor(priority)) {
406             final Message msg = new LocalizedMessage(bundle, key, params);
407             forcedLog(FQCN, priority, msg, t);
408         }
409     }
410 
411     public void log(final Priority priority, final Object message, final Throwable t) {
412         if (isEnabledFor(priority)) {
413             final Message msg = new ObjectMessage(message);
414             forcedLog(FQCN, priority, msg, t);
415         }
416     }
417 
418     public void log(final Priority priority, final Object message) {
419         if (isEnabledFor(priority)) {
420             final Message msg = new ObjectMessage(message);
421             forcedLog(FQCN, priority, msg, null);
422         }
423     }
424 
425     public void log(final String fqcn, final Priority priority, final Object message, final Throwable t) {
426         if (isEnabledFor(priority)) {
427             final Message msg = new ObjectMessage(message);
428             forcedLog(fqcn, priority, msg, t);
429         }
430     }
431 
432     private void maybeLog(final String fqcn, final org.apache.logging.log4j.Level level,
433             final Object message, final Throwable throwable) {
434         if (logger.isEnabled(level, null, message, throwable)) {
435             logger.logMessage(FQCN, level, null, new ObjectMessage(message), throwable);
436         }
437     }
438 
439     /**
440      * Private logger factory.
441      */
442     private static class PrivateFactory implements LoggerFactory {
443 
444         @Override
445         public Logger makeNewLoggerInstance(final LoggerContext context, final String name) {
446             return new Logger(context, name);
447         }
448     }
449 
450     /**
451      * Private LogManager.
452      */
453     private static class PrivateManager extends org.apache.logging.log4j.LogManager {
454         private static final String FQCN = Category.class.getName();
455 
456         public static org.apache.logging.log4j.spi.LoggerContext getContext() {
457             return getContext(FQCN, false);
458         }
459 
460         public static org.apache.logging.log4j.Logger getLogger(final String name) {
461             return getLogger(FQCN, name);
462         }
463     }
464 
465     private boolean isEnabledFor(final org.apache.logging.log4j.Level level) {
466         return logger.isEnabled(level, null, null);
467     }
468 
469 }