You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by xu...@apache.org on 2011/05/10 14:33:51 UTC

svn commit: r1101431 - in /openejb/trunk/openejb3/container/openejb-core/src: main/java/org/apache/openejb/core/timer/EJBCronTrigger.java test/java/org/apache/openejb/timer/EJBCronTriggerTest.java

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);