1 8 package org.apache.avalon.phoenix.components.classloader; 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 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 Exception 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 98 public static Object recursiveResolveProperty( final String property, 99 final Context context, 100 final boolean ignoreUndefined ) 101 throws Exception 102 { 103 int start = findBeginning( property, 0 ); 104 if( -1 == start ) 105 { 106 return property; 107 } 108 109 int end = findNestedEnding( property, start ); 110 111 final int length = property.length(); 112 113 if( 0 == start && end == (length - 1) ) 114 { 115 final String propertyName = property.substring( start + 2, end ); 116 final Object key = recursiveResolveProperty( propertyName, context, ignoreUndefined ); 117 return resolveValue( key.toString(), context, ignoreUndefined ); 118 } 119 120 final StringBuffer sb = new StringBuffer ( length * 2 ); 121 122 int lastPlace = 0; 123 124 while( true ) 125 { 126 final String propertyName = property.substring( start + 2, end ); 127 final Object key = recursiveResolveProperty( propertyName, context, ignoreUndefined ); 128 final Object value = resolveValue( key.toString(), context, ignoreUndefined ); 129 130 sb.append( property.substring( lastPlace, start ) ); 131 sb.append( value ); 132 133 lastPlace = end + 1; 134 135 start = findBeginning( property, lastPlace ); 136 if( -1 == start ) 137 { 138 break; 139 } 140 141 end = findNestedEnding( property, start ); 142 } 143 144 sb.append( property.substring( lastPlace, length ) ); 145 146 return sb.toString(); 147 } 148 149 private static int findBeginning( final String property, final int currentPosition ) 150 { 151 return property.indexOf( "${", currentPosition ); 153 } 154 155 private static int findEnding( final String property, final int currentPosition ) 156 throws Exception 157 { 158 final int index = property.indexOf( '}', currentPosition ); 160 if( -1 == index ) 161 { 162 throw new Exception ( "Malformed property with mismatched }'s" ); 163 } 164 165 return index; 166 } 167 168 private static int findNestedEnding( final String property, final int currentPosition ) 169 throws Exception 170 { 171 final int length = property.length(); 172 final int start = currentPosition + 2; 173 174 int weight = 1; 175 for( int i = start; (weight > 0) && (i < length); i++ ) 176 { 177 final char ch = property.charAt( i ); 178 switch( ch ) 179 { 180 case '}': 181 weight--; 183 if( weight == 0 ) 184 { 185 return i; 186 } 187 break; 188 189 case '$': 190 { 191 final int next = i + 1; 193 if( next < length && '{' == property.charAt( next ) ) 194 { 195 weight++; 196 } 197 } 198 break; 199 } 200 } 201 202 throw new Exception ( "Malformed property with mismatched }'s" ); 203 } 204 205 216 private static Object resolveValue( final String key, 217 final Context context, 218 final boolean ignoreUndefined ) 219 throws Exception 220 { 221 Object value = null; 222 223 try 224 { 225 value = context.get( key ); 226 } 227 catch( final ContextException ce ) 228 { 229 } 231 232 try 233 { 234 while( null != value && value instanceof Resolvable ) 235 { 236 value = ((Resolvable)value).resolve( context ); 237 } 238 } 239 catch( final ContextException ce ) 240 { 241 throw new Exception ( "Unable to resolve value for key " + key ); 242 } 243 244 if( null == value ) 245 { 246 if( ignoreUndefined ) 247 { 248 return ""; 249 } 250 else 251 { 252 throw new Exception ( "Unable to find " + key + " to expand during " 253 + "property resolution." ); 254 } 255 } 256 257 return value; 258 } 259 } 260 | Popular Tags |