/* * Constellation - An open source and standard compliant SDI * http://www.constellation-sdi.org * * Copyright 2014 Geomatys. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.constellation.admin.conf; import org.constellation.admin.web.filter.CachingHttpHeadersFilter; import org.constellation.admin.web.filter.StaticResourcesProductionFilter; import org.constellation.admin.web.filter.gzip.GZipServletFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.env.Environment; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.AbstractRefreshableWebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.servlet.DispatcherServlet; import javax.servlet.DispatcherType; import javax.servlet.FilterRegistration; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.ServletRegistration; import java.util.EnumSet; import java.util.HashMap; import java.util.Map; /** * Configuration of web application with Servlet 3.0 APIs. */ public class WebConfigurer implements ServletContextListener { private final Logger log = LoggerFactory.getLogger(WebConfigurer.class); @Override public void contextInitialized(ServletContextEvent sce) { ServletContext servletContext = sce.getServletContext(); log.info("Web application configuration"); log.debug("Configuring Spring root application context"); Object rootContextObject = WebApplicationContextUtils.getWebApplicationContext(servletContext); AbstractRefreshableWebApplicationContext rootContext; if(rootContextObject==null) { AnnotationConfigWebApplicationContext annotationRootContext = new AnnotationConfigWebApplicationContext(); annotationRootContext.register(ApplicationConfiguration.class); annotationRootContext.refresh(); servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, annotationRootContext); rootContext = annotationRootContext; } else { if (rootContextObject instanceof AbstractRefreshableWebApplicationContext) { rootContext = (AbstractRefreshableWebApplicationContext) rootContextObject; } else { throw new IllegalStateException("Root web application context not an instance " + "of AbstractRefreshableWebApplicationContext"+ rootContextObject); } } EnumSet<DispatcherType> disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC); initSpring(servletContext, rootContext); // initSpringSecurity(servletContext, disps); if (WebApplicationContextUtils .getRequiredWebApplicationContext(servletContext) .getBean(Environment.class) .acceptsProfiles(Constants.SPRING_PROFILE_PRODUCTION)) { initStaticResourcesProductionFilter(servletContext, disps); initCachingHttpHeadersFilter(servletContext, disps); } initGzipFilter(servletContext, disps); log.debug("Web application fully configured"); } /** * Initializes the GZip filter. */ private void initGzipFilter(ServletContext servletContext, EnumSet<DispatcherType> disps) { log.debug("Registering GZip Filter"); FilterRegistration.Dynamic compressingFilter = servletContext.addFilter("gzipFilter", new GZipServletFilter()); Map<String, String> parameters = new HashMap<String, String>(); compressingFilter.setInitParameters(parameters); compressingFilter.addMappingForUrlPatterns(disps, true, "*.css"); compressingFilter.addMappingForUrlPatterns(disps, true, "*.json"); compressingFilter.addMappingForUrlPatterns(disps, true, "*.html"); compressingFilter.addMappingForUrlPatterns(disps, true, "*.js"); compressingFilter.addMappingForUrlPatterns(disps, true, "*.svg"); //@TODO add gzip filter for cstl-services war and cstl-sdi //compressingFilter.addMappingForUrlPatterns(disps, true, "/app/rest/*"); //compressingFilter.addMappingForUrlPatterns(disps, true, "/metrics/*"); compressingFilter.setAsyncSupported(true); } /** * Initializes the static resources production Filter. */ private void initStaticResourcesProductionFilter(ServletContext servletContext, EnumSet<DispatcherType> disps) { log.debug("Registering static resources production Filter"); FilterRegistration.Dynamic staticResourcesProductionFilter = servletContext.addFilter("staticResourcesProductionFilter", new StaticResourcesProductionFilter()); staticResourcesProductionFilter.addMappingForUrlPatterns(disps, true, "/"); staticResourcesProductionFilter.addMappingForUrlPatterns(disps, true, "/index.html"); staticResourcesProductionFilter.addMappingForUrlPatterns(disps, true, "/img/*"); staticResourcesProductionFilter.addMappingForUrlPatterns(disps, true, "/fonts/*"); staticResourcesProductionFilter.addMappingForUrlPatterns(disps, true, "/js/*"); staticResourcesProductionFilter.addMappingForUrlPatterns(disps, true, "/css/*"); staticResourcesProductionFilter.addMappingForUrlPatterns(disps, true, "/views/*"); staticResourcesProductionFilter.setAsyncSupported(true); } /** * Initializes the cachig HTTP Headers Filter. */ private void initCachingHttpHeadersFilter(ServletContext servletContext, EnumSet<DispatcherType> disps) { log.debug("Registering Cachig HTTP Headers Filter"); FilterRegistration.Dynamic cachingHttpHeadersFilter = servletContext.addFilter("cachingHttpHeadersFilter", new CachingHttpHeadersFilter()); cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/dist/img/*"); cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/dist/fonts/*"); cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/dist/js/*"); cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/dist/css/*"); cachingHttpHeadersFilter.setAsyncSupported(true); } /** * Initializes Spring and Spring MVC. */ private ServletRegistration.Dynamic initSpring(ServletContext servletContext, AbstractRefreshableWebApplicationContext rootContext) { log.debug("Configuring Spring Web application context"); AnnotationConfigWebApplicationContext dispatcherServletConfiguration = new AnnotationConfigWebApplicationContext(); dispatcherServletConfiguration.setParent(rootContext); dispatcherServletConfiguration.register(DispatcherServletConfiguration.class); log.debug("Registering Spring MVC Servlet"); ServletRegistration.Dynamic dispatcherServlet = servletContext.addServlet("dispatcher", new DispatcherServlet( dispatcherServletConfiguration)); dispatcherServlet.addMapping("/app/*"); dispatcherServlet.setLoadOnStartup(1); dispatcherServlet.setAsyncSupported(true); return dispatcherServlet; } @Override public void contextDestroyed(ServletContextEvent sce) { log.info("Destroying Web application"); WebApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext()); AbstractRefreshableWebApplicationContext gwac = (AbstractRefreshableWebApplicationContext) ac; gwac.close(); log.debug("Web application destroyed"); } }