001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.classic.control;
015
016import java.util.HashMap;
017import java.util.Map;
018
019import ch.qos.logback.classic.Level;
020import ch.qos.logback.core.CoreConstants;
021
022/**
023 * This logger context quite optimized for logger retrieval.
024 * 
025 * <p>It uses a single loggerMap where the key is the logger name and the value
026 * is the logger.
027 * 
028 * <p>This approach acts a lower limit for what is achievable for low memory
029 * usage as well as low creation/retrieval times. However, this simplicity also
030 * results in slow effective level evaluation, the most frequently exercised
031 * part of the API.
032 * 
033 * <p>This class is expected to contain correct results, and serve to verify
034 * the correctness of a more sophisticated implementation.
035 * 
036 * @author ceki
037 */
038public class ControlLoggerContext {
039
040    private ControlLogger root;
041    //
042    // Hashtable loggerMap = new Hashtable();
043    Map<String, ControlLogger> loggerMap = new HashMap<String, ControlLogger>();
044
045    public ControlLoggerContext() {
046        this.root = new ControlLogger("root", null);
047        this.root.setLevel(Level.DEBUG);
048    }
049
050    /**
051     * Return this contexts root logger
052     * 
053     * @return
054     */
055    public ControlLogger getRootLogger() {
056        return root;
057    }
058
059    public ControlLogger exists(String name) {
060        if (name == null) {
061            throw new IllegalArgumentException("name parameter cannot be null");
062        }
063
064        synchronized (loggerMap) {
065            return (ControlLogger) loggerMap.get(name);
066        }
067    }
068
069    public final ControlLogger getLogger(String name) {
070        if (name == null) {
071            throw new IllegalArgumentException("name parameter cannot be null");
072        }
073
074        synchronized (loggerMap) {
075            ControlLogger cl = (ControlLogger) loggerMap.get(name);
076            if (cl != null) {
077                return cl;
078            }
079            ControlLogger parent = this.root;
080
081            int i = 0;
082            while (true) {
083                i = name.indexOf(CoreConstants.DOT, i);
084                if (i == -1) {
085                    // System.out.println("FINAL-Creating logger named [" + name + "] with
086                    // parent " + parent.getName());
087                    cl = new ControlLogger(name, parent);
088                    loggerMap.put(name, cl);
089                    return cl;
090                } else {
091                    String parentName = name.substring(0, i);
092                    ControlLogger p = (ControlLogger) loggerMap.get(parentName);
093                    if (p == null) {
094                        // System.out.println("INTERMEDIARY-Creating logger [" + parentName
095                        // + "] with parent " + parent.getName());
096                        p = new ControlLogger(parentName, parent);
097                        loggerMap.put(parentName, p);
098                    }
099                    parent = p;
100                }
101                // make i move past the last found dot.
102                i++;
103            }
104        }
105    }
106
107    public Map<String, ControlLogger> getLoggerMap() {
108        return loggerMap;
109    }
110}