FileDocCategorySizeDatePackage
TimerBean.javaAPI DocGlassfish v2 API36063Fri May 04 22:32:58 BST 2007com.sun.ejb.containers

TimerBean

public abstract class TimerBean extends Object implements javax.ejb.EntityBean
TimerBean is a coarse-grained persistent representation of an EJB Timer. It is part of the EJB container but implemented as a CMP 2.1 Entity bean. The standard CMP behavior is useful in implementing the transactional properties of EJB timers. When an EJB timer is created by an application, it is not eligible for expiration until the transaction commits. Likewise, if a timer is cancelled and the transaction rolls back, the timer must be reactivated. To accomplish this, TimerBean registers callbacks with the transaction manager and interacts with the EJBTimerService accordingly.
author
Kenneth Saks

Fields Summary
private static final Logger
logger
private static final int
ACTIVE
private static final int
CANCELLED
private EJBContextImpl
context_
private boolean
blobLoaded_
private Object
timedObjectPrimaryKey_
private transient Serializable
info_
private transient Date
creationTime_
private transient Date
initialExpiration_
private transient Date
lastExpiration_
Constructors Summary
Methods Summary
public voidcancel()


        // First set the timer to the cancelled state.  This step is
        // performed whether or not the current server instance owns
        // the timer.

        if( getState() == CANCELLED ) {
            // already cancelled
            return;
        }

        setState(CANCELLED);

        // Only proceed with JDK timer task cancellation if this timer
        // is owned by the current server instance.
        if( timerOwnedByThisServer() ) {
                    
            TimerPrimaryKey timerId = new TimerPrimaryKey(getTimerId());
            
            // Cancel existing timer task.  Save time at which task would
            // have executed in case cancellation is rolled back.  The 
            // nextTimeout can be null if the timer is currently being 
            // delivered.
            Date nextTimeout = getEJBTimerService().cancelTask(timerId);
            
            ContainerSynchronization containerSynch = getContainerSynch();
            Synchronization timerSynch = 
                containerSynch.getTimerSynchronization(timerId);
            
            if( timerSynch != null ) {
                // This timer was created and cancelled within the
                // same transaction.  No tx synchronization actions
                // are needed, since whether tx commits or rolls back,
                // timer will not exist.
                containerSynch.removeTimerSynchronization(timerId);
                getEJBTimerService().expungeTimer(timerId);
            } else {
                // Set tx synchronization action to handle timer cancellation.
                timerSynch = new TimerSynch(timerId, CANCELLED, nextTimeout,
                                        getContainer(getContainerId()));
                containerSynch.addTimerSynchronization(timerId, timerSynch);
            }

        }

        // NOTE that it's the caller's responsibility to call remove().
        return;
    
public voidejbActivate()

public TimerPrimaryKeyejbCreate(java.lang.String timerId, long containerId, java.lang.String ownerId, java.lang.Object timedObjectPrimaryKey, java.util.Date initialExpiration, long intervalDuration, java.io.Serializable info)

    
      
             
           
              
          

        setTimerId(timerId);
        
        setOwnerId(ownerId);

        return null;
    
public booleanejbHomeCheckStatus(java.lang.String resourceJndiName, boolean checkDatabase)


        boolean success = false;

        Connection connection = null;

        try {

            InitialContext ic = new InitialContext();
            
            DataSource dataSource = (DataSource) ic.lookup(resourceJndiName);

            if( checkDatabase ) {
                connection = dataSource.getConnection();
                
                connection.close();
                
                connection = null;
                
                // Now try to a query that will access the timer table itself.
                // Use a query that won't return a lot of data(even if the
                // table is large) to reduce the overhead of this check.
                ejbSelectCountTimersByContainer(0);
            }

            success = true;           
                        
        } catch(Exception e) {

            logger.log(Level.WARNING, "ejb.timer_service_init_error", 
                       "");
            // Log exception itself at FINE level.  The most likely cause
            // is a connection error when the database is not started.  This
            // is already logged twice by the jdbc layer.
            logger.log(Level.FINE, "ejb.timer_service_init_error", e);

        } finally {
            if( connection != null ) {
                try {
                    connection.close();
                } catch(Exception e) {
                    logger.log(Level.FINE, "timer connection close exception",
                               e);
                }
            }
        }

        return success;
    
public java.util.SetejbHomeSelectActiveTimerIdsByContainer(long containerId)

        return toPKeys(ejbSelectTimerIdsByContainerAndState(containerId, 
                                                            ACTIVE));
    
public java.util.SetejbHomeSelectActiveTimerIdsOwnedByThisServerByContainer(long containerId)

        return toPKeys(ejbSelectTimerIdsByContainerAndOwnerAndState
                       (containerId, getOwnerIdOfThisServer(), ACTIVE));
    
public java.util.SetejbHomeSelectActiveTimersByContainer(long containerId)

        return ejbSelectTimersByContainerAndState(containerId, 
                                                  ACTIVE);
    
public java.util.SetejbHomeSelectActiveTimersOwnedByThisServerByContainer(long containerId)

        return ejbSelectTimersByContainerAndOwnerAndState
                       (containerId, getOwnerIdOfThisServer(), ACTIVE);
    
public java.util.SetejbHomeSelectAllActiveTimerIdsOwnedBy(java.lang.String ownerId)

        return toPKeys(ejbSelectAllTimerIdsByOwnerAndState
                       (ownerId, ACTIVE));
    
public java.util.SetejbHomeSelectAllActiveTimerIdsOwnedByThisServer()

        return toPKeys(ejbSelectAllTimerIdsByOwnerAndState
                       (getOwnerIdOfThisServer(), ACTIVE));
    
public java.util.SetejbHomeSelectAllActiveTimersOwnedBy(java.lang.String ownerId)

        return ejbSelectAllTimersByOwnerAndState
                       (ownerId, ACTIVE);
    
public java.util.SetejbHomeSelectAllActiveTimersOwnedByThisServer()

        return ejbSelectAllTimersByOwnerAndState
                       (getOwnerIdOfThisServer(), ACTIVE);
    
public java.util.SetejbHomeSelectAllCancelledTimerIdsOwnedBy(java.lang.String ownerId)

        return toPKeys(ejbSelectAllTimerIdsByOwnerAndState
                       (ownerId, CANCELLED));
    
public java.util.SetejbHomeSelectAllCancelledTimerIdsOwnedByThisServer()

        return toPKeys(ejbSelectAllTimerIdsByOwnerAndState
                       (getOwnerIdOfThisServer(), CANCELLED));
    
public java.util.SetejbHomeSelectAllCancelledTimersOwnedBy(java.lang.String ownerId)

        return ejbSelectAllTimersByOwnerAndState
                       (ownerId, CANCELLED);
    
public java.util.SetejbHomeSelectAllCancelledTimersOwnedByThisServer()

        return ejbSelectAllTimersByOwnerAndState
                       (getOwnerIdOfThisServer(), CANCELLED);
    
public java.util.SetejbHomeSelectAllTimerIdsOwnedBy(java.lang.String ownerId)

        return toPKeys(ejbSelectAllTimerIdsByOwner(ownerId));
    
public java.util.SetejbHomeSelectAllTimerIdsOwnedByThisServer()

        return toPKeys(ejbSelectAllTimerIdsByOwner(getOwnerIdOfThisServer()));
    
public java.util.SetejbHomeSelectAllTimersOwnedBy(java.lang.String ownerId)

        return ejbSelectAllTimersByOwner(ownerId);
    
public java.util.SetejbHomeSelectAllTimersOwnedByThisServer()

        return ejbSelectAllTimersByOwner(getOwnerIdOfThisServer());
    
public java.util.SetejbHomeSelectCancelledTimerIdsByContainer(long containerId)

        return toPKeys(ejbSelectTimerIdsByContainerAndState
                       (containerId, CANCELLED));
    
public java.util.SetejbHomeSelectCancelledTimerIdsOwnedByThisServerByContainer(long containerId)

        return toPKeys(ejbSelectTimerIdsByContainerAndOwnerAndState
                       (containerId, getOwnerIdOfThisServer(), CANCELLED));
    
public java.util.SetejbHomeSelectCancelledTimersByContainer(long containerId)

        return ejbSelectTimersByContainerAndState
                       (containerId, CANCELLED);
    
