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}