blob: 656f603cf450012c4ab4f1f968f1ac193b2b0ca8 [file] [log] [blame]
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