Package org.apache.jetspeed.webapp.logging

Source Code of org.apache.jetspeed.webapp.logging.IsolatedLog4JLogger

/*
* Copyright 2000-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jetspeed.webapp.logging;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.Log4JLogger;
import org.apache.log4j.Hierarchy;

/**
* IsolatedLog4JLogger routes all commons-logging logging using Log4J to an ContextClassLoader
* specific Hierarchy.
* </p>
* <p>
* For web or application servers providing (and enforcing) commons-logging and
* Log4J from a shared context (like JBoss), configuring Log4J loggers and appenders
* from within a (web) application overrides and resets the global
* Log4J LoggerRepository.
* </p>
* <p>
* Capturing root logging for logging events from within the web application
* for example isn't possible using a Log4J propery or xml configuration without
* routing <em>ALL</em> root logging through the new (web application specific)
* configuration.
* </p>
* <p>
* <em>It is possible using the Log4J API directly instead of configuration files,
* but that requires hardcoded knowledge about how the logging is to be done.</em>
* </p>
* <p>
* Furthermore, if another application later on reconfigures the root logging again, the
* current root logging configuration is closed, detached and rerouted to the new configuration.
* </p>
* <p>
* The same applies of course to common named loggers like capturing springframework logging.
* </p>
* <p>
* The only way to prevent this <em>stealing</em> of logging configuration is allowing only
* one log4J configuration for the whole web or application server.<br/>
* As this has to be done in a web or application server specific manner, setting up Jetspeed
* for different servers will become rather complex and difficult to automate.
* </p>
* <p>
* The IsolatedLog4JLogger solves these problems by routing all logging through a statically
* configured ContextClassLoader isolated LoggerRepository.
* </p>
* Using this class requires a commons-logging.properties file in the WEB-INF/classes
* folder containing:
* <pre>
*   org.apache.commons.logging.Log=org.apache.jetspeed.util.IsolatedLog4JLogger
* </pre>
* </p>
* <p>
* During web application initialization, preferably from a ServletContextListener or
* a Servlet init method loaded with a load-on-startup value of 0 (zero), a new
* ContextClassLoader (e.g. web application) specific LoggerRepository as well as
* the initialization of Log4J should be configured as follows:
* <pre>
*   Properties p = new Properties();
*   p.load(new FileInputStream(log4jFile));
*   // Create a new LoggerRepository
*   Hierarchy h = new Hierarchy(new RootCategory(Level.INFO));
*   // Configure the LoggerRepository with our own Log4J configuration
*   new PropertyConfigurator().doConfigure(p,h);
*   // set the LoggerRepository to be used for the current ContextClassLoader
*   IsolatedLog4JLogger.setHierarchy(h);
* </pre>
* Instead of using a PropertyConfigurator a DomConfigurator could be used likewise.
* </p>
* <p>
* TODO: It might be useful to have this utility class available for usage by Portlet
* Applications too. Because this class <em>must</em> be included within a web application
* classpath, a separate jetspeed-tools or jetspeed-utils library will have to be created
* for it (and possibly other utility classes as well) which then can be put in the web
* application lib folder.
* </p>
* @author <a href="mailto:ate@douma.nu">Ate Douma</a>
* @version $Id: IsolatedLog4JLogger.java 502785 2007-02-02 22:58:50Z ate $
*/
public class IsolatedLog4JLogger implements Log
{
    private static Hierarchy hierarchy;
    private static HashMap notIsolatedLoggers = new HashMap();
   
    private Log4JLogger logger; // the wrapped Log4JLogger
   
    public static void setHierarchy(Hierarchy hierarchy)
    {
        synchronized (IsolatedLog4JLogger.class)
        {
            if ( IsolatedLog4JLogger.hierarchy == null )
            {
                IsolatedLog4JLogger.hierarchy = hierarchy;
                if ( notIsolatedLoggers.size() > 0 )
                {
                    // Reroute existing IsolatedLog4JLogger instances
                    // which were created before the new LoggerRepository.
                    // Note: This situation should be prevented as much as
                    //       possible by calling setHierarchy from
                    //       a ServletContextListener or a Servlet its init method
                    //       which has a load-on-startup value of 0 (zero).
                    Iterator iter = notIsolatedLoggers.entrySet().iterator();
                    while (iter.hasNext())
                    {
                        Map.Entry entry = (Map.Entry)iter.next();
                        IsolatedLog4JLogger logger = (IsolatedLog4JLogger)entry.getKey();
                        logger.setLogger(new Log4JLogger(hierarchy.getLogger((String)entry.getValue())));
                    }
                }
                notIsolatedLoggers = null;
            }
        }
    }
   
