1 package com.atlassian.johnson.spring.web.context.support;
2
3 import com.atlassian.johnson.context.JohnsonContextListener;
4 import com.atlassian.johnson.spring.web.context.JohnsonContextLoaderListener;
5 import org.springframework.web.context.AbstractContextLoaderInitializer;
6 import org.springframework.web.context.ContextLoaderListener;
7 import org.springframework.web.context.WebApplicationContext;
8
9 import javax.servlet.ServletContext;
10 import javax.servlet.ServletException;
11
12 /**
13 * Extends Spring's {@code AbstractDispatcherServletInitializer} to use Johnson-aware components.
14 * <ul>
15 * <li>A {@link JohnsonContextListener} will be registered <i>before</i> any other listeners that are registered
16 * by this initializer</li>
17 * <li>A {@link JohnsonContextLoaderListener} will be used to initialize the {@link #createRootApplicationContext()
18 * root ApplicationContext}</li>
19 * </ul>
20 * <p>
21 * In addition to using Johnson-aware components by default, this base class allows derived initializers to override
22 * {@link #createContextLoaderListener(WebApplicationContext) the ContextLoaderListener} used. This is intended to
23 * allow for application-specific handling on top of the Johnson-aware handling.
24 *
25 * @since 3.0
26 */
27 public abstract class AbstractJohnsonContextLoaderInitializer extends AbstractContextLoaderInitializer {
28
29 /**
30 * Creates a {@link JohnsonContextLoaderListener} which will initialize and terminate the provided
31 * {@code WebApplicationContext}. This method is provided as a convenience for derived classes to
32 * simplify replacing the listener used.
33 *
34 * @param context the {@code WebApplicationContext} to be initialized by the created listener
35 * @return the listener to register with the {@code ServletContext}
36 */
37 protected ContextLoaderListener createContextLoaderListener(WebApplicationContext context) {
38 return new JohnsonContextLoaderListener(context);
39 }
40
41 /**
42 * {@link #registerJohnsonContextListener(ServletContext) Registers a} {@link JohnsonContextListener} and then
43 * delegates to the superclass's {@code onStartup(ServletContext)} implementation.
44 *
45 * @param servletContext the {@code ServletContext} to initialize
46 * @throws ServletException potentially thrown by the superclass {@code onStartup(ServletContext)} implementation
47 */
48 @Override
49 public void onStartup(ServletContext servletContext) throws ServletException {
50 registerJohnsonContextListener(servletContext);
51
52 super.onStartup(servletContext);
53 }
54
55 /**
56 * Overrides {@code AbstractContextLoaderInitializer}'s {@code registerContextLoaderListener} to register a
57 * {@link #createContextLoaderListener(WebApplicationContext) JohnsonContextLoaderListener} instead of the
58 * standard Spring {@code ContextLoaderListener}.
59 *
60 * @param servletContext the {@code ServletContext} to register the {@link JohnsonContextLoaderListener} in
61 */
62 @Override
63 protected void registerContextLoaderListener(ServletContext servletContext) {
64 WebApplicationContext context = createRootApplicationContext();
65 if (context == null) {
66 logger.debug("No ContextLoaderListener registered, as createRootApplicationContext() did not return an application context");
67 } else {
68 servletContext.addListener(createContextLoaderListener(context));
69 }
70 }
71
72 /**
73 * Registers an {@link JohnsonContextListener} in in the provided {@code ServletContext}. This listener ensures
74 * Johnson is initialized and terminated with the application.
75 * <p>
76 * Note: Even if this method is called multiple times, with its default implementation the listener will only be
77 * added <i>once</i>.
78 *
79 * @param servletContext the {@code ServletContext} to register the {@link JohnsonContextListener} in
80 * @see JohnsonContextListener#register(ServletContext)
81 */
82 protected void registerJohnsonContextListener(ServletContext servletContext) {
83 JohnsonContextListener.register(servletContext);
84 }
85 }