001: /**
002: * Copyright (C) 2001-2003 France Telecom R&D
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */package org.objectweb.util.monolog;
018:
019: import org.objectweb.util.monolog.api.LoggerFactory;
020: import org.objectweb.util.monolog.api.HandlerFactory;
021: import org.objectweb.util.monolog.api.LevelFactory;
022: import org.objectweb.util.monolog.api.MonologFactory;
023: import org.objectweb.util.monolog.wrapper.printwriter.LoggerImpl;
024: import org.objectweb.util.monolog.file.monolog.PropertiesConfAccess;
025:
026: import java.util.Properties;
027: import java.io.File;
028: import java.io.FileInputStream;
029: import java.io.IOException;
030: import java.io.InputStream;
031: import java.io.FileNotFoundException;
032:
033: /**
034: * This class is a helper to instanciate a logger factory. It provides a set of
035: * init(...) method with various parameter:
036: * - no parameter => automatic configuration with system property and default
037: * values
038: * - Properties => contains monolog configuration (loggers, handlers, levels
039: * and optionaly the wrapper class name (automatic choice if not specified)).
040: * - String => the class name of the wrapper class to instanciate
041: *
042: * @author S.Chassande-Barrioz
043: */
044: public class Monolog {
045: /**
046: * Inidicates if the monolog wrapper must be logged itself.
047: */
048: public static boolean debug = new Boolean(System
049: .getProperty("monolog.debug")).booleanValue();
050:
051: /**
052: * is the basic loggerFactory implementation.
053: */
054: private static MonologFactory basicMonologFactory = new LoggerImpl();
055:
056: /**
057: * is the last required logger factory. By default it is initialized to the
058: * a basic logger factory implementation (LoggerImpl).
059: */
060: public static MonologFactory monologFactory = basicMonologFactory;
061:
062: /**
063: * @deprecated use monologFactory
064: */
065: public static LoggerFactory loggerFactory = monologFactory;
066:
067: /**
068: * is the default monolog configuration file lookup from the file system or
069: * from the classpath.
070: */
071: public static final String DEFAULT_MONOLOG_FILE = "monolog.properties";
072:
073: /**
074: * is the property name of the monolog configuration file. This property
075: * is searched from the specified properties or from the system properties.
076: */
077: public static final String MONOLOG_FILE_NAME = "monolog.filename";
078:
079: /**
080: * is the property name of the wrapper class name. This property is searched
081: * from the specified properties or from the system properties.
082: */
083: public static final String MONOLOG_CLASS_NAME = "monolog.classname";
084:
085: /**
086: * is the class name of logger factory for the log4j logging system.
087: */
088: public static final String LOG4J_WRAPPER_CLASS_NAME = "org.objectweb.util.monolog.wrapper.log4j.MonologLoggerFactory";
089:
090: /**
091: * is the class name of logger factory for the log4jME logging system.
092: */
093: public static final String LOG4JMini_WRAPPER_CLASS_NAME = "org.objectweb.util.monolog.wrapper.log4jMini.MonologLoggerFactory";
094:
095: /**
096: * is the class name of logger factory for the java.util.logging logging
097: * system.
098: */
099: public static final String JDK_WRAPPER_CLASS_NAME = "org.objectweb.util.monolog.wrapper.javaLog.LoggerFactory";
100: /**
101: * is the class name used to known if log4j is availlable in the classpath
102: */
103: private static final String LOG4J_CLASS_NAME = "org.apache.log4j.Logger";
104:
105: /**
106: * is the class name used to known if log4j is availlable in the classpath
107: */
108: private static final String LOG4JMini_CLASS_NAME = "org.apache.log4j.Category";
109:
110: /**
111: * is the class name used to known if the JVM version is greater or equal
112: * to 1.4
113: */
114: private static final String JDK_CLASS_NAME = "java.util.logging.Logger";
115:
116: public static MonologFactory getMonologFactory() {
117: return monologFactory;
118: }
119:
120: public static MonologFactory getDefaultMonologFactory() {
121: return basicMonologFactory;
122: }
123:
124: /**
125: * Initializes Monolog.
126: * It searches in system properties a monolog configuration file
127: * (MONOLOG_FILE_NAME system property) or use the default file name
128: * (DEFAULT_MONOLOG_FILE system property).
129: *
130: * @return the loggerFactory (never null)
131: */
132: public static MonologFactory initialize() {
133: if (monologFactory == basicMonologFactory) {
134: getMonologFactory(System.getProperty(MONOLOG_FILE_NAME,
135: DEFAULT_MONOLOG_FILE));
136: }
137: return monologFactory;
138: }
139:
140: /**
141: * @deprecated use initialize()
142: */
143: public static LoggerFactory init() {
144: return initialize();
145: }
146:
147: /**
148: * @deprecated use getMonologFactory(String)
149: */
150: public static LoggerFactory init(String fileName) {
151: return getMonologFactory(fileName);
152: }
153:
154: /**
155: * Initializes Monolog with a given monolog configuration file name
156: * if the file is found, it delegates the intialization to init(Properties)
157: * method. if the file is not found it delegates the logger factory
158: * instanciation to the getLoggerFactory(String) method.
159: *
160: * @param fileName is the file name of a properties reachable from the
161: * file system or the classpath.
162: * @return the loggerFactory (never null)
163: */
164: public static MonologFactory getMonologFactory(String fileName) {
165: Monolog.debug("DEBUG: debug is activated!");
166: File f = new File(fileName);
167: InputStream is = null;
168: if (f.exists()) {
169: Monolog.debug("DEBUG: The file " + fileName
170: + " was found from the file system.");
171: try {
172: is = new FileInputStream(f);
173: } catch (FileNotFoundException e) {
174: Monolog.debug("ERROR: " + e.getMessage());
175: is = null;
176: }
177: } else {
178: is = Monolog.class.getClassLoader().getResourceAsStream(
179: fileName);
180: if (is != null)
181: Monolog.debug("DEBUG: The file " + fileName
182: + " was found from the classpath.");
183: }
184: if (is != null) {
185: Properties p = new Properties();
186: try {
187: p.load(is);
188: } catch (IOException e) {
189: Monolog.debug("ERROR: problem to load properties from "
190: + "the input stream " + is);
191: if (debug) {
192: e.printStackTrace(System.out);
193: }
194: }
195: getMonologFactory(p);
196: } else {
197: Monolog.debug("DEBUG: The file " + fileName
198: + " was not found.");
199: monologFactory = instanciateMonologFactory(null);
200: }
201: return monologFactory;
202: }
203:
204: /**
205: * Initializes monolog in with a Properties instance.
206: * It searches from the properties the logger factory class name (
207: * MONOLOG_CLASS_NAME property) and it delegates its configuration to
208: * the loadMonologConfiguration(Properties, LoggerFactory) method.
209: *
210: * @param properties can contains the MONOLOG_CLASS_NAME property and the
211: * rest of the monolog configuration (loggers, handlers, levels).
212: * @return the loggerFactory (never null)
213: */
214: public static MonologFactory getMonologFactory(Properties properties) {
215: monologFactory = instanciateMonologFactory(properties
216: .getProperty(MONOLOG_CLASS_NAME, System
217: .getProperty(MONOLOG_CLASS_NAME)));
218: if (monologFactory != basicMonologFactory) {
219: loadMonologConfiguration(properties, monologFactory);
220: }
221: return monologFactory;
222: }
223:
224: /**
225: * @deprecated use getMonologFactory(Properties)
226: */
227: public static LoggerFactory init(Properties properties) {
228: return getMonologFactory(properties);
229: }
230:
231: /**
232: * Loads a monolog configuration into the loggerFactory.
233: * @param properties contains the properties to load into the given logger
234: * factory.
235: */
236: public static void loadMonologConfiguration(Properties properties) {
237: loadMonologConfiguration(properties, monologFactory);
238: }
239:
240: /**
241: * Loads a monolog configuration into an existing MonologFactory.
242: * @param properties contains the properties to load into the given logger
243: * factory.
244: * @param mf is the MonologFactory to configure.
245: */
246: public static void loadMonologConfiguration(Properties properties,
247: MonologFactory mf) {
248: try {
249: PropertiesConfAccess.load(properties, mf, mf, mf);
250: } catch (Exception e) {
251: Monolog.error(
252: "WARN: problem to configure a loggerFactory:", e);
253: }
254: }
255:
256: /**
257: * @deprecated use loadMonologConfiguration(Properties, MonologFactory)
258: */
259: public static void loadMonologConfiguration(Properties properties,
260: LoggerFactory lf) {
261: loadMonologConfiguration(properties, (MonologFactory) lf);
262: }
263:
264: public static LoggerFactory getLoggerFactory(String className) {
265: return getMonologFactory(className);
266: }
267:
268: public static LevelFactory getLevelFactory(String className) {
269: return getMonologFactory(className);
270: }
271:
272: public static HandlerFactory getHandlerFactory(String className) {
273: return getMonologFactory(className);
274: }
275:
276: /**
277: * Retrieves a MonologFactory instance.
278: * First it tries to instanciate the given logger factory class name.
279: * If it is not possible it tries to instanciate the logger factory of the
280: * log4j system (if the classes are availlable).
281: * If log4j or its wrapper are not reachable then it tries to instanciate
282: * the wrapper of the log4jME logging system.
283: * If log4jME or its wrapper are not reachable then it tries to instanciate
284: * the wrapper of the java.util.logging logging system.
285: * Finally if any of these wrappers are reachable the basic logger factory
286: * is used.
287: *
288: * @param className is the class name of a LoggerFactory implementation.
289: * It can be a null value.
290: * @return a LoggerFactory instance (never null).
291: */
292: public static MonologFactory instanciateMonologFactory(
293: String className) {
294: //Try with the given logger factory class name if it is not null
295: if (className != null) {
296: try {
297: Monolog.debug("DEBUG: try to use the logger factory: "
298: + className);
299: return (MonologFactory) Class.forName(className)
300: .newInstance();
301: } catch (ClassNotFoundException e) {
302: Monolog.debug("WARN: The class " + className
303: + " was not found.");
304: } catch (Exception e) {
305: Monolog.debug("WARN: The class " + className
306: + " has no public empty constructor.");
307: }
308: }
309: //Try to find the log4j classes and its wrapper
310: try {
311: Monolog.debug("DEBUG: try to use log4j");
312: Class.forName(LOG4J_CLASS_NAME);
313: return (MonologFactory) Class.forName(
314: LOG4J_WRAPPER_CLASS_NAME).newInstance();
315: } catch (Exception e) {
316: Monolog.debug("DEBUG: log4j and its wrapper are not "
317: + "availlable:" + e.getMessage());
318: if (debug) {
319: e.printStackTrace(System.out);
320: }
321: }
322: //Try to find the jdk classes and its wrapper
323: try {
324: Monolog.debug("DEBUG: try to use the jdk");
325: Class.forName(JDK_CLASS_NAME);
326: return (MonologFactory) Class.forName(
327: JDK_WRAPPER_CLASS_NAME).newInstance();
328: } catch (Exception e) {
329: Monolog.debug("DEBUG: java.util.logging and its wrapper "
330: + "are not availlable:" + e.getMessage());
331: if (debug) {
332: e.printStackTrace(System.out);
333: }
334: }
335:
336: //Try to find the log4jMini classes and its wrapper
337: try {
338: Monolog.debug("DEBUG: try to use the log4j mini");
339: Class.forName(LOG4JMini_CLASS_NAME);
340: return (MonologFactory) Class.forName(
341: LOG4JMini_WRAPPER_CLASS_NAME).newInstance();
342: } catch (Exception e) {
343: Monolog.debug("DEBUG: log4jMini and its wrapper are not "
344: + "availlable:" + e.getMessage());
345: if (debug) {
346: e.printStackTrace(System.out);
347: }
348: }
349: Monolog.debug("DEBUG: return the basic logger factory");
350: //return the basic logger factory
351: return basicMonologFactory;
352: }
353:
354: /**
355: * This method must be only used to debug the Monolog wrappers.
356: * To active the log of monolog assign the "true" value to the system
357: * property "monolog.debug".
358: *
359: * @param m the message to log.
360: */
361: static public void debug(String m) {
362: if (debug) {
363: System.out.println(m);
364: }
365: }
366:
367: static public void error(String m, Exception e) {
368: System.err.println(m);
369: if (debug) {
370: e.printStackTrace(System.err);
371: }
372: }
373: }
|