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.portlet.context;
018
019import javax.portlet.PortletConfig;
020import javax.portlet.PortletContext;
021import javax.servlet.ServletContext;
022
023import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
024import org.springframework.context.ApplicationContext;
025import org.springframework.context.support.StaticApplicationContext;
026import org.springframework.core.env.ConfigurableEnvironment;
027import org.springframework.core.io.Resource;
028import org.springframework.core.io.support.ResourcePatternResolver;
029import org.springframework.web.context.WebApplicationContext;
030import org.springframework.web.context.support.ServletContextAwareProcessor;
031
032/**
033 * Static Portlet-based {@link org.springframework.context.ApplicationContext}
034 * implementation for testing. Not intended for use in production applications.
035 *
036 * <p>Implements the
037 * {@link org.springframework.web.portlet.context.ConfigurablePortletApplicationContext}
038 * interface to allow for direct replacement of an {@link XmlPortletApplicationContext},
039 * despite not actually supporting external configuration files.
040 *
041 * <p>Interprets resource paths as portlet context resources, that is, as paths
042 * beneath the portlet application root. Absolute paths, for example for files
043 * outside the portlet app root, can be accessed via "file:" URLs, as implemented
044 * by {@link org.springframework.core.io.DefaultResourceLoader}.
045 *
046 * @author Juergen Hoeller
047 * @author Mark Fisher
048 * @since 2.0
049 */
050public class StaticPortletApplicationContext extends StaticApplicationContext
051                implements ConfigurablePortletApplicationContext {
052
053        private ServletContext servletContext;
054
055        private PortletContext portletContext;
056
057        private PortletConfig portletConfig;
058
059        private String namespace;
060
061
062        public StaticPortletApplicationContext() {
063                setDisplayName("Root Portlet ApplicationContext");
064        }
065
066
067        /**
068         * Return a new {@link StandardPortletEnvironment}
069         */
070        @Override
071        protected ConfigurableEnvironment createEnvironment() {
072                return new StandardPortletEnvironment();
073        }
074
075        /**
076         * {@inheritDoc}
077         * <p>Replace {@code Portlet}- and {@code Servlet}-related property sources.
078         */
079        @Override
080        protected void initPropertySources() {
081                PortletApplicationContextUtils.initPortletPropertySources(getEnvironment().getPropertySources(),
082                                this.servletContext, this.portletContext, this.portletConfig);
083        }
084
085        /**
086         * {@inheritDoc}
087         * <p>The parent {@linkplain #getEnvironment() environment} is
088         * delegated to this (child) context if the parent is a
089         * {@link org.springframework.context.ConfigurableApplicationContext} implementation.
090         * <p>The parent {@linkplain #getServletContext() servlet context} is
091         * delegated to this (child) context if the parent is a {@link WebApplicationContext}
092         * implementation.
093         */
094        @Override
095        public void setParent(ApplicationContext parent) {
096                super.setParent(parent);
097                if (parent instanceof WebApplicationContext) {
098                        this.servletContext = ((WebApplicationContext) parent).getServletContext();
099                }
100        }
101
102        @Override
103        public ServletContext getServletContext() {
104                return this.servletContext;
105        }
106
107        @Override
108        public void setPortletContext(PortletContext portletContext) {
109                this.portletContext = portletContext;
110        }
111
112        @Override
113        public PortletContext getPortletContext() {
114                return this.portletContext;
115        }
116
117        @Override
118        public void setPortletConfig(PortletConfig portletConfig) {
119                this.portletConfig = portletConfig;
120                if (portletConfig != null && this.portletContext == null) {
121                        this.portletContext = portletConfig.getPortletContext();
122                }
123        }
124
125        @Override
126        public PortletConfig getPortletConfig() {
127                return this.portletConfig;
128        }
129
130        @Override
131        public void setNamespace(String namespace) {
132                this.namespace = namespace;
133                if (namespace != null) {
134                        setDisplayName("Portlet ApplicationContext for namespace '" + namespace + "'");
135                }
136        }
137
138        @Override
139        public String getNamespace() {
140                return this.namespace;
141        }
142
143        /**
144         * The {@link StaticPortletApplicationContext} class does not support this method.
145         * @throws UnsupportedOperationException <b>always</b>
146         */
147        @Override
148        public void setConfigLocation(String configLocation) {
149                if (configLocation != null) {
150                        throw new UnsupportedOperationException("StaticPortletApplicationContext does not support config locations");
151                }
152        }
153
154        /**
155         * The {@link StaticPortletApplicationContext} class does not support this method.
156         * @throws UnsupportedOperationException <b>always</b>
157         */
158        @Override
159        public void setConfigLocations(String... configLocations) {
160                if (configLocations != null) {
161                        throw new UnsupportedOperationException("StaticPortletApplicationContext does not support config locations");
162                }
163        }
164
165        @Override
166        public String[] getConfigLocations() {
167                return null;
168        }
169
170
171        /**
172         * Register request/session scopes, a {@link PortletContextAwareProcessor}, etc.
173         */
174        @Override
175        protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
176                beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
177                beanFactory.addBeanPostProcessor(new PortletContextAwareProcessor(this.portletContext, this.portletConfig));
178                beanFactory.ignoreDependencyInterface(PortletContextAware.class);
179                beanFactory.ignoreDependencyInterface(PortletConfigAware.class);
180
181                PortletApplicationContextUtils.registerPortletApplicationScopes(beanFactory, this.portletContext);
182                PortletApplicationContextUtils.registerEnvironmentBeans(
183                                beanFactory, this.servletContext, this.portletContext, this.portletConfig);
184        }
185
186        /**
187         * This implementation supports file paths beneath the root of the PortletContext.
188         * @see PortletContextResource
189         */
190        @Override
191        protected Resource getResourceByPath(String path) {
192                return new PortletContextResource(this.portletContext, path);
193        }
194
195        /**
196         * This implementation supports pattern matching in unexpanded WARs too.
197         * @see PortletContextResourcePatternResolver
198         */
199        @Override
200        protected ResourcePatternResolver getResourcePatternResolver() {
201                return new PortletContextResourcePatternResolver(this);
202        }
203
204}