KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > ejb > containers > TimerBean


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.ejb.containers;
25
26 import java.io.Serializable JavaDoc;
27 import java.io.ByteArrayOutputStream JavaDoc;
28 import java.io.ByteArrayInputStream JavaDoc;
29 import java.io.ObjectInputStream JavaDoc;
30 import java.io.IOException JavaDoc;
31 import java.util.Date JavaDoc;
32 import java.util.Set JavaDoc;
33 import java.util.HashSet JavaDoc;
34 import java.util.Iterator JavaDoc;
35
36 import javax.ejb.EJBContext JavaDoc;
37 import javax.ejb.EntityBean JavaDoc;
38 import javax.ejb.EJBException JavaDoc;
39 import javax.ejb.CreateException JavaDoc;
40 import javax.ejb.FinderException JavaDoc;
41 import javax.ejb.EntityContext JavaDoc;
42 import javax.ejb.EJBLocalObject JavaDoc;
43 import javax.ejb.Timer JavaDoc;
44
45 import javax.transaction.Synchronization JavaDoc;
46 import javax.transaction.Transaction JavaDoc;
47 import javax.transaction.Status JavaDoc;
48
49 import java.util.logging.Logger JavaDoc;
50 import java.util.logging.Level JavaDoc;
51
52 import com.sun.logging.LogDomains;
53 import com.sun.enterprise.ComponentInvocation;
54 import com.sun.enterprise.InvocationManager;
55 import com.sun.enterprise.Switch;
56
57 import com.sun.enterprise.server.ApplicationServer;
58 import com.sun.enterprise.instance.InstanceEnvironment;
59 import com.sun.enterprise.instance.ServerManager;
60 import com.sun.enterprise.deployment.EjbDescriptor;
61
62 import com.sun.ejb.EJBUtils;
63 import com.sun.ejb.ContainerFactory;
64
65 import javax.naming.InitialContext JavaDoc;
66 import javax.sql.DataSource JavaDoc;
67 import java.sql.Connection JavaDoc;
68
69 /**
70  * TimerBean is a coarse-grained persistent representation
71  * of an EJB Timer. It is part of the EJB container but
72  * implemented as a CMP 2.1 Entity bean. The standard
73  * CMP behavior is useful in implementing the transactional
74  * properties of EJB timers. When an EJB timer is created
75  * by an application, it is not eligible for expiration until
76  * the transaction commits. Likewise, if a timer is cancelled
77  * and the transaction rolls back, the timer must be reactivated.
78  * To accomplish this, TimerBean registers callbacks with the
79  * transaction manager and interacts with the EJBTimerService
80  * accordingly.
81  *
82  * @author Kenneth Saks
83  */

84 public abstract class TimerBean implements EntityBean JavaDoc {
85
86     private static Logger JavaDoc logger = LogDomains.getLogger(LogDomains.EJB_LOGGER);
87
88     // Timer states
89
private static final int ACTIVE = 0;
90     private static final int CANCELLED = 1;
91
92     private EJBContextImpl context_;
93
94     //
95
// CMP fields
96
//
97

98     // primary key
99
public abstract String JavaDoc getTimerId();
100     public abstract void setTimerId(String JavaDoc timerId);
101
102     public abstract String JavaDoc getOwnerId();
103     public abstract void setOwnerId(String JavaDoc ownerId);
104
105     public abstract long getCreationTimeRaw();
106     public abstract void setCreationTimeRaw(long creationTime);
107
108     public abstract long getInitialExpirationRaw();
109     public abstract void setInitialExpirationRaw(long initialExpiration);
110
111     public abstract long getLastExpirationRaw();
112     public abstract void setLastExpirationRaw(long lastExpiration);
113
114     public abstract long getIntervalDuration();
115     public abstract void setIntervalDuration(long intervalDuration);
116
117     public abstract int getState();
118     public abstract void setState(int state);
119
120     public abstract long getContainerId();
121     public abstract void setContainerId(long containerId);
122
123     public abstract Blob getBlob();
124     public abstract void setBlob(Blob blob);
125
126     public abstract int getPkHashCode();
127     public abstract void setPkHashCode(int pkHash);
128
129     //
130
// ejbSelect methods for timer ids
131
//
132

133     public abstract Set JavaDoc ejbSelectTimerIdsByContainer(long containerId)
134         throws FinderException JavaDoc;
135     public abstract Set JavaDoc ejbSelectTimerIdsByContainerAndState
136         (long containerId, int state) throws FinderException JavaDoc;
137
138     public abstract Set JavaDoc ejbSelectTimerIdsByContainerAndOwner
139         (long containerId, String JavaDoc ownerId)
140         throws FinderException JavaDoc;
141     public abstract Set JavaDoc ejbSelectTimerIdsByContainerAndOwnerAndState
142         (long containerId, String JavaDoc ownerId, int state) throws FinderException JavaDoc;
143
144     public abstract Set JavaDoc ejbSelectAllTimerIdsByOwner(String JavaDoc ownerId)
145         throws FinderException JavaDoc;
146     public abstract Set JavaDoc ejbSelectAllTimerIdsByOwnerAndState
147         (String JavaDoc ownerId, int state) throws FinderException JavaDoc;
148
149    
150     //
151
// ejbSelect methods for timer beans
152
//
153

154     public abstract Set JavaDoc ejbSelectTimersByContainer(long containerId)
155         throws FinderException JavaDoc;
156     public abstract Set JavaDoc ejbSelectTimersByContainerAndState
157         (long containerId, int state) throws FinderException JavaDoc;
158
159     public abstract Set JavaDoc ejbSelectTimersByContainerAndOwner
160         (long containerId, String JavaDoc ownerId)
161         throws FinderException JavaDoc;
162     public abstract Set JavaDoc ejbSelectTimersByContainerAndOwnerAndState
163         (long containerId, String JavaDoc ownerId, int state) throws FinderException JavaDoc;
164
165     public abstract Set JavaDoc ejbSelectAllTimersByOwner(String JavaDoc ownerId)
166         throws FinderException JavaDoc;
167     public abstract Set JavaDoc ejbSelectAllTimersByOwnerAndState
168         (String JavaDoc ownerId, int state) throws FinderException JavaDoc;
169
170
171     //
172
// ejbSelect methods for timer counts
173
//
174

175     public abstract int ejbSelectCountTimersByContainer(long containerId)
176         throws FinderException JavaDoc;
177     public abstract int ejbSelectCountTimersByContainerAndState
178         (long containerId, int state) throws FinderException JavaDoc;
179
180     public abstract int ejbSelectCountTimersByContainerAndOwner
181         (long containerId, String JavaDoc ownerId)
182         throws FinderException JavaDoc;
183     public abstract int ejbSelectCountTimersByContainerAndOwnerAndState
184         (long containerId, String JavaDoc ownerId, int state) throws FinderException JavaDoc;
185
186     public abstract int ejbSelectCountAllTimersByOwner(String JavaDoc ownerId)
187         throws FinderException JavaDoc;
188     public abstract int ejbSelectCountAllTimersByOwnerAndState
189         (String JavaDoc ownerId, int state) throws FinderException JavaDoc;
190
191     //
192
// These data members contain derived state for
193
// some immutable fields.
194
//
195

196     // deserialized state from blob
197
private boolean blobLoaded_;
198     private Object JavaDoc timedObjectPrimaryKey_;
199     private transient Serializable JavaDoc info_;
200
201     // Dates
202
private transient Date JavaDoc creationTime_;
203     private transient Date JavaDoc initialExpiration_;
204     private transient Date JavaDoc lastExpiration_;
205     
206     public TimerPrimaryKey ejbCreate
207         (String JavaDoc timerId, long containerId, String JavaDoc ownerId,
208          Object JavaDoc timedObjectPrimaryKey,
209          Date JavaDoc initialExpiration, long intervalDuration, Serializable JavaDoc info)
210         throws CreateException JavaDoc {
211
212         setTimerId(timerId);
213         
214         setOwnerId(ownerId);
215
216         return null;
217     }
218     
219     public void ejbPostCreate(String JavaDoc timerId, long containerId, String JavaDoc ownerId,
220                               Object JavaDoc timedObjectPrimaryKey,
221                               Date JavaDoc initialExpiration,
222                               long intervalDuration, Serializable JavaDoc info)
223         throws CreateException JavaDoc {
224
225         Date JavaDoc creationTime = new Date JavaDoc();
226         setCreationTimeRaw(creationTime.getTime());
227         creationTime_ = creationTime;
228
229         setInitialExpirationRaw(initialExpiration.getTime());
230         initialExpiration_ = initialExpiration;
231
232         setLastExpirationRaw(0);
233         lastExpiration_ = null;
234
235         setIntervalDuration(intervalDuration);
236
237         setContainerId(containerId);
238
239         timedObjectPrimaryKey_ = timedObjectPrimaryKey;
240         info_ = info;
241         blobLoaded_ = true;
242
243         Blob blob = null;
244         try {
245             blob = new Blob(timedObjectPrimaryKey, info);
246         } catch(IOException JavaDoc ioe) {
247             CreateException JavaDoc ce = new CreateException JavaDoc();
248             ce.initCause(ioe);
249             throw ce;
250         }
251
252         setBlob(blob);
253         setState(ACTIVE);
254
255         if( logger.isLoggable(Level.FINE) ) {
256             logger.log(Level.FINE, "TimerBean.postCreate() ::timerId=" +
257                        getTimerId() + " ::containerId=" + getContainerId() +
258                        " ::timedObjectPK=" + timedObjectPrimaryKey +
259                        " ::info=" + info +
260                        " ::initialExpiration=" + initialExpiration +
261                        " ::intervalDuration=" + intervalDuration +
262                        " :::state=" + stateToString(getState()) +
263                        " :::creationTime=" + creationTime +
264                        " :::ownerId=" + getOwnerId());
265         }
266
267         //
268
// Only proceed with transactional semantics if this timer
269
// is owned by the current server instance. NOTE that this
270
// will *ALWAYS* be the case for timers created from EJB
271
// applications via the javax.ejb.EJBTimerService.create methods.
272
//
273
// For testing purposes, ejbCreate takes an ownerId parameter,
274
// which allows us to easily simulate other server instances
275
// by creating timers for them. In those cases, we don't need
276
// the timer transaction semantics and ejbTimeout logic. Simulating
277
// the creation of timers for the same application and different
278
// server instances from a script is difficult since the
279
// containerId is not generated until after deployment.
280
//
281
if( timerOwnedByThisServer() ) {
282
283             // Register a synchronization object to handle the commit/rollback
284
// semantics and ejbTimeout notifications.
285
Synchronization JavaDoc timerSynch =
286                 new TimerSynch(new TimerPrimaryKey(getTimerId()), ACTIVE,
287                                getInitialExpiration(),
288                                getContainer(containerId));
289             
290             try {
291                 ContainerSynchronization containerSynch = getContainerSynch();
292                 containerSynch.addTimerSynchronization
293                     (new TimerPrimaryKey(getTimerId()), timerSynch);
294             } catch(Exception JavaDoc e) {
295                 CreateException JavaDoc ce = new CreateException JavaDoc();
296                 ce.initCause(e);
297                 throw ce;
298             }
299         }
300     }
301
302     /**
303      * Checks whether this timer is owned by the server instance in
304      * which we are running.
305      */

306     private boolean timerOwnedByThisServer() {
307         String JavaDoc ownerIdOfThisServer = getOwnerIdOfThisServer();
308         return ( (ownerIdOfThisServer != null) &&
309                  (ownerIdOfThisServer.equals(getOwnerId())) );
310     }
311
312     private String JavaDoc getOwnerIdOfThisServer() {
313         return getEJBTimerService().getOwnerIdOfThisServer();
314     }
315
316     private static String JavaDoc stateToString(int state) {
317         String JavaDoc stateStr = "UNKNOWN_TIMER_STATE";
318
319         switch(state) {
320             case ACTIVE :
321                 stateStr = "TIMER_ACTIVE";
322                 break;
323             case CANCELLED :
324                 stateStr = "TIMER_CANCELLED";
325                 break;
326             default :
327                 stateStr = "UNKNOWN_TIMER_STATE";
328                 break;
329         }
330
331         return stateStr;
332     }
333
334     private static String JavaDoc txStatusToString(int txStatus) {
335         String JavaDoc txStatusStr = "UNMATCHED TX STATUS";
336
337         switch(txStatus) {
338             case Status.STATUS_ACTIVE :
339                 txStatusStr = "TX_STATUS_ACTIVE";
340                 break;
341             case Status.STATUS_COMMITTED :
342                 txStatusStr = "TX_STATUS_COMMITTED";
343                 break;
344             case Status.STATUS_COMMITTING :
345                 txStatusStr = "TX_STATUS_COMMITTING";
346                 break;
347             case Status.STATUS_MARKED_ROLLBACK :
348                 txStatusStr = "TX_STATUS_MARKED_ROLLBACK";
349                 break;
350             case Status.STATUS_NO_TRANSACTION :
351                 txStatusStr = "TX_STATUS_NO_TRANSACTION";
352                 break;
353             case Status.STATUS_PREPARED :
354                 txStatusStr = "TX_STATUS_PREPARED";
355                 break;
356             case Status.STATUS_PREPARING :
357                 txStatusStr = "TX_STATUS_PREPARING";
358                 break;
359             case Status.STATUS_ROLLEDBACK :
360                 txStatusStr = "TX_STATUS_ROLLEDBACK";
361                 break;
362             case Status.STATUS_ROLLING_BACK :
363                 txStatusStr = "TX_STATUS_ROLLING_BACK";
364                 break;
365             case Status.STATUS_UNKNOWN :
366                 txStatusStr = "TX_STATUS_UNKNOWN";
367                 break;
368             default :
369                 txStatusStr = "UNMATCHED TX STATUS";
370                 break;
371         }
372
373         return txStatusStr;
374     }
375
376
377     private ContainerSynchronization getContainerSynch() throws Exception JavaDoc {
378
379         EntityContainer container = (EntityContainer) context_.getContainer();
380         ContainerFactoryImpl containerFactory = (ContainerFactoryImpl)
381             Switch.getSwitch().getContainerFactory();
382         Transaction JavaDoc transaction = context_.getTransaction();
383
384         if( transaction == null ) {
385             logger.log(Level.FINE, "Context transaction = null. Using " +
386                        "invocation instead.");
387             InvocationManager iMgr = Switch.getSwitch().getInvocationManager();
388             ComponentInvocation i = iMgr.getCurrentInvocation();
389             transaction = i.transaction;
390         }
391         if( transaction == null ) {
392             throw new Exception JavaDoc("transaction = null in getContainerSynch " +
393                                 "for timerId = " + getTimerId());
394         }
395
396         ContainerSynchronization containerSync =
397             containerFactory.getContainerSync(transaction);
398         return containerSync;
399     }
400
401     private static EJBTimerService getEJBTimerService() {
402         ContainerFactoryImpl containerFactory = (ContainerFactoryImpl)
403             Switch.getSwitch().getContainerFactory();
404         return containerFactory.getEJBTimerService();
405     }
406
407     private void loadBlob() {
408         EJBTimerService timerService = getEJBTimerService();
409         ClassLoader JavaDoc cl = timerService.getTimerClassLoader(getContainerId());
410         if( cl != null ) {
411             loadBlob(cl);
412         } else {
413             throw new EJBException JavaDoc("No timer classloader for " + getTimerId());
414         }
415     }
416
417     private void loadBlob(ClassLoader JavaDoc cl) {
418         try {
419             Blob blob = getBlob();
420             timedObjectPrimaryKey_ = blob.getTimedObjectPrimaryKey(cl);
421             info_ = blob.getInfo(cl);
422             blobLoaded_ = true;
423         } catch(Exception JavaDoc e) {
424             EJBException JavaDoc ejbEx = new EJBException JavaDoc();
425             ejbEx.initCause(e);
426             throw ejbEx;
427         }
428     }
429
430     public void setEntityContext(EntityContext JavaDoc context) {
431         context_ = (EJBContextImpl) context;
432     }
433     
434     public void unsetEntityContext() {
435         context_ = null;
436     }
437     
438     public void ejbRemove() {}
439     
440     public void ejbLoad() {
441
442         long lastExpirationRaw = getLastExpirationRaw();
443         lastExpiration_ = (lastExpirationRaw > 0) ?
444             new Date JavaDoc(lastExpirationRaw) : null;
445         
446         // Populate derived state of immutable cmp fields.
447
creationTime_ = new Date JavaDoc(getCreationTimeRaw());
448         initialExpiration_ = new Date JavaDoc(getInitialExpirationRaw());
449
450         // Lazily deserialize Blob state. This makes the
451
// Timer bootstrapping code easier, since some of the Timer
452
// state must be loaded from the database before the
453
// container and application classloader are known.
454
timedObjectPrimaryKey_ = null;
455         info_ = null;
456         blobLoaded_ = false;
457     }
458
459     public void ejbStore() {}
460     
461     public void ejbPassivate() {}
462     
463     public void ejbActivate() {}
464
465     public boolean repeats() {
466         return (getIntervalDuration() > 0);
467     }
468
469     public void cancel() throws Exception JavaDoc {
470
471         // First set the timer to the cancelled state. This step is
472
// performed whether or not the current server instance owns
473
// the timer.
474

475         if( getState() == CANCELLED ) {
476             // already cancelled
477
return;
478         }
479
480         setState(CANCELLED);
481
482         // Only proceed with JDK timer task cancellation if this timer
483
// is owned by the current server instance.
484
if( timerOwnedByThisServer() ) {
485                     
486             TimerPrimaryKey timerId = new TimerPrimaryKey(getTimerId());
487             
488             // Cancel existing timer task. Save time at which task would
489
// have executed in case cancellation is rolled back. The
490
// nextTimeout can be null if the timer is currently being
491
// delivered.
492
Date JavaDoc nextTimeout = getEJBTimerService().cancelTask(timerId);
493             
494             ContainerSynchronization containerSynch = getContainerSynch();
495             Synchronization JavaDoc timerSynch =
496                 containerSynch.getTimerSynchronization(timerId);
497             
498             if( timerSynch != null ) {
499                 // This timer was created and cancelled within the
500
// same transaction. No tx synchronization actions
501
// are needed, since whether tx commits or rolls back,
502
// timer will not exist.
503
containerSynch.removeTimerSynchronization(timerId);
504                 getEJBTimerService().expungeTimer(timerId);
505             } else {
506                 // Set tx synchronization action to handle timer cancellation.
507
timerSynch = new TimerSynch(timerId, CANCELLED, nextTimeout,
508                                         getContainer(getContainerId()));
509                 containerSynch.addTimerSynchronization(timerId, timerSynch);
510             }
511
512         }
513
514         // NOTE that it's the caller's responsibility to call remove().
515
return;
516     }
517
518     public Serializable JavaDoc getInfo() {
519         if( !blobLoaded_ ) {
520             loadBlob();
521         }
522         return info_;
523     }
524
525     public Object JavaDoc getTimedObjectPrimaryKey() {
526         if( !blobLoaded_ ) {
527             loadBlob();
528         }
529         return timedObjectPrimaryKey_;
530     }
531
532     public Date JavaDoc getCreationTime() {
533         return creationTime_;
534     }
535
536     public Date JavaDoc getInitialExpiration() {
537         return initialExpiration_;
538     }
539
540     public Date JavaDoc getLastExpiration() {
541         return lastExpiration_;
542     }
543
544     public void setLastExpiration(Date JavaDoc lastExpiration) {
545         // can be null
546
lastExpiration_ = lastExpiration;
547         long lastExpirationRaw = (lastExpiration != null) ?
548             lastExpiration.getTime() : 0;
549         setLastExpirationRaw(lastExpirationRaw);
550     }
551
552     public boolean isActive() {
553         return (getState() == ACTIVE);
554     }
555
556     public boolean isCancelled() {
557         return (getState() == CANCELLED);
558     }
559
560     private Set JavaDoc toPKeys(Set JavaDoc ids) {
561         Set JavaDoc pkeys = new HashSet JavaDoc();
562         for(Iterator JavaDoc iter = ids.iterator(); iter.hasNext();) {
563             pkeys.add(new TimerPrimaryKey((String JavaDoc) iter.next()));
564         }
565         return pkeys;
566     }
567
568     //
569
// ejbHome methods for timer ids
570
//
571

572     public Set JavaDoc ejbHomeSelectTimerIdsByContainer(long containerId)
573         throws FinderException JavaDoc {
574         return toPKeys(ejbSelectTimerIdsByContainer(containerId));
575     }
576
577     public Set JavaDoc ejbHomeSelectActiveTimerIdsByContainer(long containerId)
578         throws FinderException JavaDoc {
579         return toPKeys(ejbSelectTimerIdsByContainerAndState(containerId,
580                                                             ACTIVE));
581     }
582
583     public Set JavaDoc ejbHomeSelectCancelledTimerIdsByContainer(long containerId)
584         throws FinderException JavaDoc {
585         return toPKeys(ejbSelectTimerIdsByContainerAndState
586                        (containerId, CANCELLED));
587     }
588
589     public Set JavaDoc ejbHomeSelectTimerIdsOwnedByThisServerByContainer
590         (long containerId)
591         throws FinderException JavaDoc {
592         return toPKeys(ejbSelectTimerIdsByContainerAndOwner
593                          (containerId, getOwnerIdOfThisServer()));
594     }
595
596     public Set JavaDoc ejbHomeSelectActiveTimerIdsOwnedByThisServerByContainer
597         (long containerId)
598         throws FinderException JavaDoc {
599         return toPKeys(ejbSelectTimerIdsByContainerAndOwnerAndState
600                        (containerId, getOwnerIdOfThisServer(), ACTIVE));
601     }
602
603     public Set JavaDoc ejbHomeSelectCancelledTimerIdsOwnedByThisServerByContainer
604         (long containerId)
605         throws FinderException JavaDoc {
606         return toPKeys(ejbSelectTimerIdsByContainerAndOwnerAndState
607                        (containerId, getOwnerIdOfThisServer(), CANCELLED));
608     }
609
610
611     public Set JavaDoc ejbHomeSelectAllTimerIdsOwnedByThisServer()
612         throws FinderException JavaDoc {
613         return toPKeys(ejbSelectAllTimerIdsByOwner(getOwnerIdOfThisServer()));
614     }
615    
616     public Set JavaDoc ejbHomeSelectAllActiveTimerIdsOwnedByThisServer()
617         throws FinderException JavaDoc {
618         return toPKeys(ejbSelectAllTimerIdsByOwnerAndState
619                        (getOwnerIdOfThisServer(), ACTIVE));
620     }
621
622     public Set JavaDoc ejbHomeSelectAllCancelledTimerIdsOwnedByThisServer()
623         throws FinderException JavaDoc {
624         return toPKeys(ejbSelectAllTimerIdsByOwnerAndState
625                        (getOwnerIdOfThisServer(), CANCELLED));
626     }
627
628     
629     public Set JavaDoc ejbHomeSelectAllTimerIdsOwnedBy(String JavaDoc ownerId)
630         throws FinderException JavaDoc {
631         return toPKeys(ejbSelectAllTimerIdsByOwner(ownerId));
632     }
633    
634     public Set JavaDoc ejbHomeSelectAllActiveTimerIdsOwnedBy(String JavaDoc ownerId)
635         throws FinderException JavaDoc {
636         return toPKeys(ejbSelectAllTimerIdsByOwnerAndState
637                        (ownerId, ACTIVE));
638     }
639
640     public Set JavaDoc ejbHomeSelectAllCancelledTimerIdsOwnedBy(String JavaDoc ownerId)
641         throws FinderException JavaDoc {
642         return toPKeys(ejbSelectAllTimerIdsByOwnerAndState
643                        (ownerId, CANCELLED));
644     }
645
646     //
647
// ejbHome methods for timer beans
648
//
649

650     public Set JavaDoc ejbHomeSelectTimersByContainer(long containerId)
651         throws FinderException JavaDoc {
652         return ejbSelectTimersByContainer(containerId);
653     }
654
655     public Set JavaDoc ejbHomeSelectActiveTimersByContainer(long containerId)
656         throws FinderException JavaDoc {
657         return ejbSelectTimersByContainerAndState(containerId,
658                                                   ACTIVE);
659     }
660
661     public Set JavaDoc ejbHomeSelectCancelledTimersByContainer(long containerId)
662         throws FinderException JavaDoc {
663         return ejbSelectTimersByContainerAndState
664                        (containerId, CANCELLED);
665     }
666
667     public Set JavaDoc ejbHomeSelectTimersOwnedByThisServerByContainer
668         (long containerId)
669         throws FinderException JavaDoc {
670         return ejbSelectTimersByContainerAndOwner
671                          (containerId, getOwnerIdOfThisServer());
672     }
673
674     public Set JavaDoc ejbHomeSelectActiveTimersOwnedByThisServerByContainer
675         (long containerId)
676         throws FinderException JavaDoc {
677         return ejbSelectTimersByContainerAndOwnerAndState
678                        (containerId, getOwnerIdOfThisServer(), ACTIVE);
679     }
680
681     public Set JavaDoc ejbHomeSelectCancelledTimersOwnedByThisServerByContainer
682         (long containerId)
683         throws FinderException JavaDoc {
684         return ejbSelectTimersByContainerAndOwnerAndState
685                        (containerId, getOwnerIdOfThisServer(), CANCELLED);
686     }
687
688
689     public Set JavaDoc ejbHomeSelectAllTimersOwnedByThisServer()
690         throws FinderException JavaDoc {
691         return ejbSelectAllTimersByOwner(getOwnerIdOfThisServer());
692     }
693    
694     public Set JavaDoc ejbHomeSelectAllActiveTimersOwnedByThisServer()
695         throws FinderException JavaDoc {
696         return ejbSelectAllTimersByOwnerAndState
697                        (getOwnerIdOfThisServer(), ACTIVE);
698     }
699
700     public Set JavaDoc ejbHomeSelectAllCancelledTimersOwnedByThisServer()
701         throws FinderException JavaDoc {
702         return ejbSelectAllTimersByOwnerAndState
703                        (getOwnerIdOfThisServer(), CANCELLED);
704     }
705
706     
707     public Set JavaDoc ejbHomeSelectAllTimersOwnedBy(String JavaDoc ownerId)
708         throws FinderException JavaDoc {
709         return ejbSelectAllTimersByOwner(ownerId);
710     }
711    
712     public Set JavaDoc ejbHomeSelectAllActiveTimersOwnedBy(String JavaDoc ownerId)
713         throws FinderException JavaDoc {
714         return ejbSelectAllTimersByOwnerAndState
715                        (ownerId, ACTIVE);
716     }
717
718     public Set JavaDoc ejbHomeSelectAllCancelledTimersOwnedBy(String JavaDoc ownerId)
719         throws FinderException JavaDoc {
720         return ejbSelectAllTimersByOwnerAndState
721                        (ownerId, CANCELLED);
722     }
723
724
725     //
726
// ejbHome methods for timer counts
727
//
728

729     public int ejbHomeSelectCountTimersByContainer(long containerId)
730         throws FinderException JavaDoc {
731         return ejbSelectCountTimersByContainer(containerId);
732     }
733
734     public int ejbHomeSelectCountActiveTimersByContainer(long containerId)
735         throws FinderException JavaDoc {
736         return ejbSelectCountTimersByContainerAndState(containerId,
737                                                        ACTIVE);
738     }
739
740     public int ejbHomeSelectCountCancelledTimersByContainer(long containerId)
741         throws FinderException JavaDoc {
742         return ejbSelectCountTimersByContainerAndState
743                        (containerId, CANCELLED);
744     }
745
746     public int ejbHomeSelectCountTimersOwnedByThisServerByContainer
747         (long containerId)
748         throws FinderException JavaDoc {
749         return ejbSelectCountTimersByContainerAndOwner
750                          (containerId, getOwnerIdOfThisServer());
751     }
752
753     public int ejbHomeSelectCountActiveTimersOwnedByThisServerByContainer
754         (long containerId)
755         throws FinderException JavaDoc {
756         return ejbSelectCountTimersByContainerAndOwnerAndState
757                        (containerId, getOwnerIdOfThisServer(), ACTIVE);
758     }
759
760     public int ejbHomeSelectCountCancelledTimersOwnedByThisServerByContainer
761         (long containerId)
762         throws FinderException JavaDoc {
763         return ejbSelectCountTimersByContainerAndOwnerAndState
764                        (containerId, getOwnerIdOfThisServer(), CANCELLED);
765     }
766
767
768     public int ejbHomeSelectCountAllTimersOwnedByThisServer()
769         throws FinderException JavaDoc {
770         return ejbSelectCountAllTimersByOwner(getOwnerIdOfThisServer());
771     }
772    
773     public int ejbHomeSelectCountAllActiveTimersOwnedByThisServer()
774         throws FinderException JavaDoc {
775         return ejbSelectCountAllTimersByOwnerAndState
776                        (getOwnerIdOfThisServer(), ACTIVE);
777     }
778
779     public int ejbHomeSelectCountAllCancelledTimersOwnedByThisServer()
780         throws FinderException JavaDoc {
781         return ejbSelectCountAllTimersByOwnerAndState
782                        (getOwnerIdOfThisServer(), CANCELLED);
783     }
784
785     
786     public int ejbHomeSelectCountAllTimersOwnedBy(String JavaDoc ownerId)
787         throws FinderException JavaDoc {
788         return ejbSelectCountAllTimersByOwner(ownerId);
789     }
790    
791     public int ejbHomeSelectCountAllActiveTimersOwnedBy(String JavaDoc ownerId)
792         throws FinderException JavaDoc {
793         return ejbSelectCountAllTimersByOwnerAndState
794                        (ownerId, ACTIVE);
795     }
796
797     public int ejbHomeSelectCountAllCancelledTimersOwnedBy(String JavaDoc ownerId)
798         throws FinderException JavaDoc {
799         return ejbSelectCountAllTimersByOwnerAndState
800                        (ownerId, CANCELLED);
801     }
802
803     public boolean ejbHomeCheckStatus(String JavaDoc resourceJndiName,
804                                       boolean checkDatabase) {
805
806         boolean success = false;
807
808         Connection JavaDoc connection = null;
809
810         try {
811
812             InitialContext JavaDoc ic = new InitialContext JavaDoc();
813             
814             DataSource JavaDoc dataSource = (DataSource JavaDoc) ic.lookup(resourceJndiName);
815
816             if( checkDatabase ) {
817                 connection = dataSource.getConnection();
818                 
819                 connection.close();
820                 
821                 connection = null;
822                 
823                 // Now try to a query that will access the timer table itself.
824
// Use a query that won't return a lot of data(even if the
825
// table is large) to reduce the overhead of this check.
826
ejbSelectCountTimersByContainer(0);
827             }
828
829             success = true;
830                         
831         } catch(Exception JavaDoc e) {
832
833             logger.log(Level.WARNING, "ejb.timer_service_init_error",
834                        "");
835             // Log exception itself at FINE level. The most likely cause
836
// is a connection error when the database is not started. This
837
// is already logged twice by the jdbc layer.
838
logger.log(Level.FINE, "ejb.timer_service_init_error", e);
839
840         } finally {
841             if( connection != null ) {
842                 try {
843                     connection.close();
844                 } catch(Exception JavaDoc e) {
845                     logger.log(Level.FINE, "timer connection close exception",
846                                e);
847                 }
848             }
849         }
850
851         return success;
852     }
853
854     /**
855      * Many DBs have a limitation that at most one field per DB
856      * can hold binary data. As a workaround, store both EJBLocalObject
857      * and "info" as a single Serializable blob. This is necessary
858      * since primary key of EJBLocalObject could be a compound object.
859      * This class also isolates the portion of Timer data that is
860      * associated with the TimedObject itself. During deserialization,
861      * we must use the application class loader for the timed object,
862      * since both the primary key and info object can be application
863      * classes.
864      *
865      */

866     public static class Blob implements Serializable JavaDoc {
867
868         private byte[] primaryKeyBytes_ = null;
869         private byte[] infoBytes_ = null;
870
871         public Blob() {
872         }
873
874         public Blob(Object JavaDoc primaryKey, Serializable JavaDoc info)
875             throws IOException JavaDoc {
876             if( primaryKey != null ) {
877                 primaryKeyBytes_ = EJBUtils.serializeObject(primaryKey);
878             }
879             if( info != null ) {
880                 infoBytes_ = EJBUtils.serializeObject(info);
881             }
882         }
883         
884         public Object JavaDoc getTimedObjectPrimaryKey(ClassLoader JavaDoc cl)
885             throws Exception JavaDoc {
886             Object JavaDoc pKey = null;
887             if( primaryKeyBytes_ != null) {
888                 pKey = EJBUtils.deserializeObject(primaryKeyBytes_, cl);
889                 if( logger.isLoggable(Level.FINER) ) {
890                     logger.log(Level.FINER, "Deserialized blob : " + pKey);
891                 }
892             }
893             return pKey;
894         }
895
896         public Serializable JavaDoc getInfo(ClassLoader JavaDoc cl) throws Exception JavaDoc {
897             Serializable JavaDoc info = null;
898             if( infoBytes_ != null) {
899                 info = (Serializable JavaDoc)EJBUtils.deserializeObject(infoBytes_, cl);
900                 if( logger.isLoggable(Level.FINER) ) {
901                     logger.log(Level.FINER, "Deserialized blob : " + info);
902                 }
903             }
904             return info;
905         }
906     }
907
908     private static class TimerSynch implements Synchronization JavaDoc {
909
910         private TimerPrimaryKey timerId_;
911         private int state_;
912         private Date JavaDoc timeout_;
913         private BaseContainer container_;
914         
915         public TimerSynch(TimerPrimaryKey timerId, int state, Date JavaDoc timeout,
916                           BaseContainer container) {
917             timerId_ = timerId;
918             state_ = state;
919             timeout_ = timeout;
920             container_ = container;
921         }
922
923         public void afterCompletion(int status) {
924             EJBTimerService timerService = getEJBTimerService();
925
926             if( logger.isLoggable(Level.FINE) ) {
927                 logger.log(Level.FINE, "TimerSynch::afterCompletion. " +
928                            "timer state = " + stateToString(state_) +
929                            " , " + "timer id = " +
930                            timerId_ + " , JTA TX status = " +
931                            txStatusToString(status) + " , " +
932                            "timeout = " + timeout_);
933             }
934
935             switch(state_) {
936             case ACTIVE :
937                 if( status == Status.STATUS_COMMITTED ) {
938                     timerService.scheduleTask(timerId_, timeout_);
939                     container_.incrementCreatedTimedObject();
940                 } else {
941                     timerService.expungeTimer(timerId_);
942                 }
943                 break;
944             case CANCELLED :
945                 if( status == Status.STATUS_ROLLEDBACK ) {
946                     if( timeout_ != null ) {
947                         // Timer was cancelled while in the SCHEDULED state.
948
// Just schedule it again with the original timeout.
949
timerService.scheduleTask(timerId_, timeout_);
950                     } else {
951                         // Timer was cancelled from within its own ejbTimeout
952
// and then rolledback.
953
timerService.restoreTaskToDelivered(timerId_);
954                     }
955                 } else {
956                     timerService.expungeTimer(timerId_);
957                     container_.incrementRemovedTimedObject();
958                 }
959                 break;
960             }
961         }
962
963         public void beforeCompletion() {}
964
965     }
966
967     public static void testCreate(String JavaDoc timerId, EJBContext JavaDoc context,
968                                    String JavaDoc ownerId,
969                                   Date JavaDoc initialExpiration,
970                                    long intervalDuration,
971                                    Serializable JavaDoc info) throws CreateException JavaDoc {
972         
973         EJBTimerService ejbTimerService = getEJBTimerService();
974         TimerLocalHome timerLocalHome = ejbTimerService.getTimerBeanHome();
975
976         EjbDescriptor ejbDesc = (EjbDescriptor)
977             Switch.getSwitch().
978             getDescriptorFor(((EJBContextImpl) context).getContainer());
979         long containerId = ejbDesc.getUniqueId();
980
981         Object JavaDoc timedObjectPrimaryKey = (context instanceof EntityContext JavaDoc) ?
982                 ((EntityContext JavaDoc)context).getPrimaryKey() : null;
983
984         timerLocalHome.create(timerId, containerId, ownerId,
985                                      timedObjectPrimaryKey, initialExpiration,
986                                      intervalDuration, info);
987         return;
988     }
989
990     public static void testMigrate(String JavaDoc fromOwnerId) {
991
992         EJBTimerService ejbTimerService = getEJBTimerService();
993         ejbTimerService.migrateTimers(fromOwnerId);
994
995     }
996
997     private BaseContainer getContainer(long containerId) {
998         ContainerFactory cf = Switch.getSwitch().getContainerFactory();
999         return (BaseContainer) cf.getContainer(containerId);
1000    }
1001
1002}
1003
Popular Tags