renamed "contextProperties" attribute to "contextParameters" (matching web.xml naming); "contextParameters" contains Servlet/PortletConfig parameters as well; added default "servletContext" and "servletConfig" environment beans; added default "portletContext" and "portletConfig" environment beans; added default web scope "application", wrapping a ServletContext/PortletContext; MockPortletSession supports destruction of session attributes on invalidation
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -143,12 +143,10 @@ public abstract class AbstractRefreshablePortletApplicationContext extends Abstr
|
||||
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
|
||||
beanFactory.ignoreDependencyInterface(PortletContextAware.class);
|
||||
beanFactory.ignoreDependencyInterface(PortletConfigAware.class);
|
||||
beanFactory.registerResolvableDependency(ServletContext.class, this.servletContext);
|
||||
beanFactory.registerResolvableDependency(PortletContext.class, this.portletContext);
|
||||
beanFactory.registerResolvableDependency(PortletConfig.class, this.portletConfig);
|
||||
|
||||
PortletApplicationContextUtils.registerPortletApplicationScopes(beanFactory);
|
||||
PortletApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.portletContext);
|
||||
PortletApplicationContextUtils.registerPortletApplicationScopes(beanFactory, this.portletContext);
|
||||
PortletApplicationContextUtils.registerEnvironmentBeans(
|
||||
beanFactory, this.servletContext, this.portletContext, this.portletConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -43,6 +43,19 @@ import org.springframework.web.context.WebApplicationContext;
|
||||
public interface ConfigurablePortletApplicationContext
|
||||
extends WebApplicationContext, ConfigurableApplicationContext {
|
||||
|
||||
/**
|
||||
* Name of the PortletContext environment bean in the factory.
|
||||
* @see javax.portlet.PortletContext
|
||||
*/
|
||||
String PORTLET_CONTEXT_BEAN_NAME = "portletContext";
|
||||
|
||||
/**
|
||||
* Name of the PortletConfig environment bean in the factory.
|
||||
* @see javax.portlet.PortletConfig
|
||||
*/
|
||||
String PORTLET_CONFIG_BEAN_NAME = "portletConfig";
|
||||
|
||||
|
||||
/**
|
||||
* Set the PortletContext for this portlet application context.
|
||||
* <p>Does not cause an initialization of the context: refresh needs to be
|
||||
|
||||
@@ -20,9 +20,11 @@ import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.portlet.PortletConfig;
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletSession;
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
@@ -102,14 +104,21 @@ public abstract class PortletApplicationContextUtils {
|
||||
|
||||
|
||||
/**
|
||||
* Register portlet-specific scopes with the given BeanFactory,
|
||||
* as used by the Portlet ApplicationContext.
|
||||
* Register web-specific scopes ("request", "session", "globalSession")
|
||||
* with the given BeanFactory, as used by the Portlet ApplicationContext.
|
||||
* @param beanFactory the BeanFactory to configure
|
||||
* @param pc the PortletContext that we're running within
|
||||
*/
|
||||
static void registerPortletApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
|
||||
static void registerPortletApplicationScopes(ConfigurableListableBeanFactory beanFactory, PortletContext pc) {
|
||||
beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
|
||||
beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope(false));
|
||||
beanFactory.registerScope(WebApplicationContext.SCOPE_GLOBAL_SESSION, new SessionScope(true));
|
||||
if (pc != null) {
|
||||
PortletContextScope appScope = new PortletContextScope(pc);
|
||||
beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
|
||||
// Register as PortletContext attribute, for ContextCleanupListener to detect it.
|
||||
pc.setAttribute(PortletContextScope.class.getName(), appScope);
|
||||
}
|
||||
|
||||
beanFactory.registerResolvableDependency(PortletRequest.class, new ObjectFactory<PortletRequest>() {
|
||||
public PortletRequest getObject() {
|
||||
@@ -132,13 +141,29 @@ public abstract class PortletApplicationContextUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register web-specific environment beans with the given BeanFactory,
|
||||
* as used by the Portlet ApplicationContext.
|
||||
* Register web-specific environment beans ("contextParameters", "contextAttributes")
|
||||
* with the given BeanFactory, as used by the Portlet ApplicationContext.
|
||||
* @param bf the BeanFactory to configure
|
||||
* @param sc the ServletContext that we're running within
|
||||
* @param pc the PortletContext that we're running within
|
||||
* @param config the PortletConfig of the containing Portlet
|
||||
*/
|
||||
static void registerEnvironmentBeans(ConfigurableListableBeanFactory bf, PortletContext pc) {
|
||||
if (!bf.containsBean(WebApplicationContext.CONTEXT_PROPERTIES_BEAN_NAME)) {
|
||||
static void registerEnvironmentBeans(
|
||||
ConfigurableListableBeanFactory bf, ServletContext sc, PortletContext pc, PortletConfig config) {
|
||||
|
||||
if (sc != null && !bf.containsBean(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME)) {
|
||||
bf.registerSingleton(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME, sc);
|
||||
}
|
||||
|
||||
if (pc != null && !bf.containsBean(ConfigurablePortletApplicationContext.PORTLET_CONTEXT_BEAN_NAME)) {
|
||||
bf.registerSingleton(ConfigurablePortletApplicationContext.PORTLET_CONTEXT_BEAN_NAME, pc);
|
||||
}
|
||||
|
||||
if (config != null && !bf.containsBean(ConfigurablePortletApplicationContext.PORTLET_CONFIG_BEAN_NAME)) {
|
||||
bf.registerSingleton(ConfigurablePortletApplicationContext.PORTLET_CONFIG_BEAN_NAME, config);
|
||||
}
|
||||
|
||||
if (!bf.containsBean(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME)) {
|
||||
Map<String, String> parameterMap = new HashMap<String, String>();
|
||||
if (pc != null) {
|
||||
Enumeration paramNameEnum = pc.getInitParameterNames();
|
||||
@@ -147,7 +172,14 @@ public abstract class PortletApplicationContextUtils {
|
||||
parameterMap.put(paramName, pc.getInitParameter(paramName));
|
||||
}
|
||||
}
|
||||
bf.registerSingleton(WebApplicationContext.CONTEXT_PROPERTIES_BEAN_NAME,
|
||||
if (config != null) {
|
||||
Enumeration paramNameEnum = config.getInitParameterNames();
|
||||
while (paramNameEnum.hasMoreElements()) {
|
||||
String paramName = (String) paramNameEnum.nextElement();
|
||||
parameterMap.put(paramName, config.getInitParameter(paramName));
|
||||
}
|
||||
}
|
||||
bf.registerSingleton(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME,
|
||||
Collections.unmodifiableMap(parameterMap));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.portlet.context;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import javax.portlet.PortletContext;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.config.Scope;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link Scope} wrapper for a PortletContext, i.e. for global web application attributes.
|
||||
*
|
||||
* <p>This differs from traditional Spring singletons in that it exposes attributes in the
|
||||
* PortletContext. Those attributes will get destroyed whenever the entire application
|
||||
* shuts down, which might be earlier or later than the shutdown of the containing Spring
|
||||
* ApplicationContext.
|
||||
*
|
||||
* <p>The associated destruction mechanism relies on a
|
||||
* {@link org.springframework.web.context.ContextCleanupListener} being registered in
|
||||
* <code>web.xml</code>. Note that {@link org.springframework.web.context.ContextLoaderListener}
|
||||
* includes ContextCleanupListener's functionality.
|
||||
*
|
||||
* <p>This scope is registered as default scope with key
|
||||
* {@link org.springframework.web.context.WebApplicationContext#SCOPE_APPLICATION "application"}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.web.context.ContextCleanupListener
|
||||
*/
|
||||
public class PortletContextScope implements Scope, DisposableBean {
|
||||
|
||||
private final PortletContext portletContext;
|
||||
|
||||
private final Map<String, Runnable> destructionCallbacks = new LinkedHashMap<String, Runnable>();
|
||||
|
||||
|
||||
/**
|
||||
* Create a new Scope wrapper for the given PortletContext.
|
||||
* @param PortletContext the PortletContext to wrap
|
||||
*/
|
||||
public PortletContextScope(PortletContext portletContext) {
|
||||
Assert.notNull(portletContext, "PortletContext must not be null");
|
||||
this.portletContext = portletContext;
|
||||
}
|
||||
|
||||
|
||||
public Object get(String name, ObjectFactory<?> objectFactory) {
|
||||
Object scopedObject = this.portletContext.getAttribute(name);
|
||||
if (scopedObject == null) {
|
||||
scopedObject = objectFactory.getObject();
|
||||
this.portletContext.setAttribute(name, scopedObject);
|
||||
}
|
||||
return scopedObject;
|
||||
}
|
||||
|
||||
public Object remove(String name) {
|
||||
Object scopedObject = this.portletContext.getAttribute(name);
|
||||
if (scopedObject != null) {
|
||||
this.portletContext.removeAttribute(name);
|
||||
this.destructionCallbacks.remove(name);
|
||||
return scopedObject;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void registerDestructionCallback(String name, Runnable callback) {
|
||||
this.destructionCallbacks.put(name, callback);
|
||||
}
|
||||
|
||||
public Object resolveContextualObject(String key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getConversationId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Invoke all registered destruction callbacks.
|
||||
* To be called on ServletContext shutdown.
|
||||
* @see org.springframework.web.context.ContextCleanupListener
|
||||
*/
|
||||
public void destroy() {
|
||||
for (Runnable runnable : this.destructionCallbacks.values()) {
|
||||
runnable.run();
|
||||
}
|
||||
this.destructionCallbacks.clear();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -139,12 +139,10 @@ public class StaticPortletApplicationContext extends StaticApplicationContext
|
||||
beanFactory.addBeanPostProcessor(new PortletContextAwareProcessor(this.portletContext, this.portletConfig));
|
||||
beanFactory.ignoreDependencyInterface(PortletContextAware.class);
|
||||
beanFactory.ignoreDependencyInterface(PortletConfigAware.class);
|
||||
beanFactory.registerResolvableDependency(ServletContext.class, this.servletContext);
|
||||
beanFactory.registerResolvableDependency(PortletContext.class, this.portletContext);
|
||||
beanFactory.registerResolvableDependency(PortletConfig.class, this.portletConfig);
|
||||
|
||||
PortletApplicationContextUtils.registerPortletApplicationScopes(beanFactory);
|
||||
PortletApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.portletContext);
|
||||
PortletApplicationContextUtils.registerPortletApplicationScopes(beanFactory, this.portletContext);
|
||||
PortletApplicationContextUtils.registerEnvironmentBeans(
|
||||
beanFactory, this.servletContext, this.portletContext, this.portletConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user