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