1. /*
  2. * Copyright 2002-2004 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.web.context.support;
  17. import javax.servlet.ServletContext;
  18. import org.springframework.beans.BeansException;
  19. import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
  20. import org.springframework.context.support.AbstractXmlApplicationContext;
  21. import org.springframework.core.io.Resource;
  22. import org.springframework.ui.context.Theme;
  23. import org.springframework.ui.context.ThemeSource;
  24. import org.springframework.ui.context.support.UiApplicationContextUtils;
  25. import org.springframework.util.StringUtils;
  26. import org.springframework.web.context.ConfigurableWebApplicationContext;
  27. /**
  28. * WebApplicationContext implementation that takes configuration from an XML document.
  29. *
  30. * <p>By default, the configuration will be taken from "/WEB-INF/applicationContext.xml"
  31. * for the root context, and "/WEB-INF/test-servlet.xml" for a context with the namespace
  32. * "test-servlet" (like for a DispatcherServlet instance with the servlet-name "test").
  33. *
  34. * <p>The config location defaults can be overridden via setConfigLocations,
  35. * respectively via the "contextConfigLocation" parameters of ContextLoader and
  36. * FrameworkServlet. Config locations can either denote concrete files like
  37. * "/WEB-INF/context.xml" or Ant-style patterns like "/WEB-INF/*-context.xml"
  38. * (see PathMatcher javadoc for pattern details).
  39. *
  40. * <p>Note: In case of multiple config locations, later bean definitions will
  41. * override ones defined in earlier loaded files. This can be leveraged to
  42. * deliberately override certain bean definitions via an extra XML file.
  43. *
  44. * <p>Interprets resource paths as servlet context resources, i.e. as paths beneath
  45. * the web application root. Absolute paths, e.g. for files outside the web app root,
  46. * can be accessed via "file:" URLs, as implemented by AbstractApplicationContext.
  47. *
  48. * <p>In addition to the special beans detected by AbstractApplicationContext,
  49. * this class detects a ThemeSource bean in the context, with the name
  50. * "themeSource".
  51. *
  52. * @author Rod Johnson
  53. * @author Juergen Hoeller
  54. * @see #setNamespace
  55. * @see #setConfigLocations
  56. * @see #getResourcePatternResolver
  57. * @see org.springframework.web.context.ContextLoader#initWebApplicationContext
  58. * @see org.springframework.web.servlet.FrameworkServlet#initWebApplicationContext
  59. * @see org.springframework.context.support.AbstractApplicationContext#getResource
  60. * @see org.springframework.ui.context.ThemeSource
  61. */
  62. public class XmlWebApplicationContext extends AbstractXmlApplicationContext
  63. implements ConfigurableWebApplicationContext {
  64. /** Default config location for the root context */
  65. public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
  66. /** Default prefix for building a config location for a namespace */
  67. public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";
  68. /** Default suffix for building a config location for a namespace */
  69. public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";
  70. /** Servlet context that this context runs in */
  71. private ServletContext servletContext;
  72. /** Namespace of this context, or null if root */
  73. private String namespace = null;
  74. /** Paths to XML configuration files */
  75. private String[] configLocations;
  76. /** the ThemeSource for this ApplicationContext */
  77. private ThemeSource themeSource;
  78. public void setServletContext(ServletContext servletContext) {
  79. this.servletContext = servletContext;
  80. }
  81. public ServletContext getServletContext() {
  82. return this.servletContext;
  83. }
  84. public void setNamespace(String namespace) {
  85. this.namespace = namespace;
  86. }
  87. protected String getNamespace() {
  88. return this.namespace;
  89. }
  90. public void setConfigLocations(String[] configLocations) {
  91. this.configLocations = configLocations;
  92. }
  93. protected String[] getConfigLocations() {
  94. return this.configLocations;
  95. }
  96. public void refresh() throws BeansException {
  97. if (this.namespace != null) {
  98. setDisplayName("XmlWebApplicationContext for namespace '" + this.namespace + "'");
  99. if (this.configLocations == null || this.configLocations.length == 0) {
  100. this.configLocations = new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + this.namespace +
  101. DEFAULT_CONFIG_LOCATION_SUFFIX};
  102. }
  103. }
  104. else {
  105. setDisplayName("Root XmlWebApplicationContext");
  106. if (this.configLocations == null || this.configLocations.length == 0) {
  107. this.configLocations = new String[] {DEFAULT_CONFIG_LOCATION};
  108. }
  109. }
  110. super.refresh();
  111. }
  112. protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  113. beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
  114. beanFactory.ignoreDependencyType(ServletContext.class);
  115. }
  116. /**
  117. * This implementation supports file paths beneath the root of the web application.
  118. */
  119. protected Resource getResourceByPath(String path) {
  120. return new ServletContextResource(this.servletContext, path);
  121. }
  122. /**
  123. * Initialize the theme capability.
  124. */
  125. protected void onRefresh() {
  126. this.themeSource = UiApplicationContextUtils.initThemeSource(this);
  127. }
  128. public Theme getTheme(String themeName) {
  129. return this.themeSource.getTheme(themeName);
  130. }
  131. /**
  132. * Return diagnostic information.
  133. */
  134. public String toString() {
  135. StringBuffer sb = new StringBuffer(super.toString() + "; ");
  136. sb.append("config locations=[" + StringUtils.arrayToCommaDelimitedString(this.configLocations) + "]; ");
  137. return sb.toString();
  138. }
  139. }