Index: modules/api/src/main/java/org/jbpm/api/activity/ExternalActivityBehaviour.java =================================================================== --- modules/api/src/main/java/org/jbpm/api/activity/ExternalActivityBehaviour.java (revision 6165) +++ modules/api/src/main/java/org/jbpm/api/activity/ExternalActivityBehaviour.java (working copy) @@ -61,4 +61,5 @@ * used any more and if this is during a transaction, the transaction should be * rolled back. */ void signal(ActivityExecution execution, String signalName, Map parameters) throws Exception; + void timeout(ActivityExecution execution, String signalName) throws Exception; } Index: modules/api/src/main/java/org/jbpm/api/history/HistoryTask.java =================================================================== --- modules/api/src/main/java/org/jbpm/api/history/HistoryTask.java (revision 6165) +++ modules/api/src/main/java/org/jbpm/api/history/HistoryTask.java (working copy) @@ -37,6 +37,7 @@ public interface HistoryTask { String STATE_COMPLETED = "completed"; + String STATE_TIMEDOUT = "timed out"; /** the unique id for this task that is used as a reference in the service methods */ String getId(); Index: modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/TaskActivity.java =================================================================== --- modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/TaskActivity.java (revision 6165) +++ modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/TaskActivity.java (working copy) @@ -27,6 +27,7 @@ import org.jbpm.api.JbpmException; import org.jbpm.api.activity.ActivityExecution; import org.jbpm.api.model.Transition; +import org.jbpm.api.task.Task; import org.jbpm.pvm.internal.cal.Duration; import org.jbpm.pvm.internal.el.Expression; import org.jbpm.pvm.internal.env.EnvironmentImpl; @@ -175,6 +176,24 @@ } } + // JBPM-2537: A triggered timer does not end the task which is left + + public void timeout(ActivityExecution execution, String signalName) throws Exception { + timeout((ExecutionImpl) execution, signalName); + } + + public void timeout(ExecutionImpl execution, String signalName) throws Exception { + + DbSession taskDbSession = EnvironmentImpl .getFromCurrent(DbSession.class); + TaskImpl task = (TaskImpl) taskDbSession.findTaskByExecution(execution); + if (task!=null) { + task.setSignalling(false); + task.timeout(); + taskDbSession.delete((Task) task); + } + + } + public TaskDefinitionImpl getTaskDefinition() { return taskDefinition; } Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/history/events/TaskTimeout.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/history/events/TaskTimeout.java (revision 0) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/history/events/TaskTimeout.java (revision 0) @@ -0,0 +1,66 @@ +/* + * 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.HistoryEvent; +import org.jbpm.pvm.internal.history.model.HistoryTaskImpl; +import org.jbpm.pvm.internal.history.model.HistoryTaskInstanceImpl; +import org.jbpm.pvm.internal.util.Clock; + + +/** + * @author Sebastian Schneider + */ +public class TaskTimeout extends HistoryEvent { + + private static final long serialVersionUID = 1L; + + protected String outcome; + + public TaskTimeout(String outcome) { + this.outcome = outcome; + } + + public void process() { + Session session = EnvironmentImpl.getFromCurrent(Session.class); + Long historyActivityInstanceDbId = execution.getHistoryActivityInstanceDbid(); + HistoryTaskInstanceImpl historyTaskInstance = (HistoryTaskInstanceImpl) + session.load(HistoryTaskInstanceImpl.class, historyActivityInstanceDbId); + historyTaskInstance.setEndTime(Clock.getTime()); + historyTaskInstance.setTransitionName(outcome); + + HistoryTaskImpl historyTask = historyTaskInstance.getHistoryTask(); + historyTask.setOutcome(outcome); + historyTask.setEndTime(Clock.getTime()); + historyTask.setState(HistoryTask.STATE_TIMEDOUT); + + session.update(historyTaskInstance); + } + + public String getOutcome() { + return outcome; + } + +} \ No newline at end of file Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java (revision 6165) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java (working copy) @@ -25,6 +25,8 @@ import java.util.Date; import org.jbpm.api.JbpmException; +import org.jbpm.api.activity.ActivityBehaviour; +import org.jbpm.api.activity.ExternalActivityBehaviour; import org.jbpm.api.cmd.Environment; import org.jbpm.api.job.Timer; import org.jbpm.internal.log.Log; @@ -33,6 +35,7 @@ import org.jbpm.pvm.internal.id.DbidGenerator; import org.jbpm.pvm.internal.jobexecutor.JobAddedNotification; import org.jbpm.pvm.internal.jobexecutor.JobExecutor; +import org.jbpm.pvm.internal.model.ActivityImpl; import org.jbpm.pvm.internal.model.ObservableElement; import org.jbpm.pvm.internal.session.DbSession; import org.jbpm.pvm.internal.session.TimerSession; @@ -82,6 +85,10 @@ throw new JbpmException("environment is null"); } + ActivityImpl activity = execution.getActivity(); + ExternalActivityBehaviour behaviour = (ExternalActivityBehaviour) activity.getActivityBehaviour(); + behaviour.timeout(execution, signalName); + if (signalName!=null) { if (log.isDebugEnabled()) log.debug("feeding timer signal "+signalName+" into "+execution); execution.signal(signalName); Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/task/LifeCycleState.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/task/LifeCycleState.java (revision 6165) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/task/LifeCycleState.java (working copy) @@ -41,4 +41,9 @@ Map parameters) throws Exception { execution.take(signalName); } + + @Override + public void timeout(ActivityExecution execution, String signalName) throws Exception { + // TODO: JBPM-2537 + } } Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/task/TaskImpl.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/task/TaskImpl.java (revision 6165) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/task/TaskImpl.java (working copy) @@ -39,6 +39,7 @@ import org.jbpm.pvm.internal.history.HistoryEvent; import org.jbpm.pvm.internal.history.events.TaskComplete; import org.jbpm.pvm.internal.history.events.TaskDelete; +import org.jbpm.pvm.internal.history.events.TaskTimeout; import org.jbpm.pvm.internal.model.ExecutionImpl; import org.jbpm.pvm.internal.model.ProcessDefinitionImpl; import org.jbpm.pvm.internal.model.ScopeInstanceImpl; @@ -210,6 +211,19 @@ public void delete(String reason) { historyTaskDelete(reason); } + + public void timeout(String outcome) { + historyTaskTimeout(outcome); + + DbSession dbSession = EnvironmentImpl.getFromCurrent(DbSession.class, false); + if (dbSession != null) { + dbSession.delete(this); + } + } + + public void timeout() { + historyTaskTimeout(TaskConstants.NO_TASK_OUTCOME_SPECIFIED); + } // state //////////////////////////////////////////////////////////////////// @@ -310,6 +324,12 @@ HistoryEvent.fire(new TaskComplete(outcome), execution); } } + + public void historyTaskTimeout(String outcome) { + if (execution != null) { + HistoryEvent.fire(new TaskTimeout(outcome), execution); + } + } public void signalExecution(String signalName) { if (execution != null) { Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/usercode/UserCodeActivityBehaviour.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/usercode/UserCodeActivityBehaviour.java (revision 6165) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/usercode/UserCodeActivityBehaviour.java (working copy) @@ -49,4 +49,10 @@ public void setCustomActivityReference(UserCodeReference customActivityReference) { this.customActivityReference = customActivityReference; } + + @Override + public void timeout(ActivityExecution execution, String signalName) throws Exception { + ExternalActivityBehaviour externalActivityBehaviour = (ExternalActivityBehaviour) customActivityReference.getObject(execution); + externalActivityBehaviour.timeout(execution, signalName); + } } Index: modules/pvm/src/test/java/org/jbpm/pvm/activities/WaitState.java =================================================================== --- modules/pvm/src/test/java/org/jbpm/pvm/activities/WaitState.java (revision 6165) +++ modules/pvm/src/test/java/org/jbpm/pvm/activities/WaitState.java (working copy) @@ -43,4 +43,9 @@ execution.setVariables(parameters); execution.take(signalName); } + + @Override + public void timeout(ActivityExecution execution, String signalName) throws Exception { + //TODO: JBPM-2537 + } } Index: modules/pvm/src/test/java/org/jbpm/pvm/executionmode/embedded/WaitState.java =================================================================== --- modules/pvm/src/test/java/org/jbpm/pvm/executionmode/embedded/WaitState.java (revision 6165) +++ modules/pvm/src/test/java/org/jbpm/pvm/executionmode/embedded/WaitState.java (working copy) @@ -43,4 +43,9 @@ public void signal(ActivityExecution execution, String signalName, Map parameters) throws Exception { execution.take(signalName); } + + @Override + public void timeout(ActivityExecution execution, String signalName) throws Exception { + // JBPM-2537 + } } \ No newline at end of file