Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ScopeInstanceImpl.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ScopeInstanceImpl.java (revision 6450) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ScopeInstanceImpl.java (working copy) @@ -34,6 +34,7 @@ import org.jbpm.api.JbpmException; import org.jbpm.internal.log.Log; import org.jbpm.pvm.internal.cal.CronExpression; +import org.jbpm.pvm.internal.el.Expression; import org.jbpm.pvm.internal.env.EnvironmentImpl; import org.jbpm.pvm.internal.history.HistoryEvent; import org.jbpm.pvm.internal.history.events.VariableCreate; @@ -56,13 +57,13 @@ private static final long serialVersionUID = 1L; private static Log log = Log.getLog(ScopeInstanceImpl.class.getName()); - + protected long dbid; protected int dbversion; protected boolean hasVariables; protected Map variables = new HashMap(); - + protected String state; protected String suspendHistoryState; @@ -100,7 +101,7 @@ protected Variable createVariableObject(String key, Object value, String typeName, boolean isHistoryEnabled) { log.debug("create variable '"+key+"' in '"+this+"' with value '"+value+"'"); - + Type type = findType(key, value, typeName); Variable variable; @@ -130,14 +131,14 @@ variable.setTask(getTask()); variable.setHistoryEnabled(isHistoryEnabled); variable.setValue(value, this); - + long dbid = DbidGenerator.getDbidGenerator().getNextId(); variable.setDbid(dbid); if (isHistoryEnabled) { HistoryEvent.fire(new VariableCreate(variable)); } - + return variable; } @@ -159,7 +160,7 @@ Variable variable = getVariableObject(key); // if there is already a variable instance and it doesn't support the current type... - if ( (variable!=null) + if ( (variable!=null) && (!variable.supports(value, this)) ) { // delete the old variable instance @@ -185,13 +186,13 @@ } } } - + public Object getVariable(String key) { Variable variable = getVariableObject(key); if (variable!=null) { return variable.getValue(this); } - + ScopeInstanceImpl parentScope = getParentVariableScope(); if (parentScope!=null) { return parentScope.getVariable(key); @@ -243,7 +244,7 @@ } return values; } - + public boolean hasVariables() { ScopeInstanceImpl parentScope = getParentVariableScope(); return ( hasVariables @@ -266,7 +267,7 @@ if (parentScope!=null) { return parentScope.removeVariable(key); } - // the actual value is not returned to prevent that an object + // the actual value is not returned to prevent that an object // has to be fetched from the db for it to be deleted return false; } @@ -283,7 +284,7 @@ protected TimerImpl newTimer() { return new TimerImpl(); } - + public TimerImpl createTimer() { return createTimer(null); } @@ -295,13 +296,13 @@ TimerImpl timer = newTimer(); timer.setExecution(getTimerExecution()); - + if (timerDefinition!=null) { timer.setEventName(timerDefinition.getEventName()); timer.setSignalName(timerDefinition.getSignalName()); timer.setDueDate(timerDefinition.getDueDate()); timer.setDueDateDescription(timerDefinition.getDueDateDescription()); - + if (timer.getDueDate() == null && timerDefinition.getCronExpression() != null) { try { timer.setDueDate(new CronExpression(timerDefinition.getCronExpression()).getNextValidTimeAfter(Clock.getTime())); @@ -309,7 +310,7 @@ throw new JbpmException("Can't parse cron expression " + timerDefinition.getCronExpression(), pe); } } - + Boolean isExclusive = timerDefinition.isExclusive(); if (isExclusive!=null) { timer.setExclusive(isExclusive); @@ -318,9 +319,16 @@ if (retries!=null) { timer.setRetries(retries); } - timer.setRepeat(timerDefinition.getRepeat()); + // support for repeat attribute given as expression + // only if repeat is specified + if (timerDefinition.getRepeat() != null) { + Object repeatEl = Expression.create(timerDefinition.getRepeat()).evaluate(); + timer.setRepeat(repeatEl.toString()); + } else { + timer.setRepeat(timerDefinition.getRepeat()); + } } - + return timer; } @@ -379,7 +387,7 @@ } // customizable methods ///////////////////////////////////////////////////// - + public ExecutionImpl getExecution() { return null; } @@ -397,7 +405,7 @@ } // getters and setters ////////////////////////////////////////////////////// - + public long getDbid() { return dbid; } Index: modules/test-db/src/test/java/org/jbpm/test/timer/TimerTest.java =================================================================== --- modules/test-db/src/test/java/org/jbpm/test/timer/TimerTest.java (revision 6450) +++ modules/test-db/src/test/java/org/jbpm/test/timer/TimerTest.java (working copy) @@ -22,6 +22,7 @@ package org.jbpm.test.timer; import java.util.Calendar; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -428,7 +429,98 @@ assertProcessInstanceEnded(processInstance); } + + public void testTimerRepeat() { + deployJpdlXmlString( + "" + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + "" + ); + ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", "82436"); + + Job job = managementService.createJobQuery() + .processInstanceId(processInstance.getId()) + .uniqueResult(); + + managementService.executeJob(job.getId()); + + + job = managementService.createJobQuery() + .processInstanceId(processInstance.getId()) + .uniqueResult(); + + managementService.executeJob(job.getId()); + + processInstance = executionService.findProcessInstanceById(processInstance.getId()); + String processInstanceId = processInstance.findActiveExecutionIn("a").getId(); + + processInstance = executionService.signalExecutionById(processInstanceId); + + processInstance = executionService.signalExecutionById(processInstance.getId()); + + assertProcessInstanceEnded(processInstance); + } + + public void testTimerELRepeat() { + deployJpdlXmlString( + "" + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + "" + ); + + Map variables = Collections.singletonMap("repeat", "20 seconds"); + ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", variables, "82436"); + + Job job = managementService.createJobQuery() + .processInstanceId(processInstance.getId()) + .uniqueResult(); + + managementService.executeJob(job.getId()); + + + job = managementService.createJobQuery() + .processInstanceId(processInstance.getId()) + .uniqueResult(); + + managementService.executeJob(job.getId()); + + processInstance = executionService.findProcessInstanceById(processInstance.getId()); + String processInstanceId = processInstance.findActiveExecutionIn("a").getId(); + + processInstance = executionService.signalExecutionById(processInstanceId); + + processInstance = executionService.signalExecutionById(processInstance.getId()); + + assertProcessInstanceEnded(processInstance); + } + public static class MyCustomWait implements ExternalActivityBehaviour, EventListener { private static final long serialVersionUID = 1L;