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}