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.servlet.view;
  17. import java.util.Locale;
  18. import org.springframework.beans.BeansException;
  19. import org.springframework.beans.factory.BeanFactory;
  20. import org.springframework.beans.factory.DisposableBean;
  21. import org.springframework.beans.factory.NoSuchBeanDefinitionException;
  22. import org.springframework.beans.factory.config.ConfigurableBeanFactory;
  23. import org.springframework.beans.factory.xml.XmlBeanFactory;
  24. import org.springframework.core.Ordered;
  25. import org.springframework.core.io.Resource;
  26. import org.springframework.core.io.ResourceEditor;
  27. import org.springframework.web.servlet.View;
  28. /**
  29. * Implementation of ViewResolver that uses bean definitions in an
  30. * XML file, specified by resource location. The file will typically
  31. * be located in the WEB-INF directory; default is "/WEB-INF/views.xml".
  32. *
  33. * <p>This ViewResolver does not support internationalization.
  34. * Consider ResourceBundleViewResolver if you need to apply
  35. * different view resources per locale.
  36. *
  37. * <p>Note: This ViewResolver implements the Ordered interface to allow for
  38. * flexible participation in ViewResolver chaining. For example, some special
  39. * views could be defined via this ViewResolver (giving it 0 as "order" value),
  40. * while all remaining views could be resolved by a UrlBasedViewResolver.
  41. *
  42. * @author Juergen Hoeller
  43. * @since 18.06.2003
  44. * @see org.springframework.context.ApplicationContext#getResource
  45. * @see ResourceBundleViewResolver
  46. * @see UrlBasedViewResolver
  47. */
  48. public class XmlViewResolver extends AbstractCachingViewResolver implements Ordered, DisposableBean {
  49. /** Default if no other location is supplied */
  50. public final static String DEFAULT_LOCATION = "/WEB-INF/views.xml";
  51. private int order = Integer.MAX_VALUE; // default: same as non-Ordered
  52. private Resource location;
  53. private ConfigurableBeanFactory cachedFactory;
  54. public void setOrder(int order) {
  55. this.order = order;
  56. }
  57. public int getOrder() {
  58. return order;
  59. }
  60. /**
  61. * Set the location of the XML file that defines the view beans.
  62. * <p>The default is "/WEB-INF/views.xml".
  63. * @param location the location of the XML file.
  64. */
  65. public void setLocation(Resource location) {
  66. this.location = location;
  67. }
  68. /**
  69. * Pre-initialize the factory from the XML file.
  70. * Only effective if caching is enabled.
  71. */
  72. protected void initApplicationContext() throws BeansException {
  73. if (isCache()) {
  74. initFactory();
  75. }
  76. }
  77. /**
  78. * This implementation returns just the view name,
  79. * as XmlViewResolver doesn't support localized resolution.
  80. */
  81. protected String getCacheKey(String viewName, Locale locale) {
  82. return viewName;
  83. }
  84. protected View loadView(String viewName, Locale locale) throws BeansException {
  85. try {
  86. return (View) initFactory().getBean(viewName, View.class);
  87. }
  88. catch (NoSuchBeanDefinitionException ex) {
  89. // to allow for ViewResolver chaining
  90. return null;
  91. }
  92. }
  93. /**
  94. * Initialize the BeanFactory from the XML file.
  95. * Synchronized because of access by parallel threads.
  96. * @throws BeansException in case of initialization errors
  97. */
  98. protected synchronized BeanFactory initFactory() throws BeansException {
  99. if (this.cachedFactory != null) {
  100. return this.cachedFactory;
  101. }
  102. Resource actualLocation = this.location;
  103. if (actualLocation == null) {
  104. actualLocation = getApplicationContext().getResource(DEFAULT_LOCATION);
  105. }
  106. XmlBeanFactory factory = new XmlBeanFactory(actualLocation, getApplicationContext());
  107. factory.registerCustomEditor(Resource.class, new ResourceEditor(getApplicationContext()));
  108. if (isCache()) {
  109. factory.preInstantiateSingletons();
  110. this.cachedFactory = factory;
  111. }
  112. return factory;
  113. }
  114. public void destroy() throws BeansException {
  115. if (this.cachedFactory != null) {
  116. this.cachedFactory.destroySingletons();
  117. }
  118. }
  119. }