All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.log4j.JBossLogManagerFacade Maven / Gradle / Ivy

There is a newer version: 1.3.1.Final
Show newest version
package org.apache.log4j;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;

import org.apache.log4j.spi.LoggerFactory;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.RootLogger;
import org.jboss.logmanager.LogContext;
import org.jboss.logmanager.Logger.AttachmentKey;

/**
 * A simple facade to interact between {@link org.apache.log4j.LogManager} and {@link org.jboss.logmanager.LogManager}.
 *
 * @author James R. Perkins
 */
public class JBossLogManagerFacade {

    public static final String LOG4J_ROOT_NAME = "root";
    public static final String JBL_ROOT_NAME = "";

    private static final AttachmentKey LOGGER_KEY = new AttachmentKey();
    private static final AttachmentKey HIERARCHY_KEY = new AttachmentKey();
    private static final AttachmentKey LOGGER_NODE_KEY = new AttachmentKey();

    private static final PrivilegedAction LOG_CONTEXT_ACTION = new PrivilegedAction() {
        @Override
        public LogContext run() {
            return LogContext.getLogContext();
        }
    };

    private JBossLogManagerFacade() {
    }

    /**
     * Returns a JBoss Log Manger logger.
     *
     * @param name the name of the logger.
     *
     * @return a logger.
     */
    static org.jboss.logmanager.Logger getJBossLogger(final String name) {
        return getJBossLogger(getLogContext(), name);
    }

    /**
     * Returns a JBoss Log Manger logger.
     *
     * @param name the name of the logger.
     *
     * @return a logger.
     */
    static org.jboss.logmanager.Logger getJBossLogger(final LogContext logContext, final String name) {
        final String loggerName = (name == null || name.equals(LOG4J_ROOT_NAME)) ? JBL_ROOT_NAME : name;
        return logContext.getLogger(loggerName);
    }

    /**
     * Gets the log4j logger repository using the default log context.
     *
     * @return the log4j logger repository
     */
    static LoggerRepository getLoggerRepository() {
        return getLoggerRepository(null);
    }

    /**
     * Gets the log4j logger repository for the log context.
     *
     * @param logContext the log context which the log4j repository is located on or should be created on or {@code
     *                   null} to create the repository on the default log context
     *
     * @return the log4j logger repository
     */
    public static LoggerRepository getLoggerRepository(final LogContext logContext) {
        return doPrivileged(new PrivilegedAction() {
            @Override
            public Hierarchy run() {
                final LogContext lc = logContext == null ? LogContext.getLogContext() : logContext;
                final org.jboss.logmanager.Logger jbossRoot = getJBossLogger(lc, JBL_ROOT_NAME);
                Hierarchy hierarchy = jbossRoot.getAttachment(HIERARCHY_KEY);
                if (hierarchy == null) {
                    // Always attach the root logger
                    Logger root = jbossRoot.getAttachment(LOGGER_KEY);
                    if (root == null) {
                        root = new RootLogger(JBossLevelMapping.getPriorityFor(jbossRoot.getLevel()));
                        final Logger appearing = jbossRoot.attachIfAbsent(LOGGER_KEY, root);
                        if (appearing != null) {
                            root = appearing;
                        }
                    }
                    hierarchy = new Hierarchy(root);
                    final Hierarchy appearing = jbossRoot.attachIfAbsent(HIERARCHY_KEY, hierarchy);
                    if (appearing != null) {
                        hierarchy = appearing;
                    }
                }
                return hierarchy;
            }
        });
    }

    /**
     * Checks the log context for an attached logger. If the logger is found it is returned, otherwise {@code null} is
     * returned.
     *
     * @param name the name of the logger to check.
     *
     * @return the logger or {@code null} if the logger does not exist.
     */

    static Logger exists(String name) {
        final org.jboss.logmanager.Logger logger = getLogContext().getLoggerIfExists(name);
        return logger == null ? null : getLogger(logger);
    }

    /**
     * Gets the log4j logger that is attached to the JBoss Log Manager logger. If the logger does not exist, {@code
     * null} is returned.
     *
     * @param lmLogger the JBoss Log Manager logger.
     *
     * @return the logger or {@code null} if no logger is attached.
     */
    static Logger getLogger(org.jboss.logmanager.Logger lmLogger) {
        return getAttachment(lmLogger, LOGGER_KEY);
    }

