SEC-268: allow for delayed obtaining of app context reference

This commit is contained in:
Luke Taylor 2006-05-19 21:38:26 +00:00
parent 5d811c4a94
commit 46cc1bec1e
2 changed files with 50 additions and 45 deletions

View File

@ -21,25 +21,27 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.util.Assert;
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; import javax.servlet.ServletContextListener;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; import javax.servlet.http.HttpSessionListener;
/** /**
* Declared in web.xml as <br> * Declared in web.xml as <br>
* <code> &lt;listener&gt;<br> * <pre>
* &lt;listener-class&gt;org.acegisecurity.ui.session.HttpSessionEventPublisher&lt;/listener-class&gt;<br> * &lt;listener&gt;
* &lt;/listener&gt;<br> * &lt;listener-class&gt;org.acegisecurity.ui.session.HttpSessionEventPublisher&lt;/listener-class&gt;
* </code> Publishes <code>HttpSessionApplicationEvent</code>s to the Spring * &lt;/listener&gt;
* Root WebApplicationContext. <br> * </pre>
* Publishes <code>HttpSessionApplicationEvent</code>s to the Spring
* Root WebApplicationContext.
* Maps javax.servlet.http.HttpSessionListener.sessionCreated() to {@link * Maps javax.servlet.http.HttpSessionListener.sessionCreated() to {@link
* HttpSessionCreatedEvent}. <br> * HttpSessionCreatedEvent}.
* Maps javax.servlet.http.HttpSessionListener.sessionDestroyed() to {@link * Maps javax.servlet.http.HttpSessionListener.sessionDestroyed() to {@link
* HttpSessionDestroyedEvent}. <br> * HttpSessionDestroyedEvent}.
* *
* @author Ray Krueger * @author Ray Krueger
*/ */
@ -51,7 +53,8 @@ public class HttpSessionEventPublisher implements HttpSessionListener,
//~ Instance fields ======================================================== //~ Instance fields ========================================================
private ApplicationContext context; private ApplicationContext appContext;
private ServletContext servletContext = null;
//~ Methods ================================================================ //~ Methods ================================================================
@ -64,22 +67,28 @@ public class HttpSessionEventPublisher implements HttpSessionListener,
/** /**
* Handled internally by a call to {@link * Handled internally by a call to {@link
* org.springframework.web.context.support.WebApplicationContextUtils#getRequiredWebApplicationContext(javax.servlet.ServletContext)} * org.springframework.web.appContext.support.WebApplicationContextUtils#getRequiredWebApplicationContext(javax.servlet.ServletContext)}
* *
* @param event the ServletContextEvent passed in by the container, * @param event the ServletContextEvent passed in by the container,
* event.getServletContext() will be used to get the * event.getServletContext() will be used to get the
* WebApplicationContext * WebApplicationContext
*/ */
public void contextInitialized(ServletContextEvent event) { public void contextInitialized(ServletContextEvent event) {
if (log.isDebugEnabled())
log.debug("Received ServletContextEvent: " + event); log.debug("Received ServletContextEvent: " + event);
setContext(WebApplicationContextUtils.getRequiredWebApplicationContext(
event.getServletContext())); appContext = WebApplicationContextUtils.getWebApplicationContext(
event.getServletContext());
if(appContext == null) {
log.warn("Web application context is null. Will delay initialization until it's first used.");
servletContext = event.getServletContext();
}
} }
/** /**
* Handles the HttpSessionEvent by publishing a {@link * Handles the HttpSessionEvent by publishing a {@link
* HttpSessionCreatedEvent} to the application context. * HttpSessionCreatedEvent} to the application appContext.
* *
* @param event HttpSessionEvent passed in by the container * @param event HttpSessionEvent passed in by the container
*/ */
@ -94,7 +103,7 @@ public class HttpSessionEventPublisher implements HttpSessionListener,
/** /**
* Handles the HttpSessionEvent by publishing a {@link * Handles the HttpSessionEvent by publishing a {@link
* HttpSessionDestroyedEvent} to the application context. * HttpSessionDestroyedEvent} to the application appContext.
* *
* @param event The HttpSessionEvent pass in by the container * @param event The HttpSessionEvent pass in by the container
*/ */
@ -107,19 +116,11 @@ public class HttpSessionEventPublisher implements HttpSessionListener,
getContext().publishEvent(e); getContext().publishEvent(e);
} }
/** ApplicationContext getContext() {
* Package level method for testing and internal usage if(appContext == null) {
* appContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
* @param context The ApplicationContext this class will use to publish
* events
*/
void setContext(ApplicationContext context) {
this.context = context;
log.debug("Using context: " + context);
} }
ApplicationContext getContext() { return appContext;
Assert.notNull(context, "setContext(...) never called, ApplicationContext must not be null");
return context;
} }
} }

View File

@ -20,13 +20,10 @@ import junit.framework.TestCase;
import org.springframework.mock.web.MockServletContext; import org.springframework.mock.web.MockServletContext;
import org.springframework.mock.web.MockHttpSession; import org.springframework.mock.web.MockHttpSession;
import org.springframework.web.context.support.StaticWebApplicationContext; import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextEvent;
import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionEvent;
import org.acegisecurity.MockApplicationContext;
/** /**
* The HttpSessionEventPublisher tests * The HttpSessionEventPublisher tests
@ -39,9 +36,8 @@ public class HttpSessionEventPublisherTests extends TestCase {
/** /**
* It's not that complicated so we'll just run it straight through here. * It's not that complicated so we'll just run it straight through here.
* @throws Exception
*/ */
public void testPublisher() throws Exception { public void testPublisher() {
HttpSessionEventPublisher publisher = new HttpSessionEventPublisher(); HttpSessionEventPublisher publisher = new HttpSessionEventPublisher();
StaticWebApplicationContext context = new StaticWebApplicationContext(); StaticWebApplicationContext context = new StaticWebApplicationContext();
@ -77,21 +73,29 @@ public class HttpSessionEventPublisherTests extends TestCase {
publisher.contextDestroyed(new ServletContextEvent(servletContext)); publisher.contextDestroyed(new ServletContextEvent(servletContext));
} }
public void testContext() throws Exception {
HttpSessionEventPublisher pub = new HttpSessionEventPublisher(); public void testDelayedContextInitializationSucceeds() {
ConfigurableApplicationContext c = MockApplicationContext.getContext(); HttpSessionEventPublisher publisher = new HttpSessionEventPublisher();
pub.setContext(c); MockServletContext servletContext = new MockServletContext();
assertEquals(c, pub.getContext());
// shouldn't fail, even with null context
publisher.contextInitialized(new ServletContextEvent(servletContext));
StaticWebApplicationContext context = new StaticWebApplicationContext();
context.setServletContext(servletContext);
} }
public void testNullContextCheck() throws Exception { public void testGetContextThrowsExceptionIfContextNotSet() {
HttpSessionEventPublisher pub = new HttpSessionEventPublisher(); HttpSessionEventPublisher publisher = new HttpSessionEventPublisher();
publisher.contextInitialized(new ServletContextEvent(new MockServletContext()));
try { try {
pub.getContext(); publisher.getContext();
fail("IllegalArgumentException expected, the context is null"); fail("IllegalStateException expected when no context set");
} catch (IllegalArgumentException e) { } catch (IllegalStateException expected) {
assertTrue(true);
} }
} }
} }