[picocontainer-dev] Patch for web ... to close that static getter IoC problem
Paul Hammant <[email protected]> Fri, 20 Jun 2008 02:59:33 -0700
| Newsgroups | gmane.comp.java.picocontainer.devel |
|---|---|
| Message-ID | <[email protected]> |
Well it goes part way.
By extending a filter, we can use some private magic to hide the
static thread local vars that would otherwise make things publicly
available.
It dictates a scenario where there is only one pico-leveraging filter
per web app. And only one 'ActionFactory' thing that is using that.
Axis and Webwork1 have two things - so it needs more thought.
Axis - PicoMsgProvider, PicoRpcProvider
WebWork1 - PicoActionFactory, WebWorkVelocityServlet
Thoughts?
- Paul
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email
ham.patch
(application/octet-stream, 22.1 KB)
Index: web-struts/src/java/org/picocontainer/web/struts/ActionFactory.java
===================================================================
--- web-struts/src/java/org/picocontainer/web/struts/ActionFactory.java (revision 4659)
+++ web-struts/src/java/org/picocontainer/web/struts/ActionFactory.java (working copy)
@@ -31,6 +31,26 @@
*/
public final class ActionFactory {
+ public static class ServletFilter extends PicoServletContainerFilter {
+
+ private static ThreadLocal<MutablePicoContainer> currentRequestContainer = new ThreadLocal<MutablePicoContainer>();
+ private static ThreadLocal<MutablePicoContainer> currentSessionContainer = new ThreadLocal<MutablePicoContainer>();
+ private static ThreadLocal<MutablePicoContainer> currentAppContainer = new ThreadLocal<MutablePicoContainer>();
+
+ protected void setAppContainer(MutablePicoContainer container) {
+ currentAppContainer.set(container);
+ }
+ protected void setRequestContainer(MutablePicoContainer container) {
+ currentRequestContainer.set(container);
+ }
+ protected void setSessionContainer(MutablePicoContainer container) {
+ currentSessionContainer.set(container);
+ }
+ private static MutablePicoContainer getRequestContainerForThread() {
+ return currentRequestContainer.get();
+ }
+ }
+
private final Map<String,Class<?>> classCache = new HashMap<String, Class<?>>();
/**
@@ -60,7 +80,7 @@
public Action getAction(HttpServletRequest request, ActionMapping mapping, ActionServlet servlet)
throws PicoCompositionException {
- MutablePicoContainer actionsContainer = PicoServletContainerFilter.getRequestContainerForThread();
+ MutablePicoContainer actionsContainer = ServletFilter.getRequestContainerForThread();
Object actionKey = mapping.getPath();
Class<?> actionType = getActionClass(mapping.getType());
Index: web-struts2/src/java/org/picocontainer/web/struts2/PicoObjectFactory.java
===================================================================
--- web-struts2/src/java/org/picocontainer/web/struts2/PicoObjectFactory.java (revision 4674)
+++ web-struts2/src/java/org/picocontainer/web/struts2/PicoObjectFactory.java (working copy)
@@ -29,6 +29,33 @@
@SuppressWarnings("serial")
public class PicoObjectFactory extends ObjectFactory {
+ public static class ServletFilter extends PicoServletContainerFilter {
+ private static ThreadLocal<MutablePicoContainer> currentRequestContainer = new ThreadLocal<MutablePicoContainer>();
+ private static ThreadLocal<MutablePicoContainer> currentSessionContainer = new ThreadLocal<MutablePicoContainer>();
+ private static ThreadLocal<MutablePicoContainer> currentAppContainer = new ThreadLocal<MutablePicoContainer>();
+
+ protected void setAppContainer(MutablePicoContainer container) {
+ currentAppContainer.set(container);
+ }
+ protected void setRequestContainer(MutablePicoContainer container) {
+ currentRequestContainer.set(container);
+ }
+ protected void setSessionContainer(MutablePicoContainer container) {
+ currentSessionContainer.set(container);
+ }
+
+ protected static MutablePicoContainer getRequestContainerForThread() {
+ return currentRequestContainer.get();
+ }
+ protected static MutablePicoContainer getSessionContainerForThread() {
+ return currentSessionContainer.get();
+ }
+ protected static MutablePicoContainer getApplicationContainerForThread() {
+ return currentAppContainer.get();
+ }
+
+ }
+
@SuppressWarnings("unchecked")
public Class getClassInstance(String name) throws ClassNotFoundException {
Class clazz = super.getClassInstance(name);
@@ -40,7 +67,7 @@
synchronized (this) {
- MutablePicoContainer reqContainer = PicoServletContainerFilter.getRequestContainerForThread();
+ MutablePicoContainer reqContainer = ServletFilter.getRequestContainerForThread();
if (reqContainer == null) {
return;
}
@@ -65,9 +92,9 @@
@SuppressWarnings("unchecked")
public Object buildBean(Class clazz, Map extraContext) throws Exception {
- MutablePicoContainer requestContainer = PicoServletContainerFilter.getRequestContainerForThread();
+ MutablePicoContainer requestContainer = ServletFilter.getRequestContainerForThread();
if (requestContainer == null) {
- MutablePicoContainer appContainer = PicoServletContainerFilter.getApplicationContainerForThread();
+ MutablePicoContainer appContainer = ServletFilter.getApplicationContainerForThread();
Object comp = appContainer.getComponent(clazz);
if (comp == null) {
appContainer.addComponent(clazz);
Index: web-core/src/java/org/picocontainer/web/PicoServletContainerFilter.java
===================================================================
--- web-core/src/java/org/picocontainer/web/PicoServletContainerFilter.java (revision 4659)
+++ web-core/src/java/org/picocontainer/web/PicoServletContainerFilter.java (working copy)
@@ -18,23 +18,21 @@
import org.picocontainer.behaviors.Storing;
@SuppressWarnings("serial")
-public class PicoServletContainerFilter implements Filter, Serializable {
+public abstract class PicoServletContainerFilter implements Filter, Serializable {
public void init(FilterConfig filterConfig) throws ServletException {
ServletContext servletContext = filterConfig.getServletContext();
ApplicationContainerHolder ach = (ApplicationContainerHolder) servletContext
.getAttribute(ApplicationContainerHolder.class.getName());
- currentAppContainer.set(ach.getContainer());
+ setAppContainer(ach.getContainer());
}
+ protected abstract void setAppContainer(MutablePicoContainer container);
+
public void destroy() {
}
- private static ThreadLocal<MutablePicoContainer> currentRequestContainer = new ThreadLocal<MutablePicoContainer>();
- public static MutablePicoContainer getRequestContainerForThread() {
- return currentRequestContainer.get();
- }
public static Object getRequestComponentForThread(Class<?> type) {
MutablePicoContainer requestContainer = getRequestContainerForThread();
@@ -42,19 +40,7 @@
container.addComponent(type);
return container.getComponent(type);
}
-
- private static ThreadLocal<MutablePicoContainer> currentSessionContainer = new ThreadLocal<MutablePicoContainer>();
- public static MutablePicoContainer getSessionContainerForThread() {
- return currentSessionContainer.get();
- }
-
- private static ThreadLocal<MutablePicoContainer> currentAppContainer = new ThreadLocal<MutablePicoContainer>();
-
- public static MutablePicoContainer getApplicationContainerForThread() {
- return currentAppContainer.get();
- }
-
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException,
ServletException {
@@ -78,15 +64,15 @@
rch.getLifecycleStateModel().resetStateModelForThread();
rch.getContainer().start();
- currentAppContainer.set(ach.getContainer());
- currentSessionContainer.set(sch.getContainer());
- currentRequestContainer.set(rch.getContainer());
+ setAppContainer(ach.getContainer());
+ setSessionContainer(sch.getContainer());
+ setRequestContainer(rch.getContainer());
filterChain.doFilter(req, resp);
- currentAppContainer.set(null);
- currentSessionContainer.set(null);
- currentRequestContainer.set(null);
+ setAppContainer(null);
+ setSessionContainer(null);
+ setRequestContainer(null);
rch.getContainer().stop();
rch.getContainer().dispose();
@@ -96,4 +82,8 @@
}
+ protected abstract void setRequestContainer(MutablePicoContainer container);
+
+ protected abstract void setSessionContainer(MutablePicoContainer container);
+
}
Index: web-webwork/src/java/org/picocontainer/web/webwork/PicoActionFactory.java
===================================================================
--- web-webwork/src/java/org/picocontainer/web/webwork/PicoActionFactory.java (revision 4659)
+++ web-webwork/src/java/org/picocontainer/web/webwork/PicoActionFactory.java (working copy)
@@ -26,6 +26,33 @@
*/
public final class PicoActionFactory extends ActionFactory {
+ public static class ServletFilter extends PicoServletContainerFilter {
+ private static ThreadLocal<MutablePicoContainer> currentRequestContainer = new ThreadLocal<MutablePicoContainer>();
+ private static ThreadLocal<MutablePicoContainer> currentSessionContainer = new ThreadLocal<MutablePicoContainer>();
+ private static ThreadLocal<MutablePicoContainer> currentAppContainer = new ThreadLocal<MutablePicoContainer>();
+
+ protected void setAppContainer(MutablePicoContainer container) {
+ currentAppContainer.set(container);
+ }
+ protected void setRequestContainer(MutablePicoContainer container) {
+ currentRequestContainer.set(container);
+ }
+ protected void setSessionContainer(MutablePicoContainer container) {
+ currentSessionContainer.set(container);
+ }
+
+ protected static MutablePicoContainer getRequestContainerForThread() {
+ return currentRequestContainer.get();
+ }
+ protected static MutablePicoContainer getSessionContainerForThread() {
+ return currentSessionContainer.get();
+ }
+ protected static MutablePicoContainer getApplicationContainerForThread() {
+ return currentAppContainer.get();
+ }
+
+ }
+
private final Map<String, Class<?>> classCache = new HashMap<String, Class<?>>();
public Action getActionImpl(String className) {
@@ -44,7 +71,7 @@
}
protected Action instantiateAction(Class<?> actionClass) {
- MutablePicoContainer actionsContainer = PicoServletContainerFilter.getRequestContainerForThread();
+ MutablePicoContainer actionsContainer = ServletFilter.getRequestContainerForThread();
Action action = (Action) actionsContainer.getComponent(actionClass);
if (action == null) {
Index: web-webwork/src/java/org/picocontainer/web/webwork/WebWorkVelocityServlet.java
===================================================================
--- web-webwork/src/java/org/picocontainer/web/webwork/WebWorkVelocityServlet.java (revision 4659)
+++ web-webwork/src/java/org/picocontainer/web/webwork/WebWorkVelocityServlet.java (working copy)
@@ -12,6 +12,7 @@
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.view.servlet.VelocityViewServlet;
import org.picocontainer.PicoContainer;
+import org.picocontainer.MutablePicoContainer;
import org.picocontainer.containers.EmptyPicoContainer;
import org.picocontainer.web.PicoServletContainerFilter;
@@ -31,6 +32,32 @@
@SuppressWarnings("serial")
public final class WebWorkVelocityServlet extends VelocityViewServlet {
+ public static class ServletFilter extends PicoServletContainerFilter {
+ private static ThreadLocal<MutablePicoContainer> currentRequestContainer = new ThreadLocal<MutablePicoContainer>();
+ private static ThreadLocal<MutablePicoContainer> currentSessionContainer = new ThreadLocal<MutablePicoContainer>();
+ private static ThreadLocal<MutablePicoContainer> currentAppContainer = new ThreadLocal<MutablePicoContainer>();
+
+ protected void setAppContainer(MutablePicoContainer container) {
+ currentAppContainer.set(container);
+ }
+ protected void setRequestContainer(MutablePicoContainer container) {
+ currentRequestContainer.set(container);
+ }
+ protected void setSessionContainer(MutablePicoContainer container) {
+ currentSessionContainer.set(container);
+ }
+
+ protected static MutablePicoContainer getRequestContainerForThread() {
+ return currentRequestContainer.get();
+ }
+ protected static MutablePicoContainer getSessionContainerForThread() {
+ return currentSessionContainer.get();
+ }
+ protected static MutablePicoContainer getApplicationContainerForThread() {
+ return currentAppContainer.get();
+ }
+ }
+
static final String WEBWORK_UTIL = "webwork";
// those have to be removed once dependency problem is solved.
// will bomb anyway.
@@ -41,7 +68,7 @@
protected Context createContext(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response) {
- Context ctx = new NanocontainerVelocityContext(PicoServletContainerFilter.getRequestContainerForThread(),
+ Context ctx = new NanocontainerVelocityContext(ServletFilter.getRequestContainerForThread(),
ServletValueStack.getStack(request));
ctx.put(REQUEST, request);
ctx.put(RESPONSE, response);
Index: web-jsf/src/java/org/picocontainer/web/jsf/PicoDelegatingVariableResolver.java
===================================================================
--- web-jsf/src/java/org/picocontainer/web/jsf/PicoDelegatingVariableResolver.java (revision 4659)
+++ web-jsf/src/java/org/picocontainer/web/jsf/PicoDelegatingVariableResolver.java (working copy)
@@ -14,6 +14,7 @@
import javax.faces.el.VariableResolver;
import org.picocontainer.PicoContainer;
+import org.picocontainer.MutablePicoContainer;
import org.picocontainer.web.PicoServletContainerFilter;
/**
@@ -113,6 +114,32 @@
*/
public class PicoDelegatingVariableResolver extends VariableResolver {
+ public static class ServletFilter extends PicoServletContainerFilter {
+ private static ThreadLocal<MutablePicoContainer> currentRequestContainer = new ThreadLocal<MutablePicoContainer>();
+ private static ThreadLocal<MutablePicoContainer> currentSessionContainer = new ThreadLocal<MutablePicoContainer>();
+ private static ThreadLocal<MutablePicoContainer> currentAppContainer = new ThreadLocal<MutablePicoContainer>();
+
+ protected void setAppContainer(MutablePicoContainer container) {
+ currentAppContainer.set(container);
+ }
+ protected void setRequestContainer(MutablePicoContainer container) {
+ currentRequestContainer.set(container);
+ }
+ protected void setSessionContainer(MutablePicoContainer container) {
+ currentSessionContainer.set(container);
+ }
+
+ protected static MutablePicoContainer getRequestContainerForThread() {
+ return currentRequestContainer.get();
+ }
+ protected static MutablePicoContainer getSessionContainerForThread() {
+ return currentSessionContainer.get();
+ }
+ protected static MutablePicoContainer getApplicationContainerForThread() {
+ return currentAppContainer.get();
+ }
+
+ }
/**
* The nested variable resolver.
*/
@@ -180,7 +207,7 @@
// First check request map.
if (requestAttributeMap != null) {
- container = PicoServletContainerFilter.getRequestContainerForThread();
+ container = ServletFilter.getRequestContainerForThread();
}
if (requestAttributeMap == null || container == null) {
@@ -189,13 +216,13 @@
Map sessionMap = facesContext.getExternalContext().getSessionMap();
if (sessionMap != null) {
// If there is a session.
- container = PicoServletContainerFilter.getSessionContainerForThread();
+ container = ServletFilter.getSessionContainerForThread();
}
if (sessionMap == null || container == null) {
// If that fails, check for App level container.
- container = PicoServletContainerFilter.getApplicationContainerForThread();
+ container = ServletFilter.getApplicationContainerForThread();
if (container == null) {
// If that fails... Fail.
throw new EvaluationException(
Index: web-webwork2/src/java/org/picocontainer/web/webwork2/PicoObjectFactory.java
===================================================================
--- web-webwork2/src/java/org/picocontainer/web/webwork2/PicoObjectFactory.java (revision 4659)
+++ web-webwork2/src/java/org/picocontainer/web/webwork2/PicoObjectFactory.java (working copy)
@@ -31,6 +31,32 @@
*/
public class PicoObjectFactory extends ObjectFactory {
+ public static class ServletFilter extends PicoServletContainerFilter {
+ private static ThreadLocal<MutablePicoContainer> currentRequestContainer = new ThreadLocal<MutablePicoContainer>();
+ private static ThreadLocal<MutablePicoContainer> currentSessionContainer = new ThreadLocal<MutablePicoContainer>();
+ private static ThreadLocal<MutablePicoContainer> currentAppContainer = new ThreadLocal<MutablePicoContainer>();
+
+ protected void setAppContainer(MutablePicoContainer container) {
+ currentAppContainer.set(container);
+ }
+ protected void setRequestContainer(MutablePicoContainer container) {
+ currentRequestContainer.set(container);
+ }
+ protected void setSessionContainer(MutablePicoContainer container) {
+ currentSessionContainer.set(container);
+ }
+
+ protected static MutablePicoContainer getRequestContainerForThread() {
+ return currentRequestContainer.get();
+ }
+ protected static MutablePicoContainer getSessionContainerForThread() {
+ return currentSessionContainer.get();
+ }
+ protected static MutablePicoContainer getApplicationContainerForThread() {
+ return currentAppContainer.get();
+ }
+ }
+
private final Map<String, Class<?>> classCache = new HashMap<String, Class<?>>();
public boolean isNoArgConstructorRequired() {
@@ -61,7 +87,7 @@
* @see com.opensymphony.xwork.ObjectFactory#buildBean(java.lang.Class)
*/
public Object buildBean(Class<?> actionClass) throws Exception {
- PicoContainer actionsContainer = PicoServletContainerFilter.getRequestContainerForThread();
+ PicoContainer actionsContainer = ServletFilter.getRequestContainerForThread();
Object action = actionsContainer.getComponent(actionClass);
if (action == null) {
Index: examples/struts-webapp/src/main/webapp/WEB-INF/web.xml
===================================================================
--- examples/struts-webapp/src/main/webapp/WEB-INF/web.xml (revision 4659)
+++ examples/struts-webapp/src/main/webapp/WEB-INF/web.xml (working copy)
@@ -10,7 +10,7 @@
<filter>
<filter-name>picoFilter</filter-name>
- <filter-class>org.picocontainer.web.PicoServletContainerFilter</filter-class>
+ <filter-class>org.picocontainer.web.struts.ActionFactory.ServletFilter</filter-class>
</filter>
<filter-mapping>
Index: examples/struts2-webapp/src/main/webapp/WEB-INF/web.xml
===================================================================
--- examples/struts2-webapp/src/main/webapp/WEB-INF/web.xml (revision 4659)
+++ examples/struts2-webapp/src/main/webapp/WEB-INF/web.xml (working copy)
@@ -10,7 +10,7 @@
<filter>
<filter-name>picoFilter</filter-name>
- <filter-class>org.picocontainer.web.PicoServletContainerFilter</filter-class>
+ <filter-class>org.picocontainer.web.struts2.PicoObjectFactory.ServletFilter</filter-class>
</filter>
<filter>
Index: examples/webwork-webapp/src/main/webapp/WEB-INF/web.xml
===================================================================
--- examples/webwork-webapp/src/main/webapp/WEB-INF/web.xml (revision 4659)
+++ examples/webwork-webapp/src/main/webapp/WEB-INF/web.xml (working copy)
@@ -10,7 +10,7 @@
<filter>
<filter-name>picoFilter</filter-name>
- <filter-class>org.picocontainer.web.PicoServletContainerFilter</filter-class>
+ <filter-class>org.picocontainer.web.webwork.PicoActionFactory.ServletFilter</filter-class>
</filter>
<filter-mapping>
Index: examples/jsf-webapp/src/main/webapp/WEB-INF/web.xml
===================================================================
--- examples/jsf-webapp/src/main/webapp/WEB-INF/web.xml (revision 4659)
+++ examples/jsf-webapp/src/main/webapp/WEB-INF/web.xml (working copy)
@@ -3,7 +3,7 @@
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
- <display-name>JSF Webapp</display-name>
+ <display-name>JSF Webapp</display-name>
<context-param>
<param-name>webapp-composer-class</param-name>
@@ -12,16 +12,16 @@
<!--
Filter to build the request container with each request to the faces servlet.
- -->
- <filter>
- <filter-name>picoFilter</filter-name>
- <filter-class>org.picocontainer.web.PicoServletContainerFilter</filter-class>
- </filter>
-
+ -->
+ <filter>
+ <filter-name>picoFilter</filter-name>
+ <filter-class>org.picocontainer.web.jsf.PicoDelegatingVariableResolver.ServletFilter</filter-class>
+ </filter>
+
<filter-mapping>
<filter-name>picoFilter</filter-name>
- <url-pattern>*.jsf</url-pattern>
- </filter-mapping>
+ <url-pattern>*.jsf</url-pattern>
+ </filter-mapping>
<listener>
<listener-class>org.picocontainer.web.PicoServletContainerListener</listener-class>
Index: examples/webwork2-webapp/src/main/webapp/WEB-INF/web.xml
===================================================================
--- examples/webwork2-webapp/src/main/webapp/WEB-INF/web.xml (revision 4659)
+++ examples/webwork2-webapp/src/main/webapp/WEB-INF/web.xml (working copy)
@@ -10,7 +10,7 @@
<filter>
<filter-name>picoFilter</filter-name>
- <filter-class>org.picocontainer.web.PicoServletContainerFilter</filter-class>
+ <filter-class>org.picocontainer.web.webwork2.PicoObjectFactory.ServletFilter</filter-class>
</filter>
<filter-mapping>