FileDocCategorySizeDatePackage
CometContext.javaAPI DocGlassfish v2 API25149Tue Jul 17 11:41:06 BST 2007com.sun.enterprise.web.connector.grizzly.comet

CometContext

public class CometContext extends Object
The main object used by CometHandler. The CometContext is always available for CometHandler and can be used to notify other CometHandler. Attributes can be added/removed the same way HttpServletSession is doing. It is not recommended to use attributes if this CometContext is not shared amongs multiple context path (uses HttpServletSession instead).
author
Jeanfrancois Arcand

Fields Summary
protected static final String
INVALID_COMET_HANDLER
Generic error message
private static final Logger
logger
Main logger
private ConcurrentHashMap
attributes
Attributes placeholder.
private String
contextPath
The context path associated with this instance.
protected boolean
cancelled
Is the CometContext instance been cancelled.
private ConcurrentHashMap
handlers
The list of registered CometHandler
private ConcurrentLinkedQueue
asyncTasks
The list of registered AsyncProcessorTask. This object are mainly keeping the state of the Comet request.
private CometSelector
cometSelector
The CometSelector used to register SelectionKey for upcoming bytes.
protected int
continuationType
The CometContext continuationType. See CometEngine
private long
expirationDelay
The default delay expiration before a CometContext's CometHandler are interrupted.
private boolean
blockingNotification
true if the caller of CometContext.notify should block when notifying other CometHandler.
private NotificationHandler
notificationHandler
The default NotificationHandler.
Constructors Summary
public CometContext(String contextPath, int continuationType)
Create a new instance

param
contextPath the context path
param
type when the Comet processing will happen (see CometEngine).

 
    
    // ---------------------------------------------------------------------- //
    
    
                             
         
        this.contextPath = contextPath;
        this.continuationType = continuationType;
        attributes = new ConcurrentHashMap();
        handlers = new ConcurrentHashMap<CometHandler,SelectionKey>();
        asyncTasks = new ConcurrentLinkedQueue<AsyncProcessorTask>();          
    
Methods Summary
protected voidaddAsyncProcessorTask(com.sun.enterprise.web.connector.grizzly.async.AsyncProcessorTask asyncTask)
Add a AsyncProcessorTask.

param
asyncTask the AsyncProcessorTask

        asyncTasks.add(asyncTask);
    
public voidaddAttribute(java.lang.Object key, java.lang.Object value)
Add an attibute.

param
key the key
param
value the value

        attributes.put(key,value);
    
public intaddCometHandler(CometHandler handler, boolean completeExecution)
Add a CometHandler. Client of this method might make sure the CometHandler is removed when the CometHandler.onInterrupt is invoked.

param
handler a new CometHandler
param
completeExecution Add the Comethandler but don't block waiting for event.

        Long threadId = Thread.currentThread().getId();
        SelectionKey key = CometEngine.getEngine().
                activateContinuation(threadId, this,completeExecution);

        if (key == null){
            throw new 
               IllegalStateException("Grizzly Comet hasn't been registered");
        }
        
        if (handler == null){
            throw new 
               IllegalStateException(INVALID_COMET_HANDLER);
        }

        if (!completeExecution){
            handlers.putIfAbsent(handler,key);
        } else {
            handlers.putIfAbsent(handler,new SelectionKey() {
                public void cancel() {
                }
                public SelectableChannel channel() {
                    throw new IllegalStateException();
                }
                public int interestOps() {
                    throw new IllegalStateException();
                }
                public SelectionKey interestOps(int ops) {
                    throw new IllegalStateException();
                }
                public boolean isValid() {
                    return true;
                }
                public int readyOps() {
                    throw new IllegalStateException();
                }
                public Selector selector() {
                    throw new IllegalStateException();
                }
            });
        }
        return handler.hashCode();
    
public intaddCometHandler(CometHandler handler)
Add a CometHandler. Client on this method might make sure the CometHandler is removed when the CometHandler.onInterrupt is invoked.

param
handler a new CometHandler

        return addCometHandler(handler,false);
    