public java.util.SetejbHomeSelectCancelledTimersOwnedByThisServerByContainer(long containerId)

        return ejbSelectTimersByContainerAndOwnerAndState
                       (containerId, getOwnerIdOfThisServer(), CANCELLED);
    
public intejbHomeSelectCountActiveTimersByContainer(long containerId)

        return ejbSelectCountTimersByContainerAndState(containerId, 
                                                       ACTIVE);
    
public intejbHomeSelectCountActiveTimersOwnedByThisServerByContainer(long containerId)

        return ejbSelectCountTimersByContainerAndOwnerAndState
                       (containerId, getOwnerIdOfThisServer(), ACTIVE);
    
public intejbHomeSelectCountAllActiveTimersOwnedBy(java.lang.String ownerId)

        return ejbSelectCountAllTimersByOwnerAndState
                       (ownerId, ACTIVE);
    
public intejbHomeSelectCountAllActiveTimersOwnedByThisServer()

        return ejbSelectCountAllTimersByOwnerAndState
                       (getOwnerIdOfThisServer(), ACTIVE);
    
public intejbHomeSelectCountAllCancelledTimersOwnedBy(java.lang.String ownerId)

        return ejbSelectCountAllTimersByOwnerAndState
                       (ownerId, CANCELLED);
    
public intejbHomeSelectCountAllCancelledTimersOwnedByThisServer()

        return ejbSelectCountAllTimersByOwnerAndState
                       (getOwnerIdOfThisServer(), CANCELLED);
    
public intejbHomeSelectCountAllTimersOwnedBy(java.lang.String ownerId)

        return ejbSelectCountAllTimersByOwner(ownerId);
    
public intejbHomeSelectCountAllTimersOwnedByThisServer()

        return ejbSelectCountAllTimersByOwner(getOwnerIdOfThisServer());
    
public intejbHomeSelectCountCancelledTimersByContainer(long containerId)

        return ejbSelectCountTimersByContainerAndState
                       (containerId, CANCELLED);
    
public intejbHomeSelectCountCancelledTimersOwnedByThisServerByContainer(long containerId)

        return ejbSelectCountTimersByContainerAndOwnerAndState
                       (containerId, getOwnerIdOfThisServer(), CANCELLED);
    
public intejbHomeSelectCountTimersByContainer(long containerId)

        return ejbSelectCountTimersByContainer(containerId);
    
public intejbHomeSelectCountTimersOwnedByThisServerByContainer(long containerId)

        return ejbSelectCountTimersByContainerAndOwner
                         (containerId, getOwnerIdOfThisServer());
    
public java.util.SetejbHomeSelectTimerIdsByContainer(long containerId)

        return toPKeys(ejbSelectTimerIdsByContainer(containerId));
    
public java.util.SetejbHomeSelectTimerIdsOwnedByThisServerByContainer(long containerId)

        return toPKeys(ejbSelectTimerIdsByContainerAndOwner
                         (containerId, getOwnerIdOfThisServer()));
    
public java.util.SetejbHomeSelectTimersByContainer(long containerId)

        return ejbSelectTimersByContainer(containerId);
    
public java.util.SetejbHomeSelectTimersOwnedByThisServerByContainer(long containerId)

        return ejbSelectTimersByContainerAndOwner
                         (containerId, getOwnerIdOfThisServer());
    
public voidejbLoad()


        long lastExpirationRaw = getLastExpirationRaw();
        lastExpiration_ = (lastExpirationRaw > 0) ? 
            new Date(lastExpirationRaw) : null;
        
        // Populate derived state of immutable cmp fields.
        creationTime_ = new Date(getCreationTimeRaw());
        initialExpiration_ = new Date(getInitialExpirationRaw());

        // Lazily deserialize Blob state.  This makes the
        // Timer bootstrapping code easier, since some of the Timer
        // state must be loaded from the database before the 
        // container and application classloader are known.
        timedObjectPrimaryKey_ = null;
        info_       = null;
        blobLoaded_ = false;
    
public voidejbPassivate()

public voidejbPostCreate(java.lang.String timerId, long containerId, java.lang.String ownerId, java.lang.Object timedObjectPrimaryKey, java.util.Date initialExpiration, long intervalDuration, java.io.Serializable info)


        Date creationTime = new Date();
		setCreationTimeRaw(creationTime.getTime());
        creationTime_ = creationTime;

        setInitialExpirationRaw(initialExpiration.getTime());
        initialExpiration_ = initialExpiration;

        setLastExpirationRaw(0);
        lastExpiration_ = null;

        setIntervalDuration(intervalDuration);

        setContainerId(containerId);

        timedObjectPrimaryKey_  = timedObjectPrimaryKey;
        info_ = info;
        blobLoaded_ = true;

        Blob blob = null;
        try {
            blob = new Blob(timedObjectPrimaryKey, info);
        } catch(IOException ioe) {
            CreateException ce = new CreateException();
            ce.initCause(ioe);
            throw ce;
        }

        setBlob(blob);
        setState(ACTIVE);

        if( logger.isLoggable(Level.FINE) ) {
            logger.log(Level.FINE, "TimerBean.postCreate() ::timerId=" +
                       getTimerId() + " ::containerId=" + getContainerId() + 
                       " ::timedObjectPK=" + timedObjectPrimaryKey +
                       " ::info=" + info +
                       " ::initialExpiration=" + initialExpiration +
                       " ::intervalDuration=" + intervalDuration +
                       " :::state=" + stateToString(getState()) + 
                       " :::creationTime="  + creationTime +
                       " :::ownerId=" + getOwnerId()); 
        }

        //
        // Only proceed with transactional semantics if this timer
        // is owned by the current server instance.  NOTE that this
        // will *ALWAYS* be the case for timers created from EJB
        // applications via the javax.ejb.EJBTimerService.create methods.  
        //
        // For testing purposes, ejbCreate takes an ownerId parameter, 
        // which allows us to easily simulate other server instances 
        // by creating timers for them.  In those cases, we don't need
        // the timer transaction semantics and ejbTimeout logic.  Simulating
        // the creation of timers for the same application and different
        // server instances from a script is difficult since the
        // containerId is not generated until after deployment.  
        //
        if( timerOwnedByThisServer() ) {

            // Register a synchronization object to handle the commit/rollback
            // semantics and ejbTimeout notifications.
            Synchronization timerSynch = 
                new TimerSynch(new TimerPrimaryKey(getTimerId()), ACTIVE, 
                               getInitialExpiration(), 
                               getContainer(containerId));
            
            try {
                ContainerSynchronization containerSynch = getContainerSynch();
                containerSynch.addTimerSynchronization
                    (new TimerPrimaryKey(getTimerId()), timerSynch);
            } catch(Exception e) {
                CreateException ce = new CreateException();
                ce.initCause(e);
                throw ce;
            }
        }
    
public voidejbRemove()

public abstract java.util.SetejbSelectAllTimerIdsByOwner(java.lang.String ownerId)

public abstract java.util.SetejbSelectAllTimerIdsByOwnerAndState(java.lang.String ownerId, int state)

public abstract java.util.SetejbSelectAllTimersByOwner(java.lang.String ownerId)

public abstract java.util.SetejbSelectAllTimersByOwnerAndState(java.lang.String ownerId, int state)

public abstract intejbSelectCountAllTimersByOwner(java.lang.String ownerId)

public abstract intejbSelectCountAllTimersByOwnerAndState(java.lang.String ownerId, int state)

public abstract intejbSelectCountTimersByContainer(long containerId)

public abstract intejbSelectCountTimersByContainerAndOwner(long containerId, java.lang.String ownerId)

public abstract intejbSelectCountTimersByContainerAndOwnerAndState(long containerId, java.lang.String ownerId, int state)

public abstract intejbSelectCountTimersByContainerAndState(long containerId, int state)

public abstract java.util.SetejbSelectTimerIdsByContainer(long containerId)

public abstract java.util.SetejbSelectTimerIdsByContainerAndOwner(long containerId, java.lang.String ownerId)

public abstract java.util.SetejbSelectTimerIdsByContainerAndOwnerAndState(long containerId, java.lang.String ownerId, int state)

public abstract java.util.SetejbSelectTimerIdsByContainerAndState(long containerId, int state)

public abstract java.util.SetejbSelectTimersByContainer(long containerId)

