1 8 package org.apache.avalon.excalibur.property; 9 10 import org.apache.avalon.framework.context.Context; 11 import org.apache.avalon.framework.context.ContextException; 12 import org.apache.avalon.framework.context.Resolvable; 13 14 21 public final class PropertyUtil 22 { 23 private PropertyUtil() 24 { 25 } 26 27 37 public static Object resolveProperty( final String property, 38 final Context context, 39 final boolean ignoreUndefined ) 40 throws PropertyException 41 { 42 int start = findBeginning( property, 0 ); 43 if( -1 == start ) 44 { 45 return property; 46 } 47 48 int end = findEnding( property, start ); 49 50 final int length = property.length(); 51 52 if( 0 == start && end == (length - 1) ) 53 { 54 return resolveValue( property.substring( start + 2, end ), 55 context, 56 ignoreUndefined ); 57 } 58 59 final StringBuffer sb = new StringBuffer ( length * 2 ); 60 int lastPlace = 0; 61 62 while( true ) 63 { 64 final Object value = 65 resolveValue( property.substring( start + 2, end ), 66 context, 67 ignoreUndefined ); 68 69 sb.append( property.substring( lastPlace, start ) ); 70 sb.append( value ); 71 72 lastPlace = end + 1; 73 74 start = findBeginning( property, lastPlace ); 75 if( -1 == start ) 76 { 77 break; 78 } 79 80 end = findEnding( property, start ); 81 } 82 83 sb.append( property.substring( lastPlace, length ) ); 84 85 return sb.toString(); 86 } 87 88 89 99 public static Object recursiveResolveProperty( final String property, 100 final Context context, 101 final boolean ignoreUndefined ) 102 throws PropertyException 103 { 104 int start = findBeginning( property, 0 ); 105 if( -1 == start ) 106 { 107 return property; 108 } 109 110 int end = findNestedEnding( property, start ); 111 112 final int length = property.length(); 113 114 if( 0 == start && end == (length - 1) ) 115 { 116 final String propertyName = property.substring( start + 2, end ); 117 final Object key = recursiveResolveProperty( propertyName, context, ignoreUndefined ); 118 return resolveValue( key.toString(), context, ignoreUndefined ); 119 } 120 121 final StringBuffer sb = new StringBuffer ( length * 2 ); 122 123 int lastPlace = 0; 124 125 while( true ) 126 { 127 final String propertyName = property.substring( start + 2, end ); 128 final Object key = recursiveResolveProperty( propertyName, context, ignoreUndefined ); 129 final Object value = resolveValue( key.toString(), context, ignoreUndefined ); 130 131 sb.append( property.substring( lastPlace, start ) ); 132 sb.append( value ); 133 134 lastPlace = end + 1; 135 136 start = findBeginning( property, lastPlace ); 137 if( -1 == start ) 138 { 139 break; 140 } 141 142 end = findNestedEnding( property, start ); 143 } 144 145 sb.append( property.substring( lastPlace, length ) ); 146 147 return sb.toString(); 148 } 149 150 private static int findBeginning( final String property, final int currentPosition ) 151 { 152 return property.indexOf( "${", currentPosition ); 154 } 155 156 private static int findEnding( final String property, final int currentPosition ) 157 throws PropertyException 158 { 159 final int index = property.indexOf( '}', currentPosition ); 161 if( -1 == index ) 162 { 163 throw new PropertyException( "Malformed property with mismatched }'s" ); 164 } 165 166 return index; 167 } 168 169 private static int findNestedEnding( final String property, final int currentPosition ) 170 throws PropertyException 171 { 172 final int length = property.length(); 173 final int start = currentPosition + 2; 174 175 int weight = 1; 176 for( int i = start; (weight > 0) && (i < length); i++ ) 177 { 178 final char ch = property.charAt( i ); 179 switch( ch ) 180 { 181 case '}': 182 weight--; 184 if( weight == 0 ) 185 { 186 return i; 187 } 188 break; 189 190 case '$': 191 { 192 final int next = i + 1; 194 if( next < length && '{' == property.charAt( next ) ) 195 { 196 weight++; 197 } 198 } 199 break; 200 } 201 } 202 203 throw new PropertyException( "Malformed property with mismatched }'s" ); 204 } 205 206 217 private static Object resolveValue( final String key, 218 final Context context, 219 final boolean ignoreUndefined ) 220 throws PropertyException 221 { 222 Object value = null; 223 224 try { value = context.get( key ); } 225 catch( final ContextException ce ) {} 226 227 try 228 { 229 while( null != value && value instanceof Resolvable ) 230 { 231 value = ((Resolvable)value).resolve( context ); 232 } 233 } 234 catch( final ContextException ce ) 235 { 236 throw new PropertyException( "Unable to resolve value for key " + key ); 237 } 238 239 if( null == value ) 240 { 241 if( ignoreUndefined ) return ""; 242 else 243 { 244 throw new PropertyException( "Unable to find " + key + " to expand during " + 245 "property resolution." ); 246 } 247 } 248 249 return value; 250 } 251 } 252 | Popular Tags |