001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2006-2007, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.util.logging;
017:
018: import java.util.logging.Logger;
019: import org.geotools.util.WeakValueHashMap;
020:
021: /**
022: * A factory for Java {@link Logger} wrapping an other logging framework. This factory is used
023: * only when wanting to log to an other framework than Java logging. The {@link #getLogger}
024: * method returns some subclass of {@link Logger} (typicallly {@link LoggerAdapter}) that
025: * forward directly all log methods to an other framework.
026: *
027: * @since 2.4
028: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/metadata/src/main/java/org/geotools/util/logging/LoggerFactory.java $
029: * @version $Id: LoggerFactory.java 27891 2007-11-14 14:10:48Z desruisseaux $
030: * @author Martin Desruisseaux
031: *
032: * @see Logging
033: * @see LoggerAdapter
034: */
035: public abstract class LoggerFactory {
036: /**
037: * The logger class. We ask for this information right at construction time in order to
038: * force a {@link NoClassDefFoundError} early rather than only the first time a message
039: * is logged.
040: */
041: private final Class loggerClass;
042:
043: /**
044: * The loggers created up to date.
045: */
046: private final WeakValueHashMap loggers;
047:
048: /**
049: * Creates a new factory.
050: *
051: * @param loggerClass The class of the wrapped logger.
052: */
053: protected LoggerFactory(final Class loggerClass) {
054: this .loggerClass = loggerClass;
055: loggers = new WeakValueHashMap();
056: }
057:
058: /**
059: * Returns the logger of the specified name, or {@code null}. If this method has already been
060: * invoked previously with the same {@code name} argument, then it may returns the same logger
061: * provided that:
062: * <ul>
063: * <li>the logger has not yet been garbage collected;</li>
064: * <li>the implementation instance (Log4J, SLF4J, <cite>etc.</cite>) returned by
065: * <code>{@linkplain #getImplementation getImplementation}(name)</code> has
066: * not changed.</li>
067: * </ul>
068: * Otherwise this method returns a new {@code Logger} instance, or {@code null} if the
069: * standard Java logging framework should be used.
070: *
071: * @param name The name of the logger.
072: * @return The logger, or {@code null}.
073: */
074: public Logger getLogger(final String name) {
075: final Object target = getImplementation(name);
076: if (target == null) {
077: return null;
078: }
079: synchronized (loggers) {
080: Logger logger = (Logger) loggers.get(name);
081: if (logger == null || !target.equals(unwrap(logger))) {
082: logger = wrap(name, target);
083: loggers.put(name, logger);
084: }
085: return logger;
086: }
087: }
088:
089: /**
090: * Returns the base class of objects to be returned by {@link #getImplementation}. The
091: * class depends on the underlying logging framework (Log4J, SLF4J, <cite>etc.</cite>).
092: */
093: public Class getImplementationClass() {
094: return loggerClass;
095: }
096:
097: /**
098: * Returns the implementation to use for the logger of the specified name. The object to be
099: * returned depends on the logging framework (Log4J, SLF4J, <cite>etc.</cite>). If the target
100: * framework redirects logging events to Java logging, then this method should returns
101: * {@code null} since we should not use wrapper at all.
102: *
103: * @param name The name of the logger.
104: * @return The logger as an object of the target logging framework (Log4J, SLF4J,
105: * <cite>etc.</cite>), or {@code null} if the target framework would redirect
106: * to the Java logging framework.
107: */
108: protected abstract Object getImplementation(String name);
109:
110: /**
111: * Wraps the specified {@linkplain #getImplementation implementation} in a Java logger.
112: *
113: * @param name The name of the logger.
114: * @param implementation An implementation returned by {@link #getImplementation}.
115: * @return A new logger wrapping the specified implementation.
116: * @throws ClassCastException if the given implementation is not an instance
117: * of the expected class.
118: */
119: protected abstract Logger wrap(String name, Object implementation)
120: throws ClassCastException;
121:
122: /**
123: * Returns the {@linkplain #getImplementation implementation} wrapped by the specified logger,
124: * or {@code null} if none. If the specified logger is not an instance of the expected class,
125: * then this method should returns {@code null}.
126: *
127: * @param logger The logger to test.
128: * @return The implementation wrapped by the specified logger, or {@code null} if none.
129: */
130: protected abstract Object unwrap(Logger logger);
131: }
|