001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.core.util; 015 016import java.lang.reflect.Constructor; 017import java.util.Properties; 018 019import ch.qos.logback.core.Context; 020import ch.qos.logback.core.spi.ContextAware; 021import ch.qos.logback.core.spi.PropertyContainer; 022import ch.qos.logback.core.spi.ScanException; 023import ch.qos.logback.core.subst.NodeToStringTransformer; 024 025/** 026 * @author Ceki Gulcu 027 */ 028public class OptionHelper { 029 030 public static Object instantiateByClassName(String className, Class<?> superClass, Context context) 031 throws IncompatibleClassException, DynamicClassLoadingException { 032 ClassLoader classLoader = Loader.getClassLoaderOfObject(context); 033 return instantiateByClassName(className, superClass, classLoader); 034 } 035 036 public static Object instantiateByClassNameAndParameter(String className, Class<?> superClass, Context context, 037 Class<?> type, Object param) throws IncompatibleClassException, DynamicClassLoadingException { 038 ClassLoader classLoader = Loader.getClassLoaderOfObject(context); 039 return instantiateByClassNameAndParameter(className, superClass, classLoader, type, param); 040 } 041 042 public static Object instantiateByClassName(String className, Class<?> superClass, ClassLoader classLoader) 043 throws IncompatibleClassException, DynamicClassLoadingException { 044 return instantiateByClassNameAndParameter(className, superClass, classLoader, null, null); 045 } 046 047 public static Object instantiateByClassNameAndParameter(String className, Class<?> superClass, 048 ClassLoader classLoader, Class<?> type, Object parameter) 049 throws IncompatibleClassException, DynamicClassLoadingException { 050 051 if (className == null) { 052 throw new NullPointerException(); 053 } 054 try { 055 Class<?> classObj = null; 056 classObj = classLoader.loadClass(className); 057 if (!superClass.isAssignableFrom(classObj)) { 058 throw new IncompatibleClassException(superClass, classObj); 059 } 060 if (type == null) { 061 return classObj.getConstructor().newInstance(); 062 } else { 063 Constructor<?> constructor = classObj.getConstructor(type); 064 return constructor.newInstance(parameter); 065 } 066 } catch (IncompatibleClassException ice) { 067 throw ice; 068 } catch (Throwable t) { 069 throw new DynamicClassLoadingException("Failed to instantiate type " + className, t); 070 } 071 } 072 073 /** 074 * Find the value corresponding to <code>key</code> in <code>props</code>. Then 075 * perform variable substitution on the found value. 076 */ 077 // public static String findAndSubst(String key, Properties props) { 078 // String value = props.getProperty(key); 079 // 080 // if (value == null) { 081 // return null; 082 // } 083 // 084 // try { 085 // return substVars(value, props); 086 // } catch (IllegalArgumentException e) { 087 // return value; 088 // } 089 // } 090 final static String DELIM_START = "${"; 091 final static char DELIM_STOP = '}'; 092 final static String DELIM_DEFAULT = ":-"; 093 094 final static int DELIM_START_LEN = 2; 095 final static int DELIM_STOP_LEN = 1; 096 final static int DELIM_DEFAULT_LEN = 2; 097 098 final static String _IS_UNDEFINED = "_IS_UNDEFINED"; 099 100 /** 101 * @see #substVars(String, PropertyContainer, PropertyContainer) 102 */ 103 public static String substVars(String val, PropertyContainer pc1) throws ScanException { 104 return substVars(val, pc1, null); 105 } 106 107 /** 108 * See http://logback.qos.ch/manual/configuration.html#variableSubstitution 109 */ 110 public static String substVars(String input, PropertyContainer pc0, PropertyContainer pc1) throws ScanException { 111 // may throw IllegalArgumentException or ScanException 112 return NodeToStringTransformer.substituteVariable(input, pc0, pc1); 113 114 } 115 116 /** 117 * Try to lookup the property in the following order: 118 * <ul> 119 * <li>pc1 (usually the local property container)</li> 120 * <li>pc2 (usually the {@link Context context})</li> 121 * <li>System properties</li> 122 * <li>Environment variables</li> 123 * </ul> 124 * 125 * @param key the property key 126 * @param pc1 the first property container to search 127 * @param pc2 the second property container to search 128 * @return the property value or null if not found 129 */ 130 public static String propertyLookup(String key, PropertyContainer pc1, PropertyContainer pc2) { 131 String value = null; 132 // first try the props passed as parameter 133 value = pc1.getProperty(key); 134 135 // then try the pc2 136 if (value == null && pc2 != null) { 137 value = pc2.getProperty(key); 138 } 139 // then try in System properties 140 if (value == null) { 141 value = getSystemProperty(key, null); 142 } 143 if (value == null) { 144 value = getEnv(key); 145 } 146 return value; 147 } 148 149 /** 150 * Very similar to <code>System.getProperty</code> except that the 151 * {@link SecurityException} is absorbed. 152 * 153 * @param key The key to search for. 154 * @param def The default value to return. 155 * @return the string value of the system property, or the default value if 156 * there is no property with that key. 157 */ 158 public static String getSystemProperty(String key, String def) { 159 try { 160 return System.getProperty(key, def); 161 } catch (SecurityException e) { 162 return def; 163 } 164 } 165 166 /** 167 * Lookup a key from the environment. 168 * 169 * @param key 170 * @return value corresponding to key from the OS environment 171 */ 172 public static String getEnv(String key) { 173 try { 174 return System.getenv(key); 175 } catch (SecurityException e) { 176 return null; 177 } 178 } 179 180 /** 181 * Very similar to <code>System.getProperty</code> except that the 182 * {@link SecurityException} is absorbed. 183 * 184 * @param key The key to search for. 185 * @return the string value of the system property. 186 */ 187 public static String getSystemProperty(String key) { 188 try { 189 return System.getProperty(key); 190 } catch (SecurityException e) { 191 return null; 192 } 193 } 194 195 public static void setSystemProperties(ContextAware contextAware, Properties props) { 196 for (Object o : props.keySet()) { 197 String key = (String) o; 198 String value = props.getProperty(key); 199 setSystemProperty(contextAware, key, value); 200 } 201 } 202 203 public static void setSystemProperty(ContextAware contextAware, String key, String value) { 204 try { 205 System.setProperty(key, value); 206 } catch (SecurityException e) { 207 contextAware.addError("Failed to set system property [" + key + "]", e); 208 } 209 } 210 211 /** 212 * Very similar to {@link System#getProperties()} except that the 213 * {@link SecurityException} is absorbed. 214 * 215 * @return the system properties 216 */ 217 public static Properties getSystemProperties() { 218 try { 219 return System.getProperties(); 220 } catch (SecurityException e) { 221 return new Properties(); 222 } 223 } 224 225 /** 226 * Return a String[] of size two. The first item containing the key part and the 227 * second item containing a default value specified by the user. The second item 228 * will be null if no default value is specified. 229 * 230 * @param key 231 * @return 232 */ 233 static public String[] extractDefaultReplacement(String key) { 234 String[] result = new String[2]; 235 if (key == null) 236 return result; 237 238 result[0] = key; 239 int d = key.indexOf(DELIM_DEFAULT); 240 if (d != -1) { 241 result[0] = key.substring(0, d); 242 result[1] = key.substring(d + DELIM_DEFAULT_LEN); 243 } 244 return result; 245 } 246 247 /** 248 * If <code>value</code> is "true", then <code>true</code> is returned. If 249 * <code>value</code> is "false", then <code>true</code> is returned. Otherwise, 250 * <code>default</code> is returned. 251 * <p> 252 * Case of value is unimportant. 253 */ 254 public static boolean toBoolean(String value, boolean dEfault) { 255 if (value == null) { 256 return dEfault; 257 } 258 259 String trimmedVal = value.trim(); 260 261 if ("true".equalsIgnoreCase(trimmedVal)) { 262 return true; 263 } 264 265 if ("false".equalsIgnoreCase(trimmedVal)) { 266 return false; 267 } 268 269 return dEfault; 270 } 271 272 /** 273 * @deprecated 274 * @since 1.3 275 */ 276 public static boolean isEmpty(String str) { 277 return isNullOrEmptyOrAllSpaces(str); 278 } 279 280 /** 281 * Returns true if input str is null or empty. 282 * 283 * @param str 284 * @return 285 */ 286 public static boolean isNullOrEmpty(String str) { 287 return ((str == null) || str.trim().length() == 0); 288 } 289 290 /** 291 * isNullOrEmpty xisNullOrEmptyOrAllSpaces 292 * @param str 293 * @return 294 * @since 1.5.0 295 */ 296 public static boolean isNullOrEmptyOrAllSpaces(String str) { 297 return ((str == null) || str.trim().length() == 0); 298 } 299 300 301 final public static boolean isNullOrEmpty(Object[] array) { 302 if(array == null || array.length == 0) 303 return true; 304 else 305 return false; 306 } 307 308 final public static boolean isNotEmtpy(Object[] array) { 309 return !isNullOrEmpty(array); 310 } 311}