SEC-268: allow for delayed obtaining of app context reference
This commit is contained in:
parent
5d811c4a94
commit
46cc1bec1e
|
@ -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> <listener><br>
|
* <pre>
|
||||||
* <listener-class>org.acegisecurity.ui.session.HttpSessionEventPublisher</listener-class><br>
|
* <listener>
|
||||||
* </listener><br>
|
* <listener-class>org.acegisecurity.ui.session.HttpSessionEventPublisher</listener-class>
|
||||||
* </code> Publishes <code>HttpSessionApplicationEvent</code>s to the Spring
|
* </listener>
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue