Ok, I have created the class that was described in the previous thread.
The class uses ThreadLocal to do the binding, and it should work in a
web application. The basic theory is the class extends
WebApplicationListener and implements a 2.4 Servlet API Listener to get
notified for requests, and then it places the DataContext in the
ThreadLocal.
I have been unable to get to my normal devel location, so this class is
basically uncompiled and very untested. I was going to wait to send it
out, but it looks like people are interested. I will post a more final
version once I actually get to working out the kinks.
If you have any questions, send them to me personally so we don't flood
the list.
Scott
package org.objectstyle.cayenne.conf;
import org.objectstyle.cayenne.access.DataContext;
import org.objectstyle.cayenne.conf.BasicServletConfiguration;
import org.objectstyle.cayenne.conf.WebApplicationListener;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* <p>This class allows for a web application to retrieve a DataContext anywhere
* in a servlet request. This is very useful when you want to decouple the
* controller layer (Servlets, Struts, etc.) from a DAO layer, and
* cannot/should not include a implementation-specific DataContext in a DAO
* interface. To use this class, configure this class as a listener (like the
* WebApplicationListener):</p>
* <p>In <code>web.xml</code> deployment descriptor, configure as a listener of
* context, session, and request events:</p>
*<pre><listener>
<listener-class>org.objectstyle.cayenne.conf.WebApplicationListener</listener-class>
</listener></pre>
* You then can retrieve a DataContext by calling the static method
* ..ink DataContextProvider#getDataContext()} or by calling
* ..ink BasicServletConfiguration#getDefaultContext(HttpSession)}
* <p><b>If using DataContextProvider, do not include a WebApplicationListener
* as well.</b></p>
* <p>This class relies on the new functionality from Servlet 2.4 API
* (Tomcat 5.*).</p>
*..uthor <a href="mailto:scott@smartblob.com">Scott McClure</a>
*/
public class DataContextProvider extends WebApplicationListener
implements ServletRequestListener {
protected static ThreadLocal dataContext = new ThreadLocal();
/*
* <p>Given a request, get the DataContext from the Session, and bind the
* DataContext to the thread.</p>
*/
public void requestInitialized(ServletRequestEvent sre) {
ServletRequest req = sre.getServletRequest();
if (req instanceof HttpServletRequest) {
HttpSession session = ((HttpServletRequest) req).getSession();
DataContext dc = (DataContext) session.getAttribute(BasicServletConfiguration.DATA_CONTEXT_KEY);
if (dc != null) {
dataContext.set(dc);
} else {
throw IllegalStateException (
"DataContext is null for the session, cannot bind to thread.");
}
}
}
/*
* Remove the reference to the DataContext from the thread.
*/
public void requestDestroyed(ServletRequestEvent sre) {
//Prevent lingering object references
dataContext.set(null);
}
/*
* <p>Return the DataContext for this request.</p>
* <p><b>ONLY CALL THIS METHOD FROM WITHIN THE CONTEXT OF A REQUEST!</b></p>
*..eturns the DataContext associated with this thread.
*/
public static DataContext getDataContext() {
DataContext dc = (DataContext) dataContext.get();
if (sess == null) {
throw new IllegalStateException (
"DataContextProvider.get() has been called outside the thread associated with a servlet request.");
}
return sess;
}
}
This archive was generated by hypermail 2.0.0 : Wed Jun 30 2004 - 15:59:35 EDT