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