private voidcloseConnection(CometEvent event, java.nio.channels.SelectionKey key)
Advise CometHandler the connection will be closed.

    
        Iterator<CometHandler> iterator = handlers.keySet().iterator();
        CometHandler handler;
        while(iterator.hasNext()){         
            handler = iterator.next();
            if ( handlers.get(handler).equals(key) ){
                try{
                    handler.onInterrupt(event);
                    iterator.remove();
                } catch (IOException ex){
                    logger.log(Level.WARNING,"Exception: ",ex);
                }
                break;
            }
        }        
    
protected java.util.concurrent.ConcurrentLinkedQueuegetAsyncProcessorTask()
Return the list of AsyncProcessorTask

return
ConcurrentLinkedQueue the list of AsyncProcessorTask

        return asyncTasks;
    
public java.lang.ObjectgetAttribute(java.lang.Object key)
Retrive an attribute.

param
key the key
return
Object the value.

        return attributes.get(key);
    
public CometHandlergetCometHandler(int hashCode)
Retrive a CometHandler using its hashKey;

        Iterator<CometHandler> iterator = handlers.keySet().iterator();
        CometHandler cometHandler = null;
        while (iterator.hasNext()){
            cometHandler = iterator.next();
            if ( cometHandler.hashCode() == hashCode ){
               return cometHandler;
            }
        }
        return null;
    
protected CometHandlergetCometHandler(java.nio.channels.SelectionKey key)
Retrive a CometHandler using its SelectionKey. The SelectionKey is not exposed to the Comet API, hence this method must be protected.

        Iterator<CometHandler> iterator = handlers.keySet().iterator();
        CometHandler cometHandler = null;
        while (iterator.hasNext()){
            cometHandler = iterator.next();
            if (handlers.get(cometHandler) == key){
               return cometHandler;
            }
        }
        return null;        
    
protected CometSelectorgetCometSelector()
Get the CometSelector associated with this instance.

return
CometSelector the CometSelector associated with this instance.

        return cometSelector;
    
public java.lang.StringgetContextPath()
Get the context path associated with this instance.

return
contextPath the context path associated with this instance

        return contextPath;
    
public longgetExpirationDelay()
Return the long delay before a request is resumed.

return
long the long delay before a request is resumed.

        return expirationDelay;
    
public NotificationHandlergetNotificationHandler()

        return notificationHandler;
    
protected voidinitialize(java.nio.channels.SelectionKey key)
Initialize the newly added CometHandler.

param
attachment An object shared amongst CometHandler.
param
type The type of notification.
param
key The SelectionKey representing the CometHandler.

        CometEvent event = new CometEvent<E>();
        event.setType(event.INITIALIZE);
        event.setCometContext(this);
        
        Iterator<CometHandler> iterator = handlers.keySet().iterator();
        CometHandler cometHandler = null;
        while(iterator.hasNext()){
            cometHandler = iterator.next();
            if(handlers.get(cometHandler).equals(key)){
                cometHandler.onInitialize(event);
                break;
            }
        }
    
protected voidinterrupt(java.nio.channels.SelectionKey key)
Invoke CometHandler.onTerminate

        CometEvent event = new CometEvent<E>();
        event.setType(CometEvent.INTERRUPT);
        event.attach(null);
        event.setCometContext(this);
        
        closeConnection(event,key);
    
public booleanisActive(CometHandler cometHandler)
Return true if this CometHandler is still active, e.g. there is still a continuation associated with it.

        if (cometHandler == null){
            throw new IllegalStateException(INVALID_COMET_HANDLER);
        }
        return (handlers.get(cometHandler) != null);
    
public booleanisBlockingNotification()
Return true if the invoker of notify() should block when notifying Comet Handlers.

        return blockingNotification;
    
protected booleanisCancelled()
Is this instance beeing cancelled by the CometSelector

return
boolean cancelled or not.

        return cancelled;
    
protected voidnotify(CometEvent event, int eventType, java.nio.channels.SelectionKey key)
Notify all CometHandler. The attachment can be null. The type will determine which code>CometHandler method will be invoked: CometEvent.INTERRUPT -> CometHandler.onInterrupt CometEvent.NOTIFY -> CometHandler.onEvent CometEvent.INITIALIZE -> CometHandler.onInitialize CometEvent.TERMINATE -> CometHandler.onTerminate CometEvent.READ -> CometHandler.onEvent CometEvent.WRITE -> CometHandler.onEvent

