1069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/* 2069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Copyright 2001-2004 The Apache Software Foundation. 3069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 4069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * you may not use this file except in compliance with the License. 6069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * You may obtain a copy of the License at 7069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 8069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 10069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * See the License for the specific language governing permissions and 14069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * limitations under the License. 15069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 16069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 17069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpackage org.apache.commons.logging.impl; 18069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 19069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 20069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.lang.reflect.Constructor; 21069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.lang.reflect.InvocationTargetException; 22069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.lang.reflect.Method; 23069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.net.URL; 24069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.Enumeration; 25069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.Hashtable; 26069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.Vector; 27069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 28069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.logging.Log; 29069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.logging.LogConfigurationException; 30069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.logging.LogFactory; 31069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 32069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 33069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/** 34069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p>Concrete subclass of {@link LogFactory} that implements the 35069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * following algorithm to dynamically select a logging implementation 36069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * class to instantiate a wrapper for.</p> 37069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <ul> 38069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>Use a factory configuration attribute named 39069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>org.apache.commons.logging.Log</code> to identify the 40069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * requested implementation class.</li> 41069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>Use the <code>org.apache.commons.logging.Log</code> system property 42069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to identify the requested implementation class.</li> 43069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>If <em>Log4J</em> is available, return an instance of 44069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>org.apache.commons.logging.impl.Log4JLogger</code>.</li> 45069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>If <em>JDK 1.4 or later</em> is available, return an instance of 46069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>org.apache.commons.logging.impl.Jdk14Logger</code>.</li> 47069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>Otherwise, return an instance of 48069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>org.apache.commons.logging.impl.SimpleLog</code>.</li> 49069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </ul> 50069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 51069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p>If the selected {@link Log} implementation class has a 52069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>setLogFactory()</code> method that accepts a {@link LogFactory} 53069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * parameter, this method will be called on each newly created instance 54069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to identify the associated factory. This makes factory configuration 55069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * attributes available to the Log instance, if it so desires.</p> 56069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 57069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p>This factory will remember previously created <code>Log</code> instances 58069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * for the same name, and will return them on repeated requests to the 59069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>getInstance()</code> method.</p> 60069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 61069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author Rod Waldhoff 62069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author Craig R. McClanahan 63069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author Richard A. Sitze 64069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author Brian Stansberry 65069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @version $Revision: 399224 $ $Date: 2006-05-03 10:25:54 +0100 (Wed, 03 May 2006) $ 66d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * 67d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * @deprecated Please use {@link java.net.URL#openConnection} instead. 68d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> 69d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * for further details. 70069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 71069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 72d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath@Deprecated 73069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpublic class LogFactoryImpl extends LogFactory { 74069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 75069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 76069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** Log4JLogger class name */ 77069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static final String LOGGING_IMPL_LOG4J_LOGGER = "org.apache.commons.logging.impl.Log4JLogger"; 78069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** Jdk14Logger class name */ 79069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static final String LOGGING_IMPL_JDK14_LOGGER = "org.apache.commons.logging.impl.Jdk14Logger"; 80069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** Jdk13LumberjackLogger class name */ 81069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static final String LOGGING_IMPL_LUMBERJACK_LOGGER = "org.apache.commons.logging.impl.Jdk13LumberjackLogger"; 82069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** SimpleLog class name */ 83069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static final String LOGGING_IMPL_SIMPLE_LOGGER = "org.apache.commons.logging.impl.SimpleLog"; 84069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 85069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static final String PKG_IMPL="org.apache.commons.logging.impl."; 86069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static final int PKG_LEN = PKG_IMPL.length(); 87069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 88069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ----------------------------------------------------------- Constructors 89069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 90069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 91069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 92069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 93069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Public no-arguments constructor required by the lookup mechanism. 94069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 95069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public LogFactoryImpl() { 96069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project super(); 97069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project initDiagnostics(); // method on this object 98069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 99069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Instance created."); 100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ----------------------------------------------------- Manifest Constants 105069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 106069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 107069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 108069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The name (<code>org.apache.commons.logging.Log</code>) of the system 109069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * property identifying our {@link Log} implementation class. 110069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 111069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static final String LOG_PROPERTY = 112069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "org.apache.commons.logging.Log"; 113069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 114069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 115069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 116069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The deprecated system property used for backwards compatibility with 117069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * old versions of JCL. 118069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 119069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static final String LOG_PROPERTY_OLD = 120069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "org.apache.commons.logging.log"; 121069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 122069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 123069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The name (<code>org.apache.commons.logging.Log.allowFlawedContext</code>) 124069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * of the system property which can be set true/false to 125069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * determine system behaviour when a bad context-classloader is encountered. 126069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * When set to false, a LogConfigurationException is thrown if 127069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * LogFactoryImpl is loaded via a child classloader of the TCCL (this 128069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * should never happen in sane systems). 129069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 130069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Default behaviour: true (tolerates bad context classloaders) 131069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 132069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * See also method setAttribute. 133069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 134069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static final String ALLOW_FLAWED_CONTEXT_PROPERTY = 135069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "org.apache.commons.logging.Log.allowFlawedContext"; 136069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 137069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 138069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The name (<code>org.apache.commons.logging.Log.allowFlawedDiscovery</code>) 139069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * of the system property which can be set true/false to 140069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * determine system behaviour when a bad logging adapter class is 141069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * encountered during logging discovery. When set to false, an 142069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * exception will be thrown and the app will fail to start. When set 143069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to true, discovery will continue (though the user might end up 144069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * with a different logging implementation than they expected). 145069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 146069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Default behaviour: true (tolerates bad logging adapters) 147069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 148069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * See also method setAttribute. 149069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 150069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static final String ALLOW_FLAWED_DISCOVERY_PROPERTY = 151069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "org.apache.commons.logging.Log.allowFlawedDiscovery"; 152069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 153069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 154069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The name (<code>org.apache.commons.logging.Log.allowFlawedHierarchy</code>) 155069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * of the system property which can be set true/false to 156069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * determine system behaviour when a logging adapter class is 157069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * encountered which has bound to the wrong Log class implementation. 158069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * When set to false, an exception will be thrown and the app will fail 159069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to start. When set to true, discovery will continue (though the user 160069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * might end up with a different logging implementation than they expected). 161069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 162069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Default behaviour: true (tolerates bad Log class hierarchy) 163069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 164069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * See also method setAttribute. 165069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 166069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static final String ALLOW_FLAWED_HIERARCHY_PROPERTY = 167069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "org.apache.commons.logging.Log.allowFlawedHierarchy"; 168069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 169069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 170069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 171069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The names of classes that will be tried (in order) as logging 172069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * adapters. Each class is expected to implement the Log interface, 173069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * and to throw NoClassDefFound or ExceptionInInitializerError when 174069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * loaded if the underlying logging library is not available. Any 175069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * other error indicates that the underlying logging library is available 176069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * but broken/unusable for some reason. 177069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 178069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static final String[] classesToDiscover = { 179069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project LOGGING_IMPL_LOG4J_LOGGER, 180069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "org.apache.commons.logging.impl.Jdk14Logger", 181069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "org.apache.commons.logging.impl.Jdk13LumberjackLogger", 182069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "org.apache.commons.logging.impl.SimpleLog" 183069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project }; 184069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 185069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 186069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ----------------------------------------------------- Instance Variables 187069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 188069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 189069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Determines whether logging classes should be loaded using the thread-context 190069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * classloader, or via the classloader that loaded this LogFactoryImpl class. 191069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 192069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private boolean useTCCL = true; 193069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 194069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 195069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The string prefixed to every message output by the logDiagnostic method. 196069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 197069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private String diagnosticPrefix; 198069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 199069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 200069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 201069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Configuration attributes. 202069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 203069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected Hashtable attributes = new Hashtable(); 204069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 205069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 206069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 207069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The {@link org.apache.commons.logging.Log} instances that have 208069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * already been created, keyed by logger name. 209069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 210069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected Hashtable instances = new Hashtable(); 211069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 212069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 213069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 214069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Name of the class implementing the Log interface. 215069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 216069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private String logClassName; 217069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 218069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 219069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 220069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The one-argument constructor of the 221069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * {@link org.apache.commons.logging.Log} 222069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * implementation class that will be used to create new instances. 223069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This value is initialized by <code>getLogConstructor()</code>, 224069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * and then returned repeatedly. 225069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 226069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected Constructor logConstructor = null; 227069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 228069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 229069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 230069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The signature of the Constructor to be used. 231069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 232069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected Class logConstructorSignature[] = 233069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project { java.lang.String.class }; 234069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 235069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 236069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 237069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The one-argument <code>setLogFactory</code> method of the selected 238069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * {@link org.apache.commons.logging.Log} method, if it exists. 239069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 240069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected Method logMethod = null; 241069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 242069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 243069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 244069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The signature of the <code>setLogFactory</code> method to be used. 245069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 246069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected Class logMethodSignature[] = 247069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project { LogFactory.class }; 248069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 249069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 250069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * See getBaseClassLoader and initConfiguration. 251069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 252069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private boolean allowFlawedContext; 253069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 254069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 255069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * See handleFlawedDiscovery and initConfiguration. 256069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 257069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private boolean allowFlawedDiscovery; 258069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 259069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 260069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * See handleFlawedHierarchy and initConfiguration. 261069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 262069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private boolean allowFlawedHierarchy; 263069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 264069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // --------------------------------------------------------- Public Methods 265069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 266069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 267069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 268069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Return the configuration attribute with the specified name (if any), 269069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * or <code>null</code> if there is no such attribute. 270069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 271069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param name Name of the attribute to return 272069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 273069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public Object getAttribute(String name) { 274069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 275069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return (attributes.get(name)); 276069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 277069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 278069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 279069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 280069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 281069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Return an array containing the names of all currently defined 282069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * configuration attributes. If there are no such attributes, a zero 283069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * length array is returned. 284069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 285069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public String[] getAttributeNames() { 286069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 287069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Vector names = new Vector(); 288069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Enumeration keys = attributes.keys(); 289069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project while (keys.hasMoreElements()) { 290069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project names.addElement((String) keys.nextElement()); 291069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 292069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String results[] = new String[names.size()]; 293069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project for (int i = 0; i < results.length; i++) { 294069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project results[i] = (String) names.elementAt(i); 295069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 296069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return (results); 297069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 298069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 299069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 300069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 301069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 302069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Convenience method to derive a name from the specified class and 303069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * call <code>getInstance(String)</code> with it. 304069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 305069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param clazz Class for which a suitable Log name will be derived 306069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 307069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @exception LogConfigurationException if a suitable <code>Log</code> 308069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * instance cannot be returned 309069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 310069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public Log getInstance(Class clazz) throws LogConfigurationException { 311069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 312069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return (getInstance(clazz.getName())); 313069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 314069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 315069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 316069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 317069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 318069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p>Construct (if necessary) and return a <code>Log</code> instance, 319069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * using the factory's current set of configuration attributes.</p> 320069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 321069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p><strong>NOTE</strong> - Depending upon the implementation of 322069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the <code>LogFactory</code> you are using, the <code>Log</code> 323069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * instance you are returned may or may not be local to the current 324069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * application, and may or may not be returned again on a subsequent 325069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * call with the same name argument.</p> 326069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 327069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param name Logical name of the <code>Log</code> instance to be 328069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * returned (the meaning of this name is only known to the underlying 329069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * logging implementation that is being wrapped) 330069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 331069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @exception LogConfigurationException if a suitable <code>Log</code> 332069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * instance cannot be returned 333069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 334069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public Log getInstance(String name) throws LogConfigurationException { 335069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 336069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Log instance = (Log) instances.get(name); 337069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (instance == null) { 338069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project instance = newInstance(name); 339069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project instances.put(name, instance); 340069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 341069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return (instance); 342069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 343069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 344069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 345069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 346069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 347069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Release any internal references to previously created 348069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * {@link org.apache.commons.logging.Log} 349069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * instances returned by this factory. This is useful in environments 350069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * like servlet containers, which implement application reloading by 351069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * throwing away a ClassLoader. Dangling references to objects in that 352069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * class loader would prevent garbage collection. 353069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 354069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public void release() { 355069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 356069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Releasing all known loggers"); 357069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project instances.clear(); 358069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 359069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 360069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 361069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 362069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Remove any configuration attribute associated with the specified name. 363069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * If there is no such attribute, no action is taken. 364069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 365069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param name Name of the attribute to remove 366069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 367069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public void removeAttribute(String name) { 368069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 369069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project attributes.remove(name); 370069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 371069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 372069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 373069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 374069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 375069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Set the configuration attribute with the specified name. Calling 376069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * this with a <code>null</code> value is equivalent to calling 377069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>removeAttribute(name)</code>. 378069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 379069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This method can be used to set logging configuration programmatically 380069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * rather than via system properties. It can also be used in code running 381069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * within a container (such as a webapp) to configure behaviour on a 382069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * per-component level instead of globally as system properties would do. 383069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * To use this method instead of a system property, call 384069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <pre> 385069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * LogFactory.getFactory().setAttribute(...) 386069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </pre> 387069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This must be done before the first Log object is created; configuration 388069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * changes after that point will be ignored. 389069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 390069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This method is also called automatically if LogFactory detects a 391069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * commons-logging.properties file; every entry in that file is set 392069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * automatically as an attribute here. 393069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 394069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param name Name of the attribute to set 395069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param value Value of the attribute to set, or <code>null</code> 396069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to remove any setting for this attribute 397069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 398069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public void setAttribute(String name, Object value) { 399069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 400069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (logConstructor != null) { 401069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("setAttribute: call too late; configuration already performed."); 402069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 403069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 404069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (value == null) { 405069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project attributes.remove(name); 406069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 407069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project attributes.put(name, value); 408069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 409069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 410069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (name.equals(TCCL_KEY)) { 411069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project useTCCL = Boolean.valueOf(value.toString()).booleanValue(); 412069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 413069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 414069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 415069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 416069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 417069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ------------------------------------------------------ 418069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Static Methods 419069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 420069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // These methods only defined as workarounds for a java 1.2 bug; 421069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // theoretically none of these are needed. 422069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ------------------------------------------------------ 423069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 424069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 425069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Gets the context classloader. 426069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This method is a workaround for a java 1.2 compiler bug. 427069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @since 1.1 428069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 429069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static ClassLoader getContextClassLoader() throws LogConfigurationException { 430069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return LogFactory.getContextClassLoader(); 431069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 432069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 433069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 434069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 435069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Workaround for bug in Java1.2; in theory this method is not needed. 436069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * See LogFactory.isDiagnosticsEnabled. 437069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 438069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static boolean isDiagnosticsEnabled() { 439069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return LogFactory.isDiagnosticsEnabled(); 440069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 441069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 442069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 443069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 444069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Workaround for bug in Java1.2; in theory this method is not needed. 445069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * See LogFactory.getClassLoader. 446069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @since 1.1 447069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 448069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static ClassLoader getClassLoader(Class clazz) { 449069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return LogFactory.getClassLoader(clazz); 450069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 451069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 452069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 453069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ------------------------------------------------------ Protected Methods 454069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 455069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 456069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Calculate and cache a string that uniquely identifies this instance, 457069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * including which classloader the object was loaded from. 458069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 459069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This string will later be prefixed to each "internal logging" message 460069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * emitted, so that users can clearly see any unexpected behaviour. 461069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 462069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Note that this method does not detect whether internal logging is 463069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * enabled or not, nor where to output stuff if it is; that is all 464069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * handled by the parent LogFactory class. This method just computes 465069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * its own unique prefix for log messages. 466069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 467069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private void initDiagnostics() { 468069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // It would be nice to include an identifier of the context classloader 469069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // that this LogFactoryImpl object is responsible for. However that 470069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // isn't possible as that information isn't available. It is possible 471069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // to figure this out by looking at the logging from LogFactory to 472069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // see the context & impl ids from when this object was instantiated, 473069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // in order to link the impl id output as this object's prefix back to 474069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // the context it is intended to manage. 475069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Note that this prefix should be kept consistent with that 476069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // in LogFactory. 477069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Class clazz = this.getClass(); 478069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader classLoader = getClassLoader(clazz); 479069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String classLoaderName; 480069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 481069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (classLoader == null) { 482069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project classLoaderName = "BOOTLOADER"; 483069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 484069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project classLoaderName = objectId(classLoader); 485069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 486069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(SecurityException e) { 487069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project classLoaderName = "UNKNOWN"; 488069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 489069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project diagnosticPrefix = "[LogFactoryImpl@" + System.identityHashCode(this) + " from " + classLoaderName + "] "; 490069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 491069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 492069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 493069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 494069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Output a diagnostic message to a user-specified destination (if the 495069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * user has enabled diagnostic logging). 496069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 497069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param msg diagnostic message 498069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @since 1.1 499069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 500069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected void logDiagnostic(String msg) { 501069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 502069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logRawDiagnostic(diagnosticPrefix + msg); 503069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 504069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 505069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 506069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 507069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Return the fully qualified Java classname of the {@link Log} 508069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * implementation we will be using. 509069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 510069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @deprecated Never invoked by this class; subclasses should not assume 511069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * it will be. 512069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 513069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected String getLogClassName() { 514069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 515069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (logClassName == null) { 516069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project discoverLogImplementation(getClass().getName()); 517069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 518069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 519069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return logClassName; 520069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 521069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 522069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 523069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 524069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p>Return the <code>Constructor</code> that can be called to instantiate 525069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * new {@link org.apache.commons.logging.Log} instances.</p> 526069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 527069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p><strong>IMPLEMENTATION NOTE</strong> - Race conditions caused by 528069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * calling this method from more than one thread are ignored, because 529069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the same <code>Constructor</code> instance will ultimately be derived 530069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * in all circumstances.</p> 531069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 532069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @exception LogConfigurationException if a suitable constructor 533069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * cannot be returned 534069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 535069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @deprecated Never invoked by this class; subclasses should not assume 536069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * it will be. 537069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 538069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected Constructor getLogConstructor() 539069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throws LogConfigurationException { 540069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 541069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Return the previously identified Constructor (if any) 542069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (logConstructor == null) { 543069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project discoverLogImplementation(getClass().getName()); 544069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 545069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 546069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return logConstructor; 547069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 548069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 549069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 550069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 551069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Is <em>JDK 1.3 with Lumberjack</em> logging available? 552069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 553069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @deprecated Never invoked by this class; subclasses should not assume 554069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * it will be. 555069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 556069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected boolean isJdk13LumberjackAvailable() { 557069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return isLogLibraryAvailable( 558069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Jdk13Lumberjack", 559069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "org.apache.commons.logging.impl.Jdk13LumberjackLogger"); 560069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 561069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 562069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 563069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 564069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p>Return <code>true</code> if <em>JDK 1.4 or later</em> logging 565069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * is available. Also checks that the <code>Throwable</code> class 566069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * supports <code>getStackTrace()</code>, which is required by 567069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Jdk14Logger.</p> 568069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 569069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @deprecated Never invoked by this class; subclasses should not assume 570069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * it will be. 571069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 572069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected boolean isJdk14Available() { 573069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return isLogLibraryAvailable( 574069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Jdk14", 575069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "org.apache.commons.logging.impl.Jdk14Logger"); 576069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 577069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 578069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 579069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 580069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Is a <em>Log4J</em> implementation available? 581069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 582069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @deprecated Never invoked by this class; subclasses should not assume 583069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * it will be. 584069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 585069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected boolean isLog4JAvailable() { 586069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return isLogLibraryAvailable( 587069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Log4J", 588069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project LOGGING_IMPL_LOG4J_LOGGER); 589069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 590069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 591069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 592069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 593069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Create and return a new {@link org.apache.commons.logging.Log} 594069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * instance for the specified name. 595069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 596069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param name Name of the new logger 597069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 598069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @exception LogConfigurationException if a new instance cannot 599069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * be created 600069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 601069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected Log newInstance(String name) throws LogConfigurationException { 602069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 603069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Log instance = null; 604069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 605069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (logConstructor == null) { 606069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project instance = discoverLogImplementation(name); 607069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 608069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project else { 609069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Object params[] = { name }; 610069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project instance = (Log) logConstructor.newInstance(params); 611069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 612069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 613069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (logMethod != null) { 614069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Object params[] = { this }; 615069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logMethod.invoke(instance, params); 616069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 617069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 618069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return (instance); 619069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 620069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (LogConfigurationException lce) { 621069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 622069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // this type of exception means there was a problem in discovery 623069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // and we've already output diagnostics about the issue, etc.; 624069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // just pass it on 625069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw (LogConfigurationException) lce; 626069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 627069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (InvocationTargetException e) { 628069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // A problem occurred invoking the Constructor or Method 629069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // previously discovered 630069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Throwable c = e.getTargetException(); 631069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (c != null) { 632069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new LogConfigurationException(c); 633069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 634069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new LogConfigurationException(e); 635069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 636069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (Throwable t) { 637069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // A problem occurred invoking the Constructor or Method 638069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // previously discovered 639069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new LogConfigurationException(t); 640069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 641069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 642069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 643069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 644069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ------------------------------------------------------ Private Methods 645069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 646069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 647069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Utility method to check whether a particular logging library is 648069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * present and available for use. Note that this does <i>not</i> 649069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * affect the future behaviour of this class. 650069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 651069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private boolean isLogLibraryAvailable(String name, String classname) { 652069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 653069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Checking for '" + name + "'."); 654069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 655069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 656069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Log log = createLogFromClass( 657069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project classname, 658069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.getClass().getName(), // dummy category 659069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project false); 660069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 661069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (log == null) { 662069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 663069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Did not find '" + name + "'."); 664069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 665069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return false; 666069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 667069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 668069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Found '" + name + "'."); 669069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 670069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return true; 671069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 672069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(LogConfigurationException e) { 673069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 674069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Logging system '" + name + "' is available but not useable."); 675069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 676069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return false; 677069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 678069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 679069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 680069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 681069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Attempt to find an attribute (see method setAttribute) or a 682069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * system property with the provided name and return its value. 683069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 684069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The attributes associated with this object are checked before 685069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * system properties in case someone has explicitly called setAttribute, 686069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * or a configuration property has been set in a commons-logging.properties 687069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * file. 688069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 689069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return the value associated with the property, or null. 690069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 691069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private String getConfigurationValue(String property) { 692069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 693069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[ENV] Trying to get configuration for item " + property); 694069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 695069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 696069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Object valueObj = getAttribute(property); 697069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (valueObj != null) { 698069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 699069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[ENV] Found LogFactory attribute [" + valueObj + "] for " + property); 700069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 701069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return valueObj.toString(); 702069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 703069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 704069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 705069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[ENV] No LogFactory attribute found for " + property); 706069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 707069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 708069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 709069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String value = System.getProperty(property); 710069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (value != null) { 711069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 712069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[ENV] Found system property [" + value + "] for " + property); 713069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 714069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return value; 715069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 716069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 717069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 718069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[ENV] No system property found for property " + property); 719069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 720069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (SecurityException e) { 721069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 722069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[ENV] Security prevented reading system property " + property); 723069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 724069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 725069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 726069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 727069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[ENV] No configuration defined for item " + property); 728069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 729069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 730069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return null; 731069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 732069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 733069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 734069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Get the setting for the user-configurable behaviour specified by key. 735069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * If nothing has explicitly been set, then return dflt. 736069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 737069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private boolean getBooleanConfiguration(String key, boolean dflt) { 738069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String val = getConfigurationValue(key); 739069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (val == null) 740069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return dflt; 741069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return Boolean.valueOf(val).booleanValue(); 742069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 743069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 744069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 745069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Initialize a number of variables that control the behaviour of this 746069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * class and that can be tweaked by the user. This is done when the first 747069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * logger is created, not in the constructor of this class, because we 748069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * need to give the user a chance to call method setAttribute in order to 749069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * configure this object. 750069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 751069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private void initConfiguration() { 752069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project allowFlawedContext = getBooleanConfiguration(ALLOW_FLAWED_CONTEXT_PROPERTY, true); 753069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project allowFlawedDiscovery = getBooleanConfiguration(ALLOW_FLAWED_DISCOVERY_PROPERTY, true); 754069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project allowFlawedHierarchy = getBooleanConfiguration(ALLOW_FLAWED_HIERARCHY_PROPERTY, true); 755069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 756069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 757069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 758069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 759069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Attempts to create a Log instance for the given category name. 760069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Follows the discovery process described in the class javadoc. 761069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 762069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param logCategory the name of the log category 763069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 764069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws LogConfigurationException if an error in discovery occurs, 765069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * or if no adapter at all can be instantiated 766069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 767069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private Log discoverLogImplementation(String logCategory) 768069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throws LogConfigurationException 769069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project { 770069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 771069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Discovering a Log implementation..."); 772069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 773069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 774069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project initConfiguration(); 775069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 776069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Log result = null; 777069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 778069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // See if the user specified the Log implementation to use 779069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String specifiedLogClassName = findUserSpecifiedLogClassName(); 780069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 781069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (specifiedLogClassName != null) { 782069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 783069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Attempting to load user-specified log class '" + 784069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project specifiedLogClassName + "'..."); 785069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 786069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 787069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project result = createLogFromClass(specifiedLogClassName, 788069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logCategory, 789069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project true); 790069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (result == null) { 791069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project StringBuffer messageBuffer = new StringBuffer("User-specified log class '"); 792069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project messageBuffer.append(specifiedLogClassName); 793069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project messageBuffer.append("' cannot be found or is not useable."); 794069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 795069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Mistyping or misspelling names is a common fault. 796069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Construct a good error message, if we can 797069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (specifiedLogClassName != null) { 798069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_LOG4J_LOGGER); 799069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_JDK14_LOGGER); 800069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_LUMBERJACK_LOGGER); 801069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_SIMPLE_LOGGER); 802069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 803069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new LogConfigurationException(messageBuffer.toString()); 804069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 805069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 806069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return result; 807069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 808069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 809069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // No user specified log; try to discover what's on the classpath 810069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 811069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Note that we deliberately loop here over classesToDiscover and 812069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // expect method createLogFromClass to loop over the possible source 813069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // classloaders. The effect is: 814069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // for each discoverable log adapter 815069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // for each possible classloader 816069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // see if it works 817069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 818069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // It appears reasonable at first glance to do the opposite: 819069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // for each possible classloader 820069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // for each discoverable log adapter 821069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // see if it works 822069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 823069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // The latter certainly has advantages for user-installable logging 824069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // libraries such as log4j; in a webapp for example this code should 825069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // first check whether the user has provided any of the possible 826069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // logging libraries before looking in the parent classloader. 827069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Unfortunately, however, Jdk14Logger will always work in jvm>=1.4, 828069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // and SimpleLog will always work in any JVM. So the loop would never 829069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ever look for logging libraries in the parent classpath. Yet many 830069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // users would expect that putting log4j there would cause it to be 831069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // detected (and this is the historical JCL behaviour). So we go with 832069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // the first approach. A user that has bundled a specific logging lib 833069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // in a webapp should use a commons-logging.properties file or a 834069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // service file in META-INF to force use of that logging lib anyway, 835069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // rather than relying on discovery. 836069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 837069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 838069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 839069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "No user-specified Log implementation; performing discovery" + 840069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project " using the standard supported logging implementations..."); 841069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 842069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project for(int i=0; (i<classesToDiscover.length) && (result == null); ++i) { 843069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project result = createLogFromClass(classesToDiscover[i], logCategory, true); 844069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 845069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 846069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (result == null) { 847069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new LogConfigurationException 848069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ("No suitable Log implementation"); 849069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 850069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 851069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return result; 852069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 853069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 854069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 855069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 856069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Appends message if the given name is similar to the candidate. 857069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param messageBuffer <code>StringBuffer</code> the message should be appended to, 858069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * not null 859069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param name the (trimmed) name to be test against the candidate, not null 860069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param candidate the candidate name (not null) 861069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 862069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private void informUponSimilarName(final StringBuffer messageBuffer, final String name, 863069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project final String candidate) { 864069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (name.equals(candidate)) { 865069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Don't suggest a name that is exactly the same as the one the 866069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // user tried... 867069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return; 868069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 869069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 870069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // If the user provides a name that is in the right package, and gets 871069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // the first 5 characters of the adapter class right (ignoring case), 872069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // then suggest the candidate adapter class name. 873069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (name.regionMatches(true, 0, candidate, 0, PKG_LEN + 5)) { 874069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project messageBuffer.append(" Did you mean '"); 875069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project messageBuffer.append(candidate); 876069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project messageBuffer.append("'?"); 877069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 878069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 879069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 880069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 881069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 882069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Checks system properties and the attribute map for 883069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * a Log implementation specified by the user under the 884069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * property names {@link #LOG_PROPERTY} or {@link #LOG_PROPERTY_OLD}. 885069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 886069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return classname specified by the user, or <code>null</code> 887069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 888069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private String findUserSpecifiedLogClassName() 889069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project { 890069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 891069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Trying to get log class from attribute '" + LOG_PROPERTY + "'"); 892069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 893069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String specifiedClass = (String) getAttribute(LOG_PROPERTY); 894069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 895069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (specifiedClass == null) { // @deprecated 896069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 897069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Trying to get log class from attribute '" + 898069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project LOG_PROPERTY_OLD + "'"); 899069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 900069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project specifiedClass = (String) getAttribute(LOG_PROPERTY_OLD); 901069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 902069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 903069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (specifiedClass == null) { 904069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 905069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Trying to get log class from system property '" + 906069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project LOG_PROPERTY + "'"); 907069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 908069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 909069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project specifiedClass = System.getProperty(LOG_PROPERTY); 910069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (SecurityException e) { 911069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 912069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("No access allowed to system property '" + 913069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project LOG_PROPERTY + "' - " + e.getMessage()); 914069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 915069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 916069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 917069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 918069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (specifiedClass == null) { // @deprecated 919069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 920069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Trying to get log class from system property '" + 921069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project LOG_PROPERTY_OLD + "'"); 922069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 923069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 924069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project specifiedClass = System.getProperty(LOG_PROPERTY_OLD); 925069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (SecurityException e) { 926069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 927069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("No access allowed to system property '" + 928069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project LOG_PROPERTY_OLD + "' - " + e.getMessage()); 929069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 930069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 931069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 932069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 933069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Remove any whitespace; it's never valid in a classname so its 934069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // presence just means a user mistake. As we know what they meant, 935069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // we may as well strip the spaces. 936069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (specifiedClass != null) { 937069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project specifiedClass = specifiedClass.trim(); 938069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 939069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 940069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return specifiedClass; 941069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 942069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 943069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 944069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 945069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Attempts to load the given class, find a suitable constructor, 946069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * and instantiate an instance of Log. 947069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 948069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param logAdapterClassName classname of the Log implementation 949069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 950069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param logCategory argument to pass to the Log implementation's 951069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * constructor 952069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 953069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param affectState <code>true</code> if this object's state should 954069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * be affected by this method call, <code>false</code> otherwise. 955069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 956069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return an instance of the given class, or null if the logging 957069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * library associated with the specified adapter is not available. 958069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 959069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws LogConfigurationException if there was a serious error with 960069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * configuration and the handleFlawedDiscovery method decided this 961069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * problem was fatal. 962069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 963069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private Log createLogFromClass(String logAdapterClassName, 964069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String logCategory, 965069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project boolean affectState) 966069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throws LogConfigurationException { 967069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 968069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 969069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Attempting to instantiate '" + logAdapterClassName + "'"); 970069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 971069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 972069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Object[] params = { logCategory }; 973069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Log logAdapter = null; 974069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Constructor constructor = null; 975069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 976069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Class logAdapterClass = null; 977069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader currentCL = getBaseClassLoader(); 978069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 979069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project for(;;) { 980069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Loop through the classloader hierarchy trying to find 981069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // a viable classloader. 982069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 983069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Trying to load '" 984069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + logAdapterClassName 985069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' from classloader " 986069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + objectId(currentCL)); 987069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 988069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 989069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Show the location of the first occurrence of the .class file 990069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // in the classpath. This is the location that ClassLoader.loadClass 991069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // will load the class from -- unless the classloader is doing 992069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // something weird. 993069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project URL url; 994069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String resourceName = logAdapterClassName.replace('.', '/') + ".class"; 995069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (currentCL != null) { 996069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project url = currentCL.getResource(resourceName ); 997069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 998069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project url = ClassLoader.getSystemResource(resourceName + ".class"); 999069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1000069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1001069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (url == null) { 1002069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Class '" + logAdapterClassName + "' [" + resourceName + "] cannot be found."); 1003069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 1004069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Class '" + logAdapterClassName + "' was found at '" + url + "'"); 1005069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1006069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1007069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1008069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Class c = null; 1009069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1010069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project c = Class.forName(logAdapterClassName, true, currentCL); 1011069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (ClassNotFoundException originalClassNotFoundException) { 1012069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // The current classloader was unable to find the log adapter 1013069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // in this or any ancestor classloader. There's no point in 1014069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // trying higher up in the hierarchy in this case.. 1015069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String msg = "" + originalClassNotFoundException.getMessage(); 1016069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1017069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "The log adapter '" 1018069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + logAdapterClassName 1019069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' is not available via classloader " 1020069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + objectId(currentCL) 1021069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + ": " 1022069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + msg.trim()); 1023069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1024069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Try the class classloader. 1025069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // This may work in cases where the TCCL 1026069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // does not contain the code executed or JCL. 1027069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // This behaviour indicates that the application 1028069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // classloading strategy is not consistent with the 1029069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Java 1.2 classloading guidelines but JCL can 1030069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // and so should handle this case. 1031069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project c = Class.forName(logAdapterClassName); 1032069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (ClassNotFoundException secondaryClassNotFoundException) { 1033069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // no point continuing: this adapter isn't available 1034069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg = "" + secondaryClassNotFoundException.getMessage(); 1035069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1036069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "The log adapter '" 1037069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + logAdapterClassName 1038069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' is not available via the LogFactoryImpl class classloader: " 1039069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + msg.trim()); 1040069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project break; 1041069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1042069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1043069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1044069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project constructor = c.getConstructor(logConstructorSignature); 1045069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Object o = constructor.newInstance(params); 1046069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1047069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Note that we do this test after trying to create an instance 1048069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // [rather than testing Log.class.isAssignableFrom(c)] so that 1049069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // we don't complain about Log hierarchy problems when the 1050069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // adapter couldn't be instantiated anyway. 1051069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (o instanceof Log) { 1052069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logAdapterClass = c; 1053069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logAdapter = (Log) o; 1054069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project break; 1055069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1056069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1057069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Oops, we have a potential problem here. An adapter class 1058069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // has been found and its underlying lib is present too, but 1059069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // there are multiple Log interface classes available making it 1060069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // impossible to cast to the type the caller wanted. We 1061069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // certainly can't use this logger, but we need to know whether 1062069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // to keep on discovering or terminate now. 1063069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1064069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // The handleFlawedHierarchy method will throw 1065069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // LogConfigurationException if it regards this problem as 1066069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // fatal, and just return if not. 1067069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project handleFlawedHierarchy(currentCL, c); 1068069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (NoClassDefFoundError e) { 1069069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // We were able to load the adapter but it had references to 1070069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // other classes that could not be found. This simply means that 1071069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // the underlying logger library is not present in this or any 1072069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ancestor classloader. There's no point in trying higher up 1073069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // in the hierarchy in this case.. 1074069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String msg = "" + e.getMessage(); 1075069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1076069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "The log adapter '" 1077069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + logAdapterClassName 1078069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' is missing dependencies when loaded via classloader " 1079069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + objectId(currentCL) 1080069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + ": " 1081069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + msg.trim()); 1082069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project break; 1083069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (ExceptionInInitializerError e) { 1084069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // A static initializer block or the initializer code associated 1085069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // with a static variable on the log adapter class has thrown 1086069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // an exception. 1087069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1088069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // We treat this as meaning the adapter's underlying logging 1089069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // library could not be found. 1090069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String msg = "" + e.getMessage(); 1091069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1092069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "The log adapter '" 1093069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + logAdapterClassName 1094069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' is unable to initialize itself when loaded via classloader " 1095069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + objectId(currentCL) 1096069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + ": " 1097069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + msg.trim()); 1098069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project break; 1099069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(LogConfigurationException e) { 1100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // call to handleFlawedHierarchy above must have thrown 1101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // a LogConfigurationException, so just throw it on 1102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw e; 1103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(Throwable t) { 1104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // handleFlawedDiscovery will determine whether this is a fatal 1105069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // problem or not. If it is fatal, then a LogConfigurationException 1106069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // will be thrown. 1107069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project handleFlawedDiscovery(logAdapterClassName, currentCL, t); 1108069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1109069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1110069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (currentCL == null) { 1111069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project break; 1112069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1113069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1114069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // try the parent classloader 1115069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project currentCL = currentCL.getParent(); 1116069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1117069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1118069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if ((logAdapter != null) && affectState) { 1119069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // We've succeeded, so set instance fields 1120069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.logClassName = logAdapterClassName; 1121069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.logConstructor = constructor; 1122069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1123069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Identify the <code>setLogFactory</code> method (if there is one) 1124069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1125069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.logMethod = logAdapterClass.getMethod("setLogFactory", 1126069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logMethodSignature); 1127069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Found method setLogFactory(LogFactory) in '" 1128069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + logAdapterClassName + "'"); 1129069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (Throwable t) { 1130069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.logMethod = null; 1131069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1132069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[INFO] '" + logAdapterClassName 1133069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' from classloader " + objectId(currentCL) 1134069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " does not declare optional method " 1135069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "setLogFactory(LogFactory)"); 1136069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1137069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1138069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1139069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Log adapter '" + logAdapterClassName 1140069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' from classloader " + objectId(logAdapterClass.getClassLoader()) 1141069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " has been selected for use."); 1142069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1143069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1144069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return logAdapter; 1145069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1146069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1147069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1148069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1149069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Return the classloader from which we should try to load the logging 1150069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * adapter classes. 1151069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1152069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This method usually returns the context classloader. However if it 1153069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * is discovered that the classloader which loaded this class is a child 1154069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * of the context classloader <i>and</i> the allowFlawedContext option 1155069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * has been set then the classloader which loaded this class is returned 1156069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * instead. 1157069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1158069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The only time when the classloader which loaded this class is a 1159069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * descendant (rather than the same as or an ancestor of the context 1160069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * classloader) is when an app has created custom classloaders but 1161069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * failed to correctly set the context classloader. This is a bug in 1162069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the calling application; however we provide the option for JCL to 1163069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * simply generate a warning rather than fail outright. 1164069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1165069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1166069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private ClassLoader getBaseClassLoader() throws LogConfigurationException { 1167069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader thisClassLoader = getClassLoader(LogFactoryImpl.class); 1168069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1169069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (useTCCL == false) { 1170069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return thisClassLoader; 1171069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1172069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1173069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader contextClassLoader = getContextClassLoader(); 1174069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1175069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader baseClassLoader = getLowestClassLoader( 1176069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project contextClassLoader, thisClassLoader); 1177069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1178069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (baseClassLoader == null) { 1179069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // The two classloaders are not part of a parent child relationship. 1180069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // In some classloading setups (e.g. JBoss with its 1181069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // UnifiedLoaderRepository) this can still work, so if user hasn't 1182069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // forbidden it, just return the contextClassLoader. 1183069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (allowFlawedContext) { 1184069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1185069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1186069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[WARNING] the context classloader is not part of a" 1187069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " parent-child relationship with the classloader that" 1188069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " loaded LogFactoryImpl."); 1189069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1190069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // If contextClassLoader were null, getLowestClassLoader() would 1191069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // have returned thisClassLoader. The fact we are here means 1192069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // contextClassLoader is not null, so we can just return it. 1193069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return contextClassLoader; 1194069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1195069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project else { 1196069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new LogConfigurationException( 1197069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Bad classloader hierarchy; LogFactoryImpl was loaded via" 1198069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " a classloader that is not related to the current context" 1199069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " classloader."); 1200069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1201069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1202069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1203069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (baseClassLoader != contextClassLoader) { 1204069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // We really should just use the contextClassLoader as the starting 1205069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // point for scanning for log adapter classes. However it is expected 1206069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // that there are a number of broken systems out there which create 1207069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // custom classloaders but fail to set the context classloader so 1208069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // we handle those flawed systems anyway. 1209069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (allowFlawedContext) { 1210069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1211069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1212069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Warning: the context classloader is an ancestor of the" 1213069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " classloader that loaded LogFactoryImpl; it should be" 1214069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " the same or a descendant. The application using" 1215069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " commons-logging should ensure the context classloader" 1216069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " is used correctly."); 1217069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1218069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 1219069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new LogConfigurationException( 1220069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Bad classloader hierarchy; LogFactoryImpl was loaded via" 1221069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " a classloader that is not related to the current context" 1222069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " classloader."); 1223069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1224069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1225069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1226069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return baseClassLoader; 1227069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1228069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1229069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1230069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Given two related classloaders, return the one which is a child of 1231069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the other. 1232069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1233069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param c1 is a classloader (including the null classloader) 1234069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param c2 is a classloader (including the null classloader) 1235069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1236069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return c1 if it has c2 as an ancestor, c2 if it has c1 as an ancestor, 1237069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * and null if neither is an ancestor of the other. 1238069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1239069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private ClassLoader getLowestClassLoader(ClassLoader c1, ClassLoader c2) { 1240069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // TODO: use AccessController when dealing with classloaders here 1241069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1242069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (c1 == null) 1243069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return c2; 1244069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1245069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (c2 == null) 1246069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return c1; 1247069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1248069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader current; 1249069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1250069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // scan c1's ancestors to find c2 1251069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project current = c1; 1252069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project while (current != null) { 1253069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (current == c2) 1254069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return c1; 1255069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project current = current.getParent(); 1256069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1257069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1258069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // scan c2's ancestors to find c1 1259069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project current = c2; 1260069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project while (current != null) { 1261069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (current == c1) 1262069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return c2; 1263069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project current = current.getParent(); 1264069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1265069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1266069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return null; 1267069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1268069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1269069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1270069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Generates an internal diagnostic logging of the discovery failure and 1271069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * then throws a <code>LogConfigurationException</code> that wraps 1272069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the passed <code>Throwable</code>. 1273069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1274069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param logAdapterClassName is the class name of the Log implementation 1275069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * that could not be instantiated. Cannot be <code>null</code>. 1276069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1277069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param classLoader is the classloader that we were trying to load the 1278069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * logAdapterClassName from when the exception occurred. 1279069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1280069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param discoveryFlaw is the Throwable created by the classloader 1281069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1282069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws LogConfigurationException ALWAYS 1283069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1284069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private void handleFlawedDiscovery(String logAdapterClassName, 1285069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader classLoader, 1286069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Throwable discoveryFlaw) { 1287069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1288069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1289069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Could not instantiate Log '" 1290069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + logAdapterClassName + "' -- " 1291069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + discoveryFlaw.getClass().getName() + ": " 1292069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + discoveryFlaw.getLocalizedMessage()); 1293069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1294069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1295069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (!allowFlawedDiscovery) { 1296069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new LogConfigurationException(discoveryFlaw); 1297069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1298069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1299069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1300069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1301069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1302069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Report a problem loading the log adapter, then either return 1303069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * (if the situation is considered recoverable) or throw a 1304069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * LogConfigurationException. 1305069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1306069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * There are two possible reasons why we successfully loaded the 1307069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * specified log adapter class then failed to cast it to a Log object: 1308069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <ol> 1309069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>the specific class just doesn't implement the Log interface 1310069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * (user screwed up), or 1311069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li> the specified class has bound to a Log class loaded by some other 1312069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * classloader; Log@classloaderX cannot be cast to Log@classloaderY. 1313069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </ol> 1314069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1315069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Here we try to figure out which case has occurred so we can give the 1316069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * user some reasonable feedback. 1317069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1318069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param badClassLoader is the classloader we loaded the problem class from, 1319069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * ie it is equivalent to badClass.getClassLoader(). 1320069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1321069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param badClass is a Class object with the desired name, but which 1322069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * does not implement Log correctly. 1323069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1324069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws LogConfigurationException when the situation 1325069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * should not be recovered from. 1326069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1327069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private void handleFlawedHierarchy(ClassLoader badClassLoader, Class badClass) 1328069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throws LogConfigurationException { 1329069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1330069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project boolean implementsLog = false; 1331069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String logInterfaceName = Log.class.getName(); 1332069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Class interfaces[] = badClass.getInterfaces(); 1333069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project for (int i = 0; i < interfaces.length; i++) { 1334069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (logInterfaceName.equals(interfaces[i].getName())) { 1335069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project implementsLog = true; 1336069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project break; 1337069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1338069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1339069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1340069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (implementsLog) { 1341069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // the class does implement an interface called Log, but 1342069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // it is in the wrong classloader 1343069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1344069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1345069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader logInterfaceClassLoader = getClassLoader(Log.class); 1346069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1347069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Class '" + badClass.getName() 1348069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' was found in classloader " 1349069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + objectId(badClassLoader) 1350069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + ". It is bound to a Log interface which is not" 1351069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " the one loaded from classloader " 1352069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + objectId(logInterfaceClassLoader)); 1353069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (Throwable t) { 1354069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1355069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Error while trying to output diagnostics about" 1356069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " bad class '" + badClass + "'"); 1357069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1358069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1359069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1360069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (!allowFlawedHierarchy) { 1361069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project StringBuffer msg = new StringBuffer(); 1362069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append("Terminating logging for this context "); 1363069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append("due to bad log hierarchy. "); 1364069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append("You have more than one version of '"); 1365069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append(Log.class.getName()); 1366069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append("' visible."); 1367069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1368069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic(msg.toString()); 1369069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1370069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new LogConfigurationException(msg.toString()); 1371069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1372069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1373069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1374069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project StringBuffer msg = new StringBuffer(); 1375069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append("Warning: bad log hierarchy. "); 1376069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append("You have more than one version of '"); 1377069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append(Log.class.getName()); 1378069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append("' visible."); 1379069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic(msg.toString()); 1380069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1381069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 1382069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // this is just a bad adapter class 1383069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (!allowFlawedDiscovery) { 1384069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project StringBuffer msg = new StringBuffer(); 1385069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append("Terminating logging for this context. "); 1386069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append("Log class '"); 1387069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append(badClass.getName()); 1388069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append("' does not implement the Log interface."); 1389069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1390069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic(msg.toString()); 1391069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1392069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1393069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new LogConfigurationException(msg.toString()); 1394069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1395069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1396069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1397069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project StringBuffer msg = new StringBuffer(); 1398069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append("[WARNING] Log class '"); 1399069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append(badClass.getName()); 1400069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg.append("' does not implement the Log interface."); 1401069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic(msg.toString()); 1402069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1403069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1404069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1405069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project} 1406