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