    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  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
    018package org.apache.commons.configuration2.io;
    019
    020import org.apache.commons.logging.Log;
    021import org.apache.commons.logging.LogFactory;
    022import org.apache.commons.logging.impl.NoOpLog;
    023
    024/**
    025 * <p>
    026 * A class providing basic logging capabilities.
    027 * </p>
    028 * <p>
    029 * When reading configuration files in complex scenarios having log output is useful for diagnostic purposes. Therefore,
    030 * <em>Commons Configuration</em> produces some logging output. As concrete projects have different requirements on the
    031 * amount and detail of logging, there is a way of configuring logging: All classes derived from
    032 * {@link org.apache.commons.configuration2.AbstractConfiguration} can be assigned a logger which is then used for all
    033 * log statements generated.
    034 * </p>
    035 * <p>
    036 * Allowing a logger object to be passed to a configuration creates a direct dependency to a concrete logging framework
    037 * in the configuration API. This would make it impossible to switch to an alternative logging framework without
    038 * breaking backwards compatibility. To avoid this, the {@code ConfigurationLogger} class is introduced. It is a minimum
    039 * abstraction over a logging framework offering only very basic logging capabilities. The methods defined in this class
    040 * are used by configuration implementations to produce their logging statements. Client applications can create
    041 * specialized instances and pass them to configuration objects without having to deal with a concrete logging
    042 * framework. It is even possible to create a subclass that uses a completely different logging framework.
    043 * </p>
    044 *
    045 * @since 2.0
    046 */
    047public class ConfigurationLogger {
    048    /**
    049     * Creates an internal logger for the given class. Throws an exception if the class is undefined.
    050     *
    051     * @param cls the logger class
    052     * @return the logger object
    053     * @throws IllegalArgumentException if the logger class is undefined
    054     */
    055    private static Log createLoggerForClass(final Class<?> cls) {
    056        if (cls == null) {
    057            throw new IllegalArgumentException("Logger class must not be null!");
    058        }
    059        return LogFactory.getLog(cls);
    060    }
    061
    062    /**
    063     * Creates an internal logger for the given name. Throws an exception if the name is undefined.
    064     *
    065     * @param name the name of the logger
    066     * @return the logger object
    067     * @throws IllegalArgumentException if the logger name is undefined
    068     */
    069    private static Log createLoggerForName(final String name) {
    070        if (name == null) {
    071            throw new IllegalArgumentException("Logger name must not be null!");
    072        }
    073        return LogFactory.getLog(name);
    074    }
    075
    076    /**
    077     * Creates a new dummy logger which produces no output. If such a logger is passed to a configuration object, logging is
    078     * effectively disabled.
    079     *
    080     * @return the new dummy logger
    081     */
    082    public static ConfigurationLogger newDummyLogger() {
    083        return new ConfigurationLogger(new NoOpLog());
    084    }
    085
    086    /** The internal logger. */
    087    private final Log log;
    088
    089    /**
    090     * Creates a new, uninitialized instance of {@code ConfigurationLogger}. This constructor can be used by derived classes
    091     * that implement their own specific logging mechanism. Such classes must override all methods because the default
    092     * implementations do not work in this uninitialized state.
    093     */
    094    protected ConfigurationLogger() {
    095        this((Log) null);
    096    }
    097
    098    /**
    099     * Creates a new instance of {@code ConfigurationLogger} that uses a logger whose name is derived from the provided
    100     * class.
    101     *
    102     * @param logCls the class whose name is to be used for logging (must not be <b>null</b>)
    103     * @throws IllegalArgumentException if the logger class is <b>null</b>
    104     */
    105    public ConfigurationLogger(final Class<?> logCls) {
    106        this(createLoggerForClass(logCls));
    107    }
    108
    109    /**
    110     * Creates a new instance of {@code ConfigurationLogger} which wraps the specified logger.
    111     *
    112     * @param wrapped the logger to be wrapped
    113     */
    114    ConfigurationLogger(final Log wrapped) {
    115        log = wrapped;
    116    }
    117
    118    /**
    119     * Creates a new instance of {@code ConfigurationLogger} that uses the specified logger name.
    120     *
    121     * @param loggerName the logger name (must not be <b>null</b>)
    122     * @throws IllegalArgumentException if the logger name is <b>null</b>
    123     */
    124    public ConfigurationLogger(final String loggerName) {
    125        this(createLoggerForName(loggerName));
    126    }
    127
    128    /**
    129     * Logs the specified message on debug level.
    130     *
    131     * @param msg the message to be logged
    132     */
    133    public void debug(final String msg) {
    134        getLog().debug(msg);
    135    }
    136
    137    /**
    138     * Logs the specified message on error level.
    139     *
    140     * @param msg the message to be logged
    141     */
    142    public void error(final String msg) {
    143        getLog().error(msg);
    144    }
    145
    146    /**
    147     * Logs the specified exception on error level.
    148     *
    149     * @param msg the message to be logged
    150     * @param ex the exception to be logged
    151     */
    152    public void error(final String msg, final Throwable ex) {
    153        getLog().error(msg, ex);
    154    }
    155
    156    /**
    157     * Gets the internal logger.
    158     *
    159     * @return the internal logger
    160     */
    161    Log getLog() {
    162        return log;
    163    }
    164
    165    /**
    166     * Logs the specified message on info level.
    167     *
    168     * @param msg the message to be logged
    169     */
    170    public void info(final String msg) {
    171        getLog().info(msg);
    172    }
    173
    174    /**
    175     * Returns a flag whether logging on debug level is enabled.
    176     *
    177     * @return <b>true</b> if debug logging is enabled, <b>false</b> otherwise
    178     */
    179    public boolean isDebugEnabled() {
    180        return getLog().isDebugEnabled();
    181    }
    182
    183    /**
    184     * Returns a flag whether logging on info level is enabled.
    185     *
    186     * @return <b>true</b> if debug logging is enabled, <b>false</b> otherwise
    187     */
    188    public boolean isInfoEnabled() {
    189        return getLog().isInfoEnabled();
    190    }
    191
    192    /**
    193     * Logs the specified message on warn level.
    194     *
    195     * @param msg the message to be logged
    196     */
    197    public void warn(final String msg) {
    198        getLog().warn(msg);
    199    }
    200
    201    /**
    202     * Logs the specified exception on warn level.
    203     *
    204     * @param msg the message to be logged
    205     * @param ex the exception to be logged
    206     */
    207    public void warn(final String msg, final Throwable ex) {
    208        getLog().warn(msg, ex);
    209    }
    210}