001 /*******************************************************************************
002 * Copyright (C) PicoContainer Organization. All rights reserved.
003 * --------------------------------------------------------------------------
004 * The software in this package is published under the terms of the BSD style
005 * license a copy of which has been included with this distribution in the
006 * LICENSE.txt file.
007 ******************************************************************************/
008 package org.picocontainer.web;
009
010 import java.io.IOException;
011 import java.io.Serializable;
012
013 import javax.servlet.Filter;
014 import javax.servlet.FilterChain;
015 import javax.servlet.FilterConfig;
016 import javax.servlet.ServletContext;
017 import javax.servlet.ServletException;
018 import javax.servlet.ServletRequest;
019 import javax.servlet.ServletResponse;
020 import javax.servlet.http.HttpServletRequest;
021 import javax.servlet.http.HttpSession;
022
023 import org.picocontainer.DefaultPicoContainer;
024 import org.picocontainer.MutablePicoContainer;
025 import org.picocontainer.behaviors.Storing;
026
027 @SuppressWarnings("serial")
028 public abstract class PicoServletContainerFilter implements Filter, Serializable {
029
030 public void init(FilterConfig filterConfig) throws ServletException {
031 ServletContext servletContext = filterConfig.getServletContext();
032 ApplicationContainerHolder ach = (ApplicationContainerHolder) servletContext
033 .getAttribute(ApplicationContainerHolder.class.getName());
034 setAppContainer(ach.getContainer());
035 }
036
037 public void destroy() {
038 }
039
040 public static Object getRequestComponentForThread(Class<?> type) {
041 MutablePicoContainer requestContainer = ServletFilter.getRequestContainerForThread();
042 MutablePicoContainer container = new DefaultPicoContainer(requestContainer);
043 container.addComponent(type);
044 return container.getComponent(type);
045 }
046
047 public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException,
048 ServletException {
049
050 HttpServletRequest httpReq = (HttpServletRequest) req;
051 HttpSession session = httpReq.getSession();
052 ServletContext context = session.getServletContext();
053
054 ApplicationContainerHolder ach = (ApplicationContainerHolder) context
055 .getAttribute(ApplicationContainerHolder.class.getName());
056 SessionContainerHolder sch = (SessionContainerHolder) context.getAttribute(SessionContainerHolder.class
057 .getName());
058 RequestContainerHolder rch = (RequestContainerHolder) context.getAttribute(RequestContainerHolder.class
059 .getName());
060
061 Storing sessionStoring = sch.getStoring();
062 Storing requestStoring = rch.getStoring();
063
064 SessionStoreHolder ssh = (SessionStoreHolder) session.getAttribute(SessionStoreHolder.class.getName());
065 sessionStoring.putCacheForThread(ssh.getStoreWrapper());
066 requestStoring.resetCacheForThread();
067 rch.getLifecycleStateModel().resetStateModelForThread();
068 rch.getContainer().start();
069
070 setAppContainer(ach.getContainer());
071 setSessionContainer(sch.getContainer());
072 setRequestContainer(rch.getContainer());
073
074 filterChain.doFilter(req, resp);
075
076 setAppContainer(null);
077 setSessionContainer(null);
078 setRequestContainer(null);
079
080 rch.getContainer().stop();
081 rch.getContainer().dispose();
082 rch.getLifecycleStateModel().invalidateStateModelForThread();
083 sessionStoring.invalidateCacheForThread();
084 requestStoring.invalidateCacheForThread();
085
086 }
087
088 protected abstract void setAppContainer(MutablePicoContainer container);
089
090 protected abstract void setSessionContainer(MutablePicoContainer container);
091
092 protected abstract void setRequestContainer(MutablePicoContainer container);
093
094 public static class ServletFilter extends PicoServletContainerFilter {
095
096 private static ThreadLocal<MutablePicoContainer> currentRequestContainer = new ThreadLocal<MutablePicoContainer>();
097 private static ThreadLocal<MutablePicoContainer> currentSessionContainer = new ThreadLocal<MutablePicoContainer>();
098 private static ThreadLocal<MutablePicoContainer> currentAppContainer = new ThreadLocal<MutablePicoContainer>();
099
100 protected void setAppContainer(MutablePicoContainer container) {
101 currentAppContainer.set(container);
102 }
103
104 protected void setRequestContainer(MutablePicoContainer container) {
105 currentRequestContainer.set(container);
106 }
107
108 protected void setSessionContainer(MutablePicoContainer container) {
109 currentSessionContainer.set(container);
110 }
111
112 public static MutablePicoContainer getRequestContainerForThread() {
113 return currentRequestContainer.get();
114 }
115
116 public static MutablePicoContainer getSessionContainerForThread() {
117 return currentSessionContainer.get();
118 }
119
120 public static MutablePicoContainer getApplicationContainerForThread() {
121 return currentAppContainer.get();
122 }
123 }
124 }