[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