Package com.eva.log

Source Code of com.eva.log.EvaLog

/*
* $Id: EvaLog.java 109 2007-03-24 14:55:03Z max $
*
* Copyright (c) 2007 Maximilian Antoni. All rights reserved.
*
* This software is licensed as described in the file LICENSE.txt, which you
* should have received as part of this distribution. The terms are also
* available at http://www.maxantoni.de/projects/eva-properties/license.txt.
*/
package com.eva.log;

import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Filter;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.eva.properties.DataSource;
import com.eva.properties.MapProperties;
import com.eva.properties.PropertiesException;

/**
* <p>
* provides factory methods for convenient logger creation. All methods require
* at least a package or package name that is used to find an optional
* configuration file in that package named &quot;log.eva&quot;.
* </p>
* <p>
* If an external properties file is found, the default properties provided by
* this package are set as the super properties. The <code>bundle</code>
* filename can be specified in the properties file and the <code>package</code>
* property can be overriden.
* </p>
* <p>
* The default properties provide the following values:
* </p>
*
* <pre>
*   encoding:          ISO8859-1
*   level:             INFO
*   dir:               &quot;${system.user.dir}/log&quot;
*   pattern:           &quot;eva%g.log&quot;
*   limit:             10000
*   count:             5
*   formatter:         ( *com.eva.log.LogFormatter(${prefix})
*                        *com.eva.log.LogFormatter()
*                      )
*   handler:           ${console-handler}
*   console-handler:   *java.util.logging.ConsoleHandler()
*   file-handler:      *java.util.logging.FileHandler(
*                          &quot;${dir}/${pattern}&quot;, ${limit}, ${count}
*                      )
*   useParentHandlers: no
* </pre>
*
* <p>
* This setup allows you to switch to a console logger setup very easily. Simply
* provide the following in your custom log properties file:
* </p>
* <p>
* <code>handler: ${file-handler}</code>
* </p>
*
* @author max
* @version $Revision: 109 $
*/
public class EvaLog {
    private static final Logger DEFAULT_LOGGER;
    private static final MapProperties DEFAULT_PROPERTIES;
    private static final String LOG_CONFIG_FILENAME = "log.eva";
   
    static {
        Exception exception = null;
        MapProperties properties;
        try {
            properties = new MapProperties(
                    new DataSource("classpath://log.eva"));
        }
        catch(PropertiesException e) {
            exception = e; // Log after initialization.
            properties = loadDefaults();
        }
        catch(FileNotFoundException e) {
            // Expected. Don't log.
            properties = loadDefaults();
        }
        DEFAULT_PROPERTIES = properties;
        DEFAULT_LOGGER = Logger.getLogger(EvaLog.class.getPackage().getName());
        configure(DEFAULT_LOGGER, DEFAULT_PROPERTIES);
        if(exception != null) {
            DEFAULT_LOGGER.log(Level.WARNING,
                    "Custom log properties cannot be read. Using defaults.",
                    exception);
        }
    }
   
    /**
     * creates a new logger for the given class.
     *
     * @param inClass the class.
     * @return the logger.
     */
    public static Logger create(Class inClass) {
        return create(inClass, (String) null);
    }
   
    /**
     * creates a new logger for the given class and bundle name.
     *
     * @param inClass the class.
     * @param inBundle the bundle name.
     * @return the logger.
     */
    public static Logger create(Class inClass, String inBundle) {
        return create(inClass.getClassLoader(), inClass.getPackage().getName(),
                inBundle);
    }
   
    /**
     * creates a new logger for the given package name.
     *
     * @param inPackage the package name.
     * @return the logger.
     */
    public static Logger create(String inPackage) {
        return create(null, inPackage, (String) null);
    }
   
    /**
     * creates a new logger for the given package name and bundle name.
     *
     * @param inPackage the package name.
     * @param inBundle the bundle name.
     * @return the logger.
     */
    public static Logger create(String inPackage, String inBundle) {
        return create(null, inPackage, inBundle);
    }
   
    /**
     * creates a new logger for the given package name and bundle name. If the
     * class loader is not <code>null</code> it is used to find the properties
     * file.
     *
     * @param inClassLoader the class loader.
     * @param inPackage the package name.
     * @param inBundle the bundle name.
     * @return the logger.
     */
    private static Logger create(ClassLoader inClassLoader, String inPackage,
            String inBundle) {
        /*
         * Check for configuration for the given package in the default
         * properties:
         */
        MapProperties properties = (MapProperties) DEFAULT_PROPERTIES
                .get(inPackage.replace('.', '-'));
        if(properties == null) {
            /*
             * Try loading the properties for the given package form the
             * classpath using the naming convention "<package>/log.eva":
             */
            try {
                properties = new MapProperties(new DataSource(inClassLoader,
                        "classpath://" + inPackage.replace('.', '/') + "/"
                                + LOG_CONFIG_FILENAME));
            }
            catch(FileNotFoundException e) {
                DEFAULT_LOGGER.log(Level.CONFIG,
                        "No logger configuration found for package \""
                                + inPackage + "\". Using defaults.");
            }
        }
        return create(inPackage, inBundle, properties);
    }
   
    /**
     * creates a new logger for the given package and properties.
     *
     * @param inPackage the package.
     * @param inProperties the properties.
     * @return the logger.
     */
    public static Logger create(Package inPackage, Map inProperties) {
        return create(inPackage.getName(), null, inProperties);
    }
   
