KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > util > defaults > Defaults


1 /*
2  * Copyright 2004 Apache Software Foundation
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12  * implied.
13  *
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.avalon.util.defaults ;
19
20 import java.io.IOException JavaDoc ;
21 import java.io.InputStream JavaDoc ;
22 import java.util.ArrayList JavaDoc ;
23 import java.util.Properties JavaDoc ;
24 import java.util.Enumeration JavaDoc ;
25
26
27 /**
28  * Gets a set of default property values based on a sequence of default value
29  * search components or finders.
30  *
31  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
32  * @version $Revision: 1.5 $
33  */

34 public class Defaults extends Properties JavaDoc
35 {
36     /** single-valued property key names */
37     private final String JavaDoc [] m_singles ;
38     /** multi-valued or enumerated property key names */
39     private final String JavaDoc [] m_enumerated ;
40     /** array of finders that define the property default discovery process */
41     private final DefaultsFinder [] m_finders ;
42     
43     
44     // ------------------------------------------------------------------------
45
// C O N S T R U C T O R S
46
// ------------------------------------------------------------------------
47

48     
49     /**
50      * Creates and populates a set of properties
51      *
52      * @param a_singles single valued key names
53      * @param a_enumerated multi-valued key names
54      * @param a_finders search components used for staged discovery of defaults
55      */

56     public Defaults( String JavaDoc [] a_singles, String JavaDoc [] a_enumerated,
57                      DefaultsFinder [] a_finders )
58     {
59         m_finders = a_finders ;
60         m_singles = a_singles ;
61         m_enumerated = a_enumerated ;
62         
63         for ( int ii = 0; ii < m_finders.length; ii++ )
64         {
65             m_finders[ii].find( this ) ;
66         }
67     }
68
69     
70     // ------------------------------------------------------------------------
71
// A C C E S S O R S
72
// ------------------------------------------------------------------------
73

74     
75     /**
76      * Gets the base names of enumerated multi-valued keys. Such keys are
77      * enumerated to have multiple values by appending an index onto a key base
78      * like so: [base.key].1,[base.key].2,[base.key].3 ... [base.key].N. The
79      * returned keys are just the base key names of multi-valued properties and
80      * do not include the appended index.
81      *
82      * @return the base key names for multi-valued properties
83      */

84     public String JavaDoc[] getEnumerated()
85     {
86         return m_enumerated ;
87     }
88
89     
90     /**
91      * Gets the linear set of finders composing the search policy.
92      *
93      * @return the finders used to discover property defaults
94      */

95     public DefaultsFinder[] getFinders()
96     {
97         return m_finders ;
98     }
99
100
101     /**
102      * Gets the names of all the single valued properties.
103      *
104      * @return single valued property key names
105      */

106     public String JavaDoc[] getSingles()
107     {
108         return m_singles ;
109     }
110     
111     
112     /**
113      * Gets the default values for an enumerated key.
114      *
115      * @param a_base the base of the enumerated key
116      * @return the values of the multi-valued property
117      */

118     public String JavaDoc[] getEnumerated( String JavaDoc a_base )
119     {
120         ArrayList JavaDoc l_values = new ArrayList JavaDoc() ;
121         Enumeration JavaDoc l_list = keys() ;
122
123         while ( l_list.hasMoreElements() )
124         {
125             String JavaDoc l_key = ( String JavaDoc ) l_list.nextElement() ;
126             if ( l_key.startsWith( a_base ) )
127             {
128                 l_values.add( getProperty( l_key ) ) ;
129             }
130         }
131         return ( String JavaDoc [] ) l_values.toArray( new String JavaDoc [0] ) ;
132     }
133
134     
135     /**
136      * Utility method that gets a key's value and returns a boolean value to
137      * represent it.
138      *
139      * @param a_key the boolean property key
140      * @return true if the property is 1, true, yes or on, and false otherwise
141      */

142     public boolean getBoolean( String JavaDoc a_key )
143     {
144         String JavaDoc l_value = getProperty( a_key ) ;
145         l_value = l_value.trim().toLowerCase() ;
146         
147         if ( l_value.equals( "1" ) ||
148              l_value.equals( "on" ) ||
149              l_value.equals( "yes" ) ||
150              l_value.equals( "true" ) )
151         {
152             return true ;
153         }
154         
155         return false ;
156     }
157     
158     
159     // ------------------------------------------------------------------------
160
// S T A T I C M E T H O D S
161
// ------------------------------------------------------------------------
162

163     
164     /**
165      * Merges a set of properties from source Properties into a Defaults
166      * instance. Does not allow null overrides.
167      *
168      * @param a_defaults the defaults to populate on discovery
169      * @param a_sources the sources to search
170      * @param a_haltOnDiscovery true to halt on first find or false to continue
171      * to last find
172      */

173     public static void discover( Defaults a_defaults, Properties JavaDoc [] a_sources,
174                                  boolean a_haltOnDiscovery )
175     {
176         if ( null == a_sources || null == a_defaults )
177         {
178             return ;
179         }
180         
181         /*
182          * H A N D L E S I N G L E V A L U E D K E Y S
183          */

184         String JavaDoc [] l_keys = a_defaults.getSingles() ;
185         for ( int ii = 0; ii < l_keys.length; ii++ )
186         {
187             String JavaDoc l_key = l_keys[ii] ;
188             String JavaDoc l_value = discover( l_key, a_sources, a_haltOnDiscovery ) ;
189             
190             if ( l_value != null )
191             {
192                 a_defaults.setProperty( l_key, l_value ) ;
193             }
194         }
195         
196         /*
197          * H A N D L E M U L T I - V A L U E D K E Y S
198          */

199         l_keys = a_defaults.getEnumerated() ;
200         for ( int ii = 0; ii < l_keys.length; ii++ )
201         {
202             String JavaDoc l_base = l_keys[ii] ;
203             
204             for ( int jj = 0; jj < a_sources.length; jj++ )
205             {
206                 Enumeration JavaDoc l_list = a_sources[jj].propertyNames() ;
207                 
208                 while ( l_list.hasMoreElements() )
209                 {
210                     String JavaDoc l_key = ( String JavaDoc ) l_list.nextElement() ;
211                     if ( ! l_key.startsWith( l_base ) )
212                     {
213                         continue ;
214                     }
215                     
216                     String JavaDoc l_value =
217                         discover( l_key, a_sources, a_haltOnDiscovery ) ;
218
219                     if ( l_value != null )
220                     {
221                         a_defaults.setProperty( l_key, l_value ) ;
222                     }
223                 }
224             }
225         }
226     }
227     
228     
229     /**
230      * Discovers a value within a set of Properties either halting on the first
231      * time the property is discovered or continuing on to take the last value
232      * found for the property key.
233      *
234      * @param l_key a property key
235      * @param a_sources a set of source Properties
236      * @param a_haltOnDiscovery true if we stop on finding a value, false
237      * otherwise
238      * @return the value found or null
239      */

240     public static String JavaDoc discover( String JavaDoc l_key, Properties JavaDoc [] a_sources,
241                                    boolean a_haltOnDiscovery )
242     {
243         String JavaDoc l_retval = null ;
244         
245         for( int ii = 0; ii < a_sources.length; ii++ )
246         {
247             if ( a_sources[ii].containsKey( l_key ) )
248             {
249                 l_retval = a_sources[ii].getProperty( l_key ) ;
250                 
251                 if ( a_haltOnDiscovery )
252                 {
253                     break ;
254                 }
255             }
256         }
257         
258         return l_retval ;
259     }
260
261
262     /**
263      * Expands out a set of property key macros in the following format
264      * ${foo.bar} where foo.bar is a property key, by dereferencing the value
265      * of the key using the original source Properties and other optional
266      * Properties.
267      *
268      * If the original expanded Properties contain the value for the macro key
269      * foo.bar then dereferencing stops by using the value in the expanded
270      * Properties: the other optional Properties are NOT used at all.
271      *
272      * If the original expanded Properties do NOT contain the value for the
273      * macro key, then the optional Properties are used in order. The first of
274      * the optionals to contain the value for the macro key (foo.bar) shorts the
275      * search. Hence the first optional Properties in the array to contain a
276      * value for the macro key (foo.bar) is used to set the expanded value.
277      *
278      * If a macro cannot be expanded because it's key was not defined within the
279      * expanded Properties or one of the optional Properties then it is left as
280      * is.
281      *
282      * @param a_expanded the Properties to perform the macro expansion upon
283      * @param a_optionals null or an optional set of Properties to use for
284      * dereferencing macro keys (foo.bar)
285      */

286     public static void macroExpand( Properties JavaDoc a_expanded,
287                                     Properties JavaDoc [] a_optionals )
288     {
289         // Handle null optionals
290
if ( null == a_optionals )
291         {
292             a_optionals = new Properties JavaDoc [ 0 ] ;
293         }
294         
295         Enumeration JavaDoc l_list = a_expanded.propertyNames() ;
296         while ( l_list.hasMoreElements() )
297         {
298             String JavaDoc l_key = ( String JavaDoc ) l_list.nextElement() ;
299             String JavaDoc l_macro = a_expanded.getProperty( l_key ) ;
300             
301             int n = l_macro.indexOf( "${" );
302             if( n < 0 )
303             {
304                 continue;
305             }
306
307             int m = l_macro.indexOf( "}", n+2 );
308             if( m < 0 )
309             {
310                 continue;
311             }
312
313             final String JavaDoc symbol = l_macro.substring( n+2, m );
314             
315             if ( a_expanded.containsKey( symbol ) )
316             {
317                 final String JavaDoc value = a_expanded.getProperty( symbol );
318                 final String JavaDoc head = l_macro.substring( 0, n );
319                 final String JavaDoc tail = l_macro.substring( m+1 );
320                 final String JavaDoc resolved = head + value + tail;
321
322                 a_expanded.put( l_key, resolved ) ;
323                 continue ;
324             }
325
326             /*
327              * Check if the macro key exists within the array of optional
328              * Properties. Set expanded value to first Properties with the
329              * key and break out of the loop.
330              */

331             for ( int ii = 0; ii < a_optionals.length; ii++ )
332             {
333                 if ( a_optionals[ii].containsKey( symbol ) )
334                 {
335                     String JavaDoc value = a_optionals[ii].getProperty( symbol ) ;
336                     final String JavaDoc head = l_macro.substring( 0, n );
337                     final String JavaDoc tail = l_macro.substring( m+1 );
338                     final String JavaDoc resolved = head + value + tail;
339
340                     a_expanded.put( l_key, resolved ) ;
341                     break ;
342                 }
343             }
344         }
345     }
346
347    /**
348     * Read in a static properties resource relative to a supplied class.
349     * The implementation will attempt to locate a property file colocated
350     * with the class with the name [class].properties.
351     *
352     * @param ref a class used to establish a classloader and anchors
353     * relative path references
354     * @return the static properties
355     */

356     public static Properties JavaDoc getStaticProperties( Class JavaDoc ref ) throws IOException JavaDoc
357     {
358         final Properties JavaDoc properties = new Properties JavaDoc();
359         final String JavaDoc address = ref.toString().replace( '.','/' );
360         final String JavaDoc path = address + ".properties";
361         InputStream JavaDoc input = ref.getResourceAsStream( path );
362         if( null != input )
363         {
364             properties.load( input );
365         }
366         return properties;
367     }
368
369    /**
370     * Read in a static properties resource relative to a supplied class
371     * and path.
372     *
373     * @param ref a class used to establish a classloader and anchors
374     * relative path references
375     * @param path the resoruce address
376     * @return the static properties
377     * @exception IllegalStateException if the path is unresolvable
378     */

379     public static Properties JavaDoc getStaticProperties( Class JavaDoc ref, String JavaDoc path ) throws IOException JavaDoc
380     {
381         Properties JavaDoc bootstrap = new Properties JavaDoc();
382         InputStream JavaDoc input = ref.getResourceAsStream( path );
383         if( input == null )
384         {
385             final String JavaDoc error =
386               "Internal error, unable to locate enbedded resource: "
387               + path
388               + " from the resource: "
389               + ref.getProtectionDomain().getCodeSource().getLocation();
390             throw new IllegalStateException JavaDoc( error );
391         }
392         bootstrap.load( input );
393         return bootstrap;
394     }
395 }
396
397
398
Popular Tags