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