    /**
     * creates a new logger for the given package name and properties.
     *
     * @param inPackage the package name.
     * @param inProperties the properties.
     * @return the logger.
     */
    public static Logger create(String inPackage, Map inProperties) {
        return create(inPackage, null, inProperties);
    }

    /**
     * creates a new logger for the given package name, bundle name and
     * properties.
     *
     * @param inPackage the package name.
     * @param inBundle the bundle name.
     * @param inProperties the properties.
     * @return the logger.
     */
    public static Logger create(String inPackage, String inBundle,
            Map inProperties) {
        String pkg;
        String bundle = inBundle;
        if(inProperties == null) {
            pkg = inPackage;
        }
        else {
            /*
             * Set the default properties as the parent for the loaded
             * properties. All properties will be inherited from the default
             * configuration.
             */
            inProperties.put(MapProperties.SUPER, DEFAULT_PROPERTIES);
            pkg = (String) inProperties.get("package");
            if(pkg == null) {
                pkg = inPackage; // Use configured package instead.
            }
            if(bundle == null) {
                bundle = (String) inProperties.get("bundle");
            }
        }
        Logger logger;
        if(bundle == null) {
            logger = Logger.getLogger(pkg);
            if(DEFAULT_LOGGER.isLoggable(Level.FINE)) {
                DEFAULT_LOGGER.log(Level.FINE, "Logger for package \""
                        + inPackage + "\" created without resource bundle.");
            }
        }
        else {
            // The bundle has to be in the package:
            logger = Logger.getLogger(pkg, pkg + "." + bundle);
            if(DEFAULT_LOGGER.isLoggable(Level.FINE)) {
                DEFAULT_LOGGER.log(Level.FINE, "Logger for package \""
                        + inPackage + "\" created with resource bundle \""
                        + bundle + "\".");
            }
        }
        if(logger.getParent() ==  DEFAULT_LOGGER) {
            // No further configuration required. Logger already configured.
            return logger;
        }
        logger.setParent(DEFAULT_LOGGER);
        if(inProperties != null) {
            configure(logger, inProperties);
        }
        return logger;
    }
   
    /**
     * returns the default logger. The default logger is used as a parent for
     * all loggers instantiated using this class.
     *
     * @return the default logger.
     */
    public static Logger getDefault() {
        return DEFAULT_LOGGER;
    }
       
    /**
     * configures a logger with the information provided by a properties map.
     *
     * @param inoutLogger the logger to configure.
     * @param inProperties the properties map.
     */
    private static void configure(Logger inoutLogger, Map inProperties) {
        if(DEFAULT_LOGGER.isLoggable(Level.FINER)) {
            DEFAULT_LOGGER.finer("Configure logger \"" + inoutLogger.getName()
                    + "\" with:");
            Map properties;
            if(inProperties instanceof MapProperties) {
                properties = ((MapProperties) inProperties).getMap();
            }
            else {
                properties = inProperties;
            }
            String[] keys = new String[] {
                    "handler", "handlers", "encoding", "level", "formatter",
                    "filter", "useParentHandlers"
            };
            boolean valuesPresent = false;
            for(int i = 0; i < keys.length; i++) {
                Object value = properties.get(keys[i]);
                if(value != null) {
                    DEFAULT_LOGGER.finer("\t" + keys[i] + ": " + value);
                    valuesPresent = true;
                }
            }
            if(!valuesPresent) {
                DEFAULT_LOGGER.finer("\tNo properties found.");
            }
        }
        Handler singleHandler = (Handler) inProperties.get("handler");
        List handlers;
        if(singleHandler == null) {
            handlers = (List) inProperties.get("handlers");
        }
        else {
            handlers = Collections.singletonList(singleHandler);
        }
       
        String encoding = (String) inProperties.get("encoding");
        String l = (String) inProperties.get("level");
        Level level = l == null ? null : Level.parse(l);
        Formatter formatter = (Formatter) inProperties.get("formatter");
       
        if(handlers != null) {
            for(Iterator i = handlers.iterator(); i.hasNext();) {
                Handler handler = (Handler) i.next();
                if(encoding != null) {
                    try {
                        handler.setEncoding(encoding);
                    }
                    catch(SecurityException e) {
                        throw new RuntimeException(e);
                    }
                    catch(UnsupportedEncodingException e) {
                        throw new RuntimeException(e);
                    }
                }
                if(level != null) {
                    handler.setLevel(level);
                }
                if(formatter != null) {
                    handler.setFormatter(formatter);
                }
                inoutLogger.addHandler(handler);
            }
        }
       
        if(level != null) {
            inoutLogger.setLevel(level);
        }
       
        Filter filter = (Filter) inProperties.get("filter");
        if(filter != null) {
            inoutLogger.setFilter(filter);
        }
        Boolean useParentHandlers = (Boolean) inProperties
                .get("useParentHandlers");
        if(useParentHandlers != null) {
            inoutLogger.setUseParentHandlers(useParentHandlers.booleanValue());
        }
    }
   
    /**
     * loads the default properties from the classpath.
     *
     * @return the default properties.
     */
    private static MapProperties loadDefaults() {
        return new MapProperties(EvaLog.class
                .getResourceAsStream(LOG_CONFIG_FILENAME));
    }
   
    /**
     * Never instantiated.
     */
    private EvaLog() {
        // Never instantiated.
    }
}
TOP

Related Classes of com.eva.log.EvaLog

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.