1 /**
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one or more
4 * contributor license agreements. See the NOTICE file distributed with
5 * this work for additional information regarding copyright ownership.
6 * The ASF licenses this file to You under the Apache License, Version 2.0
7 * (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 package org.apache.geronimo.timer;
20
21 import java.util.TimerTask;
22
23 import javax.transaction.RollbackException;
24 import javax.transaction.SystemException;
25 import javax.transaction.Synchronization;
26 import javax.transaction.Status;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31 /**
32 *
33 *
34 * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
35 *
36 * */
37 public class ExecutorFeedingTimerTask extends TimerTask {
38
39 private static final Log log = LogFactory.getLog(ExecutorFeedingTimerTask.class);
40
41 private final WorkInfo workInfo;
42 private final ThreadPooledTimer threadPooledTimer;
43 boolean cancelled = false;
44
45 public ExecutorFeedingTimerTask(WorkInfo workInfo, ThreadPooledTimer threadPooledTimer) {
46 this.workInfo = workInfo;
47 this.threadPooledTimer = threadPooledTimer;
48 }
49
50 public void run() {
51 threadPooledTimer.getExecutor().execute(workInfo.getExecutorTask());
52 }
53
54 public boolean cancel() {
55 threadPooledTimer.removeWorkInfo(workInfo);
56 try {
57 threadPooledTimer.registerSynchronization(new CancelSynchronization(this));
58 } catch (RollbackException e) {
59 log.warn("Exception canceling task", e);
60 throw (IllegalStateException) new IllegalStateException("RollbackException when trying to register Cancel Synchronization").initCause(e);
61 } catch (SystemException e) {
62 log.warn("Exception canceling task", e);
63 throw (IllegalStateException) new IllegalStateException("SystemException when trying to register Cancel Synchronization").initCause(e);
64 }
65
66
67 cancelled = true;
68 return super.cancel();
69 }
70
71 public boolean isCancelled() {
72 return cancelled;
73 }
74
75 private void doCancel() {
76 try {
77
78
79 threadPooledTimer.getWorkerPersistence().cancel(workInfo.getId());
80 } catch (PersistenceException e) {
81 log.warn("Exception canceling task", e);
82 }
83 }
84
85 private void rollbackCancel() {
86 threadPooledTimer.addWorkInfo(workInfo);
87
88
89
90 if ( workInfo.isOneTime() ) {
91 threadPooledTimer.getTimer().schedule(
92 new ExecutorFeedingTimerTask(workInfo, threadPooledTimer),
93 workInfo.getTime());
94 } else if ( workInfo.getAtFixedRate() ) {
95 threadPooledTimer.getTimer().scheduleAtFixedRate(
96 new ExecutorFeedingTimerTask(workInfo, threadPooledTimer),
97 workInfo.getTime(), workInfo.getPeriod().longValue());
98 } else {
99 threadPooledTimer.getTimer().schedule(
100 new ExecutorFeedingTimerTask(workInfo, threadPooledTimer),
101 workInfo.getTime(), workInfo.getPeriod().longValue());
102 }
103 }
104
105 private static class CancelSynchronization implements Synchronization {
106
107 private final ExecutorFeedingTimerTask worker;
108
109 public CancelSynchronization(ExecutorFeedingTimerTask worker) {
110 this.worker = worker;
111 }
112
113 public void beforeCompletion() {
114 }
115
116 public void afterCompletion(int status) {
117 if (status == Status.STATUS_COMMITTED) {
118 worker.doCancel();
119 } else if (status == Status.STATUS_ROLLEDBACK) {
120 worker.rollbackCancel();
121 }
122 }
123
124 }
125
126 }