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    public static String propertyLookup(String key, PropertyContainer pc1, PropertyContainer pc2) {
117        String value = null;
118        // first try the props passed as parameter
119        value = pc1.getProperty(key);
120
121        // then try the pc2
122        if (value == null && pc2 != null) {
123            value = pc2.getProperty(key);
124        }
125        // then try in System properties
126        if (value == null) {
127            value = getSystemProperty(key, null);
128        }
129        if (value == null) {
130            value = getEnv(key);
131        }
132        return value;
133    }
134
135    /**
136     * Very similar to <code>System.getProperty</code> except that the
137     * {@link SecurityException} is absorbed.
138     *
139     * @param key The key to search for.
140     * @param def The default value to return.
141     * @return the string value of the system property, or the default value if
142     *         there is no property with that key.
143     */
144    public static String getSystemProperty(String key, String def) {
145        try {
146            return System.getProperty(key, def);
147        } catch (SecurityException e) {
148            return def;
149        }
150    }
151
152    /**
153     * Lookup a key from the environment.
154     *
155     * @param key
156     * @return value corresponding to key from the OS environment
157     */
158    public static String getEnv(String key) {
159        try {
160            return System.getenv(key);
161        } catch (SecurityException e) {
162            return null;
163        }
164    }
165
166    /**
167     * Very similar to <code>System.getProperty</code> except that the
168     * {@link SecurityException} is absorbed.
169     *
170     * @param key The key to search for.
171     * @return the string value of the system property.
172     */
173    public static String getSystemProperty(String key) {
174        try {
175            return System.getProperty(key);
176        } catch (SecurityException e) {
177            return null;
178        }
179    }
180
181    public static void setSystemProperties(ContextAware contextAware, Properties props) {
182        for (Object o : props.keySet()) {
183            String key = (String) o;
184            String value = props.getProperty(key);
185            setSystemProperty(contextAware, key, value);
186        }
187    }
188
189    public static void setSystemProperty(ContextAware contextAware, String key, String value) {
190        try {
191            System.setProperty(key, value);
192        } catch (SecurityException e) {
193            contextAware.addError("Failed to set system property [" + key + "]", e);
194        }
195    }
196
197    /**
198     * Very similar to {@link System#getProperties()} except that the
199     * {@link SecurityException} is absorbed.
200     *
201     * @return the system properties
202     */
203    public static Properties getSystemProperties() {
204        try {
205            return System.getProperties();
206        } catch (SecurityException e) {
207            return new Properties();
208        }
209    }
210
211    /**
212     * Return a String[] of size two. The first item containing the key part and the
213     * second item containing a default value specified by the user. The second item
214     * will be null if no default value is specified.
215     *
216     * @param key
217     * @return
218     */
219    static public String[] extractDefaultReplacement(String key) {
220        String[] result = new String[2];
221        if (key == null)
222            return result;
223
224        result[0] = key;
225        int d = key.indexOf(DELIM_DEFAULT);
226        if (d != -1) {
227            result[0] = key.substring(0, d);
228            result[1] = key.substring(d + DELIM_DEFAULT_LEN);
229        }
230        return result;
231    }
232
233    /**
234     * If <code>value</code> is "true", then <code>true</code> is returned. If
235     * <code>value</code> is "false", then <code>true</code> is returned. Otherwise,
236     * <code>default</code> is returned.
237     * <p>
238     * Case of value is unimportant.
239     */
240    public static boolean toBoolean(String value, boolean dEfault) {
241        if (value == null) {
242            return dEfault;
243        }
244
245        String trimmedVal = value.trim();
246
247        if ("true".equalsIgnoreCase(trimmedVal)) {
248            return true;
249        }
250
251        if ("false".equalsIgnoreCase(trimmedVal)) {
252            return false;
253        }
254
255        return dEfault;
256    }
257
258    /**
259     * @deprecated
260     * @since 1.3
261     */
262    public static boolean isEmpty(String str) {
263        return isNullOrEmptyOrAllSpaces(str);
264    }
265
266    /**
267     * Returns true if input str is null or empty.
268     * 
269     * @param str
270     * @return
271     */
272    public static boolean isNullOrEmpty(String str) {
273        return ((str == null) || str.trim().length() == 0);
274    }
275
276    /**
277     * isNullOrEmpty xisNullOrEmptyOrAllSpaces
278     * @param str
279     * @return
280     * @since  1.5.0
281     */
282    public static boolean isNullOrEmptyOrAllSpaces(String str) {
283        return ((str == null) || str.trim().length() == 0);
284    }
285
286
287    final public static boolean isNullOrEmpty(Object[] array) {
288        if(array == null || array.length == 0)
289                return true;
290        else
291                return false;
292    }
293
294    final public static boolean isNotEmtpy(Object[] array) {
295        return !isNullOrEmpty(array);
296    }
297}