commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ebo...@apache.org
Subject svn commit: r628021 - in /commons/proper/configuration/branches/configuration2_experimental: src/main/java/org/apache/commons/configuration2/plist/ src/test/java/org/apache/commons/configuration2/plist/ xdocs/
Date Fri, 15 Feb 2008 11:31:09 GMT
Author: ebourg
Date: Fri Feb 15 03:31:07 2008
New Revision: 628021

URL: http://svn.apache.org/viewvc?rev=628021&view=rev
Log:
The calendar objects are now formatted with their own time zone
Removed the Java 1.3 workaround in PropertyListConfiguration to parse and format the dates
without a SimpleDateFormat

Modified:
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/plist/PropertyListConfiguration.java
    commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/plist/TestPropertyListConfiguration.java
    commons/proper/configuration/branches/configuration2_experimental/xdocs/changes.xml

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/plist/PropertyListConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/plist/PropertyListConfiguration.java?rev=628021&r1=628020&r2=628021&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/plist/PropertyListConfiguration.java
(original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/plist/PropertyListConfiguration.java
Fri Feb 15 03:31:07 2008
@@ -22,6 +22,7 @@
 import java.io.Reader;
 import java.io.Writer;
 import java.net.URL;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
@@ -83,51 +84,17 @@
  */
 public class PropertyListConfiguration extends AbstractHierarchicalFileConfiguration
 {
-    /** Constant for the separator parser for the date part. */
-    private static final DateComponentParser DATE_SEPARATOR_PARSER = new DateSeparatorParser(
-            "-");
-
-    /** Constant for the separator parser for the time part. */
-    private static final DateComponentParser TIME_SEPARATOR_PARSER = new DateSeparatorParser(
-            ":");
-
-    /** Constant for the separator parser for blanks between the parts. */
-    private static final DateComponentParser BLANK_SEPARATOR_PARSER = new DateSeparatorParser(
-            " ");
-
-    /** An array with the component parsers for dealing with dates. */
-    private static final DateComponentParser[] DATE_PARSERS =
-    {new DateSeparatorParser("<*D"), new DateFieldParser(Calendar.YEAR, 4),
-            DATE_SEPARATOR_PARSER, new DateFieldParser(Calendar.MONTH, 2, 1),
-            DATE_SEPARATOR_PARSER, new DateFieldParser(Calendar.DATE, 2),
-            BLANK_SEPARATOR_PARSER,
-            new DateFieldParser(Calendar.HOUR_OF_DAY, 2),
-            TIME_SEPARATOR_PARSER, new DateFieldParser(Calendar.MINUTE, 2),
-            TIME_SEPARATOR_PARSER, new DateFieldParser(Calendar.SECOND, 2),
-            BLANK_SEPARATOR_PARSER, new DateTimeZoneParser(),
-            new DateSeparatorParser(">")};
+    static final SimpleDateFormat DEFAULT_DATE_FORMAT = new SimpleDateFormat("<*'D'yyyy-MM-dd
HH:mm:ss Z>");
 
-    /** Constant for the ID prefix for GMT time zones. */
-    private static final String TIME_ZONE_PREFIX = "GMT";
+    /** Instance specific format that can be used to format date in differents time zones
*/
+    final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(DEFAULT_DATE_FORMAT.toPattern());
 
     /** The serial version UID. */
     private static final long serialVersionUID = 3227248503779092127L;
 
-    /** Constant for the milliseconds of a minute.*/
-    private static final int MILLIS_PER_MINUTE = 1000 * 60;
-
-    /** Constant for the minutes per hour.*/
-    private static final int MINUTES_PER_HOUR = 60;
-
     /** Size of the indentation for the generated file. */
     private static final int INDENT_SIZE = 4;
 
-    /** Constant for the length of a time zone.*/
-    private static final int TIME_ZONE_LENGTH = 5;
-
-    /** Constant for the padding character in the date format.*/
-    private static final char PAD_CHAR = '0';
-
     /**
      * Creates an empty PropertyListConfiguration object which can be
      * used to synthesize a new plist file by adding values and
@@ -369,7 +336,19 @@
         }
         else if (value instanceof Date)
         {
-            out.print(formatDate((Date) value));
+            out.print(DATE_FORMAT.format((Date) value));
+        }
+        else if (value instanceof Calendar)
+        {
+            // change the time zone of the date format
+            Calendar calendar = (Calendar) value;
+            TimeZone previousZone = DATE_FORMAT.getTimeZone();
+            DATE_FORMAT.setTimeZone(calendar.getTimeZone());
+
+            out.print(DATE_FORMAT.format(calendar.getTime()));
+
+            // restore the previous time zone of the date format
+            DATE_FORMAT.setTimeZone(previousZone);
         }
         else if (value != null)
         {
@@ -431,248 +410,16 @@
      */
     static Date parseDate(String s) throws ParseException
     {
-        Calendar cal = Calendar.getInstance();
-        cal.clear();
-        int index = 0;
-
-        for (int i = 0; i < DATE_PARSERS.length; i++)
-        {
-            index += DATE_PARSERS[i].parseComponent(s, index, cal);
-        }
-
-        return cal.getTime();
-    }
-
-    /**
-     * Returns a string representation for the date specified by the given
-     * calendar.
-     *
-     * @param cal the calendar with the initialized date
-     * @return a string for this date
-     */
-    static String formatDate(Calendar cal)
-    {
-        StringBuilder buf = new StringBuilder();
-
-        for (int i = 0; i < DATE_PARSERS.length; i++)
-        {
-            DATE_PARSERS[i].formatComponent(buf, cal);
-        }
-
-        return buf.toString();
-    }
-
-    /**
-     * Returns a string representation for the specified date.
-     *
-     * @param date the date
-     * @return a string for this date
-     */
-    static String formatDate(Date date)
-    {
-        Calendar cal = Calendar.getInstance();
-        cal.setTime(date);
-        return formatDate(cal);
-    }
-
-    /**
-     * A helper class for parsing and formatting date literals. Usually we would
-     * use <code>SimpleDateFormat</code> for this purpose, but in Java 1.3 the
-     * functionality of this class is limited. So we have a hierarchy of parser
-     * classes instead that deal with the different components of a date
-     * literal.
-     */
-    private abstract static class DateComponentParser
-    {
-        /**
-         * Parses a component from the given input string.
-         *
-         * @param s the string to be parsed
-         * @param index the current parsing position
-         * @param cal the calendar where to store the result
-         * @return the length of the processed component
-         * @throws ParseException if the component cannot be extracted
-         */
-        public abstract int parseComponent(String s, int index, Calendar cal)
-                throws ParseException;
-
-        /**
-         * Formats a date component. This method is used for converting a date
-         * in its internal representation into a string literal.
-         *
-         * @param buf the target buffer
-         * @param cal the calendar with the current date
-         */
-        public abstract void formatComponent(StringBuilder buf, Calendar cal);
-
-        /**
-         * Checks whether the given string has at least <code>length</code>
-         * characters starting from the given parsing position. If this is not
-         * the case, an exception will be thrown.
-         *
-         * @param s the string to be tested
-         * @param index the current index
-         * @param length the minimum length after the index
-         * @throws ParseException if the string is too short
-         */
-        protected void checkLength(String s, int index, int length)
-                throws ParseException
-        {
-            int len = (s == null) ? 0 : s.length();
-            if (index + length > len)
-            {
-                throw new ParseException("Input string too short: " + s
-                        + ", index: " + index);
-            }
-        }
-
-        /**
-         * Adds a number to the given string buffer and adds leading '0'
-         * characters until the given length is reached.
-         *
-         * @param buf the target buffer
-         * @param num the number to add
-         * @param length the required length
-         */
-        protected void padNum(StringBuilder buf, int num, int length)
-        {
-            buf.append(StringUtils.leftPad(String.valueOf(num), length, PAD_CHAR));
-        }
-    }
-
-    /**
-     * A specialized date component parser implementation that deals with
-     * numeric calendar fields. The class is able to extract fields from a
-     * string literal and to format a literal from a calendar.
-     */
-    private static class DateFieldParser extends DateComponentParser
-    {
-        /** Stores the calendar field to be processed. */
-        private int calendarField;
-
-        /** Stores the length of this field. */
-        private int length;
-
-        /** An optional offset to add to the calendar field. */
-        private int offset;
-
-        /**
-         * Creates a new instance of <code>DateFieldParser</code>.
-         *
-         * @param calFld the calendar field code
-         * @param len the length of this field
-         */
-        public DateFieldParser(int calFld, int len)
-        {
-            this(calFld, len, 0);
-        }
-
-        /**
-         * Creates a new instance of <code>DateFieldParser</code> and fully
-         * initializes it.
-         *
-         * @param calFld the calendar field code
-         * @param len the length of this field
-         * @param ofs an offset to add to the calendar field
-         */
-        public DateFieldParser(int calFld, int len, int ofs)
-        {
-            calendarField = calFld;
-            length = len;
-            offset = ofs;
-        }
-
-        public void formatComponent(StringBuilder buf, Calendar cal)
-        {
-            padNum(buf, cal.get(calendarField) + offset, length);
-        }
-
-        public int parseComponent(String s, int index, Calendar cal)
-                throws ParseException
-        {
-            checkLength(s, index, length);
-            try
-            {
-                cal.set(calendarField, Integer.parseInt(s.substring(index, index + length))
- offset);
-                return length;
-            }
-            catch (NumberFormatException nfex)
-            {
-                throw new ParseException("Invalid number: " + s + ", index " + index);
-            }
-        }
-    }
-
-    /**
-     * A specialized date component parser implementation that deals with
-     * separator characters.
-     */
-    private static class DateSeparatorParser extends DateComponentParser
-    {
-        /** Stores the separator. */
-        private String separator;
-
-        /**
-         * Creates a new instance of <code>DateSeparatorParser</code> and sets
-         * the separator string.
-         *
-         * @param sep the separator string
-         */
-        public DateSeparatorParser(String sep)
-        {
-            separator = sep;
-        }
-
-        public void formatComponent(StringBuilder buf, Calendar cal)
-        {
-            buf.append(separator);
-        }
-
-        public int parseComponent(String s, int index, Calendar cal)
-                throws ParseException
+        try
         {
-            checkLength(s, index, separator.length());
-            if (!s.startsWith(separator, index))
+            synchronized (DEFAULT_DATE_FORMAT)
             {
-                throw new ParseException("Invalid input: " + s + ", index " + index + ",
expected " + separator);
+                return DEFAULT_DATE_FORMAT.parse(s);
             }
-            return separator.length();
         }
-    }
-
-    /**
-     * A specialized date component parser implementation that deals with the
-     * time zone part of a date component.
-     */
-    private static class DateTimeZoneParser extends DateComponentParser
-    {
-        public void formatComponent(StringBuilder buf, Calendar cal)
+        catch (Exception e)
         {
-            TimeZone tz = cal.getTimeZone();
-            int ofs = tz.getRawOffset() / MILLIS_PER_MINUTE;
-            if (ofs < 0)
-            {
-                buf.append('-');
-                ofs = -ofs;
-            }
-            else
-            {
-                buf.append('+');
-            }
-            int hour = ofs / MINUTES_PER_HOUR;
-            int min = ofs % MINUTES_PER_HOUR;
-            padNum(buf, hour, 2);
-            padNum(buf, min, 2);
-        }
-
-        public int parseComponent(String s, int index, Calendar cal)
-                throws ParseException
-        {
-            checkLength(s, index, TIME_ZONE_LENGTH);
-            TimeZone tz = TimeZone.getTimeZone(TIME_ZONE_PREFIX
-                    + s.substring(index, index + TIME_ZONE_LENGTH));
-            cal.setTimeZone(tz);
-            return TIME_ZONE_LENGTH;
+            throw (ParseException) new ParseException("Unable to parse the date").initCause(e);
         }
     }
 }

Modified: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/plist/TestPropertyListConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/plist/TestPropertyListConfiguration.java?rev=628021&r1=628020&r2=628021&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/plist/TestPropertyListConfiguration.java
(original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/plist/TestPropertyListConfiguration.java
Fri Feb 15 03:31:07 2008
@@ -17,25 +17,28 @@
 
 package org.apache.commons.configuration2.plist;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileReader;
 import java.io.StringReader;
+import java.text.SimpleDateFormat;
 import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Date;
 import java.util.TimeZone;
 
-import junit.framework.TestCase;
-import junitx.framework.ArrayAssert;
-import junitx.framework.ListAssert;
-import junitx.framework.ObjectAssert;
 import org.apache.commons.configuration2.Configuration;
 import org.apache.commons.configuration2.ConfigurationAssert;
 import org.apache.commons.configuration2.ConfigurationComparator;
 import org.apache.commons.configuration2.ConfigurationException;
 import org.apache.commons.configuration2.StrictConfigurationComparator;
-import org.apache.commons.configuration2.plist.ParseException;
-import org.apache.commons.configuration2.plist.PropertyListConfiguration;
+
+import junit.framework.TestCase;
+import junitx.framework.ArrayAssert;
+import junitx.framework.ListAssert;
+import junitx.framework.ObjectAssert;
 
 /**
  * @author Emmanuel Bourg
@@ -191,6 +194,33 @@
         assertEquals("date", date, config.getProperty("date"));
     }
 
+    /**
+     * Test if the calendar objets are saved with their time zone
+     */
+    public void testCalendar() throws Exception
+    {
+        File savedFile = new File("target/testcalendar.plist");
+
+        // remove the file previously saved if necessary
+        if (savedFile.exists())
+        {
+            assertTrue(savedFile.delete());
+        }
+
+        Calendar calendar = new GregorianCalendar(2008, Calendar.JANUARY, 1);
+        calendar.setTimeZone(TimeZone.getTimeZone("GMT-0200"));
+
+        PropertyListConfiguration config = new PropertyListConfiguration();
+        config.setProperty("calendar", calendar);
+        config.save(savedFile);
+
+        BufferedReader in = new BufferedReader(new FileReader(savedFile));
+        in.readLine();
+        assertEquals("calendar output", "calendar = <*D2008-01-01 00:00:00 -0200>;",
 in.readLine().trim());
+
+        in.close();
+    }
+
     public void testSave() throws Exception
     {
         File savedFile = new File("target/testsave.plist");
@@ -314,8 +344,7 @@
     {
         try
         {
-            PropertyListConfiguration
-                    .parseDate("<*D2002-03-22 1c:30:00 +0100>");
+            PropertyListConfiguration.parseDate("<*D2002-03-22 1c:30:00 +0100>");
             fail("Could parse date with an invalid number!");
         }
         catch (ParseException pex)
@@ -347,8 +376,7 @@
     {
         try
         {
-            PropertyListConfiguration
-                    .parseDate("<*D2002+03-22 11:30:00 +0100>");
+            PropertyListConfiguration.parseDate("<*D2002+03-22 11:30:00 +0100>");
             fail("Could parse date with an invalid separator!");
         }
         catch (ParseException pex)
@@ -378,16 +406,18 @@
      */
     public void testFormatDate()
     {
-        Calendar cal = Calendar.getInstance();
-        cal.clear();
-        cal.set(2007, 9, 29, 23, 4, 30);
+        SimpleDateFormat format = config.DATE_FORMAT;
+
+        Calendar cal = new GregorianCalendar(2007, Calendar.OCTOBER, 29, 23, 4, 30);
         cal.setTimeZone(TimeZone.getTimeZone("GMT-0230"));
-        assertEquals("Wrong date literal (1)", "<*D2007-10-29 23:04:30 -0230>",
-                PropertyListConfiguration.formatDate(cal));
-        cal.clear();
-        cal.set(2007, 9, 30, 22, 2, 15);
+        format.setTimeZone(cal.getTimeZone());
+
+        assertEquals("Wrong date literal (1)", "<*D2007-10-29 23:04:30 -0230>", format.format(cal.getTime()));
+
+        cal = new GregorianCalendar(2007, Calendar.OCTOBER, 30, 22, 2, 15);
         cal.setTimeZone(TimeZone.getTimeZone("GMT+1111"));
-        assertEquals("Wrong date literal (2)", "<*D2007-10-30 22:02:15 +1111>",
-                PropertyListConfiguration.formatDate(cal));
+        format.setTimeZone(cal.getTimeZone());
+
+        assertEquals("Wrong date literal (2)", "<*D2007-10-30 22:02:15 +1111>", format.format(cal.getTime()));
     }
 }

Modified: commons/proper/configuration/branches/configuration2_experimental/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/xdocs/changes.xml?rev=628021&r1=628020&r2=628021&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/xdocs/changes.xml (original)
+++ commons/proper/configuration/branches/configuration2_experimental/xdocs/changes.xml Fri
Feb 15 03:31:07 2008
@@ -29,11 +29,14 @@
       </action>
       <action dev="oheger" type="update">
         To avoid incompatibilities with older versions the package structure
-	has been changed. The main package is now
-	org.apache.commons.configuration2.
+	    has been changed. The main package is now
+	    org.apache.commons.configuration2.
       </action>
       <action dev="oheger" type="update">
-        Commons Configuration now requires Java 1.5.
+        Commons Configuration now requires Java 5.
+      </action>
+      <action dev="ebourg" type="update">
+        Calendar objects in PropertyListConfiguration are now saved with their own time zone.
       </action>
     </release>
 



Mime
View raw message