[jbpm-commits] JBoss JBPM SVN: r1735 - in jbpm4/pvm/trunk/modules/core/src: main/java/org/jbpm/pvm/internal/jobexecutor and 6 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Mon Jul 28 07:11:28 EDT 2008


Author: pascal.verdage
Date: 2008-07-28 07:11:28 -0400 (Mon, 28 Jul 2008)
New Revision: 1735

Added:
   jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerTest.java
Removed:
   jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TestTimerSession.java
   jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TestTimerSessionBinding.java
   jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerConfiguration.java
   jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerIntegrationTest.java
   jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerUnitTest.java
Modified:
   jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java
   jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobTestTimerSession.java
   jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
   jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/model/TimerDefinitionImpl.java
   jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/model/ProcessFactory.java
   jbpm4/pvm/trunk/modules/core/src/main/resources/org/jbpm/pvm/hibernate.definition.hbm.xml
   jbpm4/pvm/trunk/modules/core/src/main/resources/org/jbpm/pvm/hibernate.job.hbm.xml
   jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/DbTests.java
   jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/pvm.wire.bindings.xml
   jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/IncrementCounterWaitState.java
   jbpm4/pvm/trunk/modules/core/src/test/resources/org/jbpm/pvm/timer/environment.cfg.xml
Log:
use scripting expressions to define timers

Modified: jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java	2008-07-28 11:11:28 UTC (rev 1735)
@@ -21,6 +21,7 @@
  */
 package org.jbpm.pvm.internal.job;
 
+import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
@@ -33,6 +34,7 @@
 import org.jbpm.pvm.internal.jobexecutor.JobAddedNotification;
 import org.jbpm.pvm.internal.jobexecutor.JobExecutor;
 import org.jbpm.pvm.internal.log.Log;
+import org.jbpm.pvm.internal.script.ScriptManager;
 import org.jbpm.pvm.internal.util.Clock;
 import org.jbpm.pvm.job.Timer;
 import org.jbpm.pvm.model.ObservableElement;
@@ -53,45 +55,115 @@
   private static final long serialVersionUID = 1L;
   private static final Log log = Log.getLog(TimerImpl.class.getName());
 
-  private final static String dateFormat = "yyyy-MM-dd HH:mm:ss,SSS";
+  private static String dateFormat = "yyyy-MM-dd HH:mm:ss,SSS";
 
   protected String signalName;
   protected String eventName;
   protected String repeat;
+  protected String language;
   
   public static final String EVENT_TIMER = "timer";
 
   public TimerImpl() {
   }
 
