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