commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rdon...@apache.org
Subject cvs commit: jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/locale/converters BaseLocaleConverterTestCase.java DateLocaleConverterTestCase.java
Date Tue, 13 Jul 2004 20:51:44 GMT
rdonkin     2004/07/13 13:51:44

  Modified:    beanutils/src/java/org/apache/commons/beanutils/locale/converters
                        DateLocaleConverter.java
               beanutils/src/test/org/apache/commons/beanutils/locale/converters
                        BaseLocaleConverterTestCase.java
                        DateLocaleConverterTestCase.java
  Log:
  Committed patch related to bug #29772 submitted by Niall Pemberton. This patch actually
fixes the more complex issue of working round a problem with some 1.4 JVMs rather than the
reported bug (which had been fixed earlier).
  
  Revision  Changes    Path
  1.10      +96 -27    jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/locale/converters/DateLocaleConverter.java
  
  Index: DateLocaleConverter.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/locale/converters/DateLocaleConverter.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- DateLocaleConverter.java	28 Feb 2004 13:18:35 -0000	1.9
  +++ DateLocaleConverter.java	13 Jul 2004 20:51:44 -0000	1.10
  @@ -17,12 +17,14 @@
   package org.apache.commons.beanutils.locale.converters;
   
   import org.apache.commons.beanutils.locale.BaseLocaleConverter;
  +import org.apache.commons.beanutils.ConvertUtils;
   import org.apache.commons.logging.LogFactory;
   import org.apache.commons.logging.Log;
   
   import java.text.ParseException;
  -import java.text.ParsePosition;
   import java.text.SimpleDateFormat;
  +import java.text.DateFormat;
  +import java.text.DateFormatSymbols;
   import java.util.Locale;
   
   
  @@ -48,6 +50,9 @@
       /** Should the date conversion be lenient? */
       boolean isLenient = false;
   
  +    /** Default Pattern Characters */
  +    public static String defaultChars;
  +
       // ----------------------------------------------------------- Constructors
   
       /**
  @@ -244,36 +249,100 @@
        * @param value The input object to be converted
        * @param pattern The pattern is used for the convertion
        *
  -     * @exception org.apache.commons.beanutils.ConversionException if conversion cannot
be performed
  -     *  successfully
  +     * @exception org.apache.commons.beanutils.ConversionException 
  +     * if conversion cannot be performed successfully
        */
       protected Object parse(Object value, String pattern) throws ParseException {
  -        SimpleDateFormat formatter = getFormatter(pattern, locale);
  -        if (locPattern) {
  -            formatter.applyLocalizedPattern(pattern);
  -        }
  -        else {
  -            formatter.applyPattern(pattern);
  + 
  +         if (locPattern) {
  +             pattern = convertLocalizedPattern(pattern, locale);
  +         }
  + 
  +         // Create Formatter - use default if pattern is null
  +         DateFormat formatter = pattern == null ? DateFormat.getDateInstance(DateFormat.SHORT,
locale)
  +                                                : new SimpleDateFormat(pattern, locale);
  +         formatter.setLenient(isLenient);
  + 
  +
  +         // Parse the Date
  +         return formatter.parse((String) value);
  +     }
  +   
  +     /**
  +      * Convert a pattern from a localized format to the default format.
  +      *
  +      * @param locale   The locale
  +      * @param pattern  The pattern in 'local' symbol format
  +      * @return pattern in 'default' symbol format
  +      */
  +     private String convertLocalizedPattern(String localizedPattern, Locale locale) {
  +        
  +         if (localizedPattern == null)
  +            return null;
  +         
  +         // Note that this is a little obtuse.
  +         // However, it is the best way that anyone can come up with 
  +         // that works with some 1.4 series JVM.
  +         
  +         // Initialize the default symbols
  +         if (defaultChars == null) {
  +             DateFormatSymbols defaultSymbols = new DateFormatSymbols(Locale.US);
  +             defaultChars = defaultSymbols.getLocalPatternChars();
  +         }
  + 
  +         // Get the symbols for the localized pattern
  +         DateFormatSymbols localizedSymbols = new DateFormatSymbols(locale);
  +         String localChars = localizedSymbols.getLocalPatternChars();
  + 
  +         if (defaultChars.equals(localChars)) {
  +             return localizedPattern;
  +         }
  + 
  +         // Convert the localized pattern to default
  +         String convertedPattern = null;
  +         try {
  +             convertedPattern = convertPattern(localizedPattern,
  +                                                localChars,
  +                                                defaultChars);
  +         } catch (Exception ex) {
  +             log.warn("Converting pattern '" + localizedPattern + "' for " + locale, ex);
  +         }
  +         return convertedPattern; 
  +    }
  +     
  +    /**
  +     * <p>Converts a Pattern from one character set to another.</p>
  +     */
  +    private String convertPattern(String pattern, String fromChars, String toChars) {
  +
  +        StringBuffer converted = new StringBuffer();
  +        boolean quoted = false;
  +
  +        for (int i = 0; i < pattern.length(); ++i) {
  +            char thisChar = pattern.charAt(i);
  +            if (quoted) {
  +                if (thisChar == '\'') {
  +                    quoted = false;
  +                }
  +            } else {
  +                if (thisChar == '\'') {
  +                   quoted = true;
  +                } else if ((thisChar >= 'a' && thisChar <= 'z') || 
  +                           (thisChar >= 'A' && thisChar <= 'Z')) {
  +                    int index = fromChars.indexOf(thisChar );
  +                    if (index == -1)
  +                        throw new IllegalArgumentException(
  +                            "Illegal pattern character '" + thisChar + "'");
  +                    thisChar = toChars.charAt(index);
  +                }
  +            }
  +            converted.append(thisChar);
           }
  -        return formatter.parse((String) value);
  -    }
   
  -    /**
  -     * Gets an appropriate <code>SimpleDateFormat</code> for given locale,

  -     * default Date format pattern is not provided.
  -     */
  -    private SimpleDateFormat getFormatter(String pattern, Locale locale) {
  -        // This method is a fix for null pattern, which would cause 
  -        // Null pointer exception when applied
  -        // Note: that many constructors default the pattern to null, 
  -        // so it only makes sense to handle nulls gracefully
  -        if(pattern == null) {
  -            pattern = locPattern ? 
  -                new SimpleDateFormat().toLocalizedPattern() : new SimpleDateFormat().toPattern();
  -            log.warn("Null pattern was provided, defaulting to: " + pattern);
  +        if (quoted) {
  +            throw new IllegalArgumentException("Unfinished quote in pattern");
           }
  -        SimpleDateFormat format = new SimpleDateFormat(pattern, locale);
  -        format.setLenient(isLenient);
  -        return format;
  +
  +        return converted.toString();
       }
   }
  
  
  
  1.2       +3 -11     jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/locale/converters/BaseLocaleConverterTestCase.java
  
  Index: BaseLocaleConverterTestCase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/locale/converters/BaseLocaleConverterTestCase.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BaseLocaleConverterTestCase.java	8 Jul 2004 13:12:06 -0000	1.1
  +++ BaseLocaleConverterTestCase.java	13 Jul 2004 20:51:44 -0000	1.2
  @@ -18,8 +18,8 @@
   
   import junit.framework.TestCase;
   import java.util.Locale;
  -import org.apache.commons.beanutils.locale.BaseLocaleConverter
  -;
  +import java.text.DateFormatSymbols;
  +import org.apache.commons.beanutils.locale.BaseLocaleConverter;
   
   /**
    * Base Test Case for the DecimalLocaleConverter classes.
  @@ -45,19 +45,15 @@
       protected Locale localizedLocale;
       protected String localizedDecimalPattern; 
       protected String localizedIntegerPattern; 
  -    protected String localizedDatePattern; 
       protected String localizedDecimalValue;
       protected String localizedIntegerValue;
  -    protected String localizedDateValue;
   
       // Locale values
       protected Locale defaultLocale;
       protected String defaultDecimalPattern; 
       protected String defaultIntegerPattern; 
  -    protected String defaultDatePattern; 
       protected String defaultDecimalValue;
       protected String defaultIntegerValue;
  -    protected String defaultDateValue;
   
   
       // Expected values
  @@ -81,19 +77,15 @@
           defaultLocale           = Locale.US;
           defaultDecimalPattern   = "#,###.00";
           defaultIntegerPattern   = "#,###";
  -        defaultDatePattern      = "d MMMM yyyy";
           defaultDecimalValue     = "1,234.56";
           defaultIntegerValue     = "1,234";
  -        defaultDateValue        = "1 October 2004";
   
           // Use German Locale (uses different separators to US)
           localizedLocale         = Locale.GERMAN;
           localizedDecimalPattern = "#.###,00";
           localizedIntegerPattern = "#.###";
  -        localizedDatePattern    = "t MMMM uuuu";
           localizedDecimalValue   = "1.234,56";
           localizedIntegerValue   = "1.234";
  -        localizedDateValue      = "1 Oktober 2004";
   
           // Expected Values
           expectedDecimalValue    = "1234.56";
  
  
  
  1.5       +302 -8    jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/locale/converters/DateLocaleConverterTestCase.java
  
  Index: DateLocaleConverterTestCase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/locale/converters/DateLocaleConverterTestCase.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DateLocaleConverterTestCase.java	28 Feb 2004 13:18:37 -0000	1.4
  +++ DateLocaleConverterTestCase.java	13 Jul 2004 20:51:44 -0000	1.5
  @@ -16,16 +16,17 @@
   
   package org.apache.commons.beanutils.locale.converters;
   
  -import junit.framework.TestSuite;
  -import junit.framework.TestCase;
  -
   import java.text.SimpleDateFormat;
   import java.text.ParseException;
  +import java.text.DateFormatSymbols;
   
   import java.util.Locale;
   
   import org.apache.commons.beanutils.Converter;
   import org.apache.commons.beanutils.ConversionException;
  +import org.apache.commons.beanutils.locale.BaseLocaleConverter;
  +import org.apache.commons.logging.LogFactory;
  +import org.apache.commons.logging.Log;
   
   /**
    * Test Case for the DateLocaleConverter class.
  @@ -34,7 +35,21 @@
    * @version $Revision$ $Date$
    */
   
  -public class DateLocaleConverterTestCase extends TestCase {
  +public class DateLocaleConverterTestCase extends BaseLocaleConverterTestCase {
  +
  +    /** All logging goes through this logger */
  +    private static Log log = LogFactory.getLog(DateLocaleConverterTestCase.class);
  +
  +    protected String localizedDatePattern; 
  +    protected String localizedDateValue;
  +    protected String localizedShortDateValue;
  +    protected String defaultDatePattern; 
  +    protected String defaultDateValue;
  +    protected String defaultShortDateValue;
  +
  +    protected Object expectedValue;
  +
  +    protected boolean validLocalDateSymbols;
   
       // ------------------------------------------------------------------------
   
  @@ -42,10 +57,61 @@
           super(name);
       }
       
  -    // ------------------------------------------------------------------------
  +    // -------------------------------------------------- Overall Test Methods
  +
  +    /**
  +     * Set up instance variables required by this test case.
  +     */
  +    public void setUp() throws Exception {
  +
  +        super.setUp();
  +
  +        String version = System.getProperty("java.specification.version");
  +        log.warn("JDK Version "+version);
  +
  +
  +        try {
  +            SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
  +            expectedValue      = format.parse("20041001");
  +            defaultValue       = format.parse("19670316");
  +        } catch (Exception ex) {
  +            log.error("Error creating expected/default dates", ex);
  +        }
  +
  +        // Default Locale (Use US)
  +        defaultLocale           = Locale.US;
  +        defaultDatePattern      = "d MMMM yyyy";
  +        defaultDateValue        = "1 October 2004";
  +        defaultShortDateValue   = "10/01/04";
  +
  +        // Use German Locale
  +//        localizedLocale         = Locale.GERMAN;  // N.B. doesn't work for dates
  +//        localizedLocale         = Locale.GERMANY; // N.B. doesn't work for dates
  +        localizedLocale         = new Locale("de", "AT"); // Austria/German works
  +        localizedDatePattern    = "t MMMM uuuu";
  +        localizedDateValue      = "1 Oktober 2004";
  +        localizedShortDateValue = "01.10.04";
  +
  +        // Test whether the "local pattern characters" are what we
  +        // are expecting - Locale.GERMAN and Locale.GERMANY, Locale.FRENCH all
  +        // returned the standard "English" pattern characters on my machine
  +        // for JDK 1.4 (JDK 1.3 was OK). The Austria/German locale was OK though
  +        String expectedChars = "GuMtkHmsSEDFwWahKzZ";
  +        DateFormatSymbols localizedSymbols = new DateFormatSymbols(localizedLocale);
  +        String localChars    = localizedSymbols.getLocalPatternChars();
  +
  +        // different JDK versions seem to have different numbers of pattern characters

  +        int lth = localChars.length() > expectedChars.length() ? expectedChars.length()
:
  +                     localChars.length() < expectedChars.length() ? localChars.length()
: expectedChars.length();
  +        validLocalDateSymbols = expectedChars.substring(0, lth).equals(localChars.substring(0,
lth));
   
  -    public static TestSuite suite() {
  -        return new TestSuite(DateLocaleConverterTestCase.class);        
  +    }
  +
  +    /**
  +     * Tear down instance variables required by this test case.
  +     */
  +    public void tearDown() {
  +        super.tearDown();
       }
   
   
  @@ -139,5 +205,233 @@
               fail("Could not parse date (6) - " + e.getMessage());
           }
       }
  +
  +    /**
  +     * Test Converter(defaultValue, locale, pattern, localizedPattern) constructor
  +     */
  +    public void testConstructorMain() {
  +
  +        // Skip this test if no valid symbols for the locale
  +        if (!validLocalDateSymbols) {
  +            log.error("Invalid locale symbols *** skipping testConstructorMain() **");
  +            return;
  +        } 
  +
  +        // ------------- Construct with localized pattern ------------
  +        converter = new DateLocaleConverter(defaultValue,
  +                                            localizedLocale,
  +                                            localizedDatePattern,
  +                                            true);
  +
  +
  +        convertValueNoPattern(converter, "(A)", localizedDateValue, expectedValue);
  +        convertValueWithPattern(converter, "(A)", localizedDateValue, localizedDatePattern,
expectedValue);
  +        convertInvalid(converter, "(A)", defaultValue);
  +        convertNull(converter, "(A)", defaultValue);
  +
  +
  +        // Convert value in the wrong format - should return default value
  +        convertValueNoPattern(converter, "(B)", defaultDateValue, defaultValue);
  +
  +        // Convert with non-localized pattern - should return default value
  +        convertValueWithPattern(converter, "(B)", localizedDateValue, defaultDatePattern,
defaultValue);
  +
  +        // **************************************************************************
  +        // Convert with specified type
  +        // 
  +        // BaseLocaleConverter completely ignores the type - so even if we specify
  +        // Double.class here it still returns a Date.
  +        //  **** SHOULD IMPLEMENT THIS BEHAVIOUR ****
  +        // **************************************************************************
  +        convertValueToType(converter, "(B)", String.class, localizedDateValue, localizedDatePattern,
expectedValue);
  +
  +
  +        // ------------- Construct with non-localized pattern ------------
  +        converter = new DateLocaleConverter(defaultValue,
  +                                            localizedLocale,
  +                                            defaultDatePattern,
  +                                            false);
  +
  +
  +        convertValueNoPattern(converter, "(C)", localizedDateValue, expectedValue);
  +        convertValueWithPattern(converter, "(C)", localizedDateValue, defaultDatePattern,
expectedValue);
  +        convertInvalid(converter, "(C)", defaultValue);
  +        convertNull(converter, "(C)", defaultValue);
  +
  +    }
  +
  +    /**
  +     * Test Converter() constructor
  +     * 
  +     * Uses the default locale, no default value
  +     * 
  +     */
  +    public void testConstructor_2() {
  +
  +        // ------------- Construct using default pattern & default locale ------------
  +        converter = new DateLocaleConverter();
  +
  +        // Perform Tests
  +        convertValueNoPattern(converter, defaultShortDateValue, expectedValue);
  +        convertValueWithPattern(converter, defaultDateValue, defaultDatePattern, expectedValue);
  +        convertInvalid(converter, null);
  +        convertNull(converter, null);
  +
  +    }
  +
  +    /**
  +     * Test Converter(locPattern) constructor
  +     * 
  +     * Uses the default locale, no default value
  +     * 
  +     */
  +    public void testConstructor_3() {
  +
  +        // ------------- Construct using default pattern & default locale --------
  +        converter = new DateLocaleConverter(true);
  +
  +        // Perform Tests
  +        convertValueNoPattern(converter, defaultShortDateValue, expectedValue);
  +        convertValueWithPattern(converter, defaultDateValue, defaultDatePattern, expectedValue);
  +        convertInvalid(converter, null);
  +        convertNull(converter, null);
  +
  +
  +    }
  +
  +    /**
  +     * Test Converter(Locale) constructor
  +     */
  +    public void testConstructor_4() {
  +
  +        // ------------- Construct using specified Locale --------
  +        converter = new DateLocaleConverter(localizedLocale);
  +
  +        // Perform Tests
  +        convertValueNoPattern(converter, localizedShortDateValue, expectedValue);
  +        convertValueWithPattern(converter, localizedDateValue, defaultDatePattern, expectedValue);
  +        convertInvalid(converter, null);
  +        convertNull(converter, null);
  +
  +
  +    }
  +
  +
  +    /**
  +     * Test Converter(Locale, locPattern) constructor
  +     */
  +    public void testConstructor_5() {
  +
  +        // Skip this test if no valid symbols for the locale
  +        if (!validLocalDateSymbols) {
  +            log.error("Invalid locale symbols *** skipping testConstructor_5() **");
  +            return;
  +        } 
  +
  +        // ------------- Construct using specified Locale --------
  +        converter = new DateLocaleConverter(localizedLocale, true);
  +
  +        // Perform Tests
  +        convertValueNoPattern(converter, localizedShortDateValue, expectedValue);
  +        convertValueWithPattern(converter, localizedDateValue, localizedDatePattern, expectedValue);
  +        convertInvalid(converter, null);
  +        convertNull(converter, null);
  +
  +
  +    }
  +
  +    /**
  +     * Test Converter(Locale, pattern) constructor
  +     */
  +    public void testConstructor_6() {
  +
  +        // ------------- Construct using specified Locale --------
  +        converter = new DateLocaleConverter(localizedLocale, defaultDatePattern);
  +
  +        // Perform Tests
  +        convertValueNoPattern(converter, localizedDateValue, expectedValue);
  +        convertValueWithPattern(converter, localizedDateValue, defaultDatePattern, expectedValue);
  +        convertInvalid(converter, null);
  +        convertNull(converter, null);
  +
  +    }
  +
  +    /**
  +     * Test Converter(Locale, pattern, locPattern) constructor
  +     */
  +    public void testConstructor_7() {
  +
  +        // Skip this test if no valid symbols for the locale
  +        if (!validLocalDateSymbols) {
  +            log.error("Invalid locale symbols *** skipping testConstructor_7() **");
  +            return;
  +        } 
  +
  +        // ------------- Construct using specified Locale --------
  +        converter = new DateLocaleConverter(localizedLocale, localizedDatePattern, true);
  +
  +        // Perform Tests
  +        convertValueNoPattern(converter, localizedDateValue, expectedValue);
  +        convertValueWithPattern(converter, localizedDateValue, localizedDatePattern, expectedValue);
  +        convertInvalid(converter, null);
  +        convertNull(converter, null);
  +
  +    }
  +
  +    /**
  +     * Test Converter(defaultValue) constructor
  +     */
  +    public void testConstructor_8() {
  +
  +        // ------------- Construct using specified Locale --------
  +        converter = new DateLocaleConverter(defaultValue);
  +
  +        // Perform Tests
  +        convertValueNoPattern(converter, defaultShortDateValue, expectedValue);
  +        convertValueWithPattern(converter, defaultDateValue, defaultDatePattern, expectedValue);
  +        convertInvalid(converter, defaultValue);
  +        convertNull(converter, defaultValue);
  +
  +    }
  +
  +    /**
  +     * Test Converter(defaultValue, locPattern) constructor
  +     */
  +    public void testConstructor_9() {
  +
  +        // ------------- Construct using specified Locale --------
  +        converter = new DateLocaleConverter(defaultValue, true);
  +
  +        // Perform Tests
  +        convertValueNoPattern(converter, defaultShortDateValue, expectedValue);
  +        convertValueWithPattern(converter, defaultDateValue, defaultDatePattern, expectedValue);
  +        convertInvalid(converter, defaultValue);
  +        convertNull(converter, defaultValue);
  +
  +    }
  +
  +    /**
  +     * Test Converting an invalid value.
  +     */
  +    protected void convertInvalid(BaseLocaleConverter converter, String msgId, Object expectedValue)
{
  +
  +        // Convert value with no pattern
  +        try {
  +            result = converter.convert("xyz");
  +            if (expectedValue == null) {
  +                fail("Expected ConversionException if no default value " + msgId);
  +            }
  +        } catch (Exception e) {
  +            if (expectedValue != null) {
  +                fail("Expected default value " + msgId + " threw " + e);
  +            }
  +        }
  +
  +        if (expectedValue != null) {
  +            assertEquals("Check invalid conversion is default " + msgId, expectedValue,
result);
  +        }
  +
  +    }
  +
   }
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message