[jbpm-commits] JBoss JBPM SVN: r4576 - in jbpm4/trunk/modules: api/src/main/resources and 17 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Fri Apr 17 11:36:53 EDT 2009


Author: tom.baeyens at jboss.com
Date: 2009-04-17 11:36:53 -0400 (Fri, 17 Apr 2009)
New Revision: 4576

Added:
   jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/businesstime/
   jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/businesstime/TimerBusinessTimeTest.java
   jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/event/
   jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/event/Escalate.java
   jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/event/TimerEventTest.java
   jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/repeat/
   jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/repeat/Escalate.java
   jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/repeat/TimerRepeatTest.java
   jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/businesstime/
   jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/businesstime/process.jpdl.xml
   jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/event/
   jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/event/process.jpdl.xml
   jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/repeat/
   jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/repeat/process.jpdl.xml
   jbpm4/trunk/modules/userguide/src/main/docbook/en/images/process.timer.event.png
   jbpm4/trunk/modules/userguide/src/main/docbook/en/images/process.timer.transition.png
Modified:
   jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/Execution.java
   jbpm4/trunk/modules/api/src/main/resources/jpdl-4.0.xsd
   jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/java/JohnDoe.java
   jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/transition/TimerTransitionTest.java
   jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/transition/process.jpdl.xml
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JpdlBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/mgmt/JobQueryTest.java
   jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch05-Jpdl.xml
Log:
JBPM-2029 timers examples and docs

Modified: jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/Execution.java
===================================================================
--- jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/Execution.java	2009-04-17 09:23:24 UTC (rev 4575)
+++ jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/Execution.java	2009-04-17 15:36:53 UTC (rev 4576)
@@ -24,6 +24,7 @@
 import java.io.Serializable;
 import java.util.Collection;
 import java.util.Map;
+import java.util.Set;
 
 import org.jbpm.api.client.ClientExecution;
 import org.jbpm.api.client.ClientProcessDefinition;
@@ -195,5 +196,13 @@
   /** indicates if this execution has a child execution with the given executionName */
   boolean hasExecution(String executionName);
   
+  /** search for an execution that is active and in the given activityName.
+   * Returns null in case there is no such execution.
+   * @see #findActiveActivityNames() */
   Execution findActiveExecutionIn(String activityName);
+  
+  /** get the set of all activities that are active. 
+   * Returns an empty set in case there are no activities active. 
+   * @see #findActiveExecutionIn(String) */
+  Set<String> findActiveActivityNames();
 }

Modified: jbpm4/trunk/modules/api/src/main/resources/jpdl-4.0.xsd
===================================================================
--- jbpm4/trunk/modules/api/src/main/resources/jpdl-4.0.xsd	2009-04-17 09:23:24 UTC (rev 4575)
+++ jbpm4/trunk/modules/api/src/main/resources/jpdl-4.0.xsd	2009-04-17 15:36:53 UTC (rev 4576)
@@ -152,8 +152,17 @@
         <complexType>
           <sequence>
             <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
-            <element ref="tns:timer" minOccurs="0" maxOccurs="unbounded"/>
-            <element ref="tns:transition" minOccurs="0" maxOccurs="unbounded" />
+            <element name="transition" minOccurs="0" maxOccurs="unbounded">
+              <complexType>
+                <complexContent>
+                  <extension base="tns:transitionType">
+                    <sequence>
+                      <element ref="tns:timer" minOccurs="0" />
+                    </sequence>
+                  </extension>
+                </complexContent>
+              </complexType>
+            </element>
           </sequence>
           <attributeGroup ref="tns:activityAttributes" />
         </complexType>
@@ -322,7 +331,17 @@
             <element name="assignment-handler" minOccurs="0"  type="tns:wireObjectType" />
             <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
             <element ref="tns:timer" minOccurs="0" maxOccurs="unbounded"/>
-            <element ref="tns:transition" minOccurs="0" maxOccurs="unbounded" />
+            <element name="transition" minOccurs="0" maxOccurs="unbounded">
+              <complexType>
+                <complexContent>
+                  <extension base="tns:transitionType">
+                    <sequence>
+                      <element ref="tns:timer" minOccurs="0" />
+                    </sequence>
+                  </extension>
+                </complexContent>
+              </complexType>
+            </element>
           </sequence>
           <attributeGroup ref="tns:activityAttributes" />
           <attributeGroup ref="tns:assignmentAttributes"/>
@@ -611,6 +630,7 @@
   <element name="on">
     <complexType>
       <sequence>
+        <element ref="tns:timer" minOccurs="0" />
         <group ref="tns:eventListenerGroup" minOccurs="0" maxOccurs="unbounded">
           <annotation><documentation>A list of event listeners that will 
           be notified when the event is fired</documentation></annotation>
@@ -632,15 +652,6 @@
           be notified when the timer fires</documentation></annotation>
         </group>
       </sequence>
