KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > velocity > runtime > configuration > Configuration


1 package org.apache.velocity.runtime.configuration;
2
3 /*
4  * Copyright (c) 2001 The Java Apache Project. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. All advertising materials mentioning features or use of this
19  * software must display the following acknowledgment:
20  * "This product includes software developed by the Java Apache
21  * Project for use in the Apache JServ servlet engine project
22  * <http://java.apache.org/>."
23  *
24  * 4. The names "Apache JServ", "Apache JServ Servlet Engine", "Turbine",
25  * "Apache Turbine", "Turbine Project", "Apache Turbine Project" and
26  * "Java Apache Project" must not be used to endorse or promote products
27  * derived from this software without prior written permission.
28  *
29  * 5. Products derived from this software may not be called "Apache JServ"
30  * nor may "Apache" nor "Apache JServ" appear in their names without
31  * prior written permission of the Java Apache Project.
32  *
33  * 6. Redistributions of any form whatsoever must retain the following
34  * acknowledgment:
35  * "This product includes software developed by the Java Apache
36  * Project for use in the Apache JServ servlet engine project
37  * <http://java.apache.org/>."
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  *
52  * This software consists of voluntary contributions made by many
53  * individuals on behalf of the Java Apache Group. For more information
54  * on the Java Apache Project and the Apache JServ Servlet Engine project,
55  * please see <http://java.apache.org/>.
56  *
57  */

58
59 import java.io.IOException JavaDoc;
60 import java.io.File JavaDoc;
61 import java.io.FileInputStream JavaDoc;
62 import java.io.InputStream JavaDoc;
63 import java.io.InputStreamReader JavaDoc;
64 import java.io.LineNumberReader JavaDoc;
65 import java.io.OutputStream JavaDoc;
66 import java.io.PrintWriter JavaDoc;
67 import java.io.Reader JavaDoc;
68
69 import java.util.ArrayList JavaDoc;
70 import java.util.Enumeration JavaDoc;
71 import java.util.Hashtable JavaDoc;
72 import java.util.Iterator JavaDoc;
73 import java.util.NoSuchElementException JavaDoc;
74 import java.util.Properties JavaDoc;
75 import java.util.StringTokenizer JavaDoc;
76 import java.util.Vector JavaDoc;
77
78 import org.apache.commons.collections.ExtendedProperties;
79
80 /**
81  * This class extends normal Java properties by adding the possibility
82  * to use the same key many times concatenating the value strings
83  * instead of overwriting them.
84  *
85  * <p>The Extended Properties syntax is explained here:
86  *
87  * <ul>
88  * <li>
89  * Each property has the syntax <code>key = value</code>
90  * </li>
91  * <li>
92  * The <i>key</i> may use any character but the equal sign '='.
93  * </li>
94  * <li>
95  * <i>value</i> may be separated on different lines if a backslash
96  * is placed at the end of the line that continues below.
97  * </li>
98  * <li>
99  * If <i>value</i> is a list of strings, each token is separated
100  * by a comma ','.
101  * </li>
102  * <li>
103  * Commas in each token are escaped placing a backslash right before
104  * the comma.
105  * </li>
106  * <li>
107  * If a <i>key</i> is used more than once, the values are appended
108  * like if they were on the same line separated with commas.
109  * </li>
110  * <li>
111  * Blank lines and lines starting with character '#' are skipped.
112  * </li>
113  * <li>
114  * If a property is named "include" (or whatever is defined by
115  * setInclude() and getInclude() and the value of that property is
116  * the full path to a file on disk, that file will be included into
117  * the ConfigurationsRepository. You can also pull in files relative
118  * to the parent configuration file. So if you have something
119  * like the following:
120  *
121  * include = additional.properties
122  *
123  * Then "additional.properties" is expected to be in the same
124  * directory as the parent configuration file.
125  *
126  * Duplicate name values will be replaced, so be careful.
127  *
128  * </li>
129  * </ul>
130  *
131  * <p>Here is an example of a valid extended properties file:
132  *
133  * <p><pre>
134  * # lines starting with # are comments
135  *
136  * # This is the simplest property
137  * key = value
138  *
139  * # A long property may be separated on multiple lines
140  * longvalue = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
141  * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
142  *
143  * # This is a property with many tokens
144  * tokens_on_a_line = first token, second token
145  *
146  * # This sequence generates exactly the same result
147  * tokens_on_multiple_lines = first token
148  * tokens_on_multiple_lines = second token
149  *
150  * # commas may be escaped in tokens
151  * commas.excaped = Hi\, what'up?
152  * </pre>
153  *
154  * <p><b>NOTE</b>: this class has <b>not</b> been written for
155  * performance nor low memory usage. In fact, it's way slower than it
156  * could be and generates too much memory garbage. But since
157  * performance is not an issue during intialization (and there is not
158  * much time to improve it), I wrote it this way. If you don't like
159  * it, go ahead and tune it up!
160  *
161  *
162  * @author <a HREF="mailto:stefano@apache.org">Stefano Mazzocchi</a>
163  * @author <a HREF="mailto:jon@latchkey.com">Jon S. Stevens</a>
164  * @author <a HREF="mailto:daveb@miceda-data">Dave Bryson</a>
165  * @author <a HREF="mailto:jvanzyl@apache.org">Jason van Zyl</a>
166  * @author <a HREF="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
167  * @author <a HREF="mailto:leon@opticode.co.za">Leon Messerschmidt</a>
168  * @author <a HREF="mailto:kjohnson@transparent.com>Kent Johnson</a>
169  * @version $Id: Configuration.java,v 1.34 2003/05/04 17:14:37 geirm Exp $
170  *
171  * @deprecated As of version 1.1, please use ExtendedProperties from
172  * the Jakarta Commons Collections component.
173  */

