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 javax.portlet.PortletConfig;
020: import javax.portlet.PortletContext;
021: import javax.servlet.ServletContext;
022:
023: import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
024: import org.springframework.context.ApplicationContext;
025: import org.springframework.context.support.AbstractRefreshableApplicationContext;
026: import org.springframework.core.io.Resource;
027: import org.springframework.core.io.support.ResourcePatternResolver;
028: import org.springframework.util.ObjectUtils;
029: import org.springframework.web.context.ServletContextAware;
030: import org.springframework.web.context.WebApplicationContext;
031: import org.springframework.web.context.request.RequestScope;
032: import org.springframework.web.context.request.SessionScope;
033: import org.springframework.web.context.support.ServletContextAwareProcessor;
034:
035: /**
036: * {@link org.springframework.context.support.AbstractRefreshableApplicationContext}
037: * subclass which implements the {@link ConfigurablePortletApplicationContext}
038: * interface for portlet environments. Provides a "configLocations" property,
039: * to be populated through the ConfigurablePortletApplicationContext interface
040: * on portlet application startup.
041: *
042: * <p>This class is as easy to subclass as AbstractRefreshableApplicationContext:
043: * All you need to implements is the {@link #loadBeanDefinitions} method;
044: * see the superclass javadoc for details. Note that implementations are supposed
045: * to load bean definitions from the files specified by the locations returned
046: * by the {@link #getConfigLocations} method.
047: *
048: * <p>Interprets resource paths as servlet context resources, i.e. as paths beneath
049: * the web application root. Absolute paths, e.g. for files outside the web app root,
050: * can be accessed via "file:" URLs, as implemented by
051: * {@link org.springframework.core.io.DefaultResourceLoader}.
052: *
053: * <p><b>This is the portlet context to be subclassed for a different bean definition format.</b>
054: * Such a context implementation can be specified as "contextClass" init-param
055: * for FrameworkPortlet, replacing the default {@link XmlPortletApplicationContext}.
056: * It will then automatically receive the "contextConfigLocation" init-param.
057: *
058: * <p>Note that Portlet-based context implementations are generally supposed
059: * to configure themselves based on the configuration received through the
060: * {@link ConfigurablePortletApplicationContext} interface. In contrast, a standalone
061: * application context might allow for configuration in custom startup code
062: * (for example, {@link org.springframework.context.support.GenericApplicationContext}).
063: *
064: * @author Juergen Hoeller
065: * @author John A. Lewis
066: * @since 2.0
067: * @see #loadBeanDefinitions
068: * @see org.springframework.web.portlet.context.ConfigurablePortletApplicationContext#setConfigLocations
069: * @see XmlPortletApplicationContext
070: */
071: public abstract class AbstractRefreshablePortletApplicationContext
072: extends AbstractRefreshableApplicationContext implements
073: WebApplicationContext, ConfigurablePortletApplicationContext {
074:
075: /** Servlet context that this context runs in */
076: private ServletContext servletContext;
077:
078: /** Portlet context that this context runs in */
079: private PortletContext portletContext;
080:
081: /** Portlet config that this context runs in */
082: private PortletConfig portletConfig;
083:
084: /** Namespace of this context, or null if root */
085: private String namespace;
086:
087: /** Paths to XML configuration files */
088: private String[] configLocations;
089:
090: public AbstractRefreshablePortletApplicationContext() {
091: setDisplayName("Root PortletApplicationContext");
092: }
093:
094: public void setParent(ApplicationContext parent) {
095: super .setParent(parent);
096: if (parent instanceof WebApplicationContext) {
097: this .servletContext = ((WebApplicationContext) parent)
098: .getServletContext();
099: }
100: }
101:
102: public ServletContext getServletContext() {
103: return this .servletContext;
104: }
105:
106: public void setPortletContext(PortletContext portletContext) {
107: this .portletContext = portletContext;
108: }
109:
110: public PortletContext getPortletContext() {
111: return this .portletContext;
112: }
113:
114: public void setPortletConfig(PortletConfig portletConfig) {
115: this .portletConfig = portletConfig;
116: if (portletConfig != null && this .portletContext == null) {
117: this .portletContext = portletConfig.getPortletContext();
118: }
119: }
120:
121: public PortletConfig getPortletConfig() {
122: return this .portletConfig;
123: }
124:
125: public void setNamespace(String namespace) {
126: this .namespace = namespace;
127: if (namespace != null) {
128: setDisplayName("PortletApplicationContext for namespace '"
129: + namespace + "'");
130: }
131: }
132:
133: public String getNamespace() {
134: return this .namespace;
135: }
136:
137: public void setConfigLocations(String[] configLocations) {
138: this .configLocations = configLocations;
139: }
140:
141: public String[] getConfigLocations() {
142: return (!ObjectUtils.isEmpty(this .configLocations) ? this .configLocations
143: : getDefaultConfigLocations());
144: }
145:
146: /**
147: * Return the default config locations to use, for the case where no
148: * explicit config locations have been specified.
149: * <p>The default implementation returns <code>null</code>,
150: * requiring explicit config locations.
151: * @see #setConfigLocations
152: */
153: protected String[] getDefaultConfigLocations() {
154: return null;
155: }
156:
157: /**
158: * Register request/session scopes, a {@link PortletContextAwareProcessor}, etc.
159: */
160: protected void postProcessBeanFactory(
161: ConfigurableListableBeanFactory beanFactory) {
162: beanFactory.registerScope(SCOPE_REQUEST, new RequestScope());
163: beanFactory.registerScope(SCOPE_SESSION,
164: new SessionScope(false));
165: beanFactory.registerScope(SCOPE_GLOBAL_SESSION,
166: new SessionScope(true));
167:
168: beanFactory
169: .addBeanPostProcessor(new ServletContextAwareProcessor(
170: this .servletContext));
171: beanFactory
172: .addBeanPostProcessor(new PortletContextAwareProcessor(
173: this .portletContext, this .portletConfig));
174: beanFactory
175: .ignoreDependencyInterface(ServletContextAware.class);
176: beanFactory
177: .ignoreDependencyInterface(PortletContextAware.class);
178: beanFactory.ignoreDependencyInterface(PortletConfigAware.class);
179: }
180:
181: /**
182: * This implementation supports file paths beneath the root of the PortletContext.
183: * @see PortletContextResource
184: */
185: protected Resource getResourceByPath(String path) {
186: return new PortletContextResource(this .portletContext, path);
187: }
188:
189: /**
190: * This implementation supports pattern matching in unexpanded WARs too.
191: * @see PortletContextResourcePatternResolver
192: */
193: protected ResourcePatternResolver getResourcePatternResolver() {
194: return new PortletContextResourcePatternResolver(this);
195: }
196:
197: }
|