1   // ========================================================================
2   // Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
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   // http://www.apache.org/licenses/LICENSE-2.0
8   // Unless required by applicable law or agreed to in writing, software
9   // distributed under the License is distributed on an "AS IS" BASIS,
10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  // See the License for the specific language governing permissions and
12  // limitations under the License.
13  // ========================================================================
14  
15  package org.mortbay.log;
16  import java.lang.reflect.Method;
17  
18  import org.mortbay.util.Loader;
19  
20  
21  
22  /*-----------------------------------------------------------------------*/
23  /** Logging.
24   * This class provides a static logging interface.  If an instance of the 
25   * org.slf4j.Logger class is found on the classpath, the static log methods
26   * are directed to a slf4j logger for "org.mortbay.log".   Otherwise the logs
27   * are directed to stderr.
28   * 
29   * If the system property VERBOSE is set, then ignored exceptions are logged in detail.
30   * 
31   */
32  public class Log 
33  {    
34      private static final String[] __nestedEx =
35          {"getTargetException","getTargetError","getException","getRootCause"};
36      /*-------------------------------------------------------------------*/
37      private static final Class[] __noArgs=new Class[0];
38      public final static String EXCEPTION= "EXCEPTION ";
39      public final static String IGNORED= "IGNORED";
40      public final static String IGNORED_FMT= "IGNORED: {}";
41      public final static String NOT_IMPLEMENTED= "NOT IMPLEMENTED ";
42      
43      private static String __logClass=System.getProperty("org.mortbay.log.class","org.mortbay.log.Slf4jLog");
44      private static boolean __verbose = System.getProperty("VERBOSE",null)!=null;
45      private static boolean __ignored = System.getProperty("IGNORED",null)!=null;
46      private static Logger __log;
47     
48      static
49      {
50          initialize();
51      }
52      
53      public static void initialize()
54      {
55          Class log_class=null;
56          try
57          {
58              log_class=Loader.loadClass(Log.class, __logClass);
59              if (__log==null || !__log.getClass().equals(log_class))
60              {
61                  __log=(Logger) log_class.newInstance();
62                  __log.info("Logging to {} via {}",__log,log_class.getName());
63              }
64          }
65          catch(Exception e)
66          {
67              if (__log==null)
68              {
69                  log_class=StdErrLog.class;
70                  __log=new StdErrLog();
71                  __log.info("Logging to {} via {}",__log,log_class.getName());
72                  if(__verbose)
73                      e.printStackTrace();
74              }
75          }
76          
77      }
78      
79      public static void setLog(Logger log)
80      {
81          Log.__log=log;
82      }
83      
84      public static Logger getLog()
85      {
86          return __log;
87      }
88      
89      
90      public static void debug(Throwable th)
91      {
92          if (__log==null || !isDebugEnabled())
93              return;
94          __log.debug(EXCEPTION,th);
95          unwind(th);
96      }
97  
98      public static void debug(String msg)
99      {
100         if (__log==null)
101             return;
102         __log.debug(msg,null,null);
103     }
104     
105     public static void debug(String msg,Object arg)
106     {
107         if (__log==null)
108             return;
109         __log.debug(msg,arg,null);
110     }
111     
112     public static void debug(String msg,Object arg0, Object arg1)
113     {
114         if (__log==null)
115             return;
116         __log.debug(msg,arg0,arg1);
117     }
118     
119     /* ------------------------------------------------------------ */
120     /**
121      * Ignore an exception unless trace is enabled.
122      * This works around the problem that log4j does not support the trace level.
123      */
124     public static void ignore(Throwable th)
125     {
126         if (__log==null)
127             return;
128         if (__ignored)
129         {
130             __log.warn(IGNORED,th);
131             unwind(th);
132         }
133         else if (__verbose)
134         {
135             __log.warn(IGNORED,th);
136             unwind(th);
137         }
138     }
139     
140     public static void info(String msg)
141     {
142         if (__log==null)
143             return;
144         __log.info(msg,null,null);
145     }
146     
147     public static void info(String msg,Object arg)
148     {
149         if (__log==null)
150             return;
151         __log.info(msg,arg,null);
152     }
153     
154     public static void info(String msg,Object arg0, Object arg1)
155     {
156         if (__log==null)
157             return;
158         __log.info(msg,arg0,arg1);
159     }
160     
161     public static boolean isDebugEnabled()
162     {
163         if (__log==null)
164             return false;
165         return __log.isDebugEnabled();
166     }
167     
168     public static void warn(String msg)
169     {
170         if (__log==null)
171             return;
172         __log.warn(msg,null,null);
173     }
174     
175     public static void warn(String msg,Object arg)
176     {
177         if (__log==null)
178             return;
179         __log.warn(msg,arg,null);        
180     }
181     
182     public static void warn(String msg,Object arg0, Object arg1)
183     {
184         if (__log==null)
185             return;
186         __log.warn(msg,arg0,arg1);        
187     }
188     
189     public static void warn(String msg, Throwable th)
190     {
191         if (__log==null)
192             return;
193         __log.warn(msg,th);
194         unwind(th);
195     }
196 
197     public static void warn(Throwable th)
198     {
199         if (__log==null)
200             return;
201         __log.warn(EXCEPTION,th);
202         unwind(th);
203     }
204 
205     /** Obtain a named Logger.
206      * Obtain a named Logger or the default Logger if null is passed.
207      */
208     public static Logger getLogger(String name)
209     {
210         if (__log==null)
211             return __log;
212         if (name==null)
213           return __log;
214         return __log.getLogger(name);
215     }
216 
217     private static void unwind(Throwable th)
218     {
219         if (th==null)
220             return;
221         for (int i=0;i<__nestedEx.length;i++)
222         {
223             try
224             {
225                 Method get_target = th.getClass().getMethod(__nestedEx[i],__noArgs);
226                 Throwable th2=(Throwable)get_target.invoke(th,(Object[])null);
227                 if (th2!=null && th2!=th)
228                     warn("Nested in "+th+":",th2);
229             }
230             catch(Exception ignore){}
231         }
232     }
233     
234 
235 }
236