⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classloaderlogmanager.java

📁 业界著名的tomcat服务器的最新6.0的源代码。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.juli;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLClassLoader;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.WeakHashMap;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;


/**
 * Per classloader LogManager implementation.
 */
public class ClassLoaderLogManager extends LogManager {


    // -------------------------------------------------------------- Variables


    /**
     * Map containing the classloader information, keyed per classloader. A
     * weak hashmap is used to ensure no classloader reference is leaked from 
     * application redeployment.
     */
    protected final Map<ClassLoader, ClassLoaderLogInfo> classLoaderLoggers = 
        new WeakHashMap<ClassLoader, ClassLoaderLogInfo>();

    
    /**
     * This prefix is used to allow using prefixes for the properties names
     * of handlers and their subcomponents.
     */
    protected ThreadLocal<String> prefix = new ThreadLocal<String>();

    
    // --------------------------------------------------------- Public Methods


    /**
     * Add the specified logger to the classloader local configuration.
     * 
     * @param logger The logger to be added
     */
    public synchronized boolean addLogger(final Logger logger) {

        final String loggerName = logger.getName();

        ClassLoader classLoader = 
            Thread.currentThread().getContextClassLoader();
        ClassLoaderLogInfo info = getClassLoaderInfo(classLoader);
        if (info.loggers.containsKey(loggerName)) {
            return false;
        }
        info.loggers.put(loggerName, logger);

        // Apply initial level for new logger
        final String levelString = getProperty(loggerName + ".level");
        if (levelString != null) {
            try {
                AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        logger.setLevel(Level.parse(levelString.trim()));
                        return null;
                    }
                });
            } catch (IllegalArgumentException e) {
                // Leave level set to null
            }
        }

        // If any parent loggers have levels definied, make sure they are
        // instantiated
        int dotIndex = loggerName.lastIndexOf('.');
        while (dotIndex >= 0) {
            final String parentName = loggerName.substring(0, dotIndex);
            if (getProperty(parentName + ".level") != null) {
                Logger.getLogger(parentName);
                break;
            }
            dotIndex = loggerName.lastIndexOf('.', dotIndex - 1);
        }

        // Find associated node
        LogNode node = info.rootNode.findNode(loggerName);
        node.logger = logger;

        // Set parent logger
        Logger parentLogger = node.findParentLogger();
        if (parentLogger != null) {
            doSetParentLogger(logger, parentLogger);
        }

        // Tell children we are their new parent
        node.setParentLogger(logger);

        // Add associated handlers, if any are defined using the .handlers property.
        // In this case, handlers of the parent logger(s) will not be used
        String handlers = getProperty(loggerName + ".handlers");
        if (handlers != null) {
            logger.setUseParentHandlers(false);
            StringTokenizer tok = new StringTokenizer(handlers, ",");
            while (tok.hasMoreTokens()) {
                String handlerName = (tok.nextToken().trim());
                Handler handler = null;
                ClassLoader current = classLoader;
                while (current != null) {
                    info = (ClassLoaderLogInfo) classLoaderLoggers.get(current);
                    if (info != null) {
                        handler = (Handler) info.handlers.get(handlerName);
                        if (handler != null) {
                            break;
                        }
                    }
                    current = current.getParent();
                }
                if (handler != null) {
                    logger.addHandler(handler);
                }
            }
        }

        // Parse useParentHandlers to set if the logger should delegate to its parent.
        // Unlike java.util.logging, the default is to not delegate if a list of handlers
        // has been specified for the logger.
        String useParentHandlersString = getProperty(loggerName + ".useParentHandlers");
        if (Boolean.valueOf(useParentHandlersString).booleanValue()) {
            logger.setUseParentHandlers(true);
        }
        
        return true;
    }

    
    /**
     * Get the logger associated with the specified name inside 
     * the classloader local configuration. If this returns null,
     * and the call originated for Logger.getLogger, a new
     * logger with the specified name will be instantiated and
     * added using addLogger.
     * 
     * @param name The name of the logger to retrieve
     */
    public synchronized Logger getLogger(final String name) {
        ClassLoader classLoader = Thread.currentThread()
                .getContextClassLoader();
        return (Logger) getClassLoaderInfo(classLoader).loggers.get(name);
    }
    
    
    /**
     * Get an enumeration of the logger names currently defined in the 
     * classloader local configuration.
     */
    public synchronized Enumeration<String> getLoggerNames() {
        ClassLoader classLoader = Thread.currentThread()
                .getContextClassLoader();
        return Collections.enumeration(getClassLoaderInfo(classLoader).loggers.keySet());
    }

    
    /**
     * Get the value of the specified property in the classloader local
     * configuration.
     * 
     * @param name The property name
     */    
    public String getProperty(String name) {
        ClassLoader classLoader = Thread.currentThread()
            .getContextClassLoader();
        String prefix = (String) this.prefix.get();
        if (prefix != null) {
            name = prefix + name;
        }
        ClassLoaderLogInfo info = getClassLoaderInfo(classLoader);
        String result = info.props.getProperty(name);
        // If the property was not found, and the current classloader had no 
        // configuration (property list is empty), look for the parent classloader
        // properties.
        if ((result == null) && (info.props.isEmpty())) {
            ClassLoader current = classLoader.getParent();
            while (current != null) {
                info = (ClassLoaderLogInfo) classLoaderLoggers.get(current);
                if (info != null) {
                    result = info.props.getProperty(name);
                    if ((result != null) || (!info.props.isEmpty())) {
                        break;
                    }
                }
                current = current.getParent();
            }
            if (result == null) {
                result = super.getProperty(name);
            }
        }
        // Simple property replacement (mostly for folder names)
        if (result != null) {
            result = replace(result);
        }
        return result;
    }
    
    
    public void readConfiguration()
        throws IOException, SecurityException {
        
        checkAccess();
        
        readConfiguration(Thread.currentThread().getContextClassLoader());
        
    }
        
    public void readConfiguration(InputStream is)
        throws IOException, SecurityException {
        
        checkAccess();
        reset();

        readConfiguration(is, Thread.currentThread().getContextClassLoader());
    
    }
        
    // ------------------------------------------------------ Protected Methods


    /**
     * Retrieve the configuration associated with the specified classloader. If
     * it does not exist, it will be created.
     * 
     * @param classLoader The classloader for which we will retrieve or build the 
     *                    configuration
     */
    protected ClassLoaderLogInfo getClassLoaderInfo(ClassLoader classLoader) {
        
        if (classLoader == null) {
            classLoader = ClassLoader.getSystemClassLoader();
        }
        ClassLoaderLogInfo info = (ClassLoaderLogInfo) classLoaderLoggers
                .get(classLoader);
        if (info == null) {
            final ClassLoader classLoaderParam = classLoader;
            AccessController.doPrivileged(new PrivilegedAction() {
                public Object run() {
                    try {
                        readConfiguration(classLoaderParam);
                    } catch (IOException e) {
                        // Ignore
                    }
                    return null;
                }
            });
            info = (ClassLoaderLogInfo) classLoaderLoggers.get(classLoader);
        }
        return info;
    }

    
    /**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -