[jbpm-commits] JBoss JBPM SVN: r4502 - in jbpm4/branches/tbaeyens/modules: jpdl/src/main/java/org/jbpm/jpdl/internal/activity and 2 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Wed Apr 8 14:52:42 EDT 2009


Author: tom.baeyens at jboss.com
Date: 2009-04-08 14:52:42 -0400 (Wed, 08 Apr 2009)
New Revision: 4502

Modified:
   jbpm4/branches/tbaeyens/modules/api/src/main/resources/jpdl.xsd
   jbpm4/branches/tbaeyens/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JpdlBinding.java
   jbpm4/branches/tbaeyens/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java
   jbpm4/branches/tbaeyens/modules/test-db/src/test/java/org/jbpm/test/eventlistener/EventListenerTest.java
Log:
event listeners testing and task schema updates

Modified: jbpm4/branches/tbaeyens/modules/api/src/main/resources/jpdl.xsd
===================================================================
--- jbpm4/branches/tbaeyens/modules/api/src/main/resources/jpdl.xsd	2009-04-08 14:06:45 UTC (rev 4501)
+++ jbpm4/branches/tbaeyens/modules/api/src/main/resources/jpdl.xsd	2009-04-08 18:52:42 UTC (rev 4502)
@@ -42,6 +42,7 @@
     <complexType>
       <sequence minOccurs="0" maxOccurs="unbounded">
         <element ref="tns:swimlane" minOccurs="0" maxOccurs="unbounded"/>
+        <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
         <group ref="tns:activityGroup" minOccurs="0" maxOccurs="unbounded" />
       </sequence>
       <attribute name="name" use="required" type="string">
@@ -85,6 +86,7 @@
         </documentation></annotation>
         <complexType>
           <sequence>
+            <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
             <element ref="tns:transition" minOccurs="0" maxOccurs="unbounded" />
           </sequence>
           <attributeGroup ref="tns:activityAttributes" />
@@ -97,6 +99,7 @@
         </documentation></annotation>
         <complexType>
           <sequence>
+            <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
           </sequence>
           <attributeGroup ref="tns:activityAttributes" />
           <attribute name="ends" default="process-instance">
@@ -118,6 +121,7 @@
         </documentation></annotation>
         <complexType>
           <sequence>
+            <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
           </sequence>
           <attributeGroup ref="tns:activityAttributes" />
           <attribute name="ends" default="process-instance">
@@ -136,6 +140,7 @@
         </documentation></annotation>
         <complexType>
           <sequence>
+            <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
           </sequence>
           <attributeGroup ref="tns:activityAttributes" />
           <attribute name="ends" default="process-instance">
@@ -157,6 +162,7 @@
         </documentation></annotation>
         <complexType>
           <sequence>
+            <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
             <element ref="tns:transition" minOccurs="0" maxOccurs="unbounded" />
           </sequence>
           <attributeGroup ref="tns:activityAttributes" />
@@ -171,6 +177,7 @@
         <complexType>
           <sequence>
             <element name="handler" minOccurs="0" type="tns:wireObjectType" />
+            <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
             <element name="transition" minOccurs="0" maxOccurs="unbounded">
               <complexType>
                 <complexContent>
@@ -214,6 +221,7 @@
         </documentation></annotation>
         <complexType>
           <sequence>
+            <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
             <element ref="tns:transition" minOccurs="0" maxOccurs="unbounded" />
           </sequence>
           <attributeGroup ref="tns:activityAttributes" />
@@ -226,6 +234,7 @@
         </documentation></annotation>
         <complexType>
           <sequence>
+            <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
             <element ref="tns:transition" minOccurs="0" maxOccurs="unbounded" />
           </sequence>
           <attributeGroup ref="tns:activityAttributes" />
@@ -239,6 +248,7 @@
           <complexContent>
             <extension base="tns:scriptType">
               <sequence>
+                <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
                 <element ref="tns:transition" minOccurs="0" maxOccurs="unbounded" />
               </sequence>
               <attributeGroup ref="tns:activityAttributes" />
@@ -254,6 +264,7 @@
           <complexContent>
             <extension base="tns:qlType">
               <sequence>
+                <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
                 <element ref="tns:transition" minOccurs="0" maxOccurs="unbounded" />
               </sequence>
               <attributeGroup ref="tns:activityAttributes" />
@@ -269,6 +280,7 @@
           <complexContent>
             <extension base="tns:qlType">
               <sequence>
