001: /*
002: * $Id: Log.java,v 1.1 2002/02/24 02:11:24 skavish Exp $
003: *
004: * ===========================================================================
005: *
006: * The JGenerator Software License, Version 1.0
007: *
008: * Copyright (c) 2000 Dmitry Skavish (skavish@usa.net). All rights reserved.
009: *
010: * Redistribution and use in source and binary forms, with or without
011: * modification, are permitted provided that the following conditions are met:
012: *
013: * 1. Redistributions of source code must retain the above copyright
014: * notice, this list of conditions and the following disclaimer.
015: *
016: * 2. Redistributions in binary form must reproduce the above copyright
017: * notice, this list of conditions and the following disclaimer in
018: * the documentation and/or other materials provided with the
019: * distribution.
020: *
021: * 3. The end-user documentation included with the redistribution, if
022: * any, must include the following acknowlegement:
023: * "This product includes software developed by Dmitry Skavish
024: * (skavish@usa.net, http://www.flashgap.com/)."
025: * Alternately, this acknowlegement may appear in the software itself,
026: * if and wherever such third-party acknowlegements normally appear.
027: *
028: * 4. The name "The JGenerator" must not be used to endorse or promote
029: * products derived from this software without prior written permission.
030: * For written permission, please contact skavish@usa.net.
031: *
032: * 5. Products derived from this software may not be called "The JGenerator"
033: * nor may "The JGenerator" appear in their names without prior written
034: * permission of Dmitry Skavish.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL DMITRY SKAVISH OR THE OTHER
040: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: *
049: */
050:
051: package org.openlaszlo.iv.flash.util;
052:
053: import org.openlaszlo.iv.flash.api.*;
054: import java.io.*;
055: import java.net.*;
056: import java.util.*;
057:
058: import org.apache.log4j.*;
059: import org.apache.log4j.spi.*;
060: import org.apache.log4j.helpers.*;
061:
062: /**
063: * Logger
064: * <P>
065: * After replacing jgenerator native logging system with log4j
066: * all the jgenerator classes like FileLogger, ConsoleLogger etc. are gone.
067: * But I decided to keep this class Log to avoid changing a lot of code
068: * which uses it.
069: * <P>
070: * Instead I changed its implementation to make it a wrapper for log4j.
071: * <P>
072: * log4j has several level methods, like 'debug', 'warn' etc., but jgenerator Log
073: * has only one method 'log' which takes the level of a message from its
074: * resource key's first character. I preserved this schema, so now if you use
075: * this class's log method it will call corresponding log4j method based
076: * on the first character of the message key, otherwise you can call any of
077: * log4j methods directly or using new Log methods with the same signature.
078: * <P>
079: * The default initialization procedure:
080: * <UL>
081: * <LI>get property org.openlaszlo.iv.flash.log4j.configuration from iv.property file
082: * <LI>if it exists and contains valid url or file name (either relative to jgen home or absolute)
083: * then use this url to initialize log4j (it can be either xml or property based configuration)
084: * <LI>if the property does not exist or is not valid then use standard log4 initialization procedure,
085: * i.e. read system property log4j.configuration etc
086: * </UL>
087: *
088: * @author Dmitry Skavish
089: */
090: public class Log {
091:
092: private static final String FQCN = Log.class.getName();
093:
094: private static Logger logger;
095: private static final String filePattern = "%d [%p] - %m%n";
096: private static final String consolePattern = "%r [%p] - %m%n";
097:
098: static {
099:
100: String log4j_conf = PropertyManager
101: .getProperty("org.openlaszlo.iv.flash.log4j.configuration");
102:
103: if (log4j_conf != null) {
104: URL url = null;
105: try {
106: url = new URL(log4j_conf);
107: } catch (MalformedURLException e) {
108: File file = Util.getSysFile(log4j_conf);
109: try {
110: url = file.toURL();
111: } catch (MalformedURLException ee) {
112: }
113: }
114:
115: // configure log4j
116: if (url != null) {
117: OptionConverter.selectAndConfigure(url, null,
118: LogManager.getLoggerRepository());
119: }
120: }
121:
122: logger = Logger.getLogger("org.openlaszlo.iv.flash.Generator");
123: logger.setResourceBundle(Resource.getInstance());
124: }
125:
126: /**
127: * Gets current logger
128: *
129: * @return current logger
130: */
131: public static Logger getLogger() {
132: return logger;
133: }
134:
135: /**
136: * Sets new logger
137: * <P>
138: * If you set new logger you probably also need to set ResourceBundle to it
139: *
140: * @param logger new logger
141: */
142: public static void setLogger(Logger logger) {
143: Log.logger = logger;
144: }
145:
146: /**
147: * Sets log to console
148: */
149: public static void setLogToConsole() {
150: logger.removeAllAppenders();
151: logger.addAppender(new ConsoleAppender(new PatternLayout(
152: consolePattern)));
153: }
154:
155: /**
156: * Sets log to file
157: * <P>
158: * File specified in property org.openlaszlo.iv.flash.logFile
159: *
160: * @deprecated logging system is configured now using log4j configuration file
161: */
162: /* public static void setLogToFile() {
163: String fileName = PropertyManager.getProperty("org.openlaszlo.iv.flash.logFile", "logs/generator.log");
164: File file = Util.getSysFile(fileName);
165: fileName = file.getAbsolutePath();
166: setLogToFile(fileName);
167: }
168: */
169: /**
170: * Sets log to the specified file
171: *
172: * @deprecated logging system is configured now using log4j configuration file
173: */
174: /* public static void setLogToFile( String fileName ) {
175: try {
176: logger.removeAllAppenders();
177: logger.addAppender(new FileAppender(new PatternLayout(filePattern), fileName, true));
178: } catch( IOException e ) {
179: setLogToConsole();
180: log(e);
181: }
182: }
183: */
184: /**
185: * Logs IVException
186: * <P>
187: * IVException contains message with parameters inside
188: * and probably nested exception
189: *
190: * @param e exception to log
191: */
192: public static void logRB(IVException e) {
193: log(e);
194: }
195:
196: public static void log(IVException e) {
197: String key = e.getMessageKey();
198: Level level = getMessageLevel(key);
199: if (!logger.isEnabledFor(level))
200: return;
201:
202: logger.log(FQCN, level, e.getLocalizedMessage(), e);
203: }
204:
205: /**
206: * Logs Exception
207: *
208: * @param e exception to log
209: */
210: public static void logRB(Throwable t) {
211: log(t);
212: }
213:
214: public static void log(Throwable t) {
215: if (t instanceof IVException) {
216: log((IVException) t);
217: } else {
218: error(t.getLocalizedMessage(), t);
219: }
220: }
221:
222: /**
223: * Logs exception as message specified by its resource key
224: *
225: * @param key resource key
226: * @param p array of parameters
227: * @param t exception to log
228: */
229: public static void logRB(String key, Object[] p, Throwable t) {
230: _logif(key, p, t);
231: }
232:
233: /**
234: * Logs exception as message specified by its resource key
235: *
236: * @param key resource key
237: * @param p array of parameters
238: */
239: public static void logRB(String key, Object[] p) {
240: _logif(key, p, null);
241: }
242:
243: /**
244: * Logs exception as message specified by its resource key
245: *
246: * @param key resource key
247: * @param p array of parameters
248: */
249: public static void logRB(String key) {
250: _logif(key, null, null);
251: }
252:
253: /**
254: * Logs exception as message specified by its resource key
255: *
256: * @param key resource key
257: * @param p array of parameters
258: */
259: public static void logRB(String key, Throwable t) {
260: _logif(key, null, t);
261: }
262:
263: public static void infoRB(String key, Object[] parms) {
264: _logif(Level.INFO, key, parms, null);
265: }
266:
267: public static void infoRB(String key, Object[] parms, Throwable t) {
268: _logif(Level.INFO, key, parms, t);
269: }
270:
271: public static void debugRB(String key, Object[] parms) {
272: _logif(Level.DEBUG, key, parms, null);
273: }
274:
275: public static void debugRB(String key, Object[] parms, Throwable t) {
276: _logif(Level.DEBUG, key, parms, t);
277: }
278:
279: public static void errorRB(String key, Object[] parms) {
280: _logif(Level.ERROR, key, parms, null);
281: }
282:
283: public static void errorRB(String key, Object[] parms, Throwable t) {
284: _logif(Level.ERROR, key, parms, t);
285: }
286:
287: public static void fatalRB(String key, Object[] parms) {
288: _logif(Level.FATAL, key, parms, null);
289: }
290:
291: public static void fatalRB(String key, Object[] parms, Throwable t) {
292: _logif(Level.FATAL, key, parms, t);
293: }
294:
295: public static void warnRB(String key, Object[] parms) {
296: _logif(Level.WARN, key, parms, null);
297: }
298:
299: public static void warnRB(String key, Object[] parms, Throwable t) {
300: _logif(Level.WARN, key, parms, t);
301: }
302:
303: //
304: // methods which take a string not a resource bundle key
305: //
306:
307: public static void info(Object msg) {
308: logger.info(msg);
309: }
310:
311: public static void info(Object msg, Throwable t) {
312: logger.info(msg, t);
313: }
314:
315: public static void debug(Object msg) {
316: logger.debug(msg);
317: }
318:
319: public static void debug(Object msg, Throwable t) {
320: logger.debug(msg, t);
321: }
322:
323: public static void error(Object msg) {
324: logger.error(msg);
325: }
326:
327: public static void error(Object msg, Throwable t) {
328: logger.error(msg, t);
329: }
330:
331: public static void fatal(Object msg) {
332: logger.fatal(msg);
333: }
334:
335: public static void fatal(Object msg, Throwable t) {
336: logger.fatal(msg, t);
337: }
338:
339: public static void warn(Object msg) {
340: logger.warn(msg);
341: }
342:
343: public static void warn(Object msg, Throwable t) {
344: logger.warn(msg, t);
345: }
346:
347: /**
348: * Checks if a messages specified by given key is enabled under current log level
349: *
350: * @param key message key
351: * @return true if message has to be logged
352: */
353: public static Level getMessageLevel(String key) {
354: if (key == null || key.length() == 0)
355: return Level.FATAL;
356: char ch = key.charAt(0);
357: switch (ch) {
358: case '0':
359: return Level.FATAL;
360: case '1':
361: return Level.ERROR;
362: case '2':
363: return Level.WARN;
364: case '3':
365: return Level.INFO;
366: case '4':
367: return Level.DEBUG;
368: default:
369: return Level.FATAL;
370: }
371: }
372:
373: public static void setFatalLevel() {
374: logger.setLevel(Level.FATAL);
375: }
376:
377: public static void setErrorLevel() {
378: logger.setLevel(Level.ERROR);
379: }
380:
381: public static void setWarnLevel() {
382: logger.setLevel(Level.WARN);
383: }
384:
385: public static void setInfoLevel() {
386: logger.setLevel(Level.INFO);
387: }
388:
389: public static void setDebugLevel() {
390: logger.setLevel(Level.DEBUG);
391: }
392:
393: /**
394: * Checks if specified message is enabled under current level and logs the message if it is
395: *
396: * @param key message key
397: * @param parms optional message parameters
398: * @param t optional exception
399: */
400: protected static void _logif(String key, Object[] parms, Throwable t) {
401: _logif(getMessageLevel(key), key, parms, t);
402: }
403:
404: /**
405: * Checks if specified level is enabled and logs the message if it is
406: *
407: * @param level specified logger level
408: * @param key message key
409: * @param parms optional message parameters
410: * @param t optional exception
411: */
412: protected static void _logif(Level level, String key,
413: Object[] parms, Throwable t) {
414: if (!logger.isEnabledFor(level))
415: return;
416: _log(level, key, parms, t);
417: }
418:
419: /**
420: * Logs specified message to current logger
421: * <P>
422: * This method does not call those methods in Logger which are supposed
423: * to be used, but instead calls appenders directly thus avoiding double
424: * checking for levels, however this can be easily replaced with standard
425: * method, just swap the comments
426: *
427: * @param level specified logger level
428: * @param key message key
429: * @param parms optional message parameters
430: * @param t optional exception
431: */
432: protected static void _log(Level level, String key, Object[] parms,
433: Throwable t) {
434: String message = getMessage(key, parms);
435: //logger.log(FQCN, level, message, t);
436: logger.callAppenders(new LoggingEvent(FQCN, logger, level,
437: message, t));
438: }
439:
440: /**
441: * Retrieves and formats a message given by its resource key
442: * <P>
443: * The messages is retrieved from resource bundle associated with current logger,
444: * then formatted using java.util.MessageFormat
445: *
446: * @param key resource key, if message is not found in the resource then the key is used as a message
447: * @param parms optional parameters
448: * @return formatted message
449: */
450: public static String getMessage(String key, Object[] parms) {
451: return getMessage(logger.getResourceBundle(), key, parms);
452: }
453:
454: /**
455: * Retrieves and formats a message given by its resource key
456: * <P>
457: * The messages is retrieved from specified resource bundle or from standard jgenerator
458: * bundle if the specified one is null, then the message is formatted using java.util.MessageFormat
459: *
460: * @param rb specified resource bundle
461: * @param key resource key, if message is not found in the resource then the key is used as a message
462: * @param parms optional parameters
463: * @return formatted message
464: */
465: public static String getMessage(ResourceBundle rb, String key,
466: Object[] parms) {
467: if (rb == null) {
468: rb = Resource.getInstance();
469: }
470:
471: String msg;
472: try {
473: msg = rb.getString(key);
474: } catch (MissingResourceException e) {
475: msg = "No resource is associated with key \"" + key + "\".";
476: error(msg);
477: } catch (Throwable t) {
478: msg = "Error retrieving resource by key \"" + key + "\".";
479: error(msg, t);
480: }
481:
482: if (parms != null) {
483: msg = java.text.MessageFormat.format(msg, parms);
484: }
485:
486: return msg;
487: }
488:
489: }
|