001    package org.apache.ojb.broker.util.logging;
002    
003    /* Copyright 2002-2005 The Apache Software Foundation
004     *
005     * Licensed under the Apache License, Version 2.0 (the "License");
006     * you may not use this file except in compliance with the License.
007     * You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    import java.net.URL;
019    import java.util.Enumeration;
020    
021    import org.apache.log4j.LogManager;
022    import org.apache.log4j.Level;
023    import org.apache.log4j.PropertyConfigurator;
024    import org.apache.ojb.broker.util.ClassHelper;
025    import org.apache.ojb.broker.util.configuration.Configuration;
026    import org.apache.ojb.broker.util.configuration.ConfigurationException;
027    
028    /**
029     * This is a Logger implementation based on Log4j.
030     * It can be enabled by putting
031     * LoggerClass=org.apache.ojb.broker.util.logging.Log4jLoggerImpl
032     * in the OJB .properties file. <br>
033     * If you want log4j to initialize from a property file you can add
034     * LoggerConfigFile=log4j.properties to the org.apache.ojb.properties file.
035     * the logger only initializes log4j if the application hasn't done it yet
036     *
037     * You can find sample log4j.properties file in the log4j web site
038     * http://jakarta.apache.org/log4j
039     * in the javadoc look for org.apache.log4j.examples
040     *
041     * @author Bertrand
042     * @author Thomas Mahler
043     * @version $Id: Log4jLoggerImpl.java,v 1.1 2007-08-24 22:17:32 ewestfal Exp $
044     */
045    public class Log4jLoggerImpl implements Logger
046    {
047            static private final String FQCN = Log4jLoggerImpl.class.getName();
048        /** flag about log4j configuration state */
049        private static boolean log4jConfigured = false;
050    
051        private transient org.apache.log4j.Logger logger;
052            private String name;
053    
054        /** Helper method to check if log4j is already configured */
055        private static synchronized boolean isLog4JConfigured()
056        {
057            if(!log4jConfigured)
058            {
059                Enumeration en = org.apache.log4j.Logger.getRootLogger().getAllAppenders();
060    
061                if (!(en instanceof org.apache.log4j.helpers.NullEnumeration))
062                {
063                    log4jConfigured = true;
064                }
065                else
066                {
067                    Enumeration cats = LogManager.getCurrentLoggers();
068                    while (cats.hasMoreElements())
069                    {
070                        org.apache.log4j.Logger c = (org.apache.log4j.Logger) cats.nextElement();
071                        if (!(c.getAllAppenders() instanceof org.apache.log4j.helpers.NullEnumeration))
072                        {
073                            log4jConfigured = true;
074                        }
075                    }
076                }
077                if(log4jConfigured)
078                {
079                    String msg = "Log4J is already configured, will not search for log4j properties file";
080                    LoggerFactory.getBootLogger().info(msg);
081                }
082                else
083                {
084                    LoggerFactory.getBootLogger().info("Log4J is not configured");
085                }
086            }
087            return log4jConfigured;
088        }
089    
090        /**
091         * Initialization of log4j <br>
092         * <b>NOTE</b>  - if log4j property file is called log4j.properties then
093         * log4j will be configured already.
094         */
095        private static synchronized void initializeLog4JSubSystem(String configFile)
096        {
097            LoggerFactory.getBootLogger().info("Initializing Log4J using file: '" + configFile + "'");
098            if(configFile == null || "".equals(configFile.trim()))
099            {
100                // no configuration available
101                LoggerFactory.getBootLogger().warn("No log4j configuration file specified");
102            }
103            else
104            {
105                // try resource look in classpath
106                URL url = ClassHelper.getResource(configFile);
107                LoggerFactory.getBootLogger().info("Initializing Log4J : resource from config file:" + url);
108                if (url != null)
109                {
110                    PropertyConfigurator.configure(url);
111                }
112                // if file is not in classpath try ordinary filesystem lookup
113                else
114                {
115                    PropertyConfigurator.configure(configFile);
116                }
117            }
118            log4jConfigured = true;
119        }
120    
121            public Log4jLoggerImpl(String name)
122            {
123                    this.name = name;
124            }
125    
126        /**
127             * @see org.apache.ojb.broker.util.configuration.Configurable#configure(Configuration)
128         * This method must be performed by LogFactory after creating a logger instance.
129             */
130            public void configure(Configuration config) throws ConfigurationException
131            {
132            if (!isLog4JConfigured())
133            {
134                LoggingConfiguration lc = (LoggingConfiguration) config;
135                initializeLog4JSubSystem(lc.getLoggerConfigFile());
136            }
137            }
138    
139        /**
140             * Gets the logger.
141         *
142             * @return Returns a Category
143             */
144            private org.apache.log4j.Logger getLogger()
145            {
146            /*
147            Logger interface extends Serializable, thus Log field is
148            declared 'transient' and we have to null-check
149                    */
150                    if (logger == null)
151                    {
152                            logger = org.apache.log4j.Logger.getLogger(name);
153                    }
154                    return logger;
155            }
156    
157            public String getName()
158            {
159                    return name;
160            }
161    
162            private Level getLevel()
163            {
164                    return getLogger().getEffectiveLevel();
165            }
166    
167            /**
168             * generate a message for loglevel DEBUG
169         *
170             * @param pObject the message Object
171             */
172            public final void debug(Object pObject)
173            {
174                    getLogger().log(FQCN, Level.DEBUG, pObject, null);
175            }
176    
177            /**
178             * generate a message for loglevel INFO
179         *
180             * @param pObject the message Object
181             */
182            public final void info(Object pObject)
183            {
184                    getLogger().log(FQCN, Level.INFO, pObject, null);
185            }
186    
187            /**
188             * generate a message for loglevel WARN
189         *
190             * @param pObject the message Object
191             */
192            public final void warn(Object pObject)
193            {
194                    getLogger().log(FQCN, Level.WARN, pObject, null);
195            }
196    
197            /**
198             * generate a message for loglevel ERROR
199         *
200             * @param pObject the message Object
201             */
202            public final void error(Object pObject)
203            {
204                    getLogger().log(FQCN, Level.ERROR, pObject, null);
205            }
206    
207            /**
208             * generate a message for loglevel FATAL
209         *
210             * @param pObject the message Object
211             */
212            public final void fatal(Object pObject)
213            {
214                    getLogger().log(FQCN, Level.FATAL, pObject, null);
215            }
216    
217            public void debug(Object message, Throwable obj)
218            {
219                    getLogger().log(FQCN, Level.DEBUG, message, obj);
220            }
221    
222            public void error(Object message, Throwable obj)
223            {
224                    getLogger().log(FQCN, Level.ERROR, message, obj);
225            }
226    
227            public void fatal(Object message, Throwable obj)
228            {
229                    getLogger().log(FQCN, Level.FATAL, message, obj);
230            }
231    
232            public void info(Object message, Throwable obj)
233            {
234                    getLogger().log(FQCN, Level.INFO, message, obj);
235            }
236    
237            public void warn(Object message, Throwable obj)
238            {
239                    getLogger().log(FQCN, Level.WARN, message, obj);
240            }
241    
242            public void safeDebug(String message, Object obj)
243            {
244                    if (Level.DEBUG.isGreaterOrEqual(getLevel()))
245                    {
246                            String toString = null;
247                            if (obj != null)
248                            {
249                                    try
250                                    {
251                                            toString = obj.toString();
252                                    }
253                                    catch (Throwable t)
254                                    {
255                                            toString = "BAD toString() impl for " + obj.getClass().getName();
256                                    }
257                            }
258                            debug(message + " : " + toString);
259                    }
260            }
261    
262            public void safeDebug(String message, Object obj, Throwable throwable)
263            {
264                    if (Level.DEBUG.isGreaterOrEqual(getLevel()))
265                    {
266                            String toString = null;
267                            if (obj != null)
268                            {
269                                    try
270                                    {
271                                            toString = obj.toString();
272                                    }
273                                    catch (Throwable t)
274                                    {
275                                            toString = "BAD toString() impl for " + obj.getClass().getName();
276                                    }
277                            }
278                            debug(message + " : " + toString, throwable);
279                    }
280            }
281    
282            public void safeInfo(String message, Object obj)
283            {
284                    if (Level.INFO.isGreaterOrEqual(getLevel()))
285                    {
286                            String toString = null;
287                            if (obj != null)
288                            {
289                                    try
290                                    {
291                                            toString = obj.toString();
292                                    }
293                                    catch (Throwable t)
294                                    {
295                                            toString = "BAD toString() impl for " + obj.getClass().getName();
296                                    }
297                            }
298                            info(message + " : " + toString);
299                    }
300            }
301    
302            public void safeInfo(String message, Object obj, Throwable throwable)
303            {
304                    if (Level.INFO.isGreaterOrEqual(getLevel()))
305                    {
306                            String toString = null;
307                            if (obj != null)
308                            {
309                                    try
310                                    {
311                                            toString = obj.toString();
312                                    }
313                                    catch (Throwable t)
314                                    {
315                                            toString = "BAD toString() impl for " + obj.getClass().getName();
316                                    }
317                            }
318                            info(message + " : " + toString, throwable);
319                    }
320            }
321    
322            public void safeWarn(String message, Object obj)
323            {
324                    if (Level.WARN.isGreaterOrEqual(getLevel()))
325                    {
326                            String toString;
327                            try
328                            {
329                                    toString = obj.toString();
330                            }
331                            catch (Throwable t)
332                            {
333                                    toString = "BAD toString() impl for " + obj.getClass().getName();
334                            }
335                             warn(message + " : " + toString);
336                    }
337            }
338    
339            public void safeWarn(String message, Object obj, Throwable throwable)
340            {
341                    if (Level.WARN.isGreaterOrEqual(getLevel()))
342                    {
343                            String toString;
344                            try
345                            {
346                                    toString = obj.toString();
347                            }
348                            catch (Throwable t)
349                            {
350                                    toString = "BAD toString() impl for " + obj.getClass().getName();
351                            }
352                            warn(message + " : " + toString, throwable);
353                    }
354            }
355    
356            public void safeError(String message, Object obj)
357            {
358                    if (Level.ERROR.isGreaterOrEqual(getLevel()))
359                    {
360                            String toString;
361                            try
362                            {
363                                    toString = obj.toString();
364                            }
365                            catch (Throwable t)
366                            {
367                                    toString = "BAD toString() impl for " + obj.getClass().getName();
368                            }
369                            error(message + " : " + toString);
370                    }
371            }
372    
373            public void safeError(String message, Object obj, Throwable throwable)
374            {
375                    if (Level.ERROR.isGreaterOrEqual(getLevel()))
376                    {
377                            String toString;
378                            try
379                            {
380                                    toString = obj.toString();
381                            }
382                            catch (Throwable t)
383                            {
384                                    toString = "BAD toString() impl for " + obj.getClass().getName();
385                            }
386                            error(message + " : " + toString, throwable);
387                    }
388            }
389    
390            public void safeFatal(String message, Object obj)
391            {
392                    if (Level.FATAL.isGreaterOrEqual(getLevel()))
393                    {
394                            String toString;
395                            try
396                            {
397                                    toString = obj.toString();
398                            }
399                            catch (Throwable t)
400                            {
401                                    toString = "BAD toString() impl for " + obj.getClass().getName();
402                            }
403                            fatal(message + " : " + toString);
404                    }
405            }
406    
407            public void safeFatal(String message, Object obj, Throwable throwable)
408            {
409                    if (Level.FATAL.isGreaterOrEqual(getLevel()))
410                    {
411                            String toString;
412                            try
413                            {
414                                    toString = obj.toString();
415                            }
416                            catch (Throwable t)
417                            {
418                                    toString = "BAD toString() impl for " + obj.getClass().getName();
419                            }
420                            fatal(message + " : " + toString, throwable);
421                    }
422            }
423    
424            public boolean isDebugEnabled()
425            {
426                    return getLogger().isDebugEnabled();
427            }
428    
429            public boolean isEnabledFor(int priority)
430            {
431            org.apache.log4j.Logger log4j = getLogger();
432            switch(priority)
433            {
434                case Logger.DEBUG: return log4j.isDebugEnabled();
435                case Logger.INFO: return log4j.isInfoEnabled();
436                case Logger.WARN: return log4j.isEnabledFor(org.apache.log4j.Priority.WARN);
437                case Logger.ERROR: return log4j.isEnabledFor(org.apache.log4j.Priority.ERROR);
438                case Logger.FATAL: return log4j.isEnabledFor(org.apache.log4j.Priority.FATAL);
439            }
440            return false;
441        }
442    }