Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 
 package org.apache.catalina.valves;
 
 
 import static org.jboss.web.CatalinaMessages.MESSAGES;
 
 import java.util.List;
 
 

Implementation of a Valve that tracks Comet connections, and closes them when the associated session expires or the webapp is reloaded.

This Valve should be attached to a Context.

Author(s):
Remy Maucherat
Version:
$Revision: 965 $ $Date: 2009-03-19 19:30:09 +0100 (Thu, 19 Mar 2009) $
 
 
     extends ValveBase
 
 
     // ----------------------------------------------------- Instance Variables
 

    
The descriptive information related to this implementation.
 
     protected static final String info =
         "org.apache.catalina.valves.CometConnectionManagerValve/1.0";


    
The lifecycle event support for this component.
 
     protected LifecycleSupport lifecycle = new LifecycleSupport(this);


    
Has this component been started yet?
 
     protected boolean started = false;

    
    
List of current Coment connections.
 
     protected List<RequestcometRequests =
         Collections.synchronizedList(new ArrayList<Request>());
    

    
Name of session attribute used to store list of comet connections.
 
     protected String cometRequestsAttribute =
         "org.apache.tomcat.comet.connectionList";
 
 
     // ------------------------------------------------------------- Properties
 
     
    // ------------------------------------------------------ Lifecycle Methods


    
Add a lifecycle event listener to this component.

Parameters:
listener The listener to add
    public void addLifecycleListener(LifecycleListener listener) {
        .addLifecycleListener(listener);
    }


    
Get the lifecycle listeners associated with this lifecycle. If this Lifecycle has no listeners registered, a zero-length array is returned.
        return .findLifecycleListeners();
    }


    
Remove a lifecycle event listener from this component.

Parameters:
listener The listener to add
    public void removeLifecycleListener(LifecycleListener listener) {
        .removeLifecycleListener(listener);
    }


    
Prepare for the beginning of active use of the public methods of this component. This method should be called after configure(), and before any of the public methods of the component are utilized.

Throws:
org.apache.catalina.LifecycleException if this component detects a fatal error that prevents this component from being used
    public void start() throws LifecycleException {
        // Validate and update our current component state
        if ()
            throw new LifecycleException
                (.valveAlreadyStarted());
         = true;
        if ( instanceof Context) {
            ((Lifecycle).addLifecycleListener(this);
        }
        
    }


    
Gracefully terminate the active use of the public methods of this component. This method should be the last one called on a given instance of this component.

Throws:
org.apache.catalina.LifecycleException if this component detects a fatal error that needs to be reported
    public void stop() throws LifecycleException {
        // Validate and update our current component state
        if (!)
            throw new LifecycleException
                (.valveNotStarted());
        .fireLifecycleEvent(null);
         = false;
        if ( instanceof Context) {
            ((Lifecycle).removeLifecycleListener(this);
        }
    }
    
    public void lifecycleEvent(LifecycleEvent event) {
        if (event.getType() == .) {
            // FIXME: in that case, it could be useful to wait until end events are processed. Mmmm.
            // The container is getting stopped, close all current connections 
            Iterator<Requestiterator = .iterator();
            while (iterator.hasNext()) {
                Request request = iterator.next();
                // Remove the session tracking attribute as it isn't
                // serializable or required.
                HttpSession session = request.getSession(false);
                if (session != null) {
                    try {
                        session.removeAttribute();
                    } catch (IllegalStateException e) {
                        // Ignore
                    }
                }
                // Close the comet connection
                try {
                    request.getEvent().close();
                } catch (Exception e) {
                    .getLogger().warn(.eventValveExceptionDuringEvent(), e);
                }
            }
            .clear();
        }
    }
    // --------------------------------------------------------- Public Methods


    
Return descriptive information about this Valve implementation.
    public String getInfo() {
        return ();
    }


    
Register requests for tracking, whenever needed.

Parameters:
request The servlet request to be processed
response The servlet response to be created
Throws:
java.io.IOException if an input/output error occurs
javax.servlet.ServletException if a servlet error occurs
    public void invoke(Request requestResponse response)
        throws IOExceptionServletException {
        // Perform the request
        getNext().invoke(requestresponse);
        
        if (request.isEventMode() && !response.isClosed()) {
            // Start tracking this connection, since this is a 
            // begin event, and Comet mode is on
            HttpSession session = request.getSession(true);
            
            // Track the conection for webapp reload
            .add(request);
            
            // Track the connection for session expiration
            synchronized (session) {
                Request[] requests = (Request[])
                        session.getAttribute();
                if (requests == null) {
                    requests = new Request[1];
                    requests[0] = request;
                    session.setAttribute(,
                            requests);
                } else {
                    Request[] newRequests = 
                        new Request[requests.length + 1];
                    for (int i = 0; i < requests.lengthi++) {
                        newRequests[i] = requests[i];
                    }
                    newRequests[requests.length] = request;
                    session.setAttribute(newRequests);
                }
            }
        }
        
    }

    
    
Use events to update the connection state.

Parameters:
request The servlet request to be processed
response The servlet response to be created
Throws:
java.io.IOException if an input/output error occurs
javax.servlet.ServletException if a servlet error occurs
    public void event(Request requestResponse responseHttpEvent event)
        throws IOExceptionServletException {
        
        // Perform the request
        boolean ok = false;
        try {
            getNext().event(requestresponseevent);
            ok = true;
        } finally {
            if (!ok || response.isClosed() 
                    || (event.getType() == ..)
                    || (event.getType() == ..)) {
                
                // Remove the connection from webapp reload tracking
                .remove(request);
                
                // Remove connection from session expiration tracking
                // Note: can't get the session if it has been invalidated but
                // OK since session listener will have done clean-up
                HttpSession session = request.getSession(false);
                if (session != null) {
                    synchronized (session) {
                        Request[] reqs = (Request[])
                            session.getAttribute();
                        if (reqs != null) {
                            boolean found = false;
                            for (int i = 0; !found && (i < reqs.length); i++) {
                                found = (reqs[i] == request);
                            }
                            if (found) {
                                if (reqs.length > 1) {
                                    Request[] newConnectionInfos = 
                                        new Request[reqs.length - 1];
                                    int pos = 0;
                                    for (int i = 0; i < reqs.lengthi++) {
                                        if (reqs[i] != request) {
                                            newConnectionInfos[pos++] = reqs[i];
                                        }
                                    }
                                    session.setAttribute(,
                                            newConnectionInfos);
                                } else {
                                    try {
                                        session.removeAttribute(
                                                );
                                    } catch (IllegalStateException e) {
                                        // Ignore
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    public void sessionCreated(HttpSessionEvent se) {
    }
    public void sessionDestroyed(HttpSessionEvent se) {
        // Close all Comet connections associated with this session
        Request[] reqs = (Request[])
            se.getSession().getAttribute();
        if (reqs != null) {
            for (int i = 0; i < reqs.lengthi++) {
                Request req = reqs[i];
                try {
                    req.getEvent().close();
                } catch (Exception e) {
                    req.getWrapper().getParent().getLogger().warn(.eventValveSessionListenerException(), e);
                }
            }
        }
    }
New to GrepCode? Check out our FAQ X