001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Rodrigo Westrupp
028: */
029:
030: package com.caucho.ejb.timer;
031:
032: import javax.ejb.*;
033:
034: import java.io.Serializable;
035: import java.util.Date;
036: import java.util.concurrent.Future;
037: import java.util.concurrent.TimeUnit;
038: import java.util.logging.*;
039:
040: import com.caucho.ejb.AbstractContext;
041: import com.caucho.util.Alarm;
042: import com.caucho.util.L10N;
043: import com.caucho.server.util.ScheduledThreadPool;
044:
045: /**
046: * Implements the EJB timer.
047: */
048: public class EjbTimer implements javax.ejb.Timer, Runnable {
049: private static final L10N L = new L10N(EjbTimer.class);
050: protected static final Logger log = Logger.getLogger(EjbTimer.class
051: .getName());
052:
053: private ScheduledThreadPool _threadPool;
054: private Future _future;
055:
056: private Date _expiration;
057: private long _interval;
058: private Serializable _info;
059: private AbstractContext _context;
060: private long _timerId;
061:
062: private static long _currentTimerId;
063:
064: EjbTimer(Date expiration, Serializable info, AbstractContext context) {
065: this (expiration, -1, info, context);
066: }
067:
068: EjbTimer(Date expiration, long interval, Serializable info,
069: AbstractContext context) {
070: _expiration = expiration;
071: _interval = interval;
072: _info = info;
073:
074: if (context == null)
075: throw new NullPointerException();
076:
077: _context = context;
078: _timerId = _currentTimerId++;
079:
080: long initialDelay = getTimeRemaining();
081:
082: _threadPool = ScheduledThreadPool.getLocal();
083:
084: if (interval <= 0)
085: _future = _threadPool.schedule(this , initialDelay,
086: TimeUnit.MILLISECONDS);
087: else
088: _future = _threadPool.scheduleWithFixedDelay(this ,
089: initialDelay, interval, TimeUnit.MILLISECONDS);
090: }
091:
092: /**
093: * Cancels the timer.
094: */
095: public void cancel() throws NoSuchObjectLocalException,
096: EJBException {
097: try {
098: _future.cancel(true);
099: } finally {
100: _expiration = new Date(Alarm.getCurrentTime());
101: _interval = -1;
102: }
103: }
104:
105: /**
106: * Returns the timer handle.
107: */
108: public TimerHandle getHandle() throws NoSuchObjectLocalException,
109: EJBException {
110: return new EjbTimerHandle(_expiration, _interval, _info,
111: _context.getServer().getEJBName(), _timerId);
112: }
113:
114: /**
115: * Returns timer information.
116: */
117: public Serializable getInfo() throws NoSuchObjectLocalException,
118: EJBException {
119: return _info;
120: }
121:
122: /**
123: * Returns the time corresponding to the next scheduled expiration.
124: */
125: public Date getNextTimeout() throws NoSuchObjectLocalException,
126: EJBException {
127: checkExpiration();
128:
129: return _expiration;
130: }
131:
132: /**
133: * Returns the time remaining in milliseconds.
134: */
135: public long getTimeRemaining() throws NoSuchObjectLocalException,
136: EJBException {
137: return checkExpiration();
138: }
139:
140: public void run() {
141: _context.__caucho_timeout_callback(this );
142: }
143:
144: long __caucho_getId() {
145: return _timerId;
146: }
147:
148: private long checkExpiration() {
149: long delay = _expiration.getTime() - Alarm.getCurrentTime();
150:
151: if (delay < 0 && _interval < 0)
152: throw new NoSuchObjectLocalException(this + " is expired");
153:
154: return delay;
155: }
156:
157: public String toString() {
158: return "EjbTimer[" + _timerId + ", " + _expiration + ", "
159: + _interval + ", " + _info + "]";
160: }
161: }
|