View Javadoc
1 package org.apache.turbine.util.parser; 2 3 /* ==================================================================== 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 2001 The Apache Software Foundation. All rights 7 * reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, 22 * if any, must include the following acknowledgment: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowledgment may appear in the software itself, 26 * if and wherever such third-party acknowledgments normally appear. 27 * 28 * 4. The names "Apache" and "Apache Software Foundation" and 29 * "Apache Turbine" must not be used to endorse or promote products 30 * derived from this software without prior written permission. For 31 * written permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache", 34 * "Apache Turbine", nor may "Apache" appear in their name, without 35 * prior written permission of the Apache Software Foundation. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>;. 55 */ 56 57 import java.beans.IndexedPropertyDescriptor; 58 import java.beans.Introspector; 59 import java.beans.PropertyDescriptor; 60 61 import java.io.UnsupportedEncodingException; 62 63 import java.lang.reflect.Method; 64 65 import java.math.BigDecimal; 66 67 import java.text.DateFormat; 68 import java.text.ParseException; 69 70 import java.util.Calendar; 71 import java.util.Date; 72 import java.util.Enumeration; 73 import java.util.GregorianCalendar; 74 import java.util.Hashtable; 75 76 import org.apache.torque.om.NumberKey; 77 import org.apache.torque.om.StringKey; 78 79 import org.apache.turbine.services.resources.TurbineResources; 80 81 import org.apache.turbine.util.DateSelector; 82 import org.apache.turbine.util.StringUtils; 83 import org.apache.turbine.util.TimeSelector; 84 import org.apache.turbine.util.ValueParser; 85 import org.apache.turbine.util.pool.Recyclable; 86 import org.apache.turbine.util.pool.RecyclableSupport; 87 88 /*** 89 * BaseValueParser is a base class for classes that need to parse 90 * name/value Parameters, for example GET/POST data or Cookies 91 * (DefaultParameterParser and DefaultCookieParser) 92 * 93 * <p>It can also be used standalone, for an example see DataStreamParser. 94 * 95 * <p>NOTE: The name= portion of a name=value pair may be converted 96 * to lowercase or uppercase when the object is initialized and when 97 * new data is added. This behaviour is determined by the url.case.folding 98 * property in TurbineResources.properties. Adding a name/value pair may 99 * overwrite existing name=value pairs if the names match: 100 * 101 * <pre> 102 * ValueParser vp = new BaseValueParser(); 103 * vp.add("ERROR",1); 104 * vp.add("eRrOr",2); 105 * int result = vp.getInt("ERROR"); 106 * </pre> 107 * 108 * In the above example, result is 2. 109 * 110 * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a> 111 * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a> 112 * @author <a href="mailto:sean@informage.net">Sean Legassick</a> 113 * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a> 114 * @version $Id: BaseValueParser.java,v 1.5 2002/07/11 07:16:43 mpoeschl Exp $ 115 */ 116 public class BaseValueParser 117 extends RecyclableSupport 118 implements ValueParser, 119 Recyclable 120 { 121 /*** 122 * Random access storage for parameter data. 123 */ 124 protected Hashtable parameters = new Hashtable(); 125 /*** 126 * The character encoding to use when converting to byte arrays 127 */ 128 private String characterEncoding = "US-ASCII"; 129 130 /*** 131 * A static version of the convert method, which 132 * trims the string data and applies the conversion specified in 133 * the property given by URL_CASE_FOLDING. It returns a new 134 * string so that it does not destroy the value data. 135 * 136 * @param value A String to be processed. 137 * @return A new String converted to lowercase and trimmed. 138 */ 139 public static String convertAndTrim ( String value ) 140 { 141 String tmp = value.trim(); 142 String fold = 143 TurbineResources.getString(URL_CASE_FOLDING, "") 144 .toLowerCase(); 145 if ((fold == null) || 146 (fold.equals("")) || 147 (fold.equals(URL_CASE_FOLDING_LOWER))) 148 return (tmp.toLowerCase()); 149 else if (fold.equals(URL_CASE_FOLDING_UPPER)) 150 return (tmp.toUpperCase()); 151 152 return (tmp); 153 } 154 155 /*** 156 * Default constructor 157 */ 158 public BaseValueParser() 159 { 160 super(); 161 } 162 163 /*** 164 * Constructor that takes a character encoding 165 */ 166 public BaseValueParser(String characterEncoding) 167 { 168 super(); 169 recycle(characterEncoding); 170 } 171 172 /*** 173 * Recycles the parser. 174 */ 175 public void recycle() 176 { 177 recycle("US-ASCII"); 178 } 179 180 /*** 181 * Recycles the parser with a character encoding. 182 * 183 * @param characterEncoding the character encoding. 184 */ 185 public void recycle(String characterEncoding) 186 { 187 setCharacterEncoding(characterEncoding); 188 if (!isDisposed()) 189 super.recycle(); 190 } 191 192 /*** 193 * Disposes the parser. 194 */ 195 public void dispose() 196 { 197 clear(); 198 super.dispose(); 199 } 200 201 /*** 202 * Clear all name/value pairs out of this object. 203 */ 204 public void clear() 205 { 206 parameters.clear(); 207 } 208 209 /*** 210 * Set the character encoding that will be used by this ValueParser. 211 */ 212 public void setCharacterEncoding (String s) 213 { 214 characterEncoding = s; 215 } 216 217 /*** 218 * Get the character encoding that will be used by this ValueParser. 219 */ 220 public String getCharacterEncoding () 221 { 222 return characterEncoding; 223 } 224 225 /*** 226 * Add a name/value pair into this object. 227 * 228 * @param name A String with the name. 229 * @param value A double with the value. 230 */ 231 public void add ( String name, 232 double value ) 233 { 234 add ( name, Double.toString(value)); 235 } 236 237 /*** 238 * Add a name/value pair into this object. 239 * 240 * @param name A String with the name. 241 * @param value An int with the value. 242 */ 243 public void add ( String name, 244 int value ) 245 { 246 add ( name, Integer.toString(value)); 247 } 248 249 /*** 250 * Add a name/value pair into this object. 251 * 252 * @param name A String with the name. 253 * @param value An Integer with the value. 254 */ 255 public void add ( String name, 256 Integer value ) 257 { 258 add ( name, value.toString()); 259 } 260 261 /*** 262 * Add a name/value pair into this object. 263 * 264 * @param name A String with the name. 265 * @param value A long with the value. 266 */ 267 public void add ( String name, 268 long value ) 269 { 270 add ( name, Long.toString(value)); 271 } 272 273 /*** 274 * Add a name/value pair into this object. 275 * 276 * @param name A String with the name. 277 * @param value A long with the value. 278 */ 279 public void add ( String name, 280 String value ) 281 { 282 append ( name, value); 283 } 284 285 /*** 286 * Add a String parameters. If there are any Strings already 287 * associated with the name, append to the array. This is used 288 * for handling parameters from mulitipart POST requests. 289 * 290 * @param name A String with the name. 291 * @param value A String with the value. 292 */ 293 public void append( String name, 294 String value ) 295 { 296 String[] items = this.getStrings(name); 297 if(items == null) 298 { 299 items = new String[1]; 300 items[0] = value; 301 parameters.put( convert(name), items ); 302 } 303 else 304 { 305 String[] newItems = new String[items.length+1]; 306 System.arraycopy(items, 0, newItems, 0, items.length); 307 newItems[items.length] = value; 308 parameters.put( convert(name), newItems ); 309 } 310 } 311 312 /*** 313 * Removes the named parameter from the contained hashtable. Wraps to the 314 * contained <code>Hashtable.remove()</code>. 315 * 316 * 317 * @return The value that was mapped to the key (a <code>String[]</code>) 318 * or <code>null</code> if the key was not mapped. 319 */ 320 public Object remove(String name) 321 { 322 return parameters.remove( convert(name) ); 323 } 324 325 /*** 326 * Trims the string data and applies the conversion specified in 327 * the property given by URL_CASE_FOLDING. It returns a new 328 * string so that it does not destroy the value data. 329 * 330 * @param value A String to be processed. 331 * @return A new String converted to lowercase and trimmed. 332 */ 333 public String convert ( String value ) 334 { 335 return convertAndTrim(value); 336 } 337 338 /*** 339 * Determine whether a given key has been inserted. All keys are 340 * stored in lowercase strings, so override method to account for 341 * this. 342 * 343 * @param key An Object with the key to search for. 344 * @return True if the object is found. 345 */ 346 public boolean containsKey( Object key ) 347 { 348 return parameters.containsKey(convert((String)key)); 349 } 350 351 /*** 352 * Check for existence of key_day, key_month and key_year 353 * parameters (as returned by DateSelector generated HTML). 354 * 355 * @param key A String with the selector name. 356 * @return True if keys are found. 357 */ 358 public boolean containsDateSelectorKeys(String key) 359 { 360 return (containsKey(key + DateSelector.DAY_SUFFIX) && 361 containsKey(key + DateSelector.MONTH_SUFFIX) && 362 containsKey(key + DateSelector.YEAR_SUFFIX)); 363 } 364 365 /*** 366 * Check for existence of key_hour, key_minute and key_second 367 * parameters (as returned by TimeSelector generated HTML). 368 * 369 * @param key A String with the selector name. 370 * @return True if keys are found. 371 */ 372 public boolean containsTimeSelectorKeys(String key) 373 { 374 return (containsKey(key + TimeSelector.HOUR_SUFFIX) && 375 containsKey(key + TimeSelector.MINUTE_SUFFIX) && 376 containsKey(key + TimeSelector.SECOND_SUFFIX)); 377 } 378 379 380 /* 381 * Get an enumerator for the parameter keys. Wraps to the 382 * contained <code>Hashtable.keys()</code>. 383 * 384 * @return An <code>enumerator</code> of the keys. 385 */ 386 public Enumeration keys() 387 { 388 return parameters.keys(); 389 } 390 391 /* 392 * Returns all the available parameter names. 393 * 394 * @return A object array with the keys. 395 */ 396 public Object[] getKeys() 397 { 398 return parameters.keySet().toArray(); 399 } 400 401 /*** 402 * Return a boolean for the given name. If the name does not 403 * exist, return defaultValue. 404 * 405 * @param name A String with the name. 406 * @param defaultValue The default value. 407 * @return A boolean. 408 */ 409 public boolean getBoolean(String name, 410 boolean defaultValue) 411 { 412 boolean value = defaultValue; 413 Object object = parameters.get(convert(name)); 414 if (object != null) 415 { 416 String tmp = getString(name); 417 if ( tmp.equalsIgnoreCase ("1") || 418 tmp.equalsIgnoreCase ("true") || 419 tmp.equalsIgnoreCase ("on") ) 420 { 421 value = true; 422 } 423 if ( tmp.equalsIgnoreCase ("0") || 424 tmp.equalsIgnoreCase ("false") ) 425 { 426 value = false; 427 } 428 } 429 return value; 430 } 431 432 /*** 433 * Return a boolean for the given name. If the name does not 434 * exist, return false. 435 * 436 * @param name A String with the name. 437 * @return A boolean. 438 */ 439 public boolean getBoolean(String name) 440 { 441 return getBoolean(name, false); 442 } 443 444 /*** 445 * Return a Boolean for the given name. If the name does not 446 * exist, return defaultValue. 447 * 448 * @param name A String with the name. 449 * @param defaultValue The default value. 450 * @return A Boolean. 451 */ 452 public Boolean getBool(String name, 453 boolean defaultValue) 454 { 455 return new Boolean(getBoolean(name, defaultValue)); 456 } 457 458 /*** 459 * Return a Boolean for the given name. If the name does not 460 * exist, return false. 461 * 462 * @param name A String with the name. 463 * @return A Boolean. 464 */ 465 public Boolean getBool(String name) 466 { 467 return new Boolean(getBoolean(name, false)); 468 } 469 470 /*** 471 * Return a double for the given name. If the name does not 472 * exist, return defaultValue. 473 * 474 * @param name A String with the name. 475 * @param defaultValue The default value. 476 * @return A double. 477 */ 478 public double getDouble(String name, 479 double defaultValue) 480 { 481 double value = defaultValue; 482 try 483 { 484 Object object = parameters.get(convert(name)); 485 if (object != null) 486 value = Double.valueOf(((String[])object)[0]).doubleValue(); 487 } 488 catch (NumberFormatException exception) 489 { 490 } 491 return value; 492 } 493 494 /*** 495 * Return a double for the given name. If the name does not 496 * exist, return 0.0. 497 * 498 * @param name A String with the name. 499 * @return A double. 500 */ 501 public double getDouble(String name) 502 { 503 return getDouble(name, 0.0); 504 } 505 506 /*** 507 * Return a float for the given name. If the name does not 508 * exist, return defaultValue. 509 * 510 * @param name A String with the name. 511 * @param defaultValue The default value. 512 * @return A float. 513 */ 514 public float getFloat(String name, 515 float defaultValue) 516 { 517 float value = defaultValue; 518 try 519 { 520 Object object = parameters.get(convert(name)); 521 if (object != null) 522 value = Float.valueOf(((String[])object)[0]).floatValue(); 523 } 524 catch (NumberFormatException exception) 525 { 526 } 527 return value; 528 } 529 530 531 /*** 532 * Return a float for the given name. If the name does not 533 * exist, return 0.0. 534 * 535 * @param name A String with the name. 536 * @return A float. 537 */ 538 public float getFloat(String name) 539 { 540 return getFloat(name, 0.0f); 541 } 542 543 /*** 544 * Return a BigDecimal for the given name. If the name does not 545 * exist, return 0.0. 546 * 547 * @param name A String with the name. 548 * @param defaultValue The default value. 549 * @return A BigDecimal. 550 */ 551 public BigDecimal getBigDecimal(String name, 552 BigDecimal defaultValue) 553 { 554 BigDecimal value = defaultValue; 555 try 556 { 557 Object object = parameters.get(convert(name)); 558 if (object != null) 559 { 560 String temp = ((String[])object)[0]; 561 if (temp.length() > 0) 562 { 563 value = new BigDecimal(((String[])object)[0]); 564 } 565 } 566 } 567 catch (NumberFormatException exception) 568 { 569 } 570 return value; 571 } 572 573 /*** 574 * Return a BigDecimal for the given name. If the name does not 575 * exist, return 0.0. 576 * 577 * @param name A String with the name. 578 * @return A BigDecimal. 579 */ 580 public BigDecimal getBigDecimal(String name) 581 { 582 return getBigDecimal(name, new BigDecimal(0.0)); 583 } 584 585 /*** 586 * Return an array of BigDecimals for the given name. If the name 587 * does not exist, return null. 588 * 589 * @param name A String with the name. 590 * @return A BigDecimal[]. 591 */ 592 public BigDecimal[] getBigDecimals(String name) 593 { 594 BigDecimal[] value = null; 595 Object object = getStrings(convert(name)); 596 if (object != null) 597 { 598 String[] temp = (String[])object; 599 value = new BigDecimal[temp.length]; 600 for (int i=0; i<temp.length; i++) 601 value[i] = new BigDecimal( temp[i] ); 602 } 603 return value; 604 } 605 606 /*** 607 * Return an int for the given name. If the name does not exist, 608 * return defaultValue. 609 * 610 * @param name A String with the name. 611 * @param defaultValue The default value. 612 * @return An int. 613 */ 614 public int getInt(String name, 615 int defaultValue ) 616 { 617 int value = defaultValue; 618 try 619 { 620 Object object = parameters.get(convert(name)); 621 if (object != null) 622 value = Integer.valueOf(((String[])object)[0]).intValue(); 623 } 624 catch (NumberFormatException exception) 625 { 626 } 627 return value; 628 } 629 630 /*** 631 * Return an int for the given name. If the name does not exist, 632 * return 0. 633 * 634 * @param name A String with the name. 635 * @return An int. 636 */ 637 public int getInt(String name) 638 { 639 return getInt(name, 0); 640 } 641 642 /*** 643 * Return an Integer for the given name. If the name does not 644 * exist, return defaultValue. 645 * 646 * @param name A String with the name. 647 * @param defaultValue The default value. 648 * @return An Integer. 649 */ 650 public Integer getInteger(String name, 651 int defaultValue) 652 { 653 return new Integer(getInt(name, defaultValue)); 654 } 655 656 /*** 657 * Return an Integer for the given name. If the name does not 658 * exist, return defaultValue. You cannot pass in a null here for 659 * the default value. 660 * 661 * @param name A String with the name. 662 * @param defaultValue The default value. 663 * @return An Integer. 664 */ 665 public Integer getInteger(String name, 666 Integer def) 667 { 668 return new Integer(getInt(name, def.intValue())); 669 } 670 671 /*** 672 * Return an Integer for the given name. If the name does not 673 * exist, return 0. 674 * 675 * @param name A String with the name. 676 * @return An Integer. 677 */ 678 public Integer getInteger(String name) 679 { 680 return new Integer(getInt(name, 0)); 681 } 682 683 /*** 684 * Return an array of ints for the given name. If the name does 685 * not exist, return null. 686 * 687 * @param name A String with the name. 688 * @return An int[]. 689 */ 690 public int[] getInts(String name) 691 { 692 int[] value = null; 693 Object object = getStrings(convert(name)); 694 if (object != null) 695 { 696 String[] temp = (String[])object; 697 value = new int[temp.length]; 698 for (int i=0; i<temp.length; i++) 699 value[i] = Integer.parseInt( temp[i] ); 700 } 701 return value; 702 } 703 704 /*** 705 * Return an array of Integers for the given name. If the name 706 * does not exist, return null. 707 * 708 * @param name A String with the name. 709 * @return An Integer[]. 710 */ 711 public Integer[] getIntegers(String name) 712 { 713 Integer[] value = null; 714 Object object = getStrings(convert(name)); 715 if (object != null) 716 { 717 String[] temp = (String[])object; 718 value = new Integer[temp.length]; 719 for (int i=0; i<temp.length; i++) 720 value[i] = Integer.valueOf( temp[i] ); 721 } 722 return value; 723 } 724 725 /*** 726 * Return a long for the given name. If the name does not exist, 727 * return defaultValue. 728 * 729 * @param name A String with the name. 730 * @param defaultValue The default value. 731 * @return A long. 732 */ 733 public long getLong(String name, 734 long defaultValue ) 735 { 736 long value = defaultValue; 737 try 738 { 739 Object object = parameters.get(convert(name)); 740 if (object != null) 741 value = Long.valueOf(((String[])object)[0]).longValue(); 742 } 743 catch (NumberFormatException exception) 744 { 745 } 746 return value; 747 } 748 749 /*** 750 * Return a long for the given name. If the name does not exist, 751 * return 0. 752 * 753 * @param name A String with the name. 754 * @return A long. 755 */ 756 public long getLong(String name) 757 { 758 return getLong(name, 0); 759 } 760 761 /*** 762 * Return an array of longs for the given name. If the name does 763 * not exist, return null. 764 * 765 * @param name A String with the name. 766 * @return A long[]. 767 */ 768 public long[] getLongs(String name) 769 { 770 long[] value = null; 771 Object object = getStrings(convert(name)); 772 if (object != null) 773 { 774 String[] temp = (String[])object; 775 value = new long[temp.length]; 776 for (int i=0; i<temp.length; i++) 777 value[i] = Long.parseLong( temp[i] ); 778 } 779 return value; 780 } 781 782 /*** 783 * Return an array of Longs for the given name. If the name does 784 * not exist, return null. 785 * 786 * @param name A String with the name. 787 * @return A Long[]. 788 */ 789 public Long[] getLongObjects(String name) 790 { 791 Long[] value = null; 792 Object object = getStrings(convert(name)); 793 if (object != null) 794 { 795 String[] temp = (String[])object; 796 value = new Long[temp.length]; 797 for (int i=0; i<temp.length; i++) 798 value[i] = Long.valueOf( temp[i] ); 799 } 800 return value; 801 } 802 803 /*** 804 * Return a byte for the given name. If the name does not exist, 805 * return defaultValue. 806 * 807 * @param name A String with the name. 808 * @param defaultValue The default value. 809 * @return A byte. 810 */ 811 public byte getByte(String name, 812 byte defaultValue ) 813 { 814 byte value = defaultValue; 815 try 816 { 817 Object object = parameters.get(convert(name)); 818 if (object != null) 819 value = Byte.valueOf(((String[])object)[0]).byteValue(); 820 } 821 catch (NumberFormatException exception) 822 { 823 } 824 return value; 825 } 826 827 /*** 828 * Return a byte for the given name. If the name does not exist, 829 * return 0. 830 * 831 * @param name A String with the name. 832 * @return A byte. 833 */ 834 public byte getByte(String name) 835 { 836 return getByte(name, (byte) 0); 837 } 838 839 /*** 840 * Return an array of bytes for the given name. If the name does 841 * not exist, return null. The array is returned according to the 842 * HttpRequest's character encoding. 843 * 844 * @param name A String with the name. 845 * @return A byte[]. 846 * @exception UnsupportedEncodingException. 847 */ 848 public byte[] getBytes(String name) 849 throws UnsupportedEncodingException 850 { 851 String tempStr = getString(name); 852 if ( tempStr != null ) 853 return tempStr.getBytes(characterEncoding); 854 return null; 855 } 856 857 /*** 858 * Return a String for the given name. If the name does not 859 * exist, return null. 860 * 861 * @param name A String with the name. 862 * @return A String. 863 */ 864 public String getString(String name) 865 { 866 try 867 { 868 String value = null; 869 Object object = parameters.get(convert(name)); 870 if (object != null) 871 value = ((String[])object)[0]; 872 if (value == null || value.equals("null")) 873 return null; 874 return value; 875 } 876 catch ( ClassCastException e ) 877 { 878 return null; 879 } 880 } 881 882 /*** 883 * Return a String for the given name. If the name does not 884 * exist, return null. It is the same as the getString() method 885 * however has been added for simplicity when working with 886 * template tools such as Velocity which allow you to do 887 * something like this: 888 * 889 * <code>$data.Parameters.form_variable_name</code> 890 * 891 * @param name A String with the name. 892 * @return A String. 893 */ 894 public String get (String name) 895 { 896 return getString(name); 897 } 898 899 /*** 900 * Return a String for the given name. If the name does not 901 * exist, return the defaultValue. 902 * 903 * @param name A String with the name. 904 * @param defaultValue The default value. 905 * @return A String. 906 */ 907 public String getString(String name, 908 String defaultValue) 909 { 910 String value = getString(name); 911 if (value == null || 912 value.length() == 0 || 913 value.equals("null")) 914 return defaultValue; 915 else 916 return value; 917 } 918 919 /*** 920 * Set a parameter to a specific value. 921 * 922 * This is useful if you want your action to override the values 923 * of the parameters for the screen to use. 924 * @param name The name of the parameter. 925 * @param value The value to set. 926 */ 927 public void setString(String name, String value) 928 { 929 if(value != null) 930 { 931 parameters.put(convert(name), new String[] {value} ); 932 } 933 } 934 935 /*** 936 * Return an array of Strings for the given name. If the name 937 * does not exist, return null. 938 * 939 * @param name A String with the name. 940 * @return A String[]. 941 */ 942 public String[] getStrings(String name) 943 { 944 String[] value = null; 945 Object object = parameters.get(convert(name)); 946 if (object != null) 947 value = ((String[])object); 948 return value; 949 } 950 951 /*** 952 * Return an array of Strings for the given name. If the name 953 * does not exist, return the defaultValue. 954 * 955 * @param name A String with the name. 956 * @param defaultValue The default value. 957 * @return A String[]. 958 */ 959 public String[] getStrings(String name, 960 String[] defaultValue) 961 { 962 String[] value = getStrings(name); 963 if (value == null || 964 value.length == 0) 965 return defaultValue; 966 else 967 return value; 968 } 969 970 /*** 971 * Set a parameter to a specific value. 972 * 973 * This is useful if you want your action to override the values 974 * of the parameters for the screen to use. 975 * @param name The name of the parameter. 976 * @param values The value to set. 977 */ 978 public void setStrings(String name, String[] values) 979 { 980 if(values != null) 981 { 982 parameters.put(convert(name), values); 983 } 984 } 985 986 /*** 987 * Return an Object for the given name. If the name does not 988 * exist, return null. 989 * 990 * @param name A String with the name. 991 * @return An Object. 992 */ 993 public Object getObject(String name) 994 { 995 try 996 { 997 Object value = null; 998 Object object = parameters.get(convert(name)); 999 if (object != null) 1000 value = ((Object[])object)[0]; 1001 return value; 1002 } 1003 catch ( ClassCastException e ) 1004 { 1005 return null; 1006 } 1007 } 1008 1009 /*** 1010 * Return an array of Objects for the given name. If the name 1011 * does not exist, return null. 1012 * 1013 * @param name A String with the name. 1014 * @return An Object[]. 1015 */ 1016 public Object[] getObjects(String name) 1017 { 1018 try 1019 { 1020 return (Object[])parameters.get(convert(name)); 1021 } 1022 catch ( ClassCastException e ) 1023 { 1024 return null; 1025 } 1026 } 1027 1028 /*** 1029 * Returns a {@link java.util.Date} object. String is parsed by supplied 1030 * DateFormat. If the name does not exist, return the 1031 * defaultValue. 1032 * 1033 * @param name A String with the name. 1034 * @param df A DateFormat. 1035 * @param defaultValue The default value. 1036 * @return A Date. 1037 */ 1038 public Date getDate(String name, 1039 DateFormat df, 1040 Date defaultValue) 1041 { 1042 Date date = null; 1043 1044 if (containsKey(name)) 1045 { 1046 try 1047 { 1048 // Reject invalid dates. 1049 df.setLenient(false); 1050 date = df.parse(getString(name)); 1051 } 1052 catch (ParseException e) 1053 { 1054 // Thrown if couldn't parse date. 1055 date = defaultValue; 1056 } 1057 } 1058 else 1059 date = defaultValue; 1060 1061 return date; 1062 } 1063 1064 /*** 1065 * Returns a {@link java.util.Date} object. If there are DateSelector or 1066 * TimeSelector style parameters then these are used. If not and there 1067 * is a parameter 'name' then this is parsed by DateFormat. If the 1068 * name does not exist, return null. 1069 * 1070 * @param name A String with the name. 1071 * @return A Date. 1072 */ 1073 public Date getDate(String name) 1074 { 1075 Date date = null; 1076 1077 if (containsDateSelectorKeys(name)) 1078 { 1079 try 1080 { 1081 Calendar cal = new GregorianCalendar( 1082 getInt(name + DateSelector.YEAR_SUFFIX), 1083 getInt(name + DateSelector.MONTH_SUFFIX), 1084 getInt(name + DateSelector.DAY_SUFFIX)); 1085 1086 // Reject invalid dates. 1087 cal.setLenient(false); 1088 date = cal.getTime(); 1089 } 1090 catch (IllegalArgumentException e) 1091 { 1092 // Thrown if an invalid date. 1093 } 1094 } 1095 else if (containsTimeSelectorKeys(name)) 1096 { 1097 try 1098 { 1099 String ampm = getString(name + TimeSelector.AMPM_SUFFIX); 1100 int hour = getInt(name + TimeSelector.HOUR_SUFFIX); 1101 1102 // Convert from 12 to 24hr format if appropriate 1103 if (ampm != null) 1104 { 1105 if ( hour == 12 ) 1106 { 1107 hour = (Integer.parseInt(ampm) == Calendar.PM) ? 12 : 0; 1108 } 1109 else if (Integer.parseInt(ampm) == Calendar.PM) 1110 { 1111 hour += 12; 1112 } 1113 } 1114 Calendar cal = new GregorianCalendar( 1, 1, 1, 1115 hour, 1116 getInt(name + TimeSelector.MINUTE_SUFFIX), 1117 getInt(name + TimeSelector.SECOND_SUFFIX)); 1118 1119 // Reject invalid dates. 1120 cal.setLenient(false); 1121 date = cal.getTime(); 1122 } 1123 catch (IllegalArgumentException e) 1124 { 1125 // Thrown if an invalid date. 1126 } 1127 } 1128 else 1129 { 1130 DateFormat df = DateFormat.getDateInstance(); 1131 date = getDate(name, df, null); 1132 } 1133 1134 return date; 1135 } 1136 1137 /*** 1138 * Returns a {@link java.util.Date} object. String is parsed by supplied 1139 * DateFormat. If the name does not exist, return null. 1140 * 1141 * @param name A String with the name. 1142 * @param df A DateFormat. 1143 * @return A Date. 1144 */ 1145 public Date getDate(String name, 1146 DateFormat df) 1147 { 1148 return getDate(name, df, null); 1149 } 1150 1151 /*** 1152 * Return an NumberKey for the given name. If the name does not 1153 * exist, return null. 1154 * 1155 * @param name A String with the name. 1156 * @return A NumberKey, or <code>null</code> if unparsable. 1157 */ 1158 public NumberKey getNumberKey(String name) 1159 { 1160 try 1161 { 1162 String value = null; 1163 Object object = parameters.get(convert(name)); 1164 if (object != null) 1165 { 1166 value = ((String[])object)[0]; 1167 } 1168 return (StringUtils.isValid(value) ? new NumberKey(value) : null); 1169 } 1170 catch ( ClassCastException e ) 1171 { 1172 return null; 1173 } 1174 } 1175 1176 /*** 1177 * Return an StringKey for the given name. If the name does not 1178 * exist, return null. 1179 * 1180 * @param name A String with the name. 1181 * @return A StringKey, or <code>null</code> if unparsable. 1182 */ 1183 public StringKey getStringKey(String name) 1184 { 1185 try 1186 { 1187 String value = null; 1188 Object object = parameters.get(convert(name)); 1189 if (object != null) 1190 { 1191 value = ((String[])object)[0]; 1192 } 1193 return (StringUtils.isValid(value) ? new StringKey(value) : null); 1194 } 1195 catch ( ClassCastException e ) 1196 { 1197 return null; 1198 } 1199 } 1200 1201 /*** 1202 * Uses bean introspection to set writable properties of bean from 1203 * the parameters, where a (case-insensitive) name match between 1204 * the bean property and the parameter is looked for. 1205 * 1206 * @param bean An Object. 1207 * @exception Exception, a generic exception. 1208 */ 1209 public void setProperties(Object bean) 1210 throws Exception 1211 { 1212 Class beanClass = bean.getClass(); 1213 PropertyDescriptor[] props 1214 = Introspector.getBeanInfo(beanClass).getPropertyDescriptors(); 1215 1216 for (int i = 0; i < props.length; i++) 1217 { 1218 String propname = props[i].getName(); 1219 Method setter = props[i].getWriteMethod(); 1220 if (setter != null && 1221 (containsKey(propname) || 1222 containsDateSelectorKeys(propname) || 1223 containsTimeSelectorKeys(propname))) 1224 { 1225 setProperty(bean, props[i]); 1226 } 1227 } 1228 } 1229 1230 /*** 1231 * Simple method that attempts to get a textual representation of 1232 * this object's name/value pairs. String[] handling is currently 1233 * a bit rough. 1234 * 1235 * @return A textual representation of the parsed name/value pairs. 1236 */ 1237 public String toString() 1238 { 1239 StringBuffer sb = new StringBuffer(); 1240 for (Enumeration e = parameters.keys() ; e.hasMoreElements() ;) 1241 { 1242 String name = (String) e.nextElement(); 1243 try 1244 { 1245 sb.append ('{'); 1246 sb.append(name); 1247 sb.append('='); 1248 String[] params = this.getStrings(name); 1249 if ( params.length <= 1 ) 1250 { 1251 sb.append(params[0]); 1252 } 1253 else 1254 { 1255 for ( int i=0; i<params.length; i++ ) 1256 { 1257 if ( i != 0 ) 1258 { 1259 sb.append(", "); 1260 } 1261 sb.append('[') 1262 .append(params[i]) 1263 .append(']'); 1264 } 1265 } 1266 sb.append ("}\n"); 1267 } 1268 catch ( Exception ee) 1269 { 1270 try 1271 { 1272 sb.append ('{'); 1273 sb.append(name); 1274 sb.append('='); 1275 sb.append ("ERROR?"); 1276 sb.append ("}\n"); 1277 } 1278 catch ( Exception eee ) 1279 { 1280 } 1281 } 1282 } 1283 return sb.toString(); 1284 } 1285 1286 /*** 1287 * Set the property 'prop' in the bean to the value of the 1288 * corresponding parameters. Supports all types supported by 1289 * getXXX methods plus a few more that come for free because 1290 * primitives have to be wrapped before being passed to invoke 1291 * anyway. 1292 * 1293 * @param bean An Object. 1294 * @param prop A PropertyDescriptor. 1295 * @exception Exception, a generic exception. 1296 */ 1297 protected void setProperty(Object bean, 1298 PropertyDescriptor prop) 1299 throws Exception 1300 { 1301 if (prop instanceof IndexedPropertyDescriptor) 1302 { 1303 throw new Exception(prop.getName() + 1304 " is an indexed property (not supported)"); 1305 } 1306 1307 Method setter = prop.getWriteMethod(); 1308 if (setter == null) 1309 { 1310 throw new Exception(prop.getName() + 1311 " is a read only property"); 1312 } 1313 1314 Class propclass = prop.getPropertyType(); 1315 Object[] args = { null }; 1316 1317 if (propclass == String.class) 1318 { 1319 args[0] = getString(prop.getName()); 1320 } 1321 else if (propclass == Integer.class || propclass == Integer.TYPE) 1322 { 1323 args[0] = getInteger(prop.getName()); 1324 } 1325 else if (propclass == Long.class || propclass == Long.TYPE) 1326 { 1327 args[0] = new Long(getLong(prop.getName())); 1328 } 1329 else if (propclass == Boolean.class || propclass == Boolean.TYPE) 1330 { 1331 args[0] = getBool(prop.getName()); 1332 } 1333 else if (propclass == Double.class || propclass == Double.TYPE) 1334 { 1335 args[0] = new Double(getDouble(prop.getName())); 1336 } 1337 else if (propclass == BigDecimal.class) 1338 { 1339 args[0] = getBigDecimal(prop.getName()); 1340 } 1341 else if (propclass == String[].class) 1342 { 1343 args[0] = getStrings(prop.getName()); 1344 } 1345 else if (propclass == Object.class) 1346 { 1347 args[0] = getObject(prop.getName()); 1348 } 1349 else if (propclass == int[].class) 1350 { 1351 args[0] = getInts(prop.getName()); 1352 } 1353 else if (propclass == Integer[].class) 1354 { 1355 args[0] = getIntegers(prop.getName()); 1356 } 1357 else if (propclass == Date.class) 1358 { 1359 args[0] = getDate(prop.getName()); 1360 } 1361 else if (propclass == NumberKey.class) 1362 { 1363 args[0] = getNumberKey(prop.getName()); 1364 } 1365 else if (propclass == StringKey.class) 1366 { 1367 args[0] = getStringKey(prop.getName()); 1368 } 1369 else 1370 { 1371 throw new Exception("property " 1372 + prop.getName() 1373 + " is of unsupported type " 1374 + propclass.toString()); 1375 } 1376 1377 setter.invoke(bean, args); 1378 } 1379 }

This page was automatically generated by Maven