KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > excalibur > property > PropertyUtil


1 /*
2  * Copyright (C) The Apache Software Foundation. All rights reserved.
3  *
4  * This software is published under the terms of the Apache Software License
5  * version 1.1, a copy of which has been included with this distribution in
6  * the LICENSE.txt file.
7  */

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 /**
15  * This provides utility methods for properties.
16  *
17  * @author <a HREF="mailto:peter@apache.org">Peter Donald</a>
18  * @version CVS $Revision: 1.5 $ $Date: 2001/12/11 09:53:32 $
19  * @since 4.0
20  */

21 public final class PropertyUtil
22 {
23     private PropertyUtil()
24     {
25     }
26
27     /**
28      * Resolve a string property. This evaluates all property
29      * substitutions based on specified context.
30      *
31      * @param property the property to resolve
32      * @param context the context in which to resolve property
33      * @param ignoreUndefined if false will throw an PropertyException if property is not found
34      * @return the reolved property
35      * @exception PropertyException if an error occurs
36      */

37     public static Object JavaDoc resolveProperty( final String JavaDoc 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 JavaDoc sb = new StringBuffer JavaDoc( length * 2 );
60         int lastPlace = 0;
61
62         while( true )
63         {
64             final Object JavaDoc 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     /**
90      * Resolve a string property. This recursively evaluates all property
91      * substitutions based on specified context.
92      *
93      * @param property the property to resolve
94      * @param context the context in which to resolve property
95      * @param ignoreUndefined if false will throw an PropertyException if property is not found
96      * @return the reolved property
97      * @exception PropertyException if an error occurs
98      */

99     public static Object JavaDoc recursiveResolveProperty( final String JavaDoc 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 JavaDoc propertyName = property.substring( start + 2, end );
117             final Object JavaDoc key = recursiveResolveProperty( propertyName, context, ignoreUndefined );
118             return resolveValue( key.toString(), context, ignoreUndefined );
119         }
120
121         final StringBuffer JavaDoc sb = new StringBuffer JavaDoc( length * 2 );
122
123         int lastPlace = 0;
124
125         while( true )
126         {
127             final String JavaDoc propertyName = property.substring( start + 2, end );
128             final Object JavaDoc key = recursiveResolveProperty( propertyName, context, ignoreUndefined );
129             final Object JavaDoc 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 JavaDoc property, final int currentPosition )
151     {
152         //TODO: Check if it is commented out
153
return property.indexOf( "${", currentPosition );
154     }
155
156     private static int findEnding( final String JavaDoc property, final int currentPosition )
157         throws PropertyException
158     {
159         //TODO: Check if it is commented out
160
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 JavaDoc 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                 //TODO: Check if it is commented out
183
weight--;
184                 if( weight == 0 )
185                 {
186                     return i;
187                 }
188                 break;
189
190             case '$':
191                 {
192                     //TODO: Check if it is commented out
193
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     /**
207      * Retrieve a value from the specified context using the specified key.
208      * If there is no such value and ignoreUndefined is not false then a
209      * PropertyException is generated.
210      *
211      * @param key the key of value in context
212      * @param context the Context
213      * @param ignoreUndefined true if undefined variables are ignored
214      * @return the object retrieved from context
215      * @exception PropertyException if an error occurs
216      */

217     private static Object JavaDoc resolveValue( final String JavaDoc key,
218                                         final Context context,
219                                         final boolean ignoreUndefined )
220         throws PropertyException
221     {
222         Object JavaDoc 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