[jbpm-commits] JBoss JBPM SVN: r6087 - in jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn: parser and 1 other directory.

do-not-reply at jboss.org do-not-reply at jboss.org
Mon Jan 18 05:57:00 EST 2010


Author: jbarrez
Date: 2010-01-18 05:56:59 -0500 (Mon, 18 Jan 2010)
New Revision: 6087

Added:
   jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java
Modified:
   jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/BpmnActivity.java
   jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java
   jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java
   jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java
Log:
Refactored gateway types: moved common operations to AbstractMergingGatewayActivity for both Parallel and Inclusive Gateway

Added: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java	                        (rev 0)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java	2010-01-18 10:56:59 UTC (rev 6087)
@@ -0,0 +1,182 @@
+/*
+ * 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.bpmn.flownodes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hibernate.LockMode;
+import org.hibernate.Session;
+import org.jbpm.api.Execution;
+import org.jbpm.api.JbpmException;
+import org.jbpm.api.activity.ActivityExecution;
+import org.jbpm.internal.log.Log;
+import org.jbpm.pvm.internal.env.EnvironmentImpl;
+import org.jbpm.pvm.internal.model.Activity;
+import org.jbpm.pvm.internal.model.ExecutionImpl;
+
+/**
+ * Superclass for gateway activities that wait on multiple incoming executions before merging
+ * them together. 
+ * 
+ * The {@link InclusiveGatewayActivity} and {@link ParallelGatewayActivity} are examples of such
+ * gateways which have merge behaviour. 
+ * 
+ * @author Joram Barrez
+ */
+public abstract class AbstractMergingGatewayActivity extends AbstractGatewayActivity {
+  
+  private static final long serialVersionUID = 1L;
+
+  private static final Log LOG = Log.getLog(AbstractMergingGatewayActivity.class.getName());
+  
+  protected LockMode lockMode = LockMode.UPGRADE;
+  
+  public void execute(ActivityExecution execution) {
+    execute((ExecutionImpl) execution);
+  }
+  
+  /**
+   * Executing the actvity logic is common for all gateway types that have merge/split behaviour.
+   * 
+   * For all incoming sequence flow, the gateway will handle the executions. When all sequence
+   * flow have arrived at the gateway, the fork logic is executed (a gateway can have both
+   * merging and splitting behaviour).
+   */
+  public void execute(ExecutionImpl execution) { 
+    int nrOfIncoming = execution.getActivity().getIncomingTransitions().size();
+    
+    if (nrOfIncoming == 1) { // no join behaviour needed, save some time and do a fork immediately
+      
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Only one incoming sequence flow found. Executing fork logic.");
+      }
+      fork(execution);
+      
+    } else {
+      
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Multiple incoming sequence flow found. Executing join logic.");
+      }
+      boolean allExecutionsArrived = handleIncomingExecution(execution);
+      
+      // After executing the join functionality, it could be that all executions have arrived 
+      // at the gateway. In that case, the gateway can be left.
+      if (allExecutionsArrived) {
+        ExecutionImpl outgoingExecution = join(execution);
+        fork(outgoingExecution);
+      }
+      
+    }
+  }
+  
+  /**
+   * Joins the incoming executions.
+   * Returns true if all executions have reached the gateway.
+   */
+  protected boolean handleIncomingExecution(ExecutionImpl execution) {
+    if (Execution.STATE_ACTIVE_CONCURRENT.equals(execution.getState())) {
+     
+      // force version increment in the parent execution
+      Session session = EnvironmentImpl.getFromCurrent(Session.class);
+      session.lock(execution.getParent(), lockMode);
+
+      execution.setState(Execution.STATE_INACTIVE_JOIN);
+      execution.waitForSignal();
+
+      return isComplete(execution);
+      
+    } else {
+      throw new JbpmException("invalid execution state: " + execution.getState());
+    }
+  }
+  
+  /**
+   * Joins all the incoming executions currently waiting at the gateway.
+   * 
+   * @return An execution that can be used to leave the gateway (one outgoing sequence flow)
+   * or to create child executions on (fork behaviour when multiple outgoing sequence flow).
+   */
+  protected ExecutionImpl join(ExecutionImpl execution) {
+    Activity activity = execution.getActivity();
+    ExecutionImpl concurrentRoot = execution.getParent();
+    List<ExecutionImpl> joinedExecutions = getJoinedExecutions(concurrentRoot, activity);
+    
+    endJoinedExecutions(joinedExecutions);
+      
+    ExecutionImpl outgoingExecution = null;
+    if (concurrentRoot.getExecutions().size() == 0) {
+      outgoingExecution = concurrentRoot;
+      outgoingExecution.setState(Execution.STATE_ACTIVE_ROOT);
+    } else {
+      outgoingExecution = concurrentRoot.createExecution();
+      outgoingExecution.setState(Execution.STATE_ACTIVE_CONCURRENT);
+    }
+      
+    outgoingExecution.setActivity(activity);
+    return outgoingExecution;
+  }
+  
+  /**
+   * @return All executions currently waiting at the gateway.
+   */
+  protected List<ExecutionImpl> getJoinedExecutions(ExecutionImpl concurrentRoot, Activity activity) {
+    List<ExecutionImpl> joinedExecutions = new ArrayList<ExecutionImpl>();
+    List<ExecutionImpl> concurrentExecutions = (List<ExecutionImpl>)concurrentRoot.getExecutions();
+    for (ExecutionImpl concurrentExecution: (List<ExecutionImpl>)concurrentExecutions) {
+      if ( (Execution.STATE_INACTIVE_JOIN.equals(concurrentExecution.getState()))
+           && (concurrentExecution.getActivity()==activity)
+         ) {
+        joinedExecutions.add(concurrentExecution);
+      }
+    }
+    
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Found " + joinedExecutions.size() + " executions currently waiting at the gateway");
+    }
+    
+    return joinedExecutions;
+  }
+
+  /**
+   * Ends all executions in the given list.
+   */
+  protected void endJoinedExecutions(List<ExecutionImpl> joinedExecutions) {
+    for (ExecutionImpl joinedExecution: joinedExecutions) {
+      joinedExecution.end();
+    }
+  }
+  
+  /*
+   * Fork (or 'split') behaviour is dependent on the actual gateway type and cannot be 
+   * generalized.
+   */
+  protected abstract void fork(ExecutionImpl execution);
+  
+  /*
+   * Checking if all incoming sequence flow have arrived at the gateway is gateway type dependent. 
+   * Eg for the parallel gateway, all incoming sequence flow need to arrive at the gateway, while
+   * for the inclusive gateway it depends on the remaining executions in the process instance.
+   */
+  protected abstract boolean isComplete(ExecutionImpl executionImpl);
+
+}

Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/BpmnActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/BpmnActivity.java	2010-01-18 09:55:50 UTC (rev 6086)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/BpmnActivity.java	2010-01-18 10:56:59 UTC (rev 6087)
@@ -35,7 +35,7 @@
 import org.jbpm.pvm.internal.model.Transition;
 
 /**
- * Basic activity for BPMN activities (tasks, gateways and event)
+ * Basic activity for BPMN activities (tasks, gateways)
  * 
  * @author bernd.ruecker at camunda.com
  * @author Ronald van Kuijk (kukeltje)
@@ -49,6 +49,8 @@
 
   protected static final boolean CONDITIONS_CHECKED = true;
   protected static final boolean CONDITIONS_IGNORED = !CONDITIONS_CHECKED;
+  
+  protected String default_;
 
   protected List<ActivityResource> activityResources = new ArrayList<ActivityResource>();
 
@@ -140,5 +142,22 @@
   public void addActivityResource(ActivityResource activityResource) {
     this.activityResources.add(activityResource);
   }
+  
+  /**
+   * Most of the BPMN activities allow to specify a default outgoing sequence
+   * flow. Subclasses must override this method when the default definition does
+   * not make sense (eg. ParallelGateway)
+   */
+  public boolean isDefaultEnabled() {
+    return true; 
+  }
+  
+  public String getDefault() {
+    return default_;
+  }
 
