Coverage Report - org.apache.fulcrum.parser.BaseValueParser
 
Classes in this File Line Coverage Branch Coverage Complexity
BaseValueParser
89%
300/336
75%
167/220
2,221
 
 1  
 package org.apache.fulcrum.parser;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import java.beans.IndexedPropertyDescriptor;
 23  
 import java.beans.Introspector;
 24  
 import java.beans.PropertyDescriptor;
 25  
 import java.io.UnsupportedEncodingException;
 26  
 import java.lang.reflect.Method;
 27  
 import java.math.BigDecimal;
 28  
 import java.text.DateFormat;
 29  
 import java.text.NumberFormat;
 30  
 import java.text.ParseException;
 31  
 import java.text.ParsePosition;
 32  
 import java.util.Date;
 33  
 import java.util.Hashtable;
 34  
 import java.util.Iterator;
 35  
 import java.util.Locale;
 36  
 import java.util.Set;
 37  
 
 38  
 import org.apache.avalon.framework.logger.LogEnabled;
 39  
 import org.apache.avalon.framework.logger.Logger;
 40  
 import org.apache.commons.lang3.ArrayUtils;
 41  
 import org.apache.commons.lang3.StringUtils;
 42  
 
 43  
 /**
 44  
  * BaseValueParser is a base class for classes that need to parse
 45  
  * name/value Parameters, for example GET/POST data or Cookies
 46  
  * (DefaultParameterParser and DefaultCookieParser)
 47  
  *
 48  
  * <p>It can also be used standalone, for an example see DataStreamParser.
 49  
  *
 50  
  * <p>NOTE: The name= portion of a name=value pair may be converted
 51  
  * to lowercase or uppercase when the object is initialized and when
 52  
  * new data is added.  This behavior is determined by the url.case.folding
 53  
  * property in TurbineResources.properties.  Adding a name/value pair may
 54  
  * overwrite existing name=value pairs if the names match:
 55  
  *
 56  
  * <pre>
 57  
  * ValueParser vp = new BaseValueParser();
 58  
  * vp.add("ERROR",1);
 59  
  * vp.add("eRrOr",2);
 60  
  * int result = vp.getInt("ERROR");
 61  
  * </pre>
 62  
  *
 63  
  * In the above example, result is 2.
 64  
  *
 65  
  * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
 66  
  * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a>
 67  
  * @author <a href="mailto:sean@informage.net">Sean Legassick</a>
 68  
  * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
 69  
  * @author <a href="mailto:jh@byteaction.de">J&#252;rgen Hoffmann</a>
 70  
  * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
 71  
  * @version $Id: BaseValueParser.java 1851537 2019-01-17 15:22:22Z painter $
 72  
  */
 73  
 public class BaseValueParser
 74  
     implements ValueParser,
 75  
                ParserServiceSupport, LogEnabled
 76  
 {
 77  
     /** The ParserService instance to query for conversion and configuration */
 78  
     protected ParserService parserService;
 79  
 
 80  
     /** A convenience logger */
 81  
     private Logger logger;
 82  
 
 83  
     /** String values which would evaluate to Boolean.TRUE */
 84  2
     private static final String[] trueValues = {"TRUE","T","YES","Y","1","ON"};
 85  
 
 86  
     /** String values which would evaluate to Boolean.FALSE */
 87  2
     private static final String[] falseValues = {"FALSE","F","NO","N","0","OFF"};
 88  
 
 89  
     /**
 90  
      * The character encoding to use when converting to byte arrays
 91  
      */
 92  140
     private String characterEncoding = DEFAULT_CHARACTER_ENCODING;
 93  
 
 94  
     /**
 95  
      * Random access storage for parameter data.
 96  
      */
 97  140
     protected Hashtable<String, Object> parameters = new Hashtable<String, Object>();
 98  
 
 99  
     /** The locale to use when converting dates, floats and decimals */
 100  140
     private Locale locale = Locale.getDefault();
 101  
 
 102  
     /** The DateFormat to use for converting dates */
 103  140
     private DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale);
 104  
 
 105  
     /** The NumberFormat to use when converting floats and decimals */
 106  140
     private NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);
 107  
 
 108  
     public BaseValueParser()
 109  
     {
 110  140
         this(DEFAULT_CHARACTER_ENCODING);
 111  140
     }
 112  
 
 113  
     /**
 114  
      * Constructor that takes a character encoding
 115  
      * 
 116  
      * @param characterEncoding desired character encoding
 117  
      */
 118  
     public BaseValueParser(String characterEncoding)
 119  
     {
 120  140
         this(characterEncoding, Locale.getDefault());
 121  140
     }
 122  
 
 123  
     /**
 124  
      * Constructor that takes a character encoding and a locale
 125  
      * 
 126  
      * @param characterEncoding Sets the character encoding
 127  
      * @param locale Sets the locale
 128  
      */
 129  
     public BaseValueParser(String characterEncoding, Locale locale)
 130  
     {
 131  140
         super();
 132  140
         recycle(characterEncoding);
 133  140
         setLocale(locale);
 134  140
     }
 135  
 
 136  
     /**
 137  
      * Set a ParserService instance
 138  
      * 
 139  
      * @param parserService The parser service instance
 140  
      */
 141  
     @Override
 142  
     public void setParserService(ParserService parserService)
 143  
     {
 144  148
         this.parserService = parserService;
 145  148
     }
 146  
 
 147  
     /**
 148  
      * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(org.apache.avalon.framework.logger.Logger)
 149  
      * @param logger The logger to be used
 150  
      */
 151  
     @Override
 152  
     public void enableLogging(Logger logger)
 153  
     {
 154  142
         this.logger = logger;
 155  142
     }
 156  
 
 157  
     /**
 158  
      * Provide an Avalon logger to the derived classes
 159  
      *
 160  
      * @return An Avalon logger instance
 161  
      */
 162  
     protected Logger getLogger()
 163  
     {
 164  138
         return logger;
 165  
     }
 166  
 
 167  
     /**
 168  
      * Recycles the parser.
 169  
      */
 170  
     public void recycle()
 171  
     {
 172  2
         recycle(DEFAULT_CHARACTER_ENCODING);
 173  2
     }
 174  
 
 175  
     /**
 176  
      * Recycles the parser with a character encoding.
 177  
      *
 178  
      * @param characterEncoding the character encoding.
 179  
      */
 180  
     public void recycle(String characterEncoding)
 181  
     {
 182  142
         setCharacterEncoding(characterEncoding);
 183  142
     }
 184  
 
 185  
     /**
 186  
      * Disposes the parser.
 187  
      */
 188  
     public void dispose()
 189  
     {
 190  136
         clear();
 191  136
         disposed = true;
 192  136
     }
 193  
 
 194  
     /**
 195  
      * Clear all name/value pairs out of this object.
 196  
      */
 197  
     @Override
 198  
     public void clear()
 199  
     {
 200  478
         parameters.clear();
 201  478
     }
 202  
 
 203  
     /**
 204  
      * Set the character encoding that will be used by this ValueParser.
 205  
      */
 206  
     @Override
 207  
     public void setCharacterEncoding(String s)
 208  
     {
 209  158
         characterEncoding = s;
 210  158
     }
 211  
 
 212  
     /**
 213  
      * Get the character encoding that will be used by this ValueParser.
 214  
      */
 215  
     @Override
 216  
     public String getCharacterEncoding()
 217  
     {
 218  28
         return characterEncoding;
 219  
     }
 220  
 
 221  
     /**
 222  
      * Set the locale that will be used by this ValueParser.
 223  
      */
 224  
     @Override
 225  
     public void setLocale(Locale l)
 226  
     {
 227  144
         locale = l;
 228  144
         setDateFormat(DateFormat.getDateInstance(DateFormat.SHORT, locale));
 229  144
         setNumberFormat(NumberFormat.getNumberInstance(locale));
 230  144
     }
 231  
 
 232  
     /**
 233  
      * Get the locale that will be used by this ValueParser.
 234  
      */
 235  
     @Override
 236  
     public Locale getLocale()
 237  
     {
 238  0
         return locale;
 239  
     }
 240  
 
 241  
     /**
 242  
      * Set the date format that will be used by this ValueParser.
 243  
      */
 244  
     @Override
 245  
     public void setDateFormat(DateFormat df)
 246  
     {
 247  144
         dateFormat = df;
 248  144
     }
 249  
 
 250  
     /**
 251  
      * Get the date format that will be used by this ValueParser.
 252  
      */
 253  
     @Override
 254  
     public DateFormat getDateFormat()
 255  
     {
 256  0
         return dateFormat;
 257  
     }
 258  
 
 259  
     /**
 260  
      * Set the number format that will be used by this ValueParser.
 261  
      */
 262  
     @Override
 263  
     public void setNumberFormat(NumberFormat nf)
 264  
     {
 265  144
         numberFormat = nf;
 266  144
     }
 267  
 
 268  
     /**
 269  
      * Get the number format that will be used by this ValueParser.
 270  
      */
 271  
     @Override
 272  
     public NumberFormat getNumberFormat()
 273  
     {
 274  0
         return numberFormat;
 275  
     }
 276  
 
 277  
     /**
 278  
      * Add a name/value pair into this object.
 279  
      *
 280  
      * @param name A String with the name.
 281  
      * @param value A double with the value.
 282  
      */
 283  
     @Override
 284  
     public void add(String name, double value)
 285  
     {
 286  20
         add(name, numberFormat.format(value));
 287  20
     }
 288  
 
 289  
     /**
 290  
      * Add a name/value pair into this object.
 291  
      *
 292  
      * @param name A String with the name.
 293  
      * @param value An int with the value.
 294  
      */
 295  
     @Override
 296  
     public void add(String name, int value)
 297  
     {
 298  34
         add(name, (long)value);
 299  34
     }
 300  
 
 301  
     /**
 302  
      * Add a name/value pair into this object.
 303  
      *
 304  
      * @param name A String with the name.
 305  
      * @param value An Integer with the value.
 306  
      */
 307  
     @Override
 308  
     public void add(String name, Integer value)
 309  
     {
 310  2
         if (value != null)
 311  
         {
 312  2
             add(name, value.intValue());
 313  
         }
 314  2
     }
 315  
 
 316  
     /**
 317  
      * Add a name/value pair into this object.
 318  
      *
 319  
      * @param name A String with the name.
 320  
      * @param value A long with the value.
 321  
      */
 322  
     @Override
 323  
     public void add(String name, long value)
 324  
     {
 325  54
         add(name, Long.toString(value));
 326  54
     }
 327  
 
 328  
     /**
 329  
      * Add a name/value pair into this object.
 330  
      *
 331  
      * @param name A String with the name.
 332  
      * @param value A long with the value.
 333  
      */
 334  
     @Override
 335  
     public void add(String name, String value)
 336  
     {
 337  408
         if (value != null)
 338  
         {
 339  404
             String [] items = getParam(name);
 340  404
             items = ArrayUtils.add(items, value);
 341  404
             putParam(name, items);
 342  
         }
 343  408
     }
 344  
 
 345  
     /**
 346  
      * Add an array of Strings for a key. This
 347  
      * is simply adding all the elements in the
 348  
      * array one by one.
 349  
      *
 350  
      * @param name A String with the name.
 351  
      * @param value A String Array.
 352  
      */
 353  
     @Override
 354  
     public void add(String name, String [] value)
 355  
     {
 356  
         // ArrayUtils.addAll() looks promising but it would also add
 357  
         // null values into the parameters array, so we can't use that.
 358  18
         if (value != null)
 359  
         {
 360  62
             for (int i = 0 ; i < value.length; i++)
 361  
             {
 362  46
                 if (value[i] != null)
 363  
                 {
 364  42
                     add(name, value[i]);
 365  
                 }
 366  
             }
 367  
         }
 368  18
     }
 369  
 
 370  
     /**
 371  
      * Removes the named parameter from the contained hashtable. Wraps to the
 372  
      * contained <code>Map.remove()</code>.
 373  
      *
 374  
      * @return The value that was mapped to the key (a <code>String[]</code>)
 375  
      *         or <code>null</code> if the key was not mapped.
 376  
      */
 377  
     @Override
 378  
     public Object remove(String name)
 379  
     {
 380  8
         return parameters.remove(convert(name));
 381  
     }
 382  
 
 383  
     /**
 384  
      * Trims the string data and applies the conversion specified in
 385  
      * the property given by URL_CASE_FOLDING.  It returns a new
 386  
      * string so that it does not destroy the value data.
 387  
      *
 388  
      * @param value A String to be processed.
 389  
      * @return A new String converted to lowercase and trimmed.
 390  
      */
 391  
     @Override
 392  
     public String convert(String value)
 393  
     {
 394  1450
         return convertAndTrim(value);
 395  
     }
 396  
 
 397  
     /**
 398  
      * Determine whether a given key has been inserted.  All keys are
 399  
      * stored in lowercase strings, so override method to account for
 400  
      * this.
 401  
      *
 402  
      * @param key An Object with the key to search for.
 403  
      * @return True if the object is found.
 404  
      */
 405  
     @Override
 406  
     public boolean containsKey(Object key)
 407  
     {
 408  34
         return parameters.containsKey(convert(String.valueOf(key)));
 409  
     }
 410  
 
 411  
     /**
 412  
      * Gets the set of keys
 413  
      *
 414  
      * @return A <code>Set</code> of the keys.
 415  
      */
 416  
     @Override
 417  
     public Set<String> keySet()
 418  
     {
 419  168
         return parameters.keySet();
 420  
     }
 421  
 
 422  
     /**
 423  
      * Returns all the available parameter names.
 424  
      *
 425  
      * @return A object array with the keys.
 426  
      */
 427  
     @Override
 428  
     public String[] getKeys()
 429  
     {
 430  4
         return keySet().toArray(new String[0]);
 431  
     }
 432  
 
 433  
     /**
 434  
      * Gets an iterator over the set of keys
 435  
      *
 436  
      * @return An <code>Iterator</code> over the keys.
 437  
      */
 438  
     @Override
 439  
     public Iterator<String> iterator()
 440  
     {
 441  0
         return parameters.keySet().iterator();
 442  
     }
 443  
 
 444  
     /**
 445  
      * Returns a Boolean object for the given string. If the value
 446  
      * can not be parsed as a boolean, null is returned.
 447  
      * <p>
 448  
      * Valid values for true: true, t, on, 1, yes, y<br>
 449  
      * Valid values for false: false, f, off, 0, no, n<br>
 450  
      * <p>
 451  
      * The string is compared without reguard to case.
 452  
      *
 453  
      * @param string A String with the value.
 454  
      * @return A Boolean.
 455  
      */
 456  
     private Boolean parseBoolean(String string)
 457  
     {
 458  122
         Boolean result = null;
 459  122
         String value = StringUtils.trim(string);
 460  
 
 461  122
         if (StringUtils.isNotEmpty(value))
 462  
         {
 463  98
             for (int cnt = 0;
 464  622
             cnt < Math.max(trueValues.length, falseValues.length); cnt++)
 465  
             {
 466  
                 // Short-cut evaluation or bust!
 467  344
                 if (cnt < trueValues.length &&
 468  344
                    value.equalsIgnoreCase(trueValues[cnt]))
 469  
                 {
 470  46
                     result = Boolean.TRUE;
 471  46
                     break;
 472  
                 }
 473  
 
 474  298
                 if (cnt < falseValues.length &&
 475  298
                    value.equalsIgnoreCase(falseValues[cnt]))
 476  
                 {
 477  36
                     result = Boolean.FALSE;
 478  36
                     break;
 479  
                 }
 480  
             }
 481  
 
 482  98
             if (result == null && getLogger().isWarnEnabled() == true)
 483  
             {
 484  16
                 getLogger().warn("Parameter with value of ("
 485  
                         + value + ") could not be converted to a Boolean");
 486  
             }
 487  
         }
 488  
 
 489  122
         return result;
 490  
     }
 491  
 
 492  
     /**
 493  
      * Return a boolean for the given name.  If the name does not
 494  
      * exist, return defaultValue.
 495  
      *
 496  
      * @param name A String with the name.
 497  
      * @param defaultValue The default value.
 498  
      * @return A boolean.
 499  
      */
 500  
     @Override
 501  
     public boolean getBoolean(String name, boolean defaultValue)
 502  
     {
 503  28
         Boolean result = getBooleanObject(name);
 504  28
         return (result == null ? defaultValue : result.booleanValue());
 505  
     }
 506  
 
 507  
     /**
 508  
      * Return a boolean for the given name.  If the name does not
 509  
      * exist, return false.
 510  
      *
 511  
      * @param name A String with the name.
 512  
      * @return A boolean.
 513  
      */
 514  
     @Override
 515  
     public boolean getBoolean(String name)
 516  
     {
 517  18
         return getBoolean(name, false);
 518  
     }
 519  
 
 520  
     /**
 521  
      * Return an array of booleans for the given name.  If the name does
 522  
      * not exist, return null.
 523  
      *
 524  
      * @param name A String with the name.
 525  
      * @return A boolean[].
 526  
      */
 527  
     @Override
 528  
     public boolean[] getBooleans(String name)
 529  
     {
 530  4
         boolean[] result = null;
 531  4
         String value[] = getParam(name);
 532  4
         if (value != null)
 533  
         {
 534  2
             result = new boolean[value.length];
 535  14
             for (int i = 0; i < value.length; i++)
 536  
             {
 537  12
                 Boolean bool = parseBoolean(value[i]);
 538  12
                 result[i] = (bool == null ? false : bool.booleanValue());
 539  
             }
 540  
         }
 541  4
         return result;
 542  
     }
 543  
 
 544  
     /**
 545  
      * Returns a Boolean object for the given name.  If the parameter
 546  
      * does not exist or can not be parsed as a boolean, null is returned.
 547  
      * <p>
 548  
      * Valid values for true: true, on, 1, yes<br>
 549  
      * Valid values for false: false, off, 0, no<br>
 550  
      * <p>
 551  
      * The string is compared without reguard to case.
 552  
      *
 553  
      * @param name A String with the name.
 554  
      * @return A Boolean.
 555  
      */
 556  
     @Override
 557  
     public Boolean getBooleanObject(String name)
 558  
     {
 559  98
         return parseBoolean(getString(name));
 560  
     }
 561  
 
 562  
     /**
 563  
      * Returns a Boolean object for the given name.  If the parameter
 564  
      * does not exist or can not be parsed as a boolean, null is returned.
 565  
      * <p>
 566  
      * Valid values for true: true, on, 1, yes<br>
 567  
      * Valid values for false: false, off, 0, no<br>
 568  
      * <p>
 569  
      * The string is compared without reguard to case.
 570  
      *
 571  
      * @param name A String with the name.
 572  
      * @param defaultValue The default value.
 573  
      * @return A Boolean.
 574  
      */
 575  
     @Override
 576  
     public Boolean getBooleanObject(String name, Boolean defaultValue)
 577  
     {
 578  12
         Boolean result = getBooleanObject(name);
 579  12
         return (result == null ? defaultValue : result);
 580  
     }
 581  
 
 582  
     /**
 583  
      * Return an array of Booleans for the given name.  If the name does
 584  
      * not exist, return null.
 585  
      *
 586  
      * @param name A String with the name.
 587  
      * @return A Boolean[].
 588  
      */
 589  
     @Override
 590  
     public Boolean[] getBooleanObjects(String name)
 591  
     {
 592  4
         Boolean[] result = null;
 593  4
         String value[] = getParam(name);
 594  4
         if (value != null)
 595  
         {
 596  2
             result = new Boolean[value.length];
 597  14
             for (int i = 0; i < value.length; i++)
 598  
             {
 599  12
                 result[i] = parseBoolean(value[i]);
 600  
             }
 601  
         }
 602  4
         return result;
 603  
     }
 604  
 
 605  
     /**
 606  
      * Return a {@link Number} for the given string.
 607  
      *
 608  
      * @param string A String with the value.
 609  
      * @return A Number.
 610  
      *
 611  
      */
 612  
     private Number parseNumber(String string)
 613  
     {
 614  442
         Number result = null;
 615  442
         String value = StringUtils.trim(string);
 616  
 
 617  442
         if (StringUtils.isNotEmpty(value))
 618  
         {
 619  376
             ParsePosition pos = new ParsePosition(0);
 620  376
             Number number = numberFormat.parse(value, pos);
 621  
 
 622  376
             if (pos.getIndex() == value.length())
 623  
             {
 624  
                 // completely parsed
 625  336
                 result = number;
 626  
             }
 627  
             else
 628  
             {
 629  40
                 if (getLogger().isWarnEnabled())
 630  
                 {
 631  80
                     getLogger().warn("Parameter with value of ("
 632  40
                             + value + ") could not be converted to a Number at position " + pos.getIndex());
 633  
                 }
 634  
             }
 635  
         }
 636  
 
 637  442
         return result;
 638  
     }
 639  
 
 640  
     /**
 641  
      * Return a {@link Number} for the given name.  If the name does not
 642  
      * exist, return null. This is the base function for all numbers.
 643  
      *
 644  
      * @param name A String with the name.
 645  
      * @return A Number.
 646  
      *
 647  
      */
 648  
     private Number getNumber(String name)
 649  
     {
 650  184
         return parseNumber(getString(name));
 651  
     }
 652  
 
 653  
     /**
 654  
      * Return a double for the given name.  If the name does not
 655  
      * exist, return defaultValue.
 656  
      *
 657  
      * @param name A String with the name.
 658  
      * @param defaultValue The default value.
 659  
      * @return A double.
 660  
      */
 661  
     @Override
 662  
     public double getDouble(String name, double defaultValue)
 663  
     {
 664  16
         Number number = getNumber(name);
 665  16
         return (number == null ? defaultValue : number.doubleValue());
 666  
     }
 667  
 
 668  
     /**
 669  
      * Return a double for the given name.  If the name does not
 670  
      * exist, return 0.0.
 671  
      *
 672  
      * @param name A String with the name.
 673  
      * @return A double.
 674  
      */
 675  
     @Override
 676  
     public double getDouble(String name)
 677  
     {
 678  14
         return getDouble(name, 0.0);
 679  
     }
 680  
 
 681  
     /**
 682  
      * Return an array of doubles for the given name.  If the name does
 683  
      * not exist, return null.
 684  
      *
 685  
      * @param name A String with the name.
 686  
      * @return A double[].
 687  
      */
 688  
     @Override
 689  
     public double[] getDoubles(String name)
 690  
     {
 691  14
         double[] result = null;
 692  14
         String value[] = getParam(name);
 693  14
         if (value != null)
 694  
         {
 695  12
             result = new double[value.length];
 696  42
             for (int i = 0; i < value.length; i++)
 697  
             {
 698  30
                 Number number = parseNumber(value[i]);
 699  30
                 result[i] = (number == null ? 0.0 : number.doubleValue());
 700  
             }
 701  
         }
 702  14
         return result;
 703  
     }
 704  
 
 705  
     /**
 706  
      * Return a Double for the given name.  If the name does not
 707  
      * exist, return defaultValue.
 708  
      *
 709  
      * @param name A String with the name.
 710  
      * @param defaultValue The default value.
 711  
      * @return A double.
 712  
      */
 713  
     @Override
 714  
     public Double getDoubleObject(String name, Double defaultValue)
 715  
     {
 716  18
         Number result = getNumber(name);
 717  18
         return (result == null ? defaultValue : new Double(result.doubleValue()));
 718  
     }
 719  
 
 720  
     /**
 721  
      * Return a Double for the given name.  If the name does not
 722  
      * exist, return null.
 723  
      *
 724  
      * @param name A String with the name.
 725  
      * @return A double.
 726  
      */
 727  
     @Override
 728  
     public Double getDoubleObject(String name)
 729  
     {
 730  16
         return getDoubleObject(name, null);
 731  
     }
 732  
 
 733  
     /**
 734  
      * Return an array of doubles for the given name.  If the name does
 735  
      * not exist, return null.
 736  
      *
 737  
      * @param name A String with the name.
 738  
      * @return A double[].
 739  
      */
 740  
     @Override
 741  
     public Double[] getDoubleObjects(String name)
 742  
     {
 743  14
         Double[] result = null;
 744  14
         String value[] = getParam(name);
 745  14
         if (value != null)
 746  
         {
 747  12
             result = new Double[value.length];
 748  42
             for (int i = 0; i < value.length; i++)
 749  
             {
 750  30
                 Number number = parseNumber(value[i]);
 751  30
                 result[i] = (number == null ? null : new Double(number.doubleValue()));
 752  
             }
 753  
         }
 754  14
         return result;
 755  
     }
 756  
 
 757  
     /**
 758  
      * Return a float for the given name.  If the name does not
 759  
      * exist, return defaultValue.
 760  
      *
 761  
      * @param name A String with the name.
 762  
      * @param defaultValue The default value.
 763  
      * @return A float.
 764  
      */
 765  
     @Override
 766  
     public float getFloat(String name, float defaultValue)
 767  
     {
 768  12
         Number number = getNumber(name);
 769  12
         return (number == null ? defaultValue : number.floatValue());
 770  
     }
 771  
 
 772  
     /**
 773  
      * Return a float for the given name.  If the name does not
 774  
      * exist, return 0.0.
 775  
      *
 776  
      * @param name A String with the name.
 777  
      * @return A float.
 778  
      */
 779  
     @Override
 780  
     public float getFloat(String name)
 781  
     {
 782  10
         return getFloat(name, 0.0f);
 783  
     }
 784  
 
 785  
     /**
 786  
      * Return an array of floats for the given name.  If the name does
 787  
      * not exist, return null.
 788  
      *
 789  
      * @param name A String with the name.
 790  
      * @return A float[].
 791  
      */
 792  
     @Override
 793  
     public float[] getFloats(String name)
 794  
     {
 795  10
         float[] result = null;
 796  10
         String value[] = getParam(name);
 797  10
         if (value != null)
 798  
         {
 799  8
             result = new float[value.length];
 800  34
             for (int i = 0; i < value.length; i++)
 801  
             {
 802  26
                 Number number = parseNumber(value[i]);
 803  26
                 result[i] = (number == null ? 0.0f : number.floatValue());
 804  
             }
 805  
         }
 806  10
         return result;
 807  
     }
 808  
 
 809  
     /**
 810  
      * Return a Float for the given name.  If the name does not
 811  
      * exist, return defaultValue.
 812  
      *
 813  
      * @param name A String with the name.
 814  
      * @param defaultValue The default value.
 815  
      * @return A Float.
 816  
      */
 817  
     @Override
 818  
     public Float getFloatObject(String name, Float defaultValue)
 819  
     {
 820  12
         Number result = getNumber(name);
 821  12
         return (result == null ? defaultValue : new Float(result.floatValue()));
 822  
     }
 823  
 
 824  
     /**
 825  
      * Return a float for the given name.  If the name does not
 826  
      * exist, return null.
 827  
      *
 828  
      * @param name A String with the name.
 829  
      * @return A Float.
 830  
      */
 831  
     @Override
 832  
     public Float getFloatObject(String name)
 833  
     {
 834  10
         return getFloatObject(name, null);
 835  
     }
 836  
 
 837  
     /**
 838  
      * Return an array of floats for the given name.  If the name does
 839  
      * not exist, return null.
 840  
      *
 841  
      * @param name A String with the name.
 842  
      * @return A float[].
 843  
      */
 844  
     @Override
 845  
     public Float[] getFloatObjects(String name)
 846  
     {
 847  10
         Float[] result = null;
 848  10
         String value[] = getParam(name);
 849  10
         if (value != null)
 850  
         {
 851  8
             result = new Float[value.length];
 852  34
             for (int i = 0; i < value.length; i++)
 853  
             {
 854  26
                 Number number = parseNumber(value[i]);
 855  26
                 result[i] = (number == null ? null : new Float(number.floatValue()));
 856  
             }
 857  
         }
 858  10
         return result;
 859  
     }
 860  
 
 861  
     /**
 862  
      * Return a BigDecimal for the given name.  If the name does not
 863  
      * exist, return defaultValue.
 864  
      *
 865  
      * @param name A String with the name.
 866  
      * @param defaultValue The default value.
 867  
      * @return A BigDecimal.
 868  
      */
 869  
     @Override
 870  
     public BigDecimal getBigDecimal(String name, BigDecimal defaultValue)
 871  
     {
 872  14
         Number result = getNumber(name);
 873  14
         return (result == null ? defaultValue : new BigDecimal(result.doubleValue()));
 874  
     }
 875  
 
 876  
     /**
 877  
      * Return a BigDecimal for the given name.  If the name does not
 878  
      * exist, return null.
 879  
      *
 880  
      * @param name A String with the name.
 881  
      * @return A BigDecimal.
 882  
      */
 883  
     @Override
 884  
     public BigDecimal getBigDecimal(String name)
 885  
     {
 886  12
         return getBigDecimal(name, null);
 887  
     }
 888  
 
 889  
     /**
 890  
      * Return an array of BigDecimals for the given name.  If the name
 891  
      * does not exist, return null.
 892  
      *
 893  
      * @param name A String with the name.
 894  
      * @return A BigDecimal[].
 895  
      */
 896  
     @Override
 897  
     public BigDecimal[] getBigDecimals(String name)
 898  
     {
 899  10
         BigDecimal[] result = null;
 900  10
         String value[] = getParam(name);
 901  10
         if (value != null)
 902  
         {
 903  8
             result = new BigDecimal[value.length];
 904  34
             for (int i = 0; i < value.length; i++)
 905  
             {
 906  26
                 Number number = parseNumber(value[i]);
 907  26
                 result[i] = (number == null ? null : new BigDecimal(number.doubleValue()));
 908  
             }
 909  
         }
 910  10
         return result;
 911  
     }
 912  
 
 913  
     /**
 914  
      * Return an int for the given name.  If the name does not exist,
 915  
      * return defaultValue.
 916  
      *
 917  
      * @param name A String with the name.
 918  
      * @param defaultValue The default value.
 919  
      * @return An int.
 920  
      */
 921  
     @Override
 922  
     public int getInt(String name, int defaultValue)
 923  
     {
 924  18
         Number result = getNumber(name);
 925  18
         return (result == null || result instanceof Double ? defaultValue : result.intValue());
 926  
     }
 927  
 
 928  
     /**
 929  
      * Return an int for the given name.  If the name does not exist,
 930  
      * return 0.
 931  
      *
 932  
      * @param name A String with the name.
 933  
      * @return An int.
 934  
      */
 935  
     @Override
 936  
     public int getInt(String name)
 937  
     {
 938  16
         return getInt(name, 0);
 939  
     }
 940  
 
 941  
     /**
 942  
      * Return an array of ints for the given name.  If the name does
 943  
      * not exist, return null.
 944  
      *
 945  
      * @param name A String with the name.
 946  
      * @return An int[].
 947  
      */
 948  
     @Override
 949  
     public int[] getInts(String name)
 950  
     {
 951  16
         int[] result = null;
 952  16
         String value[] = getParam(name);
 953  16
         if (value != null)
 954  
         {
 955  14
             result = new int[value.length];
 956  46
             for (int i = 0; i < value.length; i++)
 957  
             {
 958  32
                 Number number = parseNumber(value[i]);
 959  32
                 result[i] = (number == null || number instanceof Double ? 0 : number.intValue());
 960  
             }
 961  
         }
 962  16
         return result;
 963  
     }
 964  
 
 965  
     /**
 966  
      * Return an Integer for the given name.  If the name does not exist,
 967  
      * return defaultValue.
 968  
      *
 969  
      * @param name A String with the name.
 970  
      * @param defaultValue The default value.
 971  
      * @return An Integer.
 972  
      */
 973  
     @Override
 974  
     public Integer getIntObject(String name, Integer defaultValue)
 975  
     {
 976  20
         Number result = getNumber(name);
 977  20
         return (result == null || result instanceof Double ? defaultValue : Integer.valueOf(result.intValue()));
 978  
     }
 979  
 
 980  
     /**
 981  
      * Return an Integer for the given name.  If the name does not exist,
 982  
      * return null.
 983  
      *
 984  
      * @param name A String with the name.
 985  
      * @return An Integer.
 986  
      */
 987  
     @Override
 988  
     public Integer getIntObject(String name)
 989  
     {
 990  18
         return getIntObject(name, null);
 991  
     }
 992  
 
 993  
     /**
 994  
      * Return an array of Integers for the given name.  If the name
 995  
      * does not exist, return null.
 996  
      *
 997  
      * @param name A String with the name.
 998  
      * @return An Integer[].
 999  
      */
 1000  
     @Override
 1001  
     public Integer[] getIntObjects(String name)
 1002  
     {
 1003  16
         Integer[] result = null;
 1004  16
         String value[] = getParam(name);
 1005  16
         if (value != null)
 1006  
         {
 1007  14
             result = new Integer[value.length];
 1008  46
             for (int i = 0; i < value.length; i++)
 1009  
             {
 1010  32
                 Number number = parseNumber(value[i]);
 1011  32
                 result[i] = (number == null || number instanceof Double ? null : Integer.valueOf(number.intValue()));
 1012  
             }
 1013  
         }
 1014  16
         return result;
 1015  
     }
 1016  
 
 1017  
     /**
 1018  
      * Return a long for the given name.  If the name does not exist,
 1019  
      * return defaultValue.
 1020  
      *
 1021  
      * @param name A String with the name.
 1022  
      * @param defaultValue The default value.
 1023  
      * @return A long.
 1024  
      */
 1025  
     @Override
 1026  
     public long getLong(String name, long defaultValue)
 1027  
     {
 1028  14
         Number result = getNumber(name);
 1029  14
         return (result == null || result instanceof Double ? defaultValue : result.longValue());
 1030  
     }
 1031  
 
 1032  
     /**
 1033  
      * Return a long for the given name.  If the name does not exist,
 1034  
      * return 0.
 1035  
      *
 1036  
      * @param name A String with the name.
 1037  
      * @return A long.
 1038  
      */
 1039  
     @Override
 1040  
     public long getLong(String name)
 1041  
     {
 1042  12
         return getLong(name, 0);
 1043  
     }
 1044  
 
 1045  
     /**
 1046  
      * Return an array of longs for the given name.  If the name does
 1047  
      * not exist, return null.
 1048  
      *
 1049  
      * @param name A String with the name.
 1050  
      * @return A long[].
 1051  
      */
 1052  
     @Override
 1053  
     public long[] getLongs(String name)
 1054  
     {
 1055  12
         long[] result = null;
 1056  12
         String value[] = getParam(name);
 1057  12
         if (value != null)
 1058  
         {
 1059  10
             result = new long[value.length];
 1060  38
             for (int i = 0; i < value.length; i++)
 1061  
             {
 1062  28
                 Number number = parseNumber(value[i]);
 1063  28
                 result[i] = (number == null || number instanceof Double ? 0L : number.longValue());
 1064  
             }
 1065  
         }
 1066  12
         return result;
 1067  
     }
 1068  
 
 1069  
     /**
 1070  
      * Return an array of Longs for the given name.  If the name does
 1071  
      * not exist, return null.
 1072  
      *
 1073  
      * @param name A String with the name.
 1074  
      * @return A Long[].
 1075  
      */
 1076  
     @Override
 1077  
     public Long[] getLongObjects(String name)
 1078  
     {
 1079  12
         Long[] result = null;
 1080  12
         String value[] = getParam(name);
 1081  12
         if (value != null)
 1082  
         {
 1083  10
             result = new Long[value.length];
 1084  38
             for (int i = 0; i < value.length; i++)
 1085  
             {
 1086  28
                 Number number = parseNumber(value[i]);
 1087  28
                 result[i] = (number == null || number instanceof Double ? null : Long.valueOf(number.longValue()));
 1088  
             }
 1089  
         }
 1090  12
         return result;
 1091  
     }
 1092  
 
 1093  
     /**
 1094  
      * Return a Long for the given name.  If the name does
 1095  
      * not exist, return null.
 1096  
      *
 1097  
      * @param name A String with the name.
 1098  
      * @return A Long.
 1099  
      */
 1100  
     @Override
 1101  
     public Long getLongObject(String name)
 1102  
     {
 1103  14
         return getLongObject(name, null);
 1104  
     }
 1105  
 
 1106  
     /**
 1107  
      * Return a Long for the given name.  If the name does
 1108  
      * not exist, return the default value.
 1109  
      *
 1110  
      * @param name A String with the name.
 1111  
      * @param defaultValue The default value.
 1112  
      * @return A Long.
 1113  
      */
 1114  
     @Override
 1115  
     public Long getLongObject(String name, Long defaultValue)
 1116  
     {
 1117  16
         Number result = getNumber(name);
 1118  16
         return (result == null || result instanceof Double ? defaultValue : Long.valueOf(result.longValue()));
 1119  
     }
 1120  
 
 1121  
     /**
 1122  
      * Return a byte for the given name.  If the name does not exist,
 1123  
      * return defaultValue.
 1124  
      *
 1125  
      * @param name A String with the name.
 1126  
      * @param defaultValue The default value.
 1127  
      * @return A byte.
 1128  
      */
 1129  
     @Override
 1130  
     public byte getByte(String name, byte defaultValue)
 1131  
     {
 1132  22
         Number result = getNumber(name);
 1133  22
         return (result == null || result instanceof Double ? defaultValue : result.byteValue());
 1134  
     }
 1135  
 
 1136  
     /**
 1137  
      * Return a byte for the given name.  If the name does not exist,
 1138  
      * return 0.
 1139  
      *
 1140  
      * @param name A String with the name.
 1141  
      * @return A byte.
 1142  
      */
 1143  
     @Override
 1144  
     public byte getByte(String name)
 1145  
     {
 1146  20
         return getByte(name, (byte) 0);
 1147  
     }
 1148  
 
 1149  
     /**
 1150  
      * Return an array of bytes for the given name.  If the name does
 1151  
      * not exist, return null. The array is returned according to the
 1152  
      * HttpRequest's character encoding.
 1153  
      *
 1154  
      * @param name A String with the name.
 1155  
      * @return A byte[].
 1156  
      * @throws UnsupportedEncodingException Generic exception
 1157  
      */
 1158  
     @Override
 1159  
     public byte[] getBytes(String name)
 1160  
             throws UnsupportedEncodingException
 1161  
     {
 1162  2
         byte result[] = null;
 1163  2
         String value = getString(name);
 1164  2
         if (value != null)
 1165  
         {
 1166  2
             result = value.getBytes(getCharacterEncoding());
 1167  
         }
 1168  2
         return result;
 1169  
     }
 1170  
 
 1171  
     /**
 1172  
      * Return a byte for the given name.  If the name does not exist,
 1173  
      * return defaultValue.
 1174  
      *
 1175  
      * @param name A String with the name.
 1176  
      * @param defaultValue The default value.
 1177  
      * @return A byte.
 1178  
      */
 1179  
     @Override
 1180  
     public Byte getByteObject(String name, Byte defaultValue)
 1181  
     {
 1182  22
         Number result = getNumber(name);
 1183  22
         return (result == null || result instanceof Double ? defaultValue : Byte.valueOf(result.byteValue()));
 1184  
     }
 1185  
 
 1186  
     /**
 1187  
      * Return a byte for the given name.  If the name does not exist,
 1188  
      * return 0.
 1189  
      *
 1190  
      * @param name A String with the name.
 1191  
      * @return A byte.
 1192  
      */
 1193  
     @Override
 1194  
     public Byte getByteObject(String name)
 1195  
     {
 1196  20
         return getByteObject(name, null);
 1197  
     }
 1198  
 
 1199  
     /**
 1200  
      * Return a String for the given name.  If the name does not
 1201  
      * exist, return null.
 1202  
      *
 1203  
      * @param name A String with the name.
 1204  
      * @return A String or null if the key is unknown.
 1205  
      */
 1206  
     @Override
 1207  
     public String getString(String name)
 1208  
     {
 1209  358
         String [] value = getParam(name);
 1210  358
         return value == null || value.length == 0 ? null : value[0];
 1211  
     }
 1212  
 
 1213  
     /**
 1214  
      * Return a String for the given name.  If the name does not
 1215  
      * exist, return null. It is the same as the getString() method
 1216  
      * however has been added for simplicity when working with
 1217  
      * template tools such as Velocity which allow you to do
 1218  
      * something like this:
 1219  
      *
 1220  
      * <code>$data.Parameters.form_variable_name</code>
 1221  
      *
 1222  
      * @param name A String with the name.
 1223  
      * @return A String.
 1224  
      */
 1225  
     @Override
 1226  
     public String get(String name)
 1227  
     {
 1228  10
         return getString(name);
 1229  
     }
 1230  
 
 1231  
     /**
 1232  
      * Return a String for the given name.  If the name does not
 1233  
      * exist, return the defaultValue.
 1234  
      *
 1235  
      * @param name A String with the name.
 1236  
      * @param defaultValue The default value.
 1237  
      * @return A String.
 1238  
      */
 1239  
     @Override
 1240  
     public String getString(String name, String defaultValue)
 1241  
     {
 1242  10
         String value = getString(name);
 1243  10
         return StringUtils.isEmpty(value) ? defaultValue : value;
 1244  
     }
 1245  
 
 1246  
     /**
 1247  
      * Set a parameter to a specific value.
 1248  
      *
 1249  
      * This is useful if you want your action to override the values
 1250  
      * of the parameters for the screen to use.
 1251  
      * @param name The name of the parameter.
 1252  
      * @param value The value to set.
 1253  
      */
 1254  
     @Override
 1255  
     public void setString(String name, String value)
 1256  
     {
 1257  2
         if (value != null)
 1258  
         {
 1259  2
             putParam(name, new String[]{value});
 1260  
         }
 1261  2
     }
 1262  
 
 1263  
     /**
 1264  
      * Return an array of Strings for the given name.  If the name
 1265  
      * does not exist, return null.
 1266  
      *
 1267  
      * @param name A String with the name.
 1268  
      * @return A String[].
 1269  
      */
 1270  
     @Override
 1271  
     public String[] getStrings(String name)
 1272  
     {
 1273  64
         return getParam(name);
 1274  
     }
 1275  
 
 1276  
     /**
 1277  
      * Return an array of Strings for the given name.  If the name
 1278  
      * does not exist, return the defaultValue.
 1279  
      *
 1280  
      * @param name A String with the name.
 1281  
      * @param defaultValue The default value.
 1282  
      * @return A String[].
 1283  
      */
 1284  
     @Override
 1285  
     public String[] getStrings(String name, String[] defaultValue)
 1286  
     {
 1287  0
         String[] value = getParam(name);
 1288  0
         return value == null || value.length == 0 ? defaultValue : value;
 1289  
     }
 1290  
 
 1291  
     /**
 1292  
      * Set a parameter to a specific value.
 1293  
      *
 1294  
      * This is useful if you want your action to override the values
 1295  
      * of the parameters for the screen to use.
 1296  
      * @param name The name of the parameter.
 1297  
      * @param values The value to set.
 1298  
      */
 1299  
     @Override
 1300  
     public void setStrings(String name, String[] values)
 1301  
     {
 1302  2
         if (values != null)
 1303  
         {
 1304  2
             putParam(name, values);
 1305  
         }
 1306  2
     }
 1307  
 
 1308  
     /**
 1309  
      * Return an Object for the given name.  If the name does not
 1310  
      * exist, return null.
 1311  
      *
 1312  
      * @param name A String with the name.
 1313  
      * @return An Object.
 1314  
      */
 1315  
     @Override
 1316  
     public Object getObject(String name)
 1317  
     {
 1318  0
         return getString(name);
 1319  
     }
 1320  
 
 1321  
     /**
 1322  
      * Return an array of Objects for the given name.  If the name
 1323  
      * does not exist, return null.
 1324  
      *
 1325  
      * @param name A String with the name.
 1326  
      * @return An Object[].
 1327  
      */
 1328  
     @Override
 1329  
     public Object[] getObjects(String name)
 1330  
     {
 1331  0
         return getParam(name);
 1332  
     }
 1333  
 
 1334  
     /**
 1335  
      * Returns a {@link java.util.Date} object.  String is parsed by supplied
 1336  
      * DateFormat.  If the name does not exist or the value could not be
 1337  
      * parsed into a date return the defaultValue.
 1338  
      *
 1339  
      * @param name A String with the name.
 1340  
      * @param df A DateFormat.
 1341  
      * @param defaultValue The default value.
 1342  
      * @return A Date.
 1343  
      */
 1344  
     @Override
 1345  
     public Date getDate(String name, DateFormat df, Date defaultValue)
 1346  
     {
 1347  4
         Date result = defaultValue;
 1348  4
         String value = StringUtils.trim(getString(name));
 1349  4
         if (StringUtils.isNotEmpty(value))
 1350  
         {
 1351  
             try
 1352  
             {
 1353  
                 // Reject invalid dates.
 1354  4
                 df.setLenient(false);
 1355  4
                 result = df.parse(value);
 1356  
             }
 1357  0
             catch (ParseException e)
 1358  
             {
 1359  0
                 logConversionFailure(name, value, "Date");
 1360  4
             }
 1361  
         }
 1362  
 
 1363  4
         return result;
 1364  
     }
 1365  
 
 1366  
     /**
 1367  
      * Returns a {@link java.util.Date} object.  If there are DateSelector or
 1368  
      * TimeSelector style parameters then these are used.  If not and there
 1369  
      * is a parameter 'name' then this is parsed by DateFormat.  If the
 1370  
      * name does not exist, return null.
 1371  
      *
 1372  
      * @param name A String with the name.
 1373  
      * @return A Date.
 1374  
      */
 1375  
     @Override
 1376  
     public Date getDate(String name)
 1377  
     {
 1378  4
         return getDate(name, dateFormat, null);
 1379  
     }
 1380  
 
 1381  
     /**
 1382  
      * Returns a {@link java.util.Date} object.  String is parsed by supplied
 1383  
      * DateFormat.  If the name does not exist, return null.
 1384  
      *
 1385  
      * @param name A String with the name.
 1386  
      * @param df A DateFormat.
 1387  
      * @return A Date.
 1388  
      */
 1389  
     @Override
 1390  
     public Date getDate(String name, DateFormat df)
 1391  
     {
 1392  0
         return getDate(name, df, null);
 1393  
     }
 1394  
 
 1395  
     /**
 1396  
      * Uses bean introspection to set writable properties of bean from
 1397  
      * the parameters, where a (case-insensitive) name match between
 1398  
      * the bean property and the parameter is looked for.
 1399  
      *
 1400  
      * @param bean An Object.
 1401  
      * @exception Exception a generic exception.
 1402  
      */
 1403  
     @Override
 1404  
     public void setProperties(Object bean) throws Exception
 1405  
     {
 1406  2
         Class<?> beanClass = bean.getClass();
 1407  2
         PropertyDescriptor[] props
 1408  2
                 = Introspector.getBeanInfo(beanClass).getPropertyDescriptors();
 1409  
 
 1410  16
         for ( PropertyDescriptor pd : props )
 1411  
         {
 1412  14
             String propname = pd.getName();
 1413  14
             Method setter = pd.getWriteMethod();
 1414  14
             if (setter != null && containsKey(propname))
 1415  
             {
 1416  10
                 setProperty(bean, pd);
 1417  
             }
 1418  
         }
 1419  2
     }
 1420  
 
 1421  
     /**
 1422  
      * Simple method that attempts to get a textual representation of
 1423  
      * this object's name/value pairs.  String[] handling is currently
 1424  
      * a bit rough.
 1425  
      *
 1426  
      * @return A textual representation of the parsed name/value pairs.
 1427  
      */
 1428  
     @Override
 1429  
     public String toString()
 1430  
     {
 1431  8
         StringBuilder sb = new StringBuilder();
 1432  8
         for (String name : keySet())
 1433  
         {
 1434  8
             sb.append('{');
 1435  8
             sb.append(name);
 1436  8
             sb.append('=');
 1437  8
             Object [] params = getToStringParam(name);
 1438  
 
 1439  8
             if (params == null)
 1440  
             {
 1441  0
                 sb.append("unknown?");
 1442  
             }
 1443  8
             else if (params.length == 0)
 1444  
             {
 1445  0
                 sb.append("empty");
 1446  
             }
 1447  
             else
 1448  
             {
 1449  8
                 sb.append('[');
 1450  8
                 sb.append(StringUtils.join(params, ", "));
 1451  8
                 sb.append(']');
 1452  
             }
 1453  8
             sb.append("}\n");
 1454  8
         }
 1455  
 
 1456  8
         return sb.toString();
 1457  
     }
 1458  
 
 1459  
     /**
 1460  
      * This method is only used in toString() and can be used by
 1461  
      * derived classes to add their local parameters to the toString()
 1462  
 
 1463  
      * @param name A string with the name
 1464  
      *
 1465  
      * @return the value object array or null if not set
 1466  
      */
 1467  
     protected Object [] getToStringParam(final String name)
 1468  
     {
 1469  8
         return getParam(name);
 1470  
     }
 1471  
 
 1472  
     /**
 1473  
      * Set the property 'prop' in the bean to the value of the
 1474  
      * corresponding parameters.  Supports all types supported by
 1475  
      * getXXX methods plus a few more that come for free because
 1476  
      * primitives have to be wrapped before being passed to invoke
 1477  
      * anyway.
 1478  
      *
 1479  
      * @param bean An Object.
 1480  
      * @param prop A PropertyDescriptor.
 1481  
      * @exception Exception a generic exception.
 1482  
      */
 1483  
     protected void setProperty(Object bean,
 1484  
                                PropertyDescriptor prop)
 1485  
             throws Exception
 1486  
     {
 1487  10
         if (prop instanceof IndexedPropertyDescriptor)
 1488  
         {
 1489  0
             throw new Exception(prop.getName() +
 1490  
                     " is an indexed property (not supported)");
 1491  
         }
 1492  
 
 1493  10
         Method setter = prop.getWriteMethod();
 1494  10
         if (setter == null)
 1495  
         {
 1496  0
             throw new Exception(prop.getName() +
 1497  
                     " is a read only property");
 1498  
         }
 1499  
 
 1500  10
         Class<?> propclass = prop.getPropertyType();
 1501  10
         Object arg = null;
 1502  
 
 1503  10
         if (propclass == String.class)
 1504  
         {
 1505  2
             arg = getString(prop.getName());
 1506  
         }
 1507  8
         else if (propclass == Byte.class || propclass == Byte.TYPE)
 1508  
         {
 1509  0
             arg = getByteObject(prop.getName());
 1510  
         }
 1511  8
         else if (propclass == Integer.class || propclass == Integer.TYPE)
 1512  
         {
 1513  2
             arg = getIntObject(prop.getName());
 1514  
         }
 1515  6
         else if (propclass == Long.class || propclass == Long.TYPE)
 1516  
         {
 1517  2
             arg = getLongObject(prop.getName());
 1518  
         }
 1519  4
         else if (propclass == Boolean.class || propclass == Boolean.TYPE)
 1520  
         {
 1521  2
             arg = getBooleanObject(prop.getName());
 1522  
         }
 1523  2
         else if (propclass == Double.class || propclass == Double.TYPE)
 1524  
         {
 1525  2
             arg = getDoubleObject(prop.getName());
 1526  
         }
 1527  0
         else if (propclass == Float.class || propclass == Float.TYPE)
 1528  
         {
 1529  0
             arg = getFloatObject(prop.getName());
 1530  
         }
 1531  0
         else if (propclass == BigDecimal.class)
 1532  
         {
 1533  0
             arg = getBigDecimal(prop.getName());
 1534  
         }
 1535  0
         else if (propclass == String[].class)
 1536  
         {
 1537  0
             arg = getStrings(prop.getName());
 1538  
         }
 1539  0
         else if (propclass == Object.class)
 1540  
         {
 1541  0
             arg = getObject(prop.getName());
 1542  
         }
 1543  0
         else if (propclass == int[].class)
 1544  
         {
 1545  0
             arg = getInts(prop.getName());
 1546  
         }
 1547  0
         else if (propclass == Integer[].class)
 1548  
         {
 1549  0
             arg = getIntObjects(prop.getName());
 1550  
         }
 1551  0
         else if (propclass == Date.class)
 1552  
         {
 1553  0
             arg = getDate(prop.getName());
 1554  
         }
 1555  
         else
 1556  
         {
 1557  0
             throw new Exception("property "
 1558  0
                     + prop.getName()
 1559  
                     + " is of unsupported type "
 1560  0
                     + propclass.toString());
 1561  
         }
 1562  
 
 1563  10
         setter.invoke(bean, arg);
 1564  10
     }
 1565  
 
 1566  
     /**
 1567  
      * Puts a key into the parameters map. Makes sure that the name is always
 1568  
      * mapped correctly. This method also enforces the usage of arrays for the
 1569  
      * parameters.
 1570  
      *
 1571  
      * @param name A String with the name.
 1572  
      * @param value An array of Objects with the values.
 1573  
      *
 1574  
      */
 1575  
     protected void putParam(final String name, final String [] value)
 1576  
     {
 1577  408
         String key = convert(name);
 1578  408
         if (key != null)
 1579  
         {
 1580  408
             parameters.put(key, value);
 1581  
         }
 1582  408
     }
 1583  
 
 1584  
     /**
 1585  
      * fetches a key from the parameters map. Makes sure that the name is
 1586  
      * always mapped correctly.
 1587  
      *
 1588  
      * @param name A string with the name
 1589  
      *
 1590  
      * @return the value object array or null if not set
 1591  
      */
 1592  
     protected String [] getParam(final String name)
 1593  
     {
 1594  956
         String key = convert(name);
 1595  956
         Object value = parameters.get(key);
 1596  
 
 1597  
         // todo sgoeschl 20070405 quick fix for Scott's test case - need to
 1598  
         // be reworked for proper functioning according to TV
 1599  956
         if(value instanceof String[])
 1600  
         {
 1601  564
             return (String []) parameters.get(key);
 1602  
         }
 1603  
         else
 1604  
         {
 1605  392
             return null;
 1606  
         }
 1607  
     }
 1608  
 
 1609  
 
 1610  
     /** recyclable support **/
 1611  
 
 1612  
     /**
 1613  
      * The disposed flag.
 1614  
      */
 1615  
     private boolean disposed;
 1616  
 
 1617  
     /**
 1618  
      * Checks whether the object is disposed.
 1619  
      *
 1620  
      * @return true, if the object is disposed.
 1621  
      */
 1622  
     public boolean isDisposed()
 1623  
     {
 1624  4
         return disposed;
 1625  
     }
 1626  
 
 1627  
     /**
 1628  
      * Writes a log message about a conversion failure.
 1629  
      *
 1630  
      * @param paramName name of the parameter which could not be converted
 1631  
      * @param value value of the parameter
 1632  
      * @param type target data type.
 1633  
      */
 1634  
     private void logConversionFailure(String paramName,
 1635  
                                       String value, String type)
 1636  
     {
 1637  0
         getLogger().warn("Parameter (" + paramName
 1638  
                 + ") with value of ("
 1639  
                 + value + ") could not be converted to a " + type);
 1640  0
     }
 1641  
 
 1642  
     /**
 1643  
      * Convert a String value according to the url-case-folding property.
 1644  
      *
 1645  
      * @param value the String to convert
 1646  
      *
 1647  
      * @return a new String.
 1648  
      *
 1649  
      */
 1650  
     @Override
 1651  
     public String convertAndTrim(String value)
 1652  
     {
 1653  1450
         return parserService.convertAndTrim(value);
 1654  
     }
 1655  
 
 1656  
     /**
 1657  
      * A convert method, which trims the string data and applies the
 1658  
      * conversion specified in the parameter given. It returns a new
 1659  
      * string so that it does not destroy the value data.
 1660  
      *
 1661  
      * @param value A String to be processed.
 1662  
      * @param fold The parameter folding to be applied
 1663  
      * (see {@link ParserService})
 1664  
      * @return A new String converted to the correct case and trimmed.
 1665  
      */
 1666  
     @Override
 1667  
     public String convertAndTrim(String value, URLCaseFolding fold)
 1668  
     {
 1669  12
         return parserService.convertAndTrim(value, fold);
 1670  
     }
 1671  
 
 1672  
     /**
 1673  
      * Gets the folding value from the ParserService configuration
 1674  
      *
 1675  
      * @return The current Folding Value
 1676  
      */
 1677  
     @Override
 1678  
     public URLCaseFolding getUrlFolding()
 1679  
     {
 1680  4
         return parserService.getUrlFolding();
 1681  
     }
 1682  
 
 1683  
         public boolean isValid() 
 1684  
         {
 1685  4
             if ( this.parameters.size() == 0 )
 1686  
             {
 1687  4
                     return true;
 1688  
             }
 1689  0
             return false;
 1690  
         }
 1691  
 }