View Javadoc

1   package com.atlassian.johnson.context;
2   
3   import com.atlassian.johnson.Johnson;
4   
5   import javax.annotation.Nonnull;
6   import javax.servlet.ServletContext;
7   import javax.servlet.ServletContextEvent;
8   import javax.servlet.ServletContextListener;
9   
10  /**
11   * Initialises and terminates {@link Johnson} with the servlet container.
12   * <p>
13   * In web environments, this is the preferred mechanism for managing Johnson's lifecycle, allowing it to be initialised
14   * and terminated in a thread-safe context. This listener should be registered before any others except, if applicable,
15   * those that setup logging.
16   * <p>
17   * To use this listener, add the following to web.xml:
18   * <pre>
19   * <code>&lt;listener&gt;
20   *     &lt;listener-class&gt;com.atlassian.johnson.context.JohnsonContextListener&lt;/listener-class&gt;
21   * &lt;/listener&gt;
22   * </code>
23   * </pre>
24   * Alternatively, if the application is deployed in a Servlet 3 container such as Tomcat 7, this listener can be
25   * registered in a {@code ServletContainerInitializer} using {@code ServletContext.addListener}.
26   *
27   * @since 2.0
28   */
29  public class JohnsonContextListener implements ServletContextListener {
30  
31      /**
32       * When a {@code JohnsonContextListener} {@link #register(ServletContext) is registered} with a
33       * {@code ServletContext}, this attribute will be used to mark its registration so that multiple
34       * listeners will not be registered.
35       *
36       * @since 3.0
37       */
38      public static final String ATTR_REGISTERED = JohnsonContextListener.class.getName() + ":Registered";
39  
40      /**
41       * Registers a {@code JohnsonContextListener} with the provided {@code ServletContext} if such a listener has not
42       * already been registered.
43       * <p>
44       * This method is for use as part of Servlet 3-style {@code ServletContainerInitializer} initialization. Listeners
45       * cannot be added to {@code ServletContext} instances after they have already been initialized.
46       *
47       * @param context the {@code ServletContext} to register a {@link JohnsonContextListener} with
48       * @throws IllegalArgumentException      if the provided {@link ServletContext} was not passed to
49       *                                       {@link javax.servlet.ServletContainerInitializer#onStartup(java.util.Set, ServletContext)}
50       * @throws IllegalStateException         if the {@link ServletContext} has already been initialized
51       * @throws UnsupportedOperationException if this {@link ServletContext} was passed to the
52       *                                       {@link ServletContextListener#contextInitialized(ServletContextEvent)} method of a
53       *                                       {@link ServletContextListener} that was not either declared in {@code web.xml} or
54       *                                       {@code web-fragment.xml} or annotated with {@code &#064;WebListener}
55       * @since 3.0
56       */
57      public static void register(@Nonnull ServletContext context) {
58          if (context.getAttribute(ATTR_REGISTERED) == null) {
59              context.addListener(new JohnsonContextListener());
60              context.setAttribute(ATTR_REGISTERED, Boolean.TRUE);
61          }
62      }
63  
64      /**
65       * Terminates {@link Johnson}.
66       *
67       * @param event the context event
68       * @see Johnson#terminate(javax.servlet.ServletContext)
69       */
70      public void contextDestroyed(@Nonnull ServletContextEvent event) {
71          Johnson.terminate(event.getServletContext());
72      }
73  
74      /**
75       * Initialises {@link Johnson}.
76       *
77       * @param event the context event
78       * @see Johnson#initialize(javax.servlet.ServletContext)
79       */
80      public void contextInitialized(@Nonnull ServletContextEvent event) {
81          Johnson.initialize(event.getServletContext());
82      }
83  }