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.config;
018:
019: import org.objectweb.util.monolog.api.Handler;
020: import org.objectweb.util.monolog.api.Level;
021: import org.objectweb.util.monolog.api.Logger;
022: import org.objectweb.util.monolog.api.MonologFactory;
023: import org.objectweb.util.monolog.api.MonologFactoryListener;
024: import org.objectweb.util.monolog.api.TopicalLogger;
025: import org.objectweb.util.monolog.wrapper.common.LevelImpl;
026:
027: import java.io.Serializable;
028: import java.util.ArrayList;
029: import java.util.HashMap;
030: import java.util.Properties;
031:
032: /**
033: * This class is a basic implementation of the monolog factories
034: * (HandlerFactory, LoggerFactory and LevelFactory). It does not linked to an
035: * any underlying log system.
036: *
037: * @author Sebastien Chassande-Barrioz
038: */
039: public class BasicFactory implements MonologFactory, Serializable {
040:
041: /**
042: * This field references the level instances by their names.<br/>
043: * key = a level name<br/>
044: * value = the unique Level instance linked to the name.
045: */
046: protected HashMap nameToLevel = null;
047:
048: /**
049: * This field reference the level names by their integer value.<br/>
050: * key = a java.lang.Integer which the value is the level<br/>
051: * value = a String or an ArrayList of String. The strings represent the
052: * name which match to the integer value. Indeed both name can be associated
053: * to the same integer value.
054: */
055: protected HashMap intToNames = null;
056:
057: /**
058: * This field references the handler instance by their names.<br/>
059: * key = a String object which is an handler name.
060: * value = the unique handler instance which has the key for name.
061: */
062: protected HashMap handlers = null;
063:
064: /**
065: * This field references the handler instance by their names.<br/>
066: * key = a String object which is a logger topic.
067: * value = the unique handler instance which has the key for name.
068: */
069: protected HashMap loggers = null;
070:
071: /**
072: * The resource bundle linked to the LoggerFactory.
073: */
074: protected String resourceBundleName = null;
075:
076: /**
077: * It intializes the data struture, defines the default level and the root
078: * logger.
079: */
080: public BasicFactory() {
081: intToNames = new HashMap();
082: nameToLevel = new HashMap();
083: handlers = new HashMap();
084: loggers = new HashMap();
085: defineDefaultLevels();
086: defineRootLogger();
087: }
088:
089: /**
090: * It initializes the default monolog level:
091: * <ul>
092: * <li>DEBUG: 10 000</li>
093: * <li>INFO: 20 000</li>
094: * <li>WARN: 30 000</li>
095: * <li>ERROR: 40 000</li>
096: * <li>FATAL: 50 000</li>
097: * </ul>
098: */
099: protected void defineDefaultLevels() {
100: defineLevel("INHERIT", -1);
101: defineLevel("DEBUG", 10000);
102: defineLevel("INFO", 20000);
103: defineLevel("WARN", 30000);
104: defineLevel("ERROR", 40000);
105: defineLevel("FATAL", 50000);
106: }
107:
108: /**
109: * It defines the level of the root logger to WARN.
110: */
111: protected void defineRootLogger() {
112: getLogger("").setLevel(getLevel("WARN"));
113: }
114:
115: public void addMonologFactoryListener(MonologFactoryListener mfl) {
116: }
117:
118: public void removeMonologFactoryListener(MonologFactoryListener mfl) {
119: }
120:
121: // IMPLEMENTATION OF THE LevelFactory INTERFACE //
122: //-----------------------------------------------//
123:
124: public Level defineLevel(String name, int value) {
125: return defineLevel(new LevelImpl(name, value));
126: }
127:
128: public Level defineLevel(String name, String value) {
129: return defineLevel(new LevelImpl(name, value, this ));
130: }
131:
132: public Level getLevel(String name) {
133: return (Level) nameToLevel.get(name);
134: }
135:
136: public Level getLevel(int value) {
137: Object temp = intToNames.get(new Integer(value));
138: if (temp == null) {
139: return null;
140: } else if (temp instanceof String) {
141: return getLevel((String) temp);
142: } else if (temp instanceof ArrayList) {
143: return getLevel((String) ((ArrayList) temp).get(0));
144: }
145: return null;
146: }
147:
148: public Level[] getLevels() {
149: return (Level[]) nameToLevel.values().toArray(new Level[0]);
150: }
151:
152: public void removeLevel(String name) {
153: Level removed = (Level) nameToLevel.remove(name);
154: if (removed != null) {
155: Integer i = new Integer(removed.getIntValue());
156: Object temp = intToNames.get(i);
157: if (temp instanceof String) {
158: intToNames.remove(i);
159: } else if (temp instanceof ArrayList) {
160: ((ArrayList) temp).remove(name);
161: }
162: }
163: }
164:
165: // OTHER METHODS //
166: //---------------//
167:
168: /**
169: * Insert a level into the data structure.<br/>
170: * If the level name is already used with other integer value, the null
171: * value is returned.<br/>
172: * If the level name is already used with the same integer value, the level
173: * found in the data structure is returned.<br/>
174: *
175: * @param l the Level instance which must be inserted.
176: * @return the Level instance or a null value.
177: */
178: private Level defineLevel(Level l) {
179: String name = l.getName();
180: int value = l.getIntValue();
181: Level res = (Level) nameToLevel.get(name);
182: if (res != null) {
183: // The name is already defined.
184: return (res.getIntValue() == value ? res : null);
185: } else {
186: res = l;
187: nameToLevel.put(name, res);
188: Integer i = new Integer(value);
189: Object temp = intToNames.get(i);
190: if (temp != null) {
191: if (temp instanceof String) {
192: if (!((Level) temp).getName()
193: .equalsIgnoreCase(name)) {
194: // The int value has already another name
195: // Add the new name to the other
196: ArrayList al = new ArrayList(5);
197: al.add(temp);
198: al.add(name);
199: intToNames.put(i, al);
200: }
201: } else if (temp instanceof ArrayList) {
202: // The int value has already several another name
203: ArrayList al = (ArrayList) temp;
204: if (!al.contains(name)) {
205: // Add the new name to the others
206: al.add(name);
207: }
208: }
209: } else {
210: // The int value does not have any name
211: intToNames.put(i, name);
212: }
213: }
214: return res;
215: }
216:
217: public void configure(Properties prop) throws Exception {
218: }
219:
220: // IMPLEMENTATION OF THE LoggerFactory INTERFACE //
221: //-----------------------------------------------//
222:
223: public Logger getLogger(String _key) {
224: String key = _key;
225: if ("".equals(_key)) {
226: key = "root";
227: }
228: synchronized (loggers) {
229: Logger res = (Logger) loggers.get(key);
230: if (res == null) {
231: res = new BasicLogger(key, this );
232: loggers.put(key, res);
233: }
234: return res;
235: }
236: }
237:
238: public void removeLogger(Logger logger) {
239: synchronized (loggers) {
240: loggers.remove(logger.getName());
241: }
242: }
243:
244: public Logger getLogger(String key, String resourceBundleName) {
245: return getLogger(key);
246: }
247:
248: public String getResourceBundleName() {
249: return resourceBundleName;
250: }
251:
252: public void setResourceBundleName(String rbn) {
253: resourceBundleName = rbn;
254: }
255:
256: public Logger[] getLoggers() {
257: return (TopicalLogger[]) loggers.values().toArray(
258: new TopicalLogger[loggers.size()]);
259: }
260:
261: public String getTopicPrefix() {
262: return null;
263: }
264:
265: // IMPLEMENTATION OF THE HandlerFactory INTERFACE //
266: //------------------------------------------------//
267:
268: public Handler createHandler(String hn, String handlertype) {
269: Handler res = (Handler) handlers.get(hn);
270: if (res != null) {
271: return null;
272: }
273: res = new BasicHandler(hn, handlertype);
274: handlers.put(hn, res);
275: return res;
276: }
277:
278: public Handler[] getHandlers() {
279: return (Handler[]) handlers.values().toArray(new Handler[0]);
280: }
281:
282: public Handler getHandler(String hn) {
283: return (Handler) handlers.get(hn);
284: }
285:
286: public Handler removeHandler(String hn) {
287: return (Handler) handlers.remove(hn);
288: }
289: }
|