From 211da070598a1ceccecc2fc984bc75c7b95bcb43 Mon Sep 17 00:00:00 2001 From: David Caruana Date: Wed, 24 Jan 2007 15:36:53 +0000 Subject: [PATCH] Workflow - fix for XOR type joins where forked path were not ended properly and tasks on those paths were not removed git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4919 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/hibernate-context.xml | 2 +- .../alfresco/repo/workflow/jbpm/Join.hbm.xml | 12 ++ .../org/alfresco/repo/workflow/jbpm/Join.java | 64 ++++++++++ .../workflow/jbpm/JoinEndForkedTokens.java | 109 ++++++++++++++++++ .../alfresco/repo/workflow/jbpm/jbpm.cfg.xml | 2 +- .../repo/workflow/jbpm/jbpm.node.types.xml | 18 +++ .../alfresco/repo/workflow/jbpm/test_xor.xml | 62 ++++++++++ 7 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 source/java/org/alfresco/repo/workflow/jbpm/Join.hbm.xml create mode 100644 source/java/org/alfresco/repo/workflow/jbpm/Join.java create mode 100644 source/java/org/alfresco/repo/workflow/jbpm/JoinEndForkedTokens.java create mode 100644 source/java/org/alfresco/repo/workflow/jbpm/jbpm.node.types.xml create mode 100644 source/java/org/alfresco/repo/workflow/jbpm/test_xor.xml diff --git a/config/alfresco/hibernate-context.xml b/config/alfresco/hibernate-context.xml index 83983c5438..013d83a6aa 100644 --- a/config/alfresco/hibernate-context.xml +++ b/config/alfresco/hibernate-context.xml @@ -72,7 +72,7 @@ org/jbpm/graph/node/ProcessState.hbm.xml org/jbpm/graph/node/Decision.hbm.xml org/jbpm/graph/node/Fork.hbm.xml - org/jbpm/graph/node/Join.hbm.xml + org/alfresco/repo/workflow/jbpm/Join.hbm.xml org/jbpm/graph/node/State.hbm.xml org/jbpm/graph/node/TaskNode.hbm.xml org/jbpm/context/def/ContextDefinition.hbm.xml diff --git a/source/java/org/alfresco/repo/workflow/jbpm/Join.hbm.xml b/source/java/org/alfresco/repo/workflow/jbpm/Join.hbm.xml new file mode 100644 index 0000000000..a9958bb50b --- /dev/null +++ b/source/java/org/alfresco/repo/workflow/jbpm/Join.hbm.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/source/java/org/alfresco/repo/workflow/jbpm/Join.java b/source/java/org/alfresco/repo/workflow/jbpm/Join.java new file mode 100644 index 0000000000..35258ba5c7 --- /dev/null +++ b/source/java/org/alfresco/repo/workflow/jbpm/Join.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.workflow.jbpm; + +import org.dom4j.Element; +import org.jbpm.graph.def.Action; +import org.jbpm.graph.def.Event; +import org.jbpm.instantiation.Delegation; +import org.jbpm.jpdl.xml.JpdlXmlReader; + + +/** + * Implementation of Join which ends child tokens / tasks for nOutM cases. + * + * @author davidc + * + */ +public class Join extends org.jbpm.graph.node.Join +{ + private static final long serialVersionUID = 6417483503439714897L; + + /** + * Constructor + */ + public Join() + { + } + + /** + * Constructor + */ + public Join(String name) + { + super(name); + } + + /* (non-Javadoc) + * @see org.jbpm.jpdl.xml.Parsable#read(org.dom4j.Element, org.jbpm.jpdl.xml.JpdlXmlReader) + */ + public void read(Element element, JpdlXmlReader jpdlReader) + { + // Add "on node leave" event handler which ends child tokens / tasks + Delegation delegation = new Delegation(JoinEndForkedTokens.class.getName()); + Action action = new Action(delegation); + Event event = new Event(Event.EVENTTYPE_NODE_LEAVE); + event.addAction(action); + addEvent(event); + } + +} diff --git a/source/java/org/alfresco/repo/workflow/jbpm/JoinEndForkedTokens.java b/source/java/org/alfresco/repo/workflow/jbpm/JoinEndForkedTokens.java new file mode 100644 index 0000000000..a59ffb6d6c --- /dev/null +++ b/source/java/org/alfresco/repo/workflow/jbpm/JoinEndForkedTokens.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.workflow.jbpm; + +import java.util.Collection; +import java.util.Map; + +import org.jbpm.graph.def.ActionHandler; +import org.jbpm.graph.exe.ExecutionContext; +import org.jbpm.graph.exe.Token; +import org.jbpm.taskmgmt.exe.TaskInstance; +import org.jbpm.taskmgmt.exe.TaskMgmtInstance; + +/** + * Action Handler for ending child tokens / tasks + * + * @author davidc + */ +public class JoinEndForkedTokens implements ActionHandler +{ + private static final long serialVersionUID = 8679390550752208189L; + + /** + * Constructor + */ + public JoinEndForkedTokens() + { + } + + /* (non-Javadoc) + * @see org.jbpm.graph.def.ActionHandler#execute(org.jbpm.graph.exe.ExecutionContext) + */ + public void execute(ExecutionContext executionContext) + { + Token token = executionContext.getToken(); + Map childTokens = token.getActiveChildren(); + for (Object childToken : childTokens.values()) + { + cancelToken(executionContext, (Token)childToken); + } + } + + /** + * Cancel token + * + * @param executionContext + * @param token + */ + protected void cancelToken(ExecutionContext executionContext, Token token) + { + // visit child tokens + Map childTokens = token.getActiveChildren(); + for (Object childToken : childTokens.values()) + { + cancelToken(executionContext, (Token)childToken); + } + + // end token + if (!token.hasEnded()) + { + token.end(false); + } + + // end any associated tasks + cancelTokenTasks(executionContext, token); + } + + /** + * Cancel tasks associated with a token + * + * @param executionContext + * @param token + */ + protected void cancelTokenTasks(ExecutionContext executionContext, Token token) + { + TaskMgmtInstance tms = executionContext.getTaskMgmtInstance(); + Collection tasks = tms.getUnfinishedTasks(token); + for (Object task : tasks) + { + TaskInstance taskInstance = (TaskInstance)task; + if (taskInstance.isBlocking()) + { + taskInstance.setBlocking(false); + } + if (taskInstance.isSignalling()) + { + taskInstance.setSignalling(false); + } + if (!taskInstance.hasEnded()) + { + taskInstance.cancel(); + } + } + } +} diff --git a/source/java/org/alfresco/repo/workflow/jbpm/jbpm.cfg.xml b/source/java/org/alfresco/repo/workflow/jbpm/jbpm.cfg.xml index e15d0b62a3..1bd06e8647 100644 --- a/source/java/org/alfresco/repo/workflow/jbpm/jbpm.cfg.xml +++ b/source/java/org/alfresco/repo/workflow/jbpm/jbpm.cfg.xml @@ -14,7 +14,7 @@ - + diff --git a/source/java/org/alfresco/repo/workflow/jbpm/jbpm.node.types.xml b/source/java/org/alfresco/repo/workflow/jbpm/jbpm.node.types.xml new file mode 100644 index 0000000000..644c6f1dc2 --- /dev/null +++ b/source/java/org/alfresco/repo/workflow/jbpm/jbpm.node.types.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/source/java/org/alfresco/repo/workflow/jbpm/test_xor.xml b/source/java/org/alfresco/repo/workflow/jbpm/test_xor.xml new file mode 100644 index 0000000000..90b61185b0 --- /dev/null +++ b/source/java/org/alfresco/repo/workflow/jbpm/test_xor.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file