KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lutris > util > Config


1
2 /*
3  * Enhydra Java Application Server Project
4  *
5  * The contents of this file are subject to the Enhydra Public License
6  * Version 1.1 (the "License"); you may not use this file except in
7  * compliance with the License. You may obtain a copy of the License on
8  * the Enhydra web site ( http://www.enhydra.org/ ).
9  *
10  * Software distributed under the License is distributed on an "AS IS"
11  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
12  * the License for the specific terms governing rights and limitations
13  * under the License.
14  *
15  * The Initial Developer of the Enhydra Application Server is Lutris
16  * Technologies, Inc. The Enhydra Application Server and portions created
17  * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
18  * All Rights Reserved.
19  *
20  * Contributor(s):
21  *
22  * $Id: Config.java,v 1.6 2005/04/27 18:30:33 slobodan Exp $
23  */

24
25 package com.lutris.util;
26
27
28 import java.lang.reflect.Array JavaDoc;
29 import java.lang.reflect.Constructor JavaDoc;
30 import java.util.Hashtable JavaDoc;
31
32 import org.enhydra.util.ConfigFileInterface;
33
34 /**
35  * Config is essentially a KeywordValueTable used for recursive
36  * storage of data derived from a config file. The contents is
37  * initialized but <CODE>ConfigFile</CODE>.
38  *
39  * @see ConfigFile
40  * @see KeywordValueTable
41  * @author John Marco
42  * @author Shawn McMurdo
43  * @version $Revision: 1.6 $
44  */

