001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.context.support; 018 019import javax.servlet.ServletConfig; 020import javax.servlet.ServletContext; 021 022import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 023import org.springframework.context.support.StaticApplicationContext; 024import org.springframework.core.env.ConfigurableEnvironment; 025import org.springframework.core.io.Resource; 026import org.springframework.core.io.support.ResourcePatternResolver; 027import org.springframework.lang.Nullable; 028import org.springframework.ui.context.Theme; 029import org.springframework.ui.context.ThemeSource; 030import org.springframework.ui.context.support.UiApplicationContextUtils; 031import org.springframework.util.Assert; 032import org.springframework.web.context.ConfigurableWebApplicationContext; 033import org.springframework.web.context.ServletConfigAware; 034import org.springframework.web.context.ServletContextAware; 035 036/** 037 * Static {@link org.springframework.web.context.WebApplicationContext} 038 * implementation for testing. Not intended for use in production applications. 039 * 040 * <p>Implements the {@link org.springframework.web.context.ConfigurableWebApplicationContext} 041 * interface to allow for direct replacement of an {@link XmlWebApplicationContext}, 042 * despite not actually supporting external configuration files. 043 * 044 * <p>Interprets resource paths as servlet context resources, i.e. as paths beneath 045 * the web application root. Absolute paths, e.g. for files outside the web app root, 046 * can be accessed via "file:" URLs, as implemented by 047 * {@link org.springframework.core.io.DefaultResourceLoader}. 048 * 049 * <p>In addition to the special beans detected by 050 * {@link org.springframework.context.support.AbstractApplicationContext}, 051 * this class detects a bean of type {@link org.springframework.ui.context.ThemeSource} 052 * in the context, under the special bean name "themeSource". 053 * 054 * @author Rod Johnson 055 * @author Juergen Hoeller 056 * @see org.springframework.ui.context.ThemeSource 057 */ 058public class StaticWebApplicationContext extends StaticApplicationContext 059 implements ConfigurableWebApplicationContext, ThemeSource { 060 061 @Nullable 062 private ServletContext servletContext; 063 064 @Nullable 065 private ServletConfig servletConfig; 066 067 @Nullable 068 private String namespace; 069 070 @Nullable 071 private ThemeSource themeSource; 072 073 074 public StaticWebApplicationContext() { 075 setDisplayName("Root WebApplicationContext"); 076 } 077 078 079 /** 080 * Set the ServletContext that this WebApplicationContext runs in. 081 */ 082 @Override 083 public void setServletContext(@Nullable ServletContext servletContext) { 084 this.servletContext = servletContext; 085 } 086 087 @Override 088 @Nullable 089 public ServletContext getServletContext() { 090 return this.servletContext; 091 } 092 093 @Override 094 public void setServletConfig(@Nullable ServletConfig servletConfig) { 095 this.servletConfig = servletConfig; 096 if (servletConfig != null && this.servletContext == null) { 097 this.servletContext = servletConfig.getServletContext(); 098 } 099 } 100 101 @Override 102 @Nullable 103 public ServletConfig getServletConfig() { 104 return this.servletConfig; 105 } 106 107 @Override 108 public void setNamespace(@Nullable String namespace) { 109 this.namespace = namespace; 110 if (namespace != null) { 111 setDisplayName("WebApplicationContext for namespace '" + namespace + "'"); 112 } 113 } 114 115 @Override 116 @Nullable 117 public String getNamespace() { 118 return this.namespace; 119 } 120 121 /** 122 * The {@link StaticWebApplicationContext} class does not support this method. 123 * @throws UnsupportedOperationException <b>always</b> 124 */ 125 @Override 126 public void setConfigLocation(String configLocation) { 127 throw new UnsupportedOperationException("StaticWebApplicationContext does not support config locations"); 128 } 129 130 /** 131 * The {@link StaticWebApplicationContext} class does not support this method. 132 * @throws UnsupportedOperationException <b>always</b> 133 */ 134 @Override 135 public void setConfigLocations(String... configLocations) { 136 throw new UnsupportedOperationException("StaticWebApplicationContext does not support config locations"); 137 } 138 139 @Override 140 public String[] getConfigLocations() { 141 return null; 142 } 143 144 145 /** 146 * Register request/session scopes, a {@link ServletContextAwareProcessor}, etc. 147 */ 148 @Override 149 protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { 150 beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig)); 151 beanFactory.ignoreDependencyInterface(ServletContextAware.class); 152 beanFactory.ignoreDependencyInterface(ServletConfigAware.class); 153 154 WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext); 155 WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig); 156 } 157 158 /** 159 * This implementation supports file paths beneath the root of the ServletContext. 160 * @see ServletContextResource 161 */ 162 @Override 163 protected Resource getResourceByPath(String path) { 164 Assert.state(this.servletContext != null, "No ServletContext available"); 165 return new ServletContextResource(this.servletContext, path); 166 } 167 168 /** 169 * This implementation supports pattern matching in unexpanded WARs too. 170 * @see ServletContextResourcePatternResolver 171 */ 172 @Override 173 protected ResourcePatternResolver getResourcePatternResolver() { 174 return new ServletContextResourcePatternResolver(this); 175 } 176 177 /** 178 * Create and return a new {@link StandardServletEnvironment}. 179 */ 180 @Override 181 protected ConfigurableEnvironment createEnvironment() { 182 return new StandardServletEnvironment(); 183 } 184 185 /** 186 * Initialize the theme capability. 187 */ 188 @Override 189 protected void onRefresh() { 190 this.themeSource = UiApplicationContextUtils.initThemeSource(this); 191 } 192 193 @Override 194 protected void initPropertySources() { 195 WebApplicationContextUtils.initServletPropertySources(getEnvironment().getPropertySources(), 196 this.servletContext, this.servletConfig); 197 } 198 199 @Override 200 @Nullable 201 public Theme getTheme(String themeName) { 202 Assert.state(this.themeSource != null, "No ThemeSource available"); 203 return this.themeSource.getTheme(themeName); 204 } 205 206}