001package ch.qos.logback.classic.util; 002 003import ch.qos.logback.classic.ClassicConstants; 004import ch.qos.logback.classic.LoggerContext; 005import ch.qos.logback.classic.spi.Configurator; 006import ch.qos.logback.core.LogbackException; 007import ch.qos.logback.core.spi.ContextAwareBase; 008import ch.qos.logback.core.status.InfoStatus; 009import ch.qos.logback.core.status.StatusManager; 010import ch.qos.logback.core.util.Loader; 011import ch.qos.logback.core.util.OptionHelper; 012import ch.qos.logback.classic.joran.JoranConfigurator; 013import ch.qos.logback.core.joran.spi.JoranException; 014 015import java.io.File; 016import java.io.IOException; 017import java.net.MalformedURLException; 018import java.net.URL; 019import java.util.Set; 020 021/** 022 * @since 1.3.0-beta1 023 */ 024public class DefaultJoranConfigurator extends ContextAwareBase implements Configurator { 025 026 final public static String AUTOCONFIG_FILE = "logback.xml"; 027 final public static String TEST_AUTOCONFIG_FILE = "logback-test.xml"; 028 029 @Override 030 public ExecutionStatus configure(LoggerContext loggerContext) { 031 URL url = findURLOfDefaultConfigurationFile(true); 032 if (url != null) { 033 try { 034 configureByResource(url); 035 } catch (JoranException e) { 036 e.printStackTrace(); 037 } 038 // we tried and that counts Mary. 039 return ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY; 040 } else { 041 return ExecutionStatus.INVOKE_NEXT_IF_ANY; 042 } 043 } 044 045 public void configureByResource(URL url) throws JoranException { 046 if (url == null) { 047 throw new IllegalArgumentException("URL argument cannot be null"); 048 } 049 final String urlString = url.toString(); 050 if (urlString.endsWith("xml")) { 051 JoranConfigurator configurator = new JoranConfigurator(); 052 configurator.setContext(context); 053 configurator.doConfigure(url); 054 } else { 055 throw new LogbackException( 056 "Unexpected filename extension of file [" + url.toString() + "]. Should be .xml"); 057 } 058 } 059 060 public URL findURLOfDefaultConfigurationFile(boolean updateStatus) { 061 ClassLoader myClassLoader = Loader.getClassLoaderOfObject(this); 062 URL url = findConfigFileURLFromSystemProperties(myClassLoader, updateStatus); 063 if (url != null) { 064 return url; 065 } 066 067 url = getResource(TEST_AUTOCONFIG_FILE, myClassLoader, updateStatus); 068 if (url != null) { 069 return url; 070 } 071 072 return getResource(AUTOCONFIG_FILE, myClassLoader, updateStatus); 073 } 074 075 private URL findConfigFileURLFromSystemProperties(ClassLoader classLoader, boolean updateStatus) { 076 String logbackConfigFile = OptionHelper.getSystemProperty(ClassicConstants.CONFIG_FILE_PROPERTY); 077 if (logbackConfigFile != null) { 078 URL result = null; 079 try { 080 result = new URL(logbackConfigFile); 081 return result; 082 } catch (MalformedURLException e) { 083 // so, resource is not a URL: 084 // attempt to get the resource from the class path 085 result = Loader.getResource(logbackConfigFile, classLoader); 086 if (result != null) { 087 return result; 088 } 089 File f = new File(logbackConfigFile); 090 if (f.exists() && f.isFile()) { 091 try { 092 result = f.toURI().toURL(); 093 return result; 094 } catch (MalformedURLException e1) { 095 } 096 } 097 } finally { 098 if (updateStatus) { 099 statusOnResourceSearch(logbackConfigFile, classLoader, result); 100 } 101 } 102 } 103 return null; 104 } 105 106 private URL getResource(String filename, ClassLoader myClassLoader, boolean updateStatus) { 107 URL url = Loader.getResource(filename, myClassLoader); 108 if (updateStatus) { 109 statusOnResourceSearch(filename, myClassLoader, url); 110 } 111 return url; 112 } 113 114 private void statusOnResourceSearch(String resourceName, ClassLoader classLoader, URL url) { 115 StatusManager sm = context.getStatusManager(); 116 if (url == null) { 117 sm.add(new InfoStatus("Could NOT find resource [" + resourceName + "]", context)); 118 } else { 119 sm.add(new InfoStatus("Found resource [" + resourceName + "] at [" + url.toString() + "]", context)); 120 multiplicityWarning(resourceName, classLoader); 121 } 122 } 123 124 private void multiplicityWarning(String resourceName, ClassLoader classLoader) { 125 Set<URL> urlSet = null; 126 try { 127 urlSet = Loader.getResources(resourceName, classLoader); 128 } catch (IOException e) { 129 addError("Failed to get url list for resource [" + resourceName + "]", e); 130 } 131 if (urlSet != null && urlSet.size() > 1) { 132 addWarn("Resource [" + resourceName + "] occurs multiple times on the classpath."); 133 for (URL url : urlSet) { 134 addWarn("Resource [" + resourceName + "] occurs at [" + url.toString() + "]"); 135 } 136 } 137 } 138}