/**
 * Allows an application to have multiple Log4J configuration files.
 * Since the default initialization routine for Log4J only looks for
 * a log4j.properties or log4j.xml file in the classpath, this class
 * allows for multiple Log4J configuration files to be used and the
 * contents of each configuration file will be added to the current
 * in-memory configuration for Log4J.
 * 
 * Since this is written as a Spring BeanFactoryPostProcessor, the 
 * configuration information in Spring needs to be:
 * 
 * <bean name="<i>beanName</i> class="gov.va.med.fw.util.Log4JBeanFactoryPostProcessor">
 * 	<property name="configFiles">
 * 		<set>
 * 			<value>log4jConfigurationFile1</value>
 * 			<value>log4jConfigurationFile2</value>
 * 		</set>
 * 	</property>
 * </bean>
 */
package gov.va.med.fw.util.logging;

import java.net.URL;
import java.util.Map;

import org.apache.log4j.PropertyConfigurator;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

/**
 * @author DNS   duffg
 * 
 */
public class Log4JBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
	private Map shareableLoggers;
	private String[] configFiles = null;

	/*
	 * Accessor method to allow the setting of the Log4J configuration from
	 * Spring.
	 */
	public void setConfigFiles(final String[] configFiles) {
		this.configFiles = configFiles;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seeorg.springframework.beans.factory.config.BeanFactoryPostProcessor#
	 * postProcessBeanFactory
	 * (org.springframework.beans.factory.config.ConfigurableListableBeanFactory
	 * )
	 */
	public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) throws BeansException {
		if (configFiles != null) {
			initLog4J();
		}
	}

	/*
	 * Will loop through the configFiles array and search for each file in the
	 * classpath. When found, the appropriate Log4J Configurator will be
	 * executed based upon the extension of the file name (i.e. '*.properties'
	 * will be passed to PropertyConfigurator, '*.xml' will be passed to
	 * DOMConfigurator).
	 */
	private void initLog4J() {
		final ClassLoader cl = this.getClass().getClassLoader();
		final int configLen = configFiles.length;
		for (int i = 0; i < configLen; i++) {
			URL resourceFile = cl.getResource(configFiles[i]);
			if (resourceFile != null) {
				if (configFiles[i].endsWith("xml")) {
					Log4JDOMConfigurator.configure(resourceFile, shareableLoggers);
				} else {
					PropertyConfigurator.configure(resourceFile);
				}
				System.out.println("INFO: Loaded Log4J config files " + configFiles[i]);
			} else {
				// Use System.out since Log4J may not have been initialized for
				// this package.
				System.out.println("ERROR: Cannot find Log4J configuration file " + configFiles[i]);
			}
		}
	}

	/**
	 * @return the shareableLoggers
	 */
	public Map getShareableLoggers() {
		return shareableLoggers;
	}

	/**
	 * @param shareableLoggers
	 *            the shareableLoggers to set
	 */
	public void setShareableLoggers(Map shareableLoggers) {
		this.shareableLoggers = shareableLoggers;
	}
}
