Browse Source

Add a PropertyUtil class that doesn't need avalons Context

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271471 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Donald 23 years ago
parent
commit
1b7d8d44fd
2 changed files with 282 additions and 0 deletions
  1. +37
    -0
      proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/PropertyException.java
  2. +245
    -0
      proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/PropertyUtil.java

+ 37
- 0
proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/PropertyException.java View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.configurer;

/**
* Exception thrown when evaluating a property.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public class PropertyException
extends Exception
{
/**
* Basic constructor for exception that does not specify a message
*/
public PropertyException()
{
this( "" );
}

/**
* Basic constructor with a message
*
* @param message the message
*/
public PropertyException( final String message )
{
super( message );
}
}


+ 245
- 0
proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/PropertyUtil.java View File

@@ -0,0 +1,245 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.configurer;

import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;

/**
* Utility class to evaluate propertys.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public final class PropertyUtil
{
private final static Resources REZ =
ResourceManager.getPackageResources( PropertyUtil.class );

private PropertyUtil()
{
}

/**
* Resolve a string property. This evaluates all property
* substitutions based on specified context.
*
* @param property the property to resolve
* @param context the context in which to resolve property
* @param ignoreUndefined if false will throw an PropertyException if property is not found
* @return the reolved property
* @exception PropertyException if an error occurs
*/
public static Object resolveProperty( final String property,
final Context context,
final boolean ignoreUndefined )
throws PropertyException
{
int start = findBeginning( property, 0 );
if( -1 == start )
{
return property;
}

int end = findEnding( property, start );

final int length = property.length();

if( 0 == start && end == ( length - 1 ) )
{
return resolveValue( property.substring( start + 2, end ),
context,
ignoreUndefined );
}

final StringBuffer sb = new StringBuffer( length * 2 );
int lastPlace = 0;

while( true )
{
final Object value =
resolveValue( property.substring( start + 2, end ),
context,
ignoreUndefined );

sb.append( property.substring( lastPlace, start ) );
sb.append( value );

lastPlace = end + 1;

start = findBeginning( property, lastPlace );
if( -1 == start )
{
break;
}

end = findEnding( property, start );
}

sb.append( property.substring( lastPlace, length ) );

return sb.toString();
}

/**
* Resolve a string property. This recursively evaluates all property
* substitutions based on specified context.
*
* @param property the property to resolve
* @param context the context in which to resolve property
* @param ignoreUndefined if false will throw an PropertyException if property is not found
* @return the reolved property
* @exception PropertyException if an error occurs
*/
public static Object recursiveResolveProperty( final String property,
final Context context,
final boolean ignoreUndefined )
throws PropertyException
{
int start = findBeginning( property, 0 );
if( -1 == start )
{
return property;
}

int end = findNestedEnding( property, start );

final int length = property.length();

if( 0 == start && end == ( length - 1 ) )
{
final String propertyName = property.substring( start + 2, end );
final Object key = recursiveResolveProperty( propertyName, context, ignoreUndefined );
return resolveValue( key.toString(), context, ignoreUndefined );
}

final StringBuffer sb = new StringBuffer( length * 2 );

int lastPlace = 0;

while( true )
{
final String propertyName = property.substring( start + 2, end );
final Object key = recursiveResolveProperty( propertyName, context, ignoreUndefined );
final Object value = resolveValue( key.toString(), context, ignoreUndefined );

sb.append( property.substring( lastPlace, start ) );
sb.append( value );

lastPlace = end + 1;

start = findBeginning( property, lastPlace );
if( -1 == start )
{
break;
}

end = findNestedEnding( property, start );
}

sb.append( property.substring( lastPlace, length ) );

return sb.toString();
}

private static int findBeginning( final String property, final int currentPosition )
{
//TODO: Check if it is commented out
return property.indexOf( "${", currentPosition );
}

private static int findEnding( final String property, final int currentPosition )
throws PropertyException
{
//TODO: Check if it is commented out
final int index = property.indexOf( '}', currentPosition );
if( -1 == index )
{
final String message = REZ.getString( "prop.mismatched-braces.error" );
throw new PropertyException( message );
}

return index;
}

private static int findNestedEnding( final String property, final int currentPosition )
throws PropertyException
{
final int length = property.length();
final int start = currentPosition + 2;

int weight = 1;
for( int i = start; ( weight > 0 ) && ( i < length ); i++ )
{
final char ch = property.charAt( i );
switch( ch )
{
case '}':
//TODO: Check if it is commented out
weight--;
if( weight == 0 )
{
return i;
}
break;

case '$':
{
//TODO: Check if it is commented out
final int next = i + 1;
if( next < length && '{' == property.charAt( next ) )
{
weight++;
}
}
break;
}
}

final String message = REZ.getString( "prop.mismatched-braces.error" );
throw new PropertyException( message );
}

/**
* Retrieve a value from the specified context using the specified key.
* If there is no such value and ignoreUndefined is not false then a
* PropertyException is generated.
*
* @param key the key of value in context
* @param context the Context
* @param ignoreUndefined true if undefined variables are ignored
* @return the object retrieved from context
* @exception PropertyException if an error occurs
*/
private static Object resolveValue( final String key,
final Context context,
final boolean ignoreUndefined )
throws PropertyException
{
try
{
return context.get( key );
}
catch( final ContextException ce )
{
if( ignoreUndefined )
{
return "";
}
else
{
final String message =
REZ.getString( "prop.missing-value.error", key );
throw new PropertyException( message );
}
}
}
}


Loading…
Cancel
Save