    public IsolatedLog4JLogger(String name)
    {
        synchronized (IsolatedLog4JLogger.class)
        {
            if ( hierarchy == null )
            {
                // A LogFactory.getLog(name) is called before
                // our ContextClassLoader Hierarchy could be set.
                // Temporarily save this instance so it can be
                // rerouted one the Hierarchy is set.
                logger = new Log4JLogger(name);
                notIsolatedLoggers.put(this,name);
            }
            else
            {
                logger = new Log4JLogger(hierarchy.getLogger(name));              
            }
        }
    }
   
    private void setLogger(Log4JLogger logger)
    {
        this.logger = logger;
    }

    private Log4JLogger getLogger()
    {
        synchronized (IsolatedLog4JLogger.class)
        {
            return logger;
        }
    }

    public void debug(Object arg0)
    {
        Log4JLogger logger = getLogger();
        if ( logger != null )
        {
            logger.debug(arg0);
        }
    }
    public void debug(Object arg0, Throwable arg1)
    {
        Log4JLogger logger = getLogger();
        if ( logger != null )
        {
            logger.debug(arg0,arg1);
        }
    }
    public boolean equals(Object obj)
    {
        Log4JLogger logger = getLogger();
        return logger != null ? logger.equals(obj) : false;
    }
    public void error(Object arg0)
    {
        Log4JLogger logger = getLogger();
        if ( logger != null )
        {
            logger.error(arg0);
        }
    }
    public void error(Object arg0, Throwable arg1)
    {
        Log4JLogger logger = getLogger();
        if ( logger != null )
        {
            logger.error(arg0, arg1);
        }
    }
    public void fatal(Object arg0)
    {
        Log4JLogger logger = getLogger();
        if ( logger != null )
        {
            logger.fatal(arg0);
        }
    }
    public void fatal(Object arg0, Throwable arg1)
    {
        Log4JLogger logger = getLogger();
        if ( logger != null )
        {
            logger.fatal(arg0, arg1);
        }
    }
    public void info(Object arg0)
    {
        Log4JLogger logger = getLogger();
        if ( logger != null )
        {
            logger.info(arg0);
        }
    }
    public void info(Object arg0, Throwable arg1)
    {
        Log4JLogger logger = getLogger();
        if ( logger != null )
        {
            logger.info(arg0, arg1);
        }
    }
    public boolean isDebugEnabled()
    {
        Log4JLogger logger = getLogger();
        return logger != null ? logger.isDebugEnabled() : false;
    }
    public boolean isErrorEnabled()
    {
        Log4JLogger logger = getLogger();
        return logger != null ? logger.isErrorEnabled() : false;
    }
    public boolean isFatalEnabled()
    {
        Log4JLogger logger = getLogger();
        return logger != null ? logger.isFatalEnabled() : false;
    }
    public boolean isInfoEnabled()
    {
        Log4JLogger logger = getLogger();
        return logger != null ? logger.isInfoEnabled() : false;
    }
    public boolean isTraceEnabled()
    {
        Log4JLogger logger = getLogger();
        return logger != null ? logger.isTraceEnabled() : false;
    }
    public boolean isWarnEnabled()
    {
        Log4JLogger logger = getLogger();
        return logger != null ? logger.isWarnEnabled() : false;
    }
    public String toString()
    {
        Log4JLogger logger = getLogger();
        return logger != null ? logger.toString() : null;
    }
    public void trace(Object arg0)
    {
        Log4JLogger logger = getLogger();
        if ( logger != null )
        {
            logger.trace(arg0);
        }
    }
    public void trace(Object arg0, Throwable arg1)
    {
        Log4JLogger logger = getLogger();
        if ( logger != null )
        {
            logger.trace(arg0, arg1);
        }
    }
    public void warn(Object arg0)
    {
        Log4JLogger logger = getLogger();
        if ( logger != null )
        {
            logger.warn(arg0);
        }
    }
    public void warn(Object arg0, Throwable arg1)
    {
        Log4JLogger logger = getLogger();
        if ( logger != null )
        {
            logger.warn(arg0, arg1);
        }
    }
}
TOP

Related Classes of org.apache.jetspeed.webapp.logging.IsolatedLog4JLogger

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.