[jbpm-commits] JBoss JBPM SVN: r6360 - in jbpm4/trunk/modules: jpdl/src/main/java/org/jbpm/jpdl/internal/activity and 6 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Wed May 19 03:50:13 EDT 2010


Author: alex.guizar at jboss.com
Date: 2010-05-19 03:50:12 -0400 (Wed, 19 May 2010)
New Revision: 6360

Added:
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/events/TaskSkip.java
Modified:
   jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/history/HistoryTask.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/TaskActivity.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/Signal.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/task/TaskImpl.java
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/timer/TaskTimerTaskTest.java
Log:
JBPM-2537: mark incomplete task as obsolete before leaving it after expiration or external signal

Modified: jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/history/HistoryTask.java
===================================================================
--- jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/history/HistoryTask.java	2010-05-18 16:35:12 UTC (rev 6359)
+++ jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/history/HistoryTask.java	2010-05-19 07:50:12 UTC (rev 6360)
@@ -22,11 +22,9 @@
 package org.jbpm.api.history;
 
 import java.util.Date;
-import java.util.List;
 
 import org.jbpm.api.task.Task;
 
-
 /** history record for a task instance.  
  * 
  * In contrast to the {@link Task}, this entity will remain 
@@ -37,6 +35,7 @@
 public interface HistoryTask {
 
   String STATE_COMPLETED = "completed";
+  String STATE_OBSOLETE = "obsolete";
 
   /** the unique id for this task that is used as a reference in the service methods */
   String getId();
@@ -50,7 +49,7 @@
   /** might be null in case the activity is still active */
   Date getEndTime();
 
-  /** duration in milleseconds */
+  /** duration in milliseconds */
   long getDuration();
 
   /** history task state */  

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/TaskActivity.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/TaskActivity.java	2010-05-18 16:35:12 UTC (rev 6359)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/TaskActivity.java	2010-05-19 07:50:12 UTC (rev 6360)
@@ -34,7 +34,6 @@
 import org.jbpm.pvm.internal.history.events.TaskActivityStart;
 import org.jbpm.pvm.internal.model.ActivityImpl;
 import org.jbpm.pvm.internal.model.ExecutionImpl;
-import org.jbpm.pvm.internal.script.ScriptManager;
 import org.jbpm.pvm.internal.session.DbSession;
 import org.jbpm.pvm.internal.task.ParticipationImpl;
 import org.jbpm.pvm.internal.task.SwimlaneDefinitionImpl;
