[jboss-svn-commits] JBL Code SVN: r20178 - in labs/jbossrules/trunk: drools-process and 24 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Tue May 27 07:13:44 EDT 2008
Author: KrisVerlaenen
Date: 2008-05-27 07:13:44 -0400 (Tue, 27 May 2008)
New Revision: 20178
Added:
labs/jbossrules/trunk/drools-process/
labs/jbossrules/trunk/drools-process/drools-jpdl/
labs/jbossrules/trunk/drools-process/drools-jpdl/.classpath
labs/jbossrules/trunk/drools-process/drools-jpdl/.project
labs/jbossrules/trunk/drools-process/drools-jpdl/src/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/JpdlParser.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/JpdlProcessValidator.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/JpdlConnection.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/JpdlProcess.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/Decision.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/EndState.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/Fork.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/Join.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/JpdlNode.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/MailNode.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/ProcessState.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/StartState.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/State.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/TaskNode.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/JpdlProcessInstance.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/JpdlProcessInstanceFactory.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/DecisionInstance.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/EndStateInstance.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/ForkInstance.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/JoinInstance.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/JpdlNodeInstance.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/MailNodeInstance.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/ProcessStateInstance.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/StartStateInstance.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/StateInstance.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/TaskNodeInstance.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/xml/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/xml/JpdlProcessSemanticModule.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/xml/StartStateHandler.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/resources/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/resources/META-INF/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/resources/META-INF/JpdlProcessInstanceFactory.conf
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/resources/META-INF/JpdlProcessNodeInstanceFactory.conf
labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/resources/META-INF/drools.rulebase.conf
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/ParseSimpleProcessTest.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/SimpleProcessTest.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/SysoutHandler.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/WebsaleProcessTest.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/jbpm/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/jbpm/websale/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/jbpm/websale/RemindActor.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/jbpm/websale/ShipItem.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/jbpm/websale/UpdateBooks.java
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple/gpd.xml
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple/processdefinition.xml
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple/processimage.jpg
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple2/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple2/gpd.xml
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple2/processdefinition.xml
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple2/processimage.jpg
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/websale/
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/websale/gpd.xml
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/websale/processdefinition.xml
labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/websale/processimage.jpg
Log:
JBRULES-1623: Support for jPDL 3.2
- initial commit
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/.classpath
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/.classpath (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/.classpath 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src/main/java"/>
+ <classpathentry kind="src" path="src/main/resources"/>
+ <classpathentry kind="src" path="src/test/java"/>
+ <classpathentry kind="src" path="src/test/resources"/>
+ <classpathentry combineaccessrules="false" exported="true" kind="src" path="/drools-compiler"/>
+ <classpathentry combineaccessrules="false" exported="true" kind="src" path="/drools-core"/>
+ <classpathentry exported="true" kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
+ <classpathentry exported="true" kind="lib" path="lib/jbpm-jpdl.jar" sourcepath="F:/Mijn documenten/projects/jbpm/jbpm-jpdl-3.2.GA/src/jpdl"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="var" path="M2_REPO/commons-collections/commons-collections/3.2/commons-collections-3.2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.0.4/commons-logging-1.0.4.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/mvel/mvel/2.0-SNAPSHOT/mvel-2.0-SNAPSHOT.jar"/>
+ <classpathentry kind="var" path="M2_REPO/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/.project
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/.project (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/.project 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>drools-jpdl</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/JpdlParser.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/JpdlParser.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/JpdlParser.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,239 @@
+package org.drools.jpdl;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.drools.jpdl.core.JpdlConnection;
+import org.drools.jpdl.core.JpdlProcess;
+import org.drools.jpdl.core.node.Decision;
+import org.drools.jpdl.core.node.EndState;
+import org.drools.jpdl.core.node.Fork;
+import org.drools.jpdl.core.node.Join;
+import org.drools.jpdl.core.node.JpdlNode;
+import org.drools.jpdl.core.node.MailNode;
+import org.drools.jpdl.core.node.ProcessState;
+import org.drools.jpdl.core.node.StartState;
+import org.drools.jpdl.core.node.State;
+import org.drools.jpdl.core.node.TaskNode;
+import org.drools.process.core.ParameterDefinition;
+import org.drools.process.core.context.swimlane.Swimlane;
+import org.drools.process.core.context.swimlane.SwimlaneContext;
+import org.drools.process.core.datatype.impl.type.StringDataType;
+import org.drools.process.core.impl.ParameterDefinitionImpl;
+import org.drools.process.core.validation.ProcessValidationError;
+import org.drools.workflow.core.Node;
+import org.jbpm.graph.def.Event;
+import org.jbpm.graph.def.ExceptionHandler;
+import org.jbpm.graph.def.ProcessDefinition;
+import org.jbpm.taskmgmt.def.Task;
+
+public class JpdlParser {
+
+ private static final Set<ParameterDefinition> EMAIL_PARAMETER_DEFINITIONS = new HashSet<ParameterDefinition>();
+ private static final Pattern MAIL_TEMPLATE_PATTERN = Pattern.compile("<template>(.*)</template>", Pattern.DOTALL);
+ private static final Pattern MAIL_ACTORS_PATTERN = Pattern.compile("<actors>(.*)</actors>", Pattern.DOTALL);
+ private static final Pattern MAIL_TO_PATTERN = Pattern.compile("<to>(.*)</to>", Pattern.DOTALL);
+ private static final Pattern MAIL_SUBJECT_PATTERN = Pattern.compile("<subject>(.*)</subject>", Pattern.DOTALL);
+ private static final Pattern MAIL_TEXT_PATTERN = Pattern.compile("<text>(.*)</text>", Pattern.DOTALL);
+
+ static {
+ EMAIL_PARAMETER_DEFINITIONS.add(new ParameterDefinitionImpl("From", new StringDataType()));
+ EMAIL_PARAMETER_DEFINITIONS.add(new ParameterDefinitionImpl("To", new StringDataType()));
+ EMAIL_PARAMETER_DEFINITIONS.add(new ParameterDefinitionImpl("Subject", new StringDataType()));
+ EMAIL_PARAMETER_DEFINITIONS.add(new ParameterDefinitionImpl("Text", new StringDataType()));
+ }
+
+ private ProcessValidationError[] errors;
+
+ public JpdlProcess loadJpdlProcess(String name) {
+ org.jbpm.graph.def.ProcessDefinition processDefinition =
+ org.jbpm.graph.def.ProcessDefinition.parseXmlResource(name);
+ return loadJpdlProcess(processDefinition);
+ }
+
+ public JpdlProcess loadJpdlProcess(org.jbpm.graph.def.ProcessDefinition processDefinition) {
+ JpdlProcess process = new JpdlProcess();
+ process.setId(processDefinition.getName());
+ process.setName(processDefinition.getName());
+ process.setPackageName("org.drools");
+ SwimlaneContext swimlaneContext = new SwimlaneContext();
+ process.addContext(swimlaneContext);
+ process.setDefaultContext(swimlaneContext);
+ org.jbpm.graph.def.Node startState = processDefinition.getStartState();
+ String startStateName = startState == null ? null : startState.getName();
+
+ List<org.jbpm.graph.def.Node> nodes = processDefinition.getNodes();
+ int nodeId = 0;
+ Map<org.jbpm.graph.def.Node, Node> mapping = new HashMap<org.jbpm.graph.def.Node, Node>();
+ for (org.jbpm.graph.def.Node jPDLnode: nodes) {
+ JpdlNode node = null;
+ if (jPDLnode instanceof org.jbpm.graph.node.StartState) {
+ node = new StartState();
+ } else if (jPDLnode instanceof org.jbpm.graph.node.EndState) {
+ node = new EndState();
+ } else if (org.jbpm.graph.def.Node.class.equals(jPDLnode.getClass())) {
+ JpdlNode newNode = new JpdlNode();
+ setDefaultNodeProperties(jPDLnode, newNode);
+ node = newNode;
+ } else if (jPDLnode instanceof org.jbpm.graph.node.Fork) {
+ org.jbpm.graph.node.Fork jPDLfork =
+ (org.jbpm.graph.node.Fork) jPDLnode;
+ Fork newNode = new Fork();
+ newNode.setScript(jPDLfork.getScript());
+ node = newNode;
+ } else if (jPDLnode instanceof org.jbpm.graph.node.Join) {
+ org.jbpm.graph.node.Join jPDLjoin =
+ (org.jbpm.graph.node.Join) jPDLnode;
+ Join newNode = new Join();
+ newNode.setDiscriminator(jPDLjoin.isDiscriminator());
+ newNode.setTokenNames(jPDLjoin.getTokenNames());
+ newNode.setScript(jPDLjoin.getScript());
+ newNode.setNOutOfM(jPDLjoin.getNOutOfM());
+ node = newNode;
+ } else if (jPDLnode instanceof org.jbpm.graph.node.MailNode) {
+ String config = jPDLnode.getAction().getActionDelegation().getConfiguration();
+
+ MailNode newNode = new MailNode();
+ Matcher matcher = MAIL_TEMPLATE_PATTERN.matcher(config);
+ if (matcher.find()) {
+ newNode.setTemplate(matcher.group(1));
+ }
+ matcher = MAIL_ACTORS_PATTERN.matcher(config);
+ if (matcher.find()) {
+ newNode.setActors(matcher.group(1));
+ }
+ matcher = MAIL_TO_PATTERN.matcher(config);
+ if (matcher.find()) {
+ newNode.setTo(matcher.group(1));
+ }
+ matcher = MAIL_SUBJECT_PATTERN.matcher(config);
+ if (matcher.find()) {
+ newNode.setSubject(matcher.group(1));
+ }
+ matcher = MAIL_TEXT_PATTERN.matcher(config);
+ if (matcher.find()) {
+ newNode.setText(matcher.group(1));
+ }
+ node = newNode;
+ } else if (jPDLnode instanceof org.jbpm.graph.node.Decision) {
+ org.jbpm.graph.node.Decision jPDLdecision =
+ (org.jbpm.graph.node.Decision) jPDLnode;
+ Decision newNode = new Decision();
+ newNode.setDecisionConditions(jPDLdecision.getDecisionConditions());
+ // TODO: unable to access decisionDelegation
+ // TODO: unable to access decisionExpression
+ node = newNode;
+ } else if (jPDLnode instanceof org.jbpm.graph.node.ProcessState) {
+ org.jbpm.graph.node.ProcessState jPDLprocessState =
+ (org.jbpm.graph.node.ProcessState) jPDLnode;
+ ProcessState newNode = new ProcessState();
+ ProcessDefinition subProcessDefinition =
+ jPDLprocessState.getSubProcessDefinition();
+ if (subProcessDefinition != null) {
+ newNode.setSubProcessName(subProcessDefinition.getName());
+ // TODO: parse sub process definition as well
+ }
+ // TODO: unable to access subProcessName
+ // TODO: unable to access variableAccesses
+ node = newNode;
+ } else if (jPDLnode instanceof org.jbpm.graph.node.TaskNode) {
+ org.jbpm.graph.node.TaskNode jPDLtaskNode =
+ (org.jbpm.graph.node.TaskNode) jPDLnode;
+ TaskNode newNode = new TaskNode();
+ Set<Task> tasks = jPDLtaskNode.getTasks();
+ newNode.setTasks(tasks);
+ newNode.setSignal(jPDLtaskNode.getSignal());
+ newNode.setCreateTasks(jPDLtaskNode.getCreateTasks());
+ newNode.setEndTasks(jPDLtaskNode.isEndTasks());
+ for (Task task: tasks) {
+ org.jbpm.taskmgmt.def.Swimlane jPDLswimlane = task.getSwimlane();
+ if (jPDLswimlane != null) {
+ String swimlaneName = jPDLswimlane.getName();
+ if (swimlaneContext.getSwimlane(swimlaneName) == null) {
+ Swimlane swimlane = new Swimlane(swimlaneName);
+ swimlane.setActorId(jPDLswimlane.getActorIdExpression());
+ // TODO support other types of actor expressions as well
+ swimlaneContext.addSwimlane(swimlane);
+ }
+ }
+ }
+ node = newNode;
+ } else if (jPDLnode instanceof org.jbpm.graph.node.State) {
+ node = new State();
+ }
+ if (node == null) {
+ throw new IllegalArgumentException(
+ "Unknown node type: " + jPDLnode.getClass().getName() + " " + jPDLnode);
+ }
+ setDefaultNodeProperties(jPDLnode, (JpdlNode) node);
+ node.setId(++nodeId);
+ mapping.put(jPDLnode, node);
+ process.addNode(node);
+ if (startStateName != null && startStateName.equals(node.getName())) {
+ process.setStartState(node);
+ }
+ }
+
+ for (Map.Entry<org.jbpm.graph.def.Node, Node> entry: mapping.entrySet()) {
+ List<org.jbpm.graph.def.Transition> leavingTransitions =
+ (List<org.jbpm.graph.def.Transition>) entry.getKey().getLeavingTransitions();
+ if (leavingTransitions != null) {
+ for (org.jbpm.graph.def.Transition transition: leavingTransitions) {
+ Node from = mapping.get(transition.getFrom());
+ Node to = mapping.get(transition.getTo());
+ String transitionName = transition.getName();
+ if (transitionName == null) {
+ transitionName = Node.CONNECTION_DEFAULT_TYPE;
+ }
+ // TODO: transition condition, events and exception handlers
+ JpdlConnection connection =
+ new JpdlConnection(from, transitionName, to, Node.CONNECTION_DEFAULT_TYPE);
+ Map<String, Event> events = transition.getEvents();
+ if (events != null) {
+ for (Event event: events.values()) {
+ connection.addEvent(event);
+ }
+ }
+ List<ExceptionHandler> exceptionHandlers = transition.getExceptionHandlers();
+ if (exceptionHandlers != null) {
+ for (ExceptionHandler exceptionHandler: exceptionHandlers) {
+ connection.addExceptionHandler(exceptionHandler);
+ }
+ }
+ connection.setCondition(transition.getCondition());
+ }
+ }
+ }
+
+ errors = JpdlProcessValidator.getInstance().validateProcess(process);
+ return process;
+ }
+
+ private void setDefaultNodeProperties(org.jbpm.graph.def.Node jPDLnode, JpdlNode newNode) {
+ newNode.setName(jPDLnode.getName());
+ newNode.setAction(jPDLnode.getAction());
+ Map<String, Event> events = jPDLnode.getEvents();
+ if (events != null) {
+ for (Event event: events.values()) {
+ newNode.addEvent(event);
+ // TODO: extract timer actions and replace by our timer framework
+ }
+ }
+ List<ExceptionHandler> exceptionHandlers = jPDLnode.getExceptionHandlers();
+ if (exceptionHandlers != null) {
+ for (ExceptionHandler exceptionHandler: exceptionHandlers) {
+ newNode.addExceptionHandler(exceptionHandler);
+ }
+ }
+ }
+
+ public ProcessValidationError[] getErrors() {
+ return this.errors;
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/JpdlProcessValidator.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/JpdlProcessValidator.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/JpdlProcessValidator.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,325 @@
+package org.drools.jpdl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.jpdl.core.JpdlProcess;
+import org.drools.jpdl.core.node.EndState;
+import org.drools.jpdl.core.node.StartState;
+import org.drools.process.core.Process;
+import org.drools.process.core.Work;
+import org.drools.process.core.context.variable.Variable;
+import org.drools.process.core.validation.ProcessValidationError;
+import org.drools.process.core.validation.ProcessValidator;
+import org.drools.process.core.validation.impl.ProcessValidationErrorImpl;
+import org.drools.workflow.core.Connection;
+import org.drools.workflow.core.Node;
+import org.drools.workflow.core.impl.DroolsConsequenceAction;
+import org.drools.workflow.core.node.ActionNode;
+import org.drools.workflow.core.node.CompositeNode;
+import org.drools.workflow.core.node.Join;
+import org.drools.workflow.core.node.MilestoneNode;
+import org.drools.workflow.core.node.RuleSetNode;
+import org.drools.workflow.core.node.Split;
+import org.drools.workflow.core.node.SubProcessNode;
+import org.drools.workflow.core.node.WorkItemNode;
+import org.mvel.ErrorDetail;
+import org.mvel.ParserContext;
+import org.mvel.compiler.ExpressionCompiler;
+
+public class JpdlProcessValidator implements ProcessValidator {
+
+ private static JpdlProcessValidator instance;
+
+ private JpdlProcessValidator() {
+ }
+
+ public static JpdlProcessValidator getInstance() {
+ if ( instance == null ) {
+ instance = new JpdlProcessValidator();
+ }
+ return instance;
+ }
+
+ public ProcessValidationError[] validateProcess(final JpdlProcess process) {
+ final List<ProcessValidationError> errors = new ArrayList<ProcessValidationError>();
+
+ if (process.getName() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Process has no name."));
+ }
+
+ if (process.getId() == null || "".equals(process.getId())) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Process has no id."));
+ }
+
+ if ( process.getPackageName() == null || "".equals( process.getPackageName() ) ) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Process has no package name."));
+ }
+
+ final Node[] nodes = process.getNodes();
+ validateNodes(nodes, errors, process);
+ Node startNode = process.getStart();
+ if (startNode == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Process has no start node."));
+ }
+ for (final Iterator<Variable> it = process.getVariableScope().getVariables().iterator(); it.hasNext(); ) {
+ final Variable variable = it.next();
+ if (variable.getType() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Variable '" + variable.getName() + "' has no type."));
+ }
+ }
+
+ checkAllNodesConnectedToStart(process, errors);
+
+ return errors.toArray(new ProcessValidationError[errors.size()]);
+ }
+
+ private void validateNodes(Node[] nodes, List<ProcessValidationError> errors, JpdlProcess process) {
+ for ( int i = 0; i < nodes.length; i++ ) {
+ final Node node = nodes[i];
+ if (node instanceof StartState) {
+ final StartState startState = (StartState) node;
+ if (startState.getOutgoingConnections().size() != 1) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Start state '" + node.getName() + "' [" + node.getId() + "] has more than one type of outgoing connections."));
+ }
+ List<Connection> connections = startState.getOutgoingConnections(Node.CONNECTION_DEFAULT_TYPE);
+ if (connections == null || connections.size() == 0) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Start state '" + node.getName() + "' [" + node.getId() + "] has no default outgoing connections."));
+ }
+ if (connections.size() != 1) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Start state '" + node.getName() + "' [" + node.getId() + "] has more than one default outgoing connection."));
+ }
+ } else if (node instanceof EndState) {
+ final EndState endState = (EndState) node;
+ if (endState.getIncomingConnections().size() != 1) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "End state '" + node.getName() + "' [" + node.getId() + "] has more than one type of incoming connections."));
+ }
+ List<Connection> connections = endState.getIncomingConnections(Node.CONNECTION_DEFAULT_TYPE);
+ if (connections == null || connections.size() == 0) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "End state '" + node.getName() + "' [" + node.getId() + "] has no default incoming connections."));
+ }
+ if (connections.size() != 1) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "End state '" + node.getName() + "' [" + node.getId() + "] has more than one default incoming connection."));
+ }
+ } else if (node instanceof RuleSetNode) {
+ final RuleSetNode ruleSetNode = (RuleSetNode) node;
+ if (ruleSetNode.getFrom() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "RuleSet node '" + node.getName() + "' [" + node.getId() + "] has no incoming connection."));
+ }
+ if (ruleSetNode.getTo() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "RuleSet node '" + node.getName() + "' [" + node.getId() + "] has no outgoing connection."));
+ }
+ final String ruleFlowGroup = ruleSetNode.getRuleFlowGroup();
+ if (ruleFlowGroup == null || "".equals(ruleFlowGroup)) {
+ errors.add( new ProcessValidationErrorImpl(process,
+ "RuleSet node '" + node.getName() + "' [" + node.getId() + "] has no ruleflow-group."));
+ }
+ } else if (node instanceof Split) {
+ final Split split = (Split) node;
+ if (split.getType() == Split.TYPE_UNDEFINED) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Split node '" + node.getName() + "' [" + node.getId() + "] has no type."));
+ }
+ if (split.getFrom() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Split node '" + node.getName() + "' [" + node.getId() + "] has no incoming connection."));
+ }
+ if (split.getDefaultOutgoingConnections().size() < 2) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Split node '" + node.getName() + "' [" + node.getId() + "] does not have more than one outgoing connection: " + split.getOutgoingConnections().size() + "."));
+ }
+ if (split.getType() == Split.TYPE_XOR || split.getType() == Split.TYPE_OR ) {
+ for ( final Iterator<Connection> it = split.getDefaultOutgoingConnections().iterator(); it.hasNext(); ) {
+ final Connection connection = it.next();
+ if (split.getConstraint(connection) == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Split node '" + node.getName() + "' [" + node.getId() + "] does not have a constraint for " + connection.toString() + "."));
+ }
+ }
+ }
+ } else if ( node instanceof Join ) {
+ final Join join = (Join) node;
+ if (join.getType() == Join.TYPE_UNDEFINED) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Join node '" + node.getName() + "' [" + node.getId() + "] has no type."));
+ }
+ if (join.getDefaultIncomingConnections().size() < 2) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Join node '" + node.getName() + "' [" + node.getId() + "] does not have more than one incoming connection: " + join.getIncomingConnections().size() + "."));
+ }
+ if (join.getTo() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Join node '" + node.getName() + "' [" + node.getId() + "] has no outgoing connection."));
+ }
+ } else if (node instanceof MilestoneNode) {
+ final MilestoneNode milestone = (MilestoneNode) node;
+ if (milestone.getFrom() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Milestone node '" + node.getName() + "' [" + node.getId() + "] has no incoming connection."));
+ }
+
+ if (milestone.getTo() == null) {
+ errors.add( new ProcessValidationErrorImpl(process,
+ "Milestone node '" + node.getName() + "' [" + node.getId() + "] has no outgoing connection."));
+ }
+ if (milestone.getConstraint() == null) {
+ errors.add( new ProcessValidationErrorImpl(process,
+ "Milestone node '" + node.getName() + "' [" + node.getId() + "] has no constraint."));
+ }
+ } else if (node instanceof SubProcessNode) {
+ final SubProcessNode subProcess = (SubProcessNode) node;
+ if (subProcess.getFrom() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "SubProcess node '" + node.getName() + "' [" + node.getId() + "] has no incoming connection."));
+ }
+ if (subProcess.getTo() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "SubProcess node '" + node.getName() + "' [" + node.getId() + "] has no outgoing connection."));
+ }
+ if (subProcess.getProcessId() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "SubProcess node '" + node.getName() + "' [" + node.getId() + "] has no process id."));
+ }
+ } else if (node instanceof ActionNode) {
+ final ActionNode actionNode = (ActionNode) node;
+ if (actionNode.getFrom() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Action node '" + node.getName() + "' [" + node.getId() + "] has no incoming connection."));
+ }
+ if (actionNode.getTo() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Action node '" + node.getName() + "' [" + node.getId() + "] has no outgoing connection."));
+ }
+ if (actionNode.getAction() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Action node '" + node.getName() + "' [" + node.getId() + "] has no action."));
+ } else {
+ if (actionNode.getAction() instanceof DroolsConsequenceAction) {
+ DroolsConsequenceAction droolsAction = (DroolsConsequenceAction) actionNode.getAction();
+ String actionString = droolsAction.getConsequence();
+ if (actionString == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Action node '" + node.getName() + "' [" + node.getId() + "] has empty action."));
+ } else {
+ try {
+ ExpressionCompiler compiler = new ExpressionCompiler(actionString);
+ compiler.setVerifying(true);
+ ParserContext parserContext = new ParserContext();
+ //parserContext.setStrictTypeEnforcement(true);
+ compiler.compile(parserContext);
+ List<ErrorDetail> mvelErrors = parserContext.getErrorList();
+ if (mvelErrors != null) {
+ for (Iterator<ErrorDetail> iterator = mvelErrors.iterator(); iterator.hasNext(); ) {
+ ErrorDetail error = iterator.next();
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Action node '" + node.getName() + "' [" + node.getId() + "] has invalid action: " + error.getMessage() + "."));
+ }
+ }
+ } catch (Throwable t) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Action node '" + node.getName() + "' [" + node.getId() + "] has invalid action: " + t.getMessage() + "."));
+ }
+ }
+ }
+ }
+ } else if (node instanceof WorkItemNode) {
+ final WorkItemNode workItemNode = (WorkItemNode) node;
+ if (workItemNode.getFrom() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "WorkItem node '" + node.getName() + "' [" + node.getId() + "] has no incoming connection."));
+ }
+ if (workItemNode.getTo() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "WorkItem node '" + node.getName() + "' [" + node.getId() + "] has no outgoing connection."));
+ }
+ if (workItemNode.getWork() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "WorkItem node '" + node.getName() + "' [" + node.getId() + "] has no work specified."));
+ } else {
+ Work work = workItemNode.getWork();
+ if (work.getName() == null) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "WorkItem node '" + node.getName() + "' [" + node.getId() + "] has no work name."));
+ }
+ }
+ } else if (node instanceof CompositeNode) {
+ final CompositeNode compositeNode = (CompositeNode) node;
+ for (String inType: compositeNode.getLinkedIncomingNodes().keySet()) {
+ if (compositeNode.getIncomingConnections(inType).size() == 0) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Composite node '" + node.getName() + "' [" + node.getId() + "] has no incoming connection for type " + inType));
+ }
+ }
+ for (String outType: compositeNode.getLinkedOutgoingNodes().keySet()) {
+ if (compositeNode.getOutgoingConnections(outType).size() == 0) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Composite node '" + node.getName() + "' [" + node.getId() + "] has no outgoing connection for type " + outType));
+ }
+ }
+ validateNodes(compositeNode.getNodes(), errors, process);
+ }
+ }
+
+ }
+
+ private void checkAllNodesConnectedToStart(final JpdlProcess process,
+ final List<ProcessValidationError> errors) {
+ final Map<Node, Boolean> processNodes = new HashMap<Node, Boolean>();
+ final Node[] nodes = process.getNodes();
+ for (int i = 0; i < nodes.length; i++) {
+ final Node node = nodes[i];
+ processNodes.put(node, Boolean.FALSE);
+ }
+ Node startNode = process.getStart();
+ if (startNode != null) {
+ processNode(startNode, processNodes);
+ }
+ for ( final Iterator<Node> it = processNodes.keySet().iterator(); it.hasNext(); ) {
+ final Node node = it.next();
+ if (Boolean.FALSE.equals(processNodes.get(node))) {
+ errors.add(new ProcessValidationErrorImpl(process,
+ "Node '" + node.getName() + "' [" + node.getId() + "] has no connection to the start node."));
+ }
+ }
+ }
+
+ private void processNode(final Node node, final Map<Node, Boolean> nodes) {
+ if (!nodes.containsKey(node) ) {
+ throw new IllegalStateException("A process node is connected with a node that does not belong to the process.");
+ }
+ final Boolean prevValue = (Boolean) nodes.put(node, Boolean.TRUE);
+ if (prevValue == Boolean.FALSE) {
+ for (final Iterator<List<Connection>> it = node.getOutgoingConnections().values().iterator(); it.hasNext(); ) {
+ final List<Connection> list = it.next();
+ for (final Iterator<Connection> it2 = list.iterator(); it2.hasNext(); ) {
+ processNode(it2.next().getTo(), nodes);
+ }
+ }
+ }
+ }
+
+ public ProcessValidationError[] validateProcess(Process process) {
+ if (!(process instanceof JpdlProcess)) {
+ throw new IllegalArgumentException(
+ "This validator can only validate ruleflow processes!");
+ }
+ return validateProcess((JpdlProcess) process);
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/JpdlConnection.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/JpdlConnection.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/JpdlConnection.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,115 @@
+package org.drools.jpdl.core;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.workflow.core.Node;
+import org.drools.workflow.core.impl.ConnectionImpl;
+import org.jbpm.graph.def.Event;
+import org.jbpm.graph.def.ExceptionHandler;
+
+public class JpdlConnection extends ConnectionImpl {
+
+ private static final long serialVersionUID = 1L;
+
+ protected String condition;
+ private Map<String, Event> events;
+ private List<ExceptionHandler> exceptionHandlers;
+
+ public JpdlConnection(Node from, String fromType, Node to, String toType) {
+ super(from, fromType, to, toType);
+ }
+
+ public Map<String, Event> getEvents() {
+ return events;
+ }
+
+ public boolean hasEvents() {
+ return (events != null) && (events.size() > 0);
+ }
+
+ public Event getEvent(String eventType) {
+ Event event = null;
+ if (events != null) {
+ event = (Event) events.get(eventType);
+ }
+ return event;
+ }
+
+ public boolean hasEvent(String eventType) {
+ boolean hasEvent = false;
+ if (events != null) {
+ hasEvent = events.containsKey(eventType);
+ }
+ return hasEvent;
+ }
+
+ public Event addEvent(Event event) {
+ if (event == null) {
+ throw new IllegalArgumentException(
+ "can't add a null event to a graph element");
+ }
+ if (event.getEventType() == null) {
+ throw new IllegalArgumentException(
+ "can't add an event without an eventType to a graph element");
+ }
+ if (events == null) {
+ events = new HashMap<String, Event>();
+ }
+ events.put(event.getEventType(), event);
+ return event;
+ }
+
+ public Event removeEvent(Event event) {
+ Event removedEvent = null;
+ if (event == null) {
+ throw new IllegalArgumentException(
+ "can't remove a null event from a graph element");
+ }
+ if (event.getEventType() == null) {
+ throw new IllegalArgumentException(
+ "can't remove an event without an eventType from a graph element");
+ }
+ if (events != null) {
+ removedEvent = (Event) events.remove(event.getEventType());
+ }
+ return removedEvent;
+ }
+
+ public List getExceptionHandlers() {
+ return exceptionHandlers;
+ }
+
+ public ExceptionHandler addExceptionHandler(ExceptionHandler exceptionHandler) {
+ if (exceptionHandler == null) {
+ throw new IllegalArgumentException(
+ "can't add a null exceptionHandler to a connection");
+ }
+ if (exceptionHandlers == null) {
+ exceptionHandlers = new ArrayList<ExceptionHandler>();
+ }
+ exceptionHandlers.add(exceptionHandler);
+ return exceptionHandler;
+ }
+
+ public void removeExceptionHandler(ExceptionHandler exceptionHandler) {
+ if (exceptionHandler == null) {
+ throw new IllegalArgumentException(
+ "can't remove a null exceptionHandler from a connection");
+ }
+ if (exceptionHandlers != null) {
+ exceptionHandlers.remove(exceptionHandler);
+ }
+ }
+
+ public String getCondition() {
+ return condition;
+ }
+
+ public void setCondition(String condition) {
+ this.condition = condition;
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/JpdlProcess.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/JpdlProcess.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/JpdlProcess.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,44 @@
+package org.drools.jpdl.core;
+
+import org.drools.jpdl.core.node.StartState;
+import org.drools.process.core.context.variable.VariableScope;
+import org.drools.workflow.core.Node;
+import org.drools.workflow.core.impl.WorkflowProcessImpl;
+
+public class JpdlProcess extends WorkflowProcessImpl {
+
+ public static final String JPDL_TYPE = "jPDL";
+
+ private static final long serialVersionUID = 1L;
+
+ private Node startState;
+
+ public JpdlProcess() {
+ setType(JPDL_TYPE);
+ VariableScope variableScope = new VariableScope();
+ addContext(variableScope);
+ setDefaultContext(variableScope);
+ }
+
+ public void setStartState(Node startState) {
+ this.startState = startState;
+ }
+
+ public Node getStart() {
+ if (startState != null) {
+ return startState;
+ }
+ Node[] nodes = getNodes();
+ for (int i = 0; i < nodes.length; i++) {
+ if (nodes[i] instanceof StartState) {
+ return (StartState) nodes[i];
+ }
+ }
+ return null;
+ }
+
+ public VariableScope getVariableScope() {
+ return (VariableScope) getDefaultContext(VariableScope.VARIABLE_SCOPE);
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/Decision.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/Decision.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/Decision.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,40 @@
+package org.drools.jpdl.core.node;
+
+import java.util.List;
+
+import org.jbpm.graph.node.DecisionCondition;
+import org.jbpm.instantiation.Delegation;
+
+public class Decision extends JpdlNode {
+
+ private static final long serialVersionUID = 1L;
+
+ private List<DecisionCondition> decisionConditions;
+ private Delegation decisionDelegation;
+ private String decisionExpression;
+
+ public List<DecisionCondition> getDecisionConditions() {
+ return decisionConditions;
+ }
+
+ public void setDecisionConditions(List<DecisionCondition> decisionConditions) {
+ this.decisionConditions = decisionConditions;
+ }
+
+ public Delegation getDecisionDelegation() {
+ return decisionDelegation;
+ }
+
+ public void setDecisionDelegation(Delegation decisionDelegation) {
+ this.decisionDelegation = decisionDelegation;
+ }
+
+ public String getDecisionExpression() {
+ return decisionExpression;
+ }
+
+ public void setDecisionExpression(String decisionExpression) {
+ this.decisionExpression = decisionExpression;
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/EndState.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/EndState.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/EndState.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,19 @@
+package org.drools.jpdl.core.node;
+
+import org.drools.workflow.core.Connection;
+
+public class EndState extends JpdlNode {
+
+ private static final long serialVersionUID = 1L;
+
+ public void validateAddOutgoingConnection(final String type, final Connection connection) {
+ throw new UnsupportedOperationException(
+ "An end state does not have an outgoing connection!");
+ }
+
+ public void validateRemoveOutgoingConnection(final String type, final Connection connection) {
+ throw new UnsupportedOperationException(
+ "An end state does not have an outgoing connection!");
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/Fork.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/Fork.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/Fork.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,19 @@
+package org.drools.jpdl.core.node;
+
+import org.jbpm.graph.action.Script;
+
+public class Fork extends JpdlNode {
+
+ private static final long serialVersionUID = 1L;
+
+ private Script script;
+
+ public Script getScript() {
+ return script;
+ }
+
+ public void setScript(Script script) {
+ this.script = script;
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/Join.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/Join.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/Join.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,57 @@
+package org.drools.jpdl.core.node;
+
+import java.util.Collection;
+
+import org.jbpm.graph.action.Script;
+
+public class Join extends JpdlNode {
+
+ private static final long serialVersionUID = 1L;
+
+ private String parentLockMode;
+ private boolean isDiscriminator = false;
+ private Collection<String> tokenNames = null;
+ private Script script = null;
+ private int nOutOfM = -1;
+
+ public String getParentLockMode() {
+ return parentLockMode;
+ }
+
+ public void setParentLockMode(String parentLockMode) {
+ this.parentLockMode = parentLockMode;
+ }
+
+ public boolean isDiscriminator() {
+ return isDiscriminator;
+ }
+
+ public void setDiscriminator(boolean isDiscriminator) {
+ this.isDiscriminator = isDiscriminator;
+ }
+
+ public Collection<String> getTokenNames() {
+ return tokenNames;
+ }
+
+ public void setTokenNames(Collection<String> tokenNames) {
+ this.tokenNames = tokenNames;
+ }
+
+ public Script getScript() {
+ return script;
+ }
+
+ public void setScript(Script script) {
+ this.script = script;
+ }
+
+ public int getNOutOfM() {
+ return nOutOfM;
+ }
+
+ public void setNOutOfM(int outOfM) {
+ nOutOfM = outOfM;
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/JpdlNode.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/JpdlNode.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/JpdlNode.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,131 @@
+package org.drools.jpdl.core.node;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.process.core.context.exception.ExceptionScope;
+import org.drools.workflow.core.Connection;
+import org.drools.workflow.core.impl.NodeImpl;
+import org.jbpm.graph.def.Action;
+import org.jbpm.graph.def.Event;
+import org.jbpm.graph.def.ExceptionHandler;
+
+public class JpdlNode extends NodeImpl {
+
+ private static final long serialVersionUID = 1L;
+
+ private Map<String, Event> events;
+ private Action action;
+
+ public JpdlNode() {
+ setContext(ExceptionScope.EXCEPTION_SCOPE, new ExceptionScope());
+ }
+
+ public Action getAction() {
+ return action;
+ }
+
+ public void setAction(Action action) {
+ this.action = action;
+ }
+
+ public Connection getOutgoingConnection(String type) {
+ List<Connection> connections = getOutgoingConnections(type);
+ if (connections == null || connections.size() == 0) {
+ return null;
+ }
+ return connections.get(0);
+ }
+
+ public Map<String, Event> getEvents() {
+ return events;
+ }
+
+ public boolean hasEvents() {
+ return (events != null) && (events.size() > 0);
+ }
+
+ public Event getEvent(String eventType) {
+ Event event = null;
+ if (events != null) {
+ event = (Event) events.get(eventType);
+ }
+ return event;
+ }
+
+ public boolean hasEvent(String eventType) {
+ boolean hasEvent = false;
+ if (events != null) {
+ hasEvent = events.containsKey(eventType);
+ }
+ return hasEvent;
+ }
+
+ public Event addEvent(Event event) {
+ if (event == null) {
+ throw new IllegalArgumentException(
+ "can't add a null event to a graph element");
+ }
+ if (event.getEventType() == null) {
+ throw new IllegalArgumentException(
+ "can't add an event without an eventType to a graph element");
+ }
+ if (events == null) {
+ events = new HashMap<String, Event>();
+ }
+ events.put(event.getEventType(), event);
+ return event;
+ }
+
+ public Event removeEvent(Event event) {
+ Event removedEvent = null;
+ if (event == null) {
+ throw new IllegalArgumentException(
+ "can't remove a null event from a graph element");
+ }
+ if (event.getEventType() == null) {
+ throw new IllegalArgumentException(
+ "can't remove an event without an eventType from a graph element");
+ }
+ if (events != null) {
+ removedEvent = (Event) events.remove(event.getEventType());
+ }
+ return removedEvent;
+ }
+
+ public ExceptionScope getExceptionScope() {
+ return (ExceptionScope) getContext(ExceptionScope.EXCEPTION_SCOPE);
+ }
+
+ public ExceptionHandler addExceptionHandler(ExceptionHandler exceptionHandler) {
+ if (exceptionHandler == null) {
+ throw new IllegalArgumentException(
+ "can't add a null exceptionHandler to a graph element");
+ }
+ getExceptionScope().setExceptionHandler(
+ exceptionHandler.getExceptionClassName(),
+ new JpdlExceptionHandler(exceptionHandler));
+ return exceptionHandler;
+ }
+
+ public void removeExceptionHandler(ExceptionHandler exceptionHandler) {
+ if (exceptionHandler == null) {
+ throw new IllegalArgumentException(
+ "can't remove a null exceptionHandler from an graph element");
+ }
+ getExceptionScope().removeExceptionHandler(
+ exceptionHandler.getExceptionClassName());
+ }
+
+ private class JpdlExceptionHandler implements org.drools.process.core.context.exception.ExceptionHandler {
+ private ExceptionHandler exceptionHandler;
+ private JpdlExceptionHandler(ExceptionHandler exceptionHandler) {
+ this.exceptionHandler = exceptionHandler;
+ }
+ public ExceptionHandler getExceptionHandler() {
+ return exceptionHandler;
+ }
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/MailNode.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/MailNode.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/MailNode.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,53 @@
+package org.drools.jpdl.core.node;
+
+public class MailNode extends JpdlNode {
+
+ private static final long serialVersionUID = 1L;
+
+ private String template;
+ private String actors;
+ private String to;
+ private String subject;
+ private String text;
+
+ public String getTemplate() {
+ return template;
+ }
+
+ public void setTemplate(String template) {
+ this.template = template;
+ }
+
+ public String getActors() {
+ return actors;
+ }
+
+ public void setActors(String actors) {
+ this.actors = actors;
+ }
+
+ public String getTo() {
+ return to;
+ }
+
+ public void setTo(String to) {
+ this.to = to;
+ }
+
+ public String getSubject() {
+ return subject;
+ }
+
+ public void setSubject(String subject) {
+ this.subject = subject;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/ProcessState.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/ProcessState.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/ProcessState.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,30 @@
+package org.drools.jpdl.core.node;
+
+import java.util.Set;
+
+import org.jbpm.context.def.VariableAccess;
+
+public class ProcessState extends JpdlNode {
+
+ private static final long serialVersionUID = 1L;
+
+ private Set<VariableAccess> variableAccesses;
+ private String subProcessName;
+
+ public Set<VariableAccess> getVariableAccesses() {
+ return variableAccesses;
+ }
+
+ public void setVariableAccesses(Set<VariableAccess> variableAccesses) {
+ this.variableAccesses = variableAccesses;
+ }
+
+ public String getSubProcessName() {
+ return subProcessName;
+ }
+
+ public void setSubProcessName(String subProcessName) {
+ this.subProcessName = subProcessName;
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/StartState.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/StartState.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/StartState.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,19 @@
+package org.drools.jpdl.core.node;
+
+import org.drools.workflow.core.Connection;
+
+public class StartState extends JpdlNode {
+
+ private static final long serialVersionUID = 1L;
+
+ public void validateAddIncomingConnection(final String type, final Connection connection) {
+ throw new UnsupportedOperationException(
+ "A start state does not have an incoming connection!");
+ }
+
+ public void validateRemoveIncomingConnection(final String type, final Connection connection) {
+ throw new UnsupportedOperationException(
+ "A start state does not have an incoming connection!");
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/State.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/State.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/State.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,7 @@
+package org.drools.jpdl.core.node;
+
+public class State extends JpdlNode {
+
+ private static final long serialVersionUID = 1L;
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/TaskNode.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/TaskNode.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/core/node/TaskNode.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,48 @@
+package org.drools.jpdl.core.node;
+
+import java.util.Set;
+
+import org.jbpm.taskmgmt.def.Task;
+
+public class TaskNode extends JpdlNode {
+
+ private static final long serialVersionUID = 1L;
+
+ private Set<Task> tasks;
+ private int signal = org.jbpm.graph.node.TaskNode.SIGNAL_LAST;
+ private boolean createTasks = true;
+ private boolean endTasks = false;
+
+ public Set<Task> getTasks() {
+ return tasks;
+ }
+
+ public void setTasks(Set<Task> tasks) {
+ this.tasks = tasks;
+ }
+
+ public int getSignal() {
+ return signal;
+ }
+
+ public void setSignal(int signal) {
+ this.signal = signal;
+ }
+
+ public boolean isCreateTasks() {
+ return createTasks;
+ }
+
+ public void setCreateTasks(boolean createTasks) {
+ this.createTasks = createTasks;
+ }
+
+ public boolean isEndTasks() {
+ return endTasks;
+ }
+
+ public void setEndTasks(boolean endTasks) {
+ this.endTasks = endTasks;
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/JpdlProcessInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/JpdlProcessInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/JpdlProcessInstance.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,18 @@
+package org.drools.jpdl.instance;
+
+import org.drools.jpdl.core.JpdlProcess;
+import org.drools.workflow.instance.impl.WorkflowProcessInstanceImpl;
+
+public class JpdlProcessInstance extends WorkflowProcessInstanceImpl {
+
+ private static final long serialVersionUID = 1L;
+
+ public JpdlProcess getJpdlProcess() {
+ return (JpdlProcess) getProcess();
+ }
+
+ public void internalStart() {
+ getNodeInstance( getJpdlProcess().getStart() ).trigger( null, null );
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/JpdlProcessInstanceFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/JpdlProcessInstanceFactory.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/JpdlProcessInstanceFactory.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,26 @@
+package org.drools.jpdl.instance;
+
+import java.io.Externalizable;
+import java.io.ObjectOutput;
+import java.io.IOException;
+import java.io.ObjectInput;
+
+import org.drools.process.instance.ProcessInstance;
+import org.drools.process.instance.ProcessInstanceFactory;
+
+public class JpdlProcessInstanceFactory implements ProcessInstanceFactory, Externalizable {
+
+ private static final long serialVersionUID = 1L;
+
+ public ProcessInstance createProcessInstance() {
+ return new JpdlProcessInstance();
+ }
+
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ }
+
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/DecisionInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/DecisionInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/DecisionInstance.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,68 @@
+package org.drools.jpdl.instance.node;
+
+import org.drools.jpdl.core.node.Decision;
+import org.drools.workflow.instance.NodeInstance;
+import org.jbpm.JbpmException;
+import org.jbpm.graph.node.DecisionCondition;
+import org.jbpm.graph.node.DecisionHandler;
+import org.jbpm.instantiation.Delegation;
+import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator;
+
+public class DecisionInstance extends JpdlNodeInstance {
+
+ private static final long serialVersionUID = 1L;
+
+ public Decision getDecision() {
+ return (Decision) getNode();
+ }
+
+ public void execute(NodeInstance from, String type) {
+ String transitionName = null;
+ try {
+ Delegation decisionDelegation = getDecision().getDecisionDelegation();
+ if (decisionDelegation != null) {
+ DecisionHandler decisionHandler = (DecisionHandler) decisionDelegation.instantiate();
+ transitionName = decisionHandler.decide(new JpdlExecutionContext());
+ } else if (getDecision().getDecisionExpression() != null) {
+ String decisionExpression = getDecision().getDecisionExpression();
+ Object result = JbpmExpressionEvaluator.evaluate(
+ decisionExpression, new JpdlExecutionContext());
+ if (result == null) {
+ throw new JbpmException("decision expression '" +
+ decisionExpression + "' returned null");
+ }
+ transitionName = result.toString();
+ } else if (getDecision().getDecisionConditions() != null) {
+ for (DecisionCondition decisionCondition: getDecision().getDecisionConditions()) {
+ Object result = JbpmExpressionEvaluator.evaluate(
+ decisionCondition.getExpression(), new JpdlExecutionContext());
+ if (Boolean.TRUE.equals(result)) {
+ transitionName = decisionCondition.getTransitionName();
+ break;
+ }
+ }
+ } else {
+ // TODO
+ /*Iterator iter = leavingTransitions.iterator();
+ while (iter.hasNext() && (transition==null)) {
+ Transition candidate = (Transition) iter.next();
+ String conditionExpression = candidate.getCondition();
+ if (conditionExpression!=null) {
+ Object result = JbpmExpressionEvaluator.evaluate(conditionExpression, executionContext);
+ if (Boolean.TRUE.equals(result)) {
+ transition = candidate;
+ }
+ }
+ }*/
+ }
+ if (transitionName == null) {
+ leave();
+ } else {
+ leave(transitionName);
+ }
+ } catch (Exception exception) {
+ raiseException(exception);
+ }
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/EndStateInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/EndStateInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/EndStateInstance.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,14 @@
+package org.drools.jpdl.instance.node;
+
+import org.drools.process.instance.ProcessInstance;
+
+public class EndStateInstance extends JpdlNodeInstance {
+
+ private static final long serialVersionUID = 1L;
+
+ public void leave() {
+ getNodeInstanceContainer().removeNodeInstance(this);
+ getProcessInstance().setState(ProcessInstance.STATE_COMPLETED);
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/ForkInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/ForkInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/ForkInstance.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,48 @@
+package org.drools.jpdl.instance.node;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.drools.jpdl.core.node.Fork;
+import org.drools.workflow.instance.NodeInstance;
+import org.jbpm.JbpmException;
+import org.jbpm.graph.action.Script;
+
+public class ForkInstance extends JpdlNodeInstance {
+
+ private static final long serialVersionUID = 1L;
+
+ public Fork getFork() {
+ return (Fork) getNode();
+ }
+
+ public void execute(NodeInstance from, String type) {
+ Collection<String> transitionNames = null;
+ Script script = getFork().getScript();
+ if (script == null) {
+ transitionNames = getNode().getOutgoingConnections().keySet();
+ } else {
+ Map<String, Object> outputMap = null;
+ try {
+ outputMap = script.eval(new JpdlExecutionContext());
+ } catch (Exception e) {
+ this.raiseException(e);
+ }
+ if (outputMap.size() == 1) {
+ Object result = outputMap.values().iterator().next();
+ if (result instanceof Collection) {
+ transitionNames = (Collection<String>) result;
+ }
+ }
+ if (transitionNames == null) {
+ throw new JbpmException(
+ "script for fork '" + getNode().getName() +
+ "' should produce one collection (in one writable variable): " +
+ transitionNames);
+ }
+ }
+ for (String transitionName: transitionNames) {
+ leave(transitionName);
+ }
+ }
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/JoinInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/JoinInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/JoinInstance.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,104 @@
+package org.drools.jpdl.instance.node;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.drools.jpdl.core.node.Join;
+import org.drools.workflow.core.Connection;
+import org.drools.workflow.core.Node;
+import org.drools.workflow.instance.NodeInstance;
+import org.jbpm.graph.exe.Token;
+
+public class JoinInstance extends JpdlNodeInstance {
+
+ private static final long serialVersionUID = 1L;
+
+ private Map<Long, Integer> triggers = new HashMap<Long, Integer>();
+
+ public Join getJoin() {
+ return (Join) getNode();
+ }
+
+ public void execute(NodeInstance from, String type) {
+ if (getJoin().isDiscriminator()) {
+ leave();
+ } else {
+ // register trigger
+ Integer count = (Integer) this.triggers.get(type);
+ if (count == null) {
+ this.triggers.put(from.getNodeId(), 1);
+ } else {
+ this.triggers.put(from.getNodeId(), count.intValue() + 1);
+ }
+ // check whether we should leave node
+ if (getJoin().getTokenNames() != null) {
+ Collection<String> tokenNames = getJoin().getTokenNames();
+ // TODO: implement this
+// if (checkTriggers(tokenNames)) {
+// decreaseTriggers(tokenNames);
+// leave();
+// }
+ } else if (getJoin().getScript() != null) {
+ Object result = null;
+ try {
+ result = getJoin().getScript().eval((Token) null);
+ } catch (Exception e) {
+ this.raiseException(e);
+ }
+ if (result instanceof Collection) {
+ // TODO: implement this
+// Collection<String> runtimeTokenNames = (Collection<String>) result;
+// if (checkTriggers(runtimeTokenNames)) {
+// decreaseTriggers(runtimeTokenNames);
+// leave();
+// }
+ } else if (result instanceof Boolean) {
+ if ((Boolean) result) {
+ leave();
+ }
+ }
+ } else if (getJoin().getNOutOfM() != -1) {
+ if (triggers.size() >= getJoin().getNOutOfM()) {
+ resetAllTriggers();
+ leave();
+ }
+ } else {
+ // TODO this only works if all incoming connection paths were
+ // activated; fix this in cases where not all incoming connection
+ // paths were activated by letting the corresponding split transfer
+ // the exact number of triggered connections to this join
+ if (checkAllTriggers()) {
+ decreaseAllTriggers();
+ leave();
+ }
+ }
+ }
+ }
+
+ private boolean checkAllTriggers() {
+ for (Connection connection: getJoin().getIncomingConnections(Node.CONNECTION_DEFAULT_TYPE)) {
+ if (this.triggers.get(connection.getFrom().getId()) == null) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void decreaseAllTriggers() {
+ for (Connection connection: getJoin().getIncomingConnections(Node.CONNECTION_DEFAULT_TYPE)) {
+ final Integer count = (Integer) this.triggers.get( connection.getFrom().getId() );
+ if ( count.intValue() == 1 ) {
+ this.triggers.remove( connection.getFrom().getId() );
+ } else {
+ this.triggers.put( connection.getFrom().getId(),
+ count.intValue() - 1 );
+ }
+ }
+ }
+
+ private void resetAllTriggers() {
+ triggers.clear();
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/JpdlNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/JpdlNodeInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/JpdlNodeInstance.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,277 @@
+package org.drools.jpdl.instance.node;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.jpdl.core.JpdlConnection;
+import org.drools.jpdl.core.node.JpdlNode;
+import org.drools.process.core.context.exception.ExceptionScope;
+import org.drools.process.core.context.variable.VariableScope;
+import org.drools.process.core.timer.Timer;
+import org.drools.process.instance.ProcessInstance;
+import org.drools.process.instance.context.exception.ExceptionScopeInstance;
+import org.drools.process.instance.context.variable.VariableScopeInstance;
+import org.drools.process.instance.timer.TimerListener;
+import org.drools.workflow.core.Node;
+import org.drools.workflow.instance.NodeInstance;
+import org.drools.workflow.instance.impl.NodeInstanceImpl;
+import org.jbpm.JbpmException;
+import org.jbpm.calendar.BusinessCalendar;
+import org.jbpm.calendar.Duration;
+import org.jbpm.graph.def.Action;
+import org.jbpm.graph.def.DelegationException;
+import org.jbpm.graph.def.Event;
+import org.jbpm.graph.def.ExceptionHandler;
+import org.jbpm.graph.def.Transition;
+import org.jbpm.graph.exe.ExecutionContext;
+import org.jbpm.graph.exe.Token;
+import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator;
+import org.jbpm.scheduler.def.CancelTimerAction;
+import org.jbpm.scheduler.def.CreateTimerAction;
+
+public class JpdlNodeInstance extends NodeInstanceImpl implements TimerListener {
+
+ private static final long serialVersionUID = 1L;
+ private static final BusinessCalendar BUSINESS_CALENDAR = new BusinessCalendar();
+
+ private Map<Long, Action> timerActions = new HashMap<Long, Action>();
+ private Map<String, List<Timer>> timers = new HashMap<String, List<Timer>>();
+
+ public JpdlNode getJpdlNode() {
+ return (JpdlNode) getNode();
+ }
+
+ private Action getAction() {
+ return getJpdlNode().getAction();
+ }
+
+ public void internalTrigger(NodeInstance from, String type) {
+ fireEvent(Event.EVENTTYPE_NODE_ENTER);
+ execute(from, type);
+ }
+
+ public void execute(NodeInstance from, String type) {
+ Action action = getAction();
+ if (action != null) {
+ try {
+ action.execute(new JpdlExecutionContext());
+ } catch (Exception exception) {
+ raiseException(exception);
+ }
+ } else {
+ leave();
+ }
+ }
+
+ public void leave() {
+ if (getNode().getOutgoingConnections(Node.CONNECTION_DEFAULT_TYPE) != null) {
+ leave(Node.CONNECTION_DEFAULT_TYPE);
+ } else if (getNode().getOutgoingConnections().size() == 1) {
+ String type = getNode().getOutgoingConnections().keySet().iterator().next() ;
+ leave(type);
+ } else {
+ throw new IllegalArgumentException(
+ "Could not find default leave transition: " + this);
+ }
+ }
+
+ public void leave(String type) {
+ JpdlConnection connection = (JpdlConnection)
+ getJpdlNode().getOutgoingConnection(type);
+ if (connection == null) {
+ throw new JbpmException("transition '" + type
+ + "' is not a leaving transition of node '" + this + "'");
+ }
+ fireEvent(Event.EVENTTYPE_NODE_LEAVE);
+ getNodeInstanceContainer().removeNodeInstance(this);
+ Event event = connection.getEvent(Event.EVENTTYPE_TRANSITION);
+ if (event != null) {
+ List<Action> actions = event.getActions();
+ if (actions != null) {
+ for (Action action: actions) {
+ try {
+ action.execute(new JpdlExecutionContext());
+ } catch (Exception exception) {
+ boolean handled = false;
+ List<ExceptionHandler> exceptionHandlers = connection.getExceptionHandlers();
+ try {
+ for (ExceptionHandler exceptionHandler: exceptionHandlers) {
+ if (exceptionHandler.matches(exception)) {
+ exceptionHandler.handleException(new JpdlExecutionContext());
+ handled = true;
+ }
+ }
+ } catch (Exception e) {
+ exception = e;
+ }
+ if (!handled) {
+ if (exception instanceof JbpmException) {
+ throw (JbpmException) exception;
+ } else {
+ throw new DelegationException(exception, null);
+ }
+ }
+ }
+ }
+ }
+ }
+ String condition = connection.getCondition();
+ if (condition != null) {
+ Object result = JbpmExpressionEvaluator.evaluate(
+ condition, new JpdlExecutionContext());
+ if (result == null) {
+ throw new JbpmException("connection condition " + condition
+ + " evaluated to null");
+ } else if (!(result instanceof Boolean)) {
+ throw new JbpmException("connection condition " + condition
+ + " evaluated to non-boolean: "
+ + result.getClass().getName());
+ } else if (!((Boolean) result).booleanValue()) {
+ throw new JbpmException("connection condition " + condition
+ + " evaluated to 'false'");
+ }
+ }
+ getNodeInstanceContainer().getNodeInstance(connection.getTo())
+ .trigger(this, connection.getToType());
+ }
+
+ public void fireEvent(String eventType) {
+ fireEvent(eventType, new JpdlExecutionContext());
+ }
+
+ public void fireEvent(String eventType, ExecutionContext executionContext) {
+ Event event = getJpdlNode().getEvent(eventType);
+ if (event != null) {
+ executeActions(event.getActions(), executionContext);
+ }
+ // TODO runtime actions?
+ }
+
+ public void executeActions(List<Action> actions, ExecutionContext executionContext) {
+ if (actions != null) {
+ for (Action action: actions) {
+ executeAction(action, executionContext);
+ }
+ }
+ }
+
+ public void executeAction(Action action, ExecutionContext executionContext) {
+ if (action instanceof CreateTimerAction) {
+ CreateTimerAction createTimerAction = (CreateTimerAction) action;
+ String timerName = createTimerAction.getTimerName();
+ Timer timer = new Timer();
+ long delay = BUSINESS_CALENDAR.add(new Date(0),
+ new Duration(createTimerAction.getDueDate())).getTime();
+ timer.setDelay(delay);
+ if (createTimerAction.getRepeat() != null) {
+ long period = BUSINESS_CALENDAR.add(new Date(0),
+ new Duration(createTimerAction.getRepeat())).getTime();
+ timer.setPeriod(period);
+ }
+ if (timerActions.isEmpty()) {
+ registerTimerListener();
+ }
+ getProcessInstance().getWorkingMemory().getTimerManager()
+ .registerTimer(timer, getProcessInstance());
+ timerActions.put(timer.getId(), createTimerAction.getTimerAction());
+ List<Timer> timerList = timers.get(timerName);
+ if (timerList == null) {
+ timerList = new ArrayList<Timer>();
+ timers.put(timerName, timerList);
+ }
+ timerList.add(timer);
+ } else if (action instanceof CancelTimerAction) {
+ String timerName = ((CancelTimerAction) action).getTimerName();
+ List<Timer> timerList = timers.get(timerName);
+ if (timerList != null) {
+ for (Timer timer: timerList) {
+ timerActions.remove(timer.getId());
+ getProcessInstance().getWorkingMemory().getTimerManager()
+ .cancelTimer(timer);
+ }
+ timers.remove(timerName);
+ if (timerActions.isEmpty()) {
+ removeTimerListener();
+ }
+ }
+ } else {
+ try {
+ action.execute(executionContext);
+ } catch (Exception exception) {
+ raiseException(exception);
+ }
+ }
+ }
+
+ public void raiseException(Throwable exception) throws DelegationException {
+ Class<?> clazz = exception.getClass();
+ while (clazz != null) {
+ ExceptionScopeInstance exceptionScopeInstance = (ExceptionScopeInstance)
+ resolveContextInstance(ExceptionScope.EXCEPTION_SCOPE, clazz.getName());
+ if (exceptionScopeInstance != null) {
+ exceptionScopeInstance.handleException(clazz.getName(), exception);
+ return;
+ }
+ clazz = clazz.getSuperclass();
+ }
+ if (exception instanceof JbpmException) {
+ throw (JbpmException) exception;
+ } else {
+ throw new DelegationException(exception, null);
+ }
+ }
+
+ public void registerTimerListener() {
+ getProcessInstance().addTimerListener(this);
+ }
+
+ public void removeTimerListener() {
+ getProcessInstance().removeTimerListener(this);
+ }
+
+ public void timerTriggered(Timer timer) {
+ timerTriggered(timer, new JpdlExecutionContext());
+ }
+
+ protected void timerTriggered(Timer timer, ExecutionContext executionContext) {
+ Action action = timerActions.get(timer.getId());
+ if (action != null) {
+ executeAction(action, executionContext);
+ }
+ }
+
+ public class JpdlExecutionContext extends ExecutionContext {
+ public JpdlExecutionContext() {
+ super((Token) null);
+ }
+ public void leaveNode() {
+ leave();
+ }
+ public void leaveNode(String transitionName) {
+ leave(transitionName);
+ }
+ public void leaveNode(Transition transition) {
+ leaveNode(transition.getName());
+ }
+ public void setVariable(String name, Object value) {
+ VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
+ resolveContextInstance(VariableScope.VARIABLE_SCOPE, name);
+ variableScopeInstance.setVariable(name, value);
+ }
+ public Object getVariable(String name) {
+ VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
+ resolveContextInstance(VariableScope.VARIABLE_SCOPE, name);
+ return variableScopeInstance.getVariable(name);
+ }
+ public ProcessInstance getDroolsProcessInstance() {
+ return JpdlNodeInstance.this.getProcessInstance();
+ }
+ public NodeInstance getDroolsNodeInstance() {
+ return JpdlNodeInstance.this;
+ }
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/MailNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/MailNodeInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/MailNodeInstance.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,31 @@
+package org.drools.jpdl.instance.node;
+
+import org.drools.jpdl.core.node.MailNode;
+import org.drools.process.instance.WorkItemManager;
+import org.drools.process.instance.impl.WorkItemImpl;
+import org.drools.workflow.instance.NodeInstance;
+
+public class MailNodeInstance extends JpdlNodeInstance {
+
+ private static final long serialVersionUID = 1L;
+
+ public MailNode getMailNode() {
+ return (MailNode) getNode();
+ }
+
+ public void execute(NodeInstance from, String type) {
+ MailNode mailNode = getMailNode();
+ WorkItemManager workItemManager = getProcessInstance().getWorkingMemory().getWorkItemManager();
+ WorkItemImpl workItem = new WorkItemImpl();
+ workItem.setName("JpdlEmail");
+ workItem.setProcessInstanceId(getProcessInstance().getId());
+ workItem.setParameter("template", mailNode.getTemplate());
+ workItem.setParameter("actors", mailNode.getActors());
+ workItem.setParameter("to", mailNode.getTo());
+ workItem.setParameter("subject", mailNode.getSubject());
+ workItem.setParameter("text", mailNode.getText());
+ workItemManager.internalExecuteWorkItem(workItem);
+ leave();
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/ProcessStateInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/ProcessStateInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/ProcessStateInstance.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,136 @@
+package org.drools.jpdl.instance.node;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.drools.WorkingMemory;
+import org.drools.event.RuleFlowCompletedEvent;
+import org.drools.event.RuleFlowEventListener;
+import org.drools.event.RuleFlowGroupActivatedEvent;
+import org.drools.event.RuleFlowGroupDeactivatedEvent;
+import org.drools.event.RuleFlowNodeTriggeredEvent;
+import org.drools.event.RuleFlowStartedEvent;
+import org.drools.jpdl.core.node.ProcessState;
+import org.drools.process.core.context.variable.VariableScope;
+import org.drools.process.instance.context.variable.VariableScopeInstance;
+import org.drools.workflow.instance.NodeInstance;
+import org.jbpm.context.def.VariableAccess;
+import org.jbpm.graph.def.Event;
+
+public class ProcessStateInstance extends JpdlNodeInstance implements RuleFlowEventListener {
+
+ private static final long serialVersionUID = 1L;
+
+ private long processInstanceId;
+
+ public ProcessState getProcessState() {
+ return (ProcessState) getNode();
+ }
+
+ public void execute(NodeInstance from, String type) {
+ Map<String, Object> parameters = null;
+ Set<VariableAccess> variableAccesses = getProcessState().getVariableAccesses();
+ if ((variableAccesses != null) && (!variableAccesses.isEmpty())) {
+ parameters = new HashMap<String, Object>();
+ // TODO: transient variables ?
+ for (VariableAccess variableAccess : variableAccesses) {
+ if (variableAccess.isReadable()) {
+ String variableName = variableAccess.getVariableName();
+ VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
+ resolveContextInstance(VariableScope.VARIABLE_SCOPE, variableName);
+ Object value = variableScopeInstance.getVariable(variableName);
+ if (value != null) {
+ String mappedName = variableAccess.getMappedName();
+ parameters.put(mappedName, value);
+ }
+ }
+ }
+ }
+ addEventListeners();
+ processInstanceId = getProcessInstance().getWorkingMemory()
+ .startProcess(getProcessState().getSubProcessName(), parameters).getId();
+ fireEvent(Event.EVENTTYPE_SUBPROCESS_CREATED);
+ }
+
+ public void addEventListeners() {
+ getProcessInstance().getWorkingMemory().addEventListener(this);
+ }
+
+ public void removeEventListeners() {
+ getProcessInstance().getWorkingMemory().removeEventListener(this);
+ }
+
+ public void afterRuleFlowCompleted(RuleFlowCompletedEvent event,
+ WorkingMemory workingMemory) {
+ if ( event.getProcessInstance().getId() == processInstanceId ) {
+ removeEventListeners();
+ Set<VariableAccess> variableAccesses = getProcessState().getVariableAccesses();
+ if ((variableAccesses != null) && (!variableAccesses.isEmpty())) {
+
+ for (VariableAccess variableAccess: variableAccesses) {
+ if (variableAccess.isWritable()) {
+ String mappedName = variableAccess.getMappedName();
+ VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
+ event.getProcessInstance().getContextInstance(VariableScope.VARIABLE_SCOPE);
+ Object value = variableScopeInstance.getVariable(mappedName);
+ if (value != null) {
+ String variableName = variableAccess.getVariableName();
+ variableScopeInstance = (VariableScopeInstance)
+ resolveContextInstance(VariableScope.VARIABLE_SCOPE, mappedName);
+ variableScopeInstance.setVariable(variableName, value);
+ }
+ }
+ }
+ }
+ fireEvent(Event.EVENTTYPE_SUBPROCESS_END);
+ leave();
+ }
+ }
+
+ public void afterRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event,
+ WorkingMemory workingMemory) {
+ // Do nothing
+ }
+
+ public void afterRuleFlowGroupDeactivated(
+ RuleFlowGroupDeactivatedEvent event, WorkingMemory workingMemory) {
+ // Do nothing
+ }
+
+ public void afterRuleFlowNodeTriggered(RuleFlowNodeTriggeredEvent event,
+ WorkingMemory workingMemory) {
+ // Do nothing
+ }
+
+ public void afterRuleFlowStarted(RuleFlowStartedEvent event,
+ WorkingMemory workingMemory) {
+ // Do nothing
+ }
+
+ public void beforeRuleFlowCompleted(RuleFlowCompletedEvent event,
+ WorkingMemory workingMemory) {
+ // Do nothing
+ }
+
+ public void beforeRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event,
+ WorkingMemory workingMemory) {
+ // Do nothing
+ }
+
+ public void beforeRuleFlowGroupDeactivated(
+ RuleFlowGroupDeactivatedEvent event, WorkingMemory workingMemory) {
+ // Do nothing
+ }
+
+ public void beforeRuleFlowNodeTriggered(RuleFlowNodeTriggeredEvent event,
+ WorkingMemory workingMemory) {
+ // Do nothing
+ }
+
+ public void beforeRuleFlowStarted(RuleFlowStartedEvent event,
+ WorkingMemory workingMemory) {
+ // Do nothing
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/StartStateInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/StartStateInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/StartStateInstance.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,7 @@
+package org.drools.jpdl.instance.node;
+
+public class StartStateInstance extends JpdlNodeInstance {
+
+ private static final long serialVersionUID = 1L;
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/StateInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/StateInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/StateInstance.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,13 @@
+package org.drools.jpdl.instance.node;
+
+import org.drools.workflow.instance.NodeInstance;
+
+public class StateInstance extends JpdlNodeInstance {
+
+ private static final long serialVersionUID = 1L;
+
+ public void execute(NodeInstance from, String type) {
+ // Do nothing
+ }
+
+}
\ No newline at end of file
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/TaskNodeInstance.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/TaskNodeInstance.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/instance/node/TaskNodeInstance.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,319 @@
+package org.drools.jpdl.instance.node;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import org.drools.jpdl.core.node.TaskNode;
+import org.drools.process.core.context.swimlane.SwimlaneContext;
+import org.drools.process.core.context.variable.VariableScope;
+import org.drools.process.instance.WorkItem;
+import org.drools.process.instance.WorkItemListener;
+import org.drools.process.instance.WorkItemManager;
+import org.drools.process.instance.context.swimlane.SwimlaneContextInstance;
+import org.drools.process.instance.context.variable.VariableScopeInstance;
+import org.drools.process.instance.impl.WorkItemImpl;
+import org.drools.workflow.instance.NodeInstance;
+import org.jbpm.JbpmException;
+import org.jbpm.calendar.BusinessCalendar;
+import org.jbpm.calendar.Duration;
+import org.jbpm.context.def.VariableAccess;
+import org.jbpm.graph.def.Event;
+import org.jbpm.instantiation.Delegation;
+import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator;
+import org.jbpm.taskmgmt.def.Task;
+import org.jbpm.taskmgmt.def.TaskController;
+
+public class TaskNodeInstance extends JpdlNodeInstance implements WorkItemListener {
+
+ private static final long serialVersionUID = 1L;
+
+ private List<WorkItemImpl> workItems = new ArrayList<WorkItemImpl>();
+
+ public TaskNode getTaskNode() {
+ return (TaskNode) getNode();
+ }
+
+ public void execute(NodeInstance from, String type) {
+ Set<Task> tasks = getTaskNode().getTasks();
+ if ((getTaskNode().isCreateTasks()) && (tasks != null)) {
+ addEventListeners();
+ for (Task task: tasks) {
+ if (evaluateTaskCondition(task.getCondition())) {
+ WorkItemManager workItemManager = getProcessInstance().getWorkingMemory().getWorkItemManager();
+ WorkItemImpl workItem = new WorkItemImpl();
+ workItem.setName("JpdlTask");
+ workItem.setProcessInstanceId(getProcessInstance().getId());
+ workItem.setParameter("name", task.getName());
+ String description = task.getDescription();
+ workItem.setParameter("signalling", task.isSignalling());
+ workItem.setParameter("blocking", task.isBlocking());
+ if ((description != null) && (description.indexOf("#{") != -1)) {
+ Object result = JbpmExpressionEvaluator.evaluate(
+ description, new JpdlExecutionContext());
+ if (result != null) {
+ description = result.toString();
+ }
+ }
+ workItem.setParameter("Description", description);
+ initializeVariables(workItem, task);
+ if (task.getDueDate() != null) {
+ BusinessCalendar businessCalendar = new BusinessCalendar();
+ workItem.setParameter("dueDate",
+ businessCalendar.add(new Date(), new Duration(task.getDueDate())));
+ }
+ if (task.getSwimlane() != null) {
+ String swimlaneName = task.getSwimlane().getName();
+ SwimlaneContextInstance swimlaneContextInstance = (SwimlaneContextInstance)
+ resolveContextInstance(SwimlaneContext.SWIMLANE_SCOPE, swimlaneName);
+ String actorId = swimlaneContextInstance.getActorId(swimlaneName);
+ if (actorId == null) {
+ actorId = assignTask(task);
+ }
+ workItem.setParameter("ActorId", actorId);
+ }
+ workItems.add(workItem);
+ Event event = task.getEvent(Event.EVENTTYPE_TASK_CREATE);
+ if (event != null) {
+ // TODO this doesn't take event handlers of task itself
+ // into account
+ executeActions(event.getActions(), new JpdlTaskExecutionContext(task));
+ }
+ workItemManager.internalExecuteWorkItem(workItem);
+ }
+ }
+ }
+ boolean continueExecution = false;
+ switch (getTaskNode().getSignal()) {
+ case org.jbpm.graph.node.TaskNode.SIGNAL_UNSYNCHRONIZED:
+ continueExecution = true;
+ break;
+ case org.jbpm.graph.node.TaskNode.SIGNAL_FIRST_WAIT:
+ case org.jbpm.graph.node.TaskNode.SIGNAL_LAST_WAIT:
+ case org.jbpm.graph.node.TaskNode.SIGNAL_NEVER:
+ continueExecution = false;
+ break;
+ case org.jbpm.graph.node.TaskNode.SIGNAL_FIRST:
+ case org.jbpm.graph.node.TaskNode.SIGNAL_LAST:
+ continueExecution = !hasSignallingWorkItems();
+ }
+ if (continueExecution) {
+ leave();
+ }
+ }
+
+ private boolean evaluateTaskCondition(String condition) {
+ if (condition == null) {
+ return true;
+ }
+ Object result = JbpmExpressionEvaluator.evaluate(
+ condition, new JpdlExecutionContext());
+ if (Boolean.TRUE.equals(result)) {
+ return true;
+ }
+ return false;
+ }
+
+ private void initializeVariables(WorkItemImpl workItem, Task task) {
+ TaskController taskController = task.getTaskController();
+ if (taskController != null) {
+ Delegation taskControllerDelegation = taskController.getTaskControllerDelegation();
+ if (taskControllerDelegation != null) {
+ // TODO: delegation (API mismatch!)
+ } else {
+ List<VariableAccess> variableAccesses = taskController.getVariableAccesses();
+ if (variableAccesses != null) {
+ for (VariableAccess variableAccess: variableAccesses) {
+ String mappedName = variableAccess.getMappedName();
+ if (variableAccess.isReadable()) {
+ String variableName = variableAccess.getVariableName();
+ VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
+ resolveContextInstance(VariableScope.VARIABLE_SCOPE, variableName);
+ Object value = variableScopeInstance.getVariable(variableName);
+ workItem.setParameter(mappedName, value);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private String assignTask(Task task) {
+ Event event = task.getEvent(Event.EVENTTYPE_TASK_ASSIGN);
+ if (event != null) {
+ executeActions(event.getActions(), new JpdlTaskExecutionContext(task));
+ }
+ if (task.getActorIdExpression() != null) {
+ return resolveActor(task.getActorIdExpression());
+ } else if (task.getSwimlane().getActorIdExpression() != null) {
+ return resolveActor(task.getSwimlane().getActorIdExpression());
+ }
+ // TODO support other assignment types
+ return null;
+ }
+
+ private String resolveActor(String expression) {
+ Object result = JbpmExpressionEvaluator.evaluate(expression, new JpdlExecutionContext());
+ if (result == null) {
+ throw new JbpmException("actor-id expression '" + expression + "' returned null");
+ }
+ if (result instanceof String) {
+ return (String) result;
+ } else {
+ throw new JbpmException(
+ "actor-id expression '" + expression +
+ "' didn't resolve to a java.lang.String: '" + result +
+ "' (" + result.getClass().getName() + ")");
+ }
+ }
+
+ private boolean hasSignallingWorkItems() {
+ for (WorkItem workItem: workItems) {
+ if ((Boolean) workItem.getParameter("signalling") == true) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean hasBlockingWorkItems() {
+ for (WorkItem workItem: workItems) {
+ if ((Boolean) workItem.getParameter("blocking") == true) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void restoreVariables(WorkItemImpl workItem, Task task) {
+ TaskController taskController = task.getTaskController();
+ if (taskController != null) {
+ Delegation taskControllerDelegation = taskController.getTaskControllerDelegation();
+ if (taskControllerDelegation != null) {
+ // TODO: delegation (API mismatch!)
+ } else {
+ List<VariableAccess> variableAccesses = taskController.getVariableAccesses();
+ if (variableAccesses != null) {
+ String missingTaskVariables = null;
+ for (VariableAccess variableAccess: variableAccesses) {
+ String mappedName = variableAccess.getMappedName();
+ Object value = workItem.getParameter(mappedName);
+ if (variableAccess.isRequired() && (value != null)) {
+ if (missingTaskVariables == null) {
+ missingTaskVariables = mappedName;
+ } else {
+ missingTaskVariables += ", "+mappedName;
+ }
+ }
+ }
+ if (missingTaskVariables != null) {
+ throw new IllegalArgumentException(
+ "missing task variables: " + missingTaskVariables);
+ }
+
+ for (VariableAccess variableAccess: variableAccesses) {
+ String mappedName = variableAccess.getMappedName();
+ String variableName = variableAccess.getVariableName();
+ if (variableAccess.isWritable()) {
+ Object value = workItem.getParameter(mappedName);
+ if (value != null) {
+ VariableScopeInstance variableScopeInstance = (VariableScopeInstance)
+ resolveContextInstance(VariableScope.VARIABLE_SCOPE, variableName);
+ variableScopeInstance.setVariable(variableName, value);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void addEventListeners() {
+ getProcessInstance().addWorkItemListener(this);
+ }
+
+ public void removeEventListeners() {
+ getProcessInstance().removeWorkItemListener(this);
+ }
+
+ public void workItemAborted(WorkItem workItem) {
+ if (workItems.remove(workItem)) {
+ if (!hasBlockingWorkItems()) {
+ removeEventListeners();
+ leave();
+ }
+ }
+ }
+
+ public void workItemCompleted(WorkItem workItem) {
+ if (workItems.remove(workItem)) {
+ String taskName = (String) workItem.getParameter("name");
+ Set<Task> tasks = getTaskNode().getTasks();
+ for (Task task: tasks) {
+ if (taskName.equals(task.getName())) {
+ restoreVariables((WorkItemImpl) workItem, task);
+ if (task.getSwimlane() != null) {
+ String swimlaneName = task.getSwimlane().getName();
+ SwimlaneContextInstance swimlaneContextInstance = (SwimlaneContextInstance)
+ resolveContextInstance(SwimlaneContext.SWIMLANE_SCOPE, swimlaneName);
+ if (swimlaneContextInstance.getActorId(swimlaneName) == null) {
+ String actorId = (String) workItem.getResult("ActorId");
+ if (actorId != null) {
+ swimlaneContextInstance.setActorId(swimlaneName,
+ (String) workItem.getResult("ActorId"));
+ }
+ }
+ }
+ Event event = task.getEvent(Event.EVENTTYPE_TASK_END);
+ if (event != null) {
+ executeActions(event.getActions(), new JpdlTaskExecutionContext(task));
+ }
+ break;
+ }
+ }
+ if (!hasBlockingWorkItems()) {
+ removeEventListeners();
+ String result = (String) workItem.getResult("Result");
+ if (result != null) {
+ leave(result);
+ } else {
+ leave();
+ }
+ }
+ }
+ }
+
+ public WorkItem findWorkItem(Task task) {
+ for (WorkItem workItem: workItems) {
+ if (task.getName().equals(workItem.getName())) {
+ return workItem;
+ }
+ }
+ return null;
+ }
+
+ public void leave(String type) {
+ if (hasBlockingWorkItems()) {
+ throw new IllegalStateException("task-node '"
+ + getNode().getName() + "' still has blocking tasks");
+ }
+ if (getTaskNode().isEndTasks()) {
+ for (WorkItem workItem: workItems) {
+ getProcessInstance().getWorkingMemory().getWorkItemManager()
+ .internalAbortWorkItem(workItem.getId());
+ }
+ }
+ super.leave(type);
+ }
+
+ public class JpdlTaskExecutionContext extends JpdlExecutionContext {
+ private Task task;
+ public JpdlTaskExecutionContext(Task task) {
+ this.task = task;
+ }
+ public Task getTask() {
+ return task;
+ }
+ }
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/xml/JpdlProcessSemanticModule.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/xml/JpdlProcessSemanticModule.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/xml/JpdlProcessSemanticModule.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,82 @@
+package org.drools.jpdl.xml;
+
+import org.drools.xml.DefaultSemanticModule;
+import org.drools.xml.SemanticModule;
+import org.drools.xml.processes.ActionNodeHandler;
+import org.drools.xml.processes.CompositeNodeHandler;
+import org.drools.xml.processes.ConnectionHandler;
+import org.drools.xml.processes.ConstraintHandler;
+import org.drools.xml.processes.EndNodeHandler;
+import org.drools.xml.processes.GlobalHandler;
+import org.drools.xml.processes.ImportHandler;
+import org.drools.xml.processes.InPortHandler;
+import org.drools.xml.processes.JoinNodeHandler;
+import org.drools.xml.processes.MappingHandler;
+import org.drools.xml.processes.MilestoneNodeHandler;
+import org.drools.xml.processes.OutPortHandler;
+import org.drools.xml.processes.ParameterHandler;
+import org.drools.xml.processes.ProcessHandler;
+import org.drools.xml.processes.RuleSetNodeHandler;
+import org.drools.xml.processes.SplitNodeHandler;
+import org.drools.xml.processes.SubProcessNodeHandler;
+import org.drools.xml.processes.TimerNodeHandler;
+import org.drools.xml.processes.TypeHandler;
+import org.drools.xml.processes.ValueHandler;
+import org.drools.xml.processes.VariableHandler;
+import org.drools.xml.processes.WorkHandler;
+import org.drools.xml.processes.WorkItemNodeHandler;
+
+public class JpdlProcessSemanticModule extends DefaultSemanticModule implements SemanticModule {
+ public JpdlProcessSemanticModule() {
+ super ( "http://drools.org/drools-4.0/process" );
+
+ addHandler( "process",
+ new ProcessHandler() );
+ addHandler( "start",
+ new StartStateHandler() );
+ addHandler( "end",
+ new EndNodeHandler() );
+ addHandler( "action",
+ new ActionNodeHandler() );
+ addHandler( "ruleSet",
+ new RuleSetNodeHandler() );
+ addHandler( "subProcess",
+ new SubProcessNodeHandler() );
+ addHandler( "workItem",
+ new WorkItemNodeHandler() );
+ addHandler( "split",
+ new SplitNodeHandler() );
+ addHandler( "join",
+ new JoinNodeHandler() );
+ addHandler( "milestone",
+ new MilestoneNodeHandler() );
+ addHandler( "timer",
+ new TimerNodeHandler() );
+ addHandler( "composite",
+ new CompositeNodeHandler() );
+ addHandler( "connection",
+ new ConnectionHandler() );
+ addHandler( "import",
+ new ImportHandler() );
+ addHandler( "global",
+ new GlobalHandler() );
+ addHandler( "variable",
+ new VariableHandler() );
+ addHandler( "type",
+ new TypeHandler() );
+ addHandler( "value",
+ new ValueHandler() );
+ addHandler( "work",
+ new WorkHandler() );
+ addHandler( "parameter",
+ new ParameterHandler() );
+ addHandler( "mapping",
+ new MappingHandler() );
+ addHandler( "constraint",
+ new ConstraintHandler() );
+ addHandler( "in-port",
+ new InPortHandler() );
+ addHandler( "out-port",
+ new OutPortHandler() );
+ }
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/xml/StartStateHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/xml/StartStateHandler.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/java/org/drools/jpdl/xml/StartStateHandler.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,23 @@
+package org.drools.jpdl.xml;
+
+import org.drools.jpdl.core.node.StartState;
+import org.drools.workflow.core.Node;
+import org.drools.xml.processes.AbstractNodeHandler;
+
+public class StartStateHandler extends AbstractNodeHandler {
+
+ protected Node createNode() {
+ return new StartState();
+ }
+
+ public Class generateNodeFor() {
+ return StartState.class;
+ }
+
+ public void writeNode(Node node, StringBuffer xmlDump, boolean includeMeta) {
+ StartState startNode = (StartState) node;
+ writeNode("start", startNode, xmlDump, includeMeta);
+ endNode(xmlDump);
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/resources/META-INF/JpdlProcessInstanceFactory.conf
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/resources/META-INF/JpdlProcessInstanceFactory.conf (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/resources/META-INF/JpdlProcessInstanceFactory.conf 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,7 @@
+// we use MVEL to configure our process, simply populate a map, which will be added to the main registry
+import org.drools.jpdl.core.JpdlProcess;
+import org.drools.jpdl.instance.JpdlProcessInstanceFactory;
+
+[
+ JpdlProcess : new JpdlProcessInstanceFactory(),
+]
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/resources/META-INF/JpdlProcessNodeInstanceFactory.conf
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/resources/META-INF/JpdlProcessNodeInstanceFactory.conf (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/resources/META-INF/JpdlProcessNodeInstanceFactory.conf 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,36 @@
+// we use MVEL to configure our nodes, simply populate a map, which will be added to the main registry
+import org.drools.jpdl.core.node.Decision;
+import org.drools.jpdl.core.node.EndState;
+import org.drools.jpdl.core.node.Fork;
+import org.drools.jpdl.core.node.Join;
+import org.drools.jpdl.core.node.JpdlNode;
+import org.drools.jpdl.core.node.MailNode;
+import org.drools.jpdl.core.node.ProcessState;
+import org.drools.jpdl.core.node.StartState;
+import org.drools.jpdl.core.node.State;
+import org.drools.jpdl.core.node.TaskNode;
+import org.drools.jpdl.instance.node.DecisionInstance;
+import org.drools.jpdl.instance.node.EndStateInstance;
+import org.drools.jpdl.instance.node.ForkInstance;
+import org.drools.jpdl.instance.node.JoinInstance;
+import org.drools.jpdl.instance.node.JpdlNodeInstance;
+import org.drools.jpdl.instance.node.MailNodeInstance;
+import org.drools.jpdl.instance.node.ProcessStateInstance;
+import org.drools.jpdl.instance.node.StartStateInstance;
+import org.drools.jpdl.instance.node.StateInstance;
+import org.drools.jpdl.instance.node.TaskNodeInstance;
+import org.drools.workflow.instance.impl.factory.CreateNewNodeFactory;
+import org.drools.workflow.instance.impl.factory.ReuseNodeFactory;
+
+[
+ JpdlNode : new CreateNewNodeFactory( JpdlNodeInstance ),
+ StartState : new CreateNewNodeFactory( StartStateInstance ),
+ EndState : new CreateNewNodeFactory( EndStateInstance ),
+ Fork : new CreateNewNodeFactory( ForkInstance ),
+ Join : new ReuseNodeFactory( JoinInstance ),
+ MailNode : new CreateNewNodeFactory( MailNodeInstance ),
+ Decision : new CreateNewNodeFactory( DecisionInstance ),
+ ProcessState : new CreateNewNodeFactory( ProcessStateInstance ),
+ TaskNode : new CreateNewNodeFactory( TaskNodeInstance ),
+ State : new CreateNewNodeFactory( StateInstance ),
+]
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/resources/META-INF/drools.rulebase.conf
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/resources/META-INF/drools.rulebase.conf (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/main/resources/META-INF/drools.rulebase.conf 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,2 @@
+processInstanceFactoryRegistry=JpdlProcessInstanceFactory.conf
+processNodeInstanceFactoryRegistry=JpdlProcessNodeInstanceFactory.conf
\ No newline at end of file
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/ParseSimpleProcessTest.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/ParseSimpleProcessTest.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/ParseSimpleProcessTest.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,70 @@
+package org.drools;
+
+import junit.framework.TestCase;
+
+import org.drools.jpdl.JpdlParser;
+import org.drools.jpdl.core.JpdlProcess;
+import org.drools.process.core.validation.ProcessValidationError;
+import org.drools.process.instance.ProcessInstance;
+import org.drools.process.instance.WorkItem;
+import org.drools.process.instance.WorkItemHandler;
+import org.drools.process.instance.WorkItemManager;
+import org.drools.rule.Package;
+
+public class ParseSimpleProcessTest extends TestCase {
+
+ public void testSimpleProcess() throws Exception {
+ JpdlParser parser = new JpdlParser();
+ JpdlProcess process = parser.loadJpdlProcess("simple/processdefinition.xml");
+ ProcessValidationError[] errors = parser.getErrors();
+ for (ProcessValidationError error: errors) {
+ System.err.println(error);
+ }
+ assertEquals(0, errors.length);
+
+ RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+ Package p = new Package("com.sample");
+ p.addRuleFlow(process);
+ ruleBase.addPackage( p );
+
+ WorkingMemory workingMemory = ruleBase.newStatefulSession();
+ ProcessInstance processInstance = workingMemory.startProcess("simple");
+ assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
+ }
+
+ public void testSimpleProcess2() throws Exception {
+ JpdlParser parser = new JpdlParser();
+ JpdlProcess process = parser.loadJpdlProcess("simple2/processdefinition.xml");
+ ProcessValidationError[] errors = parser.getErrors();
+ for (ProcessValidationError error: errors) {
+ System.err.println(error);
+ }
+ assertEquals(0, errors.length);
+
+ RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+ Package p = new Package("com.sample");
+ p.addRuleFlow(process);
+ ruleBase.addPackage( p );
+
+ WorkingMemory workingMemory = ruleBase.newStatefulSession();
+ TestWorkItemHandler handler = new TestWorkItemHandler();
+ workingMemory.getWorkItemManager().registerWorkItemHandler(
+ "Email", handler);
+ assertTrue(handler.getWorkItemId() == -1);
+ ProcessInstance processInstance = workingMemory.startProcess("simple");
+ assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
+ }
+
+ private static class TestWorkItemHandler implements WorkItemHandler {
+ private long workItemId = -1;
+ public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
+ workItemId = workItem.getId();
+ }
+ public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {
+ }
+ public long getWorkItemId() {
+ return workItemId;
+ }
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/SimpleProcessTest.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/SimpleProcessTest.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/SimpleProcessTest.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,40 @@
+package org.drools;
+
+import junit.framework.TestCase;
+
+import org.jbpm.graph.def.ProcessDefinition;
+import org.jbpm.graph.exe.ProcessInstance;
+
+public class SimpleProcessTest extends TestCase {
+
+ public void testSimpleProcess() throws Exception {
+
+ // Extract a process definition from the processdefinition.xml file.
+ ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource("simple/processdefinition.xml");
+ assertNotNull("Definition should not be null", processDefinition);
+
+ // Create an instance of the process definition.
+ ProcessInstance instance = new ProcessInstance(processDefinition);
+ assertEquals(
+ "Instance is in start state",
+ instance.getRootToken().getNode().getName(),
+ "start");
+ assertNull(
+ "Message variable should not exist yet",
+ instance.getContextInstance().getVariable("message"));
+
+ instance.signal();
+ assertEquals(
+ "Instance is in node1",
+ instance.getRootToken().getNode().getName(),
+ "node1");
+
+ instance.signal();
+ assertEquals(
+ "Instance is in end state",
+ instance.getRootToken().getNode().getName(),
+ "end");
+ assertTrue("Instance has ended", instance.hasEnded());
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/SysoutHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/SysoutHandler.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/SysoutHandler.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,15 @@
+package org.drools;
+
+import org.jbpm.graph.def.ActionHandler;
+import org.jbpm.graph.exe.ExecutionContext;
+
+public class SysoutHandler implements ActionHandler {
+
+ private static final long serialVersionUID = 1L;
+
+ public void execute(ExecutionContext executionContext) throws Exception {
+ System.out.println("Executing");
+ executionContext.leaveNode();
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/WebsaleProcessTest.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/WebsaleProcessTest.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/drools/WebsaleProcessTest.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,69 @@
+package org.drools;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.jpdl.JpdlParser;
+import org.drools.jpdl.core.JpdlProcess;
+import org.drools.process.core.context.variable.Variable;
+import org.drools.process.core.context.variable.VariableScope;
+import org.drools.process.core.datatype.impl.type.StringDataType;
+import org.drools.process.core.validation.ProcessValidationError;
+import org.drools.process.instance.impl.demo.UIWorkItemHandler;
+import org.drools.rule.Package;
+
+public class WebsaleProcessTest {
+
+ public static void main(String[] args) throws Exception {
+ JpdlParser parser = new JpdlParser();
+ JpdlProcess process = parser.loadJpdlProcess("websale/processdefinition.xml");
+ VariableScope variableScope = (VariableScope)
+ process.getDefaultContext(VariableScope.VARIABLE_SCOPE);
+ // TODO: do we really need to define all process variables ?
+ List<Variable> variables = new ArrayList<Variable>();
+ Variable item = new Variable();
+ item.setName("item");
+ item.setType(new StringDataType());
+ variables.add(item);
+ Variable quantity = new Variable();
+ quantity.setName("quantity");
+ quantity.setType(new StringDataType());
+ variables.add(quantity);
+ Variable address = new Variable();
+ address.setName("address");
+ address.setType(new StringDataType());
+ variables.add(address);
+ variableScope.setVariables(variables);
+ ProcessValidationError[] errors = parser.getErrors();
+ for (ProcessValidationError error: errors) {
+ System.err.println(error);
+ }
+ if (errors.length != 0) {
+ throw new IllegalArgumentException("Errors while parsing websale process");
+ }
+
+ RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+ Package p = new Package("com.sample");
+ p.addRuleFlow(process);
+ ruleBase.addPackage( p );
+
+ WorkingMemory workingMemory = ruleBase.newStatefulSession();
+ UIWorkItemHandler uiHandler = new UIWorkItemHandler();
+ workingMemory.getWorkItemManager().registerWorkItemHandler(
+ "JpdlTask", uiHandler);
+ uiHandler.setVisible(true);
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ parameters.put("item", "Drools Manual");
+ parameters.put("quantity", "2");
+ parameters.put("item", "Drools Manual");
+ parameters.put("address",
+ "Red Hat Corporate Headquarters, " +
+ "1801 Varsity Drive, " +
+ "Raleigh, North Carolina 27606" +
+ "USA");
+ workingMemory.startProcess("websale", parameters);
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/jbpm/websale/RemindActor.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/jbpm/websale/RemindActor.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/jbpm/websale/RemindActor.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,18 @@
+package org.jbpm.websale;
+
+import org.jbpm.graph.def.ActionHandler;
+import org.jbpm.graph.exe.ExecutionContext;
+
+public class RemindActor implements ActionHandler {
+
+ private static final long serialVersionUID = 1L;
+
+ String swimlaneName;
+
+ public void execute(ExecutionContext executionContext) throws Exception {
+ System.out.println("###############################################");
+ System.out.println("### Task is waiting.");
+ System.out.println("###############################################");
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/jbpm/websale/ShipItem.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/jbpm/websale/ShipItem.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/jbpm/websale/ShipItem.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,36 @@
+package org.jbpm.websale;
+
+import org.jbpm.graph.def.ActionHandler;
+import org.jbpm.graph.exe.ExecutionContext;
+
+public class ShipItem implements ActionHandler {
+
+ private static final long serialVersionUID = 1L;
+
+ String swimlaneName;
+ String msg;
+
+ public void execute(ExecutionContext executionContext) throws Exception {
+ // TODO get real name of assigned person?
+ String actorId = "Shipper";
+ String displayMsg = replace(msg, "${"+swimlaneName+"}", actorId);
+ displayMsg = replace(displayMsg, "${item}", (String) executionContext.getVariable("item"));
+ displayMsg = replace(displayMsg, "${address}", (String) executionContext.getVariable("address"));
+
+ System.out.println("###############################################");
+ System.out.println("### " + displayMsg);
+ System.out.println("###############################################");
+
+ executionContext.leaveNode();
+ }
+
+ private static String replace(String msg, String pattern, String replacement) {
+ String replaced = null;
+ int pos = msg.indexOf(pattern);
+ if (pos!=-1) {
+ replaced = msg.substring(0,pos) + replacement
+ + msg.substring(pos + pattern.length());
+ }
+ return replaced;
+ }
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/jbpm/websale/UpdateBooks.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/jbpm/websale/UpdateBooks.java (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/java/org/jbpm/websale/UpdateBooks.java 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,19 @@
+package org.jbpm.websale;
+
+import org.jbpm.graph.def.ActionHandler;
+import org.jbpm.graph.exe.ExecutionContext;
+
+public class UpdateBooks implements ActionHandler {
+
+ String msg;
+
+ private static final long serialVersionUID = 1L;
+
+ public void execute(ExecutionContext executionContext) throws Exception {
+ System.out.println("###############################################");
+ System.out.println("### updating the accounting books");
+ System.out.println("###############################################");
+ executionContext.leaveNode();
+ }
+
+}
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple/gpd.xml
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple/gpd.xml (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple/gpd.xml 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root-container height="662" name="simple" width="694">
+ <node height="40" name="start" width="140" x="150" y="25">
+ <edge>
+ <label x="5" y="-10"/>
+ </edge>
+ </node>
+ <node height="40" name="end" width="140" x="150" y="225"/>
+ <node height="36" name="node1" width="132" x="153" y="120">
+ <edge>
+ <label x="5" y="-10"/>
+ </edge>
+ </node>
+</root-container>
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple/processdefinition.xml
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple/processdefinition.xml (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple/processdefinition.xml 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<process-definition
+ xmlns="urn:jbpm.org:jpdl-3.2"
+ name="simple">
+ <start-state name="start">
+ <transition to="node1"></transition>
+ </start-state>
+ <node name="node1">
+ <action name="Sysout" class="org.drools.SysoutHandler"></action>
+ <transition to="end"></transition>
+ </node>
+
+
+ <end-state name="end"></end-state>
+</process-definition>
\ No newline at end of file
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple/processimage.jpg
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple/processimage.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple2/gpd.xml
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple2/gpd.xml (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple2/gpd.xml 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root-container height="662" name="simple" width="694">
+ <node height="40" name="start" width="140" x="150" y="25">
+ <edge>
+ <label x="5" y="-10"/>
+ </edge>
+ </node>
+ <node height="36" name="node1" width="132" x="42" y="154">
+ <edge>
+ <label x="5" y="-10"/>
+ </edge>
+ </node>
+ <node height="40" name="end" width="140" x="154" y="290"/>
+ <node height="24" name="fork1" width="252" x="95" y="100">
+ <edge>
+ <label x="5" y="-10"/>
+ </edge>
+ <edge>
+ <label x="5" y="-10"/>
+ </edge>
+ </node>
+ <node height="24" name="join1" width="252" x="99" y="223">
+ <edge>
+ <label x="5" y="-10"/>
+ </edge>
+ </node>
+ <node height="36" name="mail-node1" width="132" x="263" y="155">
+ <edge>
+ <label x="5" y="-10"/>
+ </edge>
+ </node>
+</root-container>
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple2/processdefinition.xml
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple2/processdefinition.xml (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple2/processdefinition.xml 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<process-definition
+ xmlns="urn:jbpm.org:jpdl-3.2"
+ name="simple">
+ <start-state name="start">
+ <transition to="fork1"></transition>
+ </start-state>
+ <node name="node1">
+ <action name="Sysout" class="org.drools.SysoutHandler"></action>
+ <transition to="join1"></transition>
+ </node>
+
+ <fork name="fork1">
+ <transition to="node1"></transition>
+ <transition to="node2" name="to node2"></transition>
+ </fork>
+
+ <join name="join1">
+ <transition to="end"></transition>
+ </join>
+
+ <node name="node2">
+ <action name="Sysout" class="org.drools.SysoutHandler"></action>
+ <transition to="join1"></transition>
+ </node>
+
+
+ <end-state name="end">
+ <event type="node-enter">
+ <action name="Sysout" class="org.drools.SysoutHandler"></action>
+ </event>
+ </end-state>
+</process-definition>
\ No newline at end of file
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple2/processimage.jpg
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/simple2/processimage.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/websale/gpd.xml
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/websale/gpd.xml (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/websale/gpd.xml 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<process-diagram name="websale" width="566" height="541">
+ <node name="Create new web sale order" x="250" y="50" width="200" height="40">
+ <transition>
+ <label x="5" y="-10"/>
+ </transition>
+ </node>
+ <node name="Evaluate web order" x="280" y="125" width="140" height="40">
+ <transition name="ok">
+ <label x="9" y="-10"/>
+ </transition>
+ <transition name="more info needed">
+ <label x="-44" y="-18"/>
+ <bendpoint w1="-114" h1="-35" w2="116" h2="-35"/>
+ </transition>
+ </node>
+ <node name="Fix web order data" x="50" y="125" width="140" height="40">
+ <transition>
+ <label x="5" y="-10"/>
+ <bendpoint w1="109" h1="32" w2="-121" h2="32"/>
+ </transition>
+ </node>
+ <node name="salefork" x="250" y="200" width="200" height="25">
+ <transition name="payment">
+ <label x="12" y="-18"/>
+ <bendpoint w1="145" h1="31" w2="0" h2="-52"/>
+ </transition>
+ <transition name="shipping">
+ <label x="10" y="10"/>
+ <bendpoint w1="-130" h1="34" w2="0" h2="-89"/>
+ </transition>
+ </node>
+ <node name="Wait for money" x="425" y="275" width="140" height="40">
+ <transition>
+ <label x="5" y="-10"/>
+ </transition>
+ </node>
+ <node name="update books" x="425" y="350" width="140" height="40">
+ <transition>
+ <label x="5" y="-10"/>
+ <bendpoint w1="-1" h1="34" w2="144" h2="-33"/>
+ </transition>
+ </node>
+ <node name="ship item" x="150" y="315" width="140" height="40">
+ <transition>
+ <label x="5" y="-10"/>
+ <bendpoint w1="-1" h1="74" w2="-131" h2="-28"/>
+ </transition>
+ </node>
+ <node name="salejoin" x="250" y="425" width="200" height="25">
+ <transition>
+ <label x="5" y="-10"/>
+ </transition>
+ </node>
+ <node name="end" x="280" y="500" width="140" height="40"/>
+</process-diagram>
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/websale/processdefinition.xml
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/websale/processdefinition.xml (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/websale/processdefinition.xml 2008-05-27 11:13:44 UTC (rev 20178)
@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+
+<process-definition name="websale"
+ xmlns="urn:jbpm.org:jpdl-3.2">
+
+ <!-- SWIMLANES (= process roles) -->
+
+ <swimlane name="buyer" />
+
+ <swimlane name="salesman">
+ <assignment actor-id="ernie" />
+ </swimlane>
+
+ <swimlane name="accountant">
+ <assignment actor-id="bert" />
+ </swimlane>
+
+ <swimlane name="shipper">
+ <assignment actor-id="grover" />
+ </swimlane>
+
+ <!-- NODES -->
+
+ <start-state name="Create new web sale order">
+ <task swimlane="buyer" />
+ <transition to="Evaluate web order" />
+ </start-state>
+
+ <task-node name="Evaluate web order">
+ <task swimlane="salesman">
+ <timer duedate="20 seconds" repeat="10 seconds">
+ <action class="org.jbpm.websale.RemindActor">
+ <swimlaneName>salesman</swimlaneName>
+ </action>
+ </timer>
+ </task>
+ <transition name="OK" to="salefork" />
+ <transition name="More info needed" to="Fix web order data" />
+ </task-node>
+
+ <task-node name="Fix web order data">
+ <task swimlane="buyer" />
+ <transition to="Evaluate web order" />
+ </task-node>
+
+ <fork name="salefork">
+ <transition name="payment" to="Wait for money" />
+ <transition name="shipping" to="ship item" />
+ </fork>
+
+ <task-node name="Wait for money">
+ <task swimlane="accountant" />
+ <transition to="update books" />
+ </task-node>
+
+ <node name="update books">
+ <action class="org.jbpm.websale.UpdateBooks">
+ <msg>accountancy application is now informed of the payment</msg>
+ </action>
+ <transition to="salejoin" />
+ </node>
+
+ <node name="ship item">
+ <action class="org.jbpm.websale.ShipItem">
+ <swimlaneName>shipper</swimlaneName>
+ <msg>${shipper} now ships ${item} to ${address}</msg>
+ </action>
+ <transition to="salejoin" />
+ </node>
+
+ <join name="salejoin">
+ <transition to="end" />
+ </join>
+
+ <end-state name="end" />
+
+</process-definition>
Added: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/websale/processimage.jpg
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/trunk/drools-process/drools-jpdl/src/test/resources/websale/processimage.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
More information about the jboss-svn-commits
mailing list