[jbpm-commits] JBoss JBPM SVN: r3894 - in jbpm3/trunk/modules/core/src: test/java/org/jbpm and 1 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Mon Feb 16 12:22:34 EST 2009


Author: alex.guizar at jboss.com
Date: 2009-02-16 12:22:34 -0500 (Mon, 16 Feb 2009)
New Revision: 3894

Added:
   jbpm3/trunk/modules/core/src/test/java/org/jbpm/jbpm1954/
   jbpm3/trunk/modules/core/src/test/java/org/jbpm/jbpm1954/JBPM1954Test.java
Modified:
   jbpm3/trunk/modules/core/src/main/java/org/jbpm/graph/node/Decision.java
Log:
JBPM-1954 take default transition after exception in decision handler is caught and not rethrown by an exception handler;
prevent further execution if exception handler moves token to different node

Modified: jbpm3/trunk/modules/core/src/main/java/org/jbpm/graph/node/Decision.java
===================================================================
--- jbpm3/trunk/modules/core/src/main/java/org/jbpm/graph/node/Decision.java	2009-02-16 16:53:53 UTC (rev 3893)
+++ jbpm3/trunk/modules/core/src/main/java/org/jbpm/graph/node/Decision.java	2009-02-16 17:22:34 UTC (rev 3894)
@@ -38,161 +38,138 @@
 /**
  * decision node.
  */
