1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.log4j;
17  
18  import org.slf4j.LoggerFactory;
19  import org.slf4j.Marker;
20  import org.slf4j.MarkerFactory;
21  import org.slf4j.spi.LocationAwareLogger;
22  
23  /**
24   * <p>
25   * This class is a minimal implementation of the original
26   * <code>org.apache.log4j.Category</code> class (as found in log4j 1.2) 
27   * by delegation of all calls to a {@link org.slf4j.Logger.Logger} instance.
28   * </p>
29   * 
30   * <p>
31   * Log4j's <code>trace</code>, <code>debug()</code>, <code>info()</code>, 
32   * <code>warn()</code>, <code>error()</code> printing methods are directly 
33   * mapped to their SLF4J equivalents. Log4j's <code>fatal()</code> 
34   * printing method is mapped to SLF4J's <code>error()</code> method 
35   * with a FATAL marker.
36   * 
37   * @author S&eacute;bastien Pennec
38   * @author Ceki G&uuml;lc&uuml;
39   */
40  public class Category {
41  
42    private String name;
43  
44    protected org.slf4j.Logger slf4jLogger;
45    private org.slf4j.spi.LocationAwareLogger locationAwareLogger;
46    
47    private static Marker FATAL_MARKER = MarkerFactory.getMarker("FATAL");
48  
49    Category(String name) {
50      this.name = name;
51      slf4jLogger = LoggerFactory.getLogger(name);
52      if(slf4jLogger instanceof LocationAwareLogger) {
53        locationAwareLogger = (LocationAwareLogger) slf4jLogger;
54      }
55    }
56  
57    public static Category getInstance(Class clazz) {
58      return Log4jLoggerFactory.getLogger(clazz.getName());
59    }
60  
61    public static Category getInstance(String name) {
62      return Log4jLoggerFactory.getLogger(name);
63    }
64  
65    /**
66     * Returns the obvious.
67     * 
68     * @return
69     */
70    public String getName() {
71      return name;
72    }
73  
74    /**
75     * Return the level in effect for this category/logger.
76     * 
77     * <p>
78     * The result is computed by simulation.
79     * 
80     * @return
81     */
82    public Level getEffectiveLevel() {
83      if(slf4jLogger.isTraceEnabled()) {
84        return Level.TRACE;
85      }
86      if(slf4jLogger.isDebugEnabled()) {
87        return Level.DEBUG;
88      }
89      if(slf4jLogger.isInfoEnabled()) {
90        return Level.INFO;
91      }
92      if(slf4jLogger.isWarnEnabled()) {
93        return Level.WARN;
94      }
95      return Level.ERROR;
96    }
97  
98    /**
99     * Returns the assigned {@link Level}, if any, for this Category.
100    * This implementation always returns null.
101    * 
102    * @return Level - the assigned Level, can be <code>null</code>.
103    */
104   final public Level getLevel() {
105     return null;
106   }
107 
108 
109   /**
110    * @deprecated Please use {@link #getLevel} instead.
111   */
112   final public Level getPriority() {
113     return null;
114   }
115   
116   /**
117    * Delegates to {@link org.slf4j.Logger#isDebugEnabled} method in  SLF4J
118    */
119   public boolean isDebugEnabled() {
120     return slf4jLogger.isDebugEnabled();
121   }
122 
123   /**
124    * Delegates to {@link org.slf4j.Logger#isInfoEnabled} method in  SLF4J
125    */
126   public boolean isInfoEnabled() {
127     return slf4jLogger.isInfoEnabled();
128   }
129 
130   /**
131    * Delegates tob {@link org.slf4j.Logger#isWarnEnabled} method in  SLF4J
132    */
133   public boolean isWarnEnabled() {
134     return slf4jLogger.isWarnEnabled();
135   }
136   
137   /**
138    * Delegates to {@link org.slf4j.Logger#isErrorEnabled} method in SLF4J
139    */
140   public boolean isErrorEnabled() {
141     return slf4jLogger.isErrorEnabled();
142   }
143   
144 
145   /**
146    * Determines whether the priority passed as parameter is enabled in
147    * the underlying SLF4J logger. Each log4j priority is mapped directly to
148    * its SLF4J equivalent, except for FATAL which is mapped as ERROR. 
149    * 
150    * @param p the priority to check against
151    * @return true if this logger is enabled for the given level, false otherwise.
152    */
153   public boolean isEnabledFor(Priority p) {
154     switch (p.level) {
155     case Level.TRACE_INT:
156       return slf4jLogger.isTraceEnabled();
157     case Level.DEBUG_INT:
158       return slf4jLogger.isDebugEnabled();
159     case Level.INFO_INT:
160       return slf4jLogger.isInfoEnabled();
161     case Level.WARN_INT:
162       return slf4jLogger.isWarnEnabled();
163     case Level.ERROR_INT:
164       return slf4jLogger.isErrorEnabled();
165     case Priority.FATAL_INT:
166       return slf4jLogger.isErrorEnabled();
167     }
168     return false;
169   }
170 
171   
172   /**
173    * Delegates to {@link org.slf4j.Logger#debug(String)} method of
174    * SLF4J.
175    */
176   public void debug(Object message) {
177     // casting to String as SLF4J only accepts String instances, not Object
178     // instances.
179     slf4jLogger.debug(convertToString(message));
180   }
181 
182   /**
183    * Delegates to {@link org.slf4j.Logger#debug(String,Throwable)} 
184    * method in SLF4J.
185    */
186   public void debug(Object message, Throwable t) {
187     slf4jLogger.debug(convertToString(message), t);
188   }
189 
190   /**
191    * Delegates to {@link org.slf4j.Logger#info(String)} 
192    * method in SLF4J.
193    */
194   public void info(Object message) {
195     slf4jLogger.info(convertToString(message));
196   }
197 
198   /**
199    * Delegates to {@link org.slf4j.Logger#info(String,Throwable)} 
200    * method in SLF4J.
201    */
202   public void info(Object message, Throwable t) {
203     slf4jLogger.info(convertToString(message), t);
204   }
205 
206   /**
207    * Delegates to {@link org.slf4j.Logger#warn(String)} 
208    * method in SLF4J.
209    */
210   public void warn(Object message) {
211     slf4jLogger.warn(convertToString(message));
212   }
213 
214   /**
215    * Delegates to {@link org.slf4j.Logger#warn(String,Throwable)} 
216    * method in SLF4J.
217    */
218   public void warn(Object message, Throwable t) {
219     slf4jLogger.warn(convertToString(message), t);
220   }
221 
222   
223   /**
224    * Delegates to {@link org.slf4j.Logger#error(String)} 
225    * method in SLF4J.
226    */
227   public void error(Object message) {
228     slf4jLogger.error(convertToString(message));
229   }
230 
231   /**
232    * Delegates to {@link org.slf4j.Logger#error(String,Throwable)} 
233    * method in SLF4J.
234    */
235   public void error(Object message, Throwable t) {
236     slf4jLogger.error(convertToString(message), t);
237   }
238 
239   /**
240    * Delegates to {@link org.slf4j.Logger#error(String)} 
241    * method in SLF4J.
242    */
243   public void fatal(Object message) {
244     slf4jLogger.error(FATAL_MARKER, convertToString(message));
245   }
246 
247   /**
248    * Delegates to {@link org.slf4j.Logger#error(String,Throwable)} 
249    * method in SLF4J. In addition, the call is marked with a marker named "FATAL".
250    */
251   public void fatal(Object message, Throwable t) {
252     slf4jLogger.error(FATAL_MARKER, convertToString(message), t);
253   }
254 
255   public void log(String FQCN, Priority p, Object msg, Throwable t) {
256     int levelInt = priorityToLevelInt(p);
257     if(locationAwareLogger != null) {
258       if(msg != null) {
259         locationAwareLogger.log(null, FQCN, levelInt, msg.toString(), t); 
260       } else {
261         locationAwareLogger.log(null, FQCN, levelInt, null, t); 
262       }
263     } else {
264       throw new UnsupportedOperationException("The logger ["+slf4jLogger+"] does not seem to be location aware.");
265     }
266    
267   }
268   
269   private int priorityToLevelInt(Priority p) {
270     switch (p.level) {
271     case Level.TRACE_INT:
272       return LocationAwareLogger.TRACE_INT;
273     case Priority.DEBUG_INT:
274       return LocationAwareLogger.DEBUG_INT;
275     case Priority.INFO_INT:
276       return LocationAwareLogger.INFO_INT;
277     case Priority.WARN_INT:
278       return LocationAwareLogger.WARN_INT;
279     case Priority.ERROR_INT:
280       return LocationAwareLogger.ERROR_INT;
281     case Priority.FATAL_INT:
282       return LocationAwareLogger.ERROR_INT;
283     default:
284       throw new IllegalStateException("Unknown Priority " + p);
285     }
286   }
287   
288   protected final String convertToString(Object message) {
289     if (message == null) {
290       return (String)message;
291     } else {
292       return message.toString();
293     }
294   }
295 
296 }