/*
 * Copyright (C) 1999-2004 <a href="mailto:mandarax@jbdietrich.com">Jens Dietrich</a>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
 
package org.mandarax.util.logging;

/**
 * A factory for loggers. Abstract class, uses the "Abstract Factory" pattern.
 * @author <A HREF="mailto:mandarax@jbdietrich.com">Jens Dietrich</A>
 * @version 3.3.1 <9 August 2004>
 * @since 2.3.1
 */
public abstract class LoggerFactory {
	protected static LoggerFactory defaultInstance = null;
	private Class provider = null;
	/**
	 * Get the default instance.
	 * @return a logger factory instance
	 */
	public static LoggerFactory getDefaultFactory() {
		
		synchronized (LoggerFactory.class) {
			if (defaultInstance==null) {
				String className = System.getProperty("org.mandarax.logger");
				if (className!=null) getLoggerFactory(className).install();
			
				if (defaultInstance==null) {
					if (isInClasspath("org.apache.log4j.Logger")) (new Log4JLoggerFactory()).install();
					else if (isInClasspath("java.util.logging.Logger")) (new JDKLoggerFactory()).install();
					else (new SimpleLoggerFactory()).install();
				}						
			}
		}
		return defaultInstance;
	}
	/**
	 * Create (or get) a logger.
	 * @param loggerName The name of the logger.
	 */
	public abstract Logger getLogger(String loggerName) ;
	/**
	 * Detect whether a class is in the class path. 
	 * @param className a class name
	 * @return a boolean 
	 */ 
	protected static boolean isInClasspath(String className) {
		try {
			Class.forName(className);
			return true;
		}
		catch (ClassNotFoundException x) {
			return false;
		}
	}
	/**
	 * Detect whether a class is in the class path, is instantiable and subclasses LoggerFactory. 
	 * @param className a class name
	 * @return a logger factory if the class satisfies those conditions and null otherwise
	 */ 
	protected static LoggerFactory getLoggerFactory(String className) {
		try {
			Class clazz = Class.forName(className);
			Object inst = clazz.newInstance();
			if (inst instanceof LoggerFactory) return (LoggerFactory)inst;
			else return null;
		}
		catch (Exception x) {
			x.printStackTrace();
			return null;
		}
	}	 
	/**
	 * Install an instance as default factory.
	 */
	public void install() {
		defaultInstance = this;
	}
	

}