param
attachment An object shared amongst CometHandler.
param
type The type of notification.
param
key The SelectionKey associated with the CometHandler.

        CometHandler cometHandler = getCometHandler(key);
        if (cometHandler == null){
            throw new IllegalStateException(INVALID_COMET_HANDLER);
        }
        event.setCometContext(CometContext.this);  
        cometHandler.onEvent(event);
    
public voidnotify(E attachment)
Notify all CometHandler. The attachment can be null. All CometHandler.onEvent() will be invoked.

param
attachment An object shared amongst CometHandler.

        CometEvent event = new CometEvent<E>();
        event.setType(CometEvent.NOTIFY);
        event.attach(attachment);
        event.setCometContext(CometContext.this);
        Iterator<CometHandler> iterator = handlers.keySet().iterator();
        notificationHandler.setBlockingNotification(blockingNotification);
        notificationHandler.notify(event,iterator);
        registerKeys();           
    
public voidnotify(E attachment, int eventType, int cometHandlerID)
Notify a single CometHandler. The attachment can be null. The type will determine which code>CometHandler method will be invoked: CometEvent.INTERRUPT -> CometHandler.onInterrupt CometEvent.NOTIFY -> CometHandler.onEvent CometEvent.INITIALIZE -> CometHandler.onInitialize CometEvent.TERMINATE -> CometHandler.onTerminate CometEvent.READ -> CometHandler.onEvent

param
attachment An object shared amongst CometHandler.
param
type The type of notification.
param
cometHandlerID Notify a single CometHandler.

   
        CometHandler cometHandler = getCometHandler(cometHandlerID);
  
        if (cometHandler == null){
            throw new IllegalStateException(INVALID_COMET_HANDLER);
        }
        CometEvent event = new CometEvent<E>();
        event.setType(eventType);
        event.attach(attachment);
        event.setCometContext(CometContext.this);
        
        notificationHandler.setBlockingNotification(blockingNotification);        
        notificationHandler.notify(event,cometHandler);
        if (event.getType() == CometEvent.TERMINATE 
            || event.getType() == CometEvent.INTERRUPT) {
            resumeCometHandler(cometHandler);
        } else {
            registerKeys(); 
        }
    
public voidnotify(E attachment, int eventType)
Notify all CometHandler. The attachment can be null. The type will determine which code>CometHandler method will be invoked: CometEvent.INTERRUPT -> CometHandler.onInterrupt CometEvent.NOTIFY -> CometHandler.onEvent CometEvent.INITIALIZE -> CometHandler.onInitialize CometEvent.TERMINATE -> CometHandler.onTerminate CometEvent.READ -> CometHandler.onEvent

param
attachment An object shared amongst CometHandler.
param
type The type of notification.

        // XXX Use a pool of CometEvent instance.
        CometEvent event = new CometEvent<E>();
        event.setType(eventType);
        event.attach(attachment);
        event.setCometContext(CometContext.this);

        Iterator<CometHandler> iterator = handlers.keySet().iterator();
        notificationHandler.setBlockingNotification(blockingNotification);
        notificationHandler.notify(event,iterator);
        if (event.getType() == CometEvent.TERMINATE 
            || event.getType() == CometEvent.INTERRUPT) {
            while(iterator.hasNext()){
                resumeCometHandler(iterator.next());
            }
        } else {
            registerKeys();
        } 
    
protected voidrecycle()
Recycle this object.

        handlers.clear();
        attributes.clear();
        cancelled = false;
        asyncTasks.clear();
    
public booleanregisterAsyncRead(CometHandler handler)
Register for asynchronous read. If your client supports http pipelining, invoking this method might result in a state where your CometHandler is invoked with a CometRead that will read the next http request. In that case, it is strongly recommended to not use that method unless your CometHandler can handle the http request.

oaram
handler The CometHandler that will be invoked.

        SelectionKey key = handlers.get(handler);
        if (handler == null){
            throw new 
               IllegalStateException(INVALID_COMET_HANDLER);            
        }
        // Retrieve the CometSelector key.
        SelectionKey cometKey = cometSelector.cometKeyFor(key.channel());
        if (cometKey != null){
            cometKey.interestOps(cometKey.interestOps() | SelectionKey.OP_READ); 
            if (cometKey.attachment() != null){
                ((CometTask)cometKey.attachment()).setAsyncReadSupported(true);
            }
            return true;
        } else {
            return false;
        }  
    