-public class Decision extends Node
-{
-  static final String NEWLINE = System.getProperty("line.separator");
-  static final String DECISION_CONDITION_RESULT = "decision_condition_result";
+public class Decision extends Node {
+
   static final long serialVersionUID = 1L;
 
   List<DecisionCondition> decisionConditions = null;
   Delegation decisionDelegation = null;
   String decisionExpression = null;
 
-  public Decision()
-  {
+  public Decision() {
   }
 
-  public Decision(String name)
-  {
+  public Decision(String name) {
     super(name);
   }
 
   @Override
-  public NodeType getNodeType()
-  {
+  public NodeType getNodeType() {
     return NodeType.Decision;
   }
 
-  public void read(Element decisionElement, JpdlXmlReader jpdlReader)
-  {
-
+  public void read(Element decisionElement, JpdlXmlReader jpdlReader) {
     String expression = decisionElement.attributeValue("expression");
     Element decisionHandlerElement = decisionElement.element("handler");
 
-    if (expression != null)
-    {
+    if (expression != null) {
       decisionExpression = expression;
-
     }
-    else if (decisionHandlerElement != null)
-    {
+    else if (decisionHandlerElement != null) {
       decisionDelegation = new Delegation();
       decisionDelegation.read(decisionHandlerElement, jpdlReader);
     }
   }
 
-  public void execute(ExecutionContext executionContext)
-  {
+  public void execute(ExecutionContext executionContext) {
     Transition transition = null;
-    ClassLoader surroundingClassLoader = Thread.currentThread().getContextClassLoader();
-    try
-    {
-      // set context class loader correctly for delegation class (https://jira.jboss.org/jira/browse/JBPM-1448)
-      Thread.currentThread().setContextClassLoader(JbpmConfiguration.getProcessClassLoader(executionContext.getProcessDefinition()));
 
-      try
-      {
-        if (decisionDelegation != null)
-        {
-          DecisionHandler decisionHandler = (DecisionHandler)decisionDelegation.getInstance();
-          if (decisionHandler == null)
-            decisionHandler = (DecisionHandler)decisionDelegation.instantiate();
+    // set context class loader correctly for delegation class
+    // (https://jira.jboss.org/jira/browse/JBPM-1448)
+    Thread currentThread = Thread.currentThread();
+    ClassLoader contextClassLoader = currentThread.getContextClassLoader();
+    currentThread.setContextClassLoader(JbpmConfiguration.getProcessClassLoader(executionContext.getProcessDefinition()));
 
-          String transitionName = decisionHandler.decide(executionContext);
-          transition = getLeavingTransition(transitionName);
-          if (transition == null)
-          {
-            throw new JbpmException("decision '" + name + "' selected non existing transition '" + transitionName + "'");
-          }
+    try {
+      if (decisionDelegation != null) {
+        DecisionHandler decisionHandler = (DecisionHandler) decisionDelegation.getInstance();
+        if (decisionHandler == null)
+          decisionHandler = (DecisionHandler) decisionDelegation.instantiate();
 
+        String transitionName = decisionHandler.decide(executionContext);
+        transition = getLeavingTransition(transitionName);
+        if (transition == null) {
+          throw new JbpmException("decision '"
+              + name
+              + "' selected non existing transition '"
+              + transitionName
+              + "'");
         }
-        else if (decisionExpression != null)
-        {
-          Object result = JbpmExpressionEvaluator.evaluate(decisionExpression, executionContext);
-          if (result == null)
-          {
-            throw new JbpmException("decision expression '" + decisionExpression + "' returned null");
-          }
-          String transitionName = result.toString();
-          transition = getLeavingTransition(transitionName);
-          if (transition == null)
-          {
-            throw new JbpmException("decision '" + name + "' selected non existing transition '" + transitionName + "'");
-          }
-
+      }
+      else if (decisionExpression != null) {
+        Object result = JbpmExpressionEvaluator.evaluate(decisionExpression, executionContext);
+        if (result == null) {
+          throw new JbpmException("decision expression '" + decisionExpression + "' returned null");
         }
-        else if (decisionConditions != null && !decisionConditions.isEmpty())
-        {
-          // backwards compatible mode based on separate DecisionCondition's
-          for (DecisionCondition decisionCondition : decisionConditions) {
-            Object result = JbpmExpressionEvaluator.evaluate(decisionCondition.getExpression(), executionContext);
-            if (Boolean.TRUE.equals(result))
-            {
-              String transitionName = decisionCondition.getTransitionName();
-              transition = getLeavingTransition(transitionName);
-              if (transition != null)
-              {
-                transition.removeConditionEnforcement();
-                break;
-              }
-            }            
+        String transitionName = result.toString();
+        transition = getLeavingTransition(transitionName);
+        if (transition == null) {
+          throw new JbpmException("decision '"
+              + name
+              + "' selected non existing transition '"
+              + transitionName
+              + "'");
+        }
+      }
+      else if (decisionConditions != null && !decisionConditions.isEmpty()) {
+        // backwards compatible mode based on separate DecisionCondition's
+        for (DecisionCondition decisionCondition : decisionConditions) {
+          Object result = JbpmExpressionEvaluator.evaluate(decisionCondition.getExpression(),
+              executionContext);
+          if (Boolean.TRUE.equals(result)) {
+            String transitionName = decisionCondition.getTransitionName();
+            transition = getLeavingTransition(transitionName);
+            if (transition != null) break;
           }
         }
-        else
-        {
-          // new mode based on conditions in the transition itself
-          for (Transition candidate : leavingTransitions) {
-            String conditionExpression = candidate.getCondition();
-            if (conditionExpression != null)
-            {
-              Object result = JbpmExpressionEvaluator.evaluate(conditionExpression, executionContext);
-              if (Boolean.TRUE.equals(result))
-              {
-                transition = candidate;
-                break;
-              }
+      }
+      else {
+        // new mode based on conditions in the transition itself
+        for (Transition candidate : leavingTransitions) {
+          String conditionExpression = candidate.getCondition();
+          if (conditionExpression != null) {
+            Object result = JbpmExpressionEvaluator.evaluate(conditionExpression, executionContext);
+            if (Boolean.TRUE.equals(result)) {
+              transition = candidate;
+              break;
             }
           }
         }
-
-        if (transition == null)
-          transition = getDefaultLeavingTransition();
-        
-        if (transition == null)
-          throw new IllegalStateException("decision cannot select transition: " + this);
-        
-        log.debug("decision didn't select transition, taking default " + transition);
-
-        // since the decision node evaluates condition expressions, the
-        // condition of the
-        // taken transition will always be met. therefor we can safely turn off
-        // the
-        // standard condition enforcement in the transitions after a decision
-        // node.
-        transition.removeConditionEnforcement();
-
       }
-      catch (Exception exception)
-      {
-        raiseException(exception, executionContext);
+    }
+    catch (Exception exception) {
+      raiseException(exception, executionContext);
+      if (!equals(executionContext.getNode())) {
+        return;
       }
-
     }
-    finally
-    {
-      Thread.currentThread().setContextClassLoader(surroundingClassLoader);
+    finally {
+      currentThread.setContextClassLoader(contextClassLoader);
     }
-    log.debug("decision " + name + " is taking '" + transition + "'");
+
+    if (transition == null) {
+      transition = getDefaultLeavingTransition();
+
+      if (transition == null)
+        throw new JbpmException("decision cannot select transition: " + this);
+
+      log.debug("decision did not select transition, taking default " + transition);
+    }
+
+    // since the decision node evaluates condition expressions, the condition of the
+    // taken transition will always be met. therefore we can safely turn off
+    // the standard condition enforcement in the transitions after a decision node.
+    transition.removeConditionEnforcement();
+
+    log.debug("decision '" + name + "' is taking " + transition);
     executionContext.leaveNode(transition);
   }
 
-  public List<DecisionCondition> getDecisionConditions()
-  {
+  public List<DecisionCondition> getDecisionConditions() {
     return decisionConditions;
   }
 
-  public void setDecisionDelegation(Delegation decisionDelegation)
-  {
+  public void setDecisionDelegation(Delegation decisionDelegation) {
     this.decisionDelegation = decisionDelegation;
   }
 

Added: jbpm3/trunk/modules/core/src/test/java/org/jbpm/jbpm1954/JBPM1954Test.java
===================================================================
--- jbpm3/trunk/modules/core/src/test/java/org/jbpm/jbpm1954/JBPM1954Test.java	                        (rev 0)
+++ jbpm3/trunk/modules/core/src/test/java/org/jbpm/jbpm1954/JBPM1954Test.java	2009-02-16 17:22:34 UTC (rev 3894)
@@ -0,0 +1,89 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.jbpm1954;
+
+import org.hibernate.HibernateException;
+import org.jbpm.AbstractJbpmTestCase;
+import org.jbpm.graph.def.ProcessDefinition;
+import org.jbpm.graph.exe.ExecutionContext;
+import org.jbpm.graph.exe.ProcessInstance;
+import org.jbpm.graph.node.DecisionHandler;
+
+/**
+ * JbpmException thrown from Decision after exception in delegation class
+ * 
+ * @see <a href="https://jira.jboss.org/jira/browse/JBPM-1954">JBPM-1954</a>
+ * @author Alejandro Guizar
+ */
+public class JBPM1954Test extends AbstractJbpmTestCase {
+
+  public void testHandleExceptionInDecisionHandler() {
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString("<process-definition name='jbpm1954'>"
+        + "  <start-state>"
+        + "    <transition to='decision' />"
+        + "  </start-state>"
+        + "  <decision name='decision'>"
+        + "    <handler class='"
+        + ProblematicDecisionHandler.class.getName()
+        + "' />"
+        + "    <exception-handler exception-class='org.hibernate.HibernateException'>"
+        + "      <script>System.out.println(executionContext.getException().getMessage());</script>"
+        + "    </exception-handler>"
+        + "    <transition to='end' />"
+        + "  </decision>"
+        + "  <end-state name='end' />"
+        + "</process-definition>");
+    ProcessInstance processInstance = new ProcessInstance(processDefinition);
+    processInstance.signal();
+    assertTrue("expected " + processInstance + " to have ended", processInstance.hasEnded());
+  }
+
+  public void testHandleExceptionInDecisionHandlerAndMoveToken() {
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString("<process-definition name='jbpm1954'>"
+        + "  <start-state>"
+        + "    <transition to='decision' />"
+        + "  </start-state>"
+        + "  <decision name='decision'>"
+        + "    <handler class='"
+        + ProblematicDecisionHandler.class.getName()
+        + "' />"
+        + "    <exception-handler exception-class='org.hibernate.HibernateException'>"
+        + "      <script>token.setNode(executionContext.getProcessDefinition().getNode(\"error\"));</script>"
+        + "    </exception-handler>"
+        + "    <transition to='end' />"
+        + "  </decision>"
+        + "  <state name='error'/>"
+        + "  <end-state name='end' />"
+        + "</process-definition>");
+    ProcessInstance processInstance = new ProcessInstance(processDefinition);
+    processInstance.signal();
+    assertSame(processDefinition.getNode("error"), processInstance.getRootToken().getNode());
+  }
+
+  public static class ProblematicDecisionHandler implements DecisionHandler {
+    private static final long serialVersionUID = 1L;
+
+    public String decide(ExecutionContext executionContext) throws Exception {
+      throw new HibernateException("simulated failure");
+    }
+  }
+}




More information about the jbpm-commits mailing list