    /**
     * Gets the logger or creates the logger via the .
     *
     * @param repository the repository the logger should be set to use.
     * @param name       the name of the logger.
     * @param factory    the factory to create the logger if it does not exist.
     *
     * @return the logger.
     */
    static Logger getOrCreateLogger(final LoggerRepository repository, final String name, final LoggerFactory factory) {
        final org.jboss.logmanager.Logger lmLogger = getJBossLogger(name);
        Logger logger = getLogger(lmLogger);
        if (logger == null) {
            logger = factory.makeNewLoggerInstance(name);
            final Logger currentLogger = attachIfAbsent(lmLogger, LOGGER_KEY, logger);
            if (currentLogger != null) {
                logger = currentLogger;
            }
            final LoggerNode loggerNode;
            if (System.getSecurityManager() == null) {
                loggerNode = lmLogger.detach(LOGGER_NODE_KEY);
            } else {
                loggerNode = AccessController.doPrivileged(new PrivilegedAction() {
                    @Override
                    public LoggerNode run() {
                        return lmLogger.detach(LOGGER_NODE_KEY);
                    }
                });
            }
            if (loggerNode != null) {
                updateChildren(loggerNode, logger);
            }
            updateParents(repository, logger, lmLogger);
        }
        return logger;
    }

    /**
     * Returns a collection of the loggers that exist.
     *
     * @return a collection of the loggers.
     */
    static Collection getLoggers() {
        final LogContext logContext = getLogContext();
        final List loggerNames = logContext.getLoggingMXBean().getLoggerNames();
        final List currentLoggers = new ArrayList(loggerNames.size());
        for (String name : loggerNames) {
            final org.jboss.logmanager.Logger lmLogger = logContext.getLoggerIfExists(name);
            if (lmLogger != null) {
                final Logger logger = getLogger(lmLogger);
                if (logger != null) {
                    currentLoggers.add(logger);
                }
            }
        }
        return currentLoggers;
    }

    /**
     * This method is not thread safe.
     */
    private static void updateParents(final LoggerRepository repository, final Logger cat, final org.jboss.logmanager.Logger parentLogger) {
        final LogContext logContext = parentLogger.getLogContext();
        final String name = cat.getName();
        int length = name.length();
        boolean addRootAsParent = true;
        // if name = "w.x.y.z", loop through "w.x.y", "w.x" and "w", but not "w.x.y.z"
        for (int i = name.lastIndexOf('.', length - 1); i >= 0; i = name.lastIndexOf('.', i - 1)) {
            final String loggerName = name.substring(0, i);
            final org.jboss.logmanager.Logger lmLogger = logContext.getLoggerIfExists(loggerName);
            // This should never be null, but we'll be safe
            if (lmLogger != null) {
                cat.parent = getLogger(lmLogger);
                if (cat.parent == null) {
                    final LoggerNode loggerNode = lmLogger.getAttachment(LOGGER_NODE_KEY);
                    if (loggerNode == null) {
                        final LoggerNode appearing = attachIfAbsent(lmLogger, LOGGER_NODE_KEY, new LoggerNode(cat));
                        if (appearing != null) {
                            appearing.add(cat);
                        }
                    } else {
                        loggerNode.add(cat);
                    }
                } else {
                    addRootAsParent = false;
                    break;
                }
            }
        }
        // If we could not find any existing parents, then link with root.
        if (addRootAsParent) cat.parent = repository.getRootLogger();
    }

    private static void updateChildren(final LoggerNode loggerNode, final Logger logger) {

        for (Logger l : loggerNode) {
            // Note below was taken directly from log4j

            // 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.getName().startsWith(logger.getName())) {
                logger.parent = l.parent;
                l.parent = logger;
            }
        }
    }

    private static LogContext getLogContext() {
        return doPrivileged(LOG_CONTEXT_ACTION);
    }

    private static  T getAttachment(final org.jboss.logmanager.Logger logger, final AttachmentKey key) {
        return doPrivileged(new PrivilegedAction() {
            @Override
            public T run() {
                return logger.getAttachment(key);
            }
        });
    }

    private static  T attachIfAbsent(final org.jboss.logmanager.Logger logger, final AttachmentKey key, final T value) {
        return doPrivileged(new PrivilegedAction() {
            @Override
            public T run() {
                return logger.attachIfAbsent(key, value);
            }
        });
    }

    private static  T doPrivileged(final PrivilegedAction action) {
        if (System.getSecurityManager() == null) {
            return action.run();
        }
        return AccessController.doPrivileged(action);
    }

    private static class LoggerNode implements Iterable {
        private final Set loggers;

        public LoggerNode(final Logger logger) {
            loggers = new ConcurrentSkipListSet(LoggerComparator.INSTANCE);
            loggers.add(logger);
        }

        public void add(final Logger logger) {
            loggers.add(logger);
        }

        @Override
        public Iterator iterator() {
            return loggers.iterator();
        }
    }

    private static class LoggerComparator implements Comparator {
        static final LoggerComparator INSTANCE = new LoggerComparator();

        @Override
        public int compare(final Logger o1, final Logger o2) {
            return o1.getName().compareTo(o2.getName());
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy