You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by ca...@apache.org on 2007/04/19 19:27:31 UTC
svn commit: r530495 -
/logging/sandbox/log4j/component/src/main/java/org/apache/log4j/LoggerRepositoryExImpl.java
Author: carnold
Date: Thu Apr 19 10:27:30 2007
New Revision: 530495
URL: http://svn.apache.org/viewvc?view=rev&rev=530495
Log:
Bug 42094: Add LoggerRepositoryExImpl
Added:
logging/sandbox/log4j/component/src/main/java/org/apache/log4j/LoggerRepositoryExImpl.java
- copied, changed from r530488, logging/log4j/trunk/src/java/org/apache/log4j/Hierarchy.java
Copied: logging/sandbox/log4j/component/src/main/java/org/apache/log4j/LoggerRepositoryExImpl.java (from r530488, logging/log4j/trunk/src/java/org/apache/log4j/Hierarchy.java)
URL: http://svn.apache.org/viewvc/logging/sandbox/log4j/component/src/main/java/org/apache/log4j/LoggerRepositoryExImpl.java?view=diff&rev=530495&p1=logging/log4j/trunk/src/java/org/apache/log4j/Hierarchy.java&r1=530488&p2=logging/sandbox/log4j/component/src/main/java/org/apache/log4j/LoggerRepositoryExImpl.java&r2=530495
==============================================================================
--- logging/log4j/trunk/src/java/org/apache/log4j/Hierarchy.java (original)
+++ logging/sandbox/log4j/component/src/main/java/org/apache/log4j/LoggerRepositoryExImpl.java Thu Apr 19 10:27:30 2007
@@ -15,27 +15,21 @@
* limitations under the License.
*/
-
-// WARNING This class MUST not have references to the Category or
-// WARNING RootLogger classes in its static initiliazation neither
-// WARNING directly nor indirectly.
package org.apache.log4j;
-import org.apache.log4j.helpers.IntializationUtil;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.or.ObjectRenderer;
import org.apache.log4j.or.RendererMap;
import org.apache.log4j.plugins.PluginRegistry;
import org.apache.log4j.scheduler.Scheduler;
import org.apache.log4j.spi.ErrorItem;
+import org.apache.log4j.spi.HierarchyEventListener;
import org.apache.log4j.spi.LoggerEventListener;
import org.apache.log4j.spi.LoggerFactory;
-import org.apache.log4j.spi.LoggerRepositoryEx;
+import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.LoggerRepositoryEventListener;
+import org.apache.log4j.spi.LoggerRepositoryEx;
import org.apache.log4j.spi.RendererSupport;
-import org.apache.log4j.spi.RootLogger;
-import org.apache.log4j.spi.HierarchyEventListener;
-import org.apache.log4j.spi.HierarchyEventListenerAdapter;
import java.util.ArrayList;
import java.util.Enumeration;
@@ -46,80 +40,50 @@
import java.util.Vector;
-// Contributors: Luke Blanshard <lu...@quiq.com>
-// Mario Schomburg - IBM Global Services/Germany
-// Anders Kristensen
-// Igor Poteryaev
-
-
/**
- This class is specialized in retrieving loggers by name and also
- maintaining the logger hierarchy.
-
- <p><em>The casual user does not have to deal with this class
- directly.</em>
-
- <p>The structure of the logger hierarchy is maintained by the
- {@link #getLogger} method. The hierarchy is such that children link
- to their parent but parents do not have any pointers to their
- children. Moreover, loggers can be instantiated in any order, in
- particular descendant before ancestor.
-
- <p>In case a descendant is created before a particular ancestor,
- then it creates a provision node for the ancestor and adds itself
- to the provision node. Other descendants of the same ancestor add
- themselves to the previously created provision node.
-
- @author Ceki Gülcü
- @author Mark Womack
-
+ * This class implements LoggerRepositoryEx by
+ * wrapping an existing LoggerRepository implementation
+ * and implementing the newly added capabilities.
*/
-public class Hierarchy implements LoggerRepositoryEx, RendererSupport {
+public final class LoggerRepositoryExImpl
+ implements LoggerRepositoryEx, RendererSupport {
/**
- * Logger factory.
+ * Wrapped logger repository.
*/
- private LoggerFactory loggerFactory;
- /**
- * List of repository event listeners.
- */
- private final ArrayList repositoryEventListeners;
- /**
- * List of logger event listeners.
- */
- private final ArrayList loggerEventListeners;
- /**
- * Name of hierarchy.
- */
- String name;
+ private final LoggerRepository repo;
+
/**
- * Loggers by name.
+ * Logger factory. Does not affect class of logger
+ * created by underlying repository.
*/
- Hashtable ht;
+ private LoggerFactory loggerFactory;
+
/**
- * Root logger.
+ * Renderer support.
*/
- Logger root;
+ private final RendererSupport rendererSupport;
+
/**
- * Map of ObjectRenderer by Class.
+ * List of repository event listeners.
*/
- RendererMap rendererMap;
+ private final ArrayList repositoryEventListeners = new ArrayList();
/**
- * Numeric value for threshold.
+ * Map of HierarchyEventListener keyed by LoggingEventListener.
*/
- int thresholdInt;
+ private final Map loggerEventListeners = new HashMap();
/**
- * Threshold.
+ * Name of hierarchy.
*/
- Level threshold;
+ private String name;
/**
* Plug in registry.
*/
- PluginRegistry pluginRegistry;
+ private PluginRegistry pluginRegistry;
/**
* Properties.
*/
- Map properties;
+ private final Map properties = new Hashtable();
/**
* Scheduler.
*/
@@ -128,13 +92,8 @@
/** The repository can also be used as an object store
* for various objects used by log4j components.
*/
- private Map objectMap;
+ private Map objectMap = new HashMap();
- /**
- * The internal logger used by this instance of
- * Hierarchy for its own reporting.
- */
- private Logger myLogger;
/**
* Error list.
@@ -142,51 +101,29 @@
private List errorList = new Vector();
/**
- * True if no appender warning has already been issued.
- */
- boolean emittedNoAppenderWarning = false;
- /**
* True if hierarchy has not been modified.
*/
- boolean pristine = true;
+ private boolean pristine = true;
/**
Constructs a new logger hierarchy.
- @param rootLogger The root of the new hierarchy.
-
- */
- public Hierarchy(final Logger rootLogger) {
- ht = new Hashtable();
- repositoryEventListeners = new ArrayList(1);
- loggerEventListeners = new ArrayList(1);
- this.root = rootLogger;
- this.objectMap = new HashMap();
- // Enable all level levels by default.
- setThreshold(Level.ALL);
- this.root.setHierarchy(this);
- rendererMap = new RendererMap();
- rendererMap.setLoggerRepository(this);
- properties = new Hashtable();
- loggerFactory = new DefaultLoggerFactory();
- }
+ @param repository Base implementation of repository.
- /**
- * Constructs a new logger hierarchy with a default {@link RootLogger}.
*/
- public Hierarchy() {
- this(new RootLogger());
+ public LoggerRepositoryExImpl(final LoggerRepository repository) {
+ super();
+ if (repository == null) {
+ throw new NullPointerException("repository");
+ }
+ repo = repository;
+ if (repository instanceof RendererSupport) {
+ rendererSupport = (RendererSupport) repository;
+ } else {
+ rendererSupport = new RendererSupportImpl();
+ }
}
- /**
- Add an object renderer for a specific class.
- @param classToRender class to render
- @param or renderer
- */
- public void addRenderer(final Class classToRender,
- final ObjectRenderer or) {
- rendererMap.put(classToRender, or);
- }
/**
Add a {@link LoggerRepositoryEventListener} to the repository. The
@@ -197,7 +134,7 @@
final LoggerRepositoryEventListener listener) {
synchronized (repositoryEventListeners) {
if (repositoryEventListeners.contains(listener)) {
- getMyLogger().warn(
+ LogLog.warn(
"Ignoring attempt to add a previously "
+ "registered LoggerRepositoryEventListener.");
} else {
@@ -206,16 +143,6 @@
}
}
- /**
- * Gets logger to be used for internal diagnostic messages.
- * @return logger
- */
- private Logger getMyLogger() {
- if (myLogger == null) {
- myLogger = getLogger(this.getClass().getName());
- }
- return myLogger;
- }
/**
Remove a {@link LoggerRepositoryEventListener} from the repository.
@@ -225,7 +152,7 @@
final LoggerRepositoryEventListener listener) {
synchronized (repositoryEventListeners) {
if (!repositoryEventListeners.contains(listener)) {
- getMyLogger().warn(
+ LogLog.warn(
"Ignoring attempt to remove a "
+ "non-registered LoggerRepositoryEventListener.");
} else {
@@ -242,11 +169,14 @@
*/
public void addLoggerEventListener(final LoggerEventListener listener) {
synchronized (loggerEventListeners) {
- if (loggerEventListeners.contains(listener)) {
- getMyLogger().warn(
+ if (loggerEventListeners.get(listener) != null) {
+ LogLog.warn(
"Ignoring attempt to add a previously registerd LoggerEventListener.");
} else {
- loggerEventListeners.add(listener);
+ HierarchyEventListenerProxy proxy =
+ new HierarchyEventListenerProxy(listener);
+ loggerEventListeners.put(listener, proxy);
+ repo.addHierarchyEventListener(proxy);
}
}
}
@@ -259,7 +189,7 @@
*/
public
void addHierarchyEventListener(final HierarchyEventListener listener) {
- addLoggerEventListener(new HierarchyEventListenerAdapter(listener));
+ repo.addHierarchyEventListener(listener);
}
@@ -269,41 +199,24 @@
@since 1.3*/
public void removeLoggerEventListener(final LoggerEventListener listener) {
synchronized (loggerEventListeners) {
- if (!loggerEventListeners.contains(listener)) {
- getMyLogger().warn(
+ HierarchyEventListenerProxy proxy =
+ (HierarchyEventListenerProxy) loggerEventListeners.get(listener);
+ if (proxy == null) {
+ LogLog.warn(
"Ignoring attempt to remove a non-registered LoggerEventListener.");
} else {
loggerEventListeners.remove(listener);
+ proxy.disable();
}
}
}
- /**
- This call will clear all logger definitions from the internal
- hashtable. Invoking this method will irrevocably mess up the
- logger hierarchy.
-
- <p>You should <em>really</em> know what you are doing before
- invoking this method.
-
- @since 0.9.0 */
- public void clear() {
- //System.out.println("\n\nAbout to clear internal hash table.");
- ht.clear();
- }
-
/**
* Issue warning that there are no appenders in hierarchy.
* @param cat logger, not currently used.
*/
public void emitNoAppenderWarning(final Category cat) {
- // No appenders in hierarchy, warn user only once.
- if (!this.emittedNoAppenderWarning) {
- //LogLog.warn(
- // "No appenders could be found for logger (" + cat.getName() + ").");
- //LogLog.warn("Please initialize the log4j system properly.");
- this.emittedNoAppenderWarning = true;
- }
+ repo.emitNoAppenderWarning(cat);
}
/**
@@ -314,13 +227,7 @@
@return true if logger exists.
*/
public Logger exists(final String loggerName) {
- Object o = ht.get(new CategoryKey(loggerName));
-
- if (o instanceof Logger) {
- return (Logger) o;
- } else {
- return null;
- }
+ return repo.exists(loggerName);
}
/**
@@ -377,13 +284,7 @@
@param levelStr symbolic name for level
*/
public void setThreshold(final String levelStr) {
- Level l = Level.toLevel(levelStr, null);
-
- if (l != null) {
- setThreshold(l);
- } else {
- getMyLogger().warn("Could not convert [" + levelStr + "] to Level.");
- }
+ repo.setThreshold(levelStr);
}
/**
@@ -393,10 +294,7 @@
@param l The minimum level for which logging requests are sent to
their appenders. */
public void setThreshold(final Level l) {
- if (l != null) {
- thresholdInt = l.level;
- threshold = l;
- }
+ repo.setThreshold(l);
}
/**
@@ -419,27 +317,7 @@
*/
public void fireAddAppenderEvent(final Category logger,
final Appender appender) {
- if (logger instanceof Logger) {
- fireAddAppenderEvent((Logger) logger, appender);
- }
- }
-
- /**
- Requests that a appender added event be sent to any registered
- {@link LoggerEventListener}.
- @param logger The logger to which the appender was added.
- @param appender The appender added to the logger.
- @since 1.3
- */
- public void fireAddAppenderEvent(final Logger logger,
- final Appender appender) {
- ArrayList list = copyListenerList(loggerEventListeners);
- int size = list.size();
-
- for (int i = 0; i < size; i++) {
- ((LoggerEventListener) list.get(i)).
- appenderAddedEvent(logger, appender);
- }
+ repo.fireAddAppenderEvent(logger, appender);
}
@@ -451,27 +329,11 @@
*/
public void fireRemoveAppenderEvent(final Category logger,
final Appender appender) {
- if (logger instanceof Logger) {
- fireRemoveAppenderEvent((Logger) logger, appender);
+ if (repo instanceof Hierarchy) {
+ ((Hierarchy) repo).fireRemoveAppenderEvent(logger, appender);
}
}
- /**
- Requests that a appender removed event be sent to any registered
- {@link LoggerEventListener}.
- @param logger The logger from which the appender was removed.
- @param appender The appender removed from the logger.
- @since 1.3*/
- public void fireRemoveAppenderEvent(final Logger logger,
- final Appender appender) {
- ArrayList list = copyListenerList(loggerEventListeners);
- int size = list.size();
-
- for (int i = 0; i < size; i++) {
- ((LoggerEventListener) list.get(i)).appenderRemovedEvent(
- logger, appender);
- }
- }
/**
Requests that a level changed event be sent to any registered
@@ -479,47 +341,16 @@
@param logger The logger which changed levels.
@since 1.3*/
public void fireLevelChangedEvent(final Logger logger) {
- ArrayList list = copyListenerList(loggerEventListeners);
- int size = list.size();
-
- for (int i = 0; i < size; i++) {
- ((LoggerEventListener) list.get(i)).levelChangedEvent(logger);
- }
}
/**
+ * @TODO
Requests that a configuration changed event be sent to any registered
{@link LoggerRepositoryEventListener}.
@since 1.3*/
public void fireConfigurationChangedEvent() {
- ArrayList list = copyListenerList(repositoryEventListeners);
- int size = list.size();
-
- for (int i = 0; i < size; i++) {
- ((LoggerRepositoryEventListener) list.get(i)).configurationChangedEvent(
- this);
- }
}
- /**
- Returns a copy of the given listener vector.
- @param list original list
- @return copy of list
- */
- private ArrayList copyListenerList(final ArrayList list) {
- ArrayList listCopy = null;
-
- synchronized (list) {
- int size = list.size();
- listCopy = new ArrayList(size);
-
- for (int x = 0; x < size; x++) {
- listCopy.add(list.get(x));
- }
- }
-
- return listCopy;
- }
/**
Returns a {@link Level} representation of the <code>enable</code>
@@ -528,20 +359,9 @@
@since 1.2 */
public Level getThreshold() {
- return threshold;
+ return repo.getThreshold();
}
- /**
- Returns an integer representation of the this repository's
- threshold.
-
- @since 1.2 */
-
- //public
- //int getThresholdInt() {
- // return thresholdInt;
- //}
-
/**
Return a new logger instance named as the first parameter using
@@ -556,7 +376,7 @@
*/
public Logger getLogger(final String loggerName) {
- return getLogger(loggerName, loggerFactory);
+ return repo.getLogger(loggerName);
}
/**
@@ -575,47 +395,7 @@
*/
public Logger getLogger(final String loggerName,
final LoggerFactory factory) {
- //System.out.println("getInstance("+name+") called.");
- CategoryKey key = new CategoryKey(loggerName);
-
-
- // Synchronize to prevent write conflicts. Read conflicts (in
- // getChainedLevel method) are possible only if variable
- // assignments are non-atomic.
- Logger logger;
-
- synchronized (ht) {
- Object o = ht.get(key);
-
- if (o == null) {
- LogLog.debug(
- "Creating new logger [" + loggerName
- + "] in repository [" + getName() + "].");
- logger = factory.makeNewLoggerInstance(loggerName);
- logger.setHierarchy(this);
- ht.put(key, logger);
- updateParents(logger);
-
- return logger;
- } else if (o instanceof Logger) {
- LogLog.debug(
- "Returning existing logger [" + loggerName
- + "] in repository [" + getName() + "].");
- return (Logger) o;
- } else if (o instanceof ProvisionNode) {
- //System.out.println("("+name+") ht.get(this) returned ProvisionNode");
- logger = factory.makeNewLoggerInstance(loggerName);
- logger.setHierarchy(this);
- ht.put(key, logger);
- updateChildren((ProvisionNode) o, logger);
- updateParents(logger);
-
- return logger;
- } else {
- // It should be impossible to arrive here
- return null; // but let's keep the compiler happy.
- }
- }
+ return repo.getLogger(loggerName, factory);
}
/**
@@ -627,22 +407,7 @@
@return enumerator of current loggers
*/
public Enumeration getCurrentLoggers() {
- // The accumlation in v is necessary because not all elements in
- // ht are Logger objects as there might be some ProvisionNodes
- // as well.
- Vector v = new Vector(ht.size());
-
- Enumeration elems = ht.elements();
-
- while (elems.hasMoreElements()) {
- Object o = elems.nextElement();
-
- if (o instanceof Logger) {
- v.addElement(o);
- }
- }
-
- return v.elements();
+ return repo.getCurrentLoggers();
}
/**
@@ -668,7 +433,7 @@
@deprecated Please use {@link #getCurrentLoggers} instead.
*/
public Enumeration getCurrentCategories() {
- return getCurrentLoggers();
+ return repo.getCurrentCategories();
}
/**
@@ -676,7 +441,7 @@
@return renderer map
*/
public RendererMap getRendererMap() {
- return rendererMap;
+ return rendererSupport.getRendererMap();
}
/**
@@ -686,7 +451,7 @@
@return root of hierarchy
*/
public Logger getRootLogger() {
- return root;
+ return repo.getRootLogger();
}
/**
@@ -698,7 +463,7 @@
@return true if disabled for specified level
*/
public boolean isDisabled(final int level) {
- return thresholdInt > level;
+ return repo.isDisabled(level);
}
/**
@@ -716,36 +481,7 @@
@since 0.8.5 */
public void resetConfiguration() {
- getRootLogger().setLevel(Level.DEBUG);
- root.setResourceBundle(null);
- setThreshold(Level.ALL);
-
-
- // the synchronization is needed to prevent JDK 1.2.x hashtable
- // surprises
- synchronized (ht) {
- shutdown(true); // nested locks are OK
-
- Enumeration cats = getCurrentLoggers();
-
- while (cats.hasMoreElements()) {
- Logger c = (Logger) cats.nextElement();
- c.setLevel(null);
- c.setAdditivity(true);
- c.setResourceBundle(null);
- }
- }
-
- rendererMap.clear();
-
- // inform the listeners that the configuration has been reset
- ArrayList list = copyListenerList(repositoryEventListeners);
- int size = list.size();
-
- for (int i = 0; i < size; i++) {
- ((LoggerRepositoryEventListener) list.get(i)).configurationResetEvent(
- this);
- }
+ repo.resetConfiguration();
}
/**
@@ -755,7 +491,7 @@
*/
public void setRenderer(final Class renderedClass,
final ObjectRenderer renderer) {
- rendererMap.put(renderedClass, renderer);
+ rendererSupport.setRenderer(renderedClass, renderer);
}
/**
@@ -788,161 +524,11 @@
@since 1.0 */
public void shutdown() {
- shutdown(false);
+ repo.shutdown();
}
- /**
- * Shutdown hierarchy.
- * @param doingReset true is resetting hierarchy
- */
- private void shutdown(final boolean doingReset) {
-
- // stop this repo's scheduler if it has one
- if (scheduler != null) {
- scheduler.shutdown();
- scheduler = null;
- }
-
- // let listeners know about shutdown if this is
- // not being done as part of a reset.
- if (!doingReset) {
- ArrayList list = copyListenerList(repositoryEventListeners);
- int size = list.size();
-
- for (int i = 0; i < size; i++) {
- ((LoggerRepositoryEventListener) list.get(i)).shutdownEvent(this);
- }
- }
-
- Logger rootLogger = getRootLogger();
-
- // begin by closing nested appenders
- rootLogger.closeNestedAppenders();
-
- synchronized (ht) {
- Enumeration cats = this.getCurrentLoggers();
-
- while (cats.hasMoreElements()) {
- Logger c = (Logger) cats.nextElement();
- c.closeNestedAppenders();
- }
-
- // then, remove all appenders
- rootLogger.removeAllAppenders();
- cats = this.getCurrentLoggers();
-
- while (cats.hasMoreElements()) {
- Logger c = (Logger) cats.nextElement();
- c.removeAllAppenders();
- }
- }
-
- // log4j self configure
- IntializationUtil.log4jInternalConfiguration(this);
- }
/**
- This method loops through all the *potential* parents of
- 'cat'. There 3 possible cases:
-
- 1) No entry for the potential parent of 'cat' exists
-
- We create a ProvisionNode for this potential parent and insert
- 'cat' in that provision node.
-
- 2) There entry is of type Logger for the potential parent.
-
- The entry is 'cat's nearest existing parent. We update cat's
- parent field with this entry. We also break from the loop
- because updating our parent's parent is our parent's
- responsibility.
-
- 3) There entry is of type ProvisionNode for this potential parent.
-
- We add 'cat' to the list of children for this potential parent.
- @param cat logger whose parents are updated
- */
- private void updateParents(final Logger cat) {
- String loggerName = cat.name;
- int length = loggerName.length();
- boolean parentFound = false;
-
-
- //System.out.println("UpdateParents called for " + name);
- // if name = "w.x.y.z",
- // loop through "w.x.y", "w.x" and "w", but not "w.x.y.z"
- for (
- int i = loggerName.lastIndexOf('.', length - 1); i >= 0;
- i = loggerName.lastIndexOf('.', i - 1)) {
- String substr = loggerName.substring(0, i);
-
- //System.out.println("Updating parent : " + substr);
- CategoryKey key = new CategoryKey(substr); // simple constructor
- Object o = ht.get(key);
-
- // Create a provision node for a future parent.
- if (o == null) {
- //System.out.println("No parent "+substr+" found. Creating ProvisionNode.");
- ProvisionNode pn = new ProvisionNode(cat);
- ht.put(key, pn);
- } else if (o instanceof Logger) {
- parentFound = true;
- cat.parent = (Logger) o;
-
- //System.out.println("Linking " + cat.name + " -> " + ((Logger) o).name);
- break; // no need to update the ancestors of the closest ancestor
- } else if (o instanceof ProvisionNode) {
- ((ProvisionNode) o).addElement(cat);
- } else {
- Exception e =
- new IllegalStateException(
- "unexpected object type " + o.getClass() + " in ht.");
- e.printStackTrace();
- }
- }
-
- // If we could not find any existing parents, then link with root.
- if (!parentFound) {
- cat.parent = root;
- }
- }
-
- /**
- We update the links for all the children that placed themselves
- in the provision node 'pn'. The second argument 'cat' is a
- reference for the newly created Logger, parent of all the
- children in 'pn'
-
- We loop on all the children 'c' in 'pn':
-
- If the child 'c' has been already linked to a child of
- 'cat' then there is no need to update 'c'.
-
- Otherwise, we set cat's parent field to c's parent and set
- c's parent field to cat.
- @param pn provisional node
- @param logger parent logger
-
- */
- private void updateChildren(final ProvisionNode pn,
- final Logger logger) {
- //System.out.println("updateChildren called for " + logger.name);
- final int last = pn.size();
-
- for (int i = 0; i < last; i++) {
- Logger l = (Logger) pn.elementAt(i);
-
-
- //System.out.println("Updating child " +p.name);
- // Unless this child already points to a correct (lower) parent,
- // make cat.parent point to l.parent and l.parent to cat.
- if (!l.parent.name.startsWith(logger.name)) {
- logger.parent = l.parent;
- l.parent = logger;
- }
- }
- }
- /**
* Return this repository's own scheduler.
* The scheduler is lazily instantiated.
* @return this repository's own scheduler.
@@ -993,5 +579,90 @@
public LoggerFactory getLoggerFactory() {
return loggerFactory;
}
+
+ /**
+ * Implementation of RendererSupportImpl if not
+ * provided by LoggerRepository.
+ */
+ private static final class RendererSupportImpl implements RendererSupport {
+ /**
+ * Renderer map.
+ */
+ private final RendererMap renderers = new RendererMap();
+
+ /**
+ * Create new instance.
+ */
+ public RendererSupportImpl() {
+ super();
+ }
+
+ /** {@inheritDoc} */
+ public RendererMap getRendererMap() {
+ return renderers;
+ }
+
+ /** {@inheritDoc} */
+ public void setRenderer(final Class renderedClass,
+ final ObjectRenderer renderer) {
+ renderers.put(renderedClass, renderer);
+ }
+ }
+
+ /**
+ * Proxy that implements HierarchyEventListener
+ * and delegates to LoggerEventListener.
+ */
+ private static final class HierarchyEventListenerProxy
+ implements HierarchyEventListener {
+ /**
+ * Wrapper listener.
+ */
+ private LoggerEventListener listener;
+
+ /**
+ * Creates new instance.
+ * @param l listener
+ */
+ public HierarchyEventListenerProxy(final LoggerEventListener l) {
+ super();
+ if (l == null) {
+ throw new NullPointerException("l");
+ }
+ listener = l;
+ }
+
+ /** {@inheritDoc} */
+ public void addAppenderEvent(final Category cat,
+ final Appender appender) {
+ if (isEnabled() && cat instanceof Logger) {
+ listener.appenderAddedEvent((Logger) cat, appender);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void removeAppenderEvent(final Category cat,
+ final Appender appender) {
+ if (isEnabled() && cat instanceof Logger) {
+ listener.appenderRemovedEvent((Logger) cat, appender);
+ }
+ }
+
+ /**
+ * Disable forwarding of notifications to
+ * simulate removal of listener.
+ */
+ public synchronized void disable() {
+ listener = null;
+ }
+
+ /**
+ * Gets whether proxy is enabled.
+ * @return true if proxy is enabled.
+ */
+ private synchronized boolean isEnabled() {
+ return listener != null;
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org