45 public class Config extends KeywordValueTable {
46
47 /**
48  * Passed as the "count" argument to getInts, getLongs(), etc. to
49  * indicate that all available elements are to be retrieved.
50  */

51  private static final int GET_ALL = -1;
52
53 /**
54  * The ConfigFile object this Config is associated with (if any)
55  */

56   private ConfigFileInterface configFile = null;
57
58 /**
59  * Default constructor for an empty Config.
60  */

61   public Config() {
62     super();
63   }
64
65 /**
66  * Constructor that takes a KeywordValueTable as initialization.
67  * @param kvt KeywordValueTable with which to initialize Config
68  */

69  public Config(KeywordValueTable kvt) {
70    super();
71    String JavaDoc[] keys = kvt.keys();
72    for (int i = 0; i < keys.length; i++) {
73      try {
74        set(keys[i], kvt.get(keys[i]));
75      }
76      catch (KeywordValueException e) {
77        // This shouldn't happen
78
throw new FatalExceptionError(e);
79      }
80    }
81  }
82
83 /**
84  * Constructor that takes a KeywordValueTable and a ConfigFile as
85  * initialization. The ConfigFile is associated with this Config
86  * object.
87  * @param kvt KeywordValueTable with which to initialize Config
88  * @param configFile ConfigFile to associate this Config object with
89  */

90  public Config(KeywordValueTable kvt, ConfigFileInterface configFile) {
91     this(kvt);
92   this.configFile = configFile;
93  }
94
95 /**
96  * Constructor that associates this Config with a given ConfigFile.
97  * @param configFile ConfigFile to associate this object with
98  */

99  public Config(ConfigFileInterface configFile) {
100     this();
101   this.configFile = configFile;
102  }
103
104 /**
105  * Returnes cloned Config object. The cloned and original objects have exatly
106  * same key value pairs, but free of any common object references. Only
107  * reference which is same for both objects (the original, and it's clone) is
108  * reference to associated ConfigFile object (private argument of Config class).
109  * @return A cloned Config object.
110  * @exception KeywordValueException
111  */

112  public Config getClonedConfig() throws KeywordValueException{ // VR 13.12.2002.
113

114    Config returnConfig = this.getClonedConfigParams();
115
116 // TJ 08.11.2003. put under comment begin
117
// ConfigFileInterface cf = new ConfigFile(returnConfig);
118
// cf.setFile(this.getConfigFile().getFile());
119
// returnConfig.setConfigFile(cf);
120
// return returnConfig;
121
// TJ 08.11.2003. put under comment end
122

123    ConfigFileInterface cf = null;
124    Class JavaDoc classObj = this.getConfigFile().getClass();
125    String JavaDoc className = classObj.getName();
126
127    Class JavaDoc[] classParam = new Class JavaDoc[1];
128    Constructor JavaDoc constr = null;
129    Object JavaDoc[] arguments = new Object JavaDoc[1];
130    try {
131      classParam[0] = Class.forName("com.lutris.util.Config");
132      constr = classObj.getConstructor(classParam);
133      arguments[0] = (Object JavaDoc)(this);
134      cf = (ConfigFileInterface)constr.newInstance(arguments);
135    cf.setFile(this.getConfigFile().getFile());
136    returnConfig.setConfigFile(cf);
137    }
138    catch (Exception JavaDoc ex){
139     returnConfig.setConfigFile(cf);
140    }
141    return returnConfig;
142  }
143
144
145 /**
146  * Returnes cloned Config object. The cloned and original objects have exatly
147  * same key-value pairs, but free of any common object references. Returned
148  * cloned Config object has not defined it's private argument of type ConfigFile
149  * (reference to it's configuration file on hard disc). Method is specialy
150  * designed to enable recursion calls, and it should be called by public method
151  * getClonedConfig().
152  * @return A cloned Config object withouth reference to it's configuration file.
153  * @exception KeywordValueException
154  */

155  private Config getClonedConfigParams() throws KeywordValueException{ // VR 13.12.2002.
156

157    Config returnConfig = new Config();
158    String JavaDoc[] keys = this.keys();
159
160    for (int i = 0; i < keys.length; i++) {
161      Object JavaDoc tempValue = this.get(keys[i]);
162
163      if(tempValue instanceof String JavaDoc) {
164        returnConfig.set( new String JavaDoc(keys[i]), new String JavaDoc((String JavaDoc)tempValue) );
165      }
166      else if (tempValue instanceof KeywordValueTable) { // useing of recursion
167
Config kvtTempConfig = (new Config( (KeywordValueTable)tempValue)).getClonedConfigParams();
168        returnConfig.set( new String JavaDoc(keys[i]), (KeywordValueTable)kvtTempConfig );
169      }
170      else if (tempValue instanceof Config) { // useing of recursion
171
Config tempConfig = ((Config)tempValue).getClonedConfigParams();
172        returnConfig.set( new String JavaDoc(keys[i]), tempConfig );
173      }
174      else if( tempValue.getClass().isArray() ) {
175        int len = Array.getLength(tempValue);
176        String JavaDoc[] newTemp = new String JavaDoc[len];
177        for (int k=0; k<len; k++) {
178          newTemp[k] = new String JavaDoc( Array.get(tempValue,k).toString() );
179        }
180        returnConfig.set( new String JavaDoc(keys[i]), newTemp );
181      }
182    }
183    return returnConfig;
184  }
185 // DT 30.12.2003 BEG
186
/**
187 * Returns the hashtable containing names and values of all config parameters
188 * Names are in the form name-level-0_name-level-1_name-level-2...
189 *
190 * @param prefix - previous level name
191 * @return hashtable of all config parameters
192 */

193 public Hashtable JavaDoc allConfigParams(String JavaDoc prefix) throws KeywordValueException{
194
195    
196    String JavaDoc[] keys = this.keys();
197     Hashtable JavaDoc ht=new Hashtable JavaDoc();
198    for (int i = 0; i < keys.length; i++) {
199      Object JavaDoc tempValue = this.get(keys[i]);
200      String JavaDoc name;
201      
202      if(prefix != null && prefix.length()>0){
203         name=prefix+"_"+keys[i];
204      }else{
205         name=keys[i];
206      }
207      
208      if(tempValue instanceof String JavaDoc) {
209         ht.put(name, (String JavaDoc)tempValue);
210      }
211      else if (tempValue instanceof KeywordValueTable) { // useing of recursion
212
ht.putAll(((Config)tempValue).allConfigParams(name));
213      }
214      else if (tempValue instanceof Config) { // useing of recursion
215
ht.putAll(((Config)tempValue).allConfigParams(name));
216      }
217      else if( tempValue.getClass().isArray() ) {
218        int len = Array.getLength(tempValue);
219        String JavaDoc temp = "";
220        if (len>0){
221            for (int k=0; k<len; k++) {
222             temp=temp+","+(String JavaDoc)Array.get(tempValue,k).toString();
223            }
224            ht.put(name+"_Array",temp.substring(1));
225        } else {
226            ht.put(name+"_Array",temp);
227        }
228      }
229    }
230    return ht;
231  }
232 // DT 30.12.2003 END
233
/**
234  * Imorts and synchronizes to, all parameters (key-value pairs) according to
235  * given Config object parameters. All parameters which do not exist in imported
236  * Config object will be removed.
237  * @param config Config object which has key-value pairs for importing.
238  * @exception KeywordValueException
239  */

240  public void importConfig(Config config) throws KeywordValueException{ // VR 14.12.2002.
241

242    String JavaDoc[] original = this.keys();
243    String JavaDoc[] in = config.keys();
244
245 //adding or changing keys from imported Config object
246
for(int i=0; i<in.length; i++)
247      this.set( in[i], config.get(in[i]) );
248 //removing keys which did not exist in imported Config object
249
for(int i=0; i<original.length; i++) {
250      if(!config.containsKey(original[i]))
251        this.remove( in[i] );
252    }
253  }
254
255
256 /**
257  * Allocates a new section. The overrides the default method to allocate a
258  * section that is of class <CODE>Config<CODE>.
259  * @return A reference to a new section.
260  * @see KeywordValueTable#newSection
261  */

262   protected KeywordValueTable newSection() {
263       return new Config(configFile);
264   }
265
266 /**
267  * Gets the <code>ConfigFile</code> associated with this object.
268  * @return the associated <code>ConfigFile</code>,
269  * <code>null</code> if there is no config file associated with this
270  * object.
271  */

272   public ConfigFileInterface getConfigFile() {
273     return configFile;
274   }
275
276 /**
277  * Sets the <code>ConfigFile</code> associated with this object.
278  * For use by <code>ConfigFile</code> only, anyone else please use
279  * the appropriate constructor
280  * @param configFile ConfigFile object associated with this object
281  */

282   public void setConfigFile(ConfigFileInterface configFile) {
283     this.configFile = configFile;
284   }
285
286 /**
287  * Get the value of a section as a <CODE>Config</CODE> object.
288  * @param keyword The keyword of the field. This can be a simple keyword
289  * or a recursive, dot-seperated keyword path.
290  * @return A reference to the section object or null if not found.
291  * @exception KeywordValueException If the keyword is not syntactically
292  * legal or a non-leaf element of the keyword is not a section or the value
293  * object is not a KeywordValueTable.
294  * @see KeywordValueTable#getSection
295  */

296   public synchronized Config getConfig(String JavaDoc keyword)
297       throws KeywordValueException {
298     return (Config) getSection(keyword);
299   }
300
301 /**
302  * Gets the value of a section as a <CODE>KeywordValueTable</CODE> object.
303  * This method overrides the KeywordValueTable.getSection in order to
304  * insure that Config.getSection() always returns a Config object even
305  * if a KeywordValueTable was inserted into the Config as a section.
306  * @param keyword The keyword of the field. This can be a simple keyword
307  * or a recursive, dot-seperated keyword path.
308  * @return A reference to the section object or null if not found.
309  * @exception KeywordValueException If the keyword is not syntactically legal
310  * or a non-leaf element of the keyword is not a section or the value object is
311  * not a KeywordValueTable.
312  * @see KeywordValueTable#getSection
313  */

314   public synchronized KeywordValueTable getSection(String JavaDoc keyword)
315           throws KeywordValueException {
316     KeywordValueTable kvt = super.getSection(keyword);
317     if (kvt == null) {
318       return null;
319     }
320     if (kvt instanceof Config) {
321       return kvt;
322     }
323     else {
324       return new Config(kvt, configFile);
325     }
326   }
327
328 /**
329  * Returns <code>true</code> if the specified key is found,
330  * <code>false</code> otherwise.
331  * @param key The key whose existence is to be tested.
332  * @return <code>true</code> if the key was found, otherwise <code>false</code>.
333  */

334   public boolean containsKey(String JavaDoc key) {
335     boolean result = false;
336     try {
337       result = super.containsKey(key);
338     }
339     catch (KeywordValueException e) {
340       result = false;
341     }
342     return result;
343   }
344
345 /**
346  * Returns the number of data elements for a given key, or <code>-1</code> if
347  * the key is not found.
348  * @param key The key to search for.
349  * @return The number of entries for the given key, or <code>-1</code> if
350  * the key is not found.
351  * @exception ConfigException
352  */

353   public int containsCount(String JavaDoc key) throws ConfigException {
354     Object JavaDoc valObj = null;
355     try {
356       valObj = get(key);
357       if (valObj == null) return -1;
358       return Array.getLength(valObj);
359     }
360     catch (KeywordValueException e) {
361       throw new ConfigException(e.getMessage());
362     }
363     catch (IllegalArgumentException JavaDoc e) {
364       // Caused by object not being array.
365
}
366 // Assume if object was not null, it was single-valued entity.
367
if (valObj == null) return -1;
368     return 1;
369   }
370
371 /**
372  * Is the key is an array, or a single value. If this returns true,
373  * you should use <CODE>getStrings()</CODE> (or if you know the type
374  * of the data, you can use, for example, <CODE>getInts()</CODE>).
375  * If this returns false, you shoud use <CODE>getString()</CODE>
376  * (or if you know the type of the data, you can use, for example,
377  * <CODE>getInt()</CODE>).
378  * @param key The key to search for.
379  * @return True if the key is an array, false if it is a single value.
380  * @exception ConfigException If the key is not found.
381  */

382   public boolean isArray(String JavaDoc key) throws ConfigException {
383     Object JavaDoc valObj = null;
384     try {
385       valObj = get(key);
386       if (valObj == null)
387           throw new ConfigException("Key \"" + key + "\" not found.");
388       // Attempt array access. This will fail if not an array.
389
Array.getLength(valObj);
390       // It must be an array if we made it to here.
391
return true;
392     }
393     catch (KeywordValueException e) {
394       throw new ConfigException(e.getMessage());
395     }
396     catch (IllegalArgumentException JavaDoc e) {
397       // Caused by object not being array.
398
return false;
399     }
400   }
401
402 /**
403  * Returns the array of longs associated with a given key. If the
404  * <code>count</code> parameter is not <code>GET_ALL</code> and the
405  * number of elements in the retrieved array does not match <code>
406  * count</code> then a ConfigException is thrown with <code>reason</code>
407  * set to <code>COUNT</code>.
408  * If any of the retrieved elements cannot be converted to
409  * longs due to invalid syntax or overflow, then a ConfigException
410  * is thrown with <code>reason</code> set to <code>FORMAT</code>.
411  * @param key The key to use to search for the configuration entries.
412  * @param count The number of entries expected in the result. If the number of
413  * retrieved entries does not match <code>count</code> and <code>count</code>
414  * is not <code> GET_ALL</code> then a <code>ConfigException</code> error is
415  * thrown.
416  * @return An array of longs containing the list of long values from
417  * the configuration input stream.
418  * @exception ConfigException Thrown if the requested entry does not exist
419  * or elements are not in the requested format.
420  * @see ConfigException
421  * @see Config#GET_ALL
422  */

423   private final long[] getLongsInternal(String JavaDoc key, int count)
424         throws ConfigException {
425
426     Object JavaDoc obj;
427     try {
428       obj = get(key);
429     }
430     catch (KeywordValueException e) {
431       throw new ConfigException(e.getMessage());
432     }
433     if (obj == null) {
434       throw new ConfigException(ConfigException.NOT_FOUND,
435                                 "Key \"" + key
436                                 + "\" not found in configuration.");
437     }
438     long[] la = null;
439     if (obj.getClass().isArray()) {
440       int len = Array.getLength(obj);
441       la = new long[len];
442       for (int i=0; i<len; i++) {
443         try {
444           la[i] = (long) Long.parseLong(Array.get(obj,i).toString());
445         }
446         catch (Throwable JavaDoc e) {
447           throw new ConfigException("Element " + i +
448                                     " is not a long.");
449         }
450       }
451     }
452     else {
453       la = new long[1];
454       try {
455         la[0] = Long.parseLong(obj.toString());
456       }
457       catch (Throwable JavaDoc e) {
458         throw new ConfigException("Element 0 is not a long.");
459       }
460     }
461     if ((count != GET_ALL) && (la.length != count)) {
462       throw new ConfigException(ConfigException.COUNT,
463                                 "Key \"" + key
464                                 + "\" has " + la.length + " elements. (expected "
465                                 + count + ")");
466     }
467     return la;
468   }
469
470 /**
471  * Returns a single long integer value associated with a given key.
472  * If the key is associated with more than one element, or the
473  * retrieved element cannot be converted to a long integer then a
474  * <code>ConfigException</code> exception is thrown.
475  * @param key The key to use to search for the configuration entry.
476  * @return The long integer value associated with the given key.
477  * @exception ConfigException Thrown if the requested entry does not exist
478  * or elements are not in the requested format.
479  * @see ConfigException
480  */

481   public long getLong(String JavaDoc key) throws ConfigException
482   {
483     return (getLongsInternal(key, 1))[0];
484   }
485
486 /**
487  * Returns a single long integer value associated with a given key.
488  * If the key is associated with more than one element then a
489  * <code>ConfigException</code> error is thrown with <code>reason</code>
490  * set to <code>COUNT</code>. If the retrieved element cannot be
491  * converted to a long integer then a <code>ConfigException</code> error
492  * is thrown with <code>reason</code> set to <code>FORMAT</code>.
493  * @param key The key to use to search for the configuration entry.
494  * @param defaultValue The default value to use if the requested entry
495  * does not exist.
496  * @return The long integer value associated with the given key.
497  * @exception ConfigException Thrown if there was not exactly one requested
498  * element, or if the element is of the wrong data type or format.
499  * @see ConfigException
500  */

501   public long getLong(String JavaDoc key, long defaultValue) throws ConfigException {
502     try {
503       return (getLongsInternal(key, 1))[0];
504     }
505     catch (ConfigException e) {
506       if (e.reason != e.NOT_FOUND) {
507         throw e;
508       }
509       return defaultValue;
510     }
511   }
512
513 /**
514  * Returns all long integer values associated with a given key.
515  * If any of the elements associated with the key cannot be converted
516  * to a long integer then a <code>ConfigException</code> error is thrown.
517  * @param key The key to use to search for the configuration entry.
518  * @return An array of longs containing the list of long values from
519  * the configuration input stream.
520  * @exception ConfigException Thrown if the requested entry does not exist
521  * or elements are not in the requested format.
522  * @see ConfigException
523  */

524   public long[] getLongs(String JavaDoc key) throws ConfigException
525   {
526     return getLongsInternal(key, GET_ALL);
527   }
528
529 /**
530  * Returns all long integer values associated with a given key.
531  * If any of the elements associated with the key cannot be converted
532  * to a long integer then a <code>ConfigException</code> error is thrown.
533  * @param key The key to use to search for the configuration entry.
534  * @param defaultValue The default value to use if the requested entry
535  * does not exist.
536  * @return An array of longs containing the list of long values from the
537  * configuration input stream.
538  * @exception ConfigException Thrown if the requested entries are of the wrong
539  * data type or format.
540  * @see ConfigException
541  */

542   public long[] getLongs(String JavaDoc key, long[] defaultValue)
543         throws ConfigException
544   {
545     try {
546       return getLongsInternal(key, GET_ALL);
547     }
548     catch (ConfigException e) {
549       if (e.reason != e.NOT_FOUND) {
550         throw e;
551       }
552       return defaultValue;
553     }
554   }
555
556 /**
557  * Returns the array of integers associated with a given key. If the
558  * <code>count</code> parameter is not <code>GET_ALL</code> and the
559  * number of elements in the retrieved array does not match <code>
560  * count</code> then a ConfigException is thrown with <code>reason</code>
561  * set to <code>COUNT</code>.
562  * If any of the retrieved elements cannot be converted to
563  * integers due to invalid syntax or overflow, then a ConfigException
564  * is thrown with <code>reason</code> set to <code>FORMAT</code>.
565  * @param key The key to use to search for the configuration entries.
566  * @param count The number of entries expected in the result. If the number of
567  * retrieved entries does not match <code>count</code> and <code>count</code> is
568  * not <code> GET_ALL</code> then a <code>ConfigException</code> error is thrown.
569  * @return An array of integers containing the list of integer values from
570  * the configuration input stream.
571  * @exception ConfigException Thrown if the requested entry does not exist or
572  * elements are not in the requested format.
573  * @see ConfigException
574  * @see Config#GET_ALL
575  */

576   private final int[] getIntsInternal(String JavaDoc key, int count)
577         throws ConfigException
578   {
579     Object JavaDoc obj;
580     try {
581       obj = get(key);
582     }
583     catch (KeywordValueException e) {
584       throw new ConfigException(e.getMessage());
585     }
586     if (obj == null) {
587       throw new ConfigException(ConfigException.NOT_FOUND,
588                                 "Key \"" + key
589                                 + "\" not found in configuration.");
590     }
591     int[] ia = null;
592     if (obj.getClass().isArray()) {
593       int len = Array.getLength(obj);
594       ia = new int[len];
595       for (int i=0; i<len; i++) {
596         try {
597           ia[i] = (int)Integer.parseInt(Array.get(obj,i).toString());
598         }
599         catch (Throwable JavaDoc e) {
600           throw new ConfigException("Element " + i +
601                                     " is not an integer.");
602         }
603       }
604     }
605     else {
606       ia = new int[1];
607       try {
608         ia[0] = Integer.parseInt(obj.toString());
609       }
610       catch (Throwable JavaDoc e) {
611         throw new ConfigException("Element 0 is not an integer.");
612       }
613     }
614     if ((count != GET_ALL) && (ia.length != count)) {
615       throw new ConfigException(ConfigException.COUNT,
616                                 "Key \"" + key
617                                 + "\" has " + ia.length + " elements. (expected "
618                                 + count + ")");
619     }
620     return ia;
621   }
622
623 /**
624  * Returns a single integer value associated with a given key.
625  * If the key is associated with more than one element, or the
626  * retrieved element cannot be converted to a integer then a
627  * <code>ConfigException</code> exception is thrown.
628  * @param key The key to use to search for the configuration entry.
629  * @return The integer value associated with the given key.
630  * @exception ConfigException Thrown if the requested entry does not exist
631  * or elements are not in the requested format.
632  * @see ConfigException
633  */

634   public int getInt(String JavaDoc key) throws ConfigException
635   {
636     return (getIntsInternal(key, 1))[0];
637   }
638
639 /**
640  * Returns a single integer value associated with a given key.
641  * If the key is associated with more than one element, or the
642  * retrieved element cannot be converted to a integer then a
643  * <code>ConfigException</code> exception is thrown.
644  * @param key The key to use to search for the configuration entry.
645  * @param defaultValue The default value to use if the requested entry
646  * does not exist.
647  * @return The integer value associated with the given key.
648  * @exception ConfigException Thrown if there was not exactly one
649  * requested element, or if the element is of the wrong data type or format.
650  * @see ConfigException
651  */

652   public int getInt(String JavaDoc key, int defaultValue) throws ConfigException
653   {
654     try {
655       return (getIntsInternal(key, 1))[0];
656     }
657     catch (ConfigException e) {
658       if (e.reason != e.NOT_FOUND) {
659         throw e;
660       }
661       return defaultValue;
662     }
663   }
664
665 /**
666  * Returns all integer values associated with a given key.
667  * If any of the elements associated with the key cannot be converted
668  * to a integer then a <code>ConfigException</code> error is thrown.
669  * @param key The key to use to search for the configuration entry.
670  * @return An array of integers containing the list of integer values from
671  * the configuration input stream.
672  * @exception ConfigException Thrown if the requested entry does not exist
673  * or elements are not in the requested format.
674  * @see ConfigException
675  */

676   public int[] getInts(String JavaDoc key) throws ConfigException
677   {
678     return getIntsInternal(key, GET_ALL);
679   }
680
681 /**
682  * Returns all integer values associated with a given key.
683  * If any of the elements associated with the key cannot be converted
684  * to a integer then a <code>ConfigException</code> error is thrown.
685  * @param key The key to use to search for the configuration entry.
686  * @param defaultValue The default value to use if the requested entry
687  * does not exist.
688  * @return An array of integers containing the list of integer values from
689  * the configuration input stream.
690  * @exception ConfigException Thrown if the requested entries are of
691  * the wrong data type or format.
692  * @see ConfigException
693  */

694   public int[] getInts(String JavaDoc key, int[] defaultValue) throws ConfigException
695   {
696     try {
697       return getIntsInternal(key, GET_ALL);
698     }
699     catch (ConfigException e) {
700       if (e.reason != e.NOT_FOUND) {
701         throw e;
702       }
703       return defaultValue;
704     }
705   }
706
707 /**
708  * Returns the array of strings associated with a given key. If the
709  * <code>count</code> parameter is not <code>GET_ALL</code> and the
710  * number of elements in the retrieved array does not match <code>
711  * count</code> then a ConfigException is thrown with <code>reason</code>
712  * set to <code>COUNT</code>.
713  * @param key The key to use to search for the configuration entries.
714  * @param count The number of entries expected in the result. If the number of
715  * retrieved entries does not match <code>count</code> and <code>count</code> is
716  * not <code> GET_ALL</code> then a <code>ConfigException</code> error is thrown.
717  * @return An array of Strings containing the list of String values from the
718  * configuration input stream.
719  * @exception ConfigException Thrown if the requested entry does not exist
720  * or elements are not in the requested format.
721  * @see ConfigException
722  * @see Config#GET_ALL
723  */

724   private final String JavaDoc[] getStringsInternal(String JavaDoc key, int count)
725         throws ConfigException
726   {
727     Object JavaDoc obj;
728     try {
729       obj = get(key);
730     }
731     catch (KeywordValueException e) {
732       throw new ConfigException(e.getMessage());
733     }
734     if (obj == null) {
735       throw new ConfigException(ConfigException.NOT_FOUND,
736                                 "Key \"" + key
737                                 + "\" not found in configuration.");
738     }
739     String JavaDoc[] sa = null;
740     if (obj.getClass().isArray()) {
741       int len = Array.getLength(obj);
742       sa = new String JavaDoc[len];
743       for (int i=0; i<len; i++) {
744         try {
745           sa[i] = Array.get(obj,i).toString();
746         }
747         catch (Throwable JavaDoc e) {
748           throw new ConfigException("Element " + i +
749                                     " is not a String.");
750         }
751       }
752     }
753     else {
754       sa = new String JavaDoc[1];
755       try {
756         sa[0] = obj.toString();
757       }
758       catch (Throwable JavaDoc e) {
759         throw new ConfigException("Element 0 is not a String.");
760       }
761     }
762     if ((count != GET_ALL) && (sa.length != count)) {
763       throw new ConfigException(ConfigException.COUNT,
764                                 "Key \"" + key
765                                 + "\" has " + sa.length + " elements. (expected "
766                                 + count + ")");
767     }
768     return sa;
769   }
770
771 /**
772  * Returns a single String value associated with a given key.
773  * If the key is associated with more than one element, or the
774  * retrieved element cannot be converted to a String then a
775  * <code>ConfigException</code> exception is thrown.
776  * @param key The key to use to search for the configuration entry.
777  * @return The string value associated with the given key.
778  * @exception ConfigException Thrown if the requested entry does not exist
779  * or elements are not in the requested format.
780  * @see ConfigException
781  */

782   public String JavaDoc getString(String JavaDoc key)
783     throws ConfigException
784   {
785     return (getStringsInternal(key, 1))[0];
786   }
787
788 /**
789  * Returns a single String value associated with a given key.
790  * If the key is associated with more than one element, or the
791  * retrieved element cannot be converted to a String then a
792  * <code>ConfigException</code> exception is thrown.
793  * @param key The key to use to search for the configuration entry.
794  * @param defaultValue The default value to use if the requested entry
795  * does not exist.
796  * @return The string value associated with the given key.
797  * @exception ConfigException Thrown if there was not exactly one
798  * requested element, or if the element is of the wrong data type or format.
799  * @see ConfigException
800  */

801   public String JavaDoc getString(String JavaDoc key, String JavaDoc defaultValue)
802         throws ConfigException
803   {
804     try {
805       return (getStringsInternal(key, 1))[0];
806     }
807     catch (ConfigException e) {
808       if (e.reason != e.NOT_FOUND) {
809         throw e;
810       }
811       return defaultValue;
812     }
813   }
814
815 /**
816  * Returns all String values associated with a given key.
817  * If any of the elements associated with the key cannot be converted
818  * to a String then a <code>ConfigException</code> error is thrown.
819  * @param key The key to use to search for the configuration entry.
820  * @return An array of strings containing the list of string values from
821  * the configuration input stream.
822  * @exception ConfigException Thrown if the requested entry does not exist
823  * or elements are not in the requested format.
824  * @see ConfigException
825  */

826   public String JavaDoc[] getStrings(String JavaDoc key) throws ConfigException
827   {
828     return getStringsInternal(key, GET_ALL);
829   }
830
831 /**
832  * Returns all String values associated with a given key.
833  * If any of the elements associated with the key cannot be converted
834  * to a String then a <code>ConfigException</code> error is thrown.
835  * @param key The key to use to search for the configuration entry.
836  * @param defaultValue The default value to use if the requested entry
837  * does not exist.
838  * @return An array of strings containing the list of string values from
839  * the configuration input stream.
840  * @exception ConfigException Thrown if the requested entries are of
841  * the wrong data type or format.
842  * @see ConfigException
843  */

844   public String JavaDoc[] getStrings(String JavaDoc key, String JavaDoc[] defaultValue)
845         throws ConfigException
846   {
847     try {
848       return getStringsInternal(key, GET_ALL);
849     }
850     catch (ConfigException e) {
851       if (e.reason != e.NOT_FOUND) {
852         throw e;
853       }
854       return defaultValue;
855     }
856   }
857
858 /**
859  * Returns the array of booleans associated with a given key. If the
860  * <code>count</code> parameter is not <code>GET_ALL</code> and the
861  * number of elements in the retrieved array does not match <code>
862  * count</code> then a ConfigException is thrown with <code>reason</code>
863  * set to <code>COUNT</code>.
864  * If any of the retrieved elements cannot be converted to
865  * booleans due to invalid syntax or overflow, then a ConfigException
866  * is thrown with <code>reason</code> set to <code>FORMAT</code>.
867  * A boolean value is represented in a case independent manner as
868  * either the string <code>true</code> or <code>false</code>.
869  * @param key The key to use to search for the configuration entries.
870  * @param count The number of entries expected in the result. If the number of
871  * retrieved entries does not match <code>count</code> and <code>count</code> is
872  * not <code> GET_ALL</code> then a <code>ConfigException</code> error is thrown.
873  * @return An array of booleans containing the list of boolean values from
874  * the configuration input stream.
875  * @exception ConfigException Thrown if the requested entry does not exist
876  * or elements are not in the requested format.
877  * @see ConfigException
878  * @see Config#GET_ALL
879  */

880   private final boolean[] getBooleansInternal(String JavaDoc key, int count)
881         throws ConfigException
882   {
883     Object JavaDoc obj;
884     try {
885       obj = get(key);
886     }
887     catch (KeywordValueException e) {
888       throw new ConfigException(e.getMessage());
889     }
890     if (obj == null) {
891       throw new ConfigException(ConfigException.NOT_FOUND,
892                                 "Key \"" + key
893                                 + "\" not found in configuration.");
894     }
895     boolean[] ba = null;
896     if (obj.getClass().isArray()) {
897       int len = Array.getLength(obj);
898       ba = new boolean[len];
899       for (int i=0; i<len; i++) {
900         try {
901           ba[i] = Boolean.valueOf(
902           Array.get(obj,i).toString().toLowerCase()).booleanValue();
903         } catch (Throwable JavaDoc e) {
904           throw new ConfigException("Element " + i +
905                                     " is not a boolean.");
906         }
907       }
908     }
909     else {
910       ba = new boolean[1];
911       try {
912         ba[0] =
913             Boolean.valueOf(obj.toString().toLowerCase()).booleanValue();
914       }
915       catch (Throwable JavaDoc e) {
916         throw new ConfigException("Element 0 is not a boolean.");
917       }
918     }
919     if ((count != GET_ALL) && (ba.length != count)) {
920       throw new ConfigException(ConfigException.COUNT,
921                                 "Key \"" + key
922                                 + "\" has " + ba.length + " elements. (expected "
923                                 + count + ")");
924     }
925     return ba;
926   }
927
928 /**
929  * Returns a single boolean value associated with a given key.
930  * If the key is associated with more than one element, or the
931  * retrieved element cannot be converted to a boolean then a
932  * <code>ConfigException</code> exception is thrown.
933  * @param key The key to use to search for the configuration entry.
934  * @return The boolean value associated with the given key.
935  * @exception ConfigException Thrown if the requested entry does not exist
936  * or elements are not in the requested format.
937  * @see ConfigException
938  */

939   public boolean getBoolean(String JavaDoc key) throws ConfigException
940   {
941     return (getBooleansInternal(key, 1))[0];
942   }
943