1f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.logging; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.beans.PropertyChangeListener; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.beans.PropertyChangeSupport; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.BufferedInputStream; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.File; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.FileInputStream; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Collection; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Enumeration; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Hashtable; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Properties; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.StringTokenizer; 328ced42eaddbe441db51cf5538f15ec746c180936Jesse Wilsonimport libcore.io.IoUtils; 339a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code LogManager} is used to maintain configuration properties of the 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * logging framework, and to manage a hierarchical namespace of all named 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Logger} objects. 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * There is only one global {@code LogManager} instance in the 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * application, which can be get by calling static method 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #getLogManager()}. This instance is created and 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * initialized during class initialization and cannot be changed. 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The {@code LogManager} class can be specified by 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * java.util.logging.manager system property, if the property is unavailable or 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invalid, the default class {@link java.util.logging.LogManager} will 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be used. 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 499a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson * On initialization, {@code LogManager} reads its configuration from a 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * properties file, which by default is the "lib/logging.properties" in the JRE 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * directory. 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * However, two optional system properties can be used to customize the initial 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * configuration process of {@code LogManager}. 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ul> 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>"java.util.logging.config.class"</li> 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>"java.util.logging.config.file"</li> 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ul> 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * These two properties can be set in three ways, by the Preferences API, by the 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * "java" command line property definitions, or by system property definitions 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * passed to JNI_CreateJavaVM. 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The "java.util.logging.config.class" should specifies a class name. If it is 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * set, this given class will be loaded and instantiated during 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code LogManager} initialization, so that this object's default 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * constructor can read the initial configuration and define properties for 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code LogManager}. 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If "java.util.logging.config.class" property is not set, or it is invalid, or 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * some exception is thrown during the instantiation, then the 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * "java.util.logging.config.file" system property can be used to specify a 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * properties file. The {@code LogManager} will read initial 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * configuration from this file. 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If neither of these properties is defined, or some exception is thrown 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * during these two properties using, the {@code LogManager} will read 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * its initial configuration from default properties file, as described above. 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The global logging properties may include: 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ul> 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>"handlers". This property's values should be a list of class names for 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * handler classes separated by whitespace, these classes must be subclasses of 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Handler} and each must have a default constructor, these 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * classes will be loaded, instantiated and registered as handlers on the root 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Logger} (the {@code Logger} named ""). These 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Handler}s maybe initialized lazily.</li> 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>"config". The property defines a list of class names separated by 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * whitespace. Each class must have a default constructor, in which it can 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * update the logging configuration, such as levels, handlers, or filters for 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * some logger, etc. These classes will be loaded and instantiated during 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code LogManager} configuration</li> 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ul> 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class, together with any handler and configuration classes associated 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with it, <b>must</b> be loaded from the system classpath when 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code LogManager} configuration occurs. 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Besides global properties, the properties for loggers and Handlers can be 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified in the property files. The names of these properties will start 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with the complete dot separated names for the handlers or loggers. 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * In the {@code LogManager}'s hierarchical namespace, 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Loggers} are organized based on their dot separated names. For 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * example, "x.y.z" is child of "x.y". 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Levels for {@code Loggers} can be defined by properties whose name end 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with ".level". Thus "alogger.level" defines a level for the logger named as 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * "alogger" and for all its children in the naming hierarchy. Log levels 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * properties are read and applied in the same order as they are specified in 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the property file. The root logger's level can be defined by the property 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * named as ".level". 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 114d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * This class is thread safe. It is an error to synchronize on a 115d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * {@code LogManager} while synchronized on a {@code Logger}. 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class LogManager { 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 119d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson /** The shared logging permission. */ 1208454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes private static final LoggingPermission perm = new LoggingPermission("control", null); 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 122d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson /** The singleton instance. */ 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static LogManager manager; 1249a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The {@code String} value of the {@link LoggingMXBean}'s ObjectName. 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1288454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes public static final String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging"; 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Get the {@code LoggingMXBean} instance. this implementation always throws 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * an UnsupportedOperationException. 1339a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson * 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the {@code LoggingMXBean} instance 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static LoggingMXBean getLoggingMXBean() { 1378454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes throw new UnsupportedOperationException(); 1389a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson } 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1409a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson // FIXME: use weak reference to avoid heap memory leak 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Hashtable<String, Logger> loggers; 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 143d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson /** The configuration properties */ 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Properties props; 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 146d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson /** the property change listener */ 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private PropertyChangeSupport listeners; 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static { 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // init LogManager singleton instance 151ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes String className = System.getProperty("java.util.logging.manager"); 152ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes if (className != null) { 153ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes manager = (LogManager) getInstanceByClass(className); 154ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes } 155ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes if (manager == null) { 156ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes manager = new LogManager(); 157ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes } 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 159ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes // read configuration 160ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes try { 161ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes manager.readConfiguration(); 162ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes } catch (Exception e) { 163ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes e.printStackTrace(); 164ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes } 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 166ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes // if global logger has been initialized, set root as its parent 167ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes Logger root = new Logger("", null); 168ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes root.setLevel(Level.INFO); 169ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes Logger.global.setParent(root); 1709a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson 171ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes manager.addLogger(root); 172ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes manager.addLogger(Logger.global); 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Default constructor. This is not public because there should be only one 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code LogManager} instance, which can be get by 178b501914f9448cc0c5852922d217ae11a29c63467Jesse Wilson * {@code LogManager.getLogManager()}. This is protected so that 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * application can subclass the object. 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected LogManager() { 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project loggers = new Hashtable<String, Logger>(); 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project props = new Properties(); 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project listeners = new PropertyChangeSupport(this); 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // add shutdown hook to ensure that the associated resource will be 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // freed when JVM exits 187ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes Runtime.getRuntime().addShutdownHook(new Thread() { 188ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes @Override public void run() { 189ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes reset(); 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }); 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 195ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes * Does nothing. 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void checkAccess() { 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Add a given logger into the hierarchical namespace. The 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Logger.addLogger()} factory methods call this method to add newly 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * created Logger. This returns false if a logger with the given name has 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * existed in the namespace 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Note that the {@code LogManager} may only retain weak references to 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * registered loggers. In order to prevent {@code Logger} objects from being 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * unexpectedly garbage collected it is necessary for <i>applications</i> 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to maintain references to them. 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </p> 2119a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson * 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param logger 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the logger to be added. 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if the given logger is added into the namespace 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * successfully, false if the given logger exists in the namespace. 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized boolean addLogger(Logger logger) { 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String name = logger.getName(); 219b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (loggers.get(name) != null) { 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project addToFamilyTree(logger, name); 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project loggers.put(name, logger); 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project logger.setManager(this); 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void addToFamilyTree(Logger logger, String name) { 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Logger parent = null; 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // find parent 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int lastSeparator; 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String parentName = name; 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while ((lastSeparator = parentName.lastIndexOf('.')) != -1) { 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parentName = parentName.substring(0, lastSeparator); 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parent = loggers.get(parentName); 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (parent != null) { 237d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson setParent(logger, parent); 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 2398454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes } else if (getProperty(parentName + ".level") != null || 2408454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes getProperty(parentName + ".handlers") != null) { 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parent = Logger.getLogger(parentName); 242d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson setParent(logger, parent); 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 246b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (parent == null && (parent = loggers.get("")) != null) { 247d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson setParent(logger, parent); 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // find children 2519a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson // TODO: performance can be improved here? 252c505c37bdf75d820d389a172bd634d383a4786d1Bjorn Bringert String nameDot = name + '.'; 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Collection<Logger> allLoggers = loggers.values(); 2549a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson for (final Logger child : allLoggers) { 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Logger oldParent = child.getParent(); 256ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes if (parent == oldParent && (name.length() == 0 || child.getName().startsWith(nameDot))) { 2579a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson final Logger thisLogger = logger; 258ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes child.setParent(thisLogger); 259b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (oldParent != null) { 2609a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson // -- remove from old parent as the parent has been changed 261d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson oldParent.children.remove(child); 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Get the logger with the given name. 2699a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson * 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * name of logger 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return logger with given name, or {@code null} if nothing is found. 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized Logger getLogger(String name) { 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return loggers.get(name); 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Get a {@code Enumeration} of all registered logger names. 2809a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson * 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return enumeration of registered logger names 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized Enumeration<String> getLoggerNames() { 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return loggers.keys(); 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Get the global {@code LogManager} instance. 2899a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson * 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the global {@code LogManager} instance 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static LogManager getLogManager() { 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return manager; 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Get the value of property with given name. 2989a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson * 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of property 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value of property 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getProperty(String name) { 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return props.getProperty(name); 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Re-initialize the properties and configuration. The initialization 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * process is same as the {@code LogManager} instantiation. 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Notice : No {@code PropertyChangeEvent} are fired. 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </p> 3139a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson * 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if any IO related problems happened. 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void readConfiguration() throws IOException { 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // check config class 3198454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes String configClassName = System.getProperty("java.util.logging.config.class"); 3208ced42eaddbe441db51cf5538f15ec746c180936Jesse Wilson if (configClassName == null || getInstanceByClass(configClassName) == null) { 3219a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson // if config class failed, check config file 3228454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes String configFile = System.getProperty("java.util.logging.config.file"); 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 3248ced42eaddbe441db51cf5538f15ec746c180936Jesse Wilson if (configFile == null) { 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if cannot find configFile, use default logging.properties 3268454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes configFile = System.getProperty("java.home") + File.separator + "lib" + 3278454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes File.separator + "logging.properties"; 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InputStream input = null; 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 3338ced42eaddbe441db51cf5538f15ec746c180936Jesse Wilson input = new FileInputStream(configFile); 3348ced42eaddbe441db51cf5538f15ec746c180936Jesse Wilson } catch (IOException exception) { 3358ced42eaddbe441db51cf5538f15ec746c180936Jesse Wilson // fall back to using the built-in logging.properties file 3368ced42eaddbe441db51cf5538f15ec746c180936Jesse Wilson input = LogManager.class.getResourceAsStream("logging.properties"); 3378ced42eaddbe441db51cf5538f15ec746c180936Jesse Wilson if (input == null) { 3388ced42eaddbe441db51cf5538f15ec746c180936Jesse Wilson throw exception; 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3418ced42eaddbe441db51cf5538f15ec746c180936Jesse Wilson readConfiguration(new BufferedInputStream(input)); 3428ced42eaddbe441db51cf5538f15ec746c180936Jesse Wilson } finally { 3438ced42eaddbe441db51cf5538f15ec746c180936Jesse Wilson IoUtils.closeQuietly(input); 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // use SystemClassLoader to load class from system classpath 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static Object getInstanceByClass(final String className) { 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 3518454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass(className); 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return clazz.newInstance(); 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception e) { 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 3558454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(className); 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return clazz.newInstance(); 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception innerE) { 3588454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes System.err.println("Loading class '" + className + "' failed"); 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.err.println(innerE); 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // actual initialization process from a given input stream 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private synchronized void readConfigurationImpl(InputStream ins) 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project reset(); 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project props.load(ins); 3709a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson 371c99250a4d619670f2a9410df121eff04fdc9e87cJesse Wilson // The RI treats the root logger as special. For compatibility, always 372c99250a4d619670f2a9410df121eff04fdc9e87cJesse Wilson // update the root logger's handlers. 373b501914f9448cc0c5852922d217ae11a29c63467Jesse Wilson Logger root = loggers.get(""); 374b501914f9448cc0c5852922d217ae11a29c63467Jesse Wilson if (root != null) { 375b501914f9448cc0c5852922d217ae11a29c63467Jesse Wilson root.setManager(this); 376b501914f9448cc0c5852922d217ae11a29c63467Jesse Wilson } 377b501914f9448cc0c5852922d217ae11a29c63467Jesse Wilson 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // parse property "config" and apply setting 3798454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes String configs = props.getProperty("config"); 380b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (configs != null) { 3818454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes StringTokenizer st = new StringTokenizer(configs, " "); 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (st.hasMoreTokens()) { 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String configerName = st.nextToken(); 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project getInstanceByClass(configerName); 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3879a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // set levels for logger 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Collection<Logger> allLoggers = loggers.values(); 3909a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson for (Logger logger : allLoggers) { 3918454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes String property = props.getProperty(logger.getName() + ".level"); 392b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (property != null) { 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project logger.setLevel(Level.parse(property)); 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project listeners.firePropertyChange(null, null, null); 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Re-initialize the properties and configuration from the given 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code InputStream} 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Notice : No {@code PropertyChangeEvent} are fired. 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </p> 4059a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson * 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param ins 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input stream 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if any IO related problems happened. 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void readConfiguration(InputStream ins) throws IOException { 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkAccess(); 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readConfigurationImpl(ins); 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reset configuration. 418ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes * 419ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes * <p>All handlers are closed and removed from any named loggers. All loggers' 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * level is set to null, except the root logger's level is set to 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Level.INFO}. 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 423b501914f9448cc0c5852922d217ae11a29c63467Jesse Wilson public synchronized void reset() { 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkAccess(); 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project props = new Properties(); 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Enumeration<String> names = getLoggerNames(); 4279a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson while (names.hasMoreElements()) { 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String name = names.nextElement(); 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Logger logger = getLogger(name); 4309a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson if (logger != null) { 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project logger.reset(); 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 4348454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes Logger root = loggers.get(""); 435b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (root != null) { 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project root.setLevel(Level.INFO); 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Add a {@code PropertyChangeListener}, which will be invoked when 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the properties are reread. 4439a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson * 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param l 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code PropertyChangeListener} to be added. 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void addPropertyChangeListener(PropertyChangeListener l) { 4489a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson if (l == null) { 44986acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("l == null"); 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkAccess(); 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project listeners.addPropertyChangeListener(l); 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Remove a {@code PropertyChangeListener}, do nothing if the given 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * listener is not found. 4589a0fbe99031759393563ee69ac4640f66f182686Jesse Wilson * 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param l 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code PropertyChangeListener} to be removed. 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removePropertyChangeListener(PropertyChangeListener l) { 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkAccess(); 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project listeners.removePropertyChangeListener(l); 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 466d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson 467d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson /** 468d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * Returns a named logger associated with the supplied resource bundle. 469d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * 470d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * @param resourceBundleName the resource bundle to associate, or null for 471d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * no associated resource bundle. 472d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson */ 473d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson synchronized Logger getOrCreate(String name, String resourceBundleName) { 474d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson Logger result = getLogger(name); 475d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson if (result == null) { 476d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson result = new Logger(name, resourceBundleName); 477d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson addLogger(result); 478d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson } 479d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson return result; 480d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson } 481d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson 482d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson 483d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson /** 484d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * Sets the parent of this logger in the namespace. Callers must first 485d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * {@link #checkAccess() check security}. 486d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * 487d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * @param newParent 488d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * the parent logger to set. 489d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson */ 490d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson synchronized void setParent(Logger logger, Logger newParent) { 491d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson logger.parent = newParent; 492d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson 493d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson if (logger.levelObjVal == null) { 494d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson setLevelRecursively(logger, null); 495d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson } 496d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson newParent.children.add(logger); 497fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes logger.updateDalvikLogHandler(); 498d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson } 499d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson 500d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson /** 501d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * Sets the level on {@code logger} to {@code newLevel}. Any child loggers 502d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * currently inheriting their level from {@code logger} will be updated 503d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * recursively. 504d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * 505d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * @param newLevel the new minimum logging threshold. If null, the logger's 506d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * parent level will be used; or {@code Level.INFO} for loggers with no 507d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson * parent. 508d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson */ 509d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson synchronized void setLevelRecursively(Logger logger, Level newLevel) { 510d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson int previous = logger.levelIntVal; 511d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson logger.levelObjVal = newLevel; 512d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson 513d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson if (newLevel == null) { 514d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson logger.levelIntVal = logger.parent != null 515d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson ? logger.parent.levelIntVal 516d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson : Level.INFO.intValue(); 517d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson } else { 518d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson logger.levelIntVal = newLevel.intValue(); 519d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson } 520d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson 521d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson if (previous != logger.levelIntVal) { 522d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson for (Logger child : logger.children) { 523d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson if (child.levelObjVal == null) { 524d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson setLevelRecursively(child, null); 525d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson } 526d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson } 527d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson } 528d9b5d1b899226673e746ad4d9f517244d968e5baJesse Wilson } 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 530