+  public void setDefault(String default_) {
+    this.default_ = default_;
+  }
+
 }
\ No newline at end of file

Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java	2010-01-18 09:55:50 UTC (rev 6086)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java	2010-01-18 10:56:59 UTC (rev 6087)
@@ -40,46 +40,12 @@
 /**
  * @author Joram Barrez
  */
-public class InclusiveGatewayActivity extends DatabasedGatewayActivity {
+public class InclusiveGatewayActivity extends AbstractMergingGatewayActivity {
 
   private static final long serialVersionUID = 1L;
   
   private static final Log LOG = Log.getLog(InclusiveGatewayActivity.class.getName());
   
-  protected LockMode lockMode = LockMode.UPGRADE;
-
-  public void execute(ActivityExecution execution) throws Exception {
-    execute((ExecutionImpl) execution);
-  }
-  
-  public void execute(ExecutionImpl execution) {
-    int nrOfIncoming = execution.getActivity().getIncomingTransitions().size();
-    
-    if (nrOfIncoming == 1) { // no merge behaviour needed, save some time and do a fork immediately
-      if (LOG.isDebugEnabled()) {
-        LOG.debug("Only one incoming sequence flow found. Executing fork logic only.");
-      }
-      fork(execution);
-    } else {
-   
-      if (LOG.isDebugEnabled()) {
-        LOG.debug("Multiple incoming sequence flow found. Executing join logic.");
-      }
-      boolean allExecutionsArrived = handleIncomingExecution(execution);
-      
-      if (allExecutionsArrived) {
-        if (LOG.isDebugEnabled()) {
-          LOG.debug("All executions have reached the inclusive join. Executing fork logic.");
-        }
-        ExecutionImpl outgoingExecution = join(execution);
-        fork(outgoingExecution);
-      }
-      
-    }
-    
-   
-  }
-  
   public void fork(ExecutionImpl execution) {
     List<Transition> outgointSeqFlow = findOutgoingSequenceFlow(execution, CONDITIONS_CHECKED);
     
@@ -97,53 +63,6 @@
   }
   
   /**
-   * Joins the incoming executions.
-   * Returns true if all executions have reached the gateway.
-   */
-  protected boolean handleIncomingExecution(ExecutionImpl execution) {
-    if (Execution.STATE_ACTIVE_CONCURRENT.equals(execution.getState())) {
-     
-      // force version increment in the parent execution
-      Session session = EnvironmentImpl.getFromCurrent(Session.class);
-      session.lock(execution.getParent(), lockMode);
-
-      execution.setState(Execution.STATE_INACTIVE_JOIN);
-      execution.waitForSignal();
-
-      return isComplete(execution);
-      
-    } else {
-      throw new JbpmException("invalid execution state: " + execution.getState());
-    }
-  }
-  
-  /**
-   * Joins all the incoming executions currently waiting at the gateway.
-   * 
-   * @return An execution that can be used to leave the gateway (one outgoing sequence flow)
-   * or to create child executions on (fork behaviour when multiple outgoing sequence flow).
-   */
-  protected ExecutionImpl join(ExecutionImpl execution) {
-    Activity activity = execution.getActivity();
-    ExecutionImpl concurrentRoot = execution.getParent();
-    List<ExecutionImpl> joinedExecutions = getJoinedExecutions(concurrentRoot, activity);
-    
-    endJoinedExecutions(joinedExecutions);
-      
-    ExecutionImpl outgoingExecution = null;
-    if (concurrentRoot.getExecutions().size() == 0) {
-      outgoingExecution = concurrentRoot;
-      outgoingExecution.setState(Execution.STATE_ACTIVE_ROOT);
-    } else {
-      outgoingExecution = concurrentRoot.createExecution();
-      outgoingExecution.setState(Execution.STATE_ACTIVE_CONCURRENT);
-    }
-      
-    outgoingExecution.setActivity(activity);
-    return outgoingExecution;
-  }
-  
-  /**
    * Section 14.3.2 of the BPMN 2.0 specification.
    * 
    * The Inclusive Gateway is activated if 
@@ -171,30 +90,5 @@
     
     return true;
   }
-  
-  protected List<ExecutionImpl> getJoinedExecutions(ExecutionImpl concurrentRoot, Activity activity) {
-    List<ExecutionImpl> joinedExecutions = new ArrayList<ExecutionImpl>();
-    List<ExecutionImpl> concurrentExecutions = (List<ExecutionImpl>)concurrentRoot.getExecutions();
-    for (ExecutionImpl concurrentExecution: (List<ExecutionImpl>)concurrentExecutions) {
-      if ( (Execution.STATE_INACTIVE_JOIN.equals(concurrentExecution.getState()))
-           && (concurrentExecution.getActivity()==activity)
-         ) {
-        joinedExecutions.add(concurrentExecution);
-      }
-    }
-    
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("Found " + joinedExecutions.size() + " executions currently waiting at the gateway");
-    }
-    
-    return joinedExecutions;
-  }
 
-  protected void endJoinedExecutions(List<ExecutionImpl> joinedExecutions) {
-    for (ExecutionImpl joinedExecution: joinedExecutions) {
-      joinedExecution.end();
-    }
-  }
-  
-
 }

Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java	2010-01-18 09:55:50 UTC (rev 6086)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java	2010-01-18 10:56:59 UTC (rev 6087)
@@ -21,16 +21,9 @@
  */
 package org.jbpm.bpmn.flownodes;
 
-import java.util.ArrayList;
 import java.util.List;
 
-import org.hibernate.LockMode;
-import org.hibernate.Session;
-import org.jbpm.api.Execution;
-import org.jbpm.api.JbpmException;
-import org.jbpm.api.activity.ActivityExecution;
 import org.jbpm.internal.log.Log;
-import org.jbpm.pvm.internal.env.EnvironmentImpl;
 import org.jbpm.pvm.internal.model.Activity;
 import org.jbpm.pvm.internal.model.ExecutionImpl;
 
@@ -38,96 +31,16 @@
  * @author Ronald van Kuijk (kukeltje)
  * @author Joram Barrez
  */
-public class ParallelGatewayActivity extends AbstractGatewayActivity {
+public class ParallelGatewayActivity extends AbstractMergingGatewayActivity {
 
   private static final Log LOG = Log.getLog(ParallelGatewayActivity.class.getName());
   
   private static final long serialVersionUID = 1L;
   
-  protected LockMode lockMode = LockMode.UPGRADE;
-
-  public void execute(ActivityExecution execution) {
-    execute((ExecutionImpl) execution);
-  }
-
-  public void execute(ExecutionImpl execution) { 
-    int nrOfIncoming = execution.getActivity().getIncomingTransitions().size();
-    
-    if (nrOfIncoming == 1) { // no join behaviour needed, save some time and do a fork immediately
-      
-      if (LOG.isDebugEnabled()) {
-        LOG.debug("Only one incoming sequence flow found. Executing fork logic.");
-      }
-      fork(execution);
-      
-    } else {
-      
-      if (LOG.isDebugEnabled()) {
-        LOG.debug("Multiple incoming sequence flow found. Executing join logic.");
-      }
-      boolean allExecutionsArrived = handleIncomingExecution(execution);
-      
-      // After executing the join functionality, it could be that all executions have arrived 
-      // at the gateway. In that case, the gateway can be left.
-      if (allExecutionsArrived) {
-        ExecutionImpl outgoingExecution = join(execution);
-        fork(outgoingExecution);
-      }
-      
-    }
-  }
-  
   protected void fork(ExecutionImpl execution) {
     proceed(execution, findOutgoingSequenceFlow(execution, CONDITIONS_IGNORED));
   }
   
-  /**
-   * Joins the incoming executions.
-   * Returns true if all executions have reached the gateway.
-   */
-  protected boolean handleIncomingExecution(ExecutionImpl execution) {
-    if (Execution.STATE_ACTIVE_CONCURRENT.equals(execution.getState())) {
-     
-      // force version increment in the parent execution
-      Session session = EnvironmentImpl.getFromCurrent(Session.class);
-      session.lock(execution.getParent(), lockMode);
-
-      execution.setState(Execution.STATE_INACTIVE_JOIN);
-      execution.waitForSignal();
-
-      return isComplete(execution);
-      
-    } else {
-      throw new JbpmException("invalid execution state: " + execution.getState());
-    }
-  }
-  
-  /**
-   * Joins all the incoming executions currently waiting at the gateway.
-   * 
-   * @return An execution that can be used to leave the gateway (one outgoing sequence flow)
-   * or to create child executions on (fork behaviour when multiple outgoing sequence flow).
-   */
-  protected ExecutionImpl join(ExecutionImpl execution) {
-    Activity activity = execution.getActivity();
-    ExecutionImpl concurrentRoot = execution.getParent();
-    List<ExecutionImpl> joinedExecutions = getJoinedExecutions(concurrentRoot, activity);
-    
-    endJoinedExecutions(joinedExecutions);
-      
-    ExecutionImpl outgoingExecution = null;
-    if (concurrentRoot.getExecutions().size() == 0) {
-      outgoingExecution = concurrentRoot;
-      outgoingExecution.setState(Execution.STATE_ACTIVE_ROOT);
-    } else {
-      outgoingExecution = concurrentRoot.createExecution();
-      outgoingExecution.setState(Execution.STATE_ACTIVE_CONCURRENT);
-    }
-      
-    outgoingExecution.setActivity(activity);
-    return outgoingExecution;
-  }
-  
   protected boolean isComplete(ExecutionImpl execution) {
     
     Activity activity = execution.getActivity();
@@ -140,33 +53,10 @@
     }
     return result;
   }
-
-  protected List<ExecutionImpl> getJoinedExecutions(ExecutionImpl concurrentRoot, Activity activity) {
-    List<ExecutionImpl> joinedExecutions = new ArrayList<ExecutionImpl>();
-    List<ExecutionImpl> concurrentExecutions = (List<ExecutionImpl>)concurrentRoot.getExecutions();
-    for (ExecutionImpl concurrentExecution: (List<ExecutionImpl>)concurrentExecutions) {
-      if ( (Execution.STATE_INACTIVE_JOIN.equals(concurrentExecution.getState()))
-           && (concurrentExecution.getActivity()==activity)
-         ) {
-        joinedExecutions.add(concurrentExecution);
-      }
-    }
-    
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("Found " + joinedExecutions.size() + " executions currently waiting at the gateway");
-    }
-    
-    return joinedExecutions;
-  }
-
-  protected void endJoinedExecutions(List<ExecutionImpl> joinedExecutions) {
-    for (ExecutionImpl joinedExecution: joinedExecutions) {
-      joinedExecution.end();
-    }
-  }
   
-  public void setLockMode(LockMode lockMode) {
-    this.lockMode = lockMode;
+  @Override
+  public boolean isDefaultEnabled() {
+    return false;
   }
   
 }

Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java	2010-01-18 09:55:50 UTC (rev 6086)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java	2010-01-18 10:56:59 UTC (rev 6087)
@@ -32,6 +32,7 @@
 import org.jbpm.api.activity.ActivityBehaviour;
 import org.jbpm.bpmn.common.Resource;
 import org.jbpm.bpmn.common.ResourceParameter;
+import org.jbpm.bpmn.flownodes.BpmnActivity;
 import org.jbpm.bpmn.flownodes.BpmnBinding;
 import org.jbpm.bpmn.flownodes.DatabasedGatewayActivity;
 import org.jbpm.bpmn.model.BpmnProcessDefinition;
@@ -247,10 +248,10 @@
       try {
         // If something went wrong parsing the activity, there is no behaviour and an exception is thrown in .getBehaviour()
         ActivityBehaviour behaviour = processDefinition.findActivity(sourceRef).getActivityBehaviour();
-        if (behaviour instanceof DatabasedGatewayActivity) {
-          DatabasedGatewayActivity databasedGatewayActivity = (DatabasedGatewayActivity) behaviour;
-          String defaultSeqFlow = databasedGatewayActivity.getDefault();
-          if (defaultSeqFlow != null) {
+        if (behaviour instanceof BpmnActivity) {
+          BpmnActivity bpmnActivity = (BpmnActivity) behaviour;
+          String defaultSeqFlow = bpmnActivity.getDefault();
+          if (bpmnActivity.isDefaultEnabled() && defaultSeqFlow != null) {
             if (transitionId.equals(defaultSeqFlow)) {
               processDefinition.findActivity(sourceRef).setDefaultOutgoingTransition(transition);
             }



More information about the jbpm-commits mailing list