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.wrapper.log4j;
018:
019: import org.apache.log4j.PropertyConfigurator;
020: import org.apache.log4j.BasicConfigurator;
021: import org.apache.log4j.LogManager;
022: import org.apache.log4j.xml.DOMConfigurator;
023: import org.objectweb.util.monolog.api.BasicLevel;
024: import org.objectweb.util.monolog.api.Logger;
025: import org.objectweb.util.monolog.api.TopicalLogger;
026: import org.objectweb.util.monolog.wrapper.common.AbstractFactory;
027: import org.objectweb.util.monolog.Monolog;
028:
029: import java.io.FileInputStream;
030: import java.io.FileNotFoundException;
031: import java.io.IOException;
032: import java.io.InputStream;
033: import java.util.Enumeration;
034: import java.util.Properties;
035: import java.util.ResourceBundle;
036: import java.util.HashSet;
037:
038: /**
039: * This class wraps the LoggerFactory, HandlerFactory, LevelFactory concepts
040: * into the log4j world. This implementation supports also the Configurable
041: * interface. Then it is possible to specify a log4j configuration file.
042: *
043: * @author Sebastien Chassande-Barrioz
044: */
045: public class MonologLoggerFactory extends AbstractFactory {
046:
047: public static final String LOG4J_CF_PROP = "log4j.categoryFactory";
048: public static final String LOG4J_CF_VALUE = "org.objectweb.util.monolog.wrapper.log4j.MonologCategoryFactory";
049:
050: /**
051: * The root logger of the logger hierarchy
052: */
053: protected static Logger rootLogger = null;
054:
055: /**
056: * It specifies the factory of MonologCategory instances.
057: */
058: private static org.apache.log4j.spi.LoggerFactory factory = new MonologCategoryFactory();
059:
060: /**
061: * This static code initializes the BasicLevel fields.
062: */
063: static {
064: BasicLevel.INHERIT = -1;
065: debug("INHERIT= " + BasicLevel.INHERIT);
066: BasicLevel.DEBUG = org.apache.log4j.Level.DEBUG.toInt();
067: debug("DEBUG= " + BasicLevel.DEBUG);
068: BasicLevel.INFO = org.apache.log4j.Level.INFO.toInt();
069: debug("INFO= " + BasicLevel.INFO);
070: BasicLevel.WARN = org.apache.log4j.Level.WARN.toInt();
071: debug("WARN= " + BasicLevel.WARN);
072: BasicLevel.ERROR = org.apache.log4j.Level.ERROR.toInt();
073: debug("ERROR= " + BasicLevel.ERROR);
074: BasicLevel.FATAL = org.apache.log4j.Level.FATAL.toInt();
075: debug("FATAL= " + BasicLevel.FATAL);
076:
077: BasicLevel.LEVEL_INHERIT = new LevelImpl("INHERIT",
078: BasicLevel.INHERIT);
079: BasicLevel.LEVEL_DEBUG = new LevelImpl("DEBUG",
080: BasicLevel.DEBUG);
081: BasicLevel.LEVEL_INFO = new LevelImpl("INFO", BasicLevel.INFO);
082: BasicLevel.LEVEL_WARN = new LevelImpl("WARN", BasicLevel.WARN);
083: BasicLevel.LEVEL_ERROR = new LevelImpl("ERROR",
084: BasicLevel.ERROR);
085: BasicLevel.LEVEL_FATAL = new LevelImpl("FATAL",
086: BasicLevel.FATAL);
087:
088: if (!org.apache.log4j.Logger.getRootLogger().getAllAppenders()
089: .hasMoreElements()) {
090: BasicConfigurator.configure();
091: }
092: if (classLoaderIsoltion) {
093: String rootName = null;
094: int i = 0;
095: while (rootLogger == null) {
096: rootName = "root" + i;
097: try {
098: org.apache.log4j.Logger rlog = org.apache.log4j.Logger
099: .getLogger(rootName, factory);
100: rlog.setAdditivity(false);
101: rootLogger = (Logger) rlog;
102: Monolog.debug("Instanciate the root logger "
103: + rootName);
104: } catch (ClassCastException exc) {
105: // this name has already been reserved by another
106: // instance of this class from another class loader
107: i++;
108: }
109: }
110: rootLoggerName = rootName;
111: rootLoggerPrefix = rootLoggerName + '.';
112: }
113: }
114:
115: /**
116: * It intializes the data struture, defines the default level and the root
117: * logger.
118: */
119: public MonologLoggerFactory() {
120: super ();
121: if (!classLoaderIsoltion) {
122: rootLogger = new MonologCategory(org.apache.log4j.Logger
123: .getRootLogger());
124: }
125: }
126:
127: public String getWrapperName() {
128: return "log4j";
129: }
130:
131: protected String[][] getDefaultHandlerType2className() {
132: return new String[][] {
133: { handlerTypes[0],
134: "org.objectweb.util.monolog.wrapper.log4j.ConsoleHandler" },
135: { handlerTypes[1],
136: "org.objectweb.util.monolog.wrapper.log4j.FileHandler" },
137: { handlerTypes[2],
138: "org.objectweb.util.monolog.wrapper.log4j.RollingFileHandler" },
139: { handlerTypes[3],
140: "org.objectweb.util.monolog.wrapper.log4j.NTEventLogHandler" },
141: { handlerTypes[4],
142: "org.objectweb.util.monolog.wrapper.log4j.JMXHandler" } };
143: }
144:
145: // IMPLEMENTATION OF THE Configurable INTERFACE //
146:
147: /**
148: * This method permits to configure the factory with tha specific
149: * configuration file: like a log4j.properties
150: */
151: public void configure(Properties prop) throws Exception {
152: debug("MonologLoggerFactory.configure(prop=" + prop + ")");
153: if (prop == null) {
154: if (!org.apache.log4j.Logger.getRootLogger()
155: .getAllAppenders().hasMoreElements()) {
156: BasicConfigurator.configure();
157: }
158: return;
159: }
160:
161: String conf = prop.getProperty(LOG_CONFIGURATION_TYPE, prop
162: .getProperty("log4jConfiguration", DEFAULT));
163: debug("MonologLoggerFactory.configure(): conf=" + conf);
164:
165: if (DEFAULT.equals(conf)) {
166: if (!org.apache.log4j.Logger.getRootLogger()
167: .getAllAppenders().hasMoreElements()) {
168: BasicConfigurator.configure();
169: }
170: return;
171: }
172:
173: // Fetch the configuration file name
174: String filename = prop.getProperty(LOG_CONFIGURATION_FILE, prop
175: .getProperty("log4jConfigurationFile", ""));
176: debug("MonologLoggerFactory.configure(): filename=" + filename);
177:
178: if (XML.equals(conf)) {
179: DOMConfigurator.configure(filename);
180: } else if (PROPERTY.equals(conf)) {
181: Properties log4jfileprop = null;
182: // Check if the file name designs a path valid into the
183: // classpath, or designs a path valid into the file system.
184: // In both case load the property file
185: if (prop.getProperty(LOG_CONFIGURATION_FILE_USE_CLASSPATH,
186: "false").equalsIgnoreCase("true")
187: || prop.getProperty("findFileInClassPath", "false")
188: .equalsIgnoreCase("true")) {
189:
190: debug("MonologLoggerFactory.configure(): load from classpath");
191:
192: if (!LogManager.DEFAULT_CONFIGURATION_FILE
193: .equals(filename)) {
194: debug("MonologLoggerFactory.configure(): not default config file");
195: // valid into the classpath
196: log4jfileprop = getProperties(filename);
197: log4jfileprop.setProperty(LOG4J_CF_PROP,
198: LOG4J_CF_VALUE);
199: PropertyConfigurator.configure(log4jfileprop);
200: }
201: // else the file is already loaded by the Logger class
202: } else {
203: debug("MonologLoggerFactory.configure(): load from file system");
204: // valid into the file system
205: log4jfileprop = new Properties();
206: log4jfileprop.load(new FileInputStream(filename));
207: log4jfileprop
208: .setProperty(LOG4J_CF_PROP, LOG4J_CF_VALUE);
209: PropertyConfigurator.configure(log4jfileprop);
210: }
211: } else {
212: throw new Exception("Unsupported configuration type: "
213: + conf);
214: }
215: debug("MonologLoggerFactory.configure(): End");
216: }
217:
218: // Return null if properties are not reachable
219: private Properties getProperties(String name) throws IOException {
220: InputStream is = getClass().getClassLoader()
221: .getResourceAsStream(name);
222: if (is != null) {
223: Properties props = new Properties();
224: props.load(is);
225: return props;
226: }
227: throw new FileNotFoundException("Not found in classpath: "
228: + name);
229: }
230:
231: // IMPLEMENTATION OF INTERFACE LoggerFactory //
232: //-------------------------------------------//
233:
234: public Logger getLogger(String key) {
235: if (key == null || key.length() == 0
236: || key.equalsIgnoreCase("root")) {
237: return rootLogger;
238: }
239: // isolates the logger hierarchy
240: key = monoLoggerName(key);
241: if (resourceBundleName == null)
242: return (Logger) org.apache.log4j.Logger.getLogger(key,
243: factory);
244: else
245: return getLogger(key, resourceBundleName);
246: }
247:
248: public synchronized Logger getLogger(String key, String rbn) {
249: if (key == null || key.length() == 0
250: || key.equalsIgnoreCase("root")) {
251: return rootLogger;
252: }
253: // isolates the logger hierarchy
254: key = monoLoggerName(key);
255: org.apache.log4j.Logger res = org.apache.log4j.Logger
256: .getLogger(key, factory);
257: res.setResourceBundle(ResourceBundle.getBundle(rbn));
258: return (Logger) res;
259: }
260:
261: public Logger[] getLoggers() {
262: HashSet al = new HashSet();
263: for (Enumeration e = org.apache.log4j.LogManager
264: .getCurrentLoggers(); e.hasMoreElements();) {
265: Object o = e.nextElement();
266: if (o instanceof Logger)
267: al.add(o);
268: }
269: al.add(rootLogger);
270: return (Logger[]) al.toArray(new TopicalLogger[0]);
271: }
272: }
|