001: /*
002: * Copyright 2002-2007 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: * http://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:
017: package org.springframework.web.portlet.context;
018:
019: import java.io.IOException;
020:
021: import org.springframework.beans.BeansException;
022: import org.springframework.beans.factory.support.DefaultListableBeanFactory;
023: import org.springframework.beans.factory.xml.ResourceEntityResolver;
024: import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
025:
026: /**
027: * Portlet-based {@link org.springframework.web.context.WebApplicationContext}
028: * implementation which takes its configuration from XML documents, understood
029: * by an {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader}.
030: * This is essentially the equivalent of
031: * {@link org.springframework.context.support.AbstractXmlApplicationContext}
032: * for a portlet environment.
033: *
034: * <p>By default, the configuration will be taken from "/WEB-INF/applicationContext.xml"
035: * for the root context, and "/WEB-INF/test-portlet.xml" for a context with the namespace
036: * "test-portlet" (like for a DispatcherPortlet instance with the portlet-name "test").
037: *
038: * <p>The config location defaults can be overridden via the "contextConfigLocation"
039: * portlet init-param of {@link org.springframework.web.portlet.FrameworkPortlet}.
040: * Config locations can either denote concrete files like "/WEB-INF/context.xml"
041: * or Ant-style patterns like "/WEB-INF/*-context.xml" (see
042: * {@link org.springframework.util.PathMatcher} javadoc for pattern details).
043: *
044: * <p>Note: In case of multiple config locations, later bean definitions will
045: * override ones defined in earlier loaded files. This can be leveraged to
046: * deliberately override certain bean definitions via an extra XML file.
047: *
048: * <p><b>For a Portlet-based context that reads in a different bean definition format,
049: * create an analogous subclass of {@link AbstractRefreshablePortletApplicationContext}.</b>
050: * Such a context implementation can be specified as "contextClass" init-param
051: * for a FrameworkPortlet instance.
052: *
053: * @author Juergen Hoeller
054: * @author John A. Lewis
055: * @since 2.0
056: * @see #setNamespace
057: * @see #setConfigLocations
058: * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
059: * @see org.springframework.web.portlet.FrameworkPortlet#initPortletApplicationContext
060: */
061: public class XmlPortletApplicationContext extends
062: AbstractRefreshablePortletApplicationContext {
063:
064: /** Default config location for the root context */
065: public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
066:
067: /** Default prefix for building a config location for a namespace */
068: public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";
069:
070: /** Default suffix for building a config location for a namespace */
071: public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";
072:
073: /**
074: * Loads the bean definitions via an XmlBeanDefinitionReader.
075: * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
076: * @see #initBeanDefinitionReader
077: * @see #loadBeanDefinitions
078: */
079: protected void loadBeanDefinitions(
080: DefaultListableBeanFactory beanFactory) throws IOException {
081: // Create a new XmlBeanDefinitionReader for the given BeanFactory.
082: XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(
083: beanFactory);
084:
085: // Configure the bean definition reader with this context's
086: // resource loading environment.
087: beanDefinitionReader.setResourceLoader(this );
088: beanDefinitionReader
089: .setEntityResolver(new ResourceEntityResolver(this ));
090:
091: // Allow a subclass to provide custom initialization of the reader,
092: // then proceed with actually loading the bean definitions.
093: initBeanDefinitionReader(beanDefinitionReader);
094: loadBeanDefinitions(beanDefinitionReader);
095: }
096:
097: /**
098: * Initialize the bean definition reader used for loading the bean
099: * definitions of this context. Default implementation is empty.
100: * <p>Can be overridden in subclasses, e.g. for turning off XML validation
101: * or using a different XmlBeanDefinitionParser implementation.
102: * @param beanDefinitionReader the bean definition reader used by this context
103: * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader#setValidationMode
104: * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader#setDocumentReaderClass
105: */
106: protected void initBeanDefinitionReader(
107: XmlBeanDefinitionReader beanDefinitionReader) {
108: }
109:
110: /**
111: * Load the bean definitions with the given XmlBeanDefinitionReader.
112: * <p>The lifecycle of the bean factory is handled by the refreshBeanFactory method;
113: * therefore this method is just supposed to load and/or register bean definitions.
114: * <p>Delegates to a ResourcePatternResolver for resolving location patterns
115: * into Resource instances.
116: * @throws org.springframework.beans.BeansException in case of bean registration errors
117: * @throws java.io.IOException if the required XML document isn't found
118: * @see #refreshBeanFactory
119: * @see #getConfigLocations
120: * @see #getResources
121: * @see #getResourcePatternResolver
122: */
123: protected void loadBeanDefinitions(XmlBeanDefinitionReader reader)
124: throws BeansException, IOException {
125: String[] configLocations = getConfigLocations();
126: if (configLocations != null) {
127: for (int i = 0; i < configLocations.length; i++) {
128: reader.loadBeanDefinitions(configLocations[i]);
129: }
130: }
131: }
132:
133: /**
134: * The default location for the root context is "/WEB-INF/applicationContext.xml",
135: * and "/WEB-INF/test-portlet.xml" for a context with the namespace "test-portlet"
136: * (like for a DispatcherPortlet instance with the portlet-name "test").
137: */
138: protected String[] getDefaultConfigLocations() {
139: if (getNamespace() != null) {
140: return new String[] { DEFAULT_CONFIG_LOCATION_PREFIX
141: + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX };
142: } else {
143: return new String[] { DEFAULT_CONFIG_LOCATION };
144: }
145: }
146:
147: }
|