-      <attribute name="event" type="string">
-        <annotation><documentation>The event identification for this timer event.
-        </documentation></annotation>
-      </attribute>
-      <attribute name="transition" type="string">
-        <annotation><documentation>The name of the outgoing transition that must be 
-        taken when this timer fires.
-        </documentation></annotation>
-      </attribute>
       <attribute name="duedate" type="string">
         <annotation><documentation>Timer duedate expression that defines the duedate of this 
         timer relative to the creation time of the timer.  E.g. '2 hours' or '4 business days'

Modified: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/java/JohnDoe.java
===================================================================
--- jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/java/JohnDoe.java	2009-04-17 09:23:24 UTC (rev 4575)
+++ jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/java/JohnDoe.java	2009-04-17 15:36:53 UTC (rev 4576)
@@ -21,9 +21,6 @@
  */
 package org.jbpm.examples.java;
 
-import org.hibernate.Session;
-
-
 /**
  * @author Tom Baeyens
  */

Added: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/businesstime/TimerBusinessTimeTest.java
===================================================================
--- jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/businesstime/TimerBusinessTimeTest.java	                        (rev 0)
+++ jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/businesstime/TimerBusinessTimeTest.java	2009-04-17 15:36:53 UTC (rev 4576)
@@ -0,0 +1,55 @@
+/*
+ * 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.examples.timer.businesstime;
+
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.api.job.Job;
+import org.jbpm.test.JbpmTestCase;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class TimerBusinessTimeTest extends JbpmTestCase {
+  
+  static long HOUR_IN_MILLIS = 60*60*100;
+
+  public void testBusinessTime() {
+    deployJpdlResource("org/jbpm/examples/timer/businesstime/process.jpdl.xml");
+    
+    long now = System.currentTimeMillis();
+
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("TimerBusinessTime");
+
+    Job job = managementService.createJobQuery()
+      .processInstanceId(processInstance.getId())
+      .uniqueResult();
+
+    long difference = job.getDueDate().getTime() - now;
+
+    // we do not know when this test will be run.  So the exact actual duedate of the timer
+    // can not be calculated easily.  But we do know for sure that each working day only 
+    // has 8 business hours.  So we know that 9 business hours later always means at 
+    // least 24 hours later
+    assertTrue( 24 * HOUR_IN_MILLIS < difference );
+  }
+}


Property changes on: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/businesstime/TimerBusinessTimeTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/event/Escalate.java
===================================================================
--- jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/event/Escalate.java	                        (rev 0)
+++ jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/event/Escalate.java	2009-04-17 15:36:53 UTC (rev 4576)
@@ -0,0 +1,37 @@
+/*
+ * 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.examples.timer.event;
+
+import org.jbpm.api.listener.EventListener;
+import org.jbpm.api.listener.EventListenerExecution;
+
+/**
+ * @author Tom Baeyens
+ */
+public class Escalate implements EventListener {
+
+  private static final long serialVersionUID = 1L;
+
+  public void notify(EventListenerExecution execution) {
+    execution.setVariable("escalation", Boolean.TRUE);
+  }
+}


Property changes on: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/event/Escalate.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/event/TimerEventTest.java
===================================================================
--- jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/event/TimerEventTest.java	                        (rev 0)
+++ jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/event/TimerEventTest.java	2009-04-17 15:36:53 UTC (rev 4576)
@@ -0,0 +1,78 @@
+/*
+ * 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.examples.timer.event;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.api.job.Job;
+import org.jbpm.test.JbpmTestCase;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class TimerEventTest extends JbpmTestCase {
+
+  public void testTimerEventTimerFires() {
+    deployJpdlResource("org/jbpm/examples/timer/event/process.jpdl.xml");
+    
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("TimerEvent");
+
+    Job job = managementService.createJobQuery()
+      .processInstanceId(processInstance.getId())
+      .uniqueResult();
+    
+    managementService.executeJob(job.getDbid());
+
+    processInstance = executionService.findProcessInstanceById(processInstance.getId());
+
+    Set<String> expectedActivityNames = new HashSet<String>();
+    expectedActivityNames.add("guardedWait");
+    assertEquals(expectedActivityNames, processInstance.findActiveActivityNames());
+
+    assertEquals(Boolean.TRUE, executionService.getVariable(processInstance.getId(), "escalation"));
+  }
+
+  public void testTimerEventContinueBeforeTimerFires() {
+    deployJpdlResource("org/jbpm/examples/timer/event/process.jpdl.xml");
+    
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("TimerEvent");
+    
+    String executionId = processInstance.findActiveExecutionIn("guardedWait").getId();
+
+    executionService.signalExecutionById(executionId, "go on");
+    
+    processInstance = executionService.findProcessInstanceById(processInstance.getId());
+    
+    assertEquals("next step", processInstance.getActivityName());
+
+    List<Job> jobs = managementService.createJobQuery()
+      .processInstanceId(processInstance.getId())
+      .list();
+    
+    assertEquals(new ArrayList<Job>(), new ArrayList<Job>(jobs));
+  }
+}


Property changes on: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/event/TimerEventTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/repeat/Escalate.java
===================================================================
--- jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/repeat/Escalate.java	                        (rev 0)
+++ jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/repeat/Escalate.java	2009-04-17 15:36:53 UTC (rev 4576)
@@ -0,0 +1,42 @@
+/*
+ * 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.examples.timer.repeat;
+
+import org.jbpm.api.listener.EventListener;
+import org.jbpm.api.listener.EventListenerExecution;
+
+/**
+ * @author Tom Baeyens
+ */
+public class Escalate implements EventListener {
+
+  private static final long serialVersionUID = 1L;
+
+  public void notify(EventListenerExecution execution) {
+    Integer escalations = (Integer) execution.getVariable("escalations");
+    if (escalations==null) {
+      execution.setVariable("escalations", 1);
+    } else {
+      execution.setVariable("escalations", escalations+1);
+    }
+  }
+}