+                <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
                 <element ref="tns:transition" minOccurs="0" maxOccurs="unbounded" />
               </sequence>
               <attributeGroup ref="tns:activityAttributes" />
@@ -287,6 +299,7 @@
           <complexContent>
             <extension base="tns:javaType">
               <sequence>
+                <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
                 <element ref="tns:transition" minOccurs="0" maxOccurs="unbounded" />
               </sequence>
               <attributeGroup ref="tns:activityAttributes" />
@@ -302,6 +315,7 @@
           <complexContent>
             <extension base="tns:esbType">
               <sequence>
+                <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
                 <element ref="tns:transition" minOccurs="0" maxOccurs="unbounded" />
               </sequence>
               <attributeGroup ref="tns:activityAttributes" />
@@ -316,10 +330,12 @@
         <complexType>
           <sequence>
             <element name="assignment-handler" minOccurs="0"  type="tns:wireObjectType" />
+            <element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
             <element ref="tns:transition" minOccurs="0" maxOccurs="unbounded" />
           </sequence>
           <attributeGroup ref="tns:activityAttributes" />
           <attributeGroup ref="tns:assignmentAttributes"/>
+          <attribute name="swimlane" type="string" />
           <attribute name="on-transition" default="cancel">
             <simpleType>
               <restriction base="string">
@@ -370,58 +386,6 @@
           <attributeGroup ref="tns:activityAttributes" />
         </complexType>
       </element>
-    
-      <element name="activity">
-        <annotation><documentation>Executes an activity implementation.
-        </documentation></annotation>
-        <complexType>
-          <sequence>
-            <group ref="tns:delegationGroup"/>
-            <element ref="tns:transition" minOccurs="0" maxOccurs="unbounded" />
-            <element ref="tns:on" minOccurs="0" maxOccurs="unbounded">
-              <annotation><documentation>Events on which listeners can be registered.</documentation></annotation>
-            </element>
-          </sequence> 
-          <attributeGroup ref="tns:activityAttributes" />
-        </complexType>
-      </element>
-      
-      <element name="email">
-        <annotation><documentation>Sends an email
-        </documentation></annotation>
-        <complexType>
-          <complexContent>
-            <extension base="tns:emailType">
-              <sequence>
-                <element ref="tns:transition" minOccurs="0" maxOccurs="unbounded" />
-                <element ref="tns:on" minOccurs="0" maxOccurs="unbounded">
-                  <annotation><documentation>Events on which listeners can be registered.</documentation></annotation>
-                </element>
-              </sequence>
-              <attributeGroup ref="tns:activityAttributes" />
-            </extension>
-          </complexContent>
-        </complexType>
-      </element>
-      
-      <element name="task">
-        <annotation><documentation>Creates a human task
-        </documentation></annotation>
-        <complexType>
-          <complexContent>
-            <extension base="tns:taskType">
-              <sequence>
-                <element ref="tns:transition" minOccurs="0" maxOccurs="unbounded" />
-                <element ref="tns:on" minOccurs="0" maxOccurs="unbounded">
-                  <annotation><documentation>Events on which listeners can be registered.</documentation></annotation>
-                </element>
-                <element ref="tns:timer" minOccurs="0" maxOccurs="unbounded"/>
-              </sequence>
-              <attributeGroup ref="tns:activityAttributes" />
-            </extension>
-          </complexContent>
-        </complexType>
-      </element>
       -->
     </choice>
   </group>
@@ -593,98 +557,49 @@
       tasks and swimlanes to specify to whom these respectively are assigned.
     </documentation></annotation>
     <attribute name="assignee" type="string">
-      <annotation><documentation>An expression '#{expr}' that resolves to an identifier of 
-        the actual actor that needs to execute the task. It can be a literal as well.
+      <annotation><documentation>Expression that resolves to a userId referencing 
+      the person to which the task or swimlane will be assigned.
       </documentation></annotation>
     </attribute>
     <attribute name="assignee-lang" type="string">
-      <annotation><documentation>The expression language to use to evaluate the assignee 
-        expression.
+      <annotation><documentation>Expression language for the assignee attribute.
       </documentation></annotation>
     </attribute>
