Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/jcorporate/expresso/core/misc/upload/BaseValueParser.java


1   /* ====================================================================
2    * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3    *
4    * Copyright (c) 1995-2002 Jcorporate Ltd. 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. The end-user documentation included with the redistribution,
19   *    if any, must include the following acknowledgment:
20   *       "This product includes software developed by Jcorporate Ltd.
21   *        (http://www.jcorporate.com/)."
22   *    Alternately, this acknowledgment may appear in the software itself,
23   *    if and wherever such third-party acknowledgments normally appear.
24   *
25   * 4. "Jcorporate" and product names such as "Expresso" must
26   *    not be used to endorse or promote products derived from this
27   *    software without prior written permission. For written permission,
28   *    please contact info@jcorporate.com.
29   *
30   * 5. Products derived from this software may not be called "Expresso",
31   *    or other Jcorporate product names; nor may "Expresso" or other
32   *    Jcorporate product names appear in their name, without prior
33   *    written permission of Jcorporate Ltd.
34   *
35   * 6. No product derived from this software may compete in the same
36   *    market space, i.e. framework, without prior written permission
37   *    of Jcorporate Ltd. For written permission, please contact
38   *    partners@jcorporate.com.
39   *
40   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43   * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46   * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51   * SUCH DAMAGE.
52   * ====================================================================
53   *
54   * This software consists of voluntary contributions made by many
55   * individuals on behalf of the Jcorporate Ltd. Contributions back
56   * to the project(s) are encouraged when you make modifications.
57   * Please send them to support@jcorporate.com. For more information
58   * on Jcorporate Ltd. and its products, please see
59   * <http://www.jcorporate.com/>.
60   *
61   * Portions of this software are based upon other open source
62   * products and are subject to their respective licenses.
63   */
64  
65  package com.jcorporate.expresso.core.misc.upload;
66  
67  import java.beans.IndexedPropertyDescriptor;
68  import java.beans.Introspector;
69  import java.beans.PropertyDescriptor;
70  import java.io.UnsupportedEncodingException;
71  import java.lang.reflect.Method;
72  import java.math.BigDecimal;
73  import java.util.Enumeration;
74  import java.util.Hashtable;
75  
76  
77  // Turbine stuff
78  //import org.apache.turbine.util.DateSelector;
79  
80  /**
81   * BaseValueParser is a base class for classes that need to parse
82   * name/value Parameters, for example GET/POST data or Cookies
83   * (DefaultParameterParser and DefaultCookieParser)
84   * <p/>
85   * <p>It can also be used standalone, for an example see DataStreamParser.
86   * <p/>
87   * <p>NOTE: The name= portion of a name=value pair may be converted
88   * to lowercase or uppercase when the object is initialized and when
89   * new data is added.  This behaviour is determined by the url.case.folding
90   * property in TurbineResources.properties.  Adding a name/value pair may
91   * overwrite existing name=value pairs if the names match:
92   * <p/>
93   * <pre>
94   * ValueParser vp = new BaseValueParser();
95   * vp.add("ERROR",1);
96   * vp.add("eRrOr",2);
97   * int result = vp.getInt("ERROR");
98   * </pre>
99   * <p/>
100  * In the above example, result is 2.
101  *
102  * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
103  * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a>
104  * @author <a href="mailto:sean@informage.net">Sean Legassick</a>
105  * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
106  * @version $Id: BaseValueParser.java,v 1.7 2004/11/18 02:03:27 lhamel Exp $
107  */
108 public class BaseValueParser
109         implements ValueParser {
110 
111     /**
112      * Random access storage for parameter data.
113      */
114     protected Hashtable parameters = new Hashtable();
115 
116     /**
117      * The character encoding to use when converting to byte arrays
118      */
119     private String characterEncoding = "US-ASCII";
120 
121     /**
122      * A static version of the convert method, which
123      * trims the string data and applies the conversion specified in
124      * the property given by URL_CASE_FOLDING.  It returns a new
125      * string so that it does not destroy the value data.
126      *
127      * @param value A String to be processed.
128      * @return A new String converted to lowercase and trimmed.
129      */
130     public static String convertAndTrim(String value) {
131         return value.trim();
132     }
133 
134     /**
135      * Default constructor
136      */
137     public BaseValueParser() {
138         super();
139     }
140 
141     /**
142      * Constructor that takes a character encoding
143      */
144     public BaseValueParser(String newEncoding) {
145         super();
146         characterEncoding = newEncoding;
147     }
148 
149     /**
150      * Disposes the parser.
151      */
152     public void dispose() {
153         clear();
154     }
155 
156     /**
157      * Clear all name/value pairs out of this object.
158      */
159     public void clear() {
160         parameters.clear();
161     }
162 
163     /**
164      * Set the character encoding that will be used by this ValueParser.
165      */
166     public void setCharacterEncoding(String s) {
167         characterEncoding = s;
168     }
169 
170     /**
171      * Get the character encoding that will be used by this ValueParser.
172      */
173     public String getCharacterEncoding() {
174         return characterEncoding;
175     }
176 
177     /**
178      * Add a name/value pair into this object.
179      *
180      * @param name  A String with the name.
181      * @param value A double with the value.
182      */
183     public void add(String name, double value) {
184         add(name, Double.toString(value));
185     }
186 
187     /**
188      * Add a name/value pair into this object.
189      *
190      * @param name  A String with the name.
191      * @param value An int with the value.
192      */
193     public void add(String name, int value) {
194         add(name, Integer.toString(value));
195     }
196 
197     /**
198      * Add a name/value pair into this object.
199      *
200      * @param name  A String with the name.
201      * @param value An Integer with the value.
202      */
203     public void add(String name, Integer value) {
204         add(name, value.toString());
205     }
206 
207     /**
208      * Add a name/value pair into this object.
209      *
210      * @param name  A String with the name.
211      * @param value A long with the value.
212      */
213     public void add(String name, long value) {
214         add(name, Long.toString(value));
215     }
216 
217     /**
218      * Add a name/value pair into this object.
219      *
220      * @param name  A String with the name.
221      * @param value A long with the value.
222      */
223     public void add(String name, String value) {
224         append(name, value);
225     }
226 
227     /**
228      * Add a String parameters.  If there are any Strings already
229      * associated with the name, append to the array.  This is used
230      * for handling parameters from mulitipart POST requests.
231      *
232      * @param name  A String with the name.
233      * @param value A String with the value.
234      */
235     public void append(String name, String value) {
236         String[] items = this.getStrings(name);
237 
238         if (items == null) {
239             items = new String[1];
240             items[0] = value;
241             parameters.put(convert(name), items);
242         } else {
243             String[] newItems = new String[items.length + 1];
244             System.arraycopy(items, 0, newItems, 0, items.length);
245             newItems[items.length] = value;
246             parameters.put(convert(name), newItems);
247         }
248     }
249 
250     /**
251      * Removes the named parameter from the contained hashtable. Wraps to the
252      * contained <code>Hashtable.remove()</code>.
253      *
254      * @return The value that was mapped to the key (a <code>String[]</code>)
255      *         or <code>null</code> if the key was not mapped.
256      */
257     public Object remove(String name) {
258         return parameters.remove(convert(name));
259     }
260 
261     /**
262      * Trims the string data and applies the conversion specified in
263      * the property given by URL_CASE_FOLDING.  It returns a new
264      * string so that it does not destroy the value data.
265      *
266      * @param value A String to be processed.
267      * @return A new String converted to lowercase and trimmed.
268      */
269     public String convert(String value) {
270         return convertAndTrim(value);
271     }
272 
273     /**
274      * Determine whether a given key has been inserted.  All keys are
275      * stored in lowercase strings, so override method to account for
276      * this.
277      *
278      * @param key An Object with the key to search for.
279      * @return True if the object is found.
280      */
281     public boolean containsKey(Object key) {
282         return parameters.containsKey(convert((String) key));
283     }
284 
285     /*
286 
287      * Get an enumerator for the parameter keys. Wraps to the
288 
289      * contained <code>Hashtable.keys()</code>.
290 
291      *
292 
293      * @return An <code>enumerator</code> of the keys.
294 
295      */
296     public Enumeration keys() {
297         return parameters.keys();
298     }
299 
300     /*
301 
302      * Returns all the available parameter names.
303 
304      *
305 
306      * @return A object array with the keys.
307 
308      */
309     public Object[] getKeys() {
310         return parameters.keySet().toArray();
311     }
312 
313     /**
314      * Return a boolean for the given name.  If the name does not
315      * exist, return defaultValue.
316      *
317      * @param name         A String with the name.
318      * @param defaultValue The default value.
319      * @return A boolean.
320      */
321     public boolean getBoolean(String name, boolean defaultValue) {
322         boolean value = defaultValue;
323         Object object = parameters.get(convert(name));
324 
325         if (object != null) {
326             String tmp = getString(name);
327 
328             if (tmp.equalsIgnoreCase("1") || tmp.equalsIgnoreCase("true") ||
329                     tmp.equalsIgnoreCase("on")) {
330                 value = true;
331             }
332             if (tmp.equalsIgnoreCase("0") || tmp.equalsIgnoreCase("false")) {
333                 value = false;
334             }
335         }
336 
337         return value;
338     }
339 
340     /**
341      * Return a boolean for the given name.  If the name does not
342      * exist, return false.
343      *
344      * @param name A String with the name.
345      * @return A boolean.
346      */
347     public boolean getBoolean(String name) {
348         return getBoolean(name, false);
349     }
350 
351     /**
352      * Return a Boolean for the given name.  If the name does not
353      * exist, return defaultValue.
354      *
355      * @param name         A String with the name.
356      * @param defaultValue The default value.
357      * @return A Boolean.
358      */
359     public Boolean getBool(String name, boolean defaultValue) {
360         if (getBoolean(name, defaultValue)) {
361             return Boolean.TRUE;
362         } else {
363             return Boolean.FALSE;
364         }
365     }
366 
367     /**
368      * Return a Boolean for the given name.  If the name does not
369      * exist, return false.
370      *
371      * @param name A String with the name.
372      * @return A Boolean.
373      */
374     public Boolean getBool(String name) {
375         return getBool(name, false);
376     }
377 
378     /**
379      * Return a double for the given name.  If the name does not
380      * exist, return defaultValue.
381      *
382      * @param name         A String with the name.
383      * @param defaultValue The default value.
384      * @return A double.
385      */
386     public double getDouble(String name, double defaultValue) {
387         double value = defaultValue;
388 
389         try {
390             Object object = parameters.get(convert(name));
391 
392             if (object != null) {
393                 value = Double.valueOf(((String[]) object)[0]).doubleValue();
394             }
395         } catch (NumberFormatException exception) {
396         }
397 
398         return value;
399     }
400 
401     /**
402      * Return a double for the given name.  If the name does not
403      * exist, return 0.0.
404      *
405      * @param name A String with the name.
406      * @return A double.
407      */
408     public double getDouble(String name) {
409         return getDouble(name, 0.0);
410     }
411 
412     /**
413      * Return a float for the given name.  If the name does not
414      * exist, return defaultValue.
415      *
416      * @param name         A String with the name.
417      * @param defaultValue The default value.
418      * @return A float.
419      */
420     public float getFloat(String name, float defaultValue) {
421         float value = defaultValue;
422 
423         try {
424             Object object = parameters.get(convert(name));
425 
426             if (object != null) {
427                 value = Float.valueOf(((String[]) object)[0]).floatValue();
428             }
429         } catch (NumberFormatException exception) {
430         }
431 
432         return value;
433     }
434 
435     /**
436      * Return a float for the given name.  If the name does not
437      * exist, return 0.0.
438      *
439      * @param name A String with the name.
440      * @return A float.
441      */
442     public float getFloat(String name) {
443         return getFloat(name, 0.0f);
444     }
445 
446     /**
447      * Return a BigDecimal for the given name.  If the name does not
448      * exist, return 0.0.
449      *
450      * @param name         A String with the name.
451      * @param defaultValue The default value.
452      * @return A BigDecimal.
453      */
454     public BigDecimal getBigDecimal(String name, BigDecimal defaultValue) {
455         BigDecimal value = defaultValue;
456 
457         try {
458             Object object = parameters.get(convert(name));
459 
460             if (object != null) {
461                 value = new BigDecimal(((String[]) object)[0]);
462             }
463         } catch (NumberFormatException exception) {
464         }
465 
466         return value;
467     }
468 
469     /**
470      * Return a BigDecimal for the given name.  If the name does not
471      * exist, return 0.0.
472      *
473      * @param name A String with the name.
474      * @return A BigDecimal.
475      */
476     public BigDecimal getBigDecimal(String name) {
477         return getBigDecimal(name, new BigDecimal(0.0));
478     }
479 
480     /**
481      * Return an array of BigDecimals for the given name.  If the name
482      * does not exist, return null.
483      *
484      * @param name A String with the name.
485      * @return A BigDecimal[].
486      */
487     public BigDecimal[] getBigDecimals(String name) {
488         BigDecimal[] value = null;
489         Object object = getStrings(convert(name));
490 
491         if (object != null) {
492             String[] temp = (String[]) object;
493             value = new BigDecimal[temp.length];
494 
495             for (int i = 0; i < temp.length; i++) {
496                 value[i] = new BigDecimal(temp[i]);
497             }
498         }
499 
500         return value;
501     }
502 
503     /**
504      * Return an int for the given name.  If the name does not exist,
505      * return defaultValue.
506      *
507      * @param name         A String with the name.
508      * @param defaultValue The default value.
509      * @return An int.
510      */
511     public int getInt(String name, int defaultValue) {
512         int value = defaultValue;
513 
514         try {
515             Object object = parameters.get(convert(name));
516 
517             if (object != null) {
518                 value = Integer.valueOf(((String[]) object)[0]).intValue();
519             }
520         } catch (NumberFormatException exception) {
521         }
522 
523         return value;
524     }
525 
526     /**
527      * Return an int for the given name.  If the name does not exist,
528      * return 0.
529      *
530      * @param name A String with the name.
531      * @return An int.
532      */
533     public int getInt(String name) {
534         return getInt(name, 0);
535     }
536 
537     /**
538      * Return an Integer for the given name.  If the name does not
539      * exist, return defaultValue.
540      *
541      * @param name         A String with the name.
542      * @param defaultValue The default value.
543      * @return An Integer.
544      */
545     public Integer getInteger(String name, int defaultValue) {
546         return new Integer(getInt(name, defaultValue));
547     }
548 
549     /**
550      * Return an Integer for the given name.  If the name does not
551      * exist, return defaultValue.  You cannot pass in a null here for
552      * the default value.
553      *
554      * @param name         A String with the name.
555      * @param defaultValue The default value.
556      * @return An Integer.
557      */
558     public Integer getInteger(String name, Integer def) {
559         return new Integer(getInt(name, def.intValue()));
560     }
561 
562     /**
563      * Return an Integer for the given name.  If the name does not
564      * exist, return 0.
565      *
566      * @param name A String with the name.
567      * @return An Integer.
568      */
569     public Integer getInteger(String name) {
570         return new Integer(getInt(name, 0));
571     }
572 
573     /**
574      * Return an array of ints for the given name.  If the name does
575      * not exist, return null.
576      *
577      * @param name A String with the name.
578      * @return An int[].
579      */
580     public int[] getInts(String name) {
581         int[] value = null;
582         Object object = getStrings(convert(name));
583 
584         if (object != null) {
585             String[] temp = (String[]) object;
586             value = new int[temp.length];
587 
588             for (int i = 0; i < temp.length; i++) {
589                 value[i] = Integer.parseInt(temp[i]);
590             }
591         }
592 
593         return value;
594     }
595 
596     /**
597      * Return an array of Integers for the given name.  If the name
598      * does not exist, return null.
599      *
600      * @param name A String with the name.
601      * @return An Integer[].
602      */
603     public Integer[] getIntegers(String name) {
604         Integer[] value = null;
605         Object object = getStrings(convert(name));
606 
607         if (object != null) {
608             String[] temp = (String[]) object;
609             value = new Integer[temp.length];
610 
611             for (int i = 0; i < temp.length; i++) {
612                 value[i] = Integer.valueOf(temp[i]);
613             }
614         }
615 
616         return value;
617     }
618 
619     /**
620      * Return a long for the given name.  If the name does not exist,
621      * return defaultValue.
622      *
623      * @param name         A String with the name.
624      * @param defaultValue The default value.
625      * @return A long.
626      */
627     public long getLong(String name, long defaultValue) {
628         long value = defaultValue;
629 
630         try {
631             Object object = parameters.get(convert(name));
632 
633             if (object != null) {
634                 value = Long.valueOf(((String[]) object)[0]).longValue();
635             }
636         } catch (NumberFormatException exception) {
637         }
638 
639         return value;
640     }
641 
642     /**
643      * Return a long for the given name.  If the name does not exist,
644      * return 0.
645      *
646      * @param name A String with the name.
647      * @return A long.
648      */
649     public long getLong(String name) {
650         return getLong(name, 0);
651     }
652 
653     /**
654      * Return an array of longs for the given name.  If the name does
655      * not exist, return null.
656      *
657      * @param name A String with the name.
658      * @return A long[].
659      */
660     public long[] getLongs(String name) {
661         long[] value = null;
662         Object object = getStrings(convert(name));
663 
664         if (object != null) {
665             String[] temp = (String[]) object;
666             value = new long[temp.length];
667 
668             for (int i = 0; i < temp.length; i++) {
669                 value[i] = Long.parseLong(temp[i]);
670             }
671         }
672 
673         return value;
674     }
675 
676     /**
677      * Return an array of Longs for the given name.  If the name does
678      * not exist, return null.
679      *
680      * @param name A String with the name.
681      * @return A Long[].
682      */
683     public Long[] getLongObjects(String name) {
684         Long[] value = null;
685         Object object = getStrings(convert(name));
686 
687         if (object != null) {
688             String[] temp = (String[]) object;
689             value = new Long[temp.length];
690 
691             for (int i = 0; i < temp.length; i++) {
692                 value[i] = Long.valueOf(temp[i]);
693             }
694         }
695 
696         return value;
697     }
698 
699     /**
700      * Return a byte for the given name.  If the name does not exist,
701      * return defaultValue.
702      *
703      * @param name         A String with the name.
704      * @param defaultValue The default value.
705      * @return A byte.
706      */
707     public byte getByte(String name, byte defaultValue) {
708         byte value = defaultValue;
709 
710         try {
711             Object object = parameters.get(convert(name));
712 
713             if (object != null) {
714                 value = Byte.valueOf(((String[]) object)[0]).byteValue();
715             }
716         } catch (NumberFormatException exception) {
717         }
718 
719         return value;
720     }
721 
722     /**
723      * Return a byte for the given name.  If the name does not exist,
724      * return 0.
725      *
726      * @param name A String with the name.
727      * @return A byte.
728      */
729     public byte getByte(String name) {
730         return getByte(name, (byte) 0);
731     }
732 
733     /**
734      * Return an array of bytes for the given name.  If the name does
735      * not exist, return null. The array is returned according to the
736      * HttpRequest's character encoding.
737      *
738      * @param name A String with the name.
739      * @return A byte[].
740      */
741     public byte[] getBytes(String name)
742             throws UnsupportedEncodingException {
743         String tempStr = getString(name);
744 
745         if (tempStr != null) {
746             return tempStr.getBytes(characterEncoding);
747         }
748 
749         return null;
750     }
751 
752     /**
753      * Return a String for the given name.  If the name does not
754      * exist, return null.
755      *
756      * @param name A String with the name.
757      * @return A String.
758      */
759     public String getString(String name) {
760         try {
761             String value = null;
762             Object object = parameters.get(convert(name));
763 
764             if (object != null) {
765                 value = ((String[]) object)[0];
766             }
767             if (value == null || value.equals("null")) {
768                 return null;
769             }
770 
771             return value;
772         } catch (ClassCastException e) {
773             return null;
774         }
775     }
776 
777     /**
778      * Return a String for the given name.  If the name does not
779      * exist, return null. It is the same as the getString() method
780      * however has been added for simplicity when working with
781      * template tools such as Velocity which allow you to do
782      * something like this:
783      * <p/>
784      * <code>$data.Parameters.form_variable_name</code>
785      *
786      * @param name A String with the name.
787      * @return A String.
788      */
789     public String get(String name) {
790         return getString(name);
791     }
792 
793     /**
794      * Return a String for the given name.  If the name does not
795      * exist, return the defaultValue.
796      *
797      * @param name         A String with the name.
798      * @param defaultValue The default value.
799      * @return A String.
800      */
801     public String getString(String name, String defaultValue) {
802         String value = getString(name);
803 
804         if (value == null || value.length() == 0 || value.equals("null")) {
805             return defaultValue;
806         } else {
807             return value;
808         }
809     }
810 
811     /**
812      * Set a parameter to a specific value.
813      * <p/>
814      * This is useful if you want your action to override the values
815      * of the parameters for the screen to use.
816      *
817      * @param name  The name of the parameter.
818      * @param value The value to set.
819      */
820     public void setString(String name, String value) {
821         if (value != null) {
822             parameters.put(convert(name), new String[]{value});
823         }
824     }
825 
826     /**
827      * Return an array of Strings for the given name.  If the name
828      * does not exist, return null.
829      *
830      * @param name A String with the name.
831      * @return A String[].
832      */
833     public String[] getStrings(String name) {
834         String[] value = null;
835         Object object = parameters.get(convert(name));
836 
837         if (object != null) {
838             if (object instanceof String[]) {
839                 value = (String[]) object;
840             }
841         }
842 
843         return value;
844     }
845 
846     /**
847      * Return an array of Strings for the given name.  If the name
848      * does not exist, return the defaultValue.
849      *
850      * @param name         A String with the name.
851      * @param defaultValue The default value.
852      * @return A String[].
853      */
854     public String[] getStrings(String name, String[] defaultValue) {
855         String[] value = getStrings(name);
856 
857         if (value == null || value.length == 0) {
858             return defaultValue;
859         } else {
860             return value;
861         }
862     }
863 
864     /**
865      * Set a parameter to a specific value.
866      * <p/>
867      * This is useful if you want your action to override the values
868      * of the parameters for the screen to use.
869      *
870      * @param name   The name of the parameter.
871      * @param values The value to set.
872      */
873     public void setStrings(String name, String[] values) {
874         if (values != null) {
875             parameters.put(convert(name), values);
876         }
877     }
878 
879     /**
880      * Return an Object for the given name.  If the name does not
881      * exist, return null.
882      *
883      * @param name A String with the name.
884      * @return An Object.
885      */
886     public Object getObject(String name) {
887         try {
888             Object value = null;
889             Object object = parameters.get(convert(name));
890 
891             if (object != null) {
892                 value = ((Object[]) object)[0];
893             }
894 
895             return value;
896         } catch (ClassCastException e) {
897             return null;
898         }
899     }
900 
901     /**
902      * Return an array of Objects for the given name.  If the name
903      * does not exist, return null.
904      *
905      * @param name A String with the name.
906      * @return An Object[].
907      */
908     public Object[] getObjects(String name) {
909         try {
910             return (Object[]) parameters.get(convert(name));
911         } catch (ClassCastException e) {
912             return null;
913         }
914     }
915 
916     /**
917      * Uses bean introspection to set writable properties of bean from
918      * the parameters, where a (case-insensitive) name match between
919      * the bean property and the parameter is looked for.
920      *
921      * @param bean An Object.
922      * @throws Exception, a generic exception.
923      */
924     public void setProperties(Object bean)
925             throws Exception {
926         Class beanClass = bean.getClass();
927         PropertyDescriptor[] props = Introspector.getBeanInfo(beanClass).getPropertyDescriptors();
928 
929         for (int i = 0; i < props.length; i++) {
930             String propname = props[i].getName();
931             Method setter = props[i].getWriteMethod();
932 
933             if (setter != null && (containsKey(propname))) {
934                 setProperty(bean, props[i]);
935             }
936         }
937     }
938 
939     /**
940      * Simple method that attempts to get a toString() representation
941      * of this object.  It doesn't do well with String[]'s though.
942      *
943      * @return A String.
944      */
945     public String toString() {
946         StringBuffer sb = new StringBuffer();
947 
948         for (Enumeration e = parameters.keys(); e.hasMoreElements();) {
949             String name = (String) e.nextElement();
950 
951             try {
952                 sb.append("{");
953                 sb.append(name);
954                 sb.append("=");
955 
956                 String[] params = this.getStrings(name);
957 
958                 if (params.length <= 1) {
959                     sb.append(params[0]);
960                 } else {
961                     for (int i = 0; i < params.length; i++) {
962                         if (i != 0) {
963                             sb.append(", ");
964                         }
965 
966                         sb.append('[').append(params[i]).append(']');
967                     }
968                 }
969 
970                 sb.append("}\n");
971             } catch (Exception ee) {
972                 try {
973                     sb.append("{");
974                     sb.append(name);
975                     sb.append("=");
976                     sb.append("ERROR?");
977                     sb.append("}\n");
978                 } catch (Exception eee) {
979                 }
980             }
981         }
982 
983         return sb.toString();
984     }
985 
986     /**
987      * Set the property 'prop' in the bean to the value of the
988      * corresponding parameters.  Supports all types supported by
989      * getXXX methods plus a few more that come for free because
990      * primitives have to be wrapped before being passed to invoke
991      * anyway.
992      *
993      * @param bean An Object.
994      * @param prop A PropertyDescriptor.
995      * @throws Exception, a generic exception.
996      */
997     private void setProperty(Object bean, PropertyDescriptor prop)
998             throws Exception {
999         if (prop instanceof IndexedPropertyDescriptor) {
1000            throw new Exception(prop.getName() +
1001                    " is an indexed property (not supported)");
1002        }
1003
1004        Method setter = prop.getWriteMethod();
1005
1006        if (setter == null) {
1007            throw new Exception(prop.getName() + " is a read only property");
1008        }
1009
1010        Class propclass = prop.getPropertyType();
1011        Object[] args = {null};
1012
1013        if (propclass == String.class) {
1014            args[0] = getString(prop.getName());
1015        } else if (propclass == Integer.class || propclass == Integer.TYPE) {
1016            args[0] = getInteger(prop.getName());
1017        } else if (propclass == Long.class || propclass == Long.TYPE) {
1018            args[0] = new Long(getLong(prop.getName()));
1019        } else if (propclass == Boolean.class || propclass == Boolean.TYPE) {
1020            args[0] = getBool(prop.getName());
1021        } else if (propclass == Double.class || propclass == Double.TYPE) {
1022            args[0] = new Double(getDouble(prop.getName()));
1023        } else if (propclass == String[].class) {
1024            args[0] = getStrings(prop.getName());
1025        } else if (propclass == Object.class) {
1026            args[0] = getObject(prop.getName());
1027        } else if (propclass == int[].class) {
1028            args[0] = getInts(prop.getName());
1029        } else if (propclass == Integer[].class) {
1030            args[0] = getIntegers(prop.getName());
1031        } else {
1032            throw new Exception("property " + prop.getName() +
1033                    " is of unsupported type " +
1034                    propclass.toString());
1035        }
1036
1037        setter.invoke(bean, args);
1038    }
1039}