/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package usda.weru.util;

import java.text.MessageFormat;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import org.apache.log4j.spi.LoggingEvent;

/**
 * Redirects java.util.logging messages to log4j
 * @author Joseph Levin <joelevin@weru.ksu.edu>
 */
public class JavaLogging2Log4JHandler extends Handler {

	/**
	 *
	 */
	public static void install() {
        Logger root = Logger.getLogger("");
        Handler[] handlers = root.getHandlers();
        if(handlers != null ){
            for(Handler h : handlers){
                root.removeHandler(h);
            }
        }
        root.addHandler(new JavaLogging2Log4JHandler());
    }

	/**
	 *
	 * @param record
	 */
	@Override
    public void publish(LogRecord record) {
        org.apache.log4j.Logger log4j = getTargetLogger(record.getLoggerName());
        //log4j.log(record.getSourceClassName(), level(record.getLevel()), message(record), record.getThrown());        
        String fqcn = Logger.class.getName();
        long timestamp = record.getMillis();
        org.apache.log4j.Level level = level(record.getLevel());
        String message = message(record);
        Throwable thrown = record.getThrown();
        
        LoggingEvent event = new LoggingEvent(fqcn, log4j, timestamp, level , message , thrown);
        log4j.callAppenders(event);
        
    }

    private org.apache.log4j.Logger getTargetLogger(String loggerName) {
        return org.apache.log4j.Logger.getLogger(loggerName);
    }

    private String message(LogRecord record) {
        String message = record.getMessage();
        // Format message
        try {
            Object parameters[] = record.getParameters();
            if (parameters != null && parameters.length != 0) {
                // Check for the first few parameters ?
                if (message.indexOf("{0}") >= 0 || message.indexOf("{1}") >= 0 || message.indexOf("{2}") >= 0 || message.indexOf("{3}") >= 0) {
                    message = MessageFormat.format(message, parameters);
                }
            }
        } catch (Exception ex) {
            // ignore Exception
        }
        return message;
    }

    private org.apache.log4j.Level level(Level level) {
        if (Level.SEVERE.equals(level)) {
            return org.apache.log4j.Level.ERROR;
        } else if (Level.WARNING.equals(level)) {
            return org.apache.log4j.Level.WARN;
        } else if (Level.INFO.equals(level)) {
            return org.apache.log4j.Level.INFO;
        } else if (Level.CONFIG.equals(level)) {
            return org.apache.log4j.Level.DEBUG;
        } else if (Level.FINE.equals(level)) {
            return org.apache.log4j.Level.DEBUG;
        } else if (Level.FINER.equals(level)) {
            return org.apache.log4j.Level.TRACE;
        } else if (Level.FINEST.equals(level)) {
            return org.apache.log4j.Level.TRACE;
        } else if (Level.ALL.equals(level)) {
            return org.apache.log4j.Level.ALL;
        } else {
            return org.apache.log4j.Level.OFF;
        }
    }

	/**
	 *
	 */
	@Override
    public void flush() {
        //nothing to do
    }

	/**
	 *
	 * @throws SecurityException
	 */
	@Override
    public void close() throws SecurityException {
        //nothing to do
    }
    
}
