001/*
002 * Copyright 2002-2014 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.ui.context.Theme;
028import org.springframework.ui.context.ThemeSource;
029import org.springframework.ui.context.support.UiApplicationContextUtils;
030import org.springframework.web.context.ConfigurableWebApplicationContext;
031import org.springframework.web.context.ServletConfigAware;
032import org.springframework.web.context.ServletContextAware;
033
034/**
035 * Static {@link org.springframework.web.context.WebApplicationContext}
036 * implementation for testing. Not intended for use in production applications.
037 *
038 * <p>Implements the {@link org.springframework.web.context.ConfigurableWebApplicationContext}
039 * interface to allow for direct replacement of an {@link XmlWebApplicationContext},
040 * despite not actually supporting external configuration files.
041 *
042 * <p>Interprets resource paths as servlet context resources, i.e. as paths beneath
043 * the web application root. Absolute paths, e.g. for files outside the web app root,
044 * can be accessed via "file:" URLs, as implemented by
045 * {@link org.springframework.core.io.DefaultResourceLoader}.
046 *
047 * <p>In addition to the special beans detected by
048 * {@link org.springframework.context.support.AbstractApplicationContext},
049 * this class detects a bean of type {@link org.springframework.ui.context.ThemeSource}
050 * in the context, under the special bean name "themeSource".
051 *
052 * @author Rod Johnson
053 * @author Juergen Hoeller
054 * @see org.springframework.ui.context.ThemeSource
055 */
056public class StaticWebApplicationContext extends StaticApplicationContext
057                implements ConfigurableWebApplicationContext, ThemeSource {
058
059        private ServletContext servletContext;
060
061        private ServletConfig servletConfig;
062
063        private String namespace;
064
065        private ThemeSource themeSource;
066
067
068        public StaticWebApplicationContext() {
069                setDisplayName("Root WebApplicationContext");
070        }
071
072
073        /**
074         * Set the ServletContext that this WebApplicationContext runs in.
075         */
076        @Override
077        public void setServletContext(ServletContext servletContext) {
078                this.servletContext = servletContext;
079        }
080
081        @Override
082        public ServletContext getServletContext() {
083                return this.servletContext;
084        }
085
086        @Override
087        public void setServletConfig(ServletConfig servletConfig) {
088                this.servletConfig = servletConfig;
089                if (servletConfig != null && this.servletContext == null) {
090                        this.servletContext = servletConfig.getServletContext();
091                }
092        }
093
094        @Override
095        public ServletConfig getServletConfig() {
096                return this.servletConfig;
097        }
098
099        @Override
100        public void setNamespace(String namespace) {
101                this.namespace = namespace;
102                if (namespace != null) {
103                        setDisplayName("WebApplicationContext for namespace '" + namespace + "'");
104                }
105        }
106
107        @Override
108        public String getNamespace() {
109                return this.namespace;
110        }
111
112        /**
113         * The {@link StaticWebApplicationContext} class does not support this method.
114         * @throws UnsupportedOperationException <b>always</b>
115         */
116        @Override
117        public void setConfigLocation(String configLocation) {
118                if (configLocation != null) {
119                        throw new UnsupportedOperationException("StaticWebApplicationContext does not support config locations");
120                }
121        }
122
123        /**
124         * The {@link StaticWebApplicationContext} class does not support this method.
125         * @throws UnsupportedOperationException <b>always</b>
126         */
127        @Override
128        public void setConfigLocations(String... configLocations) {
129                if (configLocations != null) {
130                        throw new UnsupportedOperationException("StaticWebApplicationContext does not support config locations");
131                }
132        }
133
134        @Override
135        public String[] getConfigLocations() {
136                return null;
137        }
138
139
140        /**
141         * Register request/session scopes, a {@link ServletContextAwareProcessor}, etc.
142         */
143        @Override
144        protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
145                beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
146                beanFactory.ignoreDependencyInterface(ServletContextAware.class);
147                beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
148
149                WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
150                WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
151        }
152
153        /**
154         * This implementation supports file paths beneath the root of the ServletContext.
155         * @see ServletContextResource
156         */
157        @Override
158        protected Resource getResourceByPath(String path) {
159                return new ServletContextResource(this.servletContext, path);
160        }
161
162        /**
163         * This implementation supports pattern matching in unexpanded WARs too.
164         * @see ServletContextResourcePatternResolver
165         */
166        @Override
167        protected ResourcePatternResolver getResourcePatternResolver() {
168                return new ServletContextResourcePatternResolver(this);
169        }
170
171        /**
172         * Create and return a new {@link StandardServletEnvironment}.
173         */
174        @Override
175        protected ConfigurableEnvironment createEnvironment() {
176                return new StandardServletEnvironment();
177        }
178
179        /**
180         * Initialize the theme capability.
181         */
182        @Override
183        protected void onRefresh() {
184                this.themeSource = UiApplicationContextUtils.initThemeSource(this);
185        }
186
187        @Override
188        protected void initPropertySources() {
189                WebApplicationContextUtils.initServletPropertySources(getEnvironment().getPropertySources(),
190                                this.servletContext, this.servletConfig);
191        }
192
193        @Override
194        public Theme getTheme(String themeName) {
195                return this.themeSource.getTheme(themeName);
196        }
197
198}