public booleanregisterAsyncWrite(CometHandler handler)
Register for asynchronous write.

        SelectionKey key = handlers.get(handler);
        if (handler == null || key == null){
            throw new 
               IllegalStateException(INVALID_COMET_HANDLER);            
        }
        // Retrieve the CometSelector key.
        SelectionKey cometKey = cometSelector.cometKeyFor(key.channel());
        if (cometKey != null){
            cometKey.interestOps(cometKey.interestOps() | SelectionKey.OP_WRITE); 
            return true;
        } else {
            return false;
        }           
    
private synchronized voidregisterKeys()
Register the current AsyncProcessorTask keys to the CometSelector so new bytes can be processed.

        CometTask cometTask;       
        for (AsyncProcessorTask asyncTask: asyncTasks){
            SelectionKey key = asyncTask.getSelectionKey();
            
            if (key == null) continue;
            
            cometTask = (CometTask)key.attachment();            
            // Will hapens when a single CometHandler is invoked.
            if (cometTask == null){
                cometTask = CometEngine.getEngine().getCometTask(this,key);
                key.attach(cometTask);
            }
            cometTask.setExpirationDelay(expirationDelay);
            cometTask.setExpireTime(System.currentTimeMillis());
        }  
    
public java.lang.ObjectremoveAttribute(java.lang.Object key)
Remove an attribute.

param
key the key
return
Object the value

        return attributes.remove(key);
    
public voidremoveCometHandler(CometHandler handler)
Remove a CometHandler. If the continuation (connection) associated with this CometHandler no longer have CometHandler associated to it, it will be resumed.

        removeCometHandler(handler,true);
    
private voidremoveCometHandler(CometHandler handler, boolean resume)
Remove a CometHandler. If the continuation (connection) associated with this CometHandler no longer have CometHandler associated to it, it will be resumed.

param
handler The CometHandler to remove.
param
resume True is the connection can be resumed if no CometHandler are associated with the underlying SelectionKey.

        
        SelectionKey key = handlers.remove(handler);
        if (resume && !handlers.containsValue(key)){
            CometEngine.getEngine().resume(key,this);
        }
    
public voidremoveCometHandler(int hashCode)
Remove a CometHandler based on its hashcode.

        Iterator<CometHandler> iterator = handlers.keySet().iterator();
        CometHandler cometHandler = null;
        while (iterator.hasNext()){
            cometHandler = iterator.next();
            if ( cometHandler.hashCode() == hashCode ){
                iterator.remove();
                return;
            }
        }
    
public voidresumeCometHandler(CometHandler handler)
Resume the Comet request and remove it from the active CometHandler list.

        resumeCometHandler(handler,true);
    
protected voidresumeCometHandler(CometHandler handler, boolean remove)
Resume the Comet request.

param
handler The CometHandler associated with the current continuation.
param
remove true if the CometHandler needs to be removed.

        SelectionKey key = handlers.get(handler);
        if (key == null){
            throw new 
               IllegalStateException("Invalid CometHandler");
        }        
        CometEngine.getEngine().resume(key,this); 
        if (remove){
            removeCometHandler(handler,false);
        }
    
public voidsetBlockingNotification(boolean blockingNotification)
Set to true if the invoker of notify() should block when notifying Comet Handlers.

        this.blockingNotification = blockingNotification;
    
protected voidsetCancelled(boolean cancelled)
Cancel this object or "uncancel".

param
cancelled true or false.

        this.cancelled = cancelled;
    
protected voidsetCometSelector(CometSelector cometSelector)
Set the CometSelector associated with this instance.

param
CometSelector the CometSelector associated with this instance.

        this.cometSelector = cometSelector;
    
public voidsetExpirationDelay(long expirationDelay)
Set the long delay before a request is resumed.

param
long the long delay before a request is resumed.

        this.expirationDelay = expirationDelay;
    
public voidsetNotificationHandler(NotificationHandler notificationHandler)

        this.notificationHandler = notificationHandler;
    
public java.lang.StringtoString()
Helper.

        return contextPath;