Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java (revision 6437)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java (working copy)
@@ -30,27 +30,31 @@
import java.util.Map;
import java.util.regex.Pattern;
+import org.jbpm.api.Execution;
import org.jbpm.api.JbpmException;
+import org.jbpm.pvm.internal.el.Expression;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.script.ScriptManager;
import org.jbpm.pvm.internal.util.Clock;
/**
* represents a time duration.
- *
- *
With the constructor {link {@link #Duration(String)} you can create a
+ *
+ *
With the constructor {link {@link #Duration(String)} you can create a
* Duration from a text representation. The syntax is as follows
*
- *
+ *
*
* duration = part [',' part | 'and' part]*
* part = number ['business'] unit
* number = (0..9)+
* unit = (y|year|years|month|months|w|week|weeks|d|day|days|h|hour|hours|min|minute|minutes|s|sec|second|seconds|milli|millis|millisecond|milliseconds)
*
- *
+ *
* Duration is immutable.
*
+ *
+ * @author Huisheng Xu
*/
public class Duration implements Serializable {
@@ -65,12 +69,12 @@
protected int weeks;
protected int months;
protected int years;
-
+
private final static String dateFormat = "yyyy-MM-dd HH:mm:ss";
-
+
private static final Pattern dateDurationPattern = Pattern.compile("\\s*(#\\{.+\\})\\s*"
+ "(?:(\\+|-)\\s*(\\d+\\s+(?:business\\s+)?\\w+))?\\s*");
-
+
private static final Pattern durationPattern = Pattern.compile("\\s*(\\d+\\s+(?:business\\s+)?"
+ "\\w+)\\s*");
@@ -78,13 +82,13 @@
protected Duration() {
}
- /** parses the duration from a text
- *
+ /** parses the duration from a text
+ *
* duration = part [',' part | 'and' part]*
* part = number ['business'] unit
* number = (0..9)+
* unit = (y|year|years|month|months|w|week|weeks|d|day|days|h|hour|hours|min|minute|minutes|s|sec|second|seconds|milli|millis|millisecond|milliseconds)
- *
+ *
* @throws JbpmException if the parsing is unsuccessful
*/
public Duration(String text) {
@@ -93,19 +97,19 @@
for (String part: splitInParts(text)) {
parsePart(part);
}
-
+
isBusinessTime = text.indexOf("business")!=-1;
}
-
+
public static boolean isValidExpression(String durationExpression) {
try {
- new Duration(durationExpression);
+ new Duration(durationExpression);
} catch (JbpmException e) {
return false;
}
return true;
}
-
+
public static Date calculateDueDate(String durationExpression) {
Date duedate = null;
if (durationExpression != null) {
@@ -124,18 +128,27 @@
baseDate = (Date) result;
} else if (result instanceof Calendar) {
baseDate = ((Calendar) result).getTime();
+ } else if (result instanceof String) {
+ baseDate = Clock.getTime();
+ int endOfELIndex = durationExpression.indexOf("}");
+ if (endOfELIndex < (durationExpression.length() - 1)) {
+ throw new JbpmException("Invalid duedate, didnot support + or - in String type EL.");
+ }
+ durationString = (String) Expression.create(durationExpression, null).evaluate((Execution) null);
} else {
throw new JbpmException("Invalid basedate type: " + baseDateEL + " is of type " + result.getClass().getName()
+ ". Only Date and Calendar are supported");
}
- int endOfELIndex = durationExpression.indexOf("}");
- if (endOfELIndex < (durationExpression.length() - 1)) {
- durationSeparator = durationExpression.substring(endOfELIndex + 1).trim().charAt(0);
- if (durationSeparator != '+' && durationSeparator != '-') {
- throw new JbpmException("Invalid duedate, + or - missing after EL");
+ if (durationString == null) {
+ int endOfELIndex = durationExpression.indexOf("}");
+ if (endOfELIndex < (durationExpression.length() - 1)) {
+ durationSeparator = durationExpression.substring(endOfELIndex + 1).trim().charAt(0);
+ if (durationSeparator != '+' && durationSeparator != '-') {
+ throw new JbpmException("Invalid duedate, + or - missing after EL");
+ }
+ durationString = durationExpression.substring(endOfELIndex + 1).substring(2).trim();
}
- durationString = durationExpression.substring(endOfELIndex + 1).substring(2).trim();
}
} else {
@@ -173,40 +186,40 @@
this.months = months;
this.years = years;
}
-
+
private List splitInParts(String text) {
List parts = new ArrayList(2);
while (text!=null) {
int commaIndex = text.indexOf(',');
int andIndex = text.indexOf(" and ");
- if ( ( (commaIndex==-1)
+ if ( ( (commaIndex==-1)
&& (andIndex!=-1)
- )
- ||
- ( ( (commaIndex!=-1)
+ )
+ ||
+ ( ( (commaIndex!=-1)
&& (andIndex!=-1)
- )
+ )
&& (andIndexcommaIndex)
)
) {
String part = text.substring(0, commaIndex).trim();
parts.add(part);
text = text.substring(commaIndex+1);
-
+
} else {
parts.add(text.trim());
text = null;
@@ -224,7 +237,7 @@
String quantityText = part.substring(0, spaceIndex).trim();
spaceIndex = part.lastIndexOf(' ');
String unitText = part.substring(spaceIndex+1).trim().toLowerCase();
-
+
int quantity;
try {
quantity = Integer.parseInt(quantityText);
@@ -237,7 +250,7 @@
}
fieldSetter.set(this, quantity);
}
-
+
interface FieldSetter {
void set(Duration duration, int quantity);
}
@@ -325,7 +338,7 @@
fieldSetters.put("year", fieldSetter);
fieldSetters.put("years", fieldSetter);
}
-
+
public int getDays() {
return days;
}
@@ -353,7 +366,7 @@
public int getSeconds() {
return seconds;
}
-
+
public int getWeeks() {
return weeks;
}
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 6437)
+++ modules/test-db/src/test/java/org/jbpm/test/timer/TimerTest.java (working copy)
@@ -1,451 +1,486 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jbpm.test.timer;
-
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.jbpm.api.Execution;
-import org.jbpm.api.JbpmException;
-import org.jbpm.api.ProcessInstance;
-import org.jbpm.api.activity.ActivityExecution;
-import org.jbpm.api.activity.ExternalActivityBehaviour;
-import org.jbpm.api.job.Job;
-import org.jbpm.api.listener.EventListener;
-import org.jbpm.api.listener.EventListenerExecution;
-import org.jbpm.test.JbpmTestCase;
-
-/**
- * @author Tom Baeyens
- * @author Ronald Van Kuijk
- * @author Joram Barrez
- */
-public class TimerTest extends JbpmTestCase {
-
- private static final String TEST_PROCESS_CUSTOM =
- "" +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- "";
-
- public void testTimerTimeout() {
- deployJpdlXmlString(
- "" +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- ""
- );
-
- ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", "82436");
-
- Job job = managementService.createJobQuery()
- .processInstanceId(processInstance.getId())
- .uniqueResult();
-
- managementService.executeJob(job.getId());
- assertProcessInstanceEnded(processInstance);
- }
-
- /**
- * Test case for https://jira.jboss.org/jira/browse/JBPM-2517
- *
- * In this issue, it is stated that the calculations for the timer
- * will overflow if larger than 4 weeks due to integer limitations.
- */
- public void testTimerInFuture() {
- deployJpdlXmlString(
- "" +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- ""
- );
-
- ProcessInstance processInstance = executionService.startProcessInstanceByKey("theProcess");
-
- Calendar now = Calendar.getInstance();
- int currentYear = now.get(Calendar.YEAR);
-
- Job job = managementService.createJobQuery()
- .processInstanceId(processInstance.getId())
- .uniqueResult();
-
- Calendar jobDate = Calendar.getInstance();
- jobDate.setTime(job.getDuedate());
-
- assertEquals(currentYear + 10, jobDate.get(Calendar.YEAR));
- }
-
- public void testTimerELDate() {
- deployJpdlXmlString(
- "" +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- ""
- );
-
- Map proc_vars = new HashMap();
- Calendar cal = Calendar.getInstance();
- cal.add(Calendar.DAY_OF_MONTH, 6);
- proc_vars.put("proc_var", cal.getTime());
- ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
-
- Job job = managementService.createJobQuery()
- .processInstanceId(processInstance.getId())
- .uniqueResult();
-
- Calendar jobDate = Calendar.getInstance();
- jobDate.setTime(job.getDuedate());
-
- assertEquals(cal.get(Calendar.DAY_OF_MONTH), jobDate.get(Calendar.DAY_OF_MONTH));
-
- managementService.executeJob(job.getId());
- assertProcessInstanceEnded(processInstance);
- }
-
- public void testTimerELCalendar() {
- deployJpdlXmlString(
- "" +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- ""
- );
-
- Map proc_vars = new HashMap();
- Calendar cal = Calendar.getInstance();
- cal.add(Calendar.DAY_OF_MONTH, 6);
- proc_vars.put("proc_var", cal);
- ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
-
- Job job = managementService.createJobQuery()
- .processInstanceId(processInstance.getId())
- .uniqueResult();
-
- Calendar jobDate = Calendar.getInstance();
- jobDate.setTime(job.getDuedate());
-
- assertEquals(cal.get(Calendar.DAY_OF_MONTH), jobDate.get(Calendar.DAY_OF_MONTH));
-
- managementService.executeJob(job.getId());
- assertProcessInstanceEnded(processInstance);
- }
-
- public void testTimerELCalendarAdd() {
- deployJpdlXmlString(
- "" +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- ""
- );
-
- Map proc_vars = new HashMap();
- Calendar cal = Calendar.getInstance();
- cal.add(Calendar.DAY_OF_MONTH, 6);
- proc_vars.put("proc_var", cal);
- ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
-
- Job job = managementService.createJobQuery()
- .processInstanceId(processInstance.getId())
- .uniqueResult();
-
- Calendar jobDate = Calendar.getInstance();
- jobDate.setTime(job.getDuedate());
-
- cal.add(Calendar.DAY_OF_MONTH, 5);
- assertEquals(cal.get(Calendar.DAY_OF_MONTH), jobDate.get(Calendar.DAY_OF_MONTH));
-
- managementService.executeJob(job.getId());
- assertProcessInstanceEnded(processInstance);
- }
-
- public void testTimerELCalendarSubtract() {
- deployJpdlXmlString(
- "" +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- ""
- );
-
- Map proc_vars = new HashMap();
- Calendar cal = Calendar.getInstance();
- cal.add(Calendar.DAY_OF_MONTH, 6);
-
- proc_vars.put("proc_var", cal);
- ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
-
- Job job = managementService.createJobQuery()
- .processInstanceId(processInstance.getId())
- .uniqueResult();
-
- Calendar jobDate = Calendar.getInstance();
- jobDate.setTime(job.getDuedate());
-
- // 6 days from now minus 5 days is tomorrow so subtract 5 from the original added 6.
- cal.add(Calendar.DAY_OF_MONTH, -5);
- assertEquals(cal.get(Calendar.DAY_OF_MONTH) , jobDate.get(Calendar.DAY_OF_MONTH));
-
- managementService.executeJob(job.getId());
- assertProcessInstanceEnded(processInstance);
- }
-
- public void testTimerELCalendarAddBusiness() {
- deployJpdlXmlString(
- "" +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- ""
- );
-
- Map proc_vars = new HashMap();
- Calendar cal = Calendar.getInstance();
- cal.set(2010, 01, 12, 12, 00, 00); // 12 feb 2010 noon
- proc_vars.put("proc_var", cal);
- ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
-
- Job job = managementService.createJobQuery()
- .processInstanceId(processInstance.getId())
- .uniqueResult();
-
- Calendar jobDate = Calendar.getInstance();
- jobDate.setTime(job.getDuedate());
-
- // 12 feb is friday, 5 businessdays further is friday 19th
- assertEquals(19 , jobDate.get(Calendar.DAY_OF_MONTH));
-
- managementService.executeJob(job.getId());
- assertProcessInstanceEnded(processInstance);
- }
-
- public void testTimerELFail() {
- deployJpdlXmlString(
- "" +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- ""
- );
-
- Map proc_vars = new HashMap();
- proc_vars.put("proc_var", new Long(0));
- try {
- executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
- fail("Should not happen, exception expected");
- } catch (Exception e) {}
- }
-
- public void testTimerELSubtractBusinessFail() {
- deployJpdlXmlString(
- "" +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- ""
- );
-
- Map proc_vars = new HashMap();
- Calendar cal = Calendar.getInstance();
- cal.set(2010, 01, 12, 12, 00, 00); // 12 feb 2010 noon
- proc_vars.put("proc_var", cal);
- try {
- executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
- fail("Should not happen, exception expected");
- } catch (Exception e) {}
- }
-
- public void testTimerELSubtractPastFail() {
- deployJpdlXmlString(
- "" +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- " " +
- ""
- );
-
- Map proc_vars = new HashMap();
- Calendar cal = Calendar.getInstance();
- cal.add(Calendar.DAY_OF_MONTH, 2);
- proc_vars.put("proc_var", cal);
- try {
- executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
- fail("Should not happen, exception expected");
- } catch (Exception e) {}
- }
-
- public void testTimerTimeoutCustom() {
- deployJpdlXmlString(TEST_PROCESS_CUSTOM);
-
- ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL");
- assertEquals(Execution.STATE_INACTIVE_SCOPE, processInstance.getState());
- assertNotActivityActive(processInstance.getId(), "a");
-
- // execute the async state so it becomes active
- Job async = managementService.createJobQuery().messages().processInstanceId(processInstance.getId()).uniqueResult();
- managementService.executeJob(async.getId());
- assertActivityActive(processInstance.getId(), "a");
-
- try {
- executionService.signalExecutionById(processInstance.getId());
- fail("Should not happen, exception expected");
- } catch (JbpmException e) {
- // Should happen....Signalling an inactive-scope exexcution is not
- // allowed. If the timer is removed, this test should fail since the
- // state of the execution is async then and signalling that is allowed.
- }
-
- assertProcessInstanceActive(processInstance);
- executionService.signalExecutionById(processInstance.getExecution("a").getId());
- assertActivityActive(processInstance.getId(), "b");
- }
-
- public void testTimerSignalCustom() {
- deployJpdlXmlString(TEST_PROCESS_CUSTOM);
- ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL");
-
- Job async = managementService.createJobQuery().messages().processInstanceId(processInstance.getId()).uniqueResult();
- managementService.executeJob(async.getId());
-
- int beforeTimer = MyCustomWait.nrOfTimesCalled;
- Job timer = managementService.createJobQuery().timers().processInstanceId(processInstance.getId()).uniqueResult();
- managementService.executeJob(timer.getId());
- int afterTimer = MyCustomWait.nrOfTimesCalled;
- assertEquals(beforeTimer + 1, afterTimer);
-
- assertProcessInstanceEnded(processInstance);
- }
-
- public static class MyCustomWait implements ExternalActivityBehaviour, EventListener {
-
- private static final long serialVersionUID = 1L;
-
- static int nrOfTimesCalled;
-
- public void execute(ActivityExecution execution) throws Exception {
- execution.waitForSignal();
- }
-
- public void signal(ActivityExecution execution, String signalName, Map parameters) throws Exception {
- execution.take(signalName);
- }
-
- public void notify(EventListenerExecution execution) throws Exception {
- nrOfTimesCalled++;
- }
- }
-
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.test.timer;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jbpm.api.Execution;
+import org.jbpm.api.JbpmException;
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.api.activity.ActivityExecution;
+import org.jbpm.api.activity.ExternalActivityBehaviour;
+import org.jbpm.api.job.Job;
+import org.jbpm.api.listener.EventListener;
+import org.jbpm.api.listener.EventListenerExecution;
+import org.jbpm.test.JbpmTestCase;
+
+/**
+ * @author Tom Baeyens
+ * @author Ronald Van Kuijk
+ * @author Joram Barrez
+ * @author Huisheng Xu
+ */
+public class TimerTest extends JbpmTestCase {
+
+ private static final String TEST_PROCESS_CUSTOM =
+ "" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ "";
+
+ public void testTimerTimeout() {
+ deployJpdlXmlString(
+ "" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ ""
+ );
+
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", "82436");
+
+ Job job = managementService.createJobQuery()
+ .processInstanceId(processInstance.getId())
+ .uniqueResult();
+
+ managementService.executeJob(job.getId());
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ /**
+ * Test case for https://jira.jboss.org/jira/browse/JBPM-2517
+ *
+ * In this issue, it is stated that the calculations for the timer
+ * will overflow if larger than 4 weeks due to integer limitations.
+ */
+ public void testTimerInFuture() {
+ deployJpdlXmlString(
+ "" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ ""
+ );
+
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("theProcess");
+
+ Calendar now = Calendar.getInstance();
+ int currentYear = now.get(Calendar.YEAR);
+
+ Job job = managementService.createJobQuery()
+ .processInstanceId(processInstance.getId())
+ .uniqueResult();
+
+ Calendar jobDate = Calendar.getInstance();
+ jobDate.setTime(job.getDuedate());
+
+ assertEquals(currentYear + 10, jobDate.get(Calendar.YEAR));
+ }
+
+ public void testTimerELDate() {
+ deployJpdlXmlString(
+ "" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ ""
+ );
+
+ Map proc_vars = new HashMap();
+ Calendar cal = Calendar.getInstance();
+ cal.add(Calendar.DAY_OF_MONTH, 6);
+ proc_vars.put("proc_var", cal.getTime());
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
+
+ Job job = managementService.createJobQuery()
+ .processInstanceId(processInstance.getId())
+ .uniqueResult();
+
+ Calendar jobDate = Calendar.getInstance();
+ jobDate.setTime(job.getDuedate());
+
+ assertEquals(cal.get(Calendar.DAY_OF_MONTH), jobDate.get(Calendar.DAY_OF_MONTH));
+
+ managementService.executeJob(job.getId());
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ public void testTimerELCalendar() {
+ deployJpdlXmlString(
+ "" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ ""
+ );
+
+ Map proc_vars = new HashMap();
+ Calendar cal = Calendar.getInstance();
+ cal.add(Calendar.DAY_OF_MONTH, 6);
+ proc_vars.put("proc_var", cal);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
+
+ Job job = managementService.createJobQuery()
+ .processInstanceId(processInstance.getId())
+ .uniqueResult();
+
+ Calendar jobDate = Calendar.getInstance();
+ jobDate.setTime(job.getDuedate());
+
+ assertEquals(cal.get(Calendar.DAY_OF_MONTH), jobDate.get(Calendar.DAY_OF_MONTH));
+
+ managementService.executeJob(job.getId());
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ public void testTimerELString() {
+ deployJpdlXmlString(
+ "" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ ""
+ );
+
+ Map proc_vars = new HashMap();
+ proc_vars.put("proc_var", "2 minutes");
+
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
+
+ Job job = managementService.createJobQuery()
+ .processInstanceId(processInstance.getId())
+ .uniqueResult();
+
+ Date jobDate = job.getDuedate();
+ assertTrue("should less than 2 minutes", jobDate.getTime() - new Date().getTime() < 2 * 60 * 1000);
+
+ managementService.executeJob(job.getId());
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ public void testTimerELCalendarAdd() {
+ deployJpdlXmlString(
+ "" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ ""
+ );
+
+ Map proc_vars = new HashMap();
+ Calendar cal = Calendar.getInstance();
+ cal.add(Calendar.DAY_OF_MONTH, 6);
+ proc_vars.put("proc_var", cal);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
+
+ Job job = managementService.createJobQuery()
+ .processInstanceId(processInstance.getId())
+ .uniqueResult();
+
+ Calendar jobDate = Calendar.getInstance();
+ jobDate.setTime(job.getDuedate());
+
+ cal.add(Calendar.DAY_OF_MONTH, 5);
+ assertEquals(cal.get(Calendar.DAY_OF_MONTH), jobDate.get(Calendar.DAY_OF_MONTH));
+
+ managementService.executeJob(job.getId());
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ public void testTimerELCalendarSubtract() {
+ deployJpdlXmlString(
+ "" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ ""
+ );
+
+ Map proc_vars = new HashMap();
+ Calendar cal = Calendar.getInstance();
+ cal.add(Calendar.DAY_OF_MONTH, 6);
+
+ proc_vars.put("proc_var", cal);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
+
+ Job job = managementService.createJobQuery()
+ .processInstanceId(processInstance.getId())
+ .uniqueResult();
+
+ Calendar jobDate = Calendar.getInstance();
+ jobDate.setTime(job.getDuedate());
+
+ // 6 days from now minus 5 days is tomorrow so subtract 5 from the original added 6.
+ cal.add(Calendar.DAY_OF_MONTH, -5);
+ assertEquals(cal.get(Calendar.DAY_OF_MONTH) , jobDate.get(Calendar.DAY_OF_MONTH));
+
+ managementService.executeJob(job.getId());
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ public void testTimerELCalendarAddBusiness() {
+ deployJpdlXmlString(
+ "" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ ""
+ );
+
+ Map proc_vars = new HashMap();
+ Calendar cal = Calendar.getInstance();
+ cal.set(2010, 01, 12, 12, 00, 00); // 12 feb 2010 noon
+ proc_vars.put("proc_var", cal);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
+
+ Job job = managementService.createJobQuery()
+ .processInstanceId(processInstance.getId())
+ .uniqueResult();
+
+ Calendar jobDate = Calendar.getInstance();
+ jobDate.setTime(job.getDuedate());
+
+ // 12 feb is friday, 5 businessdays further is friday 19th
+ assertEquals(19 , jobDate.get(Calendar.DAY_OF_MONTH));
+
+ managementService.executeJob(job.getId());
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ public void testTimerELFail() {
+ deployJpdlXmlString(
+ "" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ ""
+ );
+
+ Map proc_vars = new HashMap();
+ proc_vars.put("proc_var", new Long(0));
+ try {
+ executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
+ fail("Should not happen, exception expected");
+ } catch (Exception e) {}
+ }
+
+ public void testTimerELSubtractBusinessFail() {
+ deployJpdlXmlString(
+ "" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ ""
+ );
+
+ Map proc_vars = new HashMap();
+ Calendar cal = Calendar.getInstance();
+ cal.set(2010, 01, 12, 12, 00, 00); // 12 feb 2010 noon
+ proc_vars.put("proc_var", cal);
+ try {
+ executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
+ fail("Should not happen, exception expected");
+ } catch (Exception e) {}
+ }
+
+ public void testTimerELSubtractPastFail() {
+ deployJpdlXmlString(
+ "" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ ""
+ );
+
+ Map proc_vars = new HashMap();
+ Calendar cal = Calendar.getInstance();
+ cal.add(Calendar.DAY_OF_MONTH, 2);
+ proc_vars.put("proc_var", cal);
+ try {
+ executionService.startProcessInstanceByKey("ICL", proc_vars, "82436");
+ fail("Should not happen, exception expected");
+ } catch (Exception e) {}
+ }
+
+ public void testTimerTimeoutCustom() {
+ deployJpdlXmlString(TEST_PROCESS_CUSTOM);
+
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL");
+ assertEquals(Execution.STATE_INACTIVE_SCOPE, processInstance.getState());
+ assertNotActivityActive(processInstance.getId(), "a");
+
+ // execute the async state so it becomes active
+ Job async = managementService.createJobQuery().messages().processInstanceId(processInstance.getId()).uniqueResult();
+ managementService.executeJob(async.getId());
+ assertActivityActive(processInstance.getId(), "a");
+
+ try {
+ executionService.signalExecutionById(processInstance.getId());
+ fail("Should not happen, exception expected");
+ } catch (JbpmException e) {
+ // Should happen....Signalling an inactive-scope exexcution is not
+ // allowed. If the timer is removed, this test should fail since the
+ // state of the execution is async then and signalling that is allowed.
+ }
+
+ assertProcessInstanceActive(processInstance);
+ executionService.signalExecutionById(processInstance.getExecution("a").getId());
+ assertActivityActive(processInstance.getId(), "b");
+ }
+
+ public void testTimerSignalCustom() {
+ deployJpdlXmlString(TEST_PROCESS_CUSTOM);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL");
+
+ Job async = managementService.createJobQuery().messages().processInstanceId(processInstance.getId()).uniqueResult();
+ managementService.executeJob(async.getId());
+
+ int beforeTimer = MyCustomWait.nrOfTimesCalled;
+ Job timer = managementService.createJobQuery().timers().processInstanceId(processInstance.getId()).uniqueResult();
+ managementService.executeJob(timer.getId());
+ int afterTimer = MyCustomWait.nrOfTimesCalled;
+ assertEquals(beforeTimer + 1, afterTimer);
+
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ public static class MyCustomWait implements ExternalActivityBehaviour, EventListener {
+
+ private static final long serialVersionUID = 1L;
+
+ static int nrOfTimesCalled;
+
+ public void execute(ActivityExecution execution) throws Exception {
+ execution.waitForSignal();
+ }
+
+ public void signal(ActivityExecution execution, String signalName, Map parameters) throws Exception {
+ execution.take(signalName);
+ }
+
+ public void notify(EventListenerExecution execution) throws Exception {
+ nrOfTimesCalled++;
+ }
+ }
+
}
\ No newline at end of file