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