Property changes on: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/repeat/Escalate.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/repeat/TimerRepeatTest.java
===================================================================
--- jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/repeat/TimerRepeatTest.java	                        (rev 0)
+++ jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/repeat/TimerRepeatTest.java	2009-04-17 15:36:53 UTC (rev 4576)
@@ -0,0 +1,75 @@
+/*
+ * 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.examples.timer.repeat;
+
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.api.job.Job;
+import org.jbpm.test.JbpmTestCase;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class TimerRepeatTest extends JbpmTestCase {
+  
+  public void testTimerRepeat() {
+    deployJpdlResource("org/jbpm/examples/timer/repeat/process.jpdl.xml");
+    
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("TimerRepeat");
+
+    Job job = managementService.createJobQuery()
+      .processInstanceId(processInstance.getId())
+      .uniqueResult();
+    
+    assertNull(executionService.getVariable(processInstance.getId(), "escalations"));
+
+    managementService.executeJob(job.getDbid());
+
+    assertEquals(1, executionService.getVariable(processInstance.getId(), "escalations"));
+
+    job = managementService.createJobQuery()
+      .processInstanceId(processInstance.getId())
+      .uniqueResult();
+    
+    assertNotNull(job);
+
+    managementService.executeJob(job.getDbid());
+
+    assertEquals(2, executionService.getVariable(processInstance.getId(), "escalations"));
+
+    job = managementService.createJobQuery()
+      .processInstanceId(processInstance.getId())
+      .uniqueResult();
+    
+    assertNotNull(job);
+
+    processInstance = executionService.findProcessInstanceById(processInstance.getId());
+    String processInstanceId = processInstance.findActiveExecutionIn("guardedWait").getId();
+    executionService.signalExecutionById(processInstanceId, "go on");
+
+    job = managementService.createJobQuery()
+      .processInstanceId(processInstance.getId())
+      .uniqueResult();
+    
+    assertNull(job);
+  }
+}


Property changes on: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/repeat/TimerRepeatTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/transition/TimerTransitionTest.java
===================================================================
--- jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/transition/TimerTransitionTest.java	2009-04-17 09:23:24 UTC (rev 4575)
+++ jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/timer/transition/TimerTransitionTest.java	2009-04-17 15:36:53 UTC (rev 4576)
@@ -1,3 +1,24 @@
+/*
+ * 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.examples.timer.transition;
 
 import java.util.ArrayList;
@@ -7,7 +28,9 @@
 import org.jbpm.api.job.Job;
 import org.jbpm.test.JbpmTestCase;
 
-
+/**
+ * @author Tom Baeyens
+ */
 public class TimerTransitionTest extends JbpmTestCase {
   
   public void testTimerTransitionTimerFires() {
@@ -16,6 +39,7 @@
     Execution processInstance = executionService.startProcessInstanceByKey("TimerTransition");
     
     Job job = managementService.createJobQuery()
+      .timers()
       .processInstanceId(processInstance.getId())
       .uniqueResult();
     
@@ -26,7 +50,7 @@
     assertEquals("escalation", processInstance.getActivityName());
   }
 
-  public void testTimerTransitionTakeTransition() {
+  public void testTimerTransitionContinueBeforeTimerFires() {
     deployJpdlResource("org/jbpm/examples/timer/transition/process.jpdl.xml");
     
     Execution processInstance = executionService.startProcessInstanceByKey("TimerTransition");

Added: jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/businesstime/process.jpdl.xml
===================================================================
--- jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/businesstime/process.jpdl.xml	                        (rev 0)
+++ jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/businesstime/process.jpdl.xml	2009-04-17 15:36:53 UTC (rev 4576)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<process name="TimerBusinessTime" xmlns="http://jbpm.org/4/jpdl">
+
+  <start g="19,50,48,48">
+    <transition to="guardedWait" />
+  </start>
+
+  <state name="guardedWait" g="98,46,127,52">
+    <transition name="go on" to="next step" g="-16,-17" />
+    <transition name="timeout" to="escalation" g="-43,-16">
+      <timer duedate="9 business hours" /> 
+    </transition>
+  </state>
+  
+  <state name="next step" g="283,46,83,53" />
+  <state name="escalation" g="118,140,88,52" />
+
+</process>


Property changes on: jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/businesstime/process.jpdl.xml
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/event/process.jpdl.xml
===================================================================
--- jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/event/process.jpdl.xml	                        (rev 0)
+++ jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/event/process.jpdl.xml	2009-04-17 15:36:53 UTC (rev 4576)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<process name="TimerEvent" xmlns="http://jbpm.org/4/jpdl">
+
+  <start g="19,50,48,48">
+    <transition to="guardedWait" />
+  </start>
+
+  <state name="guardedWait" g="98,46,127,52">
+    <on event="timeout">
+      <timer duedate="10 minutes"/>
+      <event-listener class="org.jbpm.examples.timer.event.Escalate" />
+    </on>
+    <transition name="go on" to="next step"  g="-16,-17" />
+  </state>
+  
+  <state name="next step" g="283,46,83,53" />
+
+</process>


Property changes on: jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/event/process.jpdl.xml
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/repeat/process.jpdl.xml
===================================================================
--- jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/repeat/process.jpdl.xml	                        (rev 0)
+++ jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/repeat/process.jpdl.xml	2009-04-17 15:36:53 UTC (rev 4576)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<process name="TimerRepeat" xmlns="http://jbpm.org/4/jpdl">
+
+  <start g="19,50,48,48">
+    <transition to="guardedWait" />
+  </start>
+
+  <state name="guardedWait" g="98,46,127,52">
+    <on event="timeout">
+      <timer duedate="20 minutes" repeat="10 seconds" />
+      <event-listener class="org.jbpm.examples.timer.repeat.Escalate" />
+    </on>
+    <transition name="go on" to="next step" g="-16,-17"/>
+  </state>
+  
+  <state name="next step" g="283,46,83,53"/>
+
+</process>


Property changes on: jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/repeat/process.jpdl.xml
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/transition/process.jpdl.xml
===================================================================
--- jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/transition/process.jpdl.xml	2009-04-17 09:23:24 UTC (rev 4575)
+++ jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/timer/transition/process.jpdl.xml	2009-04-17 15:36:53 UTC (rev 4576)
@@ -1,18 +1,19 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
-<process name="TimerTransition" xmlns="http://jbpm.org/4/jpdl">
-
-  <start g="20,20,48,48">
-    <transition to="guardedWait" />
-  </start>
-
-  <state name="guardedWait" g="96,16,127,52">
-    <timer duedate="10 minutes" transition="timout" />
-    <transition name="go on" to="next step" />
-    <transition name="timout" to="escalation" />
-  </state>
-  
-  <state name="next step" />
-  <state name="escalation" g="255,16,88,52"/>
-
-</process>
+<process name="TimerTransition" xmlns="http://jbpm.org/4/jpdl">
+
+  <start g="19,50,48,48">
+    <transition to="guardedWait" />
+  </start>
+
+  <state name="guardedWait" g="98,46,127,52">
+    <transition name="go on" to="next step" g="-16,-17"/>
+    <transition name="timeout" to="escalation" g="-43,-16">
+      <timer duedate="10 minutes" /> 
+    </transition>
+  </state>
+  
+  <state name="next step" g="283,46,83,53"/>
+  <state name="escalation" g="118,140,88,52" />
+
+</process>
\ No newline at end of file

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JpdlBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JpdlBinding.java	2009-04-17 09:23:24 UTC (rev 4575)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JpdlBinding.java	2009-04-17 15:36:53 UTC (rev 4576)
@@ -27,6 +27,7 @@
 import org.jbpm.jpdl.internal.xml.JpdlParser;
 import org.jbpm.jpdl.internal.xml.UnresolvedTransitions;
 import org.jbpm.pvm.internal.model.ActivityImpl;
+import org.jbpm.pvm.internal.model.TimerDefinitionImpl;
 import org.jbpm.pvm.internal.model.TransitionImpl;
 import org.jbpm.pvm.internal.util.TagBinding;
 import org.jbpm.pvm.internal.util.XmlUtil;
@@ -69,10 +70,21 @@
     UnresolvedTransitions unresolvedTransitions = parse.findObject(UnresolvedTransitions.class);
     for (Element transitionElement: transitionElements) {
       String transitionName = XmlUtil.attribute(transitionElement, "name", false, parse);
+
+      Element timerElement = XmlUtil.element(transitionElement, "timer");
+      if (timerElement!=null) {
+        if (transitionName!=null) {
+          TimerDefinitionImpl timerDefinitionImpl = jpdlParser.parseTimerDefinition(timerElement, parse, activity);
+          timerDefinitionImpl.setSignalName(transitionName);
+        } else {
+          parse.addProblem("a transition name is required when a timer is placed on a transition");
+        }
+      }
+
       TransitionImpl transition = activity.createOutgoingTransition(transitionName);
       unresolvedTransitions.add(transition, transitionElement);
       
-      jpdlParser.parseEventListeners(transitionElement, transition, Event.TAKE, parse);
+      jpdlParser.parseOnEvent(transitionElement, transition, Event.TAKE, parse);
     }
   }
 }

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java	2009-04-17 09:23:24 UTC (rev 4575)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java	2009-04-17 15:36:53 UTC (rev 4576)
@@ -186,9 +186,6 @@
       // on events
       parseOnEvents(documentElement, parse, processDefinition);
       
-      // timers
-      parseTimers(documentElement, parse, processDefinition);
-
       // activities
       parseActivities(documentElement, parse, processDefinition);
 
@@ -236,7 +233,6 @@
             activity.setBehaviour(activityBehaviour);
             
             parseOnEvents(element, parse, activity);
-            parseTimers(element, parse, activity);
             
           } finally {
             parse.popObject();
@@ -248,23 +244,9 @@
     }
   }
 