public abstract java.util.SetejbSelectTimersByContainerAndOwner(long containerId, java.lang.String ownerId)

public abstract java.util.SetejbSelectTimersByContainerAndOwnerAndState(long containerId, java.lang.String ownerId, int state)

public abstract java.util.SetejbSelectTimersByContainerAndState(long containerId, int state)

public voidejbStore()

public abstract com.sun.ejb.containers.TimerBean$BlobgetBlob()

private BaseContainergetContainer(long containerId)

        ContainerFactory cf = Switch.getSwitch().getContainerFactory();
        return (BaseContainer) cf.getContainer(containerId);
    
public abstract longgetContainerId()

private ContainerSynchronizationgetContainerSynch()


        EntityContainer container = (EntityContainer) context_.getContainer();
        ContainerFactoryImpl containerFactory = (ContainerFactoryImpl)
            Switch.getSwitch().getContainerFactory();
        Transaction transaction = context_.getTransaction();

        if( transaction == null ) {
            logger.log(Level.FINE, "Context transaction = null. Using " +
                       "invocation instead.");
            InvocationManager iMgr = Switch.getSwitch().getInvocationManager();
            ComponentInvocation i = iMgr.getCurrentInvocation();
            transaction = i.transaction;
        }
        if( transaction == null ) {
            throw new Exception("transaction = null in getContainerSynch " +
                                "for timerId = " + getTimerId());
        }

        ContainerSynchronization containerSync = 
            containerFactory.getContainerSync(transaction);
        return containerSync;
    
public java.util.DategetCreationTime()

        return creationTime_;
    
public abstract longgetCreationTimeRaw()

private static EJBTimerServicegetEJBTimerService()

        ContainerFactoryImpl containerFactory = (ContainerFactoryImpl)
            Switch.getSwitch().getContainerFactory();
        return containerFactory.getEJBTimerService();
    
public java.io.SerializablegetInfo()

        if( !blobLoaded_ ) {
            loadBlob();
        }
        return info_;
    
public java.util.DategetInitialExpiration()

        return initialExpiration_;
    
public abstract longgetInitialExpirationRaw()

public abstract longgetIntervalDuration()

public java.util.DategetLastExpiration()

        return lastExpiration_;
    
public abstract longgetLastExpirationRaw()

public abstract java.lang.StringgetOwnerId()

private java.lang.StringgetOwnerIdOfThisServer()

        return getEJBTimerService().getOwnerIdOfThisServer();                
    
public abstract intgetPkHashCode()

public abstract intgetState()

public java.lang.ObjectgetTimedObjectPrimaryKey()

        if( !blobLoaded_ ) {
            loadBlob();
        }
        return timedObjectPrimaryKey_;
    
public abstract java.lang.StringgetTimerId()

public booleanisActive()

        return (getState() == ACTIVE);
    
public booleanisCancelled()

        return (getState() == CANCELLED);
    
private voidloadBlob()

        EJBTimerService timerService = getEJBTimerService();        
        ClassLoader cl = timerService.getTimerClassLoader(getContainerId());
        if( cl != null ) {
            loadBlob(cl);
        } else {
            throw new EJBException("No timer classloader for " + getTimerId());
        }
    
private voidloadBlob(java.lang.ClassLoader cl)

        try {
            Blob blob = getBlob();
            timedObjectPrimaryKey_  = blob.getTimedObjectPrimaryKey(cl);
            info_ = blob.getInfo(cl);
            blobLoaded_ = true;
        } catch(Exception e) {
            EJBException ejbEx = new EJBException();
            ejbEx.initCause(e);
            throw ejbEx;
        }
    
public booleanrepeats()

        return (getIntervalDuration() > 0);
    
public abstract voidsetBlob(com.sun.ejb.containers.TimerBean$Blob blob)

public abstract voidsetContainerId(long containerId)

public abstract voidsetCreationTimeRaw(long creationTime)

public voidsetEntityContext(javax.ejb.EntityContext context)

        context_ = (EJBContextImpl) context;
    
public abstract voidsetInitialExpirationRaw(long initialExpiration)

public abstract voidsetIntervalDuration(long intervalDuration)