-    <attribute name="candidate-groups" type="string">
-      <annotation><documentation>An expression '#{expr}' that resolves to a comma separated
-        list of groups of actors with candidates to execute the task.
-      </documentation></annotation>
-    </attribute>
-    <attribute name="candidate-groups-lang" type="string">
-      <annotation><documentation>The expression language to use to evaluate the candidate-groups 
-        expression.
-      </documentation></annotation>
-    </attribute>
     <attribute name="candidate-users" type="string">
-      <annotation><documentation>An expression '#{expr}' that resolves to a comma separated
-        list of actors that are candidate to execute the task.
-      </documentation></annotation>
+      <annotation><documentation>Expression that resolves to a comma separated 
+      list of userId's. All the referred people will be candidates for 
+      take the task or swimlane.</documentation></annotation>
     </attribute>
     <attribute name="candidate-users-lang" type="string">
-      <annotation><documentation>The expression language to use to evaluate the candidate-users 
-        expression.
-      </documentation></annotation>
+      <annotation><documentation>Expression language for the 
+      candidate-users attribute.</documentation></annotation>
     </attribute>
-    <attribute name="swimlane" type="string">
-      <annotation><documentation>The name of the swimlane that will contain the actor that
-        needs to execute the task.
-      </documentation></annotation>
-    </attribute>
-  </attributeGroup>
-  
-<!--   <complexType name="assignmentType">
-    <annotation><documentation>An element of type assignmentType will be used in 
-      tasks and swimlanes to specify to whom these respectively are assigned.
-    </documentation></annotation>
-    <attribute name="assignee" type="string">
-      <annotation><documentation>An expression '#{expr}' that resolves to an identifier of 
-        the actual actor that needs to execute the task. It can be a literal as well.
-      </documentation></annotation>
-    </attribute>
     <attribute name="candidate-groups" type="string">
-      <annotation><documentation>An expression '#{expr}' that resolves to a comma separated
-        list of groups of actors with candidates to execute the task.
-      </documentation></annotation>
+      <annotation><documentation>Resolves to a comma separated list of groupId's.  
+      All the referred people will be candidates to 
+      take the task or swimlane.</documentation></annotation>
     </attribute>
-    <attribute name="candidate-users" type="string">
-      <annotation><documentation>An expression '#{expr}' that resolves to a comma separated
-        list of actors that are candidate to execute the task.
-      </documentation></annotation>
+    <attribute name="candidate-groups-lang" type="string">
+      <annotation><documentation>Expression language for the 
+      candidate-groups attribute.</documentation></annotation>
     </attribute>
-    <attribute name="swimlane" type="string">
-      <annotation><documentation>The name of the swimlane that will contain the actor that
-        needs to execute the task.
-      </documentation></annotation>
-    </attribute>
-  </complexType> 
+  </attributeGroup>
   
-  <element name="assignment" type="tns:assignmentType">
-    <annotation><documentation>The assignment which specifies who needs to execute
-      task or who is among the candidates to execute it.
-    </documentation></annotation>
-  </element> -->
-  
-  <complexType name="swimlaneType">
-    <annotation><documentation>Elements of type swimlaneType will be used in the 
-      process to enumerate all the participating swimlanes. 
-    </documentation></annotation>
-    <sequence>
-    </sequence>
-    <attribute name="name" type="string"/>
-    <attributeGroup ref="tns:assignmentAttributes"></attributeGroup>
-  </complexType>
-  
-  <element name="swimlane" type="tns:swimlaneType"  >
-    <annotation><documentation>A participating swimlane for this process
-    </documentation></annotation>
+  <element name="swimlane">
+    <annotation><documentation>A process role.</documentation></annotation>
+    <complexType>
+      <attribute name="name" type="string" use="required" />
+      <attributeGroup ref="tns:assignmentAttributes" />
+    </complexType>
   </element>
   
   <complexType name="transitionType">
     <annotation><documentation>The outgoing transitions.  The first in the list 
       will be the default outgoing transition.
     </documentation></annotation>
-    <!-- 
     <sequence>
-      <group ref="tns:eventListenerGroup" />
+      <group ref="tns:eventListenerGroup" minOccurs="0" maxOccurs="unbounded" />
     </sequence>
-    -->
     <attribute name="name" type="string">
       <annotation><documentation>Name of this outgoing transition</documentation></annotation>
     </attribute>
@@ -703,84 +618,30 @@
   </element>
   
   <element name="on">
-    <annotation><documentation>Events on which listeners can be registered.</documentation></annotation>
     <complexType>
