Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * JBoss, Home of Professional Open Source
   * Copyright 2013, Red Hat, Inc., and individual contributors
   * by the @authors tag. See the copyright.txt in the distribution for a
   * full listing of individual contributors.
   *
   * Licensed 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.jboss.weld.servlet;
 
 import  javax.servlet.ServletContext;
 import  javax.servlet.ServletRequestListener;
 import  javax.servlet.http.HttpServletRequest;
 import  javax.servlet.http.HttpSession;
 
Takes care of setting up and tearing down CDI contexts around an HTTP request and dispatching context lifecycle events.

Author(s):
Jozef Hartinger
Marko Luksa
 
 public class HttpContextLifecycle implements Service {
 
     private static final String HTTP_SESSION = "org.jboss.weld." + HttpSession.class.getName();
 
     private static final String INCLUDE_HEADER = "javax.servlet.include.request_uri";
     private static final String FORWARD_HEADER = "javax.servlet.forward.request_uri";
     private static final String REQUEST_DESTROYED = HttpContextLifecycle.class.getName() + ".request.destroyed";
 
     private static final String GUARD_PARAMETER_NAME = "org.jboss.weld.context.ignore.guard.marker";
     private static final Object GUARD_PARAMETER_VALUE = new Object();
 
 
     private volatile Boolean conversationActivationEnabled;
     private final boolean ignoreForwards;
     private final boolean ignoreIncludes;
 
     private final BeanManagerImpl beanManager;
 
     private final FastEvent<ServletContext> applicationInitializedEvent;
     private final FastEvent<ServletContext> applicationDestroyedEvent;
     private final FastEvent<HttpServletRequest> requestInitializedEvent;
     private final FastEvent<HttpServletRequest> requestDestroyedEvent;
     private final FastEvent<HttpSession> sessionInitializedEvent;
     private final FastEvent<HttpSession> sessionDestroyedEvent;
 
     private final ServletApiAbstraction servletApi;
 
 
     private final Container container;
 
     private static final ThreadLocal<CounternestedInvocationGuard = new ThreadLocal<HttpContextLifecycle.Counter>();
     private final boolean nestedInvocationGuardEnabled;
 
     private static class Counter {
         private int value = 1;
     }
 
     public HttpContextLifecycle(BeanManagerImpl beanManagerHttpContextActivationFilter contextActivationFilterboolean ignoreForwardsboolean ignoreIncludesboolean lazyConversationContextboolean nestedInvocationGuardEnabled) {
         this. = beanManager;
         this. = new ConversationContextActivator(beanManagerlazyConversationContext);
         this. = null;
         this. = ignoreForwards;
         this. = ignoreIncludes;
         this. = contextActivationFilter;
         this. = FastEvent.of(ServletContext.classbeanManager.);
         this. = FastEvent.of(ServletContext.classbeanManager.);
        this. = FastEvent.of(HttpServletRequest.classbeanManager.);
        this. = FastEvent.of(HttpServletRequest.classbeanManager.);
        this. = FastEvent.of(HttpSession.classbeanManager.);
        this. = FastEvent.of(HttpSession.classbeanManager.);
        this. = beanManager.getServices().get(ServletApiAbstraction.class);
        this. = beanManager.getServices().get(ServletContextService.class);
        this. = nestedInvocationGuardEnabled;
        this. = Container.instance(beanManager);
    }
        if ( == null) {
        }
        return ;
    }
        if ( == null) {
            this. = .instance().select(HttpSessionContext.class).get();
        }
        return ;
    }
        if ( == null) {
            this. = .instance().select(HttpRequestContext.class).get();
        }
        return ;
    }
    public void contextInitialized(ServletContext ctx) {
        synchronized () {
            .fire(ctx);
        }
    }
    public void contextDestroyed(ServletContext ctx) {
        synchronized () {
            .fire(ctx);
        }
    }
    public void sessionCreated(HttpSession session) {
        SessionHolder.sessionCreated(session);
        .fire(session);
    }
    public void sessionDestroyed(HttpSession session) {
        // Mark the session context and conversation contexts to destroy
        // instances when appropriate
        deactivateSessionDestructionContext(session);
        boolean destroyed = getSessionContext().destroy(session);
        SessionHolder.clear();
        RequestScopedCache.endRequest();
        if (destroyed) {
            // we are outside of a request (the session timed out) and therefore the session was destroyed immediately
            // we can fire the @Destroyed(SessionScoped.class) event immediately
            .fire(session);
        } else {
            // the old session won't be available at the time we destroy this request
            // let's store its reference until then
            if (getRequestContext() instanceof HttpRequestContextImpl) {
                HttpServletRequest request = Reflections.<HttpRequestContextImplcast(getRequestContext()).getHttpServletRequest();
                request.setAttribute(session);
            }
        }
    }
    private void deactivateSessionDestructionContext(HttpSession session) {
        if (context.isActive()) {
            context.deactivate();
            context.dissociate(session);
        }
    }
    public void requestInitialized(HttpServletRequest request, ServletContext ctx) {
        if () {
            Counter counter = .get();
            Object marker = request.getAttribute();
            if (counter != null && marker != null) {
                // this is a nested invocation, increment the counter and ignore this invocation
                counter.value++;
                return;
            } else {
                if (counter != null && marker == null) {
                    /*
                     * This request has not been processed yet but the guard is set already.
                     * That indicates, that the guard leaked from a previous request processing - most likely
                     * the Servlet container did not invoke listener methods symmetrically.
                     * Log a warning and recover by re-initializing the guard
                     */
                    ..guardLeak(counter.value);
                }
                // this is the initial (outer) invocation
                .set(new Counter());
                request.setAttribute();
            }
        }
        if ( && isForwardedRequest(request)) {
            return;
        }
        if ( && isIncludedRequest(request)) {
            return;
        }
        if (!.accepts(request)) {
            return;
        }
        ..requestInitialized(request);
        SessionHolder.requestInitialized(request);
        getRequestContext().associate(request);
        getSessionContext().associate(request);
        if () {
        }
        getRequestContext().activate();
        getSessionContext().activate();
        try {
            if () {
                .activateConversationContext(request);
            }
            .fire(request);
        } catch (RuntimeException e) {
            try {
                requestDestroyed(request);
            } catch (Exception ignored) {
                // ignored in order to let the original exception be thrown
            }
            /*
             * If the servlet container happens to call the destroyed callback again, ignore it.
             */
            request.setAttribute(.);
            throw e;
        }
    }
    public void requestDestroyed(HttpServletRequest request) {
        if (isRequestDestroyed(request)) {
            return;
        }
        if () {
            Counter counter = .get();
            if (counter != null) {
                counter.value--;
                if (counter.value > 0) {
                    return// this is a nested invocation, ignore it
                } else {
                    .remove(); // this is the outer invocation
                    request.removeAttribute();
                }
            } else {
                ..guardNotSet();
                return;
            }
        }
        if ( && isForwardedRequest(request)) {
            return;
        }
        if ( && isIncludedRequest(request)) {
            return;
        }
        if (!.accepts(request)) {
            return;
        }
        ..requestDestroyed(request);
        try {
            /*
             * if this request has been switched to async then do not invalidate the context now
             * as it will be invalidated at the end of the async operation.
             */
            if (!.isAsyncSupported() || !.isAsyncStarted(request)) {
                getRequestContext().invalidate();
            }
            safelyDeactivate(getRequestContext(),  request);
            // fire @Destroyed(RequestScoped.class)
            .fire(request);
            safelyDeactivate(getSessionContext(), request);
            // fire @Destroyed(SessionScoped.class)
            if (!getSessionContext().isValid()) {
                .fire((HttpSession) request.getAttribute());
            }
        } finally {
            safelyDissociate(getRequestContext(), request);
            // WFLY-1533 Underlying HTTP session may be invalid
            safelyDissociate(getSessionContext(), request);
            // Catch block is inside the activator method so that we're able to log the context
            SessionHolder.clear();
        }
    }
    public boolean isConversationActivationSet() {
        return  != null;
    }
    public void setConversationActivationEnabled(boolean conversationActivationEnabled) {
        this. = conversationActivationEnabled;
    }
    @Override
    public void cleanup() {
    }

    
