Package org.codehaus.loom.components.logger

Source Code of org.codehaus.loom.components.logger.DefaultLogManager

/* ====================================================================
* Loom Software License, version 1.1
*
* Copyright (c) 2003, Loom Group. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. Neither the name of the Loom Group nor the name "Loom" nor
*    the names of its contributors may be used to endorse or promote
*    products derived from this software without specific prior
*    written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* ====================================================================
*
* Loom includes code from the Apache Software Foundation
*
* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 1997-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment:
*    "This product includes software developed by the
*    Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowledgment may appear in the software
*    itself, if and wherever such third-party acknowledgments
*    normally appear.
*
* 4. The names "Jakarta", "Avalon", and "Apache Software Foundation"
*    must not be used to endorse or promote products derived from this
*    software without prior written permission. For written
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
*    nor may "Apache" appear in their name, without prior written
*    permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
package org.codehaus.loom.components.logger;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.container.ContainerUtil;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.phoenix.BlockContext;
import org.codehaus.loom.components.util.ResourceUtil;
import org.codehaus.loom.interfaces.LogManager;
import org.codehaus.spice.alchemist.logger.LoggerAlchemist;
import org.codehaus.spice.alchemist.configuration.ConfigurationAlchemist;
import org.codehaus.spice.configkit.PropertyExpander;
import org.codehaus.spice.configkit.ResolverFactory;
import org.codehaus.spice.loggerstore.LoggerStore;
import org.codehaus.spice.loggerstore.LoggerStoreFactory;
import org.codehaus.spice.loggerstore.factories.DOMLog4JLoggerStoreFactory;
import org.codehaus.spice.loggerstore.factories.InitialLoggerStoreFactory;
import org.codehaus.spice.loggerstore.factories.Jdk14LoggerStoreFactory;
import org.codehaus.spice.loggerstore.factories.LogKitLoggerStoreFactory;
import org.codehaus.spice.loggerstore.factories.PropertyLog4JLoggerStoreFactory;
import org.codehaus.spice.loggerstore.factories.SimpleLogKitLoggerStoreFactory;
import org.codehaus.spice.salt.i18n.ResourceManager;
import org.codehaus.spice.salt.i18n.Resources;
import org.codehaus.dna.AbstractLogEnabled;
import org.codehaus.dna.Composable;
import org.codehaus.dna.MissingResourceException;
import org.codehaus.dna.ResourceLocator;
import org.codehaus.dna.impl.ConfigurationUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.EntityResolver;

/**
* Interface that is used to manage Log objects for a Sar.
*
* @author Peter Donald
*/
public class DefaultLogManager
    extends AbstractLogEnabled
    implements LogManager, Composable
{
    private static final Resources REZ =
        ResourceManager.getPackageResources( DefaultLogManager.class );

    private final PropertyExpander m_expander = new PropertyExpander();

    private final InitialLoggerStoreFactory m_factory = new InitialLoggerStoreFactory();

    /** Hold the value of loom.home */
    private File m_loomHome;

    /**
     * @dna.dependency type="File" qualifier="home"
     */
    public void compose( ResourceLocator locator )
        throws MissingResourceException
    {
        m_loomHome = (File)locator.lookup( File.class.getName() + "/home" );
    }

    private Map createLoggerManagerContext( final Map appContext )
    {
        final HashMap data = new HashMap();
        data.putAll( appContext );
        data.put( "loom.home", m_loomHome );
        return data;
    }

    /**
     * Normalises file paths by replacing File.separatorChar with '/' and
     * storing the path in the map in place of the File object which would be
     * converted back to using the File.separatorChar
     *
     * @param data the Map containing the File objects
     * @return the Map with the normalised File paths
     */
    private Map normaliseFilePaths( final Map data )
    {
        final Map map = new HashMap();
        map.putAll( data );
        for( Iterator i = data.keySet().iterator(); i.hasNext(); )
        {
            final Object key = i.next();
            final Object value = data.get( key );
            if( value instanceof File )
            {
                final File file = (File)value;
                final String newPath = normalisePath( file.getPath() );
                // replace File object value with its path
                map.put( key, newPath );
            }
        }
        return map;
    }

    /**
     * Normalises file path by replacing File.separatorChar with '/'
     *
     * @param path the file path is to be normalised
     * @return the normalised file path
     */
    private String normalisePath( final String path )
    {
        return path.replace( File.separatorChar, '/' );
    }

    /**
     * Create a Logger hierarchy for specified application.
     *
     * @param logs the configuration data for logging
     * @param context the context in which to create loggers
     * @return the Log hierarchy
     * @throws Exception if unable to create Loggers
     */
    public LoggerStore
        createHierarchy( final org.codehaus.dna.Configuration logs,
                         final File homeDirectory,
                         final File workDirectory,
                         final Map context )
        throws Exception
    {
        final Map map = createLoggerManagerContext( context );
        // normalise file paths to circumvent backslash replacement
        final Map normalisedMap = normaliseFilePaths( map );
        if( null == logs )
        {
            LoggerStore store = null;
            store = scanForLoggerConfig( "SAR-INF/log4j.properties",
                                         PropertyLog4JLoggerStoreFactory.class.getName(),
                                         homeDirectory,
                                         workDirectory,
                                         normalisedMap );
            if( null != store )
            {
                return store;
            }
            store = scanForLoggerConfig( "SAR-INF/log4j.xml",
                                         DOMLog4JLoggerStoreFactory.class.getName(),
                                         homeDirectory,
                                         workDirectory,
                                         normalisedMap );
            if( null != store )
            {
                return store;
            }
            store = scanForLoggerConfig( "SAR-INF/logging.properties",
                                         Jdk14LoggerStoreFactory.class.getName(),
                                         homeDirectory,
                                         workDirectory,
                                         normalisedMap );
            if( null != store )
            {
                return store;
            }
            store = scanForLoggerConfig( "SAR-INF/excalibur-logger.xml",
                                         LogKitLoggerStoreFactory.class.getName(),
                                         homeDirectory,
                                         workDirectory,
                                         normalisedMap );
            if( null != store )
            {
                return store;
            }

            //TODO: Set up a default LoggerStore at this point
            final String message = "Unable to locate any logging configuration";
            throw new IllegalStateException( message );
        }
        else
        {
            final String version = logs.getAttribute( "version", "1.0" );
            if( getLogger().isDebugEnabled() )
            {
                final String message =
                    REZ.format( "logger-create",
                                context.get( BlockContext.APP_NAME ),
                                version );
                getLogger().debug( message );
            }

            Logger logger = LoggerAlchemist.toAvalonLogger( getLogger() );
            if( version.equals( "1.0" ) )
            {
                final LoggerStoreFactory loggerManager = new SimpleLogKitLoggerStoreFactory();
                ContainerUtil.enableLogging( loggerManager, logger );
                final HashMap config = new HashMap();
                config.put( Logger.class.getName(), logger );
                // use the original context map as SimpleLogKitManager requires
                // the File object in the context
                config.put( Context.class.getName(),
                            new DefaultContext( map ) );
                config.put( Configuration.class.getName(),
                            ConfigurationAlchemist.toAvalonConfiguration( logs ) );
                return loggerManager.createLoggerStore( config );
            }
            else if( version.equals( "1.1" ) )
            {
                final LoggerStoreFactory loggerManager = new LogKitLoggerStoreFactory();
                ContainerUtil.enableLogging( loggerManager, logger );
                final HashMap config = new HashMap();
                config.put( Logger.class.getName(), logger );
                config.put( Context.class.getName(),
                            new DefaultContext( normalisedMap ) );
                config.put( Configuration.class.getName(),
                            ConfigurationAlchemist.toAvalonConfiguration( logs ) );
                return loggerManager.createLoggerStore( config );
            }
            else if( version.equals( "log4j" ) )
            {
                final LoggerStoreFactory loggerManager = new DOMLog4JLoggerStoreFactory();
                ContainerUtil.enableLogging( loggerManager, logger );
                final HashMap config = new HashMap();
                final Element element = buildLog4JConfiguration( logs );
                m_expander.expandValues( element, normalisedMap );
                config.put( Element.class.getName(), element );
                return loggerManager.createLoggerStore( config );
            }
            else
            {
                final String message =
                    "Unknown logger version '" +
                    version +
                    "' in environment.xml";
                throw new IllegalStateException( message );
            }
        }
    }

    private Element
        buildLog4JConfiguration( final org.codehaus.dna.Configuration logs )
    {
        final Element element = ConfigurationUtil.toElement( logs );
        final Document document = element.getOwnerDocument();
        final Element newElement = document.createElement(
            "log4j:configuration" );
        final NodeList childNodes = element.getChildNodes();
        final int length = childNodes.getLength();
        for( int i = 0; i < length; i++ )
        {
            final Node node = childNodes.item( i );
            final Node newNode = node.cloneNode( true );
            newElement.appendChild( newNode );
        }

        document.appendChild( newElement );
        return newElement;
    }

    private LoggerStore scanForLoggerConfig( final String location,
                                             final String classname,
                                             final File homeDirectory,
                                             final File workDirectory,
                                             final Map context )
        throws Exception
    {
        final boolean isPropertiesFile = location.endsWith( "properties" );
        final File file =
            ResourceUtil.getFileForResource( location,
                                             homeDirectory,
                                             workDirectory );
        LoggerStore store = null;
        if( null != file )
        {
            final HashMap config = new HashMap();
            if( isPropertiesFile )
            {
                final Properties properties = new Properties();
                properties.load( file.toURL().openStream() );
                final Properties newProperties =
                    m_expander.expandValues( properties, context );
                config.put( Properties.class.getName(), newProperties );
            }
            //TODO: Remove next line as it is an ugly hack!
            else if( !location.equals( "SAR-INF/excalibur-logger.xml" ) )
            {
                final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                final DocumentBuilder builder = factory.newDocumentBuilder();

                //TODO: Need to set up config files for entity resolver
                final EntityResolver resolver =
                    ResolverFactory.createResolver(
                        getClass().getClassLoader() );
                builder.setEntityResolver( resolver );
                final Document document = builder.parse( file );
                final Element element = document.getDocumentElement();
                m_expander.expandValues( element, context );
                config.put( Element.class.getName(), element );
            }
            else
            {
                config.put( LoggerStoreFactory.URL_LOCATION, file.toURL() );
            }
            config.put( InitialLoggerStoreFactory.INITIAL_FACTORY, classname );
            store = m_factory.createLoggerStore( config );
        }
        return store;
    }
}
TOP

Related Classes of org.codehaus.loom.components.logger.DefaultLogManager

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.