| package org.apache.jcs.config; |
| |
| |
| /* |
| * Copyright 2001-2004 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License") |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| import java.util.Properties; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| |
| /** |
| * This class is based on the log4j class |
| * org.apache.log4j.helpers.OptionConverter that was made by Ceki |
| * Gülcü Simon Kitching; Avy Sharell (sharell@online.fr) Anders |
| * Kristensen Matthieu Verbert (mve@zurich.ibm.com) A convenience class to |
| * convert property values to specific types. |
| * |
| */ |
| public class OptionConverter |
| { |
| private final static Log log = |
| LogFactory.getLog( OptionConverter.class ); |
| |
| static String DELIM_START = "${"; |
| static char DELIM_STOP = '}'; |
| static int DELIM_START_LEN = 2; |
| static int DELIM_STOP_LEN = 1; |
| |
| static StringBuffer sbuf = new StringBuffer(); |
| |
| /** OptionConverter is a static class. */ |
| private OptionConverter() { } |
| |
| |
| /** Description of the Method */ |
| public static String[] concatanateArrays( String[] l, String[] r ) |
| { |
| int len = l.length + r.length; |
| String[] a = new String[len]; |
| |
| System.arraycopy( l, 0, a, 0, l.length ); |
| System.arraycopy( r, 0, a, l.length, r.length ); |
| |
| return a; |
| } |
| |
| |
| /** Description of the Method */ |
| public static String convertSpecialChars( String s ) |
| { |
| char c; |
| int len = s.length(); |
| StringBuffer sbuf = new StringBuffer( len ); |
| |
| int i = 0; |
| while ( i < len ) |
| { |
| c = s.charAt( i++ ); |
| if ( c == '\\' ) |
| { |
| c = s.charAt( i++ ); |
| if ( c == 'n' ) |
| { |
| c = '\n'; |
| } |
| else if ( c == 'r' ) |
| { |
| c = '\r'; |
| } |
| else if ( c == 't' ) |
| { |
| c = '\t'; |
| } |
| else if ( c == 'f' ) |
| { |
| c = '\f'; |
| } |
| else if ( c == '\b' ) |
| { |
| c = '\b'; |
| } |
| else if ( c == '\"' ) |
| { |
| c = '\"'; |
| } |
| else if ( c == '\'' ) |
| { |
| c = '\''; |
| } |
| else if ( c == '\\' ) |
| { |
| c = '\\'; |
| } |
| } |
| sbuf.append( c ); |
| } |
| return sbuf.toString(); |
| } |
| |
| |
| /** |
| * Very similar to <code>System.getProperty</code> except that the {@link |
| * SecurityException} is hidden. |
| * |
| * @param key The key to search for. |
| * @param def The default value to return. |
| * @return the string value of the system property, or the default value if |
| * there is no property with that key. |
| * @since 1.1 |
| */ |
| |
| public static String getSystemProperty( String key, String def ) |
| { |
| try |
| { |
| return System.getProperty( key, def ); |
| } |
| catch ( Throwable e ) |
| { |
| // MS-Java throws com.ms.security.SecurityExceptionEx |
| log.debug( "Was not allowed to read system property \"" + key + "\"." ); |
| return def; |
| } |
| } |
| |
| |
| /** Description of the Method */ |
| public static Object instantiateByKey( Properties props, String key, Class superClass, |
| Object defaultValue ) |
| { |
| |
| // Get the value of the property in string form |
| String className = findAndSubst( key, props ); |
| if ( className == null ) |
| { |
| log.warn( "Could not find value for key " + key ); |
| return defaultValue; |
| } |
| // Trim className to avoid trailing spaces that cause problems. |
| return OptionConverter.instantiateByClassName( className.trim(), superClass, |
| defaultValue ); |
| } |
| |
| |
| /** |
| * If <code>value</code> is "true", then <code>true</code> is returned. If |
| * <code>value</code> is "false", then <code>true</code> is returned. |
| * Otherwise, <code>default</code> is returned. <p> |
| * |
| * Case of value is unimportant. |
| */ |
| |
| public static boolean toBoolean( String value, boolean dEfault ) |
| { |
| if ( value == null ) |
| { |
| return dEfault; |
| } |
| String trimmedVal = value.trim(); |
| if ( "true".equalsIgnoreCase( trimmedVal ) ) |
| { |
| return true; |
| } |
| if ( "false".equalsIgnoreCase( trimmedVal ) ) |
| { |
| return false; |
| } |
| return dEfault; |
| } |
| |
| |
| /** Description of the Method */ |
| public static int toInt( String value, int dEfault ) |
| { |
| if ( value != null ) |
| { |
| String s = value.trim(); |
| try |
| { |
| return Integer.valueOf( s ).intValue(); |
| } |
| catch ( NumberFormatException e ) |
| { |
| log.error( "[" + s + "] is not in proper int form." ); |
| e.printStackTrace(); |
| } |
| } |
| return dEfault; |
| } |
| |
| |
| /** Description of the Method */ |
| public static long toFileSize( String value, long dEfault ) |
| { |
| if ( value == null ) |
| { |
| return dEfault; |
| } |
| |
| String s = value.trim().toUpperCase(); |
| long multiplier = 1; |
| int index; |
| |
| if ( ( index = s.indexOf( "KB" ) ) != -1 ) |
| { |
| multiplier = 1024; |
| s = s.substring( 0, index ); |
| } |
| else if ( ( index = s.indexOf( "MB" ) ) != -1 ) |
| { |
| multiplier = 1024 * 1024; |
| s = s.substring( 0, index ); |
| } |
| else if ( ( index = s.indexOf( "GB" ) ) != -1 ) |
| { |
| multiplier = 1024 * 1024 * 1024; |
| s = s.substring( 0, index ); |
| } |
| if ( s != null ) |
| { |
| try |
| { |
| return Long.valueOf( s ).longValue() * multiplier; |
| } |
| catch ( NumberFormatException e ) |
| { |
| log.error( "[" + s + "] is not in proper int form" ); |
| log.error( "[" + value + "] not in expected format", e ); |
| } |
| } |
| return dEfault; |
| } |
| |
| |
| /** |
| * Find the value corresponding to <code>key</code> in <code>props</code>. |
| * Then perform variable substitution on the found value. |
| */ |
| |
| public static String findAndSubst( String key, Properties props ) |
| { |
| String value = props.getProperty( key ); |
| if ( value == null ) |
| { |
| return null; |
| } |
| |
| try |
| { |
| return substVars( value, props ); |
| } |
| catch ( IllegalArgumentException e ) |
| { |
| log.error( "Bad option value [" + value + "]", e ); |
| return value; |
| } |
| } |
| |
| |
| /** |
| * Instantiate an object given a class name. Check that the <code>className</code> |
| * is a subclass of <code>superClass</code>. If that test fails or the |
| * object could not be instantiated, then <code>defaultValue</code> is |
| * returned. |
| * |
| * @param className The fully qualified class name of the object to |
| * instantiate. |
| * @param superClass The class to which the new object should belong. |
| * @param defaultValue The object to return in case of non-fulfillment |
| */ |
| |
| public static Object instantiateByClassName( String className, Class superClass, |
| Object defaultValue ) |
| { |
| if ( className != null ) |
| { |
| try |
| { |
| Class classObj = Class.forName( className ); |
| if ( !superClass.isAssignableFrom( classObj ) ) |
| { |
| log.error( "A \"" + className + "\" object is not assignable to a \"" + |
| superClass.getName() + "\" variable." ); |
| return defaultValue; |
| } |
| return classObj.newInstance(); |
| } |
| catch ( Exception e ) |
| { |
| log.error( "Could not instantiate class [" + className + "]", e ); |
| } |
| } |
| return defaultValue; |
| } |
| |
| /** |
| * Perform variable substitution in string <code>val</code> from the values |
| * of keys found in the system propeties. <p> |
| * |
| * The variable substitution delimeters are <b>${</b> and <b>}</b> . <p> |
| * |
| * For example, if the System properties contains "key=value", then the call |
| * <pre> |
| *String s = OptionConverter.substituteVars("Value of key is ${key}."); |
| *</pre> will set the variable <code>s</code> to "Value of key is value.". |
| * <p> |
| * |
| * If no value could be found for the specified key, then the <code>props</code> |
| * parameter is searched, if the value could not be found there, then |
| * substitution defaults to the empty string. <p> |
| * |
| * For example, if system propeties contains no value for the key |
| * "inexistentKey", then the call <pre> |
| *String s = OptionConverter.subsVars("Value of inexistentKey is [${inexistentKey}]"); |
| *</pre> will set <code>s</code> to "Value of inexistentKey is []" <p> |
| * |
| * An {@link java.lang.IllegalArgumentException} is thrown if <code>val</code> |
| * contains a start delimeter "${" which is not balanced by a stop delimeter |
| * "}". </p> <p> |
| * |
| * <b>Author</b> Avy Sharell</a> </p> |
| * |
| * @param val The string on which variable substitution is performed. |
| * @throws IllegalArgumentException if <code>val</code> is malformed. |
| */ |
| |
| public static String substVars( String val, Properties props ) |
| throws |
| IllegalArgumentException |
| { |
| sbuf.setLength( 0 ); |
| |
| int i = 0; |
| int j; |
| int k; |
| |
| while ( true ) |
| { |
| j = val.indexOf( DELIM_START, i ); |
| if ( j == -1 ) |
| { |
| if ( i == 0 ) |
| { |
| return val; |
| } |
| sbuf.append( val.substring( i, val.length() ) ); |
| return sbuf.toString(); |
| } |
| sbuf.append( val.substring( i, j ) ); |
| k = val.indexOf( DELIM_STOP, j ); |
| if ( k == -1 ) |
| { |
| throw new IllegalArgumentException( '"' + val + |
| "\" has no closing brace. Opening brace at position " + j |
| + '.' ); |
| } |
| j += DELIM_START_LEN; |
| String key = val.substring( j, k ); |
| // first try in System properties |
| String replacement = getSystemProperty( key, null ); |
| // then try props parameter |
| if ( replacement == null && props != null ) |
| { |
| replacement = props.getProperty( key ); |
| } |
| |
| if ( replacement != null ) |
| { |
| sbuf.append( replacement ); |
| } |
| i = k + DELIM_STOP_LEN; |
| } |
| } |
| |
| } |
| // end class |