Some Servlet containers fire HttpServletListeners for include requests (inner requests caused by calling the include method of RequestDispatcher). This causes problems with context shut down as context manipulation is not reentrant. This method detects if this request is an included request or not.
    private boolean isIncludedRequest(HttpServletRequest request) {
        return request.getAttribute() != null;
    }

    
Some Servlet containers fire HttpServletListeners for forward requests (inner requests caused by calling the forward method of RequestDispatcher). This causes problems with context shut down as context manipulation is not reentrant. This method detects if this request is an forwarded request or not.
    private boolean isForwardedRequest(HttpServletRequest request) {
        return request.getAttribute() != null;
    }

    
The way servlet containers react to an exception that occurs in a ServletRequestListener differs among servlet listeners. In certain containers the destroyed callback may be invoked multiple times, causing the latter invocations to fail as thread locals have already been unset. We use the REQUEST_DESTROYED flag to indicate that all further invocations of the ServletRequestListener.requestDestroyed(javax.servlet.ServletRequestEvent) should be ignored by Weld.
    private boolean isRequestDestroyed(HttpServletRequest request) {
        return request.getAttribute() != null;
    }
    private <T> void safelyDissociate(BoundContext<T> context, T storage) {
        try {
            context.dissociate(storage);
        } catch(Exception e) {
            ..unableToDissociateContext(contextstorage);
            ..catchingDebug(e);
        }
    }
    private void safelyDeactivate(ManagedContext context, HttpServletRequest request) {
        try {
            context.deactivate();
        } catch(Exception e) {
            ..unableToDeactivateContext(contextrequest);
            ..catchingDebug(e);
        }
    }
New to GrepCode? Check out our FAQ X