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