001package org.kuali.ole.sys.context;
002
003import java.util.Enumeration;
004
005import org.apache.log4j.Appender;
006import org.apache.log4j.ConsoleAppender;
007import org.apache.log4j.Layout;
008import org.apache.log4j.Logger;
009import org.apache.log4j.PatternLayout;
010
011/**
012 * Provides a method to add a ConsoleAppender to a Logger if one has not already been configured.
013 */
014public class BatchLogger {
015    public static final String DEFAULT_CONVERSION_PATTERN = "%d [%t] u:%X{user}/d:%X{docId} %-5p %c :: %m%n";
016    public static final Layout DEFAULT_PATTERN_LAYOUT = new PatternLayout(DEFAULT_CONVERSION_PATTERN);
017    public static final String LOG_FILE_APPENDER_NAME = "LogFile";
018    
019    /**
020     * Adds a ConsoleAppender to the Logger if one doesn't already exist. 
021     * Attempts to use the layout from the 'LogFile' appender if it exists, otherwise it uses the DEFAULT_CONVERSION_PATTERN
022     * 
023     * @param logger the Logger to which to add a ConsoleAppender
024     */
025    public static void addConsoleAppender(Logger logger) {
026        if (!isConsoleAppenderExists(logger)) {       
027            
028            Appender console = new ConsoleAppender(getLogFileAppenderLayout(logger));
029
030            logger.addAppender(console);
031        }
032    }
033    
034    /**
035     * Returns the layout for the 'LogFile' appender. Returns the DEFAULT_PATTERN_LAYOUT if the 'LogFile' doesn't exist.
036     * 
037     * @return the layout for the 'LogFile' appender
038     */
039    public static Layout getLogFileAppenderLayout() {
040        return getLogFileAppenderLayout(null);
041    }
042    
043    /**
044     * Checks whether a ConsoleAppender has already been added to either the RootLogger or to the requested Logger
045     * 
046     * @param logger the Logger to check
047     * @return true if a ConsoleAppender has already been added to the RootLogger or to the requested Logger, false otherwise
048     */
049    private static boolean isConsoleAppenderExists(Logger logger) {        
050        Enumeration<Appender> rootAppenders = Logger.getRootLogger().getAllAppenders();
051        while(rootAppenders.hasMoreElements()) {
052            Appender appender = rootAppenders.nextElement();
053            if (appender instanceof ConsoleAppender) {
054                return true;
055            }
056        }
057        
058        Enumeration<Appender> appenders = logger.getAllAppenders();        
059        while(appenders.hasMoreElements()) {
060            Appender appender = appenders.nextElement();
061            if (appender instanceof ConsoleAppender) {
062                return true;
063            }
064        }
065        return false;
066    }
067    
068    /**
069     * @return the appender for 'LogFile' if it exists on the RootLogger or the requested Logger, null otherwise
070     */
071    private static Appender getLogFileAppender(Logger logger) {
072        if (Logger.getRootLogger() != null) {
073            return Logger.getRootLogger().getAppender(LOG_FILE_APPENDER_NAME);
074        }
075        else if (logger != null ) {
076            return logger.getAppender(LOG_FILE_APPENDER_NAME);
077        }
078        return null;
079    }
080    
081    /**
082     * Returns the layout for the 'LogFile' appender.
083     * 
084     * @param logger the Logger to check
085     * @return the Layout for the 'LogFile' appender, the DEFAULT_PATTERN_LAYOUT if 'LogFile' doesn't exist
086     */
087    private static Layout getLogFileAppenderLayout(Logger logger) {
088        Appender logFileAppender = getLogFileAppender(logger);
089        
090        if (logFileAppender != null) {
091            return logFileAppender.getLayout();
092        }
093        else {
094            System.out.println(BatchLogger.class.getName() +": Could not find '"+ LOG_FILE_APPENDER_NAME +"' appender on RootLogger. Using DEFAULT_CONVERSION_PATTERN for layout to console");
095            return DEFAULT_PATTERN_LAYOUT;
096        }
097    }
098}