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.web.context.support.WebApplicationContextUtils;
import org.springframework.util.Assert;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* Declared in web.xml as <br>
* <code> &lt;listener&gt;<br>
* &lt;listener-class&gt;org.acegisecurity.ui.session.HttpSessionEventPublisher&lt;/listener-class&gt;<br>
* &lt;/listener&gt;<br>
* </code> Publishes <code>HttpSessionApplicationEvent</code>s to the Spring
* Root WebApplicationContext. <br>
* <pre>
* &lt;listener&gt;
* &lt;listener-class&gt;org.acegisecurity.ui.session.HttpSessionEventPublisher&lt;/listener-class&gt;
* &lt;/listener&gt;
* </pre>
* Publishes <code>HttpSessionApplicationEvent</code>s to the Spring
* Root WebApplicationContext.
* Maps javax.servlet.http.HttpSessionListener.sessionCreated() to {@link
* HttpSessionCreatedEvent}. <br>
* HttpSessionCreatedEvent}.
* Maps javax.servlet.http.HttpSessionListener.sessionDestroyed() to {@link
* HttpSessionDestroyedEvent}. <br>
* HttpSessionDestroyedEvent}.
*
* @author Ray Krueger
*/
@ -51,7 +53,8 @@ public class HttpSessionEventPublisher implements HttpSessionListener,
//~ Instance fields ========================================================
private ApplicationContext context;
private ApplicationContext appContext;
private ServletContext servletContext = null;
//~ Methods ================================================================
@ -64,22 +67,28 @@ public class HttpSessionEventPublisher implements HttpSessionListener,
/**
* 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,
* event.getServletContext() will be used to get the
* WebApplicationContext
*/
public void contextInitialized(ServletContextEvent event) {
if (log.isDebugEnabled())
log.debug("Received ServletContextEvent: " + event);
setContext(WebApplicationContextUtils.getRequiredWebApplicationContext(
event.getServletContext()));
log.debug("Received ServletContextEvent: " + event);
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
* HttpSessionCreatedEvent} to the application context.
* HttpSessionCreatedEvent} to the application appContext.
*
* @param event HttpSessionEvent passed in by the container
*/
@ -94,7 +103,7 @@ public class HttpSessionEventPublisher implements HttpSessionListener,
/**
* 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
*/
@ -107,19 +116,11 @@ public class HttpSessionEventPublisher implements HttpSessionListener,
getContext().publishEvent(e);
}
/**
* Package level method for testing and internal usage
*
* @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() {
Assert.notNull(context, "setContext(...) never called, ApplicationContext must not be null");
return context;
if(appContext == null) {
appContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
}
return appContext;
}
}

View File

@ -20,13 +20,10 @@ import junit.framework.TestCase;
import org.springframework.mock.web.MockServletContext;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.http.HttpSessionEvent;
import org.acegisecurity.MockApplicationContext;
/**
* 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.
* @throws Exception
*/
public void testPublisher() throws Exception {
public void testPublisher() {
HttpSessionEventPublisher publisher = new HttpSessionEventPublisher();
StaticWebApplicationContext context = new StaticWebApplicationContext();
@ -77,21 +73,29 @@ public class HttpSessionEventPublisherTests extends TestCase {
publisher.contextDestroyed(new ServletContextEvent(servletContext));
}
public void testContext() throws Exception {
HttpSessionEventPublisher pub = new HttpSessionEventPublisher();
ConfigurableApplicationContext c = MockApplicationContext.getContext();
pub.setContext(c);
assertEquals(c, pub.getContext());
public void testDelayedContextInitializationSucceeds() {
HttpSessionEventPublisher publisher = new HttpSessionEventPublisher();
MockServletContext servletContext = new MockServletContext();
// shouldn't fail, even with null context
publisher.contextInitialized(new ServletContextEvent(servletContext));
StaticWebApplicationContext context = new StaticWebApplicationContext();
context.setServletContext(servletContext);
}
public void testNullContextCheck() throws Exception {
HttpSessionEventPublisher pub = new HttpSessionEventPublisher();
public void testGetContextThrowsExceptionIfContextNotSet() {
HttpSessionEventPublisher publisher = new HttpSessionEventPublisher();
publisher.contextInitialized(new ServletContextEvent(new MockServletContext()));
try {
pub.getContext();
fail("IllegalArgumentException expected, the context is null");
} catch (IllegalArgumentException e) {
assertTrue(true);
publisher.getContext();
fail("IllegalStateException expected when no context set");
} catch (IllegalStateException expected) {
}
}
}