From 94f934782a048101668f3256cf47dc848d246b89 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Fri, 17 Sep 2010 22:53:17 +0000
Subject: [PATCH] Fix calendar roll on uneven months; make sure leap years are taken into account.

---
 opends/tests/unit-tests-testng/src/server/org/opends/server/backends/task/TaskBackendTestCase.java |    3 ++-
 opends/src/server/org/opends/server/backends/task/RecurringTask.java                               |   31 ++++++++++++++++++++++++++++---
 2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/opends/src/server/org/opends/server/backends/task/RecurringTask.java b/opends/src/server/org/opends/server/backends/task/RecurringTask.java
index c58a9d6..863e3f3 100644
--- a/opends/src/server/org/opends/server/backends/task/RecurringTask.java
+++ b/opends/src/server/org/opends/server/backends/task/RecurringTask.java
@@ -100,6 +100,14 @@
   // Number of tokens in the task schedule tab.
   private static final int TASKTAB_NUM_TOKENS = 5;
 
+  // Maximum year month days.
+  static final int MONTH_LENGTH[]
+        = {31,28,31,30,31,30,31,31,30,31,30,31};
+
+  // Maximum leap year month days.
+  static final int LEAP_MONTH_LENGTH[]
+        = {31,29,31,30,31,30,31,31,30,31,30,31};
+
   /**
    * Task tab fields.
    */
@@ -417,6 +425,11 @@
     try {
       nextTaskDate = getNextIteration(calendar);
     } catch (IllegalArgumentException e) {
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.ERROR, e);
+      }
+
       throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
         ERR_RECURRINGTASK_INVALID_TOKENS_COMBO.get(
         ATTR_RECURRING_TASK_SCHEDULE));
@@ -665,7 +678,7 @@
   }
 
   /**
-   * Get next reccuring slot from the range.
+   * Get next recurring slot from the range.
    * @param timesList the range.
    * @param fromNow the current slot.
    * @return next recurring slot in the range.
@@ -744,8 +757,20 @@
           calendar.set(GregorianCalendar.MONTH, 0);
           calendar.add(GregorianCalendar.YEAR, 1);
         } else {
-          calendar.set(GregorianCalendar.MONTH, (month - 1));
-          break;
+          if ((day > LEAP_MONTH_LENGTH[month - 1]) &&
+              ((getNextTimeSlice(daysArray, 1) != day) ||
+               (getNextTimeSlice(monthArray, 1) != month)))
+          {
+            calendar.set(GregorianCalendar.DAY_OF_MONTH, 1);
+            calendar.add(GregorianCalendar.MONTH, 1);
+          } else if ((day > MONTH_LENGTH[month - 1]) &&
+                     (!calendar.isLeapYear(calendar.get(
+                      GregorianCalendar.YEAR)))) {
+            calendar.add(GregorianCalendar.YEAR, 1);
+          } else {
+            calendar.set(GregorianCalendar.MONTH, (month - 1));
+            break;
+          }
         }
       }
       weekday = getNextTimeSlice(weekdayArray,
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/task/TaskBackendTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/task/TaskBackendTestCase.java
index a257383..1d557a8 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/task/TaskBackendTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/task/TaskBackendTestCase.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2008-2009 Sun Microsystems, Inc.
+ *      Copyright 2008-2010 Sun Microsystems, Inc.
  */
 package org.opends.server.backends.task;
 
@@ -442,6 +442,7 @@
         { "* * * * 1-7",   false },
         { "* * * * 1,7",   false },
         { "* * 31 2 *",    false },
+        { "* * 29 2 *",    true },
         { "* * * * *",     true },
         { "59 * * * *",    true },
         { "0 * * * *",     true },

--
Gitblit v1.10.0