174 public class Configuration extends Hashtable JavaDoc
175 {
176     // $$$ GMJ : remove post version 1.1
177
// intended to help deprecate this class w/o having to modify
178
// the jakarta commons collections class which contains
179
// extended properties. We need this when someone wants to
180
// configure velocity w/ a Configuration : the strategy is simply
181
// to shadow the Configuration with the EP
182
private ExtendedProperties deprecationCrutch = new ExtendedProperties();
183
184
185     /**
186      * Default configurations repository.
187      */

188     private Configuration defaults;
189
190     /**
191      * The file connected to this repository (holding comments and
192      * such).
193      *
194      * @serial
195      */

196     protected String JavaDoc file;
197
198     /**
199      * Base path of the configuration file used to create
200      * this Configuration object.
201      */

202     protected String JavaDoc basePath;
203
204     /**
205      * File separator.
206      */

207     protected String JavaDoc fileSeparator = System.getProperty("file.separator");
208
209     /**
210      * Has this configuration been intialized.
211      */

212     protected boolean isInitialized = false;
213
214     /**
215      * This is the name of the property that can point to other
216      * properties file for including other properties files.
217      */

218     protected static String JavaDoc include = "include";
219
220     /**
221      * These are the keys in the order they listed
222      * in the configuration file. This is useful when
223      * you wish to perform operations with configuration
224      * information in a particular order.
225      */

226     protected ArrayList JavaDoc keysAsListed = new ArrayList JavaDoc();
227
228     /**
229      * This class is used to read properties lines. These lines do
230      * not terminate with new-line chars but rather when there is no
231      * backslash sign a the end of the line. This is used to
232      * concatenate multiple lines for readability.
233      */

234     class PropertiesReader extends LineNumberReader JavaDoc
235     {
236         /**
237          * Constructor.
238          *
239          * @param reader A Reader.
240          */

241         public PropertiesReader(Reader JavaDoc reader)
242         {
243             super(reader);
244         }
245
246         /**
247          * Read a property.
248          *
249          * @return A String.
250          * @exception IOException.
251          */

252         public String JavaDoc readProperty() throws IOException JavaDoc
253         {
254             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
255
256             try
257             {
258                 while (true)
259                 {
260                     String JavaDoc line = readLine().trim();
261                     if ((line.length() != 0) && (line.charAt(0) != '#'))
262                     {
263                         if (line.endsWith("\\"))
264                         {
265                             line = line.substring(0, line.length() - 1);
266                             buffer.append(line);
267                         }
268                         else
269                         {
270                             buffer.append(line);
271                             break;
272                         }
273                     }
274                 }
275             }
276             catch (NullPointerException JavaDoc e)
277             {
278                 return null;
279             }
280
281             return buffer.toString();
282         }
283     }
284
285     /**
286      * This class divides into tokens a property value. Token
287      * separator is "," but commas into the property value are escaped
288      * using the backslash in front.
289      */

290     class PropertiesTokenizer extends StringTokenizer JavaDoc
291     {
292         /**
293          * The property delimiter used while parsing (a comma).
294          */

295         static final String JavaDoc DELIMITER = ",";
296
297         /**
298          * Constructor.
299          *
300          * @param string A String.
301          */

302         public PropertiesTokenizer(String JavaDoc string)
303         {
304             super(string, DELIMITER);
305         }
306
307         /**
308          * Check whether the object has more tokens.
309          *
310          * @return True if the object has more tokens.
311          */

312         public boolean hasMoreTokens()
313         {
314             return super.hasMoreTokens();
315         }
316
317         /**
318          * Get next token.
319          *
320          * @return A String.
321          */

322         public String JavaDoc nextToken()
323         {
324             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
325
326             while (hasMoreTokens())
327             {
328                 String JavaDoc token = super.nextToken();
329                 if (token.endsWith("\\"))
330                 {
331                     buffer.append(token.substring(0, token.length() - 1));
332                     buffer.append(DELIMITER);
333                 }
334                 else
335                 {
336                     buffer.append(token);
337                     break;
338                 }
339             }
340
341             return buffer.toString().trim();
342         }
343     }
344
345     /**
346      * Creates an empty extended properties object.
347      */

348     public Configuration ()
349     {
350         super();
351     }
352
353     /**
354      * Creates and loads the extended properties from the specified
355      * file.
356      *
357      * @param file A String.
358      * @exception IOException.
359      */

360     public Configuration (String JavaDoc file) throws IOException JavaDoc
361     {
362         this(file,null);
363     }
364
365     /**
366      * Creates and loads the extended properties from the specified
367      * file.
368      *
369      * @param file A String.
370      * @exception IOException.
371      */

372     public Configuration (String JavaDoc file, String JavaDoc defaultFile)
373         throws IOException JavaDoc
374     {
375         this.file = file;
376         
377         basePath = new File JavaDoc(file).getAbsolutePath();
378         basePath = basePath.substring(0, basePath.lastIndexOf(fileSeparator) + 1);
379         
380         this.load(new FileInputStream JavaDoc(file));
381         
382         if (defaultFile != null)
383         {
384             defaults = new Configuration(defaultFile);
385         }
386     }
387
388     /**
389      * Private initializer method that sets up the generic
390      * resources.
391      *
392      * @exception IOException, if there was an I/O problem.
393      */

394     private void init( Configuration exp ) throws IOException JavaDoc
395     {
396         isInitialized = true;
397     }
398     
399     /**
400      * Indicate to client code whether property
401      * resources have been initialized or not.
402      */

403     public boolean isInitialized()
404     {
405         return isInitialized;
406     }
407
408     /**
409      * Gets the property value for including other properties files.
410      * By default it is "include".
411      *
412      * @return A String.
413      */

414     public String JavaDoc getInclude()
415     {
416         return Configuration.include;
417     }
418
419     /**
420      * Sets the property value for including other properties files.
421      * By default it is "include".
422      *
423      * @param inc A String.
424      */

425     public void setInclude(String JavaDoc inc)
426     {
427         Configuration.include = inc;
428     }
429
430     /**
431      * Load the properties from the given input stream.
432      *
433      * @param input An InputStream.
434      * @exception IOException.
435      */

436     public synchronized void load(InputStream JavaDoc input)
437         throws IOException JavaDoc
438     {
439         PropertiesReader reader =
440             new PropertiesReader(new InputStreamReader JavaDoc(input));
441
442         try
443         {
444             while (true)
445             {
446                 String JavaDoc line = reader.readProperty();
447                 int equalSign = line.indexOf('=');
448
449                 if (equalSign > 0)
450                 {
451                     String JavaDoc key = line.substring(0, equalSign).trim();
452                     String JavaDoc value = line.substring(equalSign + 1).trim();
453
454                     /*
455                      * Configure produces lines like this ... just
456                      * ignore them.
457                      */

458                     if ("".equals(value))
459                         continue;
460
461                     if (getInclude() != null &&
462                         key.equalsIgnoreCase(getInclude()))
463                     {
464                         /*
465                          * Recursively load properties files.
466                          */

467                         File JavaDoc file = null;
468                         
469                         if (value.startsWith(fileSeparator))
470                         {
471                             /*
472                              * We have an absolute path so we'll
473                              * use this.
474                              */

475                             file = new File JavaDoc(value);
476                         }
477                         else
478                         {
479                             /*
480                              * We have a relative path, and we have
481                              * two possible forms here. If we have the
482                              * "./" form then just strip that off first
483                              * before continuing.
484                              */

485                             if (value.startsWith("." + fileSeparator))
486                             {
487                                 value = value.substring(2);
488                             }
489                             
490                             file = new File JavaDoc(basePath + value);
491                         }
492                         
493                         if (file != null && file.exists() && file.canRead())
494                         {
495                             load ( new FileInputStream JavaDoc(file));
496                         }
497                     }
498                     else
499                     {
500                         addProperty(key,value);
501                         //setProperty(key,value);
502
}
503                 }
504             }
505         }
506         catch (NullPointerException JavaDoc e)
507         {
508             /*
509              * Should happen only when EOF is reached.
510              */

511             return;
512         }
513     }
514
515     /**
516      * Gets a property from the configuration.
517      *
518      * @param key property to retrieve
519      * @return value as object. Will return user value if exists,
520      * if not then default value if exists, otherwise null
521      */

522     public Object JavaDoc getProperty( String JavaDoc key)
523     {
524         /*
525          * first, try to get from the 'user value' store
526          */

527         Object JavaDoc o = this.get(key);
528
529         if ( o == null)
530         {
531             /*
532              * if there isn't a value there, get it from the
533              * defaults if we have them
534              */

535             if (defaults != null)
536             {
537                 o = defaults.get(key);
538             }
539         }
540
541         return o;
542     }
543     
544     /**
545      * Add a property to the configuration. If it already
546      * exists then the value stated here will be added
547      * to the configuration entry. For example, if
548      *
549      * resource.loader = file
550      *
551      * is already present in the configuration and you
552      *
553      * addProperty("resource.loader", "classpath")
554      *
555      * Then you will end up with a Vector like the
556      * following:
557      *
558      * ["file", "classpath"]
559      *
560      * @param String key
561      * @param String value
562      */

563     //public void setProperty(String key, Object token)
564
public void addProperty(String JavaDoc key, Object JavaDoc token)
565     {
566
567         // $$$ GMJ : remove after 1.1 release
568
// for deprecation help
569
deprecationCrutch.addProperty( key, token );
570
571         Object JavaDoc o = this.get(key);
572
573         /*
574          * $$$ GMJ
575          * FIXME : post 1.0 release, we need to not assume
576          * that a scalar is a String - it can be an Object
577          * so we should make a little vector-like class
578          * say, Foo that wraps (not extends Vector),
579          * so we can do things like
580          * if ( !( o instanceof Foo) )
581          * so we know it's our 'vector' container
582          *
583          * This applies throughout
584          */

585         
586         if (o instanceof String JavaDoc)
587         {
588             Vector JavaDoc v = new Vector JavaDoc(2);
589             v.addElement(o);
590             v.addElement(token);
591             put(key, v);
592         }
593         else if (o instanceof Vector JavaDoc)
594         {
595             ((Vector JavaDoc) o).addElement(token);
596         }
597         else
598         {
599             /*
600              * This is the first time that we have seen
601              * request to place an object in the
602              * configuration with the key 'key'. So
603              * we just want to place it directly into
604              * the configuration ... but we are going to
605              * make a special exception for String objects
606              * that contain "," characters. We will take
607              * CSV lists and turn the list into a vector of
608              * Strings before placing it in the configuration.
609              * This is a concession for Properties and the
610              * like that cannot parse multiple same key
611              * values.
612              */

613             if (token instanceof String JavaDoc &&
614                 ((String JavaDoc)token).indexOf(PropertiesTokenizer.DELIMITER) > 0)
615             {
616                 PropertiesTokenizer tokenizer =
617                     new PropertiesTokenizer((String JavaDoc)token);
618                     
619                 while (tokenizer.hasMoreTokens())
620                 {
621                     String JavaDoc value = tokenizer.nextToken();
622                     
623                     /*
624                      * we know this is a string, so make sure it
625                      * just goes in rather than risking vectorization
626                      * if it contains an escaped comma
627                      */

628                     addStringProperty(key,value);
629                 }
630             }
631             else
632             {
633                 /*
634                  * We want to keep track of the order the keys
635                  * are parsed, or dynamically entered into
636                  * the configuration. So when we see a key
637                  * for the first time we will place it in
638                  * an ArrayList so that if a client class needs
639                  * to perform operations with configuration
640                  * in a definite order it will be possible.
641                  */

642
643                 /*
644                  * safety check
645                  */

646
647                 if( !containsKey( key ) )
648                 {
649                     keysAsListed.add(key);
650                 }
651
652                 /*
653                  * and the value
654                  */

655                 put(key, token);
656             }
657         }
658     }
659
660
661     /**
662      * Sets a string property w/o checking for commas - used
663      * internally when a property has been broken up into
664      * strings that could contain escaped commas to prevent
665      * the inadvertant vectorization.
666      *
667      * Thanks to Leon Messerschmidt for this one.
668      *
669      */

670     private void addStringProperty(String JavaDoc key, String JavaDoc token)
671     {
672         Object JavaDoc o = this.get(key);
673
674         /*
675          * $$$ GMJ
676          * FIXME : post 1.0 release, we need to not assume
677          * that a scalar is a String - it can be an Object
678          * so we should make a little vector-like class
679          * say, Foo that wraps (not extends Vector),
680          * so we can do things like
681          * if ( !( o instanceof Foo) )
682          * so we know it's our 'vector' container
683          *
684          * This applies throughout
685          */

686
687         /*
688          * do the usual thing - if we have a value and
689          * it's scalar, make a vector, otherwise add
690          * to the vector
691          */

692  
693         if (o instanceof String JavaDoc)
694         {
695             Vector JavaDoc v = new Vector JavaDoc(2);
696             v.addElement(o);
697             v.addElement(token);
698             put(key, v);
699         }
700         else if (o instanceof Vector JavaDoc)
701         {
702             ((Vector JavaDoc) o).addElement(token);
703         }
704         else
705         {
706             if( !containsKey( key ) )
707             {
708                 keysAsListed.add(key);
709             }
710
711             put( key, token);
712         }
713     }
714
715     /**
716      * Set a property, this will replace any previously
717      * set values. Set values is implicitly a call
718      * to clearProperty(key), addProperty(key,value).
719      *
720      * @param String key
721      * @param String value
722      */

723     public void setProperty(String JavaDoc key, Object JavaDoc value)
724     {
725         clearProperty(key);
726         addProperty(key,value);
727     }
728     
729     /**
730      * Save the properties to the given outputstream.
731      *
732      * @param output An OutputStream.
733      * @param header A String.
734      * @exception IOException.
735      */

736     public synchronized void save(OutputStream JavaDoc output,
737                                   String JavaDoc Header)
738         throws IOException JavaDoc
739     {
740         if(output != null)
741         {
742             PrintWriter JavaDoc theWrtr = new PrintWriter JavaDoc(output);
743             if(Header != null)
744             {
745                 theWrtr.println(Header);
746             }
747             Enumeration JavaDoc theKeys = keys();
748             while(theKeys.hasMoreElements())
749             {
750                 String JavaDoc key = (String JavaDoc) theKeys.nextElement();
751                 Object JavaDoc value = get((Object JavaDoc) key);
752                 if(value != null)
753                 {
754                     if(value instanceof String JavaDoc)
755                     {
756                         StringBuffer JavaDoc currentOutput = new StringBuffer JavaDoc();
757                         currentOutput.append(key);
758                         currentOutput.append("=");
759                         currentOutput.append((String JavaDoc) value);
760                         theWrtr.println(currentOutput.toString());
761                     }
762                     else if(value instanceof Vector JavaDoc)
763                     {
764                         Vector JavaDoc values = (Vector JavaDoc) value;
765                         Enumeration JavaDoc valuesEnum = values.elements();
766                         while(valuesEnum.hasMoreElements())
767                         {
768                             String JavaDoc currentElement =
769                                    (String JavaDoc) valuesEnum.nextElement();
770                             StringBuffer JavaDoc currentOutput = new StringBuffer JavaDoc();
771                             currentOutput.append(key);
772                             currentOutput.append("=");
773                             currentOutput.append(currentElement);
774                             theWrtr.println(currentOutput.toString());
775                         }
776                     }
777                 }
778                 theWrtr.println();
779                 theWrtr.flush();
780             }
781         }
782     }
783
784     /**
785      * Combines an existing Hashtable with this Hashtable.
786      *
787      * Warning: It will overwrite previous entries without warning.
788      *
789      * @param Configuration
790      */

791     public void combine (Configuration c)
792     {
793         for (Iterator JavaDoc i = c.getKeys() ; i.hasNext() ;)
794         {
795             String JavaDoc key = (String JavaDoc) i.next();
796             //clearProperty(key);
797
setProperty( key, c.get(key) );
798         }
799     }
800     
801     /**
802      * Clear a property in the configuration.
803      *
804      * @param String key to remove along with corresponding value.
805      */

806     public void clearProperty(String JavaDoc key)
807     {
808         // $$$ GMJ : remove after 1.1 release
809
// for deprecation help
810
deprecationCrutch.clearProperty( key );
811
812         if (containsKey(key))
813         {
814             /*
815              * we also need to rebuild the keysAsListed or else
816              * things get *very* confusing
817              */

818
819             for(int i = 0; i < keysAsListed.size(); i++)
820             {
821                 if ( ( (String JavaDoc) keysAsListed.get(i)).equals( key ) )
822                 {
823                     keysAsListed.remove(i);
824                     break;
825                 }
826             }
827
828             remove(key);
829         }
830     }
831
832     /**
833      * Get the list of the keys contained in the configuration
834      * repository.
835      *
836      * @return An Iterator.
837      */

838     public Iterator JavaDoc getKeys()
839     {
840         return keysAsListed.iterator();
841     }
842
843     /**
844      * Get the list of the keys contained in the configuration
845      * repository that match the specified prefix.
846      *
847      * @param prefix The prefix to test against.
848      * @return An Iterator of keys that match the prefix.
849      */

850     public Iterator JavaDoc getKeys(String JavaDoc prefix)
851     {
852         Iterator JavaDoc keys = getKeys();
853         ArrayList JavaDoc matchingKeys = new ArrayList JavaDoc();
854         
855         while( keys.hasNext() )
856         {
857             Object JavaDoc key = keys.next();
858             
859             if( key instanceof String JavaDoc && ((String JavaDoc) key).startsWith(prefix) )
860             {
861                 matchingKeys.add(key);
862             }
863         }
864         return matchingKeys.iterator();
865     }
866
867     /**
868      * Create a Configurations object that is a subset
869      * of this one. Take into account duplicate keys
870      * by using the setProperty() in Configuration.
871      *
872      * @param String prefix
873      */

874     public Configuration subset(String JavaDoc prefix)
875     {
876         Configuration c = new Configuration();
877         Iterator JavaDoc keys = getKeys();
878         boolean validSubset = false;
879         
880         while( keys.hasNext() )
881         {
882             Object JavaDoc key = keys.next();
883             
884             if( key instanceof String JavaDoc && ((String JavaDoc) key).startsWith(prefix) )
885             {
886                 if (!validSubset)
887                 {
888                     validSubset = true;
889                 }
890                 
891                 String JavaDoc newKey = null;
892                 
893                 /*
894                  * Check to make sure that c.subset(prefix) doesn't
895                  * blow up when there is only a single property
896                  * with the key prefix. This is not a useful
897                  * subset but it is a valid subset.
898                  */

899                 if ( ((String JavaDoc)key).length() == prefix.length())
900                 {
901                     newKey = prefix;
902                 }
903                 else
904                 {
905                     newKey = ((String JavaDoc)key).substring(prefix.length() + 1);
906                 }
907                 
908                 /*
909                  * Make sure to use the setProperty() method and not
910                  * just put(). setProperty() takes care of catching
911                  * all the keys in the order they appear in a
912                  * properties files or the order they are set
913                  * dynamically.
914                  */

915
916                 c.setProperty(newKey, get(key));
917             }
918         }
919         
920         if (validSubset)
921         {
922             return c;
923         }
924         else
925         {
926             return null;
927         }
928     }
929
930     /**
931      * Display the configuration for debugging
932      * purposes.
933      */

934     public void display()
935     {
936         Iterator JavaDoc i = getKeys();
937         
938         while (i.hasNext())
939         {
940             String JavaDoc key = (String JavaDoc) i.next();
941             Object JavaDoc value = get(key);
942             System.out.println(key + " => " + value);
943         }
944     }
945
946     /**
947      * Get a string associated with the given configuration key.
948      *
949      * @param key The configuration key.
950      * @return The associated string.
951      * @exception ClassCastException is thrown if the key maps to an
952      * object that is not a String.
953      */

954     public String JavaDoc getString(String JavaDoc key)
955     {
956         return getString(key, null);
957     }
958
959     /**
960      * Get a string associated with the given configuration key.
961      *
962      * @param key The configuration key.
963      * @param defaultValue The default value.
964      * @return The associated string if key is found,
965      * default value otherwise.
966      * @exception ClassCastException is thrown if the key maps to an
967      * object that is not a String.
968      */

969     public String JavaDoc getString(String JavaDoc key,
970                             String JavaDoc defaultValue)
971     {
972         Object JavaDoc value = get(key);
973
974         if (value instanceof String JavaDoc)
975         {
976             return (String JavaDoc) value;
977         }
978         else if (value == null)
979         {
980             if (defaults != null)
981             {
982                 return defaults.getString(key, defaultValue);
983             }
984             else
985             {
986                 return defaultValue;
987             }
988         }
989         else if (value instanceof Vector JavaDoc)
990         {
991             return (String JavaDoc) ((Vector JavaDoc) value).get(0);
992         }
993         else
994         {
995             throw new ClassCastException JavaDoc(
996                 '\'' + key + "' doesn't map to a String object");
997         }
998     }
999
1000    /**
1001     * Get a list of properties associated with the given
1002     * configuration key.
1003     *
1004     * @param key The configuration key.
1005     * @return The associated properties if key is found.
1006     * @exception ClassCastException is thrown if the key maps to an
1007     * object that is not a String/Vector.
1008     * @exception IllegalArgumentException if one of the tokens is
1009     * malformed (does not contain an equals sign).
1010     */

1011    public Properties JavaDoc getProperties(String JavaDoc key)
1012    {
1013        return getProperties(key, new Properties JavaDoc());
1014    }
1015
1016    /**
1017     * Get a list of properties associated with the given
1018     * configuration key.
1019     *
1020     * @param key The configuration key.
1021     * @return The associated properties if key is found.
1022     * @exception ClassCastException is thrown if the key maps to an
1023     * object that is not a String/Vector.
1024     * @exception IllegalArgumentException if one of the tokens is
1025     * malformed (does not contain an equals sign).
1026     */

1027    public Properties JavaDoc getProperties(String JavaDoc key,
1028                                    Properties JavaDoc defaults)
1029    {
1030        /*
1031         * Grab an array of the tokens for this key.
1032         */

1033        String JavaDoc[] tokens = getStringArray(key);
1034
1035        /*
1036         * Each token is of the form 'key=value'.
1037         */

1038        Properties JavaDoc props = new Properties JavaDoc(defaults);
1039        for (int i = 0; i < tokens.length; i++)
1040        {
1041            String JavaDoc token = tokens[i];
1042            int equalSign = token.indexOf('=');
1043            if (equalSign > 0)
1044            {
1045                String JavaDoc pkey = token.substring(0, equalSign).trim();
1046                String JavaDoc pvalue = token.substring(equalSign + 1).trim();
1047                props.put(pkey, pvalue);
1048            }
1049            else
1050            {
1051                throw new IllegalArgumentException JavaDoc('\'' + token +
1052                                                   "' does not contain " +
1053                                                   "an equals sign");
1054            }
1055        }
1056        return props;
1057    }
1058
1059    /**
1060     * Get an array of strings associated with the given configuration
1061     * key.
1062     *
1063     * @param key The configuration key.
1064     * @return The associated string array if key is found.
1065     * @exception ClassCastException is thrown if the key maps to an
1066     * object that is not a String/Vector.
1067     */

1068    public String JavaDoc[] getStringArray(String JavaDoc key)
1069    {
1070        Object JavaDoc value = get(key);
1071
1072        // What's your vector, Victor?
1073
Vector JavaDoc vector;
1074        if (value instanceof String JavaDoc)
1075        {
1076            vector = new Vector JavaDoc(1);
1077            vector.addElement(value);
1078        }
1079        else if (value instanceof Vector JavaDoc)
1080        {
1081            vector = (Vector JavaDoc)value;
1082        }
1083        else if (value == null)
1084        {
1085            if (defaults != null)
1086            {
1087                return defaults.getStringArray(key);
1088            }
1089            else
1090            {
1091                return new String JavaDoc[0];
1092            }
1093        }
1094        else
1095        {
1096            throw new ClassCastException JavaDoc(
1097                '\'' + key + "' doesn't map to a String/Vector object");
1098        }
1099
1100        String JavaDoc[] tokens = new String JavaDoc[vector.size()];
1101        for (int i = 0; i < tokens.length; i++)
1102        {
1103            tokens[i] = (String JavaDoc)vector.elementAt(i);
1104        }
1105
1106        return tokens;
1107    }
1108
1109    /**
1110     * Get a Vector of strings associated with the given configuration
1111     * key.
1112     *
1113     * @param key The configuration key.
1114     * @return The associated Vector.
1115     * @exception ClassCastException is thrown if the key maps to an
1116     * object that is not a Vector.
1117     */

1118    public Vector JavaDoc getVector(String JavaDoc key)
1119    {
1120        return getVector(key, null);
1121    }
1122
1123    /**
1124     * Get a Vector of strings associated with the given configuration
1125     * key.
1126     *
1127     * @param key The configuration key.
1128     * @param defaultValue The default value.
1129     * @return The associated Vector.
1130     * @exception ClassCastException is thrown if the key maps to an
1131     * object that is not a Vector.
1132     */

1133    public Vector JavaDoc getVector(String JavaDoc key,
1134                            Vector JavaDoc defaultValue)
1135    {
1136        Object JavaDoc value = get(key);
1137
1138        if (value instanceof Vector JavaDoc)
1139        {
1140            return (Vector JavaDoc) value;
1141        }
1142        else if (value instanceof String JavaDoc)
1143        {
1144            Vector JavaDoc v = new Vector JavaDoc(1);
1145            v.addElement((String JavaDoc) value);
1146            put(key, v);
1147            return v;
1148        }
1149        else if (value == null)
1150        {
1151            if (defaults != null)
1152            {
1153                return defaults.getVector(key, defaultValue);
1154            }
1155            else
1156            {
1157                return ((defaultValue == null) ?
1158                        new Vector JavaDoc() : defaultValue);
1159            }
1160        }
1161        else
1162        {
1163            throw new ClassCastException JavaDoc(
1164                '\'' + key + "' doesn't map to a Vector object");
1165        }
1166    }
1167
1168    /**
1169     * Get a boolean associated with the given configuration key.
1170     *
1171     * @param key The configuration key.
1172     * @return The associated boolean.
1173     * @exception NoSuchElementException is thrown if the key doesn't
1174     * map to an existing object.
1175     * @exception ClassCastException is thrown if the key maps to an
1176     * object that is not a Boolean.
1177     */

1178    public boolean getBoolean(String JavaDoc key)
1179    {
1180        Boolean JavaDoc b = getBoolean(key, (Boolean JavaDoc) null);
1181        if (b != null)
1182        {
1183            return b.booleanValue();
1184        }
1185        else
1186        {
1187            throw new NoSuchElementException JavaDoc(
1188                '\'' + key + "' doesn't map to an existing object");
1189        }
1190    }
1191
1192    /**
1193     * Get a boolean associated with the given configuration key.
1194     *
1195     * @param key The configuration key.
1196     * @param defaultValue The default value.
1197     * @return The associated boolean.
1198     * @exception ClassCastException is thrown if the key maps to an
1199     * object that is not a Boolean.
1200     */

1201    public boolean getBoolean(String JavaDoc key, boolean defaultValue)
1202    {
1203        return getBoolean(key, new Boolean JavaDoc(defaultValue)).booleanValue();
1204    }
1205
1206    /**
1207     * Get a boolean associated with the given configuration key.
1208     *
1209     * @param key The configuration key.
1210     * @param defaultValue The default value.
1211     * @return The associated boolean if key is found and has valid
1212     * format, default value otherwise.
1213     * @exception ClassCastException is thrown if the key maps to an
1214     * object that is not a Boolean.
1215     */

1216    public Boolean JavaDoc getBoolean(String JavaDoc key, Boolean JavaDoc defaultValue)
1217    {
1218    
1219        Object JavaDoc value = get(key);
1220
1221        if (value instanceof Boolean JavaDoc)
1222        {
1223            return (Boolean JavaDoc) value;
1224        }
1225        else if (value instanceof String JavaDoc)
1226        {
1227            String JavaDoc s = testBoolean((String JavaDoc)value);
1228            Boolean JavaDoc b = new Boolean JavaDoc(s);
1229            put(key, b);
1230            return b;
1231        }
1232        else if (value == null)
1233        {
1234            if (defaults != null)
1235            {
1236                return defaults.getBoolean(key, defaultValue);
1237            }
1238            else
1239            {
1240                return defaultValue;
1241            }
1242        }
1243        else
1244        {
1245            throw new ClassCastException JavaDoc(
1246                '\'' + key + "' doesn't map to a Boolean object");
1247        }
1248    }
1249    
1250    /**
1251     * Test whether the string represent by value maps to a boolean
1252     * value or not. We will allow <code>true</code>, <code>on</code>,
1253     * and <code>yes</code> for a <code>true</code> boolean value, and
1254     * <code>false</code>, <code>off</code>, and <code>no</code> for
1255     * <code>false</code> boolean values. Case of value to test for
1256     * boolean status is ignored.
1257     *
1258     * @param String The value to test for boolean state.
1259     * @return <code>true</code> or <code>false</code> if the supplied
1260     * text maps to a boolean value, or <code>null</code> otherwise.
1261     */

1262    public String JavaDoc testBoolean(String JavaDoc value)
1263    {
1264        String JavaDoc s = ((String JavaDoc)value).toLowerCase();
1265    
1266        if (s.equals("true") || s.equals("on") || s.equals("yes"))
1267        {
1268            return "true";
1269        }
1270        else if (s.equals("false") || s.equals("off") || s.equals("no"))
1271        {
1272            return "false";
1273        }
1274        else
1275        {
1276            return null;
1277        }
1278    }
1279
1280    /**
1281     * Get a byte associated with the given configuration key.
1282     *
1283     * @param key The configuration key.
1284     * @return The associated byte.
1285     * @exception NoSuchElementException is thrown if the key doesn't
1286     * map to an existing object.
1287     * @exception ClassCastException is thrown if the key maps to an
1288     * object that is not a Byte.
1289     * @exception NumberFormatException is thrown if the value mapped
1290     * by the key has not a valid number format.
1291     */

1292    public byte getByte(String JavaDoc key)
1293    {
1294        Byte JavaDoc b = getByte(key, null);
1295        if (b != null)
1296        {
1297            return b.byteValue();
1298        }
1299        else
1300        {
1301            throw new NoSuchElementException JavaDoc(
1302                '\'' + key + " doesn't map to an existing object");
1303        }
1304    }
1305
1306    /**
1307     * Get a byte associated with the given configuration key.
1308     *
1309     * @param key The configuration key.
1310     * @param defaultValue The default value.
1311     * @return The associated byte.
1312     * @exception ClassCastException is thrown if the key maps to an
1313     * object that is not a Byte.
1314     * @exception NumberFormatException is thrown if the value mapped
1315     * by the key has not a valid number format.
1316     */

1317    public byte getByte(String JavaDoc key,
1318                        byte defaultValue)
1319    {
1320        return getByte(key, new Byte JavaDoc(defaultValue)).byteValue();
1321    }
1322
1323    /**
1324     * Get a byte associated with the given configuration key.
1325     *
1326     * @param key The configuration key.
1327     * @param defaultValue The default value.
1328     * @return The associated byte if key is found and has valid
1329     * format, default value otherwise.
1330     * @exception ClassCastException is thrown if the key maps to an
1331     * object that is not a Byte.
1332     * @exception NumberFormatException is thrown if the value mapped
1333     * by the key has not a valid number format.
1334     */

1335    public Byte JavaDoc getByte(String JavaDoc key,
1336                        Byte JavaDoc defaultValue)
1337    {
1338        Object JavaDoc value = get(key);
1339
1340        if (value instanceof Byte JavaDoc)
1341        {
1342            return (Byte JavaDoc) value;
1343        }
1344        else if (value instanceof String JavaDoc)
1345        {
1346            Byte JavaDoc b = new Byte JavaDoc((String JavaDoc) value);
1347            put(key, b);
1348            return b;
1349        }
1350        else if (value == null)
1351        {
1352            if (defaults != null)
1353            {
1354                return defaults.getByte(key, defaultValue);
1355            }
1356            else
1357            {
1358                return defaultValue;
1359            }
1360        }
1361        else
1362        {
1363            throw new ClassCastException JavaDoc(
1364                '\'' + key + "' doesn't map to a Byte object");
1365        }
1366    }
1367
1368    /**
1369     * Get a short associated with the given configuration key.
1370     *
1371     * @param key The configuration key.
1372     * @return The associated short.
1373     * @exception NoSuchElementException is thrown if the key doesn't
1374     * map to an existing object.
1375     * @exception ClassCastException is thrown if the key maps to an
1376     * object that is not a Short.
1377     * @exception NumberFormatException is thrown if the value mapped
1378     * by the key has not a valid number format.
1379     */

1380    public short getShort(String JavaDoc key)
1381    {
1382        Short JavaDoc s = getShort(key, null);
1383        if (s != null)
1384        {
1385            return s.shortValue();
1386        }
1387        else
1388        {
1389            throw new NoSuchElementException JavaDoc(
1390                '\'' + key + "' doesn't map to an existing object");
1391        }
1392    }
1393
1394    /**
1395     * Get a short associated with the given configuration key.
1396     *
1397     * @param key The configuration key.
1398     * @param defaultValue The default value.
1399     * @return The associated short.
1400     * @exception ClassCastException is thrown if the key maps to an
1401     * object that is not a Short.
1402     * @exception NumberFormatException is thrown if the value mapped
1403     * by the key has not a valid number format.
1404     */

1405    public short getShort(String JavaDoc key,
1406                          short defaultValue)
1407    {
1408        return getShort(key, new Short JavaDoc(defaultValue)).shortValue();
1409    }
1410
1411    /**
1412     * Get a short associated with the given configuration key.
1413     *
1414     * @param key The configuration key.
1415     * @param defaultValue The default value.
1416     * @return The associated short if key is found and has valid
1417     * format, default value otherwise.
1418     * @exception ClassCastException is thrown if the key maps to an
1419     * object that is not a Short.
1420     * @exception NumberFormatException is thrown if the value mapped
1421     * by the key has not a valid number format.
1422     */

1423    public Short JavaDoc getShort(String JavaDoc key,
1424                          Short JavaDoc defaultValue)
1425    {
1426        Object JavaDoc value = get(key);
1427
1428        if (value instanceof Short JavaDoc)
1429        {
1430            return (Short JavaDoc) value;
1431        }
1432        else if (value instanceof String JavaDoc)
1433        {
1434            Short JavaDoc s = new Short JavaDoc((String JavaDoc) value);
1435            put(key, s);
1436            return s;
1437        }
1438        else if (value == null)
1439        {
1440            if (defaults != null)
1441            {
1442                return defaults.getShort(key, defaultValue);
1443            }
1444            else
1445            {
1446                return defaultValue;
1447            }
1448        }
1449        else
1450        {
1451            throw new ClassCastException JavaDoc(
1452                '\'' + key + "' doesn't map to a Short object");
1453        }
1454    }
1455
1456    /**
1457     * The purpose of this method is to get the configuration resource
1458     * with the given name as an integer.
1459     *
1460     * @param name The resource name.
1461     * @return The value of the resource as an integer.
1462     */

1463    public int getInt(String JavaDoc name)
1464    {
1465        return getInteger(name);
1466    }
1467
1468    /**
1469     * The purpose of this method is to get the configuration resource
1470     * with the given name as an integer, or a default value.
1471     *
1472     * @param name The resource name
1473     * @param def The default value of the resource.
1474     * @return The value of the resource as an integer.
1475     */

1476    public int getInt(String JavaDoc name,
1477                      int def)
1478    {
1479        return getInteger(name, def);
1480    }
1481
1482    /**
1483     * Get a int associated with the given configuration key.
1484     *
1485     * @param key The configuration key.
1486     * @return The associated int.
1487     * @exception NoSuchElementException is thrown if the key doesn't
1488     * map to an existing object.
1489     * @exception ClassCastException is thrown if the key maps to an
1490     * object that is not a Integer.
1491     * @exception NumberFormatException is thrown if the value mapped
1492     * by the key has not a valid number format.
1493     */

1494    public int getInteger(String JavaDoc key)
1495    {
1496        Integer JavaDoc i = getInteger(key, null);
1497        if (i != null)
1498        {
1499            return i.intValue();
1500        }
1501        else
1502        {
1503            throw new NoSuchElementException JavaDoc(
1504                '\'' + key + "' doesn't map to an existing object");
1505        }
1506    }
1507
1508    /**
1509     * Get a int associated with the given configuration key.
1510     *
1511     * @param key The configuration key.
1512     * @param defaultValue The default value.
1513     * @return The associated int.
1514     * @exception ClassCastException is thrown if the key maps to an
1515     * object that is not a Integer.
1516     * @exception NumberFormatException is thrown if the value mapped
1517     * by the key has not a valid number format.
1518     */

1519    public int getInteger(String JavaDoc key,
1520                          int defaultValue)
1521    {
1522        Integer JavaDoc i = getInteger(key, null);
1523        
1524        if (i == null)
1525        {
1526            return defaultValue;
1527        }
1528        
1529        return i.intValue();
1530      }
1531
1532
1533    /**
1534     * Get a int associated with the given configuration key.
1535     *
1536     * @param key The configuration key.
1537     * @param defaultValue The default value.
1538     * @return The associated int if key is found and has valid
1539     * format, default value otherwise.
1540     * @exception ClassCastException is thrown if the key maps to an
1541     * object that is not a Integer.
1542     * @exception NumberFormatException is thrown if the value mapped
1543     * by the key has not a valid number format.
1544     */

1545    public Integer JavaDoc getInteger(String JavaDoc key,
1546                              Integer JavaDoc defaultValue)
1547    {
1548        Object JavaDoc value = get(key);
1549
1550        if (value instanceof Integer JavaDoc)
1551        {
1552            return (Integer JavaDoc) value;
1553        }
1554        else if (value instanceof String JavaDoc)
1555        {
1556            Integer JavaDoc i = new Integer JavaDoc((String JavaDoc) value);
1557            put(key, i);
1558            return i;
1559        }
1560        else if (value == null)
1561        {
1562            if (defaults != null)
1563            {
1564                return defaults.getInteger(key, defaultValue);
1565            }
1566            else
1567            {
1568                return defaultValue;
1569            }
1570        }
1571        else
1572        {
1573            throw new ClassCastException JavaDoc(
1574                '\'' + key + "' doesn't map to a Integer object");
1575        }
1576    }
1577
1578    /**
1579     * Get a long associated with the given configuration key.
1580     *
1581     * @param key The configuration key.
1582     * @return The associated long.
1583     * @exception NoSuchElementException is thrown if the key doesn't
1584     * map to an existing object.
1585     * @exception ClassCastException is thrown if the key maps to an
1586     * object that is not a Long.
1587     * @exception NumberFormatException is thrown if the value mapped
1588     * by the key has not a valid number format.
1589     */

1590    public long getLong(String JavaDoc key)
1591    {
1592        Long JavaDoc l = getLong(key, null);
1593        if (l != null)
1594        {
1595            return l.longValue();
1596        }
1597        else
1598        {
1599            throw new NoSuchElementException JavaDoc(
1600                '\'' + key + "' doesn't map to an existing object");
1601        }
1602    }
1603
1604    /**
1605     * Get a long associated with the given configuration key.
1606     *
1607     * @param key The configuration key.
1608     * @param defaultValue The default value.
1609     * @return The associated long.
1610     * @exception ClassCastException is thrown if the key maps to an
1611     * object that is not a Long.
1612     * @exception NumberFormatException is thrown if the value mapped
1613     * by the key has not a valid number format.
1614     */

1615    public long getLong(String JavaDoc key,
1616                        long defaultValue)
1617    {
1618        return getLong(key, new Long JavaDoc(defaultValue)).longValue();
1619    }
1620
1621    /**
1622     * Get a long associated with the given configuration key.
1623     *
1624     * @param key The configuration key.
1625     * @param defaultValue The default value.
1626     * @return The associated long if key is found and has valid
1627     * format, default value otherwise.
1628     * @exception ClassCastException is thrown if the key maps to an
1629     * object that is not a Long.
1630     * @exception NumberFormatException is thrown if the value mapped
1631     * by the key has not a valid number format.
1632     */

1633    public Long JavaDoc getLong(String JavaDoc key,
1634                        Long JavaDoc defaultValue)
1635    {
1636        Object JavaDoc value = get(key);
1637
1638        if (value instanceof Long JavaDoc)
1639        {
1640            return (Long JavaDoc) value;
1641        }
1642        else if (value instanceof String JavaDoc)
1643        {
1644            Long JavaDoc l = new Long JavaDoc((String JavaDoc) value);
1645            put(key, l);
1646            return l;
1647        }
1648        else if (value == null)
1649        {
1650            if (defaults != null)
1651            {
1652                return defaults.getLong(key, defaultValue);
1653            }
1654            else
1655            {
1656                return defaultValue;
1657            }
1658        }
1659        else
1660        {
1661            throw new ClassCastException JavaDoc(
1662                '\'' + key + "' doesn't map to a Long object");
1663        }
1664    }
1665
1666    /**
1667     * Get a float associated with the given configuration key.
1668     *
1669     * @param key The configuration key.
1670     * @return The associated float.
1671     * @exception NoSuchElementException is thrown if the key doesn't
1672     * map to an existing object.
1673     * @exception ClassCastException is thrown if the key maps to an
1674     * object that is not a Float.
1675     * @exception NumberFormatException is thrown if the value mapped
1676     * by the key has not a valid number format.
1677     */

1678    public float getFloat(String JavaDoc key)
1679    {
1680        Float JavaDoc f = getFloat(key, null);
1681        if (f != null)
1682        {
1683            return f.floatValue();
1684        }
1685        else
1686        {
1687            throw new NoSuchElementException JavaDoc(
1688                '\'' + key + "' doesn't map to an existing object");
1689        }
1690    }
1691
1692    /**
1693     * Get a float associated with the given configuration key.
1694     *
1695     * @param key The configuration key.
1696     * @param defaultValue The default value.
1697     * @return The associated float.
1698     * @exception ClassCastException is thrown if the key maps to an
1699     * object that is not a Float.
1700     * @exception NumberFormatException is thrown if the value mapped
1701     * by the key has not a valid number format.
1702     */

1703    public float getFloat(String JavaDoc key,
1704                          float defaultValue)
1705    {
1706        return getFloat(key, new Float JavaDoc(defaultValue)).floatValue();
1707    }
1708
1709    /**
1710     * Get a float associated with the given configuration key.
1711     *
1712     * @param key The configuration key.
1713     * @param defaultValue The default value.
1714     * @return The associated float if key is found and has valid
1715     * format, default value otherwise.
1716     * @exception ClassCastException is thrown if the key maps to an
1717     * object that is not a Float.
1718     * @exception NumberFormatException is thrown if the value mapped
1719     * by the key has not a valid number format.
1720     */

1721    public Float JavaDoc getFloat(String JavaDoc key,
1722                          Float JavaDoc defaultValue)
1723    {
1724        Object JavaDoc value = get(key);
1725
1726        if (value instanceof Float JavaDoc)
1727        {
1728            return (Float JavaDoc) value;
1729        }
1730        else if (value instanceof String JavaDoc)
1731        {
1732            Float JavaDoc f = new Float JavaDoc((String JavaDoc) value);
1733            put(key, f);
1734            return f;
1735        }
1736        else if (value == null)
1737        {
1738            if (defaults != null)
1739            {
1740                return defaults.getFloat(key, defaultValue);
1741            }
1742            else
1743            {
1744                return defaultValue;
1745            }
1746        }
1747        else
1748        {
1749            throw new ClassCastException JavaDoc(
1750                '\'' + key + "' doesn't map to a Float object");
1751        }
1752    }
1753
1754    /**
1755     * Get a double associated with the given configuration key.
1756     *
1757     * @param key The configuration key.
1758     * @return The associated double.
1759     * @exception NoSuchElementException is thrown if the key doesn't
1760     * map to an existing object.
1761     * @exception ClassCastException is thrown if the key maps to an
1762     * object that is not a Double.
1763     * @exception NumberFormatException is thrown if the value mapped
1764     * by the key has not a valid number format.
1765     */

1766    public double getDouble(String JavaDoc key)
1767    {
1768        Double JavaDoc d = getDouble(key, null);
1769        if (d != null)
1770        {
1771            return d.doubleValue();
1772        }
1773        else
1774        {
1775            throw new NoSuchElementException JavaDoc(
1776                '\'' + key + "' doesn't map to an existing object");
1777        }
1778    }
1779
1780    /**
1781     * Get a double associated with the given configuration key.
1782     *
1783     * @param key The configuration key.
1784     * @param defaultValue The default value.
1785     * @return The associated double.
1786     * @exception ClassCastException is thrown if the key maps to an
1787     * object that is not a Double.
1788     * @exception NumberFormatException is thrown if the value mapped
1789     * by the key has not a valid number format.
1790     */

1791    public double getDouble(String JavaDoc key,
1792                            double defaultValue)
1793    {
1794        return getDouble(key, new Double JavaDoc(defaultValue)).doubleValue();
1795    }
1796
1797    /**
1798     * Get a double associated with the given configuration key.
1799     *
1800     * @param key The configuration key.
1801     * @param defaultValue The default value.
1802     * @return The associated double if key is found and has valid
1803     * format, default value otherwise.
1804     * @exception ClassCastException is thrown if the key maps to an
1805     * object that is not a Double.
1806     * @exception NumberFormatException is thrown if the value mapped
1807     * by the key has not a valid number format.
1808     */

1809    public Double JavaDoc getDouble(String JavaDoc key,
1810                            Double JavaDoc defaultValue)
1811    {
1812        Object JavaDoc value = get(key);
1813
1814        if (value instanceof Double JavaDoc)
1815        {
1816            return (Double JavaDoc) value;
1817        }
1818        else if (value instanceof String JavaDoc)
1819        {
1820            Double JavaDoc d = new Double JavaDoc((String JavaDoc) value);
1821            put(key, d);
1822            return d;
1823        }
1824        else if (value == null)
1825        {
1826            if (defaults != null)
1827            {
1828                return defaults.getDouble(key, defaultValue);
1829            }
1830            else
1831            {
1832                return defaultValue;
1833            }
1834        }
1835        else
1836        {
1837            throw new ClassCastException JavaDoc(
1838                '\'' + key + "' doesn't map to a Double object");
1839        }
1840    }
1841
1842    /**
1843     * Convert a standard properties class into a configuration
1844     * class.
1845     *
1846     * @param Properties properties object to convert into
1847     * a Configuration object.
1848     *
1849     * @return Configuration configuration created from the
1850     * properties object.
1851     */

1852    public static Configuration convertProperties(Properties JavaDoc p)
1853    {
1854        Configuration c = new Configuration();
1855    
1856        for (Enumeration JavaDoc e = p.keys(); e.hasMoreElements() ; )
1857        {
1858            String JavaDoc s = (String JavaDoc) e.nextElement();
1859            c.setProperty(s, p.getProperty(s));
1860        }
1861    
1862        return c;
1863    }
1864
1865    /**
1866     * <p>
1867     * Routine intended for deprecation period only
1868     * as we switch from using the Configuration
1869     * class in Velocity to the Jakarta Commons
1870     * ExtendedProperties
1871     * </p>
1872     * <p>
1873     * Do not use this for general use. It will disappear
1874     * </p>
1875     * @return ExtendedProperties containing data of Configuration
1876     *
1877     * @deprecated Do not use. For deprecation assistance only.
1878     */

1879    public ExtendedProperties getExtendedProperties()
1880    {
1881        return deprecationCrutch;
1882    }
1883
1884
1885}
1886
Popular Tags