| /* |
| * Copyright 2005 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.cocoon.util; |
| |
| import org.apache.avalon.framework.logger.ConsoleLogger; |
| import org.apache.avalon.framework.logger.Logger; |
| import org.apache.commons.lang.enums.ValuedEnum; |
| |
| /** |
| * This class provides a special static "deprecation" logger. |
| * All deprecated code should use this logger to log messages into the |
| * deprecation logger. This makes it easier for users to find out if they're |
| * using deprecated stuff. |
| * <p> |
| * Additionally, it is possible to set the forbidden level of deprecation messages (default |
| * is to forbid ERROR, i.e. allow up to WARN). Messages equal to or above the forbidden level |
| * will lead to throwing a {@link DeprecationException}. Setting the forbidden level to |
| * FATAL_ERROR allows running legacy applications using deprecated features (tolerant mode), and |
| * setting the forbidden level to DEBUG will run in strict mode, forbidding all deprecations. |
| * <p> |
| * Note that according to the above, issuing a fatalError log always raises an exception, and |
| * can therefore be used when detecting old features that have been totally removed. |
| * |
| * @version $Id$ |
| */ |
| public class Deprecation { |
| |
| /** |
| * The deprecation logger. |
| */ |
| public static final Logger logger = new LoggerWrapper(new ConsoleLogger()); |
| |
| private static final int DEBUG_VALUE = 0; |
| private static final int INFO_VALUE = 1; |
| private static final int WARN_VALUE = 2; |
| private static final int ERROR_VALUE = 3; |
| private static final int FATAL_VALUE = 3; |
| private static final int FATAL_ERROR_VALUE = 4; |
| |
| /** |
| * Debug deprecation messages indicate features that are no more considered "current" |
| * or "best practice", but for which no removal is currently foreseen. |
| */ |
| public static final LogLevel DEBUG = new LogLevel("DEBUG", DEBUG_VALUE); |
| |
| /** |
| * Info deprecation messages indicate features that are no more considered "current" |
| * or "best practice", and that will probably be removed in future releases. |
| */ |
| public static final LogLevel INFO = new LogLevel("INFO", INFO_VALUE); |
| |
| /** |
| * Warning deprecation messages indicate features that will be removed in the next major |
| * version (e.g. 2.1.x --> 2.2.0). Such features should not be used if the application is |
| * planned to be migrated to newer Cocoon versions. |
| */ |
| public static final LogLevel WARN = new LogLevel("WARN", WARN_VALUE); |
| |
| /** |
| * Error deprecation messages indicate features that will be removed in the next minor |
| * version (e.g. 2.1.6 --> 2.1.7). Although still functional, users are stronly invited to |
| * not use them. |
| */ |
| public static final LogLevel ERROR = new LogLevel("ERROR", ERROR_VALUE); |
| |
| /** |
| * Fatal error deprecation messages indicate features that used to exist but have been removed |
| * in the current version. Logging such a message always throws a {@link DeprecationException}. |
| */ |
| public static final LogLevel FATAL_ERROR = new LogLevel("FATAL_ERROR", FATAL_ERROR_VALUE); |
| |
| public static final class LogLevel extends ValuedEnum { |
| private LogLevel(String text, int value) { |
| super(text, value); |
| } |
| |
| public static LogLevel getLevel(String level) { |
| return (LogLevel)ValuedEnum.getEnum(LogLevel.class, level); |
| } |
| } |
| |
| public static void setLogger(Logger newLogger) { |
| // Note: the "logger" attribute is not of type LoggerWrapper so that it appears |
| // as a standard Logger in the javadocs. |
| ((LoggerWrapper)logger).setLogger(newLogger); |
| } |
| |
| public static void setForbiddenLevel(LogLevel level) { |
| // If null, reset to the default level |
| if (level == null) { |
| level = ERROR; |
| } |
| ((LoggerWrapper)logger).setForbiddenLevel(level); |
| } |
| |
| /** |
| * Wraps a logger, and throws an DeprecatedException if the message level is |
| * higher than the allowed one. |
| */ |
| private static class LoggerWrapper implements Logger { |
| |
| private Logger realLogger; |
| // up to warn is allowed |
| private int forbiddenLevel = ERROR_VALUE; |
| |
| public LoggerWrapper(Logger logger) { |
| this.realLogger = logger; |
| } |
| |
| public void setLogger(Logger logger) { |
| // Unwrap a wrapped logger |
| while(logger instanceof LoggerWrapper) { |
| logger = ((LoggerWrapper)logger).realLogger; |
| } |
| this.realLogger = logger; |
| } |
| |
| public void setForbiddenLevel(LogLevel level) { |
| this.forbiddenLevel = level.getValue(); |
| } |
| |
| private void throwException(int level, String message) { |
| if (level >= this.forbiddenLevel) { |
| throw new DeprecationException(message); |
| } |
| } |
| |
| private boolean isThrowingException(int level) { |
| return level >= this.forbiddenLevel; |
| } |
| |
| public void debug(String message) { |
| realLogger.debug(message); |
| throwException(DEBUG_VALUE, message); |
| } |
| public void debug(String message, Throwable thr) { |
| realLogger.debug(message, thr); |
| throwException(DEBUG_VALUE, message); |
| } |
| public void info(String message) { |
| realLogger.info(message); |
| throwException(INFO_VALUE, message); |
| } |
| public void info(String message, Throwable thr) { |
| realLogger.info(message, thr); |
| throwException(INFO_VALUE, message); |
| } |
| public void warn(String message) { |
| realLogger.warn(message); |
| throwException(WARN_VALUE, message); |
| } |
| public void warn(String message, Throwable thr) { |
| realLogger.warn(message, thr); |
| throwException(WARN_VALUE, message); |
| } |
| public void error(String message) { |
| realLogger.error(message); |
| throwException(ERROR_VALUE, message); |
| } |
| public void error(String message, Throwable thr) { |
| realLogger.error(message, thr); |
| throwException(ERROR_VALUE, message); |
| } |
| public void fatalError(String message) { |
| realLogger.fatalError(message); |
| throwException(FATAL_VALUE, message); |
| } |
| public void fatalError(String message, Throwable thr) { |
| realLogger.fatalError(message, thr); |
| throwException(FATAL_VALUE, message); |
| } |
| public boolean isDebugEnabled() { |
| // Enable level also if it is set to throw an exception, so that |
| // logging the message occurs, and then throws it. |
| return isThrowingException(DEBUG_VALUE) || realLogger.isDebugEnabled(); |
| } |
| public boolean isInfoEnabled() { |
| return isThrowingException(INFO_VALUE) || realLogger.isInfoEnabled(); |
| } |
| public boolean isWarnEnabled() { |
| return isThrowingException(WARN_VALUE) || realLogger.isWarnEnabled(); |
| } |
| public boolean isErrorEnabled() { |
| return isThrowingException(ERROR_VALUE) || realLogger.isErrorEnabled(); |
| } |
| public boolean isFatalErrorEnabled() { |
| return true; |
| } |
| public Logger getChildLogger(String message) { |
| return realLogger.getChildLogger(message); |
| } |
| } |
| } |