public voidsetLastExpiration(java.util.Date lastExpiration)

        // can be null
        lastExpiration_ = lastExpiration;
        long lastExpirationRaw = (lastExpiration != null) ?
            lastExpiration.getTime() : 0;
        setLastExpirationRaw(lastExpirationRaw);
    
public abstract voidsetLastExpirationRaw(long lastExpiration)

public abstract voidsetOwnerId(java.lang.String ownerId)

public abstract voidsetPkHashCode(int pkHash)

public abstract voidsetState(int state)

public abstract voidsetTimerId(java.lang.String timerId)

private static java.lang.StringstateToString(int state)

        String stateStr = "UNKNOWN_TIMER_STATE";

        switch(state) {
            case ACTIVE : 
                stateStr = "TIMER_ACTIVE"; 
                break;
            case CANCELLED : 
                stateStr = "TIMER_CANCELLED";
                break;
            default : 
                stateStr = "UNKNOWN_TIMER_STATE";
                break;
        }

        return stateStr;
    
public static voidtestCreate(java.lang.String timerId, javax.ejb.EJBContext context, java.lang.String ownerId, java.util.Date initialExpiration, long intervalDuration, java.io.Serializable info)

        
        EJBTimerService ejbTimerService = getEJBTimerService();
        TimerLocalHome timerLocalHome = ejbTimerService.getTimerBeanHome();

        EjbDescriptor ejbDesc = (EjbDescriptor)
            Switch.getSwitch().
            getDescriptorFor(((EJBContextImpl) context).getContainer());
        long containerId = ejbDesc.getUniqueId();

        Object timedObjectPrimaryKey = (context instanceof EntityContext) ?
                ((EntityContext)context).getPrimaryKey() : null;

        timerLocalHome.create(timerId, containerId, ownerId,
                                     timedObjectPrimaryKey, initialExpiration,
                                     intervalDuration, info);
        return;
    
public static voidtestMigrate(java.lang.String fromOwnerId)


        EJBTimerService ejbTimerService = getEJBTimerService();
        ejbTimerService.migrateTimers(fromOwnerId);

    
private booleantimerOwnedByThisServer()
Checks whether this timer is owned by the server instance in which we are running.

        String ownerIdOfThisServer = getOwnerIdOfThisServer();
        return ( (ownerIdOfThisServer != null) &&
                 (ownerIdOfThisServer.equals(getOwnerId())) );
    
private java.util.SettoPKeys(java.util.Set ids)

        Set pkeys = new HashSet();
        for(Iterator iter = ids.iterator(); iter.hasNext();) {
            pkeys.add(new TimerPrimaryKey((String) iter.next()));
        }
        return pkeys;
    
private static java.lang.StringtxStatusToString(int txStatus)

        String txStatusStr = "UNMATCHED TX STATUS";

        switch(txStatus) {
            case Status.STATUS_ACTIVE :
                txStatusStr = "TX_STATUS_ACTIVE";
                break;
            case Status.STATUS_COMMITTED : 
                txStatusStr = "TX_STATUS_COMMITTED"; 
                break;
            case Status.STATUS_COMMITTING : 
                txStatusStr = "TX_STATUS_COMMITTING";
                break;
            case Status.STATUS_MARKED_ROLLBACK :
                txStatusStr = "TX_STATUS_MARKED_ROLLBACK";
                break;
            case Status.STATUS_NO_TRANSACTION :
                txStatusStr = "TX_STATUS_NO_TRANSACTION";
                break;
            case Status.STATUS_PREPARED :
                txStatusStr = "TX_STATUS_PREPARED";
                break;
            case Status.STATUS_PREPARING :
                txStatusStr = "TX_STATUS_PREPARING";
                break;
            case Status.STATUS_ROLLEDBACK : 
                txStatusStr = "TX_STATUS_ROLLEDBACK";
                break;
            case Status.STATUS_ROLLING_BACK :
                txStatusStr = "TX_STATUS_ROLLING_BACK";
                break;               
            case Status.STATUS_UNKNOWN :
                txStatusStr = "TX_STATUS_UNKNOWN";
                break;
            default : 
                txStatusStr = "UNMATCHED TX STATUS";
                break;
        }

        return txStatusStr;
    
public voidunsetEntityContext()

        context_ = null;