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}