-  public void setDueDateDescription(String dueDateDescription) {
-    Duration duration = new Duration(dueDateDescription);
+  private static Date getDateFromDuration(String expression) {
+    Duration duration = new Duration(expression);
     Date now = Clock.getCurrentTime();
-    
+    Date result = null;
+
     if ( duration.isBusinessTime()
-         || duration.getMonths()>0 
-         || duration.getYears()>0
-       ) {
+        || duration.getMonths()>0 
+        || duration.getYears()>0
+    ) {
       Environment environment = Environment.getCurrent();
       if (environment==null) {
-        throw new PvmException("no environment to get business calendar for calculating dueDate "+dueDateDescription);
+        log.debug("no environment to get business calendar for calculating dueDate "+expression);
+      } else {
+        BusinessCalendar businessCalendar = environment.get(BusinessCalendar.class);
+        if (businessCalendar==null) {
+          log.debug("no business calendar to calculate dueDate "+expression);
+        } else {
+          result = businessCalendar.add(now, duration);
+        }
       }
-      BusinessCalendar businessCalendar = environment.get(BusinessCalendar.class);
-      dueDate = businessCalendar.add(now, duration);
-
     } else {
       long millis = duration.getMillis() + 
-                    1000*( duration.getSeconds() + 
-                           60*( duration.getMinutes() + 
-                                60*( duration.getHours() + 
-                                     24*( duration.getDays() + 
-                                          7*duration.getWeeks()))));
-      dueDate = new Date(now.getTime() + millis);
+      1000*( duration.getSeconds() + 
+          60*( duration.getMinutes() + 
+              60*( duration.getHours() + 
+                  24*( duration.getDays() + 
+                      7*duration.getWeeks()))));
+      result = new Date(now.getTime() + millis);
     }
+    return result;
   }
 
+  private Object evaluateExpression(String expression) {
+    Object result = null;
+    Environment environment = Environment.getCurrent();
+    if (environment==null) {
+      log.debug("no environment to get script manager to evaluate "+expression);
+    } else {
+      ScriptManager scriptManager = environment.getEnvironmentFactory().get(ScriptManager.class);
+      if (scriptManager==null) {
+        log.debug("no script manager to evaluate "+expression);
+      } else {
+        log.debug("evaluates "+expression);
+        result = scriptManager.evaluateExpression(expression, execution, language);
+      }
+    }
+    return result;
+  }
+
+  public void setDueDateDescription(String expression) {
+    Exception exception = null;
+    Object dueDateDescription = evaluateExpression(expression);
+
+    // now we analyse the description
+    Date date = null;
+    // date?
+    if (dueDateDescription instanceof Date) {
+      date = (Date)dueDateDescription;
+    } else if (dueDateDescription instanceof String) {
+      // formatted date?
+      try {
+        date = new SimpleDateFormat(dateFormat).parse((String) dueDateDescription);
+      } catch (ParseException e) {
+        // not a formatted date
+        exception = e;
+      }
+      
+      // duration?
+      try {
+        date = getDateFromDuration((String) dueDateDescription);
+      } catch (PvmException e) {
+        // not a duration
+        exception = e;
+      }
+    } else {
+      throw new PvmException("invalid timer's dueDateDescription");
+    }
+    
+    if (date!=null) {
+      setDueDate(date);
+    } else {
+      throw new PvmException("Unable to set dueDate from " + expression+". " +
+      		"This might be a environment configuration error", exception);
+    }
+  }
+
+  private void repeatTimer(String repeat) {
+    Object description = evaluateExpression(repeat);
+    if (description instanceof String && description!=null) {
+      setDueDate(getDateFromDuration((String)description));
+    } else {
+      throw new PvmException("invalid timer's repeat: "+repeat);
+    }
+  }
+
   public Boolean execute(Environment environment) throws Exception {
-    if (log.isDebugEnabled()) log.debug("executing " + this);
+    log.debug("executing " + this);
 
     if (environment==null) {
       throw new PvmException("environment is null");
@@ -101,13 +173,13 @@
     environment.addContext(jobContext);
     try {
       if (signalName!=null) {
-        if (log.isDebugEnabled()) log.debug("feeding timer signal "+signalName+" into "+execution);
+        log.debug("feeding timer signal "+signalName+" into "+execution);
         execution.signal(signalName);
       }
       
       if (eventName!=null) {
         ObservableElement eventSource = execution.getNode();
-        if (log.isDebugEnabled()) log.debug("firing event "+signalName+" into "+eventSource);
+        log.debug("firing event "+signalName+" into "+eventSource);
         execution.fire(eventName, eventSource);
       }
       
@@ -119,7 +191,7 @@
     // if there is no repeat on this timer
     if (repeat==null) {
       // delete the jobImpl
-      if (log.isDebugEnabled()) log.debug("deleting " + this);
+      log.debug("deleting " + this);
       DbSession dbSession = environment.get(DbSession.class);
       if (dbSession==null) {
         throw new PvmException("no "+DbSession.class.getName()+" in environment"); 
@@ -131,10 +203,10 @@
       // suppose that it took the timer runner thread a very long time to execute the timers
       // then the repeat action dueDate could already have passed
       do {
-        setDueDateDescription(repeat);
+        repeatTimer(repeat);
       } while (dueDate.getTime() <= Clock.getCurrentTime().getTime());
 
-      if (log.isDebugEnabled()) log.debug("rescheduled "+this+" for "+formatDueDate(dueDate));
+      log.debug("rescheduled "+this+" for "+formatDueDate(dueDate));
       
       // release the lock on the timer
       setLockOwner(null);
@@ -178,6 +250,9 @@
   public static String formatDueDate(Date date) {
 	  return new SimpleDateFormat(dateFormat).format(date);
   }
+  public static void setDateFormat(String dateFormat) {
+    TimerImpl.dateFormat = dateFormat;
+  }
 
   public String getSignalName() {
     return signalName;
@@ -197,4 +272,14 @@
   public void setRepeat(String repeat) {
     this.repeat = repeat;
   }
+
+  
+  public String getLanguage() {
+    return language;
+  }
+
+  
+  public void setLanguage(String language) {
+    this.language = language;
+  }
 }

Modified: jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobTestTimerSession.java
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobTestTimerSession.java	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobTestTimerSession.java	2008-07-28 11:11:28 UTC (rev 1735)
@@ -28,6 +28,7 @@
 
 /**
  * @author Tom Baeyens
+ * @author Pascal Verdage
  */
 public class JobTestTimerSession implements TimerSession {
   
@@ -35,11 +36,15 @@
   Session session;
 
   public void schedule(Timer timer) {
-    session.save(timer);
+    if (session!=null) {
+      session.save(timer);
+    }
   }
 
   public void cancel(Timer timer) {
-    session.delete(timer);
+    if (session!=null) {
+      session.delete(timer);
+    }
   }
 
 }

Modified: jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java	2008-07-28 11:11:28 UTC (rev 1735)
@@ -25,7 +25,6 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
@@ -76,6 +75,7 @@
 
 /**
  * @author Tom Baeyens
+ * @author Pascal Verdage
  */
 public class ExecutionImpl implements ClientProcessInstance,
                                       ActivityExecution, 
@@ -792,8 +792,8 @@
         createTimer(
             timerDefinition.getEventName(),
             timerDefinition.getSignalName(),
-            timerDefinition.getDueDateDescription(),
-            timerDefinition.getDueDate(),
+            timerDefinition.getExpression(),
+            timerDefinition.getLanguage(),
             timerDefinition.getRepeat(),
             timerDefinition.isExclusive(),
             timerDefinition.getRetries()
@@ -822,15 +822,16 @@
     }
   }
 
-  public void createTimer(String eventName, String signalName, String dueDateDescription) {
-    createTimer(eventName, signalName, dueDateDescription, null, null, null, null);
+  public void createTimer(String eventName, String signalName, String expression) {
+    createTimer(eventName, signalName, expression, null, null, null, null);
   }
 
-  public void createTimer(String eventName, String signalName, String dueDateDescription, String repeat) {
-    createTimer(eventName, signalName, dueDateDescription, null, repeat, null, null);
+  public void createTimer(String eventName, String signalName, String expression, String repeat) {
+    createTimer(eventName, signalName, expression, null, repeat, null, null);
   }
 
-  public void createTimer(String eventName, String signalName, String dueDateDescription, Date dueDate, String repeat, Boolean isExclusive, Integer retries) {
+  public void createTimer(String eventName, String signalName, String expression,
+      String language, String repeat, Boolean isExclusive, Integer retries) {
     if ( (eventName==null)
          && (signalName==null)
        ) {
@@ -846,16 +847,17 @@
     timerImpl.setExecution(this);
     timers.add(timerImpl);
     hasTimers = true;
-    // setInverseReference(timerImpl);
     
-    // initialise all the timer properties
+    // initialize all the timer properties
     timerImpl.setEventName(eventName);
     timerImpl.setSignalName(signalName);
-    if (dueDate!=null) {
-      timerImpl.setDueDate(dueDate);
-    } else {
-      timerImpl.setDueDateDescription(dueDateDescription);
+
+    // the if is added to keep the original default
+    if (language!=null) {
+      timerImpl.setLanguage(language);
     }
+    // language has to be set before expression
+    timerImpl.setDueDateDescription(expression);
     
     // the if is added to keep the original default
     if (isExclusive!=null) {

Modified: jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/model/TimerDefinitionImpl.java
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/model/TimerDefinitionImpl.java	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/internal/model/TimerDefinitionImpl.java	2008-07-28 11:11:28 UTC (rev 1735)
@@ -22,7 +22,6 @@
 package org.jbpm.pvm.internal.model;
 
 import java.io.Serializable;
-import java.util.Date;
 
 
 /**
@@ -35,13 +34,13 @@
 
   protected long dbid;
   protected int dbversion;
-  protected String dueDateDescription;
+  protected String expression;
+  protected String language;
   protected String repeat;
   protected Boolean isExclusive;
   protected Integer retries;
   protected String eventName;
   protected String signalName;
-  protected Date dueDate;
 
   public TimerDefinitionImpl() {
   }
@@ -55,12 +54,6 @@
   public long getDbid() {
     return dbid;
   }
-  public String getDueDateDescription() {
-    return dueDateDescription;
-  }
-  public void setDueDateDescription(String dueDateDescription) {
-    this.dueDateDescription = dueDateDescription;
-  }
   public Boolean isExclusive() {
     return isExclusive;
   }
@@ -85,10 +78,20 @@
   public void setEventName(String eventName) {
     this.eventName = eventName;
   }
-  public Date getDueDate() {
-    return dueDate;
+
+  public String getExpression() {
+    return expression;
   }
-  public void setDueDate(Date dueDate) {
-    this.dueDate = dueDate;
+
+  public void setExpression(String expression) {
+    this.expression = expression;
   }
+
+  public String getLanguage() {
+    return language;
+  }
+
+  public void setLanguage(String language) {
+    this.language = language;
+  }
 }

Modified: jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/model/ProcessFactory.java
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/model/ProcessFactory.java	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/main/java/org/jbpm/pvm/model/ProcessFactory.java	2008-07-28 11:11:28 UTC (rev 1735)
@@ -22,7 +22,6 @@
 package org.jbpm.pvm.model;
 
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 import java.util.Stack;
 
@@ -192,34 +191,26 @@
   }
 
   /** declares a timer on the current node or process. {@link #scope()} is 
-   * automatically implied. */
-  public ProcessFactory timer(String dueDateDescription, String signalName) {
-    return timer(dueDateDescription, null, signalName, null);
+   * automatically implied.
+   * @param expression can be a formatted date or duration 
+   * or an expression in the default expression language if defined */
+  public ProcessFactory timer(String expression, String signalName) {
+    return timer(expression, null, signalName, null);
   }
 
   /** declares a timer on the current node or process. {@link #scope()} is 
-   * automatically implied. */
-  public ProcessFactory timer(String dueDateDescription, String signalName, String repeat) {
-    return timer(dueDateDescription, null, signalName, repeat);
-  }
-
-  /** declares a timer on the current node or process. {@link #scope()} is 
-   * automatically implied. */
-  public ProcessFactory timer(Date dueDate, String signalName) {
-    return timer(null, dueDate, signalName, null);
-  }
-
-  protected ProcessFactory timer(String dueDateDescription, Date dueDate,
-    String signalName, String repeat) {
+   * automatically implied.
+   * @param expression can be a formatted date or duration
+   * or an expression in the given language.
+   * @param language is a supposed known language (environment configuration) */
+  public ProcessFactory timer(String expression, String language,
+      String signalName, String repeat) {
     if (node!=null && scope==null) {
       scope();
     }
     TimerDefinitionImpl timerDefinition = scope.createTimerDefinition();
-    if (dueDate!=null) {
-      timerDefinition.setDueDate(dueDate);
-    } else {
-      timerDefinition.setDueDateDescription(dueDateDescription);
-    }
+    timerDefinition.setExpression(expression);
+    timerDefinition.setLanguage(language);
     timerDefinition.setSignalName(signalName);
     timerDefinition.setRepeat(repeat);
     return this;

Modified: jbpm4/pvm/trunk/modules/core/src/main/resources/org/jbpm/pvm/hibernate.definition.hbm.xml
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/main/resources/org/jbpm/pvm/hibernate.definition.hbm.xml	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/main/resources/org/jbpm/pvm/hibernate.definition.hbm.xml	2008-07-28 11:11:28 UTC (rev 1735)
@@ -378,13 +378,13 @@
       <generator class="native" />
     </id>
     <version name="dbversion" column="DBVERSION_" />
-    <property name="dueDateDescription" column="DUEDATEDESCR_"/>
+    <property name="expression" column="EXPRESSION_"/>
+    <property name="language" column="LANGUAGE_"/>
     <property name="repeat" column="REPEAT_"/>
     <property name="isExclusive" column="ISEXCL_"/>
     <property name="retries" column="RETRIES_"/>
     <property name="eventName" column="EVENT_"/>
     <property name="signalName" column="SIGNAL_"/>
-    <property name="dueDate" column="DUEDATE_" type="timestamp"/>
   </class>
   
   <!-- ### QUERIES ######################################################## -->

Modified: jbpm4/pvm/trunk/modules/core/src/main/resources/org/jbpm/pvm/hibernate.job.hbm.xml
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/main/resources/org/jbpm/pvm/hibernate.job.hbm.xml	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/main/resources/org/jbpm/pvm/hibernate.job.hbm.xml	2008-07-28 11:11:28 UTC (rev 1735)
@@ -49,6 +49,7 @@
       <property name="signalName" column="SIGNAL_" />
       <property name="eventName" column="EVENT_" />
       <property name="repeat" column="REPEAT_" />
+      <property name="language" column="LANGUAGE_" />
     </subclass>
      
 	</class>

Modified: jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/DbTests.java
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/DbTests.java	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/DbTests.java	2008-07-28 11:11:28 UTC (rev 1735)
@@ -28,6 +28,7 @@
 import org.jbpm.pvm.db.model.DbModelTests;
 import org.jbpm.pvm.db.svc.DbSvcTests;
 import org.jbpm.pvm.jobexecutor.JobExecutorTests;
+import org.jbpm.pvm.timer.DbTimerTests;
 
 
 /**
@@ -43,7 +44,8 @@
     suite.addTest(DbModelTests.suite());
     suite.addTest(DbSvcTests.suite());
     suite.addTest(JobExecutorTests.suite());
-    
+    suite.addTest(DbTimerTests.suite());
+
     //$JUnit-END$
     return suite;
   }

Modified: jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/pvm.wire.bindings.xml
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/pvm.wire.bindings.xml	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/pvm.wire.bindings.xml	2008-07-28 11:11:28 UTC (rev 1735)
@@ -1,5 +1,2 @@
 <wire-bindings>
-
-  <binding class="org.jbpm.pvm.timer.TestTimerSessionBinding" />
-
 </wire-bindings>

Modified: jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/IncrementCounterWaitState.java
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/IncrementCounterWaitState.java	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/IncrementCounterWaitState.java	2008-07-28 11:11:28 UTC (rev 1735)
@@ -53,8 +53,10 @@
       }
     }
     if (continueToWait) {
+      log.debug("continue to wait");
       execution.waitForSignal();
     } else {
+      log.debug("take a timeout transition");
       execution.take("timeout");
     }
   }

Deleted: jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TestTimerSession.java
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TestTimerSession.java	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TestTimerSession.java	2008-07-28 11:11:28 UTC (rev 1735)
@@ -1,85 +0,0 @@
-/*
- * 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.timer;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import org.jbpm.pvm.env.Environment;
-import org.jbpm.pvm.internal.job.TimerImpl;
-import org.jbpm.pvm.job.Timer;
-import org.jbpm.pvm.session.TimerSession;
-
-/**
- * @author Tom Baeyens
- * @author Pascal Verdage
- */
-public class TestTimerSession implements TimerSession {
-  
-  private static final long serialVersionUID = 1L;
-  
-  protected List<TimerImpl> timers = new ArrayList<TimerImpl>();
-
-  public void cancel(Timer timer) {
-    timers.remove(timer);
-  }
-
-  public void schedule(Timer timer) {
-    timers.add((TimerImpl)timer);
-  }
-
-  /** execute the first timer (ordered by dueDate) 
-   * @throws Exception */
-  public void executeFirstTimer() throws Exception {
-    TimerImpl timerImpl = getFirstTimer();
-    if (timerImpl != null) {
-      TimerConfiguration.getEnvironmentFactory().openEnvironment();
-      try {
-        boolean deleteThisJob = timerImpl.execute(Environment.getCurrent());
-        if (deleteThisJob) {
-          timers.remove(timerImpl);
-        }
-      } finally {
-        Environment.getCurrent().close();
-      }
-    }
-  }
-
-  /** return the first timer (ordered by dueDate) */
-  public TimerImpl getFirstTimer() {
-    TimerImpl firstTimer = null;
-    Date firstDueDate = new Date(Long.MAX_VALUE);
-    for (TimerImpl timerImpl : timers) {
-      if (firstDueDate.after(timerImpl.getDueDate())) {
-        firstTimer = timerImpl;
-        firstDueDate = timerImpl.getDueDate();
-      }
-    }
-    return firstTimer;
-  }
-
-  /** return the number of scheduled timers */
-  public int getNbTimer() {
-    return timers.size();
-  }
-}

Deleted: jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TestTimerSessionBinding.java
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TestTimerSessionBinding.java	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TestTimerSessionBinding.java	2008-07-28 11:11:28 UTC (rev 1735)
@@ -1,45 +0,0 @@
-/*
- * 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.timer;
-
-import org.jbpm.pvm.internal.util.TagBinding;
-import org.jbpm.pvm.internal.wire.descriptor.ObjectDescriptor;
-import org.jbpm.pvm.internal.wire.xml.WireParser;
-import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
-import org.w3c.dom.Element;
-
-
-/**
- * @author Tom Baeyens
- */
-public class TestTimerSessionBinding extends TagBinding {
-
-  public TestTimerSessionBinding() {
-    super("test-timer-session", null, WireParser.CATEGORY_DESCRIPTOR);
-  }
-
-  public Object parse(Element element, Parse parse, Parser parser) {
-    return new ObjectDescriptor(TestTimerSession.class);
-  }
-
-}

Deleted: jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerConfiguration.java
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerConfiguration.java	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerConfiguration.java	2008-07-28 11:11:28 UTC (rev 1735)
@@ -1,50 +0,0 @@
- package org.jbpm.pvm.timer;
-
-import org.jbpm.pvm.ExecutionService;
-import org.jbpm.pvm.ManagementService;
-import org.jbpm.pvm.ProcessService;
-import org.jbpm.pvm.env.EnvironmentFactory;
-import org.jbpm.pvm.env.PvmEnvironmentFactory;
-
-/**
- * @author Pascal Verdage
- */
-public abstract class TimerConfiguration {
-
-  static boolean isInitialized;
-  static ProcessService processService;
-  static ExecutionService executionService;
-  static ManagementService managementService;
-  static EnvironmentFactory environmentFactory;
-    
-  public static ProcessService getProcessService() {
-    initialize();
-    return processService; 
-  }
-
-  public static ExecutionService getExecutionService() {
-    initialize();
-    return executionService; 
-  }
-
-  public static ManagementService getManagementService() {
-    initialize();
-    return managementService; 
-  }
-
-  public static EnvironmentFactory getEnvironmentFactory() {
-    initialize();
-    return environmentFactory; 
-  }
-
-  private synchronized static void initialize() {
-    if (!isInitialized) {
-      isInitialized = true;
-      environmentFactory = new PvmEnvironmentFactory("org/jbpm/pvm/timer/environment.cfg.xml");
-      processService = environmentFactory.get(ProcessService.class);
-      executionService = environmentFactory.get(ExecutionService.class);
-      managementService = environmentFactory.get(ManagementService.class);
-    }
-  }
-
-}

Deleted: jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerIntegrationTest.java
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerIntegrationTest.java	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerIntegrationTest.java	2008-07-28 11:11:28 UTC (rev 1735)
@@ -1,342 +0,0 @@
-/**
- * Copyright (C) 2006  Bull S. A. S.
- * Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois
- * This library 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
- * version 2.1 of the License.
- * This library 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
- * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA  02110-1301, USA.
- **/
-package org.jbpm.pvm.timer;
-
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.jbpm.pvm.Execution;
-import org.jbpm.pvm.ExecutionService;
-import org.jbpm.pvm.ProcessService;
-import org.jbpm.pvm.activity.ActivityExecution;
-import org.jbpm.pvm.activity.ExternalActivity;
-import org.jbpm.pvm.env.Environment;
-import org.jbpm.pvm.internal.model.ExecutionImpl;
-import org.jbpm.pvm.internal.model.NodeImpl;
-import org.jbpm.pvm.internal.util.Clock;
-import org.jbpm.pvm.job.JobTestHelper;
-import org.jbpm.pvm.job.Timer;
-import org.jbpm.pvm.model.OpenExecution;
-import org.jbpm.pvm.model.ProcessDefinition;
-import org.jbpm.pvm.model.ProcessFactory;
-import org.jbpm.pvm.samples.activities.AutomaticActivity;
-import org.jbpm.pvm.session.DbSession;
-import org.jbpm.pvm.session.PvmDbSession;
-import org.jbpm.pvm.test.base.DbTestCase;
-
-/**
- * @author Pascal Verdage
- */
-public class TimerIntegrationTest extends DbTestCase {
-  public static class WaitState implements ExternalActivity {
-
-    private static final long serialVersionUID = 1L;
-
-    public void execute(ActivityExecution execution) {
-      execution.waitForSignal();
-    }
-
-    public void signal(ActivityExecution execution, 
-                       String signalName, 
-                       Map<String, Object> parameters) {
-      if (signalName!=null) {
-        execution.take(signalName);
-      }
-    }
-  }
-
-  private static Date getDueDate(long duration) {
-    return new Date(System.currentTimeMillis() + duration);
-  }
-  
-  private static long twoDaysDuration = 2*24*60*60*1000;
-
-  private static ExecutionService getExecutionService() {
-    return Environment.getCurrent().get(ExecutionService.class);
-  }
-
-  private static ExecutionImpl deployAndInstanciateProcess(ProcessDefinition definition) {
-    ProcessService processService = Environment.getCurrent().get(ProcessService.class);
-    processService.deploy(definition);
-
-    Execution processInstance = getExecutionService().startExecution(definition.getName());   
-
-    return (ExecutionImpl) processInstance;
-  }
-
-  public void testTimerDefinition() {
-    ProcessDefinition processDefinition = ProcessFactory.build("timerDefinition")
-      .node("request").initial().behaviour(WaitState.class)
-        .transition().to("decide")
-      .node("decide").behaviour(WaitState.class)
-        .timer(getDueDate(twoDaysDuration), "timeout")
-        .transition("decision made").to("response") // first defined transition is the default one
-        .transition("timeout").to("reassign")
-      .node("reassign").behaviour(WaitState.class)
-      .node("response").behaviour(WaitState.class)
-    .done();
-    
-    ExecutionImpl processInstance = deployAndInstanciateProcess(processDefinition);
-
-    Execution execution = processInstance;
-    assertEquals("request", execution.getNodeName());
-    // first node is a wait state with no timer
-    execution = getExecutionService().signalExecution(execution.getDbid());
-    assertEquals("decide", execution.getNodeName());
-
-    assertTrue(execution instanceof OpenExecution);
-    OpenExecution openExecution = (OpenExecution) execution;
-
-    // timer are created in a child execution
-    assertFalse(openExecution.hasTimers());
-
-    assertEquals(1, openExecution.getExecutions().size());
-    OpenExecution child = openExecution.getExecutions().iterator().next();
-
-    NodeImpl node1 = (NodeImpl) openExecution.getNode();
-    NodeImpl node2 = (NodeImpl) child.getNode();
-    assertEquals(node1, node2);
-    assertEquals("decide", node1.getName());
-    assertNotNull(node1.getTimerDefinitions());
-
-    assertTrue(child.hasTimers());
-    Set<Timer> timers = child.getTimers();
-    assertEquals(1, timers.size());
-  }
-
-  private static ExecutionImpl loadExecutionFromDb(long id) {
-    return Environment.getCurrent().get(DbSession.class).get(ExecutionImpl.class, id);
-  }
-
-  public void testTimerExecution() {
-    ProcessDefinition processDefinition = ProcessFactory.build("timerExecution")
-      .node("decide").initial().behaviour(WaitState.class)
-        .timer(getDueDate(twoDaysDuration), "timeout")
-        .transition("decision made").to("response") // first defined transition is the default one
-        .transition("timeout").to("reassign")
-      .node("reassign").behaviour(WaitState.class)
-      .node("response").behaviour(WaitState.class)
-    .done();
-    
-    ExecutionImpl processInstance = deployAndInstanciateProcess(processDefinition);
-    
-    Execution execution = processInstance;
-    assertEquals("decide", execution.getNodeName());
-
-    OpenExecution child = ((OpenExecution) execution).getExecutions().iterator().next();
-    assertEquals("decide", child.getNodeName());
-    Timer timer = child.getTimers().iterator().next();
-
-    JobTestHelper jobTestHelper = getEnvironmentFactory().get(JobTestHelper.class);
-    child = (OpenExecution) jobTestHelper.executeTimer(timer.getDbid());
-    assertEquals(Execution.STATE_ENDED, child.getState());
-
-    // check that the subExecution was deleted
-    child = loadExecutionFromDb(child.getDbid());
-    assertNull(child);
-
-    // check that timers have been deleted
-    List<Timer> timers = Environment.getCurrent().get(PvmDbSession.class).findTimers();
-    assertNotNull(timers);
-    assertTrue(timers.isEmpty());
-
-    // check that process is in the right state
-    execution = loadExecutionFromDb(processInstance.getDbid());
-    assertEquals("reassign", execution.getNodeName());
-  }
-
-  public void testCanceledTimer() {
-    ProcessDefinition processDefinition = ProcessFactory.build("timerCanceled")
-      .node("decide").initial().behaviour(WaitState.class)
-        .timer(getDueDate(twoDaysDuration), "timeout")
-        .transition("decision made").to("response") // first defined transition is the default one
-        .transition("timeout").to("reassign")
-      .node("reassign").behaviour(WaitState.class)
-      .node("response").behaviour(WaitState.class)
-    .done();
-
-    ExecutionImpl processInstance = deployAndInstanciateProcess(processDefinition);
-
-    Execution execution = processInstance;
-    assertEquals("decide", execution.getNodeName());
-
-    // signal child execution
-    Execution child = ((OpenExecution)execution).getExecutions().iterator().next();
-    execution = getExecutionService().signalExecution(child.getDbid());
-    assertEquals(Execution.STATE_ENDED, execution.getState());
-
-    // check that the subExecution was deleted
-    child = loadExecutionFromDb(child.getDbid());
-    assertNull(child);
-    
-    // check that timers have been deleted
-    List<Timer> timers = Environment.getCurrent().get(PvmDbSession.class).findTimers();
-    assertNotNull(timers);
-    assertTrue(timers.isEmpty());
-
-    // check that process is in the right state
-    execution = loadExecutionFromDb(processInstance.getDbid());
-    assertEquals("response", execution.getNodeName());
-  }
-
-  public void testFixedDateTimer() {
-    Date now = new Date();
-    long twoDaysFromNow = now.getTime() + twoDaysDuration;
-
-    ProcessDefinition processDefinition = ProcessFactory.build("fixedDateTimer")
-      .node("decide").initial().behaviour(WaitState.class)
-        .timer(getDueDate(twoDaysDuration), "timeout")
-        .transition("decision made").to("response") // first defined transition is the default one
-        .transition("timeout").to("reassign")
-      .node("reassign").behaviour(WaitState.class)
-      .node("response").behaviour(WaitState.class)
-    .done();
-
-    ExecutionImpl processInstance = deployAndInstanciateProcess(processDefinition);
-
-    Execution execution = processInstance;
-    OpenExecution child = ((OpenExecution) execution).getExecutions().iterator().next();
-    assertEquals("decide", child.getNodeName());
-
-    // check that timer's dueDate is good
-    Timer timer = child.getTimers().iterator().next();
-    assertTrue(twoDaysFromNow <= timer.getDueDate().getTime());
-    
-    // timer execution is tested in testTimerExecution
-  }
-
-  public void testDueDateDescriptionTimer() {
-    Date now = new Date();
-    long twoDaysFromNow = now.getTime() + twoDaysDuration;
-
-    ProcessDefinition processDefinition = ProcessFactory.build("dueDateDescriptionTimer")
-      .node("decide").initial().behaviour(WaitState.class)
-        .timer("2 days", "timeout")
-        .transition("decision made").to("response") // first defined transition is the default one
-        .transition("timeout").to("reassign")
-      .node("reassign").behaviour(WaitState.class)
-      .node("response").behaviour(WaitState.class)
-    .done();
-
-    ExecutionImpl processInstance = deployAndInstanciateProcess(processDefinition);
-
-    Execution execution = processInstance;
-    OpenExecution child = ((OpenExecution) execution).getExecutions().iterator().next();
-    assertEquals("decide", child.getNodeName());
-
-    // check that timer's dueDate is good
-    Timer timer = child.getTimers().iterator().next();
-    assertTrue(twoDaysFromNow <= timer.getDueDate().getTime());
-    
-    // timer execution is tested in testTimerExecution
-  }
-
-  public void testReschedulingTimer() {
-    Date now = Clock.getCurrentTime();
-    long twoDaysFromNow = now.getTime() + twoDaysDuration;
-
-    ProcessDefinition processDefinition = ProcessFactory.build("reschedulingTimer")
-      .node("decide").initial().behaviour(IncrementCounterWaitState.class)
-        .variable(IncrementCounterWaitState.COUNTER, "0")
-        .timer("2 days", "increment", "2 days")
-        .transition("decision made").to("response") // first defined transition is the default one
-        .transition("timeout").to("reassign")
-      .node("reassign").behaviour(WaitState.class)
-      .node("response").behaviour(WaitState.class)
-    .done();
-
-    ExecutionImpl processInstance = deployAndInstanciateProcess(processDefinition);
-
-    Execution execution = processInstance;
-    OpenExecution child = ((OpenExecution) execution).getExecutions().iterator().next();
-
-    for (int i=0; i<IncrementCounterWaitState.MAX_COUNTER_VALUE; i++) {
-      // check that the execution is in the right node
-      assertNotNull(child);
-      assertEquals("decide", child.getNodeName());
-      assertEquals(Execution.STATE_ACTIVE, child.getState());
-
-      // check there is one timer
-      assertTrue(child.hasTimers());
-      assertEquals(1, child.getTimers().size());
-
-      // check that timer's dueDate is good
-      Timer timer = child.getTimers().iterator().next();
-      assertTrue("error is "+(timer.getDueDate().getTime()-twoDaysFromNow)+" millis",
-          twoDaysFromNow <= timer.getDueDate().getTime()+200);
-
-      // set next minimum due date
-      twoDaysFromNow = Clock.getCurrentTime().getTime() + twoDaysDuration;
-
-      // execute timer
-      JobTestHelper jobTestHelper = getEnvironmentFactory().get(JobTestHelper.class);
-      jobTestHelper.executeTimer(timer.getDbid());
-      child = loadExecutionFromDb(child.getDbid());
-    }
-
-    newTransaction();
-    child = loadExecutionFromDb(child.getDbid());
-    assertNull(child);
-
-    // check that timers have been deleted
-    List<Timer> timers = Environment.getCurrent().get(PvmDbSession.class).findTimers();
-    assertNotNull(timers);
-    assertTrue(timers.isEmpty());
-
-    // check that process is in the right state
-    execution = loadExecutionFromDb(processInstance.getDbid());
-    assertEquals("reassign", execution.getNodeName());
-  }
-
-  public void testTimerEndingProcessExecution() {
-    ProcessDefinition processDefinition = ProcessFactory.build("timerEndingProcess")
-      .node("decide").initial().behaviour(WaitState.class)
-        .timer("2 business days", "timeout")
-        .transition("decision made").to("response") // first defined transition is the default one
-        .transition("timeout").to("reassign")
-      .node("reassign").behaviour(AutomaticActivity.class)
-      .node("response").behaviour(WaitState.class)
-    .done();
-    
-    ExecutionImpl processInstance = deployAndInstanciateProcess(processDefinition);
-
-    Execution execution = processInstance;
-    OpenExecution child = ((OpenExecution) execution).getExecutions().iterator().next();
-    assertEquals("decide", child.getNodeName());
-
-    // timer execution
-    Timer timer = child.getTimers().iterator().next();
-
-    JobTestHelper jobTestHelper = getEnvironmentFactory().get(JobTestHelper.class);
-    child = (OpenExecution) jobTestHelper.executeTimer(timer.getDbid());
-    assertEquals(Execution.STATE_ENDED, child.getState());
-
-    // check that the subExecution was deleted
-    child = loadExecutionFromDb(child.getDbid());
-    assertNull(child);
-
-    // check that timers have been deleted
-    List<Timer> timers = Environment.getCurrent().get(PvmDbSession.class).findTimers();
-    assertNotNull(timers);
-    assertTrue(timers.isEmpty());
-
-    // check that process is in the right state
-    execution = loadExecutionFromDb(processInstance.getDbid());
-    assertEquals("reassign", execution.getNodeName());
-    assertEquals(Execution.STATE_ENDED, execution.getState());
-  }
-
-}

Copied: jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerTest.java (from rev 1696, jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerIntegrationTest.java)
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerTest.java	                        (rev 0)
+++ jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerTest.java	2008-07-28 11:11:28 UTC (rev 1735)
@@ -0,0 +1,475 @@
+/**
+ * Copyright (C) 2006  Bull S. A. S.
+ * Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois
+ * This library 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
+ * version 2.1 of the License.
+ * This library 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
+ * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+ * Floor, Boston, MA  02110-1301, USA.
+ **/
+package org.jbpm.pvm.timer;
+
+import java.util.Date;
+import java.util.Map;
+
+import org.jbpm.pvm.Execution;
+import org.jbpm.pvm.ExecutionService;
+import org.jbpm.pvm.ProcessService;
+import org.jbpm.pvm.activity.ActivityExecution;
+import org.jbpm.pvm.activity.ExternalActivity;
+import org.jbpm.pvm.env.Environment;
+import org.jbpm.pvm.internal.job.TimerImpl;
+import org.jbpm.pvm.internal.model.ExecutionImpl;
+import org.jbpm.pvm.internal.util.Clock;
+import org.jbpm.pvm.job.JobTestHelper;
+import org.jbpm.pvm.job.Timer;
+import org.jbpm.pvm.model.OpenExecution;
+import org.jbpm.pvm.model.ProcessDefinition;
+import org.jbpm.pvm.model.ProcessFactory;
+import org.jbpm.pvm.samples.activities.AutomaticActivity;
+import org.jbpm.pvm.session.DbSession;
+import org.jbpm.pvm.session.PvmDbSession;
+import org.jbpm.pvm.test.base.DbTestCase;
+
+/**
+ * @author Pascal Verdage
+ */
+public class TimerTest extends DbTestCase {
+  /** Wait state that tries to take a transition when signalled */
+  public static class WaitState implements ExternalActivity {
+
+    private static final long serialVersionUID = 1L;
+
+    public void execute(ActivityExecution execution) {
+      execution.waitForSignal();
+    }
+
+    public void signal(ActivityExecution execution, 
+                       String signalName, 
+                       Map<String, Object> parameters) {
+      if (signalName!=null &&
+          execution.getNode().hasOutgoingTransition(signalName)) {
+        execution.take(signalName);
+      }
+    }
+  }
+
+  /** Wait state whose execution sets 'dueDate' variable to a fixed Date */
+  public static class SetDueDateWaitState extends WaitState {
+    private static final long serialVersionUID = 1L;
+
+    public void execute(ActivityExecution execution) {
+      Date dueDate = new Date(Clock.getCurrentTime().getTime() + twoDaysDuration);
+      execution.setVariable("dueDate", dueDate);
+      super.execute(execution);
+    }
+    
+  }
+  /////////////////////////////////////////////////////////
+  // Tools
+  /////////////////////////////////////////////////////////
+  private static long twoDaysDuration = 2*24*60*60*1000;
+
+  private static String getFormattedDate(long delay) {
+    return TimerImpl.formatDueDate(new Date(System.currentTimeMillis() + delay));
+  }
+
+  private static OpenExecution signalExecution(long executionDbid) {
+    ExecutionService executionService =
+      Environment.getCurrent().get(ExecutionService.class);
+    return (OpenExecution) executionService.signalExecution(executionDbid);
+  }
+
+  private static OpenExecution deployAndInstanciateProcess(ProcessDefinition definition) {
+    ProcessService processService = Environment.getCurrent().get(ProcessService.class);
+    processService.deploy(definition);
+
+    ExecutionService executionService =
+      Environment.getCurrent().get(ExecutionService.class);
+    Execution processInstance = executionService.startExecution(definition.getName());   
+
+    return (ExecutionImpl) processInstance;
+  }
+
+  private static OpenExecution loadExecutionFromDb(long id) {
+    return Environment.getCurrent().get(DbSession.class).get(ExecutionImpl.class, id);
+  }
+
+  private static void assertNoTimer() {
+    assertTrue(Environment.getCurrent().get(PvmDbSession.class).findTimers().isEmpty());
+  }
+
+  /////////////////////////////////////////////////////////
+  // test methods
+  /////////////////////////////////////////////////////////
+  private OpenExecution initTest(ProcessDefinition definition) {
+    OpenExecution processInstance = deployAndInstanciateProcess(definition);
+    OpenExecution execution = processInstance;
+
+    if ("request".equals(execution.getNodeName())) {
+      /* the request node might be use to have a specific initialisation
+       * through the node execution */
+      // go to test node
+      execution = signalExecution(execution.getDbid());
+    }
+    return execution;
+  }
+  
+  private long makeTestNode(long minimumDate, OpenExecution execution) {
+    // check there is one sub execution
+    assertEquals(1, execution.getExecutions().size());
+
+    // check the execution state
+    assertEquals("decide", execution.getNodeName());
+    OpenExecution child = execution.getExecutions().iterator().next();
+    assertEquals("decide", child.getNodeName());
+
+    // check there is one timer
+    assertFalse(execution.hasTimers());
+    assertTrue(child.hasTimers());
+    assertEquals(1, child.getTimers().size());
+
+    // check that timer's dueDate is good
+    Timer timer = child.getTimers().iterator().next();
+    assertTrue("error is "+(minimumDate-timer.getDueDate().getTime()),
+        minimumDate <= timer.getDueDate().getTime());
+
+    // execute the timer
+    JobTestHelper jobTestHelper = getEnvironmentFactory().get(JobTestHelper.class);
+    child = (OpenExecution) jobTestHelper.executeTimer(timer.getDbid());
+
+    return child.getDbid();
+  }
+
+  private void endTest(long executionDbid, long childDbid, String expectedState) {
+    newTransaction();
+
+    // check that the sub execution has been deleted
+    OpenExecution child = loadExecutionFromDb(childDbid);
+    assertNull(child);
+
+    // check that timers have been deleted
+    assertNoTimer();
+
+    // check that process is in the right state
+    OpenExecution execution = loadExecutionFromDb(executionDbid);
+    assertEquals(0, execution.getExecutions().size());
+    assertEquals("reassign", execution.getNodeName());
+    assertEquals(expectedState, execution.getState());
+  }
+
+  private void makeTestNoRepeat(ProcessDefinition definition) {
+    long twoDaysFromNow =Clock.getCurrentTime().getTime() + twoDaysDuration;
+    OpenExecution execution = initTest(definition);
+
+    long childDbid = makeTestNode(twoDaysFromNow - 100, execution);
+    
+    endTest(execution.getDbid(), childDbid, Execution.STATE_ACTIVE);
+  }
+
+  private void makeTestRepeat(ProcessDefinition definition) {
+    OpenExecution execution = initTest(definition);
+    long childDbid = -1;
+
+    for (int i=0; i<IncrementCounterWaitState.MAX_COUNTER_VALUE; i++) {
+      long twoDaysFromNow = Clock.getCurrentTime().getTime() + twoDaysDuration;
+      childDbid = makeTestNode(twoDaysFromNow-200, execution);
+      newTransaction();
+      execution = loadExecutionFromDb(execution.getDbid());
+    }
+
+    endTest(execution.getDbid(), childDbid, Execution.STATE_ACTIVE);
+  }
+
+  /////////////////////////////////////////////////////////
+  // simple timer execution
+  // not repeated timer when due date is not a script
+  /////////////////////////////////////////////////////////
+  /** This scenario test a timer defined by a string.
+   * The string represents a formatted date. */
+  public void testFormattedDateTimer() {
+    String dueDate = getFormattedDate(twoDaysDuration);
+
+    ProcessDefinition processDefinition = ProcessFactory.build("formattedDateTimer")
+      .node("decide").initial().behaviour(WaitState.class)
+        .timer(dueDate, "timeout")
+        .transition("decision made").to("response")
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+
+    makeTestNoRepeat(processDefinition);
+  }
+
+  /** This scenario test a timer defined by a string.
+   * The string represents a formatted date. */
+  public void testCustomFormattedDateTimer() {
+    TimerImpl.setDateFormat("EE, MM dd yyyy, hh:mm:ss,SSS a");
+    try {
+      String dueDate = getFormattedDate(twoDaysDuration);
+  
+      ProcessDefinition processDefinition = ProcessFactory.build("customFormattedDateTimer")
+        .node("decide").initial().behaviour(WaitState.class)
+          .timer(dueDate, "timeout")
+          .transition("decision made").to("response")
+          .transition("timeout").to("reassign")
+        .node("reassign").behaviour(WaitState.class)
+        .node("response").behaviour(WaitState.class)
+      .done();
+  
+      makeTestNoRepeat(processDefinition);
+    } finally {
+      // reset original date format
+      TimerImpl.setDateFormat("yyyy-MM-dd HH:mm:ss,SSS");
+    }
+  }
+
+  /** This scenario test a timer defined by a string.
+   * The string represents a duration. */
+  public void testDurationTimer() {
+    ProcessDefinition processDefinition = ProcessFactory.build("durationTimer")
+      .node("decide").initial().behaviour(WaitState.class)
+        .timer("2 days", "juel", "timeout", null)
+        .transition("decision made").to("response")
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+
+    makeTestNoRepeat(processDefinition);
+  }
+
+  /////////////////////////////////////////////////////////
+  // simple timer execution
+  // not repeated timer when due date is a juel script
+  /////////////////////////////////////////////////////////
+  /** This scenario test a timer defined by a juel script.
+   * The corresponding variable is a Date object */
+  public void testDateVariableJuelTimer() {
+    ProcessDefinition processDefinition = ProcessFactory.build("dateVariableJuelTimer")
+      .variable("dueDate")
+      .node("request").initial().behaviour(SetDueDateWaitState.class)
+        .transition().to("decide")
+      .node("decide").behaviour(WaitState.class)
+        .timer("#{dueDate}", "juel", "timeout", null)
+        .transition("decision made").to("response")
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+
+    makeTestNoRepeat(processDefinition);
+  }
+
+  /** This scenario test a timer defined by a juel script.
+   * The corresponding variable is a String object.
+   * The string represents a formatted date */
+  public void testFormattedDateVariableJuelTimer() {
+    String dueDate = getFormattedDate(twoDaysDuration);
+
+    ProcessDefinition processDefinition = ProcessFactory.build("formattedDateVariableJuelTimer")
+      .variable("timerDelay", dueDate)
+      .node("decide").initial().behaviour(WaitState.class)
+        .timer("#{timerDelay}", "juel", "timeout", null)
+        .transition("decision made").to("response")
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+
+    makeTestNoRepeat(processDefinition);
+  }
+
+  /** This scenario test a timer defined by a juel script.
+   * The corresponding variable is a String object.
+   * The string represents a duration */
+  public void testDurationVariableJuelTimer() {
+    ProcessDefinition processDefinition = ProcessFactory.build("durationVariableJuelTimer")
+      .variable("timerDelay", "2 days")
+      .node("decide").initial().behaviour(WaitState.class)
+        .timer("#{timerDelay}", "juel", "timeout", null)
+        .transition("decision made").to("response")
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+
+    makeTestNoRepeat(processDefinition);
+  }
+
+  /*
+  /////////////////////////////////////////////////////////
+  // simple timer execution
+  // not repeated timer when due date is a groovy script
+  /////////////////////////////////////////////////////////
+  public void testDateVariableGroovyTimer() {
+    ProcessDefinition processDefinition = ProcessFactory.build("dateVariableGroovyTimer")
+      .variable("dueDate")
+      .node("request").initial().behaviour(SetDueDateWaitState.class)
+        .transition().to("decide")
+      .node("decide").behaviour(WaitState.class)
+        .timer("dueDate", "groovy", "timeout", null)
+        .transition("decision made").to("response")
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+
+    makeTestNoRepeat(processDefinition);
+  }
+
+  public void testFormattedDateVariableGroovyTimer() {
+    String dueDate = getFormattedDate(twoDaysDuration);
+
+    ProcessDefinition processDefinition = ProcessFactory.build("formattedDateVariableGroovyTimer")
+      .variable("timerDelay", dueDate)
+      .node("decide").initial().behaviour(WaitState.class)
+        .timer("timerDelay", "groovy", "timeout", null)
+        .transition("decision made").to("response")
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+
+    makeTestNoRepeat(processDefinition);
+  }
+  
+  public void testDurationVariableGroovyTimer() {
+    ProcessDefinition processDefinition = ProcessFactory.build("durationVariableGroovyTimer")
+      .variable("timerDelay", "2 days")
+      .node("decide").initial().behaviour(WaitState.class)
+        .timer("timerDelay", "groovy", "timeout", null)
+        .transition("decision made").to("response")
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+
+    makeTestNoRepeat(processDefinition);
+  }
+  */
+
+  /////////////////////////////////////////////////////////
+  // repeated timer execution
+  /////////////////////////////////////////////////////////
+  /** <p>this scenario tests a repeated timer.
+   * When signalled, the node makes an alert (logs).<br>
+   * After IncrementCounterWaitState.COUNTER loops,
+   * the node takes a timeout transition.</p>
+   * <p>Repeat is a string representing a duration.</p> */
+  public void testDurationRepeat() {
+    ProcessDefinition processDefinition = ProcessFactory.build("durationRepeat")
+      .node("decide").initial().behaviour(IncrementCounterWaitState.class)
+        .variable(IncrementCounterWaitState.COUNTER, "0")
+        .timer("2 days", null, "increment", "2 days")
+        .transition("decision made").to("response")
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+    
+    makeTestRepeat(processDefinition);
+  }
+
+  /*
+  public void testDurationVariableGroovyRepeat() {
+    // groovy constraint
+    // if we use '2 days' instead of 'timerDelay' variable,
+    // scripting fails to evaluate '2 days'
+    ProcessDefinition processDefinition = ProcessFactory.build("durationGroovyRepeat")
+      .variable("repeat", "2 days")
+      .node("decide").initial().behaviour(IncrementCounterWaitState.class)
+        .variable(IncrementCounterWaitState.COUNTER, "0")
+        .timer("'2 days'", "groovy", "increment", "repeat")
+        .transition("decision made").to("response")
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+
+    makeTestRepeat(processDefinition);
+  }
+  */
+
+  /** <p>this scenario tests a repeated timer.
+   * When signalled, the node makes an alert (logs).<br>
+   * After IncrementCounterWaitState.COUNTER loops,
+   * the node takes a timeout transition.</p>
+   * <p>Repeat is a juel script referring to a duration.</p> */
+  public void testDurationVariableJuelRepeat() {
+    ProcessDefinition processDefinition = ProcessFactory.build("durationJuelRepeat")
+      .variable("repeat", "2 days")
+      .node("decide").initial().behaviour(IncrementCounterWaitState.class)
+        .variable(IncrementCounterWaitState.COUNTER, "0")
+        .timer("2 days", "juel", "increment", "#{repeat}")
+        .transition("decision made").to("response")
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+
+    makeTestRepeat(processDefinition);
+  }
+
+  /////////////////////////////////////////////////////////
+  // others
+  /////////////////////////////////////////////////////////
+  /** this scenario tests a timer that doesn't fire */
+  public void testCanceledTimer() {
+    String dueDate = getFormattedDate(twoDaysDuration);
+    ProcessDefinition processDefinition = ProcessFactory.build("timerCanceled")
+      .node("decide").initial().behaviour(WaitState.class)
+        .timer(dueDate, "timeout")
+        .transition("decision made").to("response")
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(WaitState.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+
+    OpenExecution processInstance = deployAndInstanciateProcess(processDefinition);
+
+    OpenExecution execution = processInstance;
+    assertEquals("decide", execution.getNodeName());
+
+    // signal child execution
+    OpenExecution child = execution.getExecutions().iterator().next();
+    execution = signalExecution(child.getDbid());
+    assertEquals(Execution.STATE_ENDED, execution.getState());
+
+    // check that the subExecution was deleted
+    child = loadExecutionFromDb(child.getDbid());
+    assertNull(child);
+    
+    // check that timers have been deleted
+    assertNoTimer();
+
+    // check that process is in the right state
+    execution = loadExecutionFromDb(processInstance.getDbid());
+    assertEquals("response", execution.getNodeName());
+    assertEquals(Execution.STATE_ACTIVE, execution.getState());
+  }
+
+  /** this scenario tests the case where the process execution ends
+   * in the transaction that executes the timer */
+  public void testTimerEndingProcessExecution() {
+    ProcessDefinition processDefinition = ProcessFactory.build("timerEndingProcess")
+      .node("decide").initial().behaviour(WaitState.class)
+        .timer("2 business days", "timeout")
+        .transition("decision made").to("response")
+        .transition("timeout").to("reassign")
+      .node("reassign").behaviour(AutomaticActivity.class)
+      .node("response").behaviour(WaitState.class)
+    .done();
+
+    long twoDaysFromNow = Clock.getCurrentTime().getTime()+twoDaysDuration;
+    OpenExecution execution = initTest(processDefinition);
+    long childDbid = makeTestNode(twoDaysFromNow, execution);
+    endTest(execution.getDbid(), childDbid, Execution.STATE_ENDED);
+  }
+
+}


Property changes on: jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerTest.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + LF

Deleted: jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerUnitTest.java
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerUnitTest.java	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/test/java/org/jbpm/pvm/timer/TimerUnitTest.java	2008-07-28 11:11:28 UTC (rev 1735)
@@ -1,176 +0,0 @@
-/*
- * 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.timer;
-
-import java.util.Date;
-
-import org.jbpm.pvm.test.base.JbpmTestCase;
-import org.jbpm.pvm.internal.job.TimerImpl;
-import org.jbpm.pvm.job.Timer;
-
-/**
- * @author Tom Baeyens
- * @author Pascal Verdage
- */
-public class TimerUnitTest extends JbpmTestCase
-{
-
-
-  protected Timer timer() {
-    return new TimerImpl();
-  }
-  
-  public void testSetDueDate() throws Exception {
-    TimerImpl timer = new TimerImpl();
-    Date now = new Date(System.currentTimeMillis());
-    timer.setDueDate(now);
-    TestTimerSession timerSession = new TestTimerSession();
-    timerSession.schedule(timer);
-    assertEquals(1, timerSession.getNbTimer());
-    assertEquals(timer, timerSession.getFirstTimer());
-    timerSession.executeFirstTimer();
-    assertEquals(0, timerSession.getNbTimer());
-  }
-
-  /*
-  TODO finish after refactoring
-  
-
-  public void testSetDueDateDescription() throws Exception {
-    TimerImpl timerImpl = new TimerImpl();
-    timerImpl.setDueDateDescription("5 seconds");
-    TestTimerSession timerSession = new TestTimerSession();
-    timerSession.schedule(timerImpl);
-    assertEquals(1, timerSession.getNbTimer());
-    assertEquals(timerImpl, timerSession.getFirstTimer());
-    timerSession.executeFirstTimer();
-    assertEquals(0, timerSession.getNbTimer());
-  }
-  
-  public void testRepeatedTimer() throws Exception {
-    TimerImpl timerImpl = new TimerImpl();
-    Date now= new Date();
-    timerImpl.setDueDate(now);
-    timerImpl.setRepeat("3 seconds");
-    TestTimerSession timerSession = new TestTimerSession();
-    timerSession.schedule(timerImpl);
-    assertEquals(1, timerSession.getNbTimer());
-    assertEquals(timerImpl, timerSession.getFirstTimer());
-    timerSession.executeFirstTimer();
-    assertEquals(1, timerSession.getNbTimer());
-  }
-  
-  private static class TestActivityInstance extends ActivityInstanceImpl {
-    private static final long serialVersionUID = 1L;
-    private int executionCount = 0;
-    
-    public void signal(String signalName, Map<String, Object> parameters) {
-      executionCount++;
-    }
-    public int getExecutionCount() {
-      return executionCount;
-    }
-
-    public String toString() {
-      return "test activity";
-    }
-  }
-
-  public void testActivityInstanceNoSignalNoEvent() throws Exception {
-    TimerImpl timerImpl = new TimerImpl();
-    TestActivityInstance instance = new TestActivityInstance();
-    TestExecution execution = new TestExecution();
-    timerImpl.setActivityInstance(instance);
-    timerImpl.setExecution(execution);
-    TestTimerSession timerSession = new TestTimerSession();
-    timerSession.schedule(timerImpl);
-    assertEquals(1, timerSession.getNbTimer());
-    timerSession.executeFirstTimer();
-    assertEquals(0, timerSession.getNbTimer());
-    assertEquals(0, instance.getExecutionCount());
-    assertEquals(0, execution.getExecutionCount());
-  }
-
-  public void testActivityInstanceWithSignal() throws Exception {
-    TimerImpl timerImpl = new TimerImpl();
-    TestActivityInstance instance = new TestActivityInstance();
-    TestExecution execution = new TestExecution();
-    timerImpl.setActivityInstance(instance);
-    timerImpl.setSignalName("timeout");
-    timerImpl.setExecution(execution);
-    TestTimerSession timerSession = new TestTimerSession();
-    timerSession.schedule(timerImpl);
-    assertEquals(1, timerSession.getNbTimer());
-    timerSession.executeFirstTimer();
-    assertEquals(0, timerSession.getNbTimer());
-    assertEquals(1, instance.getExecutionCount());
-    assertEquals(0, execution.getExecutionCount());
-  }
-
-  private static class TestExecution extends ExecutionImpl {
-    private static final long serialVersionUID = 1L;
-    private int executionCount = 0;
-    
-    public int getExecutionCount() {
-      return executionCount;
-    }
-    
-    public void fire(String eventName, ObservableElement eventSource) {
-      executionCount++;
-    }
-
-    public String toString() {
-      return "test execution";
-    }
-  }
-
-  public void testActivityInstanceWithEvent() throws Exception {
-    TimerImpl timerImpl = new TimerImpl();
-    TestActivityInstance instance = new TestActivityInstance();
-    TestExecution execution = new TestExecution();
-    timerImpl.setActivityInstance(instance);
-    timerImpl.setEventName("timeout");
-    timerImpl.setExecution(execution);
-    TestTimerSession timerSession = new TestTimerSession();
-    timerSession.schedule(timerImpl);
-    assertEquals(1, timerSession.getNbTimer());
-    timerSession.executeFirstTimer();
-    assertEquals(0, timerSession.getNbTimer());
-    assertEquals(0, instance.getExecutionCount());
-    assertEquals(1, execution.getExecutionCount());
-  }
-
-  public void testEventWithNoActivityInstance() throws Exception {
-    TimerImpl timerImpl = new TimerImpl();
-    TestExecution execution = new TestExecution();
-    timerImpl.setEventName("timeout");
-    timerImpl.setExecution(execution);
-    TestTimerSession timerSession = new TestTimerSession();
-    timerSession.schedule(timerImpl);
-    assertEquals(1, timerSession.getNbTimer());
-    timerSession.executeFirstTimer();
-    assertEquals(0, timerSession.getNbTimer());
-    assertEquals(1, execution.getExecutionCount());
-  }
-  
-  */
-}

Modified: jbpm4/pvm/trunk/modules/core/src/test/resources/org/jbpm/pvm/timer/environment.cfg.xml
===================================================================
--- jbpm4/pvm/trunk/modules/core/src/test/resources/org/jbpm/pvm/timer/environment.cfg.xml	2008-07-27 08:13:58 UTC (rev 1734)
+++ jbpm4/pvm/trunk/modules/core/src/test/resources/org/jbpm/pvm/timer/environment.cfg.xml	2008-07-28 11:11:28 UTC (rev 1735)
@@ -7,6 +7,7 @@
     <job-test-helper />
     
     <process-service />
+    <execution-service />
     
     <command-service>
       <retry-interceptor />
@@ -39,6 +40,14 @@
       <holiday period="01/07/2008 - 31/08/2008"/>
     </business-calendar>
     
+    <script-manager default-expression-language='juel'
+                    default-script-language='juel'
+                    read-contexts='execution, environment, environment-factory'
+                    write-context='null'>
+      <script-language name='juel' factory='com.sun.script.juel.JuelScriptEngineFactory' />
+<!--      <script-language name='groovy' factory='com.sun.script.groovy.GroovyScriptEngineFactory' />-->
+    </script-manager>
+
   </environment-factory>
 
   <environment>




More information about the jbpm-commits mailing list