[jboss-svn-commits] JBL Code SVN: r30566 - in labs/jbossrules/trunk: drools-core/src/main/java/org/drools/process/instance/timer and 2 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Wed Dec 9 15:50:53 EST 2009
Author: mark.proctor at jboss.com
Date: 2009-12-09 15:50:53 -0500 (Wed, 09 Dec 2009)
New Revision: 30566
Modified:
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/RuleBuilder.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerManager.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/CronTrigger.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/IntervalTimer.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/IntervalTrigger.java
labs/jbossrules/trunk/drools-vsm/src/main/java/org/drools/vsm/remote/StatefulKnowledgeSessionRemoteClient.java
Log:
JBRULES-1944 Timer support
-added start end parsing capabilities
-missing tests and actual time limits
Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/RuleBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/RuleBuilder.java 2009-12-09 16:21:54 UTC (rev 30565)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/RuleBuilder.java 2009-12-09 20:50:53 UTC (rev 30566)
@@ -18,6 +18,7 @@
import java.text.ParseException;
import java.util.Calendar;
+import java.util.Date;
import java.util.List;
import org.drools.RuntimeDroolsException;
@@ -121,23 +122,7 @@
String duration = attributeDescr.getValue();
buildTimer( rule, duration, context);
} else if ( name.equals( "calendars" ) ) {
- Object val = null;
- try {
- val = MVEL.eval( attributeDescr.getValue() );
- String[] calNames = null;
- if ( val instanceof List ) {
- calNames = ( String[] ) ((List)val).toArray( new String[ ((List)val).size() ] );
- } else if ( val instanceof String ) {
- calNames = new String[] { (String) val };
- } else {
- context.getErrors().add( "Calendars attribute did not return a String or String[] '" + val + "'" );
- }
- if ( calNames != null ) {
- rule.setCalendars( calNames );
- }
- } catch ( Exception e ) {
- context.getErrors().add( "Unable to build Calendars attribute '" + val + "'" + e.getMessage() );
- }
+ buildCalendars( rule, attributeDescr.getValue(), context );
} else if ( name.equals( "date-effective" ) ) {
final Calendar cal = Calendar.getInstance();
cal.setTime( DateUtils.parseDate( attributeDescr.getValue() ) );
@@ -204,6 +189,26 @@
}
}
+ private void buildCalendars(Rule rule, String calendarsString, RuleBuildContext context) {
+ Object val = null;
+ try {
+ val = MVEL.eval( calendarsString );
+ String[] calNames = null;
+ if ( val instanceof List ) {
+ calNames = ( String[] ) ((List)val).toArray( new String[ ((List)val).size() ] );
+ } else if ( val instanceof String ) {
+ calNames = new String[] { (String) val };
+ } else {
+ context.getErrors().add( "Calendars attribute did not return a String or String[] '" + val + "'" );
+ }
+ if ( calNames != null ) {
+ rule.setCalendars( calNames );
+ }
+ } catch ( Exception e ) {
+ context.getErrors().add( "Unable to build Calendars attribute '" + val + "'" + e.getMessage() );
+ }
+ }
+
private void buildTimer(Rule rule, String timerString, RuleBuildContext context) {
if( timerString.indexOf( '(' ) >=0 ) {
timerString = timerString.substring( timerString.indexOf( '(' )+1, timerString.lastIndexOf( ')' ) );
@@ -218,12 +223,44 @@
protocol = timerString.substring( 0, colonPos );
}
- String body = timerString.substring( colonPos + 1 );
+ int startPos = timerString.indexOf( "start" );
+ int endPos = timerString.indexOf( "end" );
+ int optionsPos = timerString.length();
+
+ Date startDate = null;
+ Date endDate = null;
+
+ if ( startPos != -1 && endPos != -1 ) {
+ // support case where someone puts end before start
+ if ( startPos < endPos ) {
+ // start is first
+ optionsPos = startPos;
+ int equalsPos = timerString.indexOf( '=', startPos );
+ startDate = DateUtils.parseDate( timerString.substring( equalsPos + 2, endPos ).trim() );
+ } else {
+ // end is first
+ optionsPos = endPos;
+ int equalsPos = timerString.indexOf( '=', endPos );
+ startDate = DateUtils.parseDate( timerString.substring( equalsPos + 2, startPos ).trim() );
+ }
+ } else if ( startPos != -1 ) {
+ optionsPos = startPos;
+ int equalsPos = timerString.indexOf( '=', startPos );
+ startDate = DateUtils.parseDate( timerString.substring( equalsPos + 2 ).trim() );
+ } else if ( endPos != -1 ) {
+ optionsPos = endPos;
+ int equalsPos = timerString.indexOf( '=', endPos );
+ endDate = DateUtils.parseDate( timerString.substring( equalsPos + 2 ).trim() );
+ }
+
+
+ String body = timerString.substring( colonPos + 1, optionsPos ).trim();
+
Timer timer = null;
if ( "cron".equals( protocol ) ) {
try {
- timer = new CronTimer( null, null, new CronExpression( body ) );
+ timer = new CronTimer( startDate, endDate, new CronExpression( body ) );
} catch ( ParseException e ) {
context.getErrors().add( "Unable to build set timer '" + timerString + "'");
return;
@@ -243,7 +280,7 @@
context.getErrors().add( "Incorrect number of arguments for interval timer '" + timerString + "'");
return;
}
- timer = new IntervalTimer(null, null, delay, period);
+ timer = new IntervalTimer(startDate, endDate, delay, period);
} else {
context.getErrors().add( "Protocol for timer does not exist '" + timerString +"'");
return;
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerManager.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerManager.java 2009-12-09 16:21:54 UTC (rev 30565)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/process/instance/timer/TimerManager.java 2009-12-09 20:50:53 UTC (rev 30566)
@@ -18,14 +18,15 @@
* @author <a href="mailto:kris_verlaenen at hotmail.com">Kris Verlaenen</a>
*/
public class TimerManager {
- private long timerId = 0;
+ private long timerId = 0;
- private WorkingMemory workingMemory;
- private TimerService timerService;
- private Map<Long, TimerInstance> timers = new HashMap<Long, TimerInstance>();
- private Job processJob = new ProcessJob();
+ private WorkingMemory workingMemory;
+ private TimerService timerService;
+ private Map<Long, TimerInstance> timers = new HashMap<Long, TimerInstance>();
+ private Job processJob = new ProcessJob();
- public TimerManager(WorkingMemory workingMemory, TimerService timerService) {
+ public TimerManager(WorkingMemory workingMemory,
+ TimerService timerService) {
this.workingMemory = workingMemory;
this.timerService = timerService;
}
@@ -33,9 +34,9 @@
public void registerTimer(final TimerInstance timer,
ProcessInstance processInstance) {
timer.setId( ++timerId );
- timer.setProcessInstanceId(processInstance.getId());
- timer.setActivated(new Date());
-
+ timer.setProcessInstanceId( processInstance.getId() );
+ timer.setActivated( new Date() );
+
ProcessJobContext ctx = new ProcessJobContext( timer,
processInstance.getId(),
this.workingMemory );
@@ -43,82 +44,92 @@
JobHandle jobHandle = this.timerService.scheduleJob( processJob,
ctx,
new IntervalTrigger( timerService.getCurrentTime(),
- timer.getDelay(),
- timer.getPeriod(),
- null,
- null ) );
+ null,
+ null,
+ timer.getDelay(),
+ timer.getPeriod(),
+ null,
+ null ) );
timer.setJobHandle( jobHandle );
- timers.put(timer.getId(), timer);
+ timers.put( timer.getId(),
+ timer );
}
public void internalAddTimer(final TimerInstance timer) {
- ProcessJobContext ctx = new ProcessJobContext(
- timer, timer.getProcessInstanceId(), this.workingMemory);
+ ProcessJobContext ctx = new ProcessJobContext( timer,
+ timer.getProcessInstanceId(),
+ this.workingMemory );
- long delay;
- Date lastTriggered = timer.getLastTriggered();
- if (lastTriggered == null) {
- Date activated = timer.getActivated();
- Date now = new Date();
- long timespan = now.getTime() - activated.getTime();
- delay = timer.getDelay() - timespan;
- if (delay < 0) {
- delay = 0;
- }
- } else {
- Date now = new Date();
- long timespan = now.getTime() - lastTriggered.getTime();
- delay = timespan - timer.getPeriod();
- if (delay < 0) {
- delay = 0;
- }
- }
- JobHandle jobHandle = this.timerService.scheduleJob(
- processJob, ctx, new IntervalTrigger(timerService.getCurrentTime(),
- delay,
- timer.getPeriod(),
- null,
- null));
- timer.setJobHandle(jobHandle);
- timers.put(timer.getId(), timer);
- }
+ long delay;
+ Date lastTriggered = timer.getLastTriggered();
+ if ( lastTriggered == null ) {
+ Date activated = timer.getActivated();
+ Date now = new Date();
+ long timespan = now.getTime() - activated.getTime();
+ delay = timer.getDelay() - timespan;
+ if ( delay < 0 ) {
+ delay = 0;
+ }
+ } else {
+ Date now = new Date();
+ long timespan = now.getTime() - lastTriggered.getTime();
+ delay = timespan - timer.getPeriod();
+ if ( delay < 0 ) {
+ delay = 0;
+ }
+ }
+ JobHandle jobHandle = this.timerService.scheduleJob( processJob,
+ ctx,
+ new IntervalTrigger( timerService.getCurrentTime(),
+ null,
+ null,
+ delay,
+ timer.getPeriod(),
+ null,
+ null ) );
+ timer.setJobHandle( jobHandle );
+ timers.put( timer.getId(),
+ timer );
+ }
public void cancelTimer(long timerId) {
- TimerInstance timer = timers.remove(timerId);
- if (timer != null) {
- timerService.removeJob( timer.getJobHandle() );
- }
+ TimerInstance timer = timers.remove( timerId );
+ if ( timer != null ) {
+ timerService.removeJob( timer.getJobHandle() );
+ }
}
-
+
public void dispose() {
- for (TimerInstance timer: timers.values()) {
- timerService.removeJob( timer.getJobHandle() );
- }
- timerService.shutdown();
+ for ( TimerInstance timer : timers.values() ) {
+ timerService.removeJob( timer.getJobHandle() );
+ }
+ timerService.shutdown();
}
-
+
public TimerService getTimerService() {
return this.timerService;
}
-
+
public Collection<TimerInstance> getTimers() {
- return timers.values();
+ return timers.values();
}
-
+
public long internalGetTimerId() {
- return timerId;
+ return timerId;
}
-
+
public void internalSetTimerId(long timerId) {
- this.timerId = timerId;
+ this.timerId = timerId;
}
-
+
public void setTimerService(TimerService timerService) {
this.timerService = timerService;
}
- public class ProcessJob implements Job {
-
+ public class ProcessJob
+ implements
+ Job {
+
public void execute(JobContext c) {
ProcessJobContext ctx = (ProcessJobContext) c;
@@ -128,13 +139,15 @@
if ( processInstanceId == null ) {
throw new IllegalArgumentException( "Could not find process instance for timer " );
}
-
- ctx.getTimer().setLastTriggered(new Date());
-
- workingMemory.getSignalManager().signalEvent(processInstanceId, "timerTriggered", ctx.getTimer());
- if (ctx.getTimer().getPeriod() == 0) {
- TimerManager.this.timers.remove(ctx.getTimer().getId());
+ ctx.getTimer().setLastTriggered( new Date() );
+
+ workingMemory.getSignalManager().signalEvent( processInstanceId,
+ "timerTriggered",
+ ctx.getTimer() );
+
+ if ( ctx.getTimer().getPeriod() == 0 ) {
+ TimerManager.this.timers.remove( ctx.getTimer().getId() );
}
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/CronTrigger.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/CronTrigger.java 2009-12-09 16:21:54 UTC (rev 30565)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/CronTrigger.java 2009-12-09 20:50:53 UTC (rev 30566)
@@ -39,7 +39,8 @@
setTimeZone(TimeZone.getDefault());
// Set the first FireTime, this is sensitive to StartTime
- this.nextFireTime = getFireTimeAfter(new Date(timestamp - 1000l));
+ this.nextFireTime = new Date(timestamp - 1000l);
+ setFirstFireTimeAfter();
this.calendarNames = calendarNames;
this.calendars = calendars;
@@ -211,7 +212,7 @@
public Date nextFireTime() {
Date date = this.nextFireTime;
- this.nextFireTime = getFireTimeAfter(this.nextFireTime);
+ this.nextFireTime = getTimeAfter(this.nextFireTime);
updateToNextIncludeDate();
return date;
}
@@ -228,21 +229,21 @@
* org.quartz.Calendar (if any)
* </p>
*/
- public Date getFireTimeAfter(Date afterTime) {
- if (getStartTime().after(afterTime)) {
- afterTime = new Date(getStartTime().getTime() - 1000l);
+ public void setFirstFireTimeAfter() {
+ if (getStartTime().after(this.nextFireTime)) {
+ this.nextFireTime = new Date(getStartTime().getTime() - 1000l);
}
- if (getEndTime() != null && (afterTime.compareTo(getEndTime()) >= 0)) {
- return null;
+ if (getEndTime() != null && (this.nextFireTime.compareTo(getEndTime()) >= 0)) {
+ this.nextFireTime = null;
}
- Date pot = getTimeAfter(afterTime);
+ Date pot = getTimeAfter(this.nextFireTime);
if (getEndTime() != null && pot != null && pot.after(getEndTime())) {
- return null;
+ this.nextFireTime = null;
+ } else {
+ this.nextFireTime = pot;
}
-
- return pot;
}
protected Date getTimeAfter(Date afterTime) {
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/IntervalTimer.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/IntervalTimer.java 2009-12-09 16:21:54 UTC (rev 30565)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/IntervalTimer.java 2009-12-09 20:50:53 UTC (rev 30566)
@@ -67,8 +67,10 @@
String[] calendarNames,
Calendars calendars) {
return new IntervalTrigger( timestamp,
- delay,
- period,
+ this.startTime,
+ this.endTime,
+ this.delay,
+ this.period,
calendarNames,
calendars );
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/IntervalTrigger.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/IntervalTrigger.java 2009-12-09 16:21:54 UTC (rev 30565)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/IntervalTrigger.java 2009-12-09 20:50:53 UTC (rev 30566)
@@ -6,6 +6,7 @@
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.util.Calendar;
import java.util.Date;
import org.drools.runtime.Calendars;
@@ -14,6 +15,8 @@
public class IntervalTrigger
implements
Trigger {
+ private Date startTime;
+ private Date endTime;
private Date nextFireTime;
private long period;
private String[] calendarNames;
@@ -23,22 +26,98 @@
}
- public IntervalTrigger(long currentTS,
+ public IntervalTrigger(long timestamp,
+ Date startTime,
+ Date endTime,
long delay,
long period,
String[] calendarNames,
Calendars calendars) {
- this.nextFireTime = new Date( currentTS + delay );
this.period = period;
+ if (startTime == null) {
+ startTime = new Date(timestamp);
+ }
+ setStartTime(startTime);
+
+ if (endTime != null) {
+ setEndTime(endTime);
+ }
+
this.calendarNames = calendarNames;
this.calendars = calendars;
+ this.nextFireTime = new Date( timestamp + delay );
+ setFirstFireTime();
+
// Update to next include time, if we have calendars
updateToNextIncludeDate( );
}
+
+ public Date getStartTime() {
+ return this.startTime;
+ }
+
+ public void setStartTime(Date startTime) {
+ if (startTime == null) {
+ throw new IllegalArgumentException("Start time cannot be null");
+ }
+ Date eTime = getEndTime();
+ if (eTime != null && startTime != null && eTime.before(startTime)) {
+ throw new IllegalArgumentException(
+ "End time cannot be before start time");
+ }
+
+ // round off millisecond...
+ // Note timeZone is not needed here as parameter for
+ // Calendar.getInstance(),
+ // since time zone is implicit when using a Date in the setTime method.
+ Calendar cl = Calendar.getInstance();
+ cl.setTime(startTime);
+ cl.set(Calendar.MILLISECOND, 0);
+
+ this.startTime = cl.getTime();
+ }
+
+ /**
+ * <p>
+ * Get the time at which the <code>CronTrigger</code> should quit
+ * repeating - even if repeastCount isn't yet satisfied.
+ * </p>
+ *
+ * @see #getFinalFireTime()
+ */
+ public Date getEndTime() {
+ return this.endTime;
+ }
+
+ public void setEndTime(Date endTime) {
+ Date sTime = getStartTime();
+ if (sTime != null && endTime != null && sTime.after(endTime)) {
+ throw new IllegalArgumentException(
+ "End time cannot be before start time");
+ }
+
+ this.endTime = endTime;
+ }
+
+ public void setFirstFireTime() {
+ if (getStartTime().after(this.nextFireTime)) {
+ this.nextFireTime = new Date(getStartTime().getTime() - 1000l);
+ }
+
+ if (getEndTime() != null && (this.nextFireTime.compareTo(getEndTime()) >= 0)) {
+ this.nextFireTime = null;
+ }
+
+ Date pot = getTimeAfter();
+ if (getEndTime() != null && pot != null && pot.after(getEndTime())) {
+ this.nextFireTime = null;
+ }
+ }
+
public Date hasNextFireTime() {
return nextFireTime;
}
Modified: labs/jbossrules/trunk/drools-vsm/src/main/java/org/drools/vsm/remote/StatefulKnowledgeSessionRemoteClient.java
===================================================================
--- labs/jbossrules/trunk/drools-vsm/src/main/java/org/drools/vsm/remote/StatefulKnowledgeSessionRemoteClient.java 2009-12-09 16:21:54 UTC (rev 30565)
+++ labs/jbossrules/trunk/drools-vsm/src/main/java/org/drools/vsm/remote/StatefulKnowledgeSessionRemoteClient.java 2009-12-09 20:50:53 UTC (rev 30566)
@@ -11,6 +11,7 @@
import org.drools.event.process.ProcessEventListener;
import org.drools.event.rule.AgendaEventListener;
import org.drools.event.rule.WorkingMemoryEventListener;
+import org.drools.runtime.Calendars;
import org.drools.runtime.Environment;
import org.drools.runtime.ExecutionResults;
import org.drools.runtime.ExitPoint;
@@ -347,4 +348,9 @@
}
+ public Calendars getCalendars() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
}
More information about the jboss-svn-commits
mailing list