Author: xuhaihong
Date: Tue May 10 12:33:51 2011
New Revision: 1101431

URL: http://svn.apache.org/viewvc?rev=1101431&view=rev
Log:
OPENEJB-1542 Implement the Expression Rules defined in ejb3.1 spec 18.2.1.2 
(Patch from Shawn Jiang)

Modified:
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EJBCronTrigger.java
    
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/timer/EJBCronTriggerTest.java

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EJBCronTrigger.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EJBCronTrigger.java?rev=1101431&r1=1101430&r2=1101431&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EJBCronTrigger.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EJBCronTrigger.java
 Tue May 10 12:33:51 2011
@@ -448,35 +448,67 @@ public class EJBCronTrigger extends Trig
                }
 
                int currentFieldIndex = 0;
+               
                while (currentFieldIndex <=6 && calendar.before(stopCalendar)) {
+                   
                        FieldExpression expr = expressions[currentFieldIndex];
                        Integer value = expr.getNextValue(calendar);
-            if (value != null) {
+                       
+                       /*
+                        * 18.2.1.2 Expression Rules
+                        * If dayOfMonth has a non-wildcard value and dayOfWeek 
has a non-wildcard value, then either the
+                        * dayOfMonth field or the dayOfWeek field must match 
the current day (even though the other of the
+                        * two fields need not match the current day).
+                        */
+            if (currentFieldIndex == 2 && !(expressions[3] instanceof 
AsteriskExpression)){
+                
+                Calendar calendarDayOfWeek =(Calendar)calendar.clone();
+                
+                Integer nextDayOfWeek = 
expressions[3].getNextValue(calendarDayOfWeek);
+                
+                while (nextDayOfWeek == null){
+                    calendarDayOfWeek.add(Calendar.DAY_OF_MONTH, 1);
+                    nextDayOfWeek = 
expressions[3].getNextValue(calendarDayOfWeek);
+                }
+                
+                if (value!=null && nextDayOfWeek!=null) {
+                    
+                    calendarDayOfWeek.set(expressions[3].field, nextDayOfWeek);
+                    int newDayOfMonth = 
calendarDayOfWeek.get(expressions[2].field);
+                    value = Math.min(value, newDayOfMonth);
+                    
+                    //Next valid DayOfWeek might exist in next month.
+                    calendar.set(Calendar.MONTH, 
calendarDayOfWeek.get(Calendar.MONTH));
+                }
+            }
+                       
+            if (currentFieldIndex >= 1 && value == null) {
+                
+                    // No suitable value was found, so move back to the 
previous field
+                    // and increase the value
+                    // When current field is HOUR_OF_DAY, its upper field is 
DAY_OF_MONTH, so we need to -2 due to DAY_OF_WEEK.
+                    int parentFieldIndex = currentFieldIndex ==4 ? 
currentFieldIndex- 2 : currentFieldIndex - 1;
+                    int maxAffectedFieldType = upadteCalendar(calendar, 
expressions[parentFieldIndex].field, 1);
+                    currentFieldIndex = 
CALENDAR_FIELD_TYPE_ORDERED_INDEX_MAP.get(maxAffectedFieldType);
+                    resetFields(calendar, maxAffectedFieldType, false);
+                
+            } else if (value != null) {
+                
                 int oldValue = calendar.get(expr.field);
                 if (oldValue != value) {
                     // The value has changed, so update the calendar and reset 
all
                     // less significant fields
                     calendar.set(expr.field, value);
                     resetFields(calendar, expr.field, false);
+                    currentFieldIndex++;
 
-                    // If the weekday changed, the day of month changed too
-                    if (expr.field == Calendar.DAY_OF_WEEK) {
-                        currentFieldIndex--;
-                    } else {
-                        currentFieldIndex++;
-                    }
                 } else {
                     currentFieldIndex++;
                 }
-            } else if (currentFieldIndex >= 1) {
-                // No suitable value was found, so move back to the previous 
field
-                // and increase the value
-                // When current field is HOUR_OF_DAY, its upper field is 
DAY_OF_MONTH, so we need to -2 due to DAY_OF_WEEK.
-                int parentFieldIndex = currentFieldIndex ==4 ? 
currentFieldIndex- 2 : currentFieldIndex - 1;
-                int maxAffectedFieldType = upadteCalendar(calendar, 
expressions[parentFieldIndex].field, 1);
-                currentFieldIndex = 
CALENDAR_FIELD_TYPE_ORDERED_INDEX_MAP.get(maxAffectedFieldType);
-                resetFields(calendar, maxAffectedFieldType, false);
+                
             } else {
+                
+                log.debug("end of getFireTimeAfter, result is:"+ null);
                 return null;
             }
         }

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/timer/EJBCronTriggerTest.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/timer/EJBCronTriggerTest.java?rev=1101431&r1=1101430&r2=1101431&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/timer/EJBCronTriggerTest.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/timer/EJBCronTriggerTest.java
 Tue May 10 12:33:51 2011
@@ -112,7 +112,7 @@ public class EJBCronTriggerTest {
                EJBCronTrigger trigger = new EJBCronTrigger(expr);
 
                // Should not be fired at all since the first Saturday the 20th 
is in September
-               Calendar calendar = new GregorianCalendar(2008, 6, 1);
+               Calendar calendar = new GregorianCalendar(2008, 0, 4);
                trigger.setEndTime(calendar.getTime());
                calendar = new GregorianCalendar(2008, 0, 1);
                assertNull(trigger.getFireTimeAfter(calendar.getTime()));
@@ -128,18 +128,18 @@ public class EJBCronTriggerTest {
         assertEquals(new GregorianCalendar(2011, 1, 5, 0, 1, 5).getTime(), 
trigger.getFireTimeAfter(new GregorianCalendar(2011, 1, 5, 0, 0, 6).getTime()));
        }
 
-       @Test(timeout = 5000)
-    public void testBothDayOfMonthAndDayOfWeekNullValue() throws 
ParseException {
+       @Test(timeout = 5000000)
+    public void testBothDayOfMonthAndDayOfWeekA() throws ParseException {
         ScheduleExpression expr = new 
ScheduleExpression().dayOfMonth("5").dayOfWeek("6").year(2010).start(new 
Date(0));
         EJBCronTrigger trigger = new EJBCronTrigger(expr);
-        assertNull(trigger.getFireTimeAfter(new GregorianCalendar(2010, 6, 1, 
0, 0, 0).getTime()));
+        assertEquals(new GregorianCalendar(2010, 6, 3, 0, 0, 0).getTime(), 
trigger.getFireTimeAfter(new GregorianCalendar(2010, 6, 1, 0, 0, 0).getTime()));
     }
 
-       @Test(timeout = 5000)
-    public void testBothDayOfMonthAndDayOfWeekNonNullValue() throws 
ParseException {
-        ScheduleExpression expr = new 
ScheduleExpression().dayOfMonth("5").dayOfWeek("6").year(2011).start(new 
Date(0));
+       @Test(timeout = 5000000)
+    public void testBothDayOfMonthAndDayOfWeekB() throws ParseException {
+        ScheduleExpression expr = new 
ScheduleExpression().dayOfMonth("last").dayOfWeek("3").year(2011).start(new 
Date(0));
         EJBCronTrigger trigger = new EJBCronTrigger(expr);
-        assertEquals(new GregorianCalendar(2011, 1, 5, 0, 0, 0).getTime(), 
trigger.getFireTimeAfter(new GregorianCalendar(2010, 6, 1, 0, 0, 0).getTime()));
+        assertEquals(new GregorianCalendar(2011, 4, 11, 0, 0, 0).getTime(), 
trigger.getFireTimeAfter(new GregorianCalendar(2011, 4, 7, 0, 0, 0).getTime()));
     }
 
        @Test(timeout = 5000)
@@ -300,7 +300,7 @@ public class EJBCronTriggerTest {
         assertEquals(new GregorianCalendar(2010, 6, 6, 23, 1, 59).getTime(), 
trigger.getFireTimeAfter(new GregorianCalendar(2010, 6, 2, 23, 2, 
0).getTime()));
     }
 
-       @Test(timeout = 5000)
+       @Test(timeout = 5000000)
     public void testRangeDayOfWeekB() throws ParseException {
         ScheduleExpression expr = new 
ScheduleExpression().dayOfWeek("fri-tue").hour(23).minute(1).second(59).start(new
 Date(0));
         EJBCronTrigger trigger = new EJBCronTrigger(expr);


Reply via email to