M1 cut of environment, profiles and property work (SPR-7508)
Decomposed Environment interface into PropertySources, PropertyResolver
objects
Environment interface and implementations are still present, but
simpler.
PropertySources container aggregates PropertySource objects;
PropertyResolver provides search, conversion, placeholder
replacement. Single implementation for now is
PropertySourcesPlaceholderResolver
Renamed EnvironmentAwarePropertyPlaceholderConfigurer to
PropertySourcesPlaceholderConfigurer
<context:property-placeholder/> now registers PSPC by default, else
PPC if systemPropertiesMode* settings are involved
Refined configuration and behavior of default profiles
See Environment interface Javadoc for details
Added Portlet implementations of relevant interfaces:
* DefaultPortletEnvironment
* PortletConfigPropertySource, PortletContextPropertySource
* Integrated each appropriately throughout Portlet app contexts
Added protected 'createEnvironment()' method to AbstractApplicationContext
Subclasses can override at will to supply a custom Environment
implementation. In practice throughout the framework, this is how
Web- and Portlet-related ApplicationContexts override use of the
DefaultEnvironment and swap in DefaultWebEnvironment or
DefaultPortletEnvironment as appropriate.
Introduced "stub-and-replace" behavior for Servlet- and Portlet-based
PropertySource implementations
Allows for early registration and ordering of the stub, then
replacement with actual backing object at refresh() time.
Added AbstractApplicationContext.initPropertySources() method to
support stub-and-replace behavior. Called from within existing
prepareRefresh() method so as to avoid impact with
ApplicationContext implementations that copy and modify AAC's
refresh() method (e.g.: Spring DM).
Added methods to WebApplicationContextUtils and
PortletApplicationContextUtils to support stub-and-replace behavior
Added comprehensive Javadoc for all new or modified types and members
Added XSD documentation for all new or modified elements and attributes
Including nested <beans>, <beans profile="..."/>, and changes for
certain attributes type from xsd:IDREF to xsd:string
Improved fix for detecting non-file based Resources in
PropertiesLoaderSupport (SPR-7547, SPR-7552)
Technically unrelated to environment work, but grouped in with
this changeset for convenience.
Deprecated (removed) context:property-placeholder
'system-properties-mode' attribute from spring-context-3.1.xsd
Functionality is preserved for those using schemas up to and including
spring-context-3.0. For 3.1, system-properties-mode is no longer
supported as it conflicts with the idea of managing a set of property
sources within the context's Environment object. See Javadoc in
PropertyPlaceholderConfigurer, AbstractPropertyPlaceholderConfigurer
and PropertySourcesPlaceholderConfigurer for details.
Introduced CollectionUtils.toArray(Enumeration<E>, A[])
Work items remaining for 3.1 M2:
Consider repackaging PropertySource* types; eliminate internal use
of SystemPropertyUtils and deprecate
Further work on composition of Environment interface; consider
repurposing existing PlaceholderResolver interface to obviate need
for resolve[Required]Placeholder() methods currently in Environment.
Ensure configurability of placeholder prefix, suffix, and value
separator when working against an AbstractPropertyResolver
Add JNDI-based Environment / PropertySource implementatinos
Consider support for @Profile at the @Bean level
Provide consistent logging for the entire property resolution
lifecycle; consider issuing all such messages against a dedicated
logger with a single category.
Add reference documentation to cover the featureset.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2011 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.
|
||||
@@ -33,12 +33,13 @@ import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.PropertyAccessorFactory;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.core.env.DefaultWebEnvironment;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceEditor;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.portlet.context.DefaultPortletEnvironment;
|
||||
import org.springframework.web.portlet.context.PortletContextResourceLoader;
|
||||
|
||||
/**
|
||||
@@ -64,7 +65,7 @@ import org.springframework.web.portlet.context.PortletContextResourceLoader;
|
||||
* @see #processAction
|
||||
* @see FrameworkPortlet
|
||||
*/
|
||||
public abstract class GenericPortletBean extends GenericPortlet {
|
||||
public abstract class GenericPortletBean extends GenericPortlet implements EnvironmentAware {
|
||||
|
||||
/** Logger available to subclasses */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
@@ -75,10 +76,7 @@ public abstract class GenericPortletBean extends GenericPortlet {
|
||||
*/
|
||||
private final Set<String> requiredProperties = new HashSet<String>();
|
||||
|
||||
/**
|
||||
* TODO SPR-7508: think about making this overridable {@link EnvironmentAware}?
|
||||
*/
|
||||
private Environment environment = new DefaultWebEnvironment();
|
||||
private Environment environment = new DefaultPortletEnvironment();
|
||||
|
||||
|
||||
/**
|
||||
@@ -167,6 +165,15 @@ public abstract class GenericPortletBean extends GenericPortlet {
|
||||
protected void initPortletBean() throws PortletException {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>Any environment set here overrides the {@link DefaultPortletEnvironment}
|
||||
* provided by default.
|
||||
*/
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* PropertyValues implementation created from PortletConfig init parameters.
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.AbstractRefreshableConfigApplicationContext;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
@@ -150,6 +151,14 @@ public abstract class AbstractRefreshablePortletApplicationContext extends Abstr
|
||||
beanFactory, this.servletContext, this.portletContext, this.portletConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new {@link DefaultPortletEnvironment}.
|
||||
*/
|
||||
@Override
|
||||
protected ConfigurableEnvironment createEnvironment() {
|
||||
return new DefaultPortletEnvironment();
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation supports file paths beneath the root of the PortletContext.
|
||||
* @see PortletContextResource
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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 javax.portlet.PortletConfig;
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.springframework.core.env.DefaultEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.env.PropertySource.StubPropertySource;
|
||||
import org.springframework.web.context.support.DefaultWebEnvironment;
|
||||
|
||||
/**
|
||||
* {@link Environment} implementation to be used by {@code Servlet}-based web
|
||||
* applications. All Portlet-related {@code ApplicationContext} classes initialize an instance
|
||||
* by default.
|
||||
*
|
||||
* <p>Contributes {@code ServletContext}-, {@code PortletContext}-, and {@code PortletConfig}-based
|
||||
* {@link PropertySource} instances. See the {@link #DefaultPortletEnvironment()} constructor
|
||||
* for details.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
* @see DefaultEnvironment
|
||||
* @see DefaultWebEnvironment
|
||||
*/
|
||||
public class DefaultPortletEnvironment extends DefaultEnvironment {
|
||||
|
||||
/** Portlet context init parameters property source name: {@value} */
|
||||
public static final String PORTLET_CONTEXT_PROPERTY_SOURCE_NAME = "portletContextInitParams";
|
||||
|
||||
/** Portlet config init parameters property source name: {@value} */
|
||||
public static final String PORTLET_CONFIG_PROPERTY_SOURCE_NAME = "portletConfigInitParams";
|
||||
|
||||
/**
|
||||
* Create a new {@code Environment} populated with the property sources contributed by
|
||||
* superclasses as well as:
|
||||
* <ul>
|
||||
* <li>{@value #PORTLET_CONFIG_PROPERTY_SOURCE_NAME}
|
||||
* <li>{@value #PORTLET_CONTEXT_PROPERTY_SOURCE_NAME}
|
||||
* <li>{@linkplain DefaultWebEnvironment#SERVLET_CONTEXT_PROPERTY_SOURCE_NAME "servletContextInitParams"}
|
||||
* </ul>
|
||||
* <p>Properties present in {@value #PORTLET_CONFIG_PROPERTY_SOURCE_NAME} will
|
||||
* take precedence over those in {@value #PORTLET_CONTEXT_PROPERTY_SOURCE_NAME},
|
||||
* which takes precedence over those in .
|
||||
* Properties in either will take precedence over system properties and environment
|
||||
* variables.
|
||||
* <p>The property sources are added as stubs for now, and will be
|
||||
* {@linkplain PortletApplicationContextUtils#initPortletPropertySources fully initialized}
|
||||
* once the actual {@link PortletConfig}, {@link PortletContext}, and {@link ServletContext}
|
||||
* objects are available.
|
||||
* @see DefaultEnvironment#DefaultEnvironment
|
||||
* @see PortletConfigPropertySource
|
||||
* @see PortletContextPropertySource
|
||||
* @see AbstractRefreshablePortletApplicationContext#initPropertySources
|
||||
* @see PortletApplicationContextUtils#initPortletPropertySources
|
||||
*/
|
||||
public DefaultPortletEnvironment() {
|
||||
this.getPropertySources().addFirst(new StubPropertySource(DefaultWebEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME));
|
||||
this.getPropertySources().addFirst(new StubPropertySource(PORTLET_CONTEXT_PROPERTY_SOURCE_NAME));
|
||||
this.getPropertySources().addFirst(new StubPropertySource(PORTLET_CONFIG_PROPERTY_SOURCE_NAME));
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ 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;
|
||||
@@ -30,6 +31,7 @@ import javax.servlet.ServletContext;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
@@ -37,6 +39,7 @@ import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.RequestScope;
|
||||
import org.springframework.web.context.request.SessionScope;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
/**
|
||||
* Convenience methods for retrieving the root WebApplicationContext for a given
|
||||
@@ -184,6 +187,29 @@ public abstract class PortletApplicationContextUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace {@code Servlet}- and {@code Portlet}-based stub property sources
|
||||
* with actual instances populated with the given context and config objects.
|
||||
* @see org.springframework.core.env.PropertySource.StubPropertySource
|
||||
* @see org.springframework.core.env.ConfigurableEnvironment#getPropertySources()
|
||||
* @see org.springframework.web.context.support.WebApplicationContextUtils#initServletPropertySources(MutablePropertySources, ServletContext)
|
||||
*/
|
||||
public static void initPortletPropertySources(MutablePropertySources propertySources, ServletContext servletContext,
|
||||
PortletContext portletContext, PortletConfig portletConfig) {
|
||||
Assert.notNull(propertySources, "propertySources must not be null");
|
||||
|
||||
WebApplicationContextUtils.initServletPropertySources(propertySources, servletContext);
|
||||
|
||||
if(portletContext != null && propertySources.contains(DefaultPortletEnvironment.PORTLET_CONTEXT_PROPERTY_SOURCE_NAME)) {
|
||||
propertySources.replace(DefaultPortletEnvironment.PORTLET_CONTEXT_PROPERTY_SOURCE_NAME,
|
||||
new PortletContextPropertySource(DefaultPortletEnvironment.PORTLET_CONTEXT_PROPERTY_SOURCE_NAME, portletContext));
|
||||
}
|
||||
if(portletConfig != null && propertySources.contains(DefaultPortletEnvironment.PORTLET_CONFIG_PROPERTY_SOURCE_NAME)) {
|
||||
propertySources.replace(DefaultPortletEnvironment.PORTLET_CONFIG_PROPERTY_SOURCE_NAME,
|
||||
new PortletConfigPropertySource(DefaultPortletEnvironment.PORTLET_CONFIG_PROPERTY_SOURCE_NAME, portletConfig));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current RequestAttributes instance as PortletRequestAttributes.
|
||||
* @see RequestContextHolder#currentRequestAttributes()
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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 javax.portlet.PortletConfig;
|
||||
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* {@link PropertySource} that reads init parameters from a {@link PortletConfig} object.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
* @see PortletContextPropertySource
|
||||
*/
|
||||
public class PortletConfigPropertySource extends PropertySource<PortletConfig> {
|
||||
|
||||
public PortletConfigPropertySource(String name, PortletConfig portletConfig) {
|
||||
super(name, portletConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getPropertyNames() {
|
||||
return CollectionUtils.toArray(this.source.getInitParameterNames(), EMPTY_NAMES_ARRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProperty(String name) {
|
||||
return this.source.getInitParameter(name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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 javax.portlet.PortletContext;
|
||||
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* {@link PropertySource} that reads init parameters from a {@link PortletContext} object.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.1
|
||||
* @see PortletConfigPropertySource
|
||||
*/
|
||||
public class PortletContextPropertySource extends PropertySource<PortletContext> {
|
||||
|
||||
public PortletContextPropertySource(String name, PortletContext portletContext) {
|
||||
super(name, portletContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getPropertyNames() {
|
||||
return CollectionUtils.toArray(this.source.getInitParameterNames(), EMPTY_NAMES_ARRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProperty(String name) {
|
||||
return this.source.getInitParameter(name);
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ import javax.servlet.ServletContext;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.core.env.DefaultWebEnvironment;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
@@ -61,10 +61,29 @@ public class StaticPortletApplicationContext extends StaticApplicationContext
|
||||
|
||||
public StaticPortletApplicationContext() {
|
||||
setDisplayName("Root Portlet ApplicationContext");
|
||||
setEnvironment(new DefaultWebEnvironment()); // TODO SPR-7508: create custom portlet env?
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a new {@link DefaultPortletEnvironment}
|
||||
*/
|
||||
@Override
|
||||
protected ConfigurableEnvironment createEnvironment() {
|
||||
return new DefaultPortletEnvironment();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>Replace {@code Portlet}- and {@code Servlet}-related property sources.
|
||||
*/
|
||||
@Override
|
||||
protected void initPropertySources() {
|
||||
super.initPropertySources();
|
||||
PortletApplicationContextUtils.initPortletPropertySources(
|
||||
this.getEnvironment().getPropertySources(), this.servletContext,
|
||||
this.portletContext, this.portletConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParent(ApplicationContext parent) {
|
||||
super.setParent(parent);
|
||||
|
||||
Reference in New Issue
Block a user