Source Code Cross Referenced for TimerImpl.java in  » EJB-Server-JBoss-4.2.1 » server » org » jboss » ejb » txtimer » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server JBoss 4.2.1 » server » org.jboss.ejb.txtimer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * JBoss, Home of Professional Open Source.
003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004:         * as indicated by the @author tags. See the copyright.txt file in the
005:         * distribution for a full listing of individual contributors.
006:         *
007:         * This is free software; you can redistribute it and/or modify it
008:         * under the terms of the GNU Lesser General Public License as
009:         * published by the Free Software Foundation; either version 2.1 of
010:         * the License, or (at your option) any later version.
011:         *
012:         * This software is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this software; if not, write to the Free
019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021:         */
022:        package org.jboss.ejb.txtimer;
023:
024:        // $Id: TimerImpl.java 62329 2007-04-13 13:51:10Z dimitris@jboss.org $
025:
026:        import java.io.Serializable;
027:        import java.util.Date;
028:        import java.util.Timer;
029:        import java.util.TimerTask;
030:
031:        import javax.ejb.EJBException;
032:        import javax.ejb.NoSuchObjectLocalException;
033:        import javax.ejb.TimerHandle;
034:        import javax.transaction.Status;
035:        import javax.transaction.Synchronization;
036:        import javax.transaction.Transaction;
037:
038:        import org.jboss.ejb.AllowedOperationsAssociation;
039:        import org.jboss.logging.Logger;
040:
041:        /**
042:         * An implementation of an EJB Timer.
043:         * 
044:         * Internally it uses a java.util.Timer and maintains its state in
045:         * a Tx manner.
046:         *
047:         * @author Thomas.Diesler@jboss.org
048:         * @author Dimitris.Andreadis@jboss.org
049:         * @version $Revision: 62329 $
050:         * @since 07-Apr-2004
051:         */
052:        public class TimerImpl implements  javax.ejb.Timer, Synchronization {
053:            // logging support
054:            private static Logger log = Logger.getLogger(TimerImpl.class);
055:
056:            /**
057:             * Timer states and their allowed transitions
058:             * <p/>
059:             * CREATED  - on create
060:             * CREATED -> STARTED_IN_TX - when strated with Tx
061:             * CREATED -> ACTIVE  - when started without Tx
062:             * STARTED_IN_TX -> ACTIVE - on Tx commit
063:             * STARTED_IN_TX -> CANCELED - on Tx rollback
064:             * ACTIVE -> CANCELED_IN_TX - on cancel() with Tx
065:             * ACTIVE -> CANCELED - on cancel() without Tx
066:             * CANCELED_IN_TX -> CANCELED - on Tx commit
067:             * CANCELED_IN_TX -> ACTIVE - on Tx rollback
068:             * ACTIVE -> IN_TIMEOUT - on TimerTask run
069:             * IN_TIMEOUT -> ACTIVE - on Tx commit if periode > 0
070:             * IN_TIMEOUT -> EXPIRED -> on Tx commit if periode == 0
071:             * IN_TIMEOUT -> RETRY_TIMEOUT -> on Tx rollback
072:             * RETRY_TIMEOUT -> ACTIVE -> on Tx commit/rollback if periode > 0
073:             * RETRY_TIMEOUT -> EXPIRED -> on Tx commit/rollback if periode == 0
074:             */
075:            private static final int CREATED = 0;
076:            private static final int STARTED_IN_TX = 1;
077:            private static final int ACTIVE = 2;
078:            private static final int CANCELED_IN_TX = 3;
079:            private static final int CANCELED = 4;
080:            private static final int EXPIRED = 5;
081:            private static final int IN_TIMEOUT = 6;
082:            private static final int RETRY_TIMEOUT = 7;
083:
084:            private static final String[] TIMER_STATES = { "created",
085:                    "started_in_tx", "active", "canceled_in_tx", "canceled",
086:                    "expired", "in_timeout", "retry_timeout" };
087:
088:            // The initial txtimer properties
089:            private TimerServiceImpl timerService;
090:            private String timerId;
091:            private TimedObjectId timedObjectId;
092:            private TimedObjectInvoker timedObjectInvoker;
093:            private Date firstTime;
094:            private long periode;
095:            private Serializable info;
096:
097:            private long nextExpire;
098:            private int timerState;
099:            private Timer utilTimer;
100:            private int hashCode;
101:
102:            /**
103:             * Schedules the txtimer for execution at the specified time with a specified periode.
104:             */
105:            TimerImpl(TimerServiceImpl timerService, String timerId,
106:                    TimedObjectId timedObjectId,
107:                    TimedObjectInvoker timedObjectInvoker, Serializable info) {
108:                this .timerService = timerService;
109:                this .timerId = timerId;
110:                this .timedObjectId = timedObjectId;
111:                this .timedObjectInvoker = timedObjectInvoker;
112:                this .info = info;
113:
114:                setTimerState(CREATED);
115:            }
116:
117:            void startTimer(Date firstTime, long periode) {
118:                this .firstTime = firstTime;
119:                this .nextExpire = firstTime.getTime();
120:                this .periode = periode;
121:
122:                timerService.addTimer(this );
123:                registerTimerWithTx();
124:
125:                // the timer will actually go ACTIVE on tx commit
126:                startInTx();
127:            }
128:
129:            public String getTimerId() {
130:                return timerId;
131:            }
132:
133:            public TimedObjectId getTimedObjectId() {
134:                return timedObjectId;
135:            }
136:
137:            public Date getFirstTime() {
138:                return firstTime;
139:            }
140:
141:            public long getPeriode() {
142:                return periode;
143:            }
144:
145:            public long getNextExpire() {
146:                return nextExpire;
147:            }
148:
149:            public Serializable getInfoInternal() {
150:                return info;
151:            }
152:
153:            public boolean isActive() {
154:                return !isCanceled() && !isExpired();
155:            }
156:
157:            public boolean isInRetry() {
158:                return timerState == RETRY_TIMEOUT;
159:            }
160:
161:            public boolean isCanceled() {
162:                return timerState == CANCELED_IN_TX || timerState == CANCELED;
163:            }
164:
165:            public boolean isExpired() {
166:                return timerState == EXPIRED;
167:            }
168:
169:            /**
170:             * Cause the txtimer and all its associated expiration notifications to be cancelled.
171:             *
172:             * @throws IllegalStateException  If this method is invoked while the instance is in
173:             *                                a state that does not allow access to this method.
174:             * @throws javax.ejb.NoSuchObjectLocalException
175:             *                                If invoked on a txtimer that has expired or has been cancelled.
176:             * @throws javax.ejb.EJBException If this method could not complete due to a system-level failure.
177:             */
178:            public void cancel() throws IllegalStateException,
179:                    NoSuchObjectLocalException, EJBException {
180:                assertTimedOut();
181:                assertAllowedOperation("Timer.cancel");
182:                registerTimerWithTx();
183:                cancelInTx();
184:            }
185:
186:            /**
187:             * Kill the timer, and remove it from the timer service
188:             */
189:            public void killTimer() {
190:                log.debug("killTimer: " + this );
191:                if (timerState != EXPIRED)
192:                    setTimerState(CANCELED);
193:                timerService.removeTimer(this );
194:                utilTimer.cancel();
195:            }
196:
197:            /**
198:             * killTimer w/o persistence work
199:             */
200:            private void cancelTimer() {
201:                if (timerState != EXPIRED)
202:                    setTimerState(CANCELED);
203:                utilTimer.cancel();
204:            }
205:
206:            /**
207:             * Kill the timer, do not remove from timer service
208:             */
209:            public void stopTimer() {
210:                log.debug("stopTimer: " + this );
211:                if (timerState != EXPIRED)
212:                    setTimerState(CANCELED);
213:                utilTimer.cancel();
214:            }
215:
216:            /**
217:             * Get the number of milliseconds that will elapse before the next scheduled txtimer expiration.
218:             *
219:             * @return Number of milliseconds that will elapse before the next scheduled txtimer expiration.
220:             * @throws IllegalStateException  If this method is invoked while the instance is in
221:             *                                a state that does not allow access to this method.
222:             * @throws javax.ejb.NoSuchObjectLocalException
223:             *                                If invoked on a txtimer that has expired or has been cancelled.
224:             * @throws javax.ejb.EJBException If this method could not complete due to a system-level failure.
225:             */
226:            public long getTimeRemaining() throws IllegalStateException,
227:                    NoSuchObjectLocalException, EJBException {
228:                assertTimedOut();
229:                assertAllowedOperation("Timer.getTimeRemaining");
230:                return nextExpire - System.currentTimeMillis();
231:            }
232:
233:            /**
234:             * Get the point in time at which the next txtimer expiration is scheduled to occur.
235:             *
236:             * @return Get the point in time at which the next txtimer expiration is scheduled to occur.
237:             * @throws IllegalStateException  If this method is invoked while the instance is in
238:             *                                a state that does not allow access to this method.
239:             * @throws javax.ejb.NoSuchObjectLocalException
240:             *                                If invoked on a txtimer that has expired or has been cancelled.
241:             * @throws javax.ejb.EJBException If this method could not complete due to a system-level failure.
242:             */
243:            public Date getNextTimeout() throws IllegalStateException,
244:                    NoSuchObjectLocalException, EJBException {
245:                assertTimedOut();
246:                assertAllowedOperation("Timer.getNextTimeout");
247:                return new Date(nextExpire);
248:            }
249:
250:            /**
251:             * Get the information associated with the txtimer at the time of creation.
252:             *
253:             * @return The Serializable object that was passed in at txtimer creation, or null if the
254:             *         info argument passed in at txtimer creation was null.
255:             * @throws IllegalStateException  If this method is invoked while the instance is in
256:             *                                a state that does not allow access to this method.
257:             * @throws javax.ejb.NoSuchObjectLocalException
258:             *                                If invoked on a txtimer that has expired or has been cancelled.
259:             * @throws javax.ejb.EJBException If this method could not complete due to a system-level failure.
260:             */
261:            public Serializable getInfo() throws IllegalStateException,
262:                    NoSuchObjectLocalException, EJBException {
263:                assertTimedOut();
264:                assertAllowedOperation("Timer.getInfo");
265:                return info;
266:            }
267:
268:            /**
269:             * Get a serializable handle to the txtimer. This handle can be used at a later time to
270:             * re-obtain the txtimer reference.
271:             *
272:             * @return Handle of the Timer
273:             * @throws IllegalStateException  If this method is invoked while the instance is in
274:             *                                a state that does not allow access to this method.
275:             * @throws javax.ejb.NoSuchObjectLocalException
276:             *                                If invoked on a txtimer that has expired or has been cancelled.
277:             * @throws javax.ejb.EJBException If this method could not complete due to a system-level failure.
278:             */
279:            public TimerHandle getHandle() throws IllegalStateException,
280:                    NoSuchObjectLocalException, EJBException {
281:                assertTimedOut();
282:                assertAllowedOperation("Timer.getHandle");
283:                return new TimerHandleImpl(this );
284:            }
285:
286:            /**
287:             * Return true if objectId, createDate, periode are equal
288:             */
289:            public boolean equals(Object obj) {
290:                if (obj == this )
291:                    return true;
292:                if (obj instanceof  TimerImpl) {
293:                    TimerImpl other = (TimerImpl) obj;
294:                    return hashCode() == other.hashCode();
295:                }
296:                return false;
297:            }
298:
299:            /**
300:             * Hash code based on the Timers invariant properties
301:             */
302:            public int hashCode() {
303:                if (hashCode == 0) {
304:                    String hash = "[" + timerId + "," + timedObjectId + ","
305:                            + firstTime + "," + periode + "]";
306:                    hashCode = hash.hashCode();
307:                }
308:                return hashCode;
309:            }
310:
311:            /**
312:             * Returns a string representation of the object.
313:             */
314:            public String toString() {
315:                long remaining = nextExpire - System.currentTimeMillis();
316:                String retStr = "[id=" + timerId + ",target=" + timedObjectId
317:                        + ",remaining=" + remaining + ",periode=" + periode
318:                        + "," + TIMER_STATES[timerState] + "]";
319:                return retStr;
320:            }
321:
322:            /**
323:             * Register the txtimer with the current transaction
324:             */
325:            private void registerTimerWithTx() {
326:                Transaction tx = timerService.getTransaction();
327:                if (tx != null) {
328:                    try {
329:                        tx.registerSynchronization(this );
330:                    } catch (Exception e) {
331:                        log.error("Cannot register txtimer with Tx: " + this );
332:                    }
333:                }
334:            }
335:
336:            private void setTimerState(int state) {
337:                log.debug("setTimerState: " + TIMER_STATES[state]);
338:                timerState = state;
339:            }
340:
341:            private void startInTx() {
342:                // JBAS-4330, provide a meaningful name to the timer thread, needs jdk5+
343:                utilTimer = new Timer("EJB-Timer-" + timerId + timedObjectId);
344:
345:                if (timerService.getTransaction() != null) {
346:                    // don't schedule the timeout yet
347:                    setTimerState(STARTED_IN_TX);
348:                } else {
349:                    scheduleTimeout();
350:                    setTimerState(ACTIVE);
351:                }
352:            }
353:
354:            private void cancelInTx() {
355:                if (timerService.getTransaction() != null)
356:                    setTimerState(CANCELED_IN_TX);
357:                else
358:                    killTimer();
359:            }
360:
361:            private void scheduleTimeout() {
362:                if (periode > 0)
363:                    utilTimer.schedule(new TimerTaskImpl(this ), new Date(
364:                            nextExpire), periode);
365:                else
366:                    utilTimer.schedule(new TimerTaskImpl(this ), new Date(
367:                            nextExpire));
368:            }
369:
370:            /**
371:             * Throws NoSuchObjectLocalException if the txtimer was canceled or has expired
372:             */
373:            private void assertTimedOut() {
374:                if (timerState == EXPIRED)
375:                    throw new NoSuchObjectLocalException("Timer has expired");
376:                if (timerState == CANCELED_IN_TX || timerState == CANCELED)
377:                    throw new NoSuchObjectLocalException("Timer was canceled");
378:            }
379:
380:            /**
381:             * Throws an IllegalStateException if the Timer method call is not allowed in the current context
382:             */
383:            private void assertAllowedOperation(String timerMethod) {
384:                AllowedOperationsAssociation
385:                        .assertAllowedIn(
386:                                timerMethod,
387:                                AllowedOperationsAssociation.IN_BUSINESS_METHOD
388:                                        | AllowedOperationsAssociation.IN_EJB_TIMEOUT
389:                                        | AllowedOperationsAssociation.IN_SERVICE_ENDPOINT_METHOD
390:                                        | AllowedOperationsAssociation.IN_AFTER_BEGIN
391:                                        | AllowedOperationsAssociation.IN_BEFORE_COMPLETION
392:                                        | AllowedOperationsAssociation.IN_EJB_POST_CREATE
393:                                        | AllowedOperationsAssociation.IN_EJB_REMOVE
394:                                        | AllowedOperationsAssociation.IN_EJB_LOAD
395:                                        | AllowedOperationsAssociation.IN_EJB_STORE);
396:            }
397:
398:            // Synchronization **************************************************************************************************
399:
400:            /**
401:             * This method is invoked before the start of the commit or rollback
402:             * process. The method invocation is done in the context of the
403:             * transaction that is about to be committed or rolled back.
404:             */
405:            public void beforeCompletion() {
406:                switch (timerState) {
407:                case CANCELED_IN_TX:
408:                    timerService.removeTimer(this );
409:                    break;
410:
411:                case IN_TIMEOUT:
412:                case RETRY_TIMEOUT:
413:                    if (periode == 0) {
414:                        timerService.removeTimer(this );
415:                    }
416:                    break;
417:                }
418:            }
419:
420:            /**
421:             * This method is invoked after the transaction has committed or
422:             * rolled back.
423:             *
424:             * @param status The status of the completed transaction.
425:             */
426:            public void afterCompletion(int status) {
427:                if (status == Status.STATUS_COMMITTED) {
428:                    log.debug("commit: " + this );
429:
430:                    switch (timerState) {
431:                    case STARTED_IN_TX:
432:                        scheduleTimeout();
433:                        setTimerState(ACTIVE);
434:                        break;
435:
436:                    case CANCELED_IN_TX:
437:                        cancelTimer();
438:                        break;
439:
440:                    case IN_TIMEOUT:
441:                    case RETRY_TIMEOUT:
442:                        if (periode == 0) {
443:                            setTimerState(EXPIRED);
444:                            cancelTimer();
445:                        } else {
446:                            setTimerState(ACTIVE);
447:                        }
448:                        break;
449:                    }
450:                } else if (status == Status.STATUS_ROLLEDBACK) {
451:                    log.debug("rollback: " + this );
452:
453:                    switch (timerState) {
454:                    case STARTED_IN_TX:
455:                        cancelTimer();
456:                        break;
457:
458:                    case CANCELED_IN_TX:
459:                        setTimerState(ACTIVE);
460:                        break;
461:
462:                    case IN_TIMEOUT:
463:                        setTimerState(RETRY_TIMEOUT);
464:                        log.debug("retry: " + this );
465:                        timerService.retryTimeout(this );
466:                        break;
467:
468:                    case RETRY_TIMEOUT:
469:                        if (periode == 0) {
470:                            setTimerState(EXPIRED);
471:                            cancelTimer();
472:                        } else {
473:                            setTimerState(ACTIVE);
474:                        }
475:                        break;
476:                    }
477:                }
478:            }
479:
480:            // TimerTask ********************************************************************************************************
481:
482:            /**
483:             * The TimerTask's run method is invoked by the java.util.Timer
484:             */
485:            private class TimerTaskImpl extends TimerTask {
486:                private TimerImpl timer;
487:
488:                public TimerTaskImpl(TimerImpl timer) {
489:                    this .timer = timer;
490:                }
491:
492:                /**
493:                 * The action to be performed by this txtimer task.
494:                 */
495:                public void run() {
496:                    log.debug("run: " + timer);
497:
498:                    // Set next scheduled execution attempt. This is used only
499:                    // for reporting (getTimeRemaining()/getNextTimeout())
500:                    // and not from the underlying jdk timer implementation.
501:                    if (isActive() && periode > 0) {
502:                        nextExpire += periode;
503:                    }
504:
505:                    // If a retry thread is in progress, we don't want to allow another
506:                    // interval to execute until the retry is complete. See JIRA-1926.
507:                    if (isInRetry()) {
508:                        log
509:                                .debug("Timer in retry mode, skipping this scheduled execution");
510:                        return;
511:                    }
512:
513:                    if (isActive()) {
514:                        try {
515:                            setTimerState(IN_TIMEOUT);
516:                            timedObjectInvoker.callTimeout(timer);
517:                        } catch (Exception e) {
518:                            log.error("Error invoking ejbTimeout: "
519:                                    + e.toString());
520:                        } finally {
521:                            if (timerState == IN_TIMEOUT) {
522:                                log
523:                                        .debug("Timer was not registered with Tx, resetting state: "
524:                                                + timer);
525:                                if (periode == 0) {
526:                                    setTimerState(EXPIRED);
527:                                    killTimer();
528:                                } else {
529:                                    setTimerState(ACTIVE);
530:                                }
531:                            }
532:                        }
533:                    }
534:                }
535:            }
536:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.