View Javadoc

1   /*
2    * SymmetricDS is an open source database synchronization solution.
3    *   
4    * Copyright (C) Chris Henson <chenson42@users.sourceforge.net>
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 3 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, see
18   * <http://www.gnu.org/licenses/>.
19   */
20  
21  package org.jumpmind.symmetric;
22  
23  import javax.servlet.ServletContext;
24  import javax.servlet.ServletContextEvent;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.springframework.beans.BeanUtils;
29  import org.springframework.beans.BeansException;
30  import org.springframework.context.ApplicationContext;
31  import org.springframework.context.ApplicationContextException;
32  import org.springframework.util.StringUtils;
33  import org.springframework.web.context.ConfigurableWebApplicationContext;
34  import org.springframework.web.context.ContextLoader;
35  import org.springframework.web.context.ContextLoaderListener;
36  import org.springframework.web.context.WebApplicationContext;
37  import org.springframework.web.context.support.WebApplicationContextUtils;
38  
39  /***
40   * This is the standard way to bootstrap Symmetric in a web container. Symmetric
41   * uses Spring's WebApplicationContext for access to symmetric from its
42   * Servlets. This servlet context listener forces the contextConfigLocation for
43   * Spring to be load symmetric.xml. <p/> Developers have the option to subclass
44   * off of this listener and override the createConfigureAndStartEngine() method.
45   */
46  public class SymmetricEngineContextLoaderListener extends ContextLoaderListener {
47  
48      static final String SYMMETRIC_SPRING_LOCATION = "classpath:/symmetric.xml";
49  
50      static final Log logger = LogFactory.getLog(SymmetricEngineContextLoaderListener.class);
51  
52      SymmetricEngine engine = null;
53  
54      public SymmetricEngineContextLoaderListener() {
55      }
56  
57      public SymmetricEngineContextLoaderListener(SymmetricEngine engine) {
58          this.engine = engine;
59      }
60  
61      @Override
62      final public void contextInitialized(ServletContextEvent event) {
63          try {
64              super.contextInitialized(event);
65              ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
66              createConfigureAndStartEngine(ctx);
67          } catch (Exception ex) {
68              logger.error("Failed to initialize the web server context.", ex);
69              if (ex instanceof RuntimeException) {
70                  throw (RuntimeException) ex;
71              } else {
72                  throw new RuntimeException(ex);
73              }
74          }
75      }
76  
77      @Override
78      public void contextDestroyed(ServletContextEvent event) {
79          if (engine != null) {
80              engine.stop();
81              engine = null;
82          }
83      }
84  
85      protected void createConfigureAndStartEngine(ApplicationContext ctx) {
86          if (this.engine == null) {
87              this.engine = new SymmetricEngine(ctx);
88          }
89          engine.start();
90      }
91  
92      @Override
93      protected ContextLoader createContextLoader() {
94          return new ContextLoader() {
95              @SuppressWarnings("unchecked")
96              protected WebApplicationContext createWebApplicationContext(ServletContext servletContext,
97                      ApplicationContext parent) throws BeansException {
98  
99                  Class contextClass = determineContextClass(servletContext);
100                 if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
101                     throw new ApplicationContextException("Custom context class [" + contextClass.getName()
102                             + "] is not of type ConfigurableWebApplicationContext");
103                 }
104 
105                 ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils
106                         .instantiateClass(contextClass);
107                 wac.setParent(parent);
108                 wac.setServletContext(servletContext);
109                 String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
110                 if (configLocation == null) {
111                     configLocation = SYMMETRIC_SPRING_LOCATION;
112                 } else if (!configLocation.contains(SYMMETRIC_SPRING_LOCATION)) {
113                     configLocation = SYMMETRIC_SPRING_LOCATION + "," + configLocation;
114                 }
115                 wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,
116                         ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
117 
118                 wac.refresh();
119                 return wac;
120             }
121         };
122     }
123 
124     public SymmetricEngine getEngine() {
125         return engine;
126     }
127 
128 }