-      <!-- 
       <sequence>
         <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>
         </group>
       </sequence>
-      -->
       <attribute name="event" type="string">
-        <annotation><documentation>The event identification
+        <annotation><documentation>The event identification.  start, end, take or 
+        any other custom event.
         </documentation></annotation>
       </attribute>
     </complexType>
   </element>
   
-  <!-- 
-
   <group name="eventListenerGroup">
     <choice>
-      <element name="notify">
-        <annotation><documentation>Calls the notify method on an 
-        EventListener.
+      <element name="event-listener" type="tns:wireObjectType" >
+        <annotation><documentation>An EventListener
         </documentation></annotation>
-        <complexType>
-          <group ref="tns:delegationGroup" />
-          <attribute name="object" type="string">
-            <annotation><documentation>The reference to an object that is declared 
-            in the objects section of this process definition.
-            </documentation></annotation>
-          </attribute>
-          <attribute name="expr" type="string">
-            <annotation><documentation>The expression that will resolve to 
-            an Activity implementation.</documentation></annotation>
-          </attribute>
-        </complexType>
       </element>
-      <element name="invoke" type="tns:invokeType">
-        <annotation><documentation>Invokes a method on a Java object
-        through reflection.  The return value can be captured in a 
-        process variable.
-        </documentation></annotation>
-      </element>
-      <element name="script" type="tns:scriptType">
-        <annotation><documentation>Evaluates a piece of text as a script
-        </documentation></annotation>
-      </element>
-      <element name="email" type="tns:emailType">
-        <annotation><documentation>Sends an email
-        </documentation></annotation>
-      </element>
-      <element ref="tns:timer">
-        <annotation><documentation>Creates a timer.
-        </documentation></annotation>
-      </element>
     </choice>
   </group>
 
-  <complexType name="scriptType">
-    <sequence>
-      <element name="expr" type="string">
-        <annotation><documentation>The content of this expression element 
-        is the script text that will be evaluated.  This is mutually 
-        exclusive with the expression attribute.</documentation></annotation>
-      </element>
-    </sequence>
-    <attribute name="expr" type="string">
-      <annotation><documentation>The script text that will be evaluated.  This 
-      is mutually exclusive with the expression element.
-      </documentation></annotation>
-    </attribute>
-    <attribute name="lang" type="string">
-      <annotation><documentation>Identification of the scripting language 
-      to use.</documentation></annotation>
-    </attribute>
-  </complexType>
-
   <complexType name="emailType">
     <sequence>
       <element name="property">
@@ -797,55 +658,26 @@
     </attribute>
   </complexType>
 
-  <element name="timer">
-    <annotation><documentation>A timer that will be bound to the most inner enclosing scope.
-    Timers can give a signal to an activity instance.  The signal will correspond to a transition 
-    or to an event being fired.
-    </documentation></annotation>
-    <complexType>
-      <choice minOccurs="0" maxOccurs="unbounded">
-        <group ref="tns:eventListenerGroup">
-          <annotation><documentation>An inline list of event listeners 
-          on a timer is a short cut for defining the event separately.
-          </documentation></annotation>
-        </group>
-      </choice>
-      <attribute name="duedate" type="string" use="required" />
-      <attribute name="signal" type="string"  use="required">
-        <annotation><documentation>Refers to the signal that will be used.
-        If inline event listeners are declared, the signal name can not be 
-        the same as an event that is declared in this scope.
-        </documentation></annotation>
-      </attribute>
-      <attribute name="repeat" type="string" />
-    </complexType>
-  </element>
-
-  <complexType name="taskType">
+  <complexType name="taskType" >
+    <!-- 
     <sequence>
-      <element ref="tns:assignment" />
       <element name="reminder">
         <complexType>
           <attribute name="duedate" type="string" use="required" />
           <attribute name="repeat" type="string" />
         </complexType>
       </element>
-      <element ref="tns:subtask" />
     </sequence>
-    <attribute name="title" type="string">
-    </attribute>
+    -->
+    <attributeGroup ref="tns:assignmentAttributes" />
     <attribute name="form" type="string">
     </attribute>
     <attribute name="swimlane" type="string">
     </attribute>
     <attribute name="description" type="string" />
     <attribute name="duedate" type="string" />
-    <attribute name="priority" type="tns:priorityType" default="normal" />
     <attribute name="notify" type="boolean" default="false"/>
-    <attribute name="dynamic" type="boolean" default="true">
-      <annotation><documentation>Is dynamic creation of subtasks 
-      allowed ?</documentation></annotation>
-    </attribute>
+    <!-- 
     <attribute name="subtasksync">
       <simpleType>
         <union>
@@ -871,8 +703,34 @@
         </union>
       </simpleType>
     </attribute>
+    -->
   </complexType>
   
+  <!-- 
+  <element name="timer">
+    <annotation><documentation>A timer that will be bound to the most inner enclosing scope.
+    Timers can give a signal to an activity instance.  The signal will correspond to a transition 
+    or to an event being fired.
+    </documentation></annotation>
+    <complexType>
+      <choice minOccurs="0" maxOccurs="unbounded">
+        <group ref="tns:eventListenerGroup">
+          <annotation><documentation>An inline list of event listeners 
+          on a timer is a short cut for defining the event separately.
+          </documentation></annotation>
+        </group>
+      </choice>
+      <attribute name="duedate" type="string" use="required" />
+      <attribute name="signal" type="string"  use="required">
+        <annotation><documentation>Refers to the signal that will be used.
+        If inline event listeners are declared, the signal name can not be 
+        the same as an event that is declared in this scope.
+        </documentation></annotation>
+      </attribute>
+      <attribute name="repeat" type="string" />
+    </complexType>
+  </element>
+
   <simpleType name="priorityType">
     <restriction base="string">
       <enumeration value="highest"/>
@@ -885,52 +743,40 @@
 
   <element name="subtask" type="tns:taskType">
     <annotation><documentation>Subtask in a task activity.</documentation></annotation>
-  </element>
+  </element> 
+
+  <complexType name="assignmentType">
+    <annotation><documentation>An element of type assignmentType will be used in 
+      tasks and swimlanes to specify to whom these respectively are assigned.
+    </documentation></annotation>
+    <attribute name="assignee" type="string">
+      <annotation><documentation>An expression '#{expr}' that resolves to an identifier of 
+        the actual actor that needs to execute the task. It can be a literal as well.
+      </documentation></annotation>
+    </attribute>
+    <attribute name="candidate-groups" type="string">
+      <annotation><documentation>An expression '#{expr}' that resolves to a comma separated
+        list of groups of actors with candidates to execute the task.
+      </documentation></annotation>
+    </attribute>
+    <attribute name="candidate-users" type="string">
+      <annotation><documentation>An expression '#{expr}' that resolves to a comma separated
+        list of actors that are candidate to execute the task.
+      </documentation></annotation>
+    </attribute>
+    <attribute name="swimlane" type="string">
+      <annotation><documentation>The name of the swimlane that will contain the actor that
+        needs to execute the task.
+      </documentation></annotation>
+    </attribute>
+  </complexType> 
   
-  <element name="swimlane">
-    <annotation><documentation>A process role.</documentation></annotation>
-    <complexType>
-      <sequence>
-        <element ref="tns:assignment"/>
-      </sequence>
-      <attribute name="name" type="string" use="required" />
-    </complexType>
+  <element name="assignment" type="tns:assignmentType">
+    <annotation><documentation>The assignment which specifies who needs to execute
+      task or who is among the candidates to execute it.
+    </documentation></annotation>
   </element>
+
+  -->
   
-  <element name="assignment">
-    <annotation><documentation>Specifies how a task or a swimlane should be assigned 
-    to a specific user or who will be identified as a candidate for it.</documentation></annotation>
-    <complexType>
-      <sequence minOccurs="0">
-        <group ref="tns:delegationGroup">
-          <annotation><documentation>An object that implements the 
-          Assigner interface.
-          </documentation></annotation>
-        </group>
-      </sequence>
-	    <attribute name="assignee" type="string">
-	      <annotation><documentation>User ID of the person to which the task
-	      or swimlane will be assigned.
-	      </documentation></annotation>
-	    </attribute>
-	    <attribute name="assignee-expr" type="string">
-	      <annotation><documentation>Expression that resolves to a 
-	      User ID to which the task or swimlane will be assigned.
-	      </documentation></annotation>
-	    </attribute>
-	    <attribute name="candidates" type="string">
-	      <annotation><documentation>Comma separated list of User ID's 
-	      or Group ID's.  All the referred people will be candidates to 
-	      take the task or swimlane.</documentation></annotation>
-	    </attribute>
-	    <attribute name="candidate-expr" type="string">
-	      <annotation><documentation>Expression that resolves to a 
-	      comma separated list of User ID's or Group ID's.  All the 
-	      referred people will be candidates to 
-	      take the task or swimlane.</documentation></annotation>
-	    </attribute>
-    </complexType>
-  </element>
-  -->  
-  
 </schema>