@@ -46,6 +45,8 @@
 /**
  * @author Tom Baeyens
  * @author Alejandro Guizar
+ * @author Ronald van Kuijk
+ * @author Maciej Swiderski
  */
 public class TaskActivity extends JpdlExternalActivity {
 
@@ -59,7 +60,7 @@
 
   public void execute(ExecutionImpl execution) {
     DbSession dbSession = EnvironmentImpl.getFromCurrent(DbSession.class);
-    TaskImpl task = (TaskImpl) dbSession.createTask();
+    TaskImpl task = dbSession.createTask();
     task.setTaskDefinition(taskDefinition);
     task.setExecution(execution);
     task.setProcessInstance(execution.getProcessInstance());
@@ -68,7 +69,8 @@
     // initialize the name
     if (taskDefinition.getName()!=null) {
       task.setName(taskDefinition.getName());
-    } else {
+    }
+    else {
       task.setName(execution.getActivityName());
     }
 
@@ -96,8 +98,9 @@
       
       // copy the swimlane assignments to the task
       task.setAssignee(swimlane.getAssignee());
-      for (ParticipationImpl participant: swimlane.getParticipations()) {
-        task.addParticipation(participant.getUserId(), participant.getGroupId(), participant.getType());
+      for (ParticipationImpl participant : swimlane.getParticipations()) {
+        task.addParticipation(participant.getUserId(), participant.getGroupId(),
+          participant.getType());
       }
     }
 
@@ -108,11 +111,13 @@
     execution.waitForSignal();
   }
   
-  public void signal(ActivityExecution execution, String signalName, Map<String, ?> parameters) throws Exception {
+  public void signal(ActivityExecution execution, String signalName, Map<String, ?> parameters)
+    throws Exception {
     signal((ExecutionImpl)execution, signalName, parameters);
   }
 
-  public void signal(ExecutionImpl execution, String signalName, Map<String, ?> parameters) throws Exception {
+  public void signal(ExecutionImpl execution, String signalName, Map<String, ?> parameters)
+    throws Exception {
     ActivityImpl activity = execution.getActivity();
     
     if (parameters!=null) {
@@ -121,8 +126,8 @@
     
     execution.fire(signalName, activity);
 
-    DbSession taskDbSession = EnvironmentImpl .getFromCurrent(DbSession.class);
-    TaskImpl task = (TaskImpl) taskDbSession.findTaskByExecution(execution);
+    DbSession taskDbSession = EnvironmentImpl.getFromCurrent(DbSession.class);
+    TaskImpl task = taskDbSession.findTaskByExecution(execution);
     if (task!=null) {
       task.setSignalling(false);
     }
@@ -130,45 +135,51 @@
     Transition transition = null;
     List<Transition> outgoingTransitions = activity.getOutgoingTransitions();
     
-    if ( (outgoingTransitions!=null) && (!outgoingTransitions.isEmpty()) ) {
-      
+    if (outgoingTransitions!=null && !outgoingTransitions.isEmpty()) {
       // Lookup the outgoing transition
-      
-      boolean noOutcomeSpecified =TaskConstants.NO_TASK_OUTCOME_SPECIFIED.equals(signalName); 
+      boolean noOutcomeSpecified = TaskConstants.NO_TASK_OUTCOME_SPECIFIED.equals(signalName);
       if (noOutcomeSpecified && activity.findOutgoingTransition(signalName) == null) {
         // When no specific outcome was specified, the unnamed transition
         // is looked up (name is null). If a null outcome was specifically
         // used, then the else clause will be used (but the result is the same)
         // Note: the second part of the if clause is to avoid the siutation
         // where the user would have chosen the same name as the constant
-        transition = activity.findOutgoingTransition(null); 
-      } else {
-        transition = activity.findOutgoingTransition(signalName);        
+        transition = activity.findOutgoingTransition(null);
       }
+      else {
+        transition = activity.findOutgoingTransition(signalName);
+      }
       
       // If no transition has been found, we check if we have a special case
       // in which we can still deduce the outgoing transition
-      
-      if (transition==null) { // no unnamed transition found
-        
-        if (signalName == null) { 
+      if (transition==null) {
+        // no unnamed transition found
+        if (signalName == null) {
           // null was explicitely given as outcome
-          throw new JbpmException("No unnamed transitions were found for the task '" + getTaskDefinition().getName() + "'"); 
-          
-        } else if (noOutcomeSpecified) { // Special case: complete(id)
-           
+          throw new JbpmException("No unnamed transitions were found for the task '"
+            + getTaskDefinition().getName() + "'");
+        }
+        else if (noOutcomeSpecified) {
+          // Special case: complete(id)
           if (outgoingTransitions.size() == 1) { // If only 1 transition, take that one
             transition = outgoingTransitions.get(0);
-          } else {
-            throw new JbpmException("No unnamed transitions were found for the task '" + getTaskDefinition().getName() + "'");                                          
           }
-          
-        } else {
+          else {
+            throw new JbpmException("No unnamed transitions were found for the task '"
+              + getTaskDefinition().getName() + "'");
+          }
+        }
+        else {
           // Likely a programmatic error.
-          throw new JbpmException("No transition named '" + signalName + "' was found."); 
+          throw new JbpmException("No transition named '" + signalName + "' was found.");
         }
       }
       
+      if (task != null && !task.isCompleted()) {
+        // task should be skipped since it is not completed yet !!!
+        task.skip(transition.getName());
+      }
+      
       if (transition!=null) {
         execution.take(transition);
       }

Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/events/TaskSkip.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/events/TaskSkip.java	                        (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/events/TaskSkip.java	2010-05-19 07:50:12 UTC (rev 6360)
@@ -0,0 +1,75 @@
+/*
+ * 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.pvm.internal.history.events;
+
+import org.hibernate.Session;
+import org.jbpm.api.history.HistoryTask;
+import org.jbpm.pvm.internal.env.EnvironmentImpl;
+import org.jbpm.pvm.internal.history.model.HistoryActivityInstanceImpl;
+import org.jbpm.pvm.internal.history.model.HistoryTaskImpl;
+import org.jbpm.pvm.internal.history.model.HistoryTaskInstanceImpl;
+import org.jbpm.pvm.internal.task.TaskImpl;
+import org.jbpm.pvm.internal.util.Clock;
+
+/**
+ * @author Maciej Swiderski
+ */
+public class TaskSkip extends ActivityEnd {
+
+  private static final long serialVersionUID = 1L;
+
+  protected String outcome;
+
+  public TaskSkip(TaskImpl taskImpl, String outcome) {
+    this(outcome);
+  }
+
+  public TaskSkip(String outcome) {
+    this.outcome = outcome;
+  }
+
+  @Override
+  protected void updateHistoryActivityInstance(
+    HistoryActivityInstanceImpl historyActivityInstance) {
+    super.updateHistoryActivityInstance(historyActivityInstance);
+
+    Session session = EnvironmentImpl.getFromCurrent(Session.class);
+    Long historyTaskInstanceId = execution.getHistoryActivityInstanceDbid();
+    HistoryTaskInstanceImpl historyTaskInstance = (HistoryTaskInstanceImpl) session
+      .load(HistoryTaskInstanceImpl.class, historyTaskInstanceId);
+    historyTaskInstance.setEndTime(Clock.getTime());
+    historyTaskInstance.setTransitionName(outcome);
+
+    HistoryTaskImpl historyTask = historyTaskInstance.getHistoryTask();
+    historyTask.setOutcome(outcome);
+    historyTask.setEndTime(Clock.getTime());
+    historyTask.setState(HistoryTask.STATE_OBSOLETE);
+
+    session.update(historyTaskInstance);
+  }
+
+  @Override
+  protected Class<? extends HistoryActivityInstanceImpl> getHistoryActivityInstanceClass() {
+    return HistoryTaskInstanceImpl.class;
+  }
+
+}


Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/history/events/TaskSkip.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java	2010-05-18 16:35:12 UTC (rev 6359)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java	2010-05-19 07:50:12 UTC (rev 6360)
@@ -46,6 +46,7 @@
  * @author Pascal Verdage
  * @author Alejandro Guizar
  * @author Ronald Van Kuijk
+ * @author Maciej Swiderski
  */
 public class TimerImpl extends JobImpl<Boolean> implements Timer {
 
@@ -84,6 +85,8 @@
     
     if (signalName!=null) {
       if (log.isDebugEnabled()) log.debug("feeding timer signal "+signalName+" into "+execution);
+      
+      // feed expiration signal
       execution.signal(signalName);
     }
     
@@ -139,11 +142,12 @@
     if ((getSignalName() == null) && (getEventName() == null)) {
       throw new JbpmException("timer has no signalName or eventName specified");
     }
-    if (getDueDate() == null) {
+    if (getDuedate() == null) {
       throw new JbpmException("timer scheduled at null date");
     }
   }
 
+  @Override
   public String toString() {
     StringBuilder text = new StringBuilder();
     text.append("timer[");

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java	2010-05-18 16:35:12 UTC (rev 6359)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java	2010-05-19 07:50:12 UTC (rev 6360)
@@ -21,7 +21,6 @@
  */
 package org.jbpm.pvm.internal.model;
 
-import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
@@ -83,11 +82,8 @@
 /**
  * @author Tom Baeyens
  */
-public class ExecutionImpl extends ScopeInstanceImpl 
-                           implements ClientProcessInstance,
-                                      ActivityExecution, 
-                                      EventListenerExecution, 
-                                      Serializable {
+public class ExecutionImpl extends ScopeInstanceImpl implements ClientProcessInstance,
+  ActivityExecution, EventListenerExecution {
 
   private static final long serialVersionUID = 1L;
 
@@ -110,7 +106,7 @@
 
   /** the parent child relation of executions is convenient for some forms of
    * concurrency. */
-  protected ExecutionImpl parent = null;
+  protected ExecutionImpl parent;
   protected ExecutionImpl processInstance;
   
   /** the super process link in case this is a sub process execution */  
@@ -174,13 +170,14 @@
   public enum Propagation {
     UNSPECIFIED, WAIT, EXPLICIT
   }
-  protected Propagation propagation = null;
 
+  protected Propagation propagation;
+
   // construction /////////////////////////////////////////////////////////////
   
   public void initializeProcessInstance(ProcessDefinitionImpl processDefinition, String key) {
     setProcessDefinition(processDefinition);
-    setActivity ( (ActivityImpl) processDefinition.getInitial() );
+    setActivity(processDefinition.getInitial());
     this.processInstance = this;
     this.state = STATE_CREATED;
     this.key = key;
@@ -203,7 +200,6 @@
     this.id = IdComposer.getIdComposer().createId(processDefinition, parent, this);
   }
 
-
   // execution method : start /////////////////////////////////////////////////
 
   public void start() {
@@ -276,11 +272,11 @@
     parent.setPropagation(getPropagation());
     
     ExecutionImpl parentsParent = parent.getParent();
-    if ( (parentsParent!=null)
-         && (STATE_INACTIVE_CONCURRENT_ROOT.equals(parentsParent.getState()))
-       ) {
+    if (parentsParent!=null
+      && STATE_INACTIVE_CONCURRENT_ROOT.equals(parentsParent.getState())) {
       parent.setState(STATE_ACTIVE_CONCURRENT);
-    } else {
+    }
+    else {
       parent.setState(STATE_ACTIVE_ROOT);
     }
     
@@ -293,14 +289,13 @@
     return parent;
   }
   
-  
+  @Override
   protected void destroyTimers(CompositeElementImpl scope) {
     TimerSession timerSession = EnvironmentImpl.getFromCurrent(TimerSession.class, false);
     if (timerSession!=null) {
       log.debug("destroying timers of "+this);
       List<Timer> timers = timerSession.findTimersByExecution(this);
       for (Timer timer: timers) {
-        
         Job job = EnvironmentImpl.getFromCurrent(JobImpl.class, false);
         if (timer!=job) {
           timerSession.cancel(timer);
@@ -309,9 +304,9 @@
     }
   }
 
-  
   // basic object methods /////////////////////////////////////////////////////
 
+  @Override
   public String toString() {
     if (getId()!=null) {
       return "execution["+id+"]";
@@ -347,7 +342,8 @@
     if (log.isDebugEnabled()) {
       if (state==STATE_ENDED) {
         log.debug(toString()+" ends");
-      } else {
+      }
+      else {
         log.debug(toString()+" ends with state "+state);
       }
     }
@@ -370,16 +366,17 @@
       if (dbSession!=null) {
         dbSession.delete(this);
       }
-      
-    } else { // this is a process instance
+    }
+    else {
+      // this is a process instance
       HistoryEvent.fire(new ProcessInstanceEnd(), this);
       fire(Event.END, getProcessDefinition());
 
       if (superProcessExecution!=null) {
         log.trace(toString()+" signals super process execution");
         superProcessExecution.signal();
-
-      } else if (dbSession!=null) {
+      }
+      else if (dbSession != null) {
         dbSession.deleteProcessInstance(id, false);
       }
     }
@@ -393,7 +390,6 @@
     ((ExecutionImpl)executionToEnd).end(state);
   }
 
-
   // execution method : signal ////////////////////////////////////////////////
 
   public void signal() {
@@ -416,9 +412,11 @@
     propagation = Propagation.EXPLICIT;
     if (getActivity()!=null) {
       performAtomicOperation(new Signal(signal, parameters));
-    } else if (transition!=null) {
+    }
+    else if (transition != null) {
       performAtomicOperation(AtomicOperation.TRANSITION_START_ACTIVITY);
-    } else {
+    }
+    else {
       throw new JbpmException("execution is not in a activity or in a transition");
     }
   }
@@ -518,19 +516,19 @@
     TransitionImpl defaultTransition = findDefaultTransition();
     if (defaultTransition!=null) {
       take(defaultTransition);
-      
+    }
     // in block structured processDefinition languages we assume that 
     // there is no default transition and that there is a 
     // parent activity of the current activity
-    } else {
+    else {
       ActivityImpl parentActivity = getActivity().getParentActivity();
 
       // if there is a parent activity
       if (parentActivity!=null) {
         // propagate to the parent
         performAtomicOperation(AtomicOperation.PROPAGATE_TO_PARENT);
-        
-      }  else {
+      }
+      else {
         // When we don't know how to proceed, i don't know if it's best to 
         // throw new PvmException("don't know how to proceed");
         // or to end the execution.  Because of convenience for testing, 
@@ -554,7 +552,8 @@
     fire(eventName, (ObservableElementImpl) eventSource, null);
   }
 
-  public void fire(String eventName, ObservableElementImpl observableElement, AtomicOperation eventCompletedOperation) {
+  public void fire(String eventName, ObservableElementImpl observableElement,
+    AtomicOperation eventCompletedOperation) {
     EventImpl event = findEvent(observableElement, eventName);
     if (event!=null) {
       setEvent(event);
@@ -562,11 +561,10 @@
       setEventListenerIndex(0);
       setEventCompletedOperation(eventCompletedOperation);
       performAtomicOperation(AtomicOperation.EXECUTE_EVENT_LISTENER);
-    } else {
-      if (eventCompletedOperation!=null) {
-        performAtomicOperationSync(eventCompletedOperation);
-      }
     }
+    else if (eventCompletedOperation != null) {
+      performAtomicOperationSync(eventCompletedOperation);
+    }
   }
   
   public static EventImpl findEvent(ObservableElementImpl observableElement, String eventName) {
@@ -613,7 +611,8 @@
   public synchronized void performAtomicOperation(AtomicOperation operation) {
     if (operation.isAsync(this)) {
       sendContinuationMessage(operation);
-    } else {
+    }
+    else {
       performAtomicOperationSync(operation);
     }
   }
@@ -631,7 +630,6 @@
 
   public void performAtomicOperationSync(AtomicOperation operation) {
     if (atomicOperations==null) {
-      
       // initialise the fifo queue of atomic operations
       atomicOperations = new LinkedList<AtomicOperation>();
       atomicOperations.offer(operation);
@@ -640,12 +638,13 @@
       ExecutionContext executionContext = null;
       EnvironmentImpl environment = EnvironmentImpl.getCurrent();
       if (environment!=null) {
-        originalExecutionContext = (ExecutionContext) environment.getContext(Context.CONTEXTNAME_EXECUTION);
-        if ( (originalExecutionContext!=null)
-             && (originalExecutionContext.getExecution()==this)
-           ) {
+        originalExecutionContext = (ExecutionContext) environment
+          .getContext(Context.CONTEXTNAME_EXECUTION);
+        if (originalExecutionContext != null
+          && originalExecutionContext.getExecution() == this) {
           originalExecutionContext = null;
-        } else {
+        }
+        else {
           executionContext = new ExecutionContext(this);
           environment.setContext(executionContext);
         }
@@ -656,10 +655,8 @@
           AtomicOperation atomicOperation = atomicOperations.poll();
           atomicOperation.perform(this);
         }
-
-      } catch (RuntimeException e ) {
-        throw e;
-      } finally {
+      }
+      finally {
         atomicOperations = null;
         
         if (executionContext!=null) {
@@ -669,7 +666,8 @@
           environment.setContext(originalExecutionContext);
         }
       }
-    } else {
+    }
+    else {
       atomicOperations.offer(operation);
     }
   }
@@ -684,12 +682,13 @@
     ExecutionContext executionContext = null;
     EnvironmentImpl environment = EnvironmentImpl.getCurrent();
     if (environment!=null) {
-      originalExecutionContext = (ExecutionContext) environment.getContext(Context.CONTEXTNAME_EXECUTION);
-      if ( (originalExecutionContext!=null)
-           && (originalExecutionContext.getExecution()==this)
-         ) {
+      originalExecutionContext = (ExecutionContext) environment
+        .getContext(Context.CONTEXTNAME_EXECUTION);
+      if (originalExecutionContext != null
+        && originalExecutionContext.getExecution() == this) {
         originalExecutionContext = null;
-      } else {
+      }
+      else {
         executionContext = new ExecutionContext(this);
         environment.setContext(executionContext);
       }
@@ -698,10 +697,12 @@
     try {
       ScriptManager scriptManager = ScriptManager.getScriptManager();
       return scriptManager.evaluateScript(expression, language);
-    } catch(RuntimeException e) {
+    }
+    catch (RuntimeException e) {
       log.error("Error while evaluation script " + expression, e);
       throw e;
-    } finally {
+    }
+    finally {
       if (executionContext != null) {
         environment.removeContext(executionContext);
       }
@@ -711,11 +712,8 @@
     }
   }
 
-  public void handleException(ObservableElementImpl observableElement,
-                              EventImpl event,
-                              EventListenerReference eventListenerReference,
-                              Exception exception,
-                              String rethrowMessage) {
+  public void handleException(ObservableElementImpl observableElement, EventImpl event,
+    EventListenerReference eventListenerReference, Exception exception, String rethrowMessage) {
     
     List<ProcessElementImpl> processElements = new ArrayList<ProcessElementImpl>();
     if (eventListenerReference!=null) {
@@ -737,7 +735,8 @@
             try {
               exceptionHandler.handle(this, exception);
               return;
-            } catch (Exception rethrowException) {
+            }
+            catch (Exception rethrowException) {
               if (!exceptionHandler.isRethrowMasked()) {
                 exception = rethrowException;
               }
@@ -752,13 +751,13 @@
     ExceptionHandlerImpl.rethrow(exception, rethrowMessage+": "+exception.getMessage());
   }
   
-  
   // tasks ////////////////////////////////////////////////////////////////////
 
   /** tasks and swimlane assignment.
    * SwimlaneDefinitionImpl is base class for TaskDefinitionImpl.
    * Both Task and Swimlane implement Assignable. */
-  public void initializeAssignments(AssignableDefinitionImpl assignableDefinition, Assignable assignable) {
+  public void initializeAssignments(AssignableDefinitionImpl assignableDefinition,
+    Assignable assignable) {
     Expression assigneeExpression = assignableDefinition.getAssigneeExpression();
     if (assigneeExpression!=null) {
       String assignee = (String) assigneeExpression.evaluate(this);
@@ -788,19 +787,21 @@
       }
     }
     
-    UserCodeReference assignmentHandlerReference = assignableDefinition.getAssignmentHandlerReference();
+    UserCodeReference assignmentHandlerReference = assignableDefinition
+      .getAssignmentHandlerReference();
     if (assignmentHandlerReference!=null) {
-      
       // JBPM-2758 
       // TODO Find out why processdefinition is null in at this time....
       if (processDefinition == null) {
-    	  processDefinition = getProcessDefinition();
+        processDefinition = getProcessDefinition();
       }
-      AssignmentHandler assignmentHandler = (AssignmentHandler) assignmentHandlerReference.getObject(processDefinition);
+      AssignmentHandler assignmentHandler = (AssignmentHandler) assignmentHandlerReference
+        .getObject(processDefinition);
       if (assignmentHandler!=null) {
         try {
           assignmentHandler.assign(assignable, this);
-        } catch (Exception e) {
+        }
+        catch (Exception e) {
           throw new JbpmException("assignment handler threw exception: " + e, e);
         }
       }
@@ -810,9 +811,7 @@
   protected String resolveAssignmentExpression(String expression, String expressionLanguage) {
     ScriptManager scriptManager = EnvironmentImpl.getFromCurrent(ScriptManager.class);
     Object result = scriptManager.evaluateExpression(expression, expressionLanguage);
-    if ( (result ==null)
-         || (result instanceof String)
-       ) {
+    if (result == null || result instanceof String) {
       return (String) result;
     }
     throw new JbpmException("result of assignment expression "+expression+" is "+result+" ("+result.getClass().getName()+") instead of String");
@@ -830,8 +829,8 @@
   }
   
   public void removeSwimlane(SwimlaneImpl swimlane) {
-      swimlanes.remove(swimlane.getName());
-      swimlane.setExecution(null);
+    swimlanes.remove(swimlane.getName());
+    swimlane.setExecution(null);
   }
 
   public SwimlaneImpl getInitializedSwimlane(SwimlaneDefinitionImpl swimlaneDefinition) {
@@ -905,7 +904,7 @@
   /** @see Execution#getExecution(String) */
   public ExecutionImpl getExecution(String name) {
     Map<String, Execution> executionsMap = getExecutionsMap();
-    return (ExecutionImpl) (executionsMap!=null ? executionsMap.get(name) : null);
+    return executionsMap != null ? (ExecutionImpl) executionsMap.get(name) : null;
   }
 
   public void removeExecution(ExecutionImpl child) {
@@ -915,14 +914,15 @@
 
         // invalidate the executionsMap cache
         executionsMap = null;
-      } else {
-        throw new JbpmException(child+" is not a child execution of "+this);
       }
+      else {
+        throw new JbpmException(child + " is not a child execution of " + this);
+      }
     }
   }
 
   public Map<String, Execution> getExecutionsMap() {
-    if ((executionsMap==null)) {
+    if (executionsMap == null) {
       // initialize executionsMap cache
       executionsMap = new HashMap<String, Execution>();
       for(ExecutionImpl execution: executions) {
@@ -938,9 +938,7 @@
   }
   
   public boolean hasExecution(String name) {
-    return ( (getExecutionsMap()!=null)
-             && executionsMap.containsKey(name)
-           );
+    return getExecutionsMap() != null && executionsMap.containsKey(name);
   }
 
   public boolean isActive(String activityName) {
@@ -952,10 +950,8 @@
   }
 
   protected Set<String> addActiveActivityNames(Set<String> activityNames) {
-    if ( ( (state.equals(STATE_ACTIVE_ROOT)) || (state.equals(STATE_ACTIVE_CONCURRENT)) )
-         && 
-         (activityName!=null)
-       ) {
+    if ((state.equals(STATE_ACTIVE_ROOT) || state.equals(STATE_ACTIVE_CONCURRENT))
+      && activityName != null) {
       activityNames.add(activityName);
     }
   
@@ -967,8 +963,7 @@
   }
 
   public ExecutionImpl findActiveExecutionIn(String activityName) {
-    if ( activityName.equals(this.activityName)
-         && isActive()) {
+    if (activityName.equals(this.activityName) && isActive()) {
       return this;
     }
 
@@ -998,7 +993,8 @@
     if (variable!=null) {
       log.debug("setting system variable '"+key+"' in '"+this+"' to value '"+value+"'");
       variable.setValue(value, this);
-    } else {
+    }
+    else {
       log.debug("creating system variable '"+key+"' in '"+this+"' to value '"+value+"'");
       createSystemVariable(key, value, null);
     }
@@ -1014,7 +1010,7 @@
   
   public boolean removeSystemVariable(String key) {
     if (systemVariables.containsKey(key)) {
-      return (systemVariables.remove(key)!=null);
+      return systemVariables.remove(key) != null;
     }
     return false;
   }
@@ -1047,6 +1043,7 @@
   // state mgmt ///////////////////////////////////////////////////////////////
 
   /** @see Execution#suspend() */
+  @Override
   public void suspend() {
     super.suspend();
     this.propagation = Propagation.EXPLICIT;
@@ -1057,6 +1054,7 @@
   }
 
   /** @see Execution#resume() */
+  @Override
   public void resume() {
     super.resume();
     DbSession hibernatePvmDbSession = EnvironmentImpl.getFromCurrent(DbSession.class, false);
@@ -1150,6 +1148,7 @@
   // equals ///////////////////////////////////////////////////////////////////
   // hack to support comparing hibernate proxies against the real objects
   // since this always falls back to ==, we don't need to overwrite the hashcode
+  @Override
   public boolean equals(Object o) {
     return EqualsUtil.equals(this, o);
   }
@@ -1159,13 +1158,11 @@
   // process definition id.                                                  //
   /////////////////////////////////////////////////////////////////////////////
   
-  
   public ProcessDefinitionImpl getProcessDefinition() {
-    if ( (processDefinition==null)
-         && (processDefinitionId!=null) 
-       ) {
-      RepositorySession repositorySession = EnvironmentImpl.getFromCurrent(RepositorySession.class);
-      processDefinition = (ProcessDefinitionImpl) repositorySession.findProcessDefinitionById(processDefinitionId);
+    if (processDefinition == null && processDefinitionId != null) {
+      RepositorySession repositorySession = EnvironmentImpl
+        .getFromCurrent(RepositorySession.class);
+      processDefinition = repositorySession.findProcessDefinitionById(processDefinitionId);
       if (processDefinition==null) {
         throw new JbpmException("couldn't find process definition "+processDefinitionId+" in the repository");
       }
@@ -1183,9 +1180,7 @@
   /////////////////////////////////////////////////////////////////////////////
   
   public ActivityImpl getActivity() {
-    if ( (activity==null)
-         && (activityName!=null)
-       ) {
+    if (activity == null && activityName != null) {
       activity = getProcessDefinition().findActivity(activityName);
     }
     return activity;
@@ -1195,7 +1190,8 @@
     this.activity = activity;
     if (activity!=null) {
       this.activityName = activity.getName();
-    } else {
+    }
+    else {
       this.activityName = null;
     }
   }
@@ -1209,9 +1205,7 @@
   public boolean hasAsyncEndEvent(List<ActivityImpl> leftActivities) {
     for (ActivityImpl leftActivity : leftActivities) {
       EventImpl endEvent = leftActivity.getEvent(Event.END);
-      if ( (endEvent!=null)
-           && (endEvent.isAsync())
-         ) {
+      if (endEvent != null && endEvent.isAsync()) {
         return true;
       }
     }
@@ -1224,6 +1218,7 @@
 
   // getters and setters for scope instance //////////////////////////////////////
   
+  @Override
   public ExecutionImpl getExecution() {
     return this;
   }
@@ -1243,7 +1238,7 @@
     return eventSource;
   }
   public Collection<ExecutionImpl> getExecutions() {
-    return (Collection) executions;
+    return executions;
   }
   public String getName() {
     return name;

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/Signal.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/Signal.java	2010-05-18 16:35:12 UTC (rev 6359)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/op/Signal.java	2010-05-19 07:50:12 UTC (rev 6360)
@@ -40,49 +40,53 @@
 
   private static final Log log = Log.getLog(Signal.class.getName());
 
-  String signalName;
-  Map<String, ?> parameters;
+  private final String signalName;
+  private final Map<String, ?> parameters;
 
   public Signal(String signalName, Map<String, ?> parameters) {
     this.signalName = signalName;
     this.parameters = parameters;
   }
 
+  @Override
   public boolean isAsync(ExecutionImpl execution) {
     return false;
   }
 
+  @Override
   public void perform(ExecutionImpl execution) {
     ActivityImpl activity = execution.getActivity();
-    
-    if (execution.getName()!=null) {
-      log.debug(execution.toString()+" signals "+activity);
-    } else {
-      log.debug("signalling "+activity+", signalName="+signalName);
+    if (execution.getName() != null) {
+      log.debug(execution.toString() + " signals " + activity);
     }
+    else {
+      log.debug("signalling " + activity + ", signalName=" + signalName);
+    }
 
-    ExternalActivityBehaviour externalActivityBehaviour = (ExternalActivityBehaviour) activity.getActivityBehaviour();
-    
+    ExternalActivityBehaviour activityBehaviour = (ExternalActivityBehaviour) activity
+      .getActivityBehaviour();
     try {
       execution.setPropagation(Propagation.UNSPECIFIED);
-      externalActivityBehaviour.signal(execution, signalName, parameters);
-
-    } catch (RuntimeException e) {
+      activityBehaviour.signal(execution, signalName, parameters);
+    }
+    catch (RuntimeException e) {
       throw e;
-      
-    } catch (Exception e) {
-      throw new JbpmException("couldn't signal "+activity+": "+e.getMessage(), e);
     }
+    catch (Exception e) {
+      throw new JbpmException("couldn't signal " + activity + ": " + e.getMessage(), e);
+    }
 
     if (execution.getPropagation() == Propagation.UNSPECIFIED) {
       execution.proceed();
     }
   }
   
+  @Override
   public String toString() {
-    return "Signal";
+    return "Signal(" + signalName + ')';
   }
 
+  @Override
   public MessageImpl<?> createAsyncMessage(ExecutionImpl execution) {
     return null;
   }

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/task/TaskImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/task/TaskImpl.java	2010-05-18 16:35:12 UTC (rev 6359)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/task/TaskImpl.java	2010-05-19 07:50:12 UTC (rev 6360)
@@ -21,7 +21,6 @@
  */
 package org.jbpm.pvm.internal.task;
 
-import java.io.Serializable;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashSet;
@@ -37,6 +36,7 @@
 import org.jbpm.pvm.internal.client.ClientExecution;
 import org.jbpm.pvm.internal.env.EnvironmentImpl;
 import org.jbpm.pvm.internal.history.HistoryEvent;
+import org.jbpm.pvm.internal.history.events.TaskSkip;
 import org.jbpm.pvm.internal.history.events.TaskComplete;
 import org.jbpm.pvm.internal.history.events.TaskDelete;
 import org.jbpm.pvm.internal.model.ExecutionImpl;
@@ -49,13 +49,14 @@
 /**
  * is one task instance that can be assigned to an actor (read: put in someone's task list) and that
  * can trigger the continuation of execution of the token upon completion.
+ * 
+ * @author Tom Baeyens
+ * @author Ronald van Kuijk
  */
-public class TaskImpl extends ScopeInstanceImpl implements Serializable, OpenTask, Assignable {
+public class TaskImpl extends ScopeInstanceImpl implements OpenTask, Assignable {
 
   private static final long serialVersionUID = 1L;
 
-  // private static Log log = Log.getLog(TaskImpl.class.getName());
-
   protected boolean isNew;
   protected String name;
   protected String description;
@@ -97,10 +98,12 @@
 
   // parent for variable lookup /////////////////////////////////////////////// 
 
+  @Override
   public ScopeInstanceImpl getParentVariableScope() {
     return execution;
   }
   
+  @Override
   public TaskImpl getTask() {
     return this;
   }
@@ -147,7 +150,7 @@
       allRoles = new HashSet<ParticipationImpl>(participations);
     }
     if (swimlane != null) {
-      allRoles.addAll((Set) swimlane.getParticipations());
+      allRoles.addAll(swimlane.getParticipations());
     }
     return allRoles;
   }
@@ -194,7 +197,7 @@
     }
 
     if (isSignalling()) {
-      ClientExecution execution = (ClientExecution) getExecution();
+      ClientExecution execution = getExecution();
       execution.signal(outcome);
     }
     
@@ -210,13 +213,23 @@
     historyTaskDelete(reason);
   }
 
+  public void skip(String outcome) {
+    if (outcome == null || outcome.equals("")) {
+      outcome = TaskConstants.NO_TASK_OUTCOME_SPECIFIED;
+    }
+    
+    historyTaskSkip(outcome);
+    
+    DbSession dbSession = EnvironmentImpl.getFromCurrent(DbSession.class, false);
+    if (dbSession!=null){
+      dbSession.delete(this);
+    }
+  }
+
   // state ////////////////////////////////////////////////////////////////////
 
   public boolean isCompleted() {
-    if (Task.STATE_COMPLETED.equals(state)) {
-      return true;
-    }
-    if ((Task.STATE_OPEN.equals(state)) || (Task.STATE_SUSPENDED.equals(state))) {
+    if (Task.STATE_OPEN.equals(state) || Task.STATE_SUSPENDED.equals(state)) {
       return false;
     }
     return true;
@@ -225,15 +238,13 @@
   // subtasks /////////////////////////////////////////////////////////////////
 
   public Set<Task> getSubTasks() {
-    if (subTasks == null) {
-      return Collections.emptySet();
-    }
-    return (Set) subTasks;
+    return subTasks != null ? Collections.<Task> unmodifiableSet(subTasks) :
+      Collections.<Task> emptySet();
   }
 
   public TaskImpl createSubTask() {
     DbSession dbSession = EnvironmentImpl.getFromCurrent(DbSession.class);
-    TaskImpl subTask = (TaskImpl) dbSession.createTask();
+    TaskImpl subTask = dbSession.createTask();
     if (subTasks == null) {
       subTasks = new HashSet<TaskImpl>();
     }
@@ -270,10 +281,12 @@
   // equals ///////////////////////////////////////////////////////////////////
   // hack to support comparing hibernate proxies against the real objects
   // since this always falls back to ==, we don't need to overwrite the hashcode
+  @Override
   public boolean equals(Object o) {
     return EqualsUtil.equals(this, o);
   }
 
+  @Override
   public String toString() {
     return "Task(" + name + ")";
   }
@@ -310,6 +323,12 @@
     }
   }
 
+  public void historyTaskSkip(String outcome) {
+    if (execution != null) {
+      HistoryEvent.fire(new TaskSkip(outcome), execution);
+    }
+  }
+
   public void signalExecution(String signalName) {
     if (execution != null) {
       execution.signal(signalName);
@@ -386,6 +405,7 @@
     this.duedate = duedate;
   }
 
+  @Override
   public ExecutionImpl getExecution() {
     return execution;
   }

Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/timer/TaskTimerTaskTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/timer/TaskTimerTaskTest.java	2010-05-18 16:35:12 UTC (rev 6359)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/timer/TaskTimerTaskTest.java	2010-05-19 07:50:12 UTC (rev 6360)
@@ -19,21 +19,24 @@
  * 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.test.timer;
 
 import java.util.List;
 
+import org.jbpm.api.Execution;
 import org.jbpm.api.ProcessInstance;
+import org.jbpm.api.history.HistoryTask;
 import org.jbpm.api.job.Job;
 import org.jbpm.api.task.Task;
 import org.jbpm.test.JbpmTestCase;
 
-
 /**
+ * A triggered timer does not end the task which is left.
+ * 
+ * @see <a href="https://jira.jboss.org/browse/JBPM-2537">JBPM-2537</a>
  * @author Joram Barrez
+ * @author Ronald van Kuijk
+ * @author Maciej Swiderski
  */
 public class TaskTimerTaskTest extends JbpmTestCase {
   
@@ -54,29 +57,57 @@
       "</process>");
     
     ProcessInstance processInstance = executionService.startProcessInstanceByKey("TaskTimer");
-    
-    assertEquals(1, taskService.createTaskQuery()
-                      .assignee("johndoe")
-                      .list()
-                      .size() );
-    
-    Job timer = managementService.createJobQuery()
-        .processInstanceId(processInstance.getId())
-        .timers()
-        .uniqueResult();
-    
+
+    List<Task> tasks = taskService.createTaskQuery().assignee("johndoe").list();
+    assertEquals(1, tasks.size());
+
+    Job timer = managementService
+      .createJobQuery()
+      .processInstanceId(processInstance.getId())
+      .timers()
+      .uniqueResult();
     assertNotNull(timer);
     
     managementService.executeJob(timer.getId());
-    
     assertActivityActive(processInstance.getId(), "go to cafeteria");
 
-//  TODO JBPM-2537    
-//    assertEquals(0, taskService.createTaskQuery()
-//            .assignee("johndoe")
-//            .list()
-//            .size() );
+    assertEquals(0, taskService.createTaskQuery().assignee("johndoe").list().size());
+
+    String taskId = tasks.get(0).getId();
+    List<HistoryTask> history = historyService.createHistoryTaskQuery().taskId(taskId).list();
+    assertEquals(1, history.size());
+    assertEquals(HistoryTask.STATE_OBSOLETE, history.get(0).getState());
   }
 
+  public void testTaskClosedBySignal() {
+    deployJpdlXmlString("<process name='TaskTimer'>" +
+      "  <start name='start'>" +
+      "    <transition to='do work' />" +
+      "  </start>" +
+      "  <task name='do work' assignee='johndoe'>" +
+      "    <transition name='done' to='go home' />" +
+      "    <transition name='lunch' to='go to cafeteria'>" +
+      "      <timer duedate='10 seconds' />" +
+      "    </transition>" +
+      "  </task>" +
+      "  <state name='go home' />" +
+      "  <state name='go to cafeteria' />" +
+      "</process>");
 
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("TaskTimer");
+
+    List<Task> tasks = taskService.createTaskQuery().assignee("johndoe").list();
+    assertEquals(1, tasks.size());
+
+    Execution exec = processInstance.findActiveExecutionIn("do work");
+    processInstance = executionService.signalExecutionById(exec.getId(), "done");
+    assertActivityActive(processInstance.getId(), "go home");
+
+    assertEquals(0, taskService.createTaskQuery().assignee("johndoe").list().size());
+
+    String taskId = tasks.get(0).getId();
+    List<HistoryTask> history = historyService.createHistoryTaskQuery().taskId(taskId).list();
+    assertEquals(1, history.size());
+    assertEquals(HistoryTask.STATE_OBSOLETE, history.get(0).getState());
+  }
 }



More information about the jbpm-commits mailing list