1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.container.servlet

File XWikiServletContextListener.java

 

Coverage histogram

../../../../img/srcFileCovDistChart9.png
38% of files have more coverage

Code metrics

2
33
2
1
158
75
8
0.24
16.5
2
4

Classes

Class Line # Actions
XWikiServletContextListener 43 33 0% 8 4
0.891891989.2%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.container.servlet;
21   
22    import javax.servlet.ServletContextEvent;
23    import javax.servlet.ServletContextListener;
24   
25    import org.slf4j.Logger;
26    import org.slf4j.LoggerFactory;
27    import org.xwiki.component.embed.EmbeddableComponentManager;
28    import org.xwiki.component.internal.StackingComponentEventManager;
29    import org.xwiki.component.manager.ComponentLookupException;
30    import org.xwiki.container.ApplicationContextListenerManager;
31    import org.xwiki.container.Container;
32    import org.xwiki.environment.Environment;
33    import org.xwiki.environment.internal.ServletEnvironment;
34    import org.xwiki.observation.ObservationManager;
35    import org.xwiki.observation.event.ApplicationStartedEvent;
36    import org.xwiki.observation.event.ApplicationStoppedEvent;
37   
38    /**
39    * Implementation of the {@link ServletContextListener}. Initializes component manager and application context.
40    *
41    * @version $Id: a862c07669bd64b10add688c90f8ff273847326f $
42    */
 
43    public class XWikiServletContextListener implements ServletContextListener
44    {
45    /**
46    * Logger to use to log shutdown information (opposite of initialization).
47    */
48    private static final Logger SHUTDOWN_LOGGER = LoggerFactory.getLogger("org.xwiki.shutdown");
49   
50    /** The component manager used to lookup other components. */
51    private EmbeddableComponentManager componentManager;
52   
 
53  32 toggle @Override
54    public void contextInitialized(ServletContextEvent servletContextEvent)
55    {
56    // Initializes the Embeddable Component Manager
57  32 EmbeddableComponentManager ecm = new EmbeddableComponentManager();
58   
59    // Initialize all the components. Note that this can fail with a Runtime Exception. This is done voluntarily so
60    // that the XWiki webapp will not be available if one component fails to load. It's better to fail-fast.
61  32 ecm.initialize(this.getClass().getClassLoader());
62  32 this.componentManager = ecm;
63   
64    // This is a temporary bridge to allow non XWiki components to lookup XWiki components.
65    // We're putting the XWiki Component Manager instance in the Servlet Context so that it's
66    // available in the XWikiAction class which in turn puts it into the XWikiContext instance.
67    // Class that need to lookup then just need to get it from the XWikiContext instance.
68    // This is of course not necessary for XWiki components since they just need to implement
69    // the Composable interface to get access to the Component Manager or better they simply
70    // need to declare their components requirements using the @Inject annotation of the xwiki
71    // component manager together with a private class member, for automatic injection by the CM on init.
72  32 servletContextEvent.getServletContext().setAttribute(
73    org.xwiki.component.manager.ComponentManager.class.getName(), this.componentManager);
74   
75    // Use a Component Event Manager that stacks Component instance creation events till we tell it to flush them.
76    // The reason is that the Observation Manager used to send the events but we need the Application Context to
77    // be set up before we start sending events since there can be Observation Listener components that require
78    // the Application Context (this is the case for example for the Office Importer Lifecycle Listener).
79  32 StackingComponentEventManager eventManager = new StackingComponentEventManager();
80  32 this.componentManager.setComponentEventManager(eventManager);
81   
82    // Initialize the Environment
83  32 try {
84  32 ServletEnvironment servletEnvironment = this.componentManager.getInstance(Environment.class);
85  32 servletEnvironment.setServletContext(servletContextEvent.getServletContext());
86    } catch (ComponentLookupException e) {
87  0 throw new RuntimeException("Failed to initialize the Servlet Environment", e);
88    }
89   
90    // Initializes the Application Context.
91    // Even though the notion of ApplicationContext has been deprecated in favor of the notion of Environment we
92    // still keep this initialization for backward-compatibility.
93    // TODO: Add an Observation Even that we send when the Environment is initialized so that we can move the code
94    // below in an Event Listener and move it to the legacy module.
95  32 try {
96  32 ServletContainerInitializer containerInitializer =
97    this.componentManager.getInstance(ServletContainerInitializer.class);
98  32 containerInitializer.initializeApplicationContext(servletContextEvent.getServletContext());
99    } catch (ComponentLookupException e) {
100  0 throw new RuntimeException("Failed to initialize the Application Context", e);
101    }
102   
103    // Send an Observation event to signal the XWiki application is started. This allows components who need to do
104    // something on startup to do it.
105  32 ObservationManager observationManager;
106  32 try {
107  32 observationManager = this.componentManager.getInstance(ObservationManager.class);
108    } catch (ComponentLookupException e) {
109  0 throw new RuntimeException("Failed to find the Observation Manager component", e);
110    }
111   
112    // Now that the Application Context is set up, send the Component instance creation events we had stacked up.
113  32 eventManager.setObservationManager(observationManager);
114  32 eventManager.shouldStack(false);
115  32 eventManager.flushEvents();
116   
117    // Indicate to the various components that XWiki is ready
118  32 observationManager.notify(new ApplicationStartedEvent(), this);
119    }
120   
 
121  32 toggle @Override
122    public void contextDestroyed(ServletContextEvent sce)
123    {
124  32 SHUTDOWN_LOGGER.debug("Stopping XWiki...");
125   
126    // It's possible that the Component Manager failed to initialize some of the required components.
127  32 if (this.componentManager != null) {
128    // Send an Observation event to signal the XWiki application is stopped. This allows components who need
129    // to do something on stop to do it.
130  32 try {
131  32 ObservationManager observationManager = this.componentManager.getInstance(ObservationManager.class);
132  32 observationManager.notify(new ApplicationStoppedEvent(), this);
133    } catch (ComponentLookupException e) {
134    // Nothing to do here.
135    // TODO: Log a warning
136    }
137   
138    // Even though the notion of ApplicationContext has been deprecated in favor of the notion of Environment we
139    // still keep this destruction for backward-compatibility.
140    // TODO: Add an Observation Even that we send when the Environment is destroyed so that we can move the code
141    // below in an Event Listener and move it to the legacy module.
142  32 try {
143  32 ApplicationContextListenerManager applicationContextListenerManager =
144    this.componentManager.getInstance(ApplicationContextListenerManager.class);
145  32 Container container = this.componentManager.getInstance(Container.class);
146  32 applicationContextListenerManager.destroyApplicationContext(container.getApplicationContext());
147    } catch (ComponentLookupException ex) {
148    // Nothing to do here.
149    // TODO: Log a warning
150    }
151   
152    // Make sure to dispose all components before leaving
153  32 this.componentManager.dispose();
154    }
155   
156  32 SHUTDOWN_LOGGER.debug("XWiki has been stopped!");
157    }
158    }