Modified: jbpm4/branches/tbaeyens/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JpdlBinding.java
===================================================================
--- jbpm4/branches/tbaeyens/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JpdlBinding.java	2009-04-08 14:06:45 UTC (rev 4501)
+++ jbpm4/branches/tbaeyens/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JpdlBinding.java	2009-04-08 18:52:42 UTC (rev 4502)
@@ -25,6 +25,7 @@
 
 import org.jbpm.jpdl.internal.xml.JpdlParser;
 import org.jbpm.jpdl.internal.xml.UnresolvedTransitions;
+import org.jbpm.model.Event;
 import org.jbpm.pvm.internal.model.ActivityImpl;
 import org.jbpm.pvm.internal.model.TransitionImpl;
 import org.jbpm.pvm.internal.util.TagBinding;
@@ -63,13 +64,15 @@
     return true;
   }
 
-  public void parseFlows(Element element, ActivityImpl activity, Parse parse) {
+  public void parseTransitions(Element element, ActivityImpl activity, Parse parse, JpdlParser jpdlParser) {
     List<Element> transitionElements = XmlUtil.elements(element, "transition");
     UnresolvedTransitions unresolvedTransitions = parse.findObject(UnresolvedTransitions.class);
     for (Element transitionElement: transitionElements) {
       String transitionName = XmlUtil.attribute(transitionElement, "name", false, parse);
       TransitionImpl transition = activity.createOutgoingTransition(transitionName);
       unresolvedTransitions.add(transition, transitionElement);
+      
+      jpdlParser.parseEventListeners(transitionElement, transition, Event.TAKE, parse);
     }
   }
 }

Modified: jbpm4/branches/tbaeyens/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java
===================================================================
--- jbpm4/branches/tbaeyens/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java	2009-04-08 14:06:45 UTC (rev 4501)
+++ jbpm4/branches/tbaeyens/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java	2009-04-08 18:52:42 UTC (rev 4502)
@@ -177,7 +177,7 @@
         }
       }
 
-      parseEventListeners(documentElement, parse, processDefinition);
+      parseOnEvents(documentElement, parse, processDefinition);
 
       // activities
       List<Element> elements = XmlUtil.elements(documentElement);
@@ -190,11 +190,11 @@
             try {
               activity.setType(activityBinding.getTagName());
               activityBinding.parseName(element, activity, parse);
-              activityBinding.parseFlows(element, activity, parse);
+              activityBinding.parseTransitions(element, activity, parse, this);
               ActivityBehaviour activityBehaviour = (ActivityBehaviour) activityBinding.parse(element, parse, this);
               activity.setBehaviour(activityBehaviour);
               
-              parseEventListeners(element, parse, activity);
+              parseOnEvents(element, parse, activity);
               
             } finally {
               parse.popObject();
@@ -221,26 +221,30 @@
     return processDefinition;
   }
 
