    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
    030 * useful for diagnostic purposes. Therefore, <em>Commons Configuration</em>
    031 * produces some logging output. As concrete projects have different
    032 * requirements on the amount and detail of logging, there is a way of
    033 * configuring logging: All classes derived from
    034 * {@link org.apache.commons.configuration2.AbstractConfiguration}
    035 * can be assigned a logger which is then used for all log statements generated.
    036 * </p>
    037 * <p>
    038 * Allowing a logger object to be passed to a configuration creates a direct
    039 * dependency to a concrete logging framework in the configuration API. This
    040 * would make it impossible to switch to an alternative logging framework
    041 * without breaking backwards compatibility. To avoid this, the
    042 * {@code ConfigurationLogger} class is introduced. It is a minimum abstraction
    043 * over a logging framework offering only very basic logging capabilities. The
    044 * methods defined in this class are used by configuration implementations to
    045 * produce their logging statements. Client applications can create specialized
    046 * instances and pass them to configuration objects without having to deal with
    047 * a concrete logging framework. It is even possible to create a subclass that
    048 * uses a completely different logging framework.
    049 * </p>
    050 *
    051 * @version $Id: ConfigurationLogger.java 1842194 2018-09-27 22:24:23Z ggregory $
    052 * @since 2.0
    053 */
    054public class ConfigurationLogger
    055{
    056    /** The internal logger. */
    057    private final Log log;
    058
    059    /**
    060     * Creates a new instance of {@code ConfigurationLogger} that uses the
    061     * specified logger name.
    062     *
    063     * @param loggerName the logger name (must not be <b>null</b>)
    064     * @throws IllegalArgumentException if the logger name is <b>null</b>
    065     */
    066    public ConfigurationLogger(final String loggerName)
    067    {
    068        this(createLoggerForName(loggerName));
    069    }
    070
    071    /**
    072     * Creates a new instance of {@code ConfigurationLogger} that uses a logger
    073     * whose name is derived from the provided class.
    074     *
    075     * @param logCls the class whose name is to be used for logging (must not be
    076     *        <b>null</b>)
    077     * @throws IllegalArgumentException if the logger class is <b>null</b>
    078     */
    079    public ConfigurationLogger(final Class<?> logCls)
    080    {
    081        this(createLoggerForClass(logCls));
    082    }
    083
    084    /**
    085     * Creates a new, uninitialized instance of {@code ConfigurationLogger}.
    086     * This constructor can be used by derived classes that implement their own
    087     * specific logging mechanism. Such classes must override all methods
    088     * because the default implementations do not work in this uninitialized
    089     * state.
    090     */
    091    protected ConfigurationLogger()
    092    {
    093        this((Log) null);
    094    }
    095
    096    /**
    097     * Creates a new instance of {@code ConfigurationLogger} which wraps the
    098     * specified logger.
    099     *
    100     * @param wrapped the logger to be wrapped
    101     */
    102    ConfigurationLogger(final Log wrapped)
    103    {
    104        log = wrapped;
    105    }
    106
    107    /**
    108     * Creates a new dummy logger which produces no output. If such a logger is
    109     * passed to a configuration object, logging is effectively disabled.
    110     *
    111     * @return the new dummy logger
    112     */
    113    public static ConfigurationLogger newDummyLogger()
    114    {
    115        return new ConfigurationLogger(new NoOpLog());
    116    }
    117
    118    /**
    119     * Returns a flag whether logging on debug level is enabled.
    120     *
    121     * @return <b>true</b> if debug logging is enabled, <b>false</b> otherwise
    122     */
    123    public boolean isDebugEnabled()
    124    {
    125        return getLog().isDebugEnabled();
    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    {
    135        getLog().debug(msg);
    136    }
    137
    138    /**
    139     * Returns a flag whether logging on info level is enabled.
    140     *
    141     * @return <b>true</b> if debug logging is enabled, <b>false</b> otherwise
    142     */
    143    public boolean isInfoEnabled()
    144    {
    145        return getLog().isInfoEnabled();
    146    }
    147
    148    /**
    149     * Logs the specified message on info level.
    150     *
    151     * @param msg the message to be logged
    152     */
    153    public void info(final String msg)
    154    {
    155        getLog().info(msg);
    156    }
    157
    158    /**
    159     * Logs the specified message on warn level.
    160     *
    161     * @param msg the message to be logged
    162     */
    163    public void warn(final String msg)
    164    {
    165        getLog().warn(msg);
    166    }
    167
    168    /**
    169     * Logs the specified exception on warn level.
    170     *
    171     * @param msg the message to be logged
    172     * @param ex the exception to be logged
    173     */
    174    public void warn(final String msg, final Throwable ex)
    175    {
    176        getLog().warn(msg, ex);
    177    }
    178
    179    /**
    180     * Logs the specified message on error level.
    181     *
    182     * @param msg the message to be logged
    183     */
    184    public void error(final String msg)
    185    {
    186        getLog().error(msg);
    187    }
    188
    189    /**
    190     * Logs the specified exception on error level.
    191     *
    192     * @param msg the message to be logged
    193     * @param ex the exception to be logged
    194     */
    195    public void error(final String msg, final Throwable ex)
    196    {
    197        getLog().error(msg, ex);
    198    }
    199
    200    /**
    201     * Returns the internal logger.
    202     *
    203     * @return the internal logger
    204     */
    205    Log getLog()
    206    {
    207        return log;
    208    }
    209
    210    /**
    211     * Creates an internal logger for the given name. Throws an exception if the
    212     * name is undefined.
    213     *
    214     * @param name the name of the logger
    215     * @return the logger object
    216     * @throws IllegalArgumentException if the logger name is undefined
    217     */
    218    private static Log createLoggerForName(final String name)
    219    {
    220        if (name == null)
    221        {
    222            throw new IllegalArgumentException("Logger name must not be null!");
    223        }
    224        return LogFactory.getLog(name);
    225    }
    226
    227    /**
    228     * Creates an internal logger for the given class. Throws an exception if
    229     * the class is undefined.
    230     *
    231     * @param cls the logger class
    232     * @return the logger object
    233     * @throws IllegalArgumentException if the logger class is undefined
    234     */
    235    private static Log createLoggerForClass(final Class<?> cls)
    236    {
    237        if (cls == null)
    238        {
    239            throw new IllegalArgumentException(
    240                    "Logger class must not be null!");
    241        }
    242        return LogFactory.getLog(cls);
    243    }
    244}