[jbpm-commits] JBoss JBPM SVN: r4543 - in jbpm4/trunk: modules/api/src/main/resources and 2 other directories.
do-not-reply at jboss.org
do-not-reply at jboss.org
Mon Apr 13 07:01:01 EDT 2009
Author: tom.baeyens at jboss.com
Date: 2009-04-13 07:01:01 -0400 (Mon, 13 Apr 2009)
New Revision: 4543
Modified:
jbpm4/trunk/build.xml
jbpm4/trunk/modules/api/src/main/resources/jpdl.xsd
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/TimerDefinitionImpl.java
Log:
JBPM-2029 added parsing and updated schema for timers
Modified: jbpm4/trunk/build.xml
===================================================================
--- jbpm4/trunk/build.xml 2009-04-13 08:59:29 UTC (rev 4542)
+++ jbpm4/trunk/build.xml 2009-04-13 11:01:01 UTC (rev 4543)
@@ -98,7 +98,7 @@
<arg line="-Pschemadocs package" />
</exec>
<antcall target="show.html">
- <param name="page" value="modules/api/target/doc/schemadoc/index.html"/>
+ <param name="page" value="modules/api/target/schemadocs/index.html"/>
</antcall>
</target>
Modified: jbpm4/trunk/modules/api/src/main/resources/jpdl.xsd
===================================================================
--- jbpm4/trunk/modules/api/src/main/resources/jpdl.xsd 2009-04-13 08:59:29 UTC (rev 4542)
+++ jbpm4/trunk/modules/api/src/main/resources/jpdl.xsd 2009-04-13 11:01:01 UTC (rev 4543)
@@ -6,7 +6,6 @@
elementFormDefault="qualified"
attributeFormDefault="unqualified">
-
<annotation>
<documentation>Schema for jPDL 4 process descriptions;
element process is the top level element.
@@ -18,17 +17,6 @@
delegation group can be pulled up as an expression
attribute in each use case of the delegationGroup
- TODO: Should automatic activities have timers? That makes sense
- in a transient scenario, but not in a transactional scenario.
- Same comment holds for asynchronous continuations
-
- TODO: Is it a good idea to move blocking and signalling to the API ?
-
- TODO: Figure out task reuse (requires templating and parameters)
- and dynamic task creation (requires tasks to be declared by name
- in the process definition and that from the API tasks can be
- easily instantiated.
-
TODO: Investigate if object-refs to centrally defined objects would
add value over inline defined objects.
</documentation>
@@ -43,6 +31,7 @@
<sequence minOccurs="0" maxOccurs="unbounded">
<element ref="tns:swimlane" minOccurs="0" maxOccurs="unbounded"/>
<element ref="tns:on" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="tns:timer" minOccurs="0" maxOccurs="unbounded"/>
<group ref="tns:activityGroup" minOccurs="0" maxOccurs="unbounded" />
</sequence>
<attribute name="name" use="required" type="string">
@@ -163,13 +152,14 @@
<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" />
</sequence>
<attributeGroup ref="tns:activityAttributes" />
</complexType>
</element>
- <!-- ~~~ EXCLUSIVE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+ <!-- ~~~ DECISION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<element name="decision">
<annotation><documentation>Decision gateway: selects one path out of many alternatives.
When an execution comes in, exactly one outgoing transition is taken.
@@ -331,6 +321,7 @@
<sequence>
<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" />
</sequence>
<attributeGroup ref="tns:activityAttributes" />
@@ -632,6 +623,42 @@
</attribute>
</complexType>
</element>
+
+ <element name="timer">
+ <complexType>
+ <sequence>
+ <group ref="tns:eventListenerGroup" minOccurs="0" maxOccurs="unbounded">
+ <annotation><documentation>A list of event listeners that will
+ 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'
+ </documentation></annotation>
+ </attribute>
+ <attribute name="repeat" type="string">
+ <annotation><documentation>Timer duedate expression that defines repeated scheduling
+ relative to the last timer fire event. E.g. '2 hours' or '4 business days'
+ </documentation></annotation>
+ </attribute>
+ <attribute name="duedatetime" type="string">
+ <annotation><documentation>Absolute time in format <code>HH:mm dd/MM/yyyy</code>
+ (see SimpleDateFormat). The format for the absolute time can be customized in the
+ jbpm configuration.
+ </documentation></annotation>
+ </attribute>
+ </complexType>
+ </element>
<group name="eventListenerGroup">
<choice>
@@ -743,42 +770,6 @@
</restriction>
</simpleType>
- <element name="subtask" type="tns:taskType">
- <annotation><documentation>Subtask in a task activity.</documentation></annotation>
- </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="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>
-
-->
</schema>
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-13 08:59:29 UTC (rev 4542)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java 2009-04-13 11:01:01 UTC (rev 4543)
@@ -22,12 +22,16 @@
package org.jbpm.jpdl.internal.xml;
import java.net.URL;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
import org.jbpm.activity.ActivityBehaviour;
+import org.jbpm.env.Environment;
import org.jbpm.internal.log.Log;
import org.jbpm.jpdl.internal.activity.JpdlBinding;
import org.jbpm.jpdl.internal.model.JpdlProcessDefinition;
@@ -36,6 +40,8 @@
import org.jbpm.pvm.internal.model.EventImpl;
import org.jbpm.pvm.internal.model.ObservableElementImpl;
import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
+import org.jbpm.pvm.internal.model.ScopeElementImpl;
+import org.jbpm.pvm.internal.model.TimerDefinitionImpl;
import org.jbpm.pvm.internal.task.AssignableDefinitionImpl;
import org.jbpm.pvm.internal.task.SwimlaneDefinitionImpl;
import org.jbpm.pvm.internal.task.TaskDefinitionImpl;
@@ -177,38 +183,18 @@
}
}
+ // on events
parseOnEvents(documentElement, parse, processDefinition);
+
+ // timers
+ parseTimers(documentElement, parse, processDefinition);
// activities
- List<Element> elements = XmlUtil.elements(documentElement);
- for (Element element: elements) {
- if (!"on".equals(XmlUtil.getTagLocalName(element))) {
- JpdlBinding activityBinding = (JpdlBinding) getBinding(element, "activity");
- if (activityBinding!=null) {
- ActivityImpl activity = processDefinition.createActivity();
- parse.pushObject(activity);
- try {
- activity.setType(activityBinding.getTagName());
- activityBinding.parseName(element, activity, parse);
- activityBinding.parseTransitions(element, activity, parse, this);
- ActivityBehaviour activityBehaviour = (ActivityBehaviour) activityBinding.parse(element, parse, this);
- activity.setBehaviour(activityBehaviour);
-
- parseOnEvents(element, parse, activity);
-
- } finally {
- parse.popObject();
- }
- } else {
- log.debug("unrecognized activity: "+XmlUtil.getTagLocalName(element));
- }
- }
- }
-
- for (UnresolvedTransition unresolvedTransition: unresolvedTransitions.list) {
- unresolvedTransition.resolve(processDefinition, parse);
- }
+ parseActivities(documentElement, parse, processDefinition);
+ // bind activities to their destinations
+ resolveTransitionDestinations(parse, processDefinition, unresolvedTransitions);
+
} finally {
parse.popObject();
}
@@ -221,6 +207,81 @@
return processDefinition;
}
+ private void resolveTransitionDestinations(Parse parse, JpdlProcessDefinition processDefinition, UnresolvedTransitions unresolvedTransitions) {
+ for (UnresolvedTransition unresolvedTransition: unresolvedTransitions.list) {
+ unresolvedTransition.resolve(processDefinition, parse);
+ }
+ }
+
+ private void parseActivities(Element documentElement, Parse parse, JpdlProcessDefinition processDefinition) {
+ List<Element> elements = XmlUtil.elements(documentElement);
+ for (Element element: elements) {
+ if ( !"on".equals(XmlUtil.getTagLocalName(element))
+ && !"timer".equals(XmlUtil.getTagLocalName(element))
+ ) {
+ JpdlBinding activityBinding = (JpdlBinding) getBinding(element, "activity");
+ if (activityBinding!=null) {
+ ActivityImpl activity = processDefinition.createActivity();
+ parse.pushObject(activity);
+ try {
+ activity.setType(activityBinding.getTagName());
+ activityBinding.parseName(element, activity, parse);
+ activityBinding.parseTransitions(element, activity, parse, this);
+ ActivityBehaviour activityBehaviour = (ActivityBehaviour) activityBinding.parse(element, parse, this);
+ activity.setBehaviour(activityBehaviour);
+
+ parseOnEvents(element, parse, activity);
+ parseTimers(element, parse, activity);
+
+ } finally {
+ parse.popObject();
+ }
+ } else {
+ log.debug("unrecognized activity: "+XmlUtil.getTagLocalName(element));
+ }
+ }
+ }
+ }
+
+ 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) {
+ 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", true, parse);
+ timerDefinition.setDueDateDescription(duedate);
+
+ String duedatetime = XmlUtil.attribute(timerElement, "duedatetime", true, parse);
+ if (duedatetime!=null) {
+ String dueDateTimeFormatText = (String) Environment.getFromCurrent("jbpm.duedatetime.format");
+ if (dueDateTimeFormatText==null) {
+ dueDateTimeFormatText = "HH:mm dd/MM/yyyy";
+ }
+ SimpleDateFormat dateFormat = new SimpleDateFormat(dueDateTimeFormatText);
+ try {
+ Date duedatetimeDate = dateFormat.parse(duedatetime);
+ timerDefinition.setDueDate(duedatetimeDate);
+ } catch (ParseException e) {
+ parse.addProblem("couldn't parse duedatetime "+duedatetime, e);
+ }
+ }
+
+ String repeat = XmlUtil.attribute(timerElement, "repeat");
+ timerDefinition.setRepeat(repeat);
+ }
+
public void parseOnEvents(Element element, Parse parse, ObservableElementImpl observableElement) {
// event listeners
List<Element> onElements = XmlUtil.elements(element, "on");
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/TimerDefinitionImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/TimerDefinitionImpl.java 2009-04-13 08:59:29 UTC (rev 4542)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/TimerDefinitionImpl.java 2009-04-13 11:01:01 UTC (rev 4543)
@@ -36,12 +36,12 @@
protected long dbid;
protected int dbversion;
protected String dueDateDescription;
+ protected Date dueDate;
protected String repeat;
protected Boolean isExclusive;
protected Integer retries;
protected String eventName;
protected String signalName;
- protected Date dueDate;
public TimerDefinitionImpl() {
}
More information about the jbpm-commits
mailing list