-  public void parseEventListeners(Element element, Parse parse, ObservableElementImpl observableElement) {
+  public void parseOnEvents(Element element, Parse parse, ObservableElementImpl observableElement) {
     // event listeners
     List<Element> onElements = XmlUtil.elements(element, "on");
     for (Element onElement: onElements) {
       String eventName = XmlUtil.attribute(onElement, "event", true, parse);
-      if (eventName!=null) {
-        EventImpl event = observableElement.getEvent(eventName);
-        if (event==null) {
-          event = observableElement.createEvent(eventName);
+      parseEventListeners(onElement, observableElement, eventName, parse);
+    }
+  }
+
+  public void parseEventListeners(Element element, ObservableElementImpl observableElement, String eventName, Parse parse) {
+    if (eventName!=null) {
+      EventImpl event = observableElement.getEvent(eventName);
+      if (event==null) {
+        event = observableElement.createEvent(eventName);
+      }
+      
+      for (Element eventListenerElement: XmlUtil.elements(element)) {
+        JpdlBinding eventBinding = (JpdlBinding) getBinding(eventListenerElement, "eventlistener");
+        if (eventBinding!=null) {
+          EventListener eventListener = (EventListener) eventBinding.parse(eventListenerElement, parse, this);
+          event.createEventListenerReference(eventListener);
+        } else {
+          log.debug("unrecognized event listener: "+XmlUtil.getTagLocalName(eventListenerElement));
         }
-        
-        for (Element eventListenerElement: XmlUtil.elements(onElement)) {
-          JpdlBinding eventBinding = (JpdlBinding) getBinding(eventListenerElement, "eventlistener");
-          if (eventBinding!=null) {
-            EventListener eventListener = (EventListener) eventBinding.parse(eventListenerElement, parse, this);
-            event.createEventListenerReference(eventListener);
-          } else {
-            log.debug("unrecognized event listener: "+XmlUtil.getTagLocalName(eventListenerElement));
-          }
-        }
       }
     }
   }

Modified: jbpm4/branches/tbaeyens/modules/test-db/src/test/java/org/jbpm/test/eventlistener/EventListenerTest.java
===================================================================
--- jbpm4/branches/tbaeyens/modules/test-db/src/test/java/org/jbpm/test/eventlistener/EventListenerTest.java	2009-04-08 14:06:45 UTC (rev 4501)
+++ jbpm4/branches/tbaeyens/modules/test-db/src/test/java/org/jbpm/test/eventlistener/EventListenerTest.java	2009-04-08 18:52:42 UTC (rev 4502)
@@ -21,6 +21,10 @@
  */
 package org.jbpm.test.eventlistener;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jbpm.Execution;
 import org.jbpm.listener.EventListener;
 import org.jbpm.listener.EventListenerExecution;
 import org.jbpm.test.JbpmTestCase;
@@ -31,18 +35,28 @@
  */
 public class EventListenerTest extends JbpmTestCase {
   
-  public static class ProcessEventRecorder implements EventListener {
+  static boolean isInvoked = false;
+  static List<Integer> order;
+  
+  protected void setUp() throws Exception {
+    super.setUp();
+    isInvoked = false;
+  }
+
+  public static class ProcessStartListener implements EventListener {
     private static final long serialVersionUID = 1L;
     public void notify(EventListenerExecution execution) {
-      assertNull(execution.getActivity());
+      assertNotNull(execution.getActivity());
+      assertSame(execution.getActivity(), execution.getProcessDefinition().getInitial());
+      isInvoked = true;
     }
   }
 
-  public void testProcessStart() {
+  public void testProcessStartListener() {
     deployJpdlXmlString(
       "<process name='Insurance claim' key='ICL'>" +
       "  <on event='start'>" +
-      "    <event-listener class='"+ProcessEventRecorder.class.getName()+"' />" +
+      "    <event-listener class='"+ProcessStartListener.class.getName()+"' />" +
       "  </on>" +
       "  <start>" +
       "    <transition to='a' />" +
@@ -52,6 +66,171 @@
     );
     
     executionService.startProcessInstanceByKey("ICL");
+
+    assertTrue("process start listener not invoked", isInvoked);
   }
 
+  public static class ProcessEndListener implements EventListener {
+    private static final long serialVersionUID = 1L;
+    public void notify(EventListenerExecution execution) {
+      assertNotNull(execution.getActivity());
+      assertSame(execution.getActivity(), execution.getProcessDefinition().getActivity("end"));
+      isInvoked = true;
+    }
+  }
+
+  public void testProcessEndListener() {
+    deployJpdlXmlString(
+      "<process name='Insurance claim' key='ICL'>" +
+      "  <on event='end'>" +
+      "    <event-listener class='"+ProcessEndListener.class.getName()+"' />" +
+      "  </on>" +
+      "  <start>" +
+      "    <transition to='end' />" +
+      "  </start>" +
+      "  <end name='end' />" +
+      "</process>"
+    );
+    
+    executionService.startProcessInstanceByKey("ICL");
+    
+    assertTrue("process end listener not invoked", isInvoked);
+  }
+
+  public static class ActivityStartListener implements EventListener {
+    private static final long serialVersionUID = 1L;
+    public void notify(EventListenerExecution execution) {
+      assertNotNull(execution.getActivity());
+      assertSame(execution.getActivity(), execution.getProcessDefinition().getActivity("s"));
+      isInvoked = true;
+    }
+  }
+
+  public void testActivityStartListener() {
+    deployJpdlXmlString(
+      "<process name='Insurance claim' key='ICL'>" +
+      "  <start>" +
+      "    <transition to='s' />" +
+      "  </start>" +
+      "  <state name='s'>" +
+      "    <on event='start'>" +
+      "      <event-listener class='"+ActivityStartListener.class.getName()+"' />" +
+      "    </on>" +
+      "    <transition to='end' />" +
+      "  </state>" +
+      "  <end name='end' />" +
+      "</process>"
+    );
+    
+    executionService.startProcessInstanceByKey("ICL");
+    
+    assertTrue("activity start listener not invoked", isInvoked);
+  }
+
+  public static class ActivityEndListener implements EventListener {
+    private static final long serialVersionUID = 1L;
+    public void notify(EventListenerExecution execution) {
+      assertNotNull(execution.getActivity());
+      assertSame(execution.getActivity(), execution.getProcessDefinition().getActivity("s"));
+      isInvoked = true;
+    }
+  }
+
+  public void testActivityEndListener() {
+    deployJpdlXmlString(
+      "<process name='Insurance claim' key='ICL'>" +
+      "  <start>" +
+      "    <transition to='s' />" +
+      "  </start>" +
+      "  <state name='s'>" +
+      "    <on event='end'>" +
+      "      <event-listener class='"+ActivityStartListener.class.getName()+"' />" +
+      "    </on>" +
+      "    <transition to='end' />" +
+      "  </state>" +
+      "  <end name='end' />" +
+      "</process>"
+    );
+    
+    Execution execution = executionService.startProcessInstanceByKey("ICL");
+
+    assertFalse("activity end listener invoked too early", isInvoked);
+    
+    executionService.signalExecutionById(execution.getId());
+
+    assertTrue("activity end listener not invoked", isInvoked);
+  }
+
+  public static class TransitionListener implements EventListener {
+    private static final long serialVersionUID = 1L;
+    public void notify(EventListenerExecution execution) {
+      assertNotNull(execution.getTransition());
+      isInvoked = true;
+    }
+  }
+
+  public void testTransitionListener() {
+    order = new ArrayList<Integer>();
+    deployJpdlXmlString(
+      "<process name='Insurance claim' key='ICL'>" +
+      "  <start>" +
+      "    <transition to='end'>" +
+      "      <event-listener class='"+TransitionListener.class.getName()+"' />" +
+      "    </transition>" +
+      "  </start>" +
+      "  <end name='end' />" +
+      "</process>"
+    );
+    
+    executionService.startProcessInstanceByKey("ICL");
+    
+    assertTrue("transition listener not invoked", isInvoked);
+  }
+
+  public static class OrderListener implements EventListener {
+    private static final long serialVersionUID = 1L;
+    int i;
+    public void notify(EventListenerExecution execution) {
+      order.add(i);
+    }
+  }
+
+  public void testEventOrdering() {
+    order = new ArrayList<Integer>();
+    deployJpdlXmlString(
+      "<process name='Insurance claim' key='ICL'>" +
+      "  <start>" +
+      "    <transition to='end'>" +
+      "      <event-listener class='"+OrderListener.class.getName()+"'>" +
+      "        <field name='i'><int value='1' /></field> " +
+      "      </event-listener>" +
+      "      <event-listener class='"+OrderListener.class.getName()+"'>" +
+      "        <field name='i'><int value='2' /></field> " +
+      "      </event-listener>" +
+      "      <event-listener class='"+OrderListener.class.getName()+"'>" +
+      "        <field name='i'><int value='3' /></field> " +
+      "      </event-listener>" +
+      "      <event-listener class='"+OrderListener.class.getName()+"'>" +
+      "        <field name='i'><int value='4' /></field> " +
+      "      </event-listener>" +
+      "      <event-listener class='"+OrderListener.class.getName()+"'>" +
+      "        <field name='i'><int value='5' /></field> " +
+      "      </event-listener>" +
+      "    </transition>" +
+      "  </start>" +
+      "  <end name='end' />" +
+      "</process>"
+    );
+    
+    executionService.startProcessInstanceByKey("ICL");
+    
+    List<Integer> expectedOrder = new ArrayList<Integer>();
+    expectedOrder.add(1);
+    expectedOrder.add(2);
+    expectedOrder.add(3);
+    expectedOrder.add(4);
+    expectedOrder.add(5);
+    
+    assertEquals(expectedOrder, order);
+  }
 }




More information about the jbpm-commits mailing list