    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 *     https://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    /**
    050     * Creates an internal logger for the given class. Throws an exception if the class is undefined.
    051     *
    052     * @param cls the logger class
    053     * @return the logger object
    054     * @throws IllegalArgumentException if the logger class is undefined
    055     */
    056    private static Log createLoggerForClass(final Class<?> cls) {
    057        if (cls == null) {
    058            throw new IllegalArgumentException("Logger class must not be null.");
    059        }
    060        return LogFactory.getLog(cls);
    061    }
    062
    063    /**
    064     * Creates an internal logger for the given name. Throws an exception if the name is undefined.
    065     *
    066     * @param name the name of the logger
    067     * @return the logger object
    068     * @throws IllegalArgumentException if the logger name is undefined
    069     */
    070    private static Log createLoggerForName(final String name) {
    071        if (name == null) {
    072            throw new IllegalArgumentException("Logger name must not be null.");
    073        }
    074        return LogFactory.getLog(name);
    075    }
    076
    077    /**
    078     * Creates a new dummy logger which produces no output. If such a logger is passed to a configuration object, logging is
    079     * effectively disabled.
    080     *
    081     * @return the new dummy logger
    082     */
    083    public static ConfigurationLogger newDummyLogger() {
    084        return new ConfigurationLogger(new NoOpLog());
    085    }
    086
    087    /** The internal logger. */
    088    private final Log log;
    089
    090    /**
    091     * Creates a new, uninitialized instance of {@code ConfigurationLogger}. This constructor can be used by derived classes
    092     * that implement their own specific logging mechanism. Such classes must override all methods because the default
    093     * implementations do not work in this uninitialized state.
    094     */
    095    protected ConfigurationLogger() {
    096        this((Log) null);
    097    }
    098
    099    /**
    100     * Creates a new instance of {@code ConfigurationLogger} that uses a logger whose name is derived from the provided
    101     * class.
    102     *
    103     * @param logCls the class whose name is to be used for logging (must not be <strong>null</strong>)
    104     * @throws IllegalArgumentException if the logger class is <strong>null</strong>
    105     */
    106    public ConfigurationLogger(final Class<?> logCls) {
    107        this(createLoggerForClass(logCls));
    108    }
    109
    110    /**
    111     * Creates a new instance of {@code ConfigurationLogger} which wraps the specified logger.
    112     *
    113     * @param wrapped the logger to be wrapped
    114     */
    115    ConfigurationLogger(final Log wrapped) {
    116        log = wrapped;
    117    }
    118
    119    /**
    120     * Creates a new instance of {@code ConfigurationLogger} that uses the specified logger name.
    121     *
    122     * @param loggerName the logger name (must not be <strong>null</strong>)
    123     * @throws IllegalArgumentException if the logger name is <strong>null</strong>
    124     */
    125    public ConfigurationLogger(final String loggerName) {
    126        this(createLoggerForName(loggerName));
    127    }
    128
    129    /**
    130     * Logs the specified message on debug level.
    131     *
    132     * @param msg the message to be logged
    133     */
    134    public void debug(final String msg) {
    135        getLog().debug(msg);
    136    }
    137
    138    /**
    139     * Logs the specified message on error level.
    140     *
    141     * @param msg the message to be logged
    142     */
    143    public void error(final String msg) {
    144        getLog().error(msg);
    145    }
    146
    147    /**
    148     * Logs the specified exception on error level.
    149     *
    150     * @param msg the message to be logged
    151     * @param ex the exception to be logged
    152     */
    153    public void error(final String msg, final Throwable ex) {
    154        getLog().error(msg, ex);
    155    }
    156
    157    /**
    158     * Gets the internal logger.
    159     *
    160     * @return the internal logger
    161     */
    162    Log getLog() {
    163        return log;
    164    }
    165
    166    /**
    167     * Logs the specified message on info level.
    168     *
    169     * @param msg the message to be logged
    170     */
    171    public void info(final String msg) {
    172        getLog().info(msg);
    173    }
    174
    175    /**
    176     * Returns a flag whether logging on debug level is enabled.
    177     *
    178     * @return <strong>true</strong> if debug logging is enabled, <strong>false</strong> otherwise
    179     */
    180    public boolean isDebugEnabled() {
    181        return getLog().isDebugEnabled();
    182    }
    183
    184    /**
    185     * Returns a flag whether logging on info level is enabled.
    186     *
    187     * @return <strong>true</strong> if debug logging is enabled, <strong>false</strong> otherwise
    188     */
    189    public boolean isInfoEnabled() {
    190        return getLog().isInfoEnabled();
    191    }
    192
    193    /**
    194     * Logs the specified message on warn level.
    195     *
    196     * @param msg the message to be logged
    197     */
    198    public void warn(final String msg) {
    199        getLog().warn(msg);
    200    }
    201
    202    /**
    203     * Logs the specified exception on warn level.
    204     *
    205     * @param msg the message to be logged
    206     * @param ex the exception to be logged
    207     */
    208    public void warn(final String msg, final Throwable ex) {
    209        getLog().warn(msg, ex);
    210    }
    211}