-  public void parseTimers(Element element, Parse parse, ScopeElementImpl scopeElement) {
-    List<Element> timerElements = XmlUtil.elements(element, "timer");
-    for (Element timerElement: timerElements) {
-      parseTimerDefinition(timerElement, parse, scopeElement);
-    }
-  }
-
-  private void parseTimerDefinition(Element timerElement, Parse parse, ScopeElementImpl scopeElement) {
+  public TimerDefinitionImpl parseTimerDefinition(Element timerElement, Parse parse, ScopeElementImpl scopeElement) {
     TimerDefinitionImpl timerDefinition = scopeElement.createTimerDefinition();
 
-    String eventName = XmlUtil.attribute(timerElement, "event");
-    timerDefinition.setEventName(eventName);
-    parseEventListeners(timerElement, scopeElement, eventName, parse);
-
-    String transition = XmlUtil.attribute(timerElement, "transition");
-    timerDefinition.setSignalName(transition);
-
     String duedate = XmlUtil.attribute(timerElement, "duedate");
     String duedatetime = XmlUtil.attribute(timerElement, "duedatetime");
 
@@ -289,22 +271,30 @@
     
     String repeat = XmlUtil.attribute(timerElement, "repeat");
     timerDefinition.setRepeat(repeat);
+    
+    return timerDefinition;
   }
 
-  public void parseOnEvents(Element element, Parse parse, ObservableElementImpl observableElement) {
+  public void parseOnEvents(Element element, Parse parse, ScopeElementImpl scopeElement) {
     // event listeners
     List<Element> onElements = XmlUtil.elements(element, "on");
     for (Element onElement: onElements) {
       String eventName = XmlUtil.attribute(onElement, "event", true, parse);
-      parseEventListeners(onElement, observableElement, eventName, parse);
+      parseOnEvent(onElement, scopeElement, eventName, parse);
+      
+      Element timerElement = XmlUtil.element(onElement, "timer");
+      if (timerElement!=null) {
+        TimerDefinitionImpl timerDefinitionImpl = parseTimerDefinition(timerElement, parse, scopeElement);
+        timerDefinitionImpl.setEventName(eventName);
+      }
     }
   }
 
-  public void parseEventListeners(Element element, ObservableElementImpl observableElement, String eventName, Parse parse) {
+  public void parseOnEvent(Element element, ObservableElementImpl scopeElement, String eventName, Parse parse) {
     if (eventName!=null) {
-      EventImpl event = observableElement.getEvent(eventName);
+      EventImpl event = scopeElement.getEvent(eventName);
       if (event==null) {
-        event = observableElement.createEvent(eventName);
+        event = scopeElement.createEvent(eventName);
       }
       
       for (Element eventListenerElement: XmlUtil.elements(element)) {

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java	2009-04-17 09:23:24 UTC (rev 4575)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java	2009-04-17 15:36:53 UTC (rev 4576)
@@ -27,6 +27,7 @@
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
@@ -862,6 +863,26 @@
            );
   }
 
+  public Set<String> findActiveActivityNames() {
+    return addActiveActivityNames(new HashSet<String>());
+  }
+
+  protected Set<String> addActiveActivityNames(Set<String> activityNames) {
+    if ( (state.equals(STATE_ACTIVE))
+         && (activityName!=null)
+       ) {
+      activityNames.add(activityName);
+    }
+  
+    if (executions!=null) {
+      for (ExecutionImpl childExecution: executions) {
+        childExecution.addActiveActivityNames(activityNames);
+      }
+    }
+  
+    return activityNames;
+  }
+
   public ExecutionImpl findActiveExecutionIn(String activityName) {
     if ( activityName.equals(this.activityName)
          && state.equals(STATE_ACTIVE)) {

Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/mgmt/JobQueryTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/mgmt/JobQueryTest.java	2009-04-17 09:23:24 UTC (rev 4575)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/mgmt/JobQueryTest.java	2009-04-17 15:36:53 UTC (rev 4576)
@@ -15,8 +15,9 @@
       "    <transition to='t' />" +
       "  </start>" +
       "  <state name='t'>" +
-      "    <timer duedate='20 seconds' transition='timeout' />" +
-      "    <transition name='timeout' to='t' />" +
+      "    <transition name='timeout' to='t'>" +
+      "      <timer duedate='20 seconds' />" +
+      "    </transition>" +
       "  </state>" +
       "</process>"
     );

Added: jbpm4/trunk/modules/userguide/src/main/docbook/en/images/process.timer.event.png
===================================================================
(Binary files differ)


Property changes on: jbpm4/trunk/modules/userguide/src/main/docbook/en/images/process.timer.event.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: jbpm4/trunk/modules/userguide/src/main/docbook/en/images/process.timer.transition.png
===================================================================
(Binary files differ)


Property changes on: jbpm4/trunk/modules/userguide/src/main/docbook/en/images/process.timer.transition.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch05-Jpdl.xml
===================================================================
--- jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch05-Jpdl.xml	2009-04-17 09:23:24 UTC (rev 4575)
+++ jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch05-Jpdl.xml	2009-04-17 15:36:53 UTC (rev 4576)
@@ -1840,12 +1840,268 @@
 
   <section id="timer">
     <title><literal>timer</literal> </title>
-    <para>A timer can be specified in <literal>state</literal>s, 
-    <literal>task</literal>s  and <literal>super-state</literal>s.
-    Timers are created when the activity is entered and cancelled 
-    then the activity is left.  When the duedate arrives before the 
-    activity ends, then the 
+    <para>A timer can be specified in the <literal>transition</literal>
+    element in wait state activities such as <literal>state</literal>s, 
+    <literal>task</literal>s, <literal>sub-process</literal>es and 
+    <literal>super-state</literal>s.  
+    When such a timer fires, that transition is taken.
     </para>
+    <para>A timer can also be specified in custom events in wait state 
+    activities such as <literal>state</literal>s, 
+    <literal>task</literal>s, <literal>sub-process</literal>es and 
+    <literal>super-state</literal>s.  The <literal>timer</literal> element 
+    should then be the first element in the <literal>on</literal> element representing 
+    the event. In that case the event fires upon the duedate of the timer.   
+    </para>
+    <para>Timers are created when the activity is entered.  The timer can fire 
+    when the execution remains in the activity until the <literal>duedate</literal>.
+    When the execution leaves the activity, the timer is cancelled. 
+    </para>
+    <table><title><literal>timer</literal> attributes:</title>
+      <tgroup cols="5" rowsep="1" colsep="1">
+        <thead>
+          <row>
+            <entry>Attribute</entry>
+            <entry>Type</entry>
+            <entry>Default</entry>
+            <entry>Required?</entry>
+            <entry>Description</entry>
+          </row>
+        </thead>
+        <tbody>
+          <row>
+            <entry><literal>duedate</literal></entry>
+            <entry><link linkend="duedateexpressions">duedate expression</link></entry>
+            <entry></entry>
+            <entry><emphasis role="bold">required</emphasis></entry>
+            <entry>Specifies when the timer needs to fire.  For 
+            example: <literal>20 minutes</literal> or
+            <literal>3 business days</literal> 
+            </entry>
+          </row>
+          <row>
+            <entry><literal>repeat</literal></entry>
+            <entry><link linkend="duedateexpressions">duedate expression</link></entry>
+            <entry></entry>
+            <entry>optional</entry>
+            <entry>When a timer fires, this attribute specifies when the timer 
+            needs to fire again.   For example: <literal>20 minutes</literal> or
+            <literal>3 business days</literal> 
+            </entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </table>
+
+    <section id="duedateexpressions">
+      <title>Duedate expressions</title>
+      <para>A duedate expression has the following syntax:</para>
+      <programlisting>quantity [business] {second | seconds | minute | minutes | 
+                     hour | hours | day | days | week | 
+                     weeks | month | months | year | years}</programlisting>
+      <para>where <literal>quantity</literal> is a positive integer.
+      </para>
+      <para>And adding the optional indication <literal>business</literal> means 
+      that only business hours should be taken into account for this duration. Without 
+      the indication business, the duration will be interpreted as an absolute time period.
+      How to configure business hours is explained in <xref linkend="businesscalendar"/>
+      </para>
+    </section>
+
+    <section id="businesscalendar">
+      <title>Business calendar</title>
+      <para>The default configuration will contain a reference to the file
+        <literal>jbpm.business.calendar.xml</literal>.  That contains a 
+        configuration of business hours in the following format: 
+      </para>
+      <programlisting>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+
+&lt;jbpm-configuration xmlns=&quot;http://jbpm.org/xsd/cfg&quot;&gt;
+
+  &lt;process-engine-context&gt;
+      
+      &lt;business-calendar&gt;
+			  &lt;monday    hours=&quot;9:00-12:00 and 12:30-17:00&quot;/&gt;
+			  &lt;tuesday   hours=&quot;9:00-12:00 and 12:30-17:00&quot;/&gt;
+			  &lt;wednesday hours=&quot;9:00-12:00 and 12:30-17:00&quot;/&gt;
+			  &lt;thursday  hours=&quot;9:00-12:00 and 12:30-17:00&quot;/&gt;
+			  &lt;friday    hours=&quot;9:00-12:00 and 12:30-17:00&quot;/&gt;
+			  &lt;holiday period=&quot;01/07/2008 - 31/08/2008&quot;/&gt;
+			&lt;/business-calendar&gt;
+
+  &lt;/process-engine-context&gt;
+
+&lt;/jbpm-configuration&gt;</programlisting>
+      <para>For an example of where the business calendar is used, see
+      <xref linkedn="timerbusinesstime" /> 
+      </para>
+    </section>
+
+    <section id="timertransition">
+      <title>Timer transition</title>
+      <para>Example TimerTransitionTest shows how to put a timer on a transition.</para>
+	    <figure id="process.timer.transition">
+	      <title>The timer transition example process</title>
+	      <mediaobject><imageobject><imagedata align="center" fileref="images/process.timer.transition.png"/></imageobject></mediaobject>
+	    </figure>
+      <programlisting>&lt;process name=&quot;TimerTransition&quot; xmlns=&quot;http://jbpm.org/4/jpdl&quot;&gt;
+
+  &lt;start&gt;
+    &lt;transition to=&quot;guardedWait&quot; /&gt;
+  &lt;/start&gt;
+
+  &lt;state name=&quot;guardedWait&quot;&gt;
+    &lt;transition name=&quot;go on&quot; to=&quot;next step&quot; /&gt;
+    &lt;transition name=&quot;timeout&quot; to=&quot;escalation&quot;&gt;
+      <emphasis role="bold">&lt;timer duedate=&quot;10 minutes&quot; /&gt;</emphasis>
+    &lt;/transition&gt;
+  &lt;/state&gt;
+  
+  &lt;state name=&quot;next step&quot; /&gt;
+  &lt;state name=&quot;escalation&quot; /&gt;
+
+&lt;/process&gt;</programlisting>
+      <para>When an process instance for this process is started, it arrives immediately 
+      in the <literal>guardedWait</literal> state.  At that time, a timer is created that will fire 
+      after 10 minutes.  
+      </para>
+      <programlisting>Execution processInstance = executionService
+      .startProcessInstanceByKey(&quot;TimerTransition&quot;);</programlisting>
+      <para>With the following query, we can query for the timers related to the newly created 
+      processInstance.  We know that there should be exactly one such timer.
+      </para>
+      <programlisting>Job job = managementService.createJobQuery()
+      .timers()
+      .processInstanceId(processInstance.getId())
+      .uniqueResult();
+      </programlisting>
+      <para>In a unit test, we won't use the JobExecutor to execute the timer.  Instead,
+      we execute timers directly in the thread of the unit test.  That way it is easy to 
+      simulate one scenario though an execution.
+      </para>
+      <para>So as the next step, we assume that the timer will fire.  We simulate this 
+      by executing the timer programmatically:
+      </para>
+      <programlisting>managementService.executeJob(job.getDbid());</programlisting>
+      <para>After that the process instance will have taken the 
+      <literal>timeout</literal> transition and moved to the escalation state.  
+      </para>
+      <programlisting>processInstance = executionService.findExecutionById(processInstance.getId());
+assertEquals(&quot;escalation&quot;, processInstance.getActivityName());</programlisting>
+      <para>The second scenario in TimerTransitionTest shows that the 
+      timer is cancelled in case the signal <literal>go on</literal> is given 
+      before the timer fires.  In that case the execution ends up in the 
+      <literal>next step</literal>.  
+      </para>
+    </section>
+
+    <section id="timerevent">
+      <title>Timer event</title>
+      <para>Example TimerEventTest shows how to put a timer on a custom event.</para>
+      <figure id="process.timer.event">
+        <title>The timer event example process</title>
+        <mediaobject><imageobject><imagedata align="center" fileref="images/process.timer.event.png"/></imageobject></mediaobject>
+      </figure>
+      <programlisting>&lt;process name=&quot;TimerEvent&quot; xmlns=&quot;http://jbpm.org/4/jpdl&quot;&gt;
+
+  &lt;start&gt;
+    &lt;transition to=&quot;guardedWait&quot; /&gt;
+  &lt;/start&gt;
+
+  &lt;state name=&quot;guardedWait&quot; &gt;
+    <emphasis role="bold">&lt;on event=&quot;timeout&quot;&gt;
+      &lt;timer duedate=&quot;10 minutes&quot;/&gt;
+      &lt;event-listener class=&quot;org.jbpm.examples.timer.event.Escalate&quot; /&gt;
+    &lt;/on&gt;</emphasis>
+    &lt;transition name=&quot;go on&quot; to=&quot;next step&quot; /&gt;
+  &lt;/state&gt;
+  
+  &lt;state name=&quot;next step&quot; /&gt;
+
+&lt;/process&gt;</programlisting>
+      <para>In this case, if the execution is not signalled within 10 minutes after the 
+      activity is started, the event <literal>timeout</literal> is fired 
+      and the event listener <literal>org.jbpm.examples.timer.event.Escalate</literal>
+      will be notified.
+      </para>
+      <para>Again, if the <literal>guardedWait</literal> activity is ended within 
+      10 minutes, then the timer is cancelled and the <literal>Escalate</literal> 
+      event listener will not be notified.
+      </para>
+    </section>
+
+    <section id="timerbusinesstime">
+      <title>Timer business time</title>
+      <para>Example TimerBusinessTimeTest shows how business time works.</para>
+      <figure id="process.timer.event">
+        <title>The timer businesstime example process</title>
+        <mediaobject><imageobject><imagedata align="center" fileref="images/process.timer.transition.png"/></imageobject></mediaobject>
+      </figure>
+      <programlisting>&lt;process name=&quot;TimerBusinessTime&quot; xmlns=&quot;http://jbpm.org/4/jpdl&quot;&gt;
+
+  &lt;start&gt;
+    &lt;transition to=&quot;guardedWait&quot; /&gt;
+  &lt;/start&gt;
+
+  &lt;state name=&quot;guardedWait&quot; &gt;
+    &lt;transition name=&quot;go on&quot; to=&quot;next step&quot; /&gt;
+    &lt;transition name=&quot;timeout&quot; to=&quot;escalation&quot; &gt;
+      &lt;timer <emphasis role="bold">duedate=&quot;9 business hours&quot;</emphasis> /&gt; 
+    &lt;/transition&gt;
+  &lt;/state&gt;
+  
+  &lt;state name=&quot;next step&quot; /&gt;
+  &lt;state name=&quot;escalation&quot; /&gt;
+
+&lt;/process&gt;</programlisting>
+      <para>Suppose that a new <literal>TimerBusinessTime</literal> process instance is started
+      at 11:30am on a tuesday.  The default configured business calendar specifies working hours 
+      between 9:00-12:00 and 12:30-17:00.  So 9 business hours later results in an actual duedate 
+      for the timer of wednesday 13:00 (1pm).
+      </para>
+      <para>Since we do not know when the TimerBusinessTimeTest will be ran, we only assert 
+      in the test that the actual duedate of the scheduled timer at least 24 hours ahead.
+      </para>
+    </section>
+
+    <section id="timerrepeat">
+      <title>Timer repeat</title>
+      <para>Example TimerRepeatTest shows how to put a timer with a repeat. The attribute 
+      <literal>repeat</literal> on a timer will cause the timer to be rescheduled automatically
+      after it is executed.
+      </para>
+      <figure id="process.timer.repeat">
+        <title>The timer repeat example process</title>
+        <mediaobject><imageobject><imagedata align="center" fileref="images/process.timer.event.png"/></imageobject></mediaobject>
+      </figure>
+      <programlisting>&lt;process name=&quot;TimerRepeat&quot; xmlns=&quot;http://jbpm.org/4/jpdl&quot;&gt;
+
+  &lt;start&gt;
+    &lt;transition to=&quot;guardedWait&quot; /&gt;
+  &lt;/start&gt;
+
+  &lt;state name=&quot;guardedWait&quot;&gt;
+    &lt;on event=&quot;timeout&quot;&gt;
+      &lt;timer duedate=&quot;20 minutes&quot; <emphasis role="bold">repeat=&quot;10 seconds&quot;</emphasis> /&gt;
+      &lt;event-listener class=&quot;org.jbpm.examples.timer.repeat.Escalate&quot; /&gt;
+    &lt;/on&gt;
+    &lt;transition name=&quot;go on&quot; to=&quot;next step&quot;/&gt;
+  &lt;/state&gt;
+  
+  &lt;state name=&quot;next step&quot;/&gt;
+
+&lt;/process&gt;</programlisting>
+      <para>When a new process is started, a timer is created and the duedate 
+      will be 20 minutes ahead.  When the timer fires, a new timer will be created 
+      with a duedate of 10 seconds ahead.  When that timer fires, a new timer will
+      be created again 10 seconds ahead. And so on.
+      </para>
+      <para>New timers will be created each time the timer fires until the 
+      <literal>guardedWait</literal> state activity is ended with a signal.
+      When the <literal>guardedWait</literal> state activity is ended, the 
+      existing timer will be cancelled.  
+      </para>
+    </section>
   </section>
 
   <section id="usercode">




More information about the jbpm-commits mailing list