Browse Source
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.
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@3839 50f2f4bb-b051-0410-bef5-90022cba6387
pull/1/head
111 changed files with 3441 additions and 1717 deletions
@ -1,15 +1,17 @@
@@ -1,15 +1,17 @@
|
||||
target |
||||
*.java.hsp |
||||
*.sonarj |
||||
*.sw* |
||||
.DS_Store |
||||
.settings |
||||
.springBeans |
||||
bin |
||||
build.sh |
||||
integration-repo |
||||
ivy-cache |
||||
jmx.log |
||||
.springBeans |
||||
.settings |
||||
.DS_Store |
||||
*.sw* |
||||
org.springframework.test/test-output/ |
||||
org.springframework.jdbc/derby.log |
||||
org.springframework.spring-parent/.classpath |
||||
org.springframework.spring-parent/.project |
||||
build.sh |
||||
org.springframework.jdbc/derby.log |
||||
org.springframework.test/test-output/ |
||||
spring-build |
||||
target |
||||
|
||||
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
my.name=foo |
||||
@ -1,10 +1,10 @@
@@ -1,10 +1,10 @@
|
||||
|
||||
/** |
||||
* |
||||
* |
||||
* Annotation support for the Application Context, including JSR-250 "common" |
||||
* annotations, component-scanning, and Java-based metadata for creating |
||||
* Spring-managed objects. |
||||
* |
||||
* |
||||
*/ |
||||
package org.springframework.context.annotation; |
||||
|
||||
|
||||
@ -1,115 +0,0 @@
@@ -1,115 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2010 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.context.support; |
||||
|
||||
import java.util.LinkedList; |
||||
import java.util.Properties; |
||||
|
||||
import org.springframework.beans.BeansException; |
||||
import org.springframework.beans.factory.config.AbstractPropertyPlaceholderConfigurer; |
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; |
||||
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; |
||||
import org.springframework.context.EnvironmentAware; |
||||
import org.springframework.core.env.AbstractEnvironment; |
||||
import org.springframework.core.env.ConfigurableEnvironment; |
||||
import org.springframework.core.env.Environment; |
||||
import org.springframework.core.env.PropertiesPropertySource; |
||||
import org.springframework.core.env.PropertySource; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver; |
||||
|
||||
|
||||
/** |
||||
* TODO SPR-7508: document |
||||
* |
||||
* Local properties are added as a property source in any case. Precedence is based |
||||
* on the value of the {@link #setLocalOverride(boolean) localOverride} property. |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
* @see PropertyPlaceholderConfigurer |
||||
* @see EnvironmentAwarePropertyOverrideConfigurer |
||||
*/ |
||||
public class EnvironmentAwarePropertyPlaceholderConfigurer |
||||
extends AbstractPropertyPlaceholderConfigurer implements EnvironmentAware { |
||||
|
||||
private ConfigurableEnvironment environment; |
||||
private Environment wrappedEnvironment; |
||||
|
||||
public void setEnvironment(Environment environment) { |
||||
this.wrappedEnvironment = environment; |
||||
} |
||||
|
||||
@Override |
||||
protected PlaceholderResolver getPlaceholderResolver(Properties props) { |
||||
return new PlaceholderResolver() { |
||||
public String resolvePlaceholder(String placeholderName) { |
||||
return environment.getProperty(placeholderName); |
||||
} |
||||
}; |
||||
} |
||||
|
||||
@Override |
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { |
||||
Assert.notNull(this.wrappedEnvironment, "Environment must not be null. Did you call setEnvironment()?"); |
||||
environment = new AbstractEnvironment() { }; |
||||
|
||||
LinkedList<PropertySource<?>> propertySources = environment.getPropertySources(); |
||||
EnvironmentPropertySource environmentPropertySource = |
||||
new EnvironmentPropertySource("wrappedEnvironment", wrappedEnvironment); |
||||
|
||||
if (!this.localOverride) { |
||||
propertySources.add(environmentPropertySource); |
||||
} |
||||
|
||||
if (this.localProperties != null) { |
||||
int cx=0; |
||||
for (Properties localProps : this.localProperties) { |
||||
propertySources.add(new PropertiesPropertySource("localProperties"+cx++, localProps)); |
||||
} |
||||
} |
||||
|
||||
if (this.localOverride) { |
||||
propertySources.add(environmentPropertySource); |
||||
} |
||||
|
||||
super.postProcessBeanFactory(beanFactory); |
||||
} |
||||
|
||||
static class EnvironmentPropertySource extends PropertySource<Environment> { |
||||
|
||||
public EnvironmentPropertySource(String name, Environment source) { |
||||
super(name, source); |
||||
} |
||||
|
||||
@Override |
||||
public boolean containsProperty(String key) { |
||||
return source.containsProperty(key); |
||||
} |
||||
|
||||
@Override |
||||
public String getProperty(String key) { |
||||
return source.getProperty(key); |
||||
} |
||||
|
||||
@Override |
||||
public int size() { |
||||
// TODO Auto-generated method stub
|
||||
return source.getPropertyCount(); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,134 @@
@@ -0,0 +1,134 @@
|
||||
/* |
||||
* 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.context.support; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.Properties; |
||||
|
||||
import org.springframework.beans.BeansException; |
||||
import org.springframework.beans.factory.BeanInitializationException; |
||||
import org.springframework.beans.factory.config.AbstractPropertyPlaceholderConfigurer; |
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; |
||||
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; |
||||
import org.springframework.context.EnvironmentAware; |
||||
import org.springframework.core.env.Environment; |
||||
import org.springframework.core.env.MutablePropertySources; |
||||
import org.springframework.core.env.PropertiesPropertySource; |
||||
import org.springframework.core.env.PropertyResolver; |
||||
import org.springframework.core.env.PropertySource; |
||||
import org.springframework.core.env.PropertySources; |
||||
import org.springframework.core.env.PropertySourcesPropertyResolver; |
||||
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver; |
||||
|
||||
/** |
||||
* Specialization of {@link AbstractPropertyPlaceholderConfigurer} |
||||
* |
||||
* <p>Local properties are added as a property source in any case. Precedence is based |
||||
* on the value of the {@link #setLocalOverride localOverride} property. |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
* @see AbstractPropertyPlaceholderConfigurer |
||||
* @see PropertyPlaceholderConfigurer |
||||
*/ |
||||
public class PropertySourcesPlaceholderConfigurer extends AbstractPropertyPlaceholderConfigurer |
||||
implements EnvironmentAware { |
||||
|
||||
/** |
||||
* {@value} is the name given to the {@link PropertySource} for the set of |
||||
* {@linkplain #mergeProperties() merged properties} supplied to this configurer. |
||||
*/ |
||||
public static final String LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME = "localProperties"; |
||||
|
||||
private MutablePropertySources propertySources; |
||||
|
||||
private PropertyResolver propertyResolver; |
||||
|
||||
private Environment environment; |
||||
|
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
* <p>{@code PropertySources} from this environment will be searched when replacing ${...} placeholders |
||||
* @see #setPropertySources |
||||
* @see #postProcessBeanFactory |
||||
*/ |
||||
public void setEnvironment(Environment environment) { |
||||
this.environment = environment; |
||||
} |
||||
|
||||
/** |
||||
* Customize the set of {@link PropertySources} to be used by this configurer. |
||||
* Setting this property indicates that environment property sources and local |
||||
* properties should be ignored. |
||||
* @see #postProcessBeanFactory |
||||
*/ |
||||
public void setPropertySources(PropertySources propertySources) { |
||||
this.propertySources = new MutablePropertySources(propertySources); |
||||
} |
||||
|
||||
@Override |
||||
protected PlaceholderResolver getPlaceholderResolver(Properties props) { |
||||
return new PlaceholderResolver() { |
||||
public String resolvePlaceholder(String placeholderName) { |
||||
return propertyResolver.getProperty(placeholderName); |
||||
} |
||||
}; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
* <p>Processing occurs by replacing ${...} placeholders in bean definitions by resolving each |
||||
* against this configurer's set of {@link PropertySources}, which includes: |
||||
* <ul> |
||||
* <li>all {@linkplain Environment#getPropertySources environment property sources}, if an |
||||
* {@code Environment} {@linkplain #setEnvironment is present} |
||||
* <li>{@linkplain #mergeProperties merged local properties}, if {@linkplain #setLocation any} |
||||
* {@linkplain #setLocations have} {@linkplain #setProperties been} |
||||
* {@linkplain #setPropertiesArray specified} |
||||
* <li>any property sources set by calling {@link #setPropertySources} |
||||
* </ul> |
||||
* <p>If {@link #setPropertySources} is called, <strong>environment and local properties will be |
||||
* ignored</strong>. This method is designed to give the user fine-grained control over property |
||||
* sources, and once set, the configurer makes no assumptions about adding additional sources. |
||||
*/ |
||||
@Override |
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { |
||||
if (this.propertySources == null) { |
||||
this.propertySources = new MutablePropertySources(); |
||||
if (this.environment != null) { |
||||
this.propertySources.addAll(this.environment.getPropertySources()); |
||||
} |
||||
try { |
||||
PropertySource<?> localPropertySource = |
||||
new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, this.mergeProperties()); |
||||
if (this.localOverride) { |
||||
this.propertySources.addFirst(localPropertySource); |
||||
} else { |
||||
this.propertySources.addLast(localPropertySource); |
||||
} |
||||
} |
||||
catch (IOException ex) { |
||||
throw new BeanInitializationException("Could not load properties", ex); |
||||
} |
||||
} |
||||
|
||||
this.propertyResolver = new PropertySourcesPropertyResolver(this.propertySources); |
||||
this.processProperties(beanFactory, this.propertyResolver.asProperties()); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
/* |
||||
* Copyright 2002-2010 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 example.profilescan; |
||||
|
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
import org.springframework.context.annotation.Profile; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Target(ElementType.TYPE) |
||||
@Profile(DevComponent.PROFILE_NAME) |
||||
@Component |
||||
public @interface DevComponent { |
||||
|
||||
public static final String PROFILE_NAME = "dev"; |
||||
|
||||
String value() default ""; |
||||
|
||||
} |
||||
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
/* |
||||
* Copyright 2002-2010 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 example.profilescan; |
||||
|
||||
|
||||
@DevComponent(ProfileMetaAnnotatedComponent.BEAN_NAME) |
||||
public class ProfileMetaAnnotatedComponent { |
||||
|
||||
public static final String BEAN_NAME = "profileMetaAnnotatedComponent"; |
||||
|
||||
} |
||||
@ -1,91 +0,0 @@
@@ -1,91 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2010 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.context.support; |
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo; |
||||
import static org.junit.Assert.assertThat; |
||||
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition; |
||||
|
||||
import org.junit.Test; |
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory; |
||||
import org.springframework.mock.env.MockEnvironment; |
||||
|
||||
import test.beans.TestBean; |
||||
|
||||
/** |
||||
* Unit tests for {@link EnvironmentAwarePropertyPlaceholderConfigurer}. |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
* @see EnvironmentAwarePropertyPlaceholderConfigurerTests |
||||
*/ |
||||
public class EnvironmentAwarePropertyPlaceholderConfigurerTests { |
||||
|
||||
@Test(expected=IllegalArgumentException.class) |
||||
public void environmentNotNull() { |
||||
new EnvironmentAwarePropertyPlaceholderConfigurer().postProcessBeanFactory(new DefaultListableBeanFactory()); |
||||
} |
||||
|
||||
@Test |
||||
public void localPropertiesOverrideFalse() { |
||||
localPropertiesOverride(false); |
||||
} |
||||
|
||||
@Test |
||||
public void localPropertiesOverrideTrue() { |
||||
localPropertiesOverride(true); |
||||
} |
||||
|
||||
private void localPropertiesOverride(boolean override) { |
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); |
||||
bf.registerBeanDefinition("testBean", |
||||
genericBeanDefinition(TestBean.class) |
||||
.addPropertyValue("name", "${foo}") |
||||
.getBeanDefinition()); |
||||
|
||||
EnvironmentAwarePropertyPlaceholderConfigurer ppc = new EnvironmentAwarePropertyPlaceholderConfigurer(); |
||||
|
||||
ppc.setLocalOverride(override); |
||||
ppc.setProperties(MockEnvironment.withProperty("foo", "local").asProperties()); |
||||
ppc.setEnvironment(MockEnvironment.withProperty("foo", "enclosing")); |
||||
ppc.postProcessBeanFactory(bf); |
||||
if (override) { |
||||
assertThat(bf.getBean(TestBean.class).getName(), equalTo("local")); |
||||
} else { |
||||
assertThat(bf.getBean(TestBean.class).getName(), equalTo("enclosing")); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void simpleReplacement() { |
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); |
||||
bf.registerBeanDefinition("testBean", |
||||
genericBeanDefinition(TestBean.class) |
||||
.addPropertyValue("name", "${my.name}") |
||||
.getBeanDefinition()); |
||||
|
||||
MockEnvironment env = new MockEnvironment(); |
||||
env.setProperty("my.name", "myValue"); |
||||
|
||||
EnvironmentAwarePropertyPlaceholderConfigurer ppc = |
||||
new EnvironmentAwarePropertyPlaceholderConfigurer(); |
||||
ppc.setEnvironment(env); |
||||
ppc.postProcessBeanFactory(bf); |
||||
assertThat(bf.getBean(TestBean.class).getName(), equalTo("myValue")); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,163 @@
@@ -0,0 +1,163 @@
|
||||
/* |
||||
* Copyright 2002-2010 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.context.support; |
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo; |
||||
import static org.junit.Assert.assertThat; |
||||
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition; |
||||
|
||||
import java.util.Properties; |
||||
|
||||
import org.junit.Test; |
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory; |
||||
import org.springframework.core.env.MutablePropertySources; |
||||
import org.springframework.core.io.ClassPathResource; |
||||
import org.springframework.core.io.Resource; |
||||
import org.springframework.mock.env.MockEnvironment; |
||||
import org.springframework.mock.env.MockPropertySource; |
||||
|
||||
import test.beans.TestBean; |
||||
|
||||
/** |
||||
* Unit tests for {@link PropertySourcesPlaceholderConfigurer}. |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
*/ |
||||
public class PropertySourcesPlaceholderConfigurerTests { |
||||
|
||||
@Test |
||||
public void replacementFromEnvironmentProperties() { |
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); |
||||
bf.registerBeanDefinition("testBean", |
||||
genericBeanDefinition(TestBean.class) |
||||
.addPropertyValue("name", "${my.name}") |
||||
.getBeanDefinition()); |
||||
|
||||
MockEnvironment env = new MockEnvironment(); |
||||
env.setProperty("my.name", "myValue"); |
||||
|
||||
PropertySourcesPlaceholderConfigurer ppc = |
||||
new PropertySourcesPlaceholderConfigurer(); |
||||
ppc.setEnvironment(env); |
||||
ppc.postProcessBeanFactory(bf); |
||||
assertThat(bf.getBean(TestBean.class).getName(), equalTo("myValue")); |
||||
} |
||||
|
||||
@Test |
||||
public void localPropertiesViaResource() { |
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); |
||||
bf.registerBeanDefinition("testBean", |
||||
genericBeanDefinition(TestBean.class) |
||||
.addPropertyValue("name", "${my.name}") |
||||
.getBeanDefinition()); |
||||
|
||||
PropertySourcesPlaceholderConfigurer pc = new PropertySourcesPlaceholderConfigurer(); |
||||
Resource resource = new ClassPathResource("PropertySourcesPlaceholderConfigurerTests.properties", this.getClass()); |
||||
pc.setLocation(resource); |
||||
pc.postProcessBeanFactory(bf); |
||||
assertThat(bf.getBean(TestBean.class).getName(), equalTo("foo")); |
||||
} |
||||
|
||||
@Test |
||||
public void localPropertiesOverrideFalse() { |
||||
localPropertiesOverride(false); |
||||
} |
||||
|
||||
@Test |
||||
public void localPropertiesOverrideTrue() { |
||||
localPropertiesOverride(true); |
||||
} |
||||
|
||||
@Test |
||||
public void explicitPropertySources() { |
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); |
||||
bf.registerBeanDefinition("testBean", |
||||
genericBeanDefinition(TestBean.class) |
||||
.addPropertyValue("name", "${my.name}") |
||||
.getBeanDefinition()); |
||||
|
||||
MutablePropertySources propertySources = new MutablePropertySources(); |
||||
propertySources.addLast(new MockPropertySource().withProperty("my.name", "foo")); |
||||
|
||||
PropertySourcesPlaceholderConfigurer pc = new PropertySourcesPlaceholderConfigurer(); |
||||
pc.setPropertySources(propertySources); |
||||
pc.postProcessBeanFactory(bf); |
||||
assertThat(bf.getBean(TestBean.class).getName(), equalTo("foo")); |
||||
} |
||||
|
||||
@Test |
||||
public void explicitPropertySourcesExcludesEnvironment() { |
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); |
||||
bf.registerBeanDefinition("testBean", |
||||
genericBeanDefinition(TestBean.class) |
||||
.addPropertyValue("name", "${my.name}") |
||||
.getBeanDefinition()); |
||||
|
||||
MutablePropertySources propertySources = new MutablePropertySources(); |
||||
propertySources.addLast(new MockPropertySource()); |
||||
|
||||
PropertySourcesPlaceholderConfigurer pc = new PropertySourcesPlaceholderConfigurer(); |
||||
pc.setPropertySources(propertySources); |
||||
pc.setEnvironment(new MockEnvironment().withProperty("my.name", "env")); |
||||
pc.setIgnoreUnresolvablePlaceholders(true); |
||||
pc.postProcessBeanFactory(bf); |
||||
assertThat(bf.getBean(TestBean.class).getName(), equalTo("${my.name}")); |
||||
} |
||||
|
||||
@Test |
||||
@SuppressWarnings("serial") |
||||
public void explicitPropertySourcesExcludesLocalProperties() { |
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); |
||||
bf.registerBeanDefinition("testBean", |
||||
genericBeanDefinition(TestBean.class) |
||||
.addPropertyValue("name", "${my.name}") |
||||
.getBeanDefinition()); |
||||
|
||||
MutablePropertySources propertySources = new MutablePropertySources(); |
||||
propertySources.addLast(new MockPropertySource()); |
||||
|
||||
PropertySourcesPlaceholderConfigurer pc = new PropertySourcesPlaceholderConfigurer(); |
||||
pc.setPropertySources(propertySources); |
||||
pc.setProperties(new Properties() {{ put("my.name", "local"); }}); |
||||
pc.setIgnoreUnresolvablePlaceholders(true); |
||||
pc.postProcessBeanFactory(bf); |
||||
assertThat(bf.getBean(TestBean.class).getName(), equalTo("${my.name}")); |
||||
} |
||||
|
||||
@SuppressWarnings("serial") |
||||
private void localPropertiesOverride(boolean override) { |
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); |
||||
bf.registerBeanDefinition("testBean", |
||||
genericBeanDefinition(TestBean.class) |
||||
.addPropertyValue("name", "${foo}") |
||||
.getBeanDefinition()); |
||||
|
||||
PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer(); |
||||
|
||||
ppc.setLocalOverride(override); |
||||
ppc.setProperties(new Properties() {{ setProperty("foo", "local"); }}); |
||||
ppc.setEnvironment(new MockEnvironment().withProperty("foo", "enclosing")); |
||||
ppc.postProcessBeanFactory(bf); |
||||
if (override) { |
||||
assertThat(bf.getBean(TestBean.class).getName(), equalTo("local")); |
||||
} else { |
||||
assertThat(bf.getBean(TestBean.class).getName(), equalTo("enclosing")); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
my.name=foo |
||||
@ -0,0 +1,96 @@
@@ -0,0 +1,96 @@
|
||||
/* |
||||
* Copyright 2002-2010 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.core.env; |
||||
|
||||
import static java.lang.String.format; |
||||
|
||||
import static org.springframework.util.SystemPropertyUtils.PLACEHOLDER_PREFIX; |
||||
import static org.springframework.util.SystemPropertyUtils.PLACEHOLDER_SUFFIX; |
||||
import static org.springframework.util.SystemPropertyUtils.VALUE_SEPARATOR; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
import org.springframework.core.convert.ConversionService; |
||||
import org.springframework.core.convert.support.ConversionServiceFactory; |
||||
import org.springframework.util.PropertyPlaceholderHelper; |
||||
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver; |
||||
|
||||
|
||||
/** |
||||
* Abstract base class for resolving properties against any underlying source. |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
*/ |
||||
public abstract class AbstractPropertyResolver implements ConfigurablePropertyResolver { |
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass()); |
||||
|
||||
protected ConversionService conversionService = ConversionServiceFactory.createDefaultConversionService(); |
||||
|
||||
private final PropertyPlaceholderHelper nonStrictHelper = |
||||
new PropertyPlaceholderHelper(PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, VALUE_SEPARATOR, true); |
||||
|
||||
private final PropertyPlaceholderHelper strictHelper = |
||||
new PropertyPlaceholderHelper(PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, VALUE_SEPARATOR, false); |
||||
|
||||
|
||||
public ConversionService getConversionService() { |
||||
return this.conversionService; |
||||
} |
||||
|
||||
public void setConversionService(ConversionService conversionService) { |
||||
this.conversionService = conversionService; |
||||
} |
||||
|
||||
public String getRequiredProperty(String key) throws IllegalStateException { |
||||
String value = getProperty(key); |
||||
if (value == null) { |
||||
throw new IllegalStateException(format("required key [%s] not found", key)); |
||||
} |
||||
return value; |
||||
} |
||||
|
||||
public <T> T getRequiredProperty(String key, Class<T> valueType) throws IllegalStateException { |
||||
T value = getProperty(key, valueType); |
||||
if (value == null) { |
||||
throw new IllegalStateException(format("required key [%s] not found", key)); |
||||
} |
||||
return value; |
||||
} |
||||
|
||||
public int getPropertyCount() { |
||||
return asProperties().size(); |
||||
} |
||||
|
||||
public String resolvePlaceholders(String text) { |
||||
return doResolvePlaceholders(text, this.nonStrictHelper); |
||||
} |
||||
|
||||
public String resolveRequiredPlaceholders(String text) { |
||||
return doResolvePlaceholders(text, this.strictHelper); |
||||
} |
||||
|
||||
private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) { |
||||
return helper.replacePlaceholders(text, new PlaceholderResolver() { |
||||
public String resolvePlaceholder(String placeholderName) { |
||||
return getProperty(placeholderName); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
/* |
||||
* Copyright 2002-2010 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.core.env; |
||||
|
||||
import org.springframework.core.convert.ConversionService; |
||||
|
||||
|
||||
/** |
||||
* Configuration interface to be implemented by most if not all {@link PropertyResolver |
||||
* PropertyResolvers}. Provides facilities for accessing and customizing the |
||||
* {@link ConversionService} used when converting property values from one type to |
||||
* another. |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
*/ |
||||
public interface ConfigurablePropertyResolver extends PropertyResolver { |
||||
|
||||
/** |
||||
* @return the {@link ConversionService} used when performing type |
||||
* conversions on properties. |
||||
* @see PropertyResolver#getProperty(String, Class) |
||||
*/ |
||||
ConversionService getConversionService(); |
||||
|
||||
/** |
||||
* Set the {@link ConversionService} to be used when performing type |
||||
* conversions on properties. |
||||
* @see PropertyResolver#getProperty(String, Class) |
||||
*/ |
||||
void setConversionService(ConversionService conversionService); |
||||
|
||||
} |
||||
@ -0,0 +1,123 @@
@@ -0,0 +1,123 @@
|
||||
/* |
||||
* Copyright 2002-2010 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.core.env; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.LinkedList; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.util.Assert; |
||||
|
||||
|
||||
public class MutablePropertySources implements PropertySources { |
||||
|
||||
private final LinkedList<PropertySource<?>> propertySourceList = new LinkedList<PropertySource<?>>(); |
||||
|
||||
static final String NON_EXISTENT_PROPERTY_SOURCE_MESSAGE = "PropertySource named [%s] does not exist"; |
||||
static final String ILLEGAL_RELATIVE_ADDITION_MESSAGE = "PropertySource named [%s] cannot be added relative to itself"; |
||||
|
||||
|
||||
public MutablePropertySources() { |
||||
} |
||||
|
||||
public MutablePropertySources(PropertySources propertySources) { |
||||
this.addAll(propertySources); |
||||
} |
||||
|
||||
public void addAll(PropertySources propertySources) { |
||||
for (PropertySource<?> propertySource : propertySources.asList()) { |
||||
this.addLast(propertySource); |
||||
} |
||||
} |
||||
|
||||
public void addFirst(PropertySource<?> propertySource) { |
||||
removeIfPresent(propertySource); |
||||
this.propertySourceList.addFirst(propertySource); |
||||
} |
||||
|
||||
public void addLast(PropertySource<?> propertySource) { |
||||
removeIfPresent(propertySource); |
||||
this.propertySourceList.addLast(propertySource); |
||||
} |
||||
|
||||
public void addBefore(String relativePropertySourceName, PropertySource<?> propertySource) { |
||||
assertLegalRelativeAddition(relativePropertySourceName, propertySource); |
||||
removeIfPresent(propertySource); |
||||
int index = assertPresentAndGetIndex(relativePropertySourceName); |
||||
addAtIndex(index, propertySource); |
||||
} |
||||
|
||||
public void addAfter(String relativePropertySourceName, PropertySource<?> propertySource) { |
||||
assertLegalRelativeAddition(relativePropertySourceName, propertySource); |
||||
removeIfPresent(propertySource); |
||||
int index = assertPresentAndGetIndex(relativePropertySourceName); |
||||
addAtIndex(index+1, propertySource); |
||||
} |
||||
|
||||
protected void assertLegalRelativeAddition(String relativePropertySourceName, PropertySource<?> propertySource) { |
||||
String newPropertySourceName = propertySource.getName(); |
||||
Assert.isTrue(!relativePropertySourceName.equals(newPropertySourceName), |
||||
String.format(ILLEGAL_RELATIVE_ADDITION_MESSAGE, newPropertySourceName)); |
||||
} |
||||
|
||||
protected void addAtIndex(int index, PropertySource<?> propertySource) { |
||||
removeIfPresent(propertySource); |
||||
this.propertySourceList.add(index, propertySource); |
||||
} |
||||
|
||||
protected void removeIfPresent(PropertySource<?> propertySource) { |
||||
if (this.propertySourceList.contains(propertySource)) { |
||||
this.propertySourceList.remove(propertySource); |
||||
} |
||||
} |
||||
|
||||
public boolean contains(String propertySourceName) { |
||||
return propertySourceList.contains(PropertySource.named(propertySourceName)); |
||||
} |
||||
|
||||
public PropertySource<?> remove(String propertySourceName) { |
||||
int index = propertySourceList.indexOf(PropertySource.named(propertySourceName)); |
||||
if (index >= 0) { |
||||
return propertySourceList.remove(index); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public void replace(String propertySourceName, PropertySource<?> propertySource) { |
||||
int index = assertPresentAndGetIndex(propertySourceName); |
||||
this.propertySourceList.set(index, propertySource); |
||||
} |
||||
|
||||
protected int assertPresentAndGetIndex(String propertySourceName) { |
||||
int index = this.propertySourceList.indexOf(PropertySource.named(propertySourceName)); |
||||
Assert.isTrue(index >= 0, String.format(NON_EXISTENT_PROPERTY_SOURCE_MESSAGE, propertySourceName)); |
||||
return index; |
||||
} |
||||
|
||||
public int size() { |
||||
return propertySourceList.size(); |
||||
} |
||||
|
||||
public List<PropertySource<?>> asList() { |
||||
return Collections.unmodifiableList(this.propertySourceList); |
||||
} |
||||
|
||||
public PropertySource<?> get(String propertySourceName) { |
||||
return propertySourceList.get(propertySourceList.indexOf(PropertySource.named(propertySourceName))); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,96 @@
@@ -0,0 +1,96 @@
|
||||
/* |
||||
* Copyright 2002-2010 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.core.env; |
||||
|
||||
import java.util.Properties; |
||||
|
||||
|
||||
/** |
||||
* Interface for resolving properties against any underlying source. |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
* @see Environment#getPropertyResolver() |
||||
*/ |
||||
public interface PropertyResolver { |
||||
|
||||
/** |
||||
* @return whether the given property key is available for resolution |
||||
*/ |
||||
boolean containsProperty(String key); |
||||
|
||||
/** |
||||
* @return the property value associated with the given key |
||||
* @see #getProperty(String, Class) |
||||
*/ |
||||
String getProperty(String key); |
||||
|
||||
/** |
||||
* @return the property value associated with the given key, or {@code null} |
||||
* if the key cannot be resolved |
||||
*/ |
||||
<T> T getProperty(String key, Class<T> targetType); |
||||
|
||||
/** |
||||
* @return the property value associated with the given key, converted to the given |
||||
* targetType (never {@code null}) |
||||
* @throws IllegalStateException if the key cannot be resolved |
||||
* @see #getRequiredProperty(String, Class) |
||||
*/ |
||||
String getRequiredProperty(String key) throws IllegalStateException; |
||||
|
||||
/** |
||||
* @return the property value associated with the given key, converted to the given |
||||
* targetType (never {@code null}) |
||||
* @throws IllegalStateException if the given key cannot be resolved |
||||
*/ |
||||
<T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException; |
||||
|
||||
/** |
||||
* @return the number of unique properties keys resolvable |
||||
*/ |
||||
int getPropertyCount(); |
||||
|
||||
/** |
||||
* @return all property key/value pairs as a {@link java.util.Properties} instance |
||||
*/ |
||||
Properties asProperties(); |
||||
|
||||
/** |
||||
* Resolve ${...} placeholders in the given text, replacing them with corresponding |
||||
* property values as resolved by {@link #getProperty}. Unresolvable placeholders with |
||||
* no default value are ignored and passed through unchanged. |
||||
* @param text the String to resolve |
||||
* @return the resolved String (never {@code null}) |
||||
* @throws IllegalArgumentException if given text is {@code null} |
||||
* @see #resolveRequiredPlaceholders |
||||
* @see org.springframework.util.SystemPropertyUtils#resolvePlaceholders(String) |
||||
*/ |
||||
String resolvePlaceholders(String text); |
||||
|
||||
/** |
||||
* Resolve ${...} placeholders in the given text, replacing them with corresponding |
||||
* property values as resolved by {@link #getProperty}. Unresolvable placeholders with |
||||
* no default value will cause an IllegalArgumentException to be thrown. |
||||
* @return the resolved String (never {@code null}) |
||||
* @throws IllegalArgumentException if given text is {@code null} |
||||
* @throws IllegalArgumentException if any placeholders are unresolvable |
||||
* @see org.springframework.util.SystemPropertyUtils#resolvePlaceholders(String, boolean) |
||||
*/ |
||||
String resolveRequiredPlaceholders(String path) throws IllegalArgumentException; |
||||
|
||||
} |
||||
@ -0,0 +1,109 @@
@@ -0,0 +1,109 @@
|
||||
/* |
||||
* 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.core.env; |
||||
|
||||
import static java.lang.String.format; |
||||
|
||||
import java.util.List; |
||||
import java.util.Properties; |
||||
|
||||
/** |
||||
* {@link PropertyResolver} implementation that resolves property values against |
||||
* an underlying set of {@link PropertySources}. |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
*/ |
||||
public class PropertySourcesPropertyResolver extends AbstractPropertyResolver { |
||||
|
||||
private final PropertySources propertySources; |
||||
|
||||
/** |
||||
* Create a new resolver against the given property sources. |
||||
* @param propertySources the set of {@link PropertySource} objects to use |
||||
*/ |
||||
public PropertySourcesPropertyResolver(PropertySources propertySources) { |
||||
this.propertySources = propertySources; |
||||
} |
||||
|
||||
|
||||
public boolean containsProperty(String key) { |
||||
for (PropertySource<?> propertySource : this.propertySources.asList()) { |
||||
if (propertySource.containsProperty(key)) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public String getProperty(String key) { |
||||
if (logger.isTraceEnabled()) { |
||||
logger.trace(format("getProperty(\"%s\") (implicit targetType [String])", key)); |
||||
} |
||||
return this.getProperty(key, String.class); |
||||
} |
||||
|
||||
public <T> T getProperty(String key, Class<T> targetValueType) { |
||||
boolean debugEnabled = logger.isDebugEnabled(); |
||||
if (logger.isTraceEnabled()) { |
||||
logger.trace(format("getProperty(\"%s\", %s)", key, targetValueType.getSimpleName())); |
||||
} |
||||
|
||||
for (PropertySource<?> propertySource : this.propertySources.asList()) { |
||||
if (debugEnabled) { |
||||
logger.debug(format("Searching for key '%s' in [%s]", key, propertySource.getName())); |
||||
} |
||||
if (propertySource.containsProperty(key)) { |
||||
Object value = propertySource.getProperty(key); |
||||
Class<?> valueType = value == null ? null : value.getClass(); |
||||
if (debugEnabled) { |
||||
logger.debug( |
||||
format("Found key '%s' in [%s] with type [%s] and value '%s'", |
||||
key, propertySource.getName(), |
||||
valueType == null ? "" : valueType.getSimpleName(), value)); |
||||
} |
||||
if (value == null) { |
||||
return null; |
||||
} |
||||
if (!this.conversionService.canConvert(valueType, targetValueType)) { |
||||
throw new IllegalArgumentException( |
||||
format("Cannot convert value [%s] from source type [%s] to target type [%s]", |
||||
value, valueType.getSimpleName(), targetValueType.getSimpleName())); |
||||
} |
||||
return conversionService.convert(value, targetValueType); |
||||
} |
||||
} |
||||
|
||||
if (debugEnabled) { |
||||
logger.debug(format("Could not find key '%s' in any property source. Returning [null]", key)); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public Properties asProperties() { |
||||
Properties mergedProps = new Properties(); |
||||
List<PropertySource<?>> propertySourcesList = this.propertySources.asList(); |
||||
for (int i = propertySourcesList.size() -1; i >= 0; i--) { |
||||
PropertySource<?> source = propertySourcesList.get(i); |
||||
for (String key : source.getPropertyNames()) { |
||||
mergedProps.put(key, source.getProperty(key)); |
||||
} |
||||
} |
||||
return mergedProps; |
||||
} |
||||
|
||||
} |
||||
@ -1,56 +0,0 @@
@@ -1,56 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2010 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.core.env; |
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo; |
||||
import static org.junit.Assert.assertThat; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
|
||||
/** |
||||
* Test that {@link Environment#getValue} performs late-resolution of property |
||||
* values i.e., does not eagerly resolve and cache only at construction time. |
||||
* |
||||
* @see EnvironmentPropertyResolutionSearchTests |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
*/ |
||||
public class EnvironmentPropertyResolutionLateBindingTests { |
||||
@Test |
||||
public void replaceExistingKeyPostConstruction() { |
||||
String key = "foo"; |
||||
String value1 = "bar"; |
||||
String value2 = "biz"; |
||||
|
||||
System.setProperty(key, value1); // before construction
|
||||
DefaultEnvironment env = new DefaultEnvironment(); |
||||
assertThat(env.getProperty(key), equalTo(value1)); |
||||
System.setProperty(key, value2); // after construction and first resolution
|
||||
assertThat(env.getProperty(key), equalTo(value2)); |
||||
System.clearProperty(key); // clean up
|
||||
} |
||||
|
||||
@Test |
||||
public void addNewKeyPostConstruction() { |
||||
DefaultEnvironment env = new DefaultEnvironment(); |
||||
assertThat(env.getProperty("foo"), equalTo(null)); |
||||
System.setProperty("foo", "42"); |
||||
assertThat(env.getProperty("foo"), equalTo("42")); |
||||
System.clearProperty("foo"); // clean up
|
||||
} |
||||
} |
||||
@ -1,102 +0,0 @@
@@ -1,102 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2010 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.core.env; |
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo; |
||||
import static org.hamcrest.CoreMatchers.is; |
||||
import static org.junit.Assert.assertThat; |
||||
|
||||
import java.lang.reflect.Field; |
||||
import java.util.Collections; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
import java.util.Properties; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* Unit tests for {@link DefaultEnvironment} proving that it (a) searches |
||||
* standard property sources (b) in the correct order. |
||||
* |
||||
* @see AbstractEnvironment#getProperty(String) |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
*/ |
||||
public class EnvironmentPropertyResolutionSearchTests { |
||||
|
||||
@Test @SuppressWarnings({ "unchecked", "serial", "rawtypes" }) |
||||
public void propertySourcesHaveLIFOSearchOrder() { |
||||
ConfigurableEnvironment env = new AbstractEnvironment() { }; |
||||
env.addPropertySource("ps1", new HashMap() {{ put("pName", "ps1Value"); }}); |
||||
assertThat(env.getProperty("pName"), equalTo("ps1Value")); |
||||
env.addPropertySource("ps2", new HashMap() {{ put("pName", "ps2Value"); }}); |
||||
assertThat(env.getProperty("pName"), equalTo("ps2Value")); |
||||
env.addPropertySource("ps3", new HashMap() {{ put("pName", "ps3Value"); }}); |
||||
assertThat(env.getProperty("pName"), equalTo("ps3Value")); |
||||
} |
||||
|
||||
@Test |
||||
public void resolveFromDefaultPropertySources() throws Exception { |
||||
String key = "x"; |
||||
String localPropsValue = "local"; |
||||
String sysPropsValue = "sys"; |
||||
String envVarsValue = "env"; |
||||
|
||||
Map<String, String> systemEnvironment = getModifiableSystemEnvironment(); |
||||
Properties systemProperties = System.getProperties(); |
||||
Properties localProperties = new Properties(); |
||||
|
||||
DefaultEnvironment env = new DefaultEnvironment(); |
||||
env.addPropertySource("localProperties", localProperties); |
||||
|
||||
// set all properties
|
||||
systemEnvironment.put(key, envVarsValue); |
||||
systemProperties.setProperty(key, sysPropsValue); |
||||
localProperties.setProperty(key, localPropsValue); |
||||
|
||||
// local properties should have highest resolution precedence
|
||||
assertThat(env.getProperty(key), equalTo(localPropsValue)); |
||||
|
||||
// system properties should be next in line
|
||||
localProperties.remove(key); |
||||
assertThat(env.getProperty(key), equalTo(sysPropsValue)); |
||||
|
||||
// system environment variables should be final fallback
|
||||
systemProperties.remove(key); |
||||
assertThat(env.getProperty(key), equalTo(envVarsValue)); |
||||
|
||||
// with no propertysource containing the key in question, should return null
|
||||
systemEnvironment.remove(key); |
||||
assertThat(env.getProperty(key), equalTo(null)); |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
private static Map<String, String> getModifiableSystemEnvironment() throws Exception { |
||||
Class<?>[] classes = Collections.class.getDeclaredClasses(); |
||||
Map<String, String> env = System.getenv(); |
||||
for (Class<?> cl : classes) { |
||||
if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) { |
||||
Field field = cl.getDeclaredField("m"); |
||||
field.setAccessible(true); |
||||
Object obj = field.get(env); |
||||
return (Map<String, String>) obj; |
||||
} |
||||
} |
||||
throw new IllegalStateException(); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,288 @@
@@ -0,0 +1,288 @@
|
||||
/* |
||||
* Copyright 2002-2010 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.core.env; |
||||
|
||||
import static java.lang.String.format; |
||||
import static org.hamcrest.CoreMatchers.equalTo; |
||||
import static org.hamcrest.CoreMatchers.instanceOf; |
||||
import static org.hamcrest.CoreMatchers.is; |
||||
import static org.hamcrest.CoreMatchers.not; |
||||
import static org.hamcrest.CoreMatchers.notNullValue; |
||||
import static org.hamcrest.CoreMatchers.nullValue; |
||||
import static org.junit.Assert.assertSame; |
||||
import static org.junit.Assert.assertThat; |
||||
import static org.junit.Assert.fail; |
||||
import static org.junit.matchers.JUnitMatchers.hasItem; |
||||
import static org.junit.matchers.JUnitMatchers.hasItems; |
||||
import static org.springframework.core.env.AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME; |
||||
import static org.springframework.core.env.AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME; |
||||
|
||||
import java.lang.reflect.Field; |
||||
import java.security.AccessControlException; |
||||
import java.security.Permission; |
||||
import java.util.Arrays; |
||||
import java.util.Collections; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.Test; |
||||
import org.springframework.mock.env.MockPropertySource; |
||||
|
||||
|
||||
/** |
||||
* Unit tests for {@link DefaultEnvironment}. |
||||
* |
||||
* @author Chris Beams |
||||
*/ |
||||
public class EnvironmentTests { |
||||
|
||||
private static final String ALLOWED_PROPERTY_NAME = "theanswer"; |
||||
private static final String ALLOWED_PROPERTY_VALUE = "42"; |
||||
|
||||
private static final String DISALLOWED_PROPERTY_NAME = "verboten"; |
||||
private static final String DISALLOWED_PROPERTY_VALUE = "secret"; |
||||
|
||||
private static final String STRING_PROPERTY_NAME = "stringPropName"; |
||||
private static final String STRING_PROPERTY_VALUE = "stringPropValue"; |
||||
private static final Object NON_STRING_PROPERTY_NAME = new Object(); |
||||
private static final Object NON_STRING_PROPERTY_VALUE = new Object(); |
||||
|
||||
private ConfigurableEnvironment environment = new DefaultEnvironment(); |
||||
|
||||
@Test |
||||
public void activeProfiles() { |
||||
assertThat(environment.getActiveProfiles().length, is(0)); |
||||
environment.setActiveProfiles("local", "embedded"); |
||||
String[] activeProfiles = environment.getActiveProfiles(); |
||||
assertThat(Arrays.asList(activeProfiles), hasItems("local", "embedded")); |
||||
assertThat(activeProfiles.length, is(2)); |
||||
} |
||||
|
||||
@Test |
||||
public void getActiveProfiles_systemPropertiesEmpty() { |
||||
assertThat(environment.getActiveProfiles().length, is(0)); |
||||
System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, ""); |
||||
assertThat(environment.getActiveProfiles().length, is(0)); |
||||
System.getProperties().remove(ACTIVE_PROFILES_PROPERTY_NAME); |
||||
} |
||||
|
||||
@Test |
||||
public void getActiveProfiles_fromSystemProperties() { |
||||
assertThat(environment.getActiveProfiles().length, is(0)); |
||||
System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, "foo"); |
||||
assertThat(Arrays.asList(environment.getActiveProfiles()), hasItem("foo")); |
||||
System.getProperties().remove(ACTIVE_PROFILES_PROPERTY_NAME); |
||||
} |
||||
|
||||
@Test |
||||
public void getActiveProfiles_fromSystemProperties_withMultipleProfiles() { |
||||
assertThat(environment.getActiveProfiles().length, is(0)); |
||||
System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, "foo,bar"); |
||||
assertThat(Arrays.asList(environment.getActiveProfiles()), hasItems("foo", "bar")); |
||||
System.getProperties().remove(ACTIVE_PROFILES_PROPERTY_NAME); |
||||
} |
||||
|
||||
@Test |
||||
public void getActiveProfiles_fromSystemProperties_withMulitpleProfiles_withWhitespace() { |
||||
assertThat(environment.getActiveProfiles().length, is(0)); |
||||
System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, " bar , baz "); // notice whitespace
|
||||
assertThat(Arrays.asList(environment.getActiveProfiles()), hasItems("bar", "baz")); |
||||
System.getProperties().remove(ACTIVE_PROFILES_PROPERTY_NAME); |
||||
} |
||||
|
||||
@Test |
||||
public void getDefaultProfiles() { |
||||
assertThat(environment.getDefaultProfiles().length, is(0)); |
||||
environment.getPropertySources().addFirst(new MockPropertySource().withProperty(DEFAULT_PROFILES_PROPERTY_NAME, "pd1")); |
||||
assertThat(environment.getDefaultProfiles().length, is(1)); |
||||
assertThat(Arrays.asList(environment.getDefaultProfiles()), hasItem("pd1")); |
||||
} |
||||
|
||||
@Test |
||||
public void setDefaultProfiles() { |
||||
environment.setDefaultProfiles(); |
||||
assertThat(environment.getDefaultProfiles().length, is(0)); |
||||
environment.setDefaultProfiles("pd1"); |
||||
assertThat(Arrays.asList(environment.getDefaultProfiles()), hasItem("pd1")); |
||||
environment.setDefaultProfiles("pd2", "pd3"); |
||||
assertThat(Arrays.asList(environment.getDefaultProfiles()), not(hasItem("pd1"))); |
||||
assertThat(Arrays.asList(environment.getDefaultProfiles()), hasItems("pd2", "pd3")); |
||||
} |
||||
|
||||
@Test(expected=IllegalArgumentException.class) |
||||
public void acceptsProfiles_mustSpecifyAtLeastOne() { |
||||
environment.acceptsProfiles(); |
||||
} |
||||
|
||||
@Test |
||||
public void acceptsProfiles_activeProfileSetProgrammatically() { |
||||
assertThat(environment.acceptsProfiles("p1", "p2"), is(false)); |
||||
environment.setActiveProfiles("p1"); |
||||
assertThat(environment.acceptsProfiles("p1", "p2"), is(true)); |
||||
environment.setActiveProfiles("p2"); |
||||
assertThat(environment.acceptsProfiles("p1", "p2"), is(true)); |
||||
environment.setActiveProfiles("p1", "p2"); |
||||
assertThat(environment.acceptsProfiles("p1", "p2"), is(true)); |
||||
} |
||||
|
||||
@Test |
||||
public void acceptsProfiles_activeProfileSetViaProperty() { |
||||
assertThat(environment.acceptsProfiles("p1"), is(false)); |
||||
environment.getPropertySources().addFirst(new MockPropertySource().withProperty(ACTIVE_PROFILES_PROPERTY_NAME, "p1")); |
||||
assertThat(environment.acceptsProfiles("p1"), is(true)); |
||||
} |
||||
|
||||
@Test |
||||
public void acceptsProfiles_defaultProfile() { |
||||
assertThat(environment.acceptsProfiles("pd"), is(false)); |
||||
environment.setDefaultProfiles("pd"); |
||||
assertThat(environment.acceptsProfiles("pd"), is(true)); |
||||
environment.setActiveProfiles("p1"); |
||||
assertThat(environment.acceptsProfiles("pd"), is(false)); |
||||
assertThat(environment.acceptsProfiles("p1"), is(true)); |
||||
} |
||||
|
||||
@Test |
||||
public void getSystemProperties_withAndWithoutSecurityManager() { |
||||
System.setProperty(ALLOWED_PROPERTY_NAME, ALLOWED_PROPERTY_VALUE); |
||||
System.setProperty(DISALLOWED_PROPERTY_NAME, DISALLOWED_PROPERTY_VALUE); |
||||
System.getProperties().put(STRING_PROPERTY_NAME, NON_STRING_PROPERTY_VALUE); |
||||
System.getProperties().put(NON_STRING_PROPERTY_NAME, STRING_PROPERTY_VALUE); |
||||
|
||||
{ |
||||
Map<?, ?> systemProperties = environment.getSystemProperties(); |
||||
assertThat(systemProperties, notNullValue()); |
||||
assertSame(systemProperties, System.getProperties()); |
||||
assertThat(systemProperties.get(ALLOWED_PROPERTY_NAME), equalTo((Object)ALLOWED_PROPERTY_VALUE)); |
||||
assertThat(systemProperties.get(DISALLOWED_PROPERTY_NAME), equalTo((Object)DISALLOWED_PROPERTY_VALUE)); |
||||
|
||||
// non-string keys and values work fine... until the security manager is introduced below
|
||||
assertThat(systemProperties.get(STRING_PROPERTY_NAME), equalTo(NON_STRING_PROPERTY_VALUE)); |
||||
assertThat(systemProperties.get(NON_STRING_PROPERTY_NAME), equalTo((Object)STRING_PROPERTY_VALUE)); |
||||
} |
||||
|
||||
SecurityManager oldSecurityManager = System.getSecurityManager(); |
||||
SecurityManager securityManager = new SecurityManager() { |
||||
@Override |
||||
public void checkPropertiesAccess() { |
||||
// see http://download.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#getProperties()
|
||||
throw new AccessControlException("Accessing the system properties is disallowed"); |
||||
} |
||||
@Override |
||||
public void checkPropertyAccess(String key) { |
||||
// see http://download.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#getProperty(java.lang.String)
|
||||
if (DISALLOWED_PROPERTY_NAME.equals(key)) { |
||||
throw new AccessControlException( |
||||
format("Accessing the system property [%s] is disallowed", DISALLOWED_PROPERTY_NAME)); |
||||
} |
||||
} |
||||
@Override |
||||
public void checkPermission(Permission perm) { |
||||
// allow everything else
|
||||
} |
||||
}; |
||||
System.setSecurityManager(securityManager); |
||||
|
||||
{ |
||||
Map<?, ?> systemProperties = environment.getSystemProperties(); |
||||
assertThat(systemProperties, notNullValue()); |
||||
assertThat(systemProperties, instanceOf(ReadOnlySystemAttributesMap.class)); |
||||
assertThat((String)systemProperties.get(ALLOWED_PROPERTY_NAME), equalTo(ALLOWED_PROPERTY_VALUE)); |
||||
assertThat(systemProperties.get(DISALLOWED_PROPERTY_NAME), equalTo(null)); |
||||
|
||||
// nothing we can do here in terms of warning the user that there was
|
||||
// actually a (non-string) value available. By this point, we only
|
||||
// have access to calling System.getProperty(), which itself returns null
|
||||
// if the value is non-string. So we're stuck with returning a potentially
|
||||
// misleading null.
|
||||
assertThat(systemProperties.get(STRING_PROPERTY_NAME), nullValue()); |
||||
|
||||
// in the case of a non-string *key*, however, we can do better. Alert
|
||||
// the user that under these very special conditions (non-object key +
|
||||
// SecurityManager that disallows access to system properties), they
|
||||
// cannot do what they're attempting.
|
||||
try { |
||||
systemProperties.get(NON_STRING_PROPERTY_NAME); |
||||
fail("Expected IllegalArgumentException when searching with non-string key against ReadOnlySystemAttributesMap"); |
||||
} catch (IllegalArgumentException ex) { |
||||
// expected
|
||||
} |
||||
} |
||||
|
||||
System.setSecurityManager(oldSecurityManager); |
||||
System.clearProperty(ALLOWED_PROPERTY_NAME); |
||||
System.clearProperty(DISALLOWED_PROPERTY_NAME); |
||||
System.getProperties().remove(STRING_PROPERTY_NAME); |
||||
System.getProperties().remove(NON_STRING_PROPERTY_NAME); |
||||
} |
||||
|
||||
@Test |
||||
public void getSystemEnvironment_withAndWithoutSecurityManager() throws Exception { |
||||
getModifiableSystemEnvironment().put(ALLOWED_PROPERTY_NAME, ALLOWED_PROPERTY_VALUE); |
||||
getModifiableSystemEnvironment().put(DISALLOWED_PROPERTY_NAME, DISALLOWED_PROPERTY_VALUE); |
||||
|
||||
{ |
||||
Map<String, String> systemEnvironment = environment.getSystemEnvironment(); |
||||
assertThat(systemEnvironment, notNullValue()); |
||||
assertSame(systemEnvironment, System.getenv()); |
||||
} |
||||
|
||||
SecurityManager oldSecurityManager = System.getSecurityManager(); |
||||
SecurityManager securityManager = new SecurityManager() { |
||||
@Override |
||||
public void checkPermission(Permission perm) { |
||||
//see http://download.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#getenv()
|
||||
if ("getenv.*".equals(perm.getName())) { |
||||
throw new AccessControlException("Accessing the system environment is disallowed"); |
||||
} |
||||
//see http://download.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#getenv(java.lang.String)
|
||||
if (("getenv."+DISALLOWED_PROPERTY_NAME).equals(perm.getName())) { |
||||
throw new AccessControlException( |
||||
format("Accessing the system environment variable [%s] is disallowed", DISALLOWED_PROPERTY_NAME)); |
||||
} |
||||
} |
||||
}; |
||||
System.setSecurityManager(securityManager); |
||||
|
||||
{ |
||||
Map<String, String> systemEnvironment = environment.getSystemEnvironment(); |
||||
assertThat(systemEnvironment, notNullValue()); |
||||
assertThat(systemEnvironment, instanceOf(ReadOnlySystemAttributesMap.class)); |
||||
assertThat(systemEnvironment.get(ALLOWED_PROPERTY_NAME), equalTo(ALLOWED_PROPERTY_VALUE)); |
||||
assertThat(systemEnvironment.get(DISALLOWED_PROPERTY_NAME), nullValue()); |
||||
} |
||||
|
||||
System.setSecurityManager(oldSecurityManager); |
||||
getModifiableSystemEnvironment().remove(ALLOWED_PROPERTY_NAME); |
||||
getModifiableSystemEnvironment().remove(DISALLOWED_PROPERTY_NAME); |
||||
} |
||||
|
||||
// TODO SPR-7508: duplicated from EnvironmentPropertyResolutionSearchTests
|
||||
@SuppressWarnings("unchecked") |
||||
private static Map<String, String> getModifiableSystemEnvironment() throws Exception { |
||||
Class<?>[] classes = Collections.class.getDeclaredClasses(); |
||||
Map<String, String> systemEnv = System.getenv(); |
||||
for (Class<?> cl : classes) { |
||||
if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) { |
||||
Field field = cl.getDeclaredField("m"); |
||||
field.setAccessible(true); |
||||
Object obj = field.get(systemEnv); |
||||
return (Map<String, String>) obj; |
||||
} |
||||
} |
||||
throw new IllegalStateException(); |
||||
} |
||||
} |
||||
@ -0,0 +1,282 @@
@@ -0,0 +1,282 @@
|
||||
/* |
||||
* Copyright 2002-2010 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.core.env; |
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo; |
||||
import static org.hamcrest.CoreMatchers.is; |
||||
import static org.hamcrest.CoreMatchers.notNullValue; |
||||
import static org.hamcrest.CoreMatchers.nullValue; |
||||
import static org.junit.Assert.assertThat; |
||||
import static org.junit.Assert.fail; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
import java.util.Properties; |
||||
|
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.springframework.mock.env.MockPropertySource; |
||||
|
||||
|
||||
/** |
||||
* Unit tests for {@link PropertyResolver}. |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
* @see PropertySourcesPropertyResolver |
||||
*/ |
||||
public class PropertyResolverTests { |
||||
private Properties testProperties; |
||||
private MutablePropertySources propertySources; |
||||
private ConfigurablePropertyResolver propertyResolver; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
propertySources = new MutablePropertySources(); |
||||
propertyResolver = new PropertySourcesPropertyResolver(propertySources); |
||||
testProperties = new Properties(); |
||||
propertySources.addFirst(new PropertiesPropertySource("testProperties", testProperties)); |
||||
} |
||||
|
||||
@Test |
||||
public void containsProperty() { |
||||
assertThat(propertyResolver.containsProperty("foo"), is(false)); |
||||
testProperties.put("foo", "bar"); |
||||
assertThat(propertyResolver.containsProperty("foo"), is(true)); |
||||
} |
||||
|
||||
@Test |
||||
public void getProperty() { |
||||
assertThat(propertyResolver.getProperty("foo"), nullValue()); |
||||
testProperties.put("foo", "bar"); |
||||
assertThat(propertyResolver.getProperty("foo"), is("bar")); |
||||
} |
||||
|
||||
@Test |
||||
public void getProperty_propertySourceSearchOrderIsFIFO() { |
||||
MutablePropertySources sources = new MutablePropertySources(); |
||||
PropertyResolver resolver = new PropertySourcesPropertyResolver(sources); |
||||
sources.addFirst(new MockPropertySource("ps1").withProperty("pName", "ps1Value")); |
||||
assertThat(resolver.getProperty("pName"), equalTo("ps1Value")); |
||||
sources.addFirst(new MockPropertySource("ps2").withProperty("pName", "ps2Value")); |
||||
assertThat(resolver.getProperty("pName"), equalTo("ps2Value")); |
||||
sources.addFirst(new MockPropertySource("ps3").withProperty("pName", "ps3Value")); |
||||
assertThat(resolver.getProperty("pName"), equalTo("ps3Value")); |
||||
} |
||||
|
||||
@Test |
||||
public void getProperty_withExplicitNullValue() { |
||||
// java.util.Properties does not allow null values (because Hashtable does not)
|
||||
Map<String, String> nullableProperties = new HashMap<String, String>(); |
||||
propertySources.addLast(new MapPropertySource("nullableProperties", nullableProperties)); |
||||
nullableProperties.put("foo", null); |
||||
assertThat(propertyResolver.getProperty("foo"), nullValue()); |
||||
} |
||||
|
||||
@Test |
||||
public void getProperty_withStringArrayConversion() { |
||||
testProperties.put("foo", "bar,baz"); |
||||
assertThat(propertyResolver.getProperty("foo", String[].class), equalTo(new String[] { "bar", "baz" })); |
||||
} |
||||
|
||||
|
||||
@Test |
||||
public void getProperty_withNonConvertibleTargetType() { |
||||
testProperties.put("foo", "bar"); |
||||
|
||||
class TestType { } |
||||
|
||||
try { |
||||
propertyResolver.getProperty("foo", TestType.class); |
||||
fail("Expected IllegalArgumentException due to non-convertible types"); |
||||
} catch (IllegalArgumentException ex) { |
||||
// expected
|
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void getProperty_doesNotCache_replaceExistingKeyPostConstruction() { |
||||
String key = "foo"; |
||||
String value1 = "bar"; |
||||
String value2 = "biz"; |
||||
|
||||
HashMap<String, String> map = new HashMap<String, String>(); |
||||
map.put(key, value1); // before construction
|
||||
MutablePropertySources propertySources = new MutablePropertySources(); |
||||
propertySources.addFirst(new MapPropertySource("testProperties", map)); |
||||
PropertyResolver propertyResolver = new PropertySourcesPropertyResolver(propertySources); |
||||
assertThat(propertyResolver.getProperty(key), equalTo(value1)); |
||||
map.put(key, value2); // after construction and first resolution
|
||||
assertThat(propertyResolver.getProperty(key), equalTo(value2)); |
||||
} |
||||
|
||||
@Test |
||||
public void getProperty_doesNotCache_addNewKeyPostConstruction() { |
||||
HashMap<String, String> map = new HashMap<String, String>(); |
||||
MutablePropertySources propertySources = new MutablePropertySources(); |
||||
propertySources.addFirst(new MapPropertySource("testProperties", map)); |
||||
PropertyResolver propertyResolver = new PropertySourcesPropertyResolver(propertySources); |
||||
assertThat(propertyResolver.getProperty("foo"), equalTo(null)); |
||||
map.put("foo", "42"); |
||||
assertThat(propertyResolver.getProperty("foo"), equalTo("42")); |
||||
} |
||||
|
||||
@Test |
||||
public void getPropertySources_replacePropertySource() { |
||||
propertySources = new MutablePropertySources(); |
||||
propertyResolver = new PropertySourcesPropertyResolver(propertySources); |
||||
propertySources.addLast(new MockPropertySource("local").withProperty("foo", "localValue")); |
||||
propertySources.addLast(new MockPropertySource("system").withProperty("foo", "systemValue")); |
||||
|
||||
// 'local' was added first so has precedence
|
||||
assertThat(propertyResolver.getProperty("foo"), equalTo("localValue")); |
||||
|
||||
// replace 'local' with new property source
|
||||
propertySources.replace("local", new MockPropertySource("new").withProperty("foo", "newValue")); |
||||
|
||||
// 'system' now has precedence
|
||||
assertThat(propertyResolver.getProperty("foo"), equalTo("newValue")); |
||||
|
||||
assertThat(propertySources.size(), is(2)); |
||||
} |
||||
|
||||
@Test |
||||
public void getRequiredProperty() { |
||||
testProperties.put("exists", "xyz"); |
||||
assertThat(propertyResolver.getRequiredProperty("exists"), is("xyz")); |
||||
|
||||
try { |
||||
propertyResolver.getRequiredProperty("bogus"); |
||||
fail("expected IllegalStateException"); |
||||
} catch (IllegalStateException ex) { |
||||
// expected
|
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void getRequiredProperty_withStringArrayConversion() { |
||||
testProperties.put("exists", "abc,123"); |
||||
assertThat(propertyResolver.getRequiredProperty("exists", String[].class), equalTo(new String[] { "abc", "123" })); |
||||
|
||||
try { |
||||
propertyResolver.getRequiredProperty("bogus", String[].class); |
||||
fail("expected IllegalStateException"); |
||||
} catch (IllegalStateException ex) { |
||||
// expected
|
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void asProperties() { |
||||
propertySources = new MutablePropertySources(); |
||||
propertyResolver = new PropertySourcesPropertyResolver(propertySources); |
||||
assertThat(propertyResolver.asProperties(), notNullValue()); |
||||
|
||||
propertySources.addLast(new MockPropertySource("highestPrecedence").withProperty("common", "highCommon").withProperty("highKey", "highVal")); |
||||
propertySources.addLast(new MockPropertySource("middlePrecedence").withProperty("common", "midCommon").withProperty("midKey", "midVal")); |
||||
propertySources.addLast(new MockPropertySource("lowestPrecedence").withProperty("common", "lowCommon").withProperty("lowKey", "lowVal")); |
||||
|
||||
Properties props = propertyResolver.asProperties(); |
||||
assertThat(props.getProperty("common"), is("highCommon")); |
||||
assertThat(props.getProperty("lowKey"), is("lowVal")); |
||||
assertThat(props.getProperty("midKey"), is("midVal")); |
||||
assertThat(props.getProperty("highKey"), is("highVal")); |
||||
assertThat(props.size(), is(4)); |
||||
} |
||||
|
||||
@Test |
||||
public void asProperties_withMixedPropertySourceTypes() { |
||||
class Foo { } |
||||
class FooPropertySource extends PropertySource<Foo> { |
||||
public FooPropertySource() { super("fooProperties", new Foo()); } |
||||
public String[] getPropertyNames() { return new String[] {"pName"}; } |
||||
public String getProperty(String key) { return "fooValue"; } |
||||
} |
||||
propertySources = new MutablePropertySources(); |
||||
propertyResolver = new PropertySourcesPropertyResolver(propertySources); |
||||
assertThat(propertyResolver.asProperties(), notNullValue()); |
||||
|
||||
propertySources.addLast(new MockPropertySource()); |
||||
propertySources.addLast(new FooPropertySource()); |
||||
|
||||
Properties props = propertyResolver.asProperties(); |
||||
assertThat(props.getProperty("pName"), is("fooValue")); |
||||
assertThat(props.size(), is(1)); |
||||
} |
||||
|
||||
|
||||
@Test |
||||
public void resolvePlaceholders() { |
||||
MutablePropertySources propertySources = new MutablePropertySources(); |
||||
propertySources.addFirst(new MockPropertySource().withProperty("key", "value")); |
||||
PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); |
||||
assertThat(resolver.resolvePlaceholders("Replace this ${key}"), equalTo("Replace this value")); |
||||
} |
||||
|
||||
@Test |
||||
public void resolvePlaceholders_withUnresolvable() { |
||||
MutablePropertySources propertySources = new MutablePropertySources(); |
||||
propertySources.addFirst(new MockPropertySource().withProperty("key", "value")); |
||||
PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); |
||||
assertThat(resolver.resolvePlaceholders("Replace this ${key} plus ${unknown}"), |
||||
equalTo("Replace this value plus ${unknown}")); |
||||
} |
||||
|
||||
@Test |
||||
public void resolvePlaceholders_withDefault() { |
||||
MutablePropertySources propertySources = new MutablePropertySources(); |
||||
propertySources.addFirst(new MockPropertySource().withProperty("key", "value")); |
||||
PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); |
||||
assertThat(resolver.resolvePlaceholders("Replace this ${key} plus ${unknown:defaultValue}"), |
||||
equalTo("Replace this value plus defaultValue")); |
||||
} |
||||
|
||||
@Test(expected=IllegalArgumentException.class) |
||||
public void resolvePlaceholders_withNullInput() { |
||||
new PropertySourcesPropertyResolver(new MutablePropertySources()).resolvePlaceholders(null); |
||||
} |
||||
|
||||
@Test |
||||
public void resolveRequiredPlaceholders() { |
||||
MutablePropertySources propertySources = new MutablePropertySources(); |
||||
propertySources.addFirst(new MockPropertySource().withProperty("key", "value")); |
||||
PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); |
||||
assertThat(resolver.resolveRequiredPlaceholders("Replace this ${key}"), equalTo("Replace this value")); |
||||
} |
||||
|
||||
@Test(expected=IllegalArgumentException.class) |
||||
public void resolveRequiredPlaceholders_withUnresolvable() { |
||||
MutablePropertySources propertySources = new MutablePropertySources(); |
||||
propertySources.addFirst(new MockPropertySource().withProperty("key", "value")); |
||||
PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); |
||||
resolver.resolveRequiredPlaceholders("Replace this ${key} plus ${unknown}"); |
||||
} |
||||
|
||||
@Test |
||||
public void resolveRequiredPlaceholders_withDefault() { |
||||
MutablePropertySources propertySources = new MutablePropertySources(); |
||||
propertySources.addFirst(new MockPropertySource().withProperty("key", "value")); |
||||
PropertyResolver resolver = new PropertySourcesPropertyResolver(propertySources); |
||||
assertThat(resolver.resolveRequiredPlaceholders("Replace this ${key} plus ${unknown:defaultValue}"), |
||||
equalTo("Replace this value plus defaultValue")); |
||||
} |
||||
|
||||
@Test(expected=IllegalArgumentException.class) |
||||
public void resolveRequiredPlaceholders_withNullInput() { |
||||
new PropertySourcesPropertyResolver(new MutablePropertySources()).resolveRequiredPlaceholders(null); |
||||
} |
||||
} |
||||
@ -0,0 +1,149 @@
@@ -0,0 +1,149 @@
|
||||
/* |
||||
* Copyright 2002-2010 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.core.env; |
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo; |
||||
import static org.hamcrest.CoreMatchers.is; |
||||
import static org.hamcrest.CoreMatchers.not; |
||||
import static org.hamcrest.CoreMatchers.nullValue; |
||||
import static org.junit.Assert.assertEquals; |
||||
import static org.junit.Assert.assertThat; |
||||
import static org.junit.Assert.fail; |
||||
|
||||
import org.junit.Test; |
||||
import org.springframework.mock.env.MockPropertySource; |
||||
|
||||
public class PropertySourcesTests { |
||||
@Test |
||||
public void test() { |
||||
MutablePropertySources sources = new MutablePropertySources(); |
||||
sources.addLast(new MockPropertySource("b").withProperty("p1", "bValue")); |
||||
sources.addLast(new MockPropertySource("d").withProperty("p1", "dValue")); |
||||
sources.addLast(new MockPropertySource("f").withProperty("p1", "fValue")); |
||||
|
||||
assertThat(sources.size(), equalTo(3)); |
||||
assertThat(sources.contains("a"), is(false)); |
||||
assertThat(sources.contains("b"), is(true)); |
||||
assertThat(sources.contains("c"), is(false)); |
||||
assertThat(sources.contains("d"), is(true)); |
||||
assertThat(sources.contains("e"), is(false)); |
||||
assertThat(sources.contains("f"), is(true)); |
||||
assertThat(sources.contains("g"), is(false)); |
||||
|
||||
assertThat(sources.get("b"), not(nullValue())); |
||||
assertThat(sources.get("b").getProperty("p1"), equalTo("bValue")); |
||||
assertThat(sources.get("d"), not(nullValue())); |
||||
assertThat(sources.get("d").getProperty("p1"), equalTo("dValue")); |
||||
|
||||
sources.addBefore("b", new MockPropertySource("a")); |
||||
sources.addAfter("b", new MockPropertySource("c")); |
||||
|
||||
assertThat(sources.size(), equalTo(5)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("a")), is(0)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("b")), is(1)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("c")), is(2)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("d")), is(3)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("f")), is(4)); |
||||
|
||||
sources.addBefore("f", new MockPropertySource("e")); |
||||
sources.addAfter("f", new MockPropertySource("g")); |
||||
|
||||
assertThat(sources.size(), equalTo(7)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("a")), is(0)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("b")), is(1)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("c")), is(2)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("d")), is(3)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("e")), is(4)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("f")), is(5)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("g")), is(6)); |
||||
|
||||
sources.addLast(new MockPropertySource("a")); |
||||
assertThat(sources.size(), equalTo(7)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("b")), is(0)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("c")), is(1)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("d")), is(2)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("e")), is(3)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("f")), is(4)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("g")), is(5)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("a")), is(6)); |
||||
|
||||
sources.addFirst(new MockPropertySource("a")); |
||||
assertThat(sources.size(), equalTo(7)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("a")), is(0)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("b")), is(1)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("c")), is(2)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("d")), is(3)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("e")), is(4)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("f")), is(5)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("g")), is(6)); |
||||
|
||||
assertEquals(sources.remove("a"), PropertySource.named("a")); |
||||
assertThat(sources.size(), equalTo(6)); |
||||
assertThat(sources.contains("a"), is(false)); |
||||
|
||||
assertEquals(sources.remove("a"), null); |
||||
assertThat(sources.size(), equalTo(6)); |
||||
|
||||
String bogusPS = "bogus"; |
||||
try { |
||||
sources.addAfter(bogusPS, new MockPropertySource("h")); |
||||
fail("expected non-existent PropertySource exception"); |
||||
} catch (IllegalArgumentException ex) { |
||||
assertThat(ex.getMessage(), |
||||
equalTo(String.format(MutablePropertySources.NON_EXISTENT_PROPERTY_SOURCE_MESSAGE, bogusPS))); |
||||
} |
||||
|
||||
sources.addFirst(new MockPropertySource("a")); |
||||
assertThat(sources.size(), equalTo(7)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("a")), is(0)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("b")), is(1)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("c")), is(2)); |
||||
|
||||
sources.replace("a", new MockPropertySource("a-replaced")); |
||||
assertThat(sources.size(), equalTo(7)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("a-replaced")), is(0)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("b")), is(1)); |
||||
assertThat(sources.asList().indexOf(PropertySource.named("c")), is(2)); |
||||
|
||||
sources.replace("a-replaced", new MockPropertySource("a")); |
||||
|
||||
try { |
||||
sources.replace(bogusPS, new MockPropertySource("bogus-replaced")); |
||||
fail("expected non-existent PropertySource exception"); |
||||
} catch (IllegalArgumentException ex) { |
||||
assertThat(ex.getMessage(), |
||||
equalTo(String.format(MutablePropertySources.NON_EXISTENT_PROPERTY_SOURCE_MESSAGE, bogusPS))); |
||||
} |
||||
|
||||
try { |
||||
sources.addBefore("b", new MockPropertySource("b")); |
||||
fail("expected exception"); |
||||
} catch (IllegalArgumentException ex) { |
||||
assertThat(ex.getMessage(), |
||||
equalTo(String.format(MutablePropertySources.ILLEGAL_RELATIVE_ADDITION_MESSAGE, "b"))); |
||||
} |
||||
|
||||
try { |
||||
sources.addAfter("b", new MockPropertySource("b")); |
||||
fail("expected exception"); |
||||
} catch (IllegalArgumentException ex) { |
||||
assertThat(ex.getMessage(), |
||||
equalTo(String.format(MutablePropertySources.ILLEGAL_RELATIVE_ADDITION_MESSAGE, "b"))); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
/* |
||||
* 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.mock.env; |
||||
|
||||
import java.util.Properties; |
||||
|
||||
import org.springframework.core.env.PropertiesPropertySource; |
||||
import org.springframework.core.env.PropertySource; |
||||
|
||||
/** |
||||
* Simple {@link PropertySource} implementation for use in testing. Accepts |
||||
* a user-provided {@link Properties} object, or if omitted during construction, |
||||
* the implementation will initialize its own. |
||||
* |
||||
* The {@link #setProperty} and {@link #withProperty} methods are exposed for |
||||
* convenience, for example: |
||||
* <pre> |
||||
* {@code |
||||
* PropertySource<?> source = new MockPropertySource().withProperty("foo", "bar"); |
||||
* } |
||||
* </pre> |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
* @see MockEnvironment |
||||
*/ |
||||
public class MockPropertySource extends PropertiesPropertySource { |
||||
|
||||
/** |
||||
* {@value} is the default name for {@link MockPropertySource} instances not |
||||
* otherwise given an explicit name. |
||||
* @see #MockPropertySource() |
||||
* @see #MockPropertySource(String) |
||||
*/ |
||||
public static final String MOCK_PROPERTIES_PROPERTY_SOURCE_NAME = "mockProperties"; |
||||
|
||||
/** |
||||
* Create a new {@code MockPropertySource} named {@value #MOCK_PROPERTIES_PROPERTY_SOURCE_NAME} |
||||
* that will maintain its own internal {@link Properties} instance. |
||||
*/ |
||||
public MockPropertySource() { |
||||
this(new Properties()); |
||||
} |
||||
|
||||
/** |
||||
* Create a new {@code MockPropertySource} with the given name that will |
||||
* maintain its own internal {@link Properties} instance. |
||||
* @param name the {@linkplain #getName() name} of the property source |
||||
*/ |
||||
public MockPropertySource(String name) { |
||||
this(name, new Properties()); |
||||
} |
||||
|
||||
/** |
||||
* Create a new {@code MockPropertySource} named {@value #MOCK_PROPERTIES_PROPERTY_SOURCE_NAME} |
||||
* and backed by the given {@link Properties} object. |
||||
* @param properties the properties to use |
||||
*/ |
||||
public MockPropertySource(Properties properties) { |
||||
this(MOCK_PROPERTIES_PROPERTY_SOURCE_NAME, properties); |
||||
} |
||||
|
||||
/** |
||||
* Create a new {@code MockPropertySource} with with the given name and backed by the given |
||||
* {@link Properties} object |
||||
* @param name the {@linkplain #getName() name} of the property source |
||||
* @param properties the properties to use |
||||
*/ |
||||
public MockPropertySource(String name, Properties properties) { |
||||
super(name, properties); |
||||
} |
||||
|
||||
/** |
||||
* Set the given property on the underlying {@link Properties} object. |
||||
*/ |
||||
public void setProperty(String key, String value) { |
||||
this.source.put(key, value); |
||||
} |
||||
|
||||
/** |
||||
* Convenient synonym for {@link #setProperty} that returns the current instance. |
||||
* Useful for method chaining and fluent-style use. |
||||
* @return this {@link MockPropertySource} instance |
||||
*/ |
||||
public MockPropertySource withProperty(String key, String value) { |
||||
this.setProperty(key, value); |
||||
return this; |
||||
} |
||||
} |
||||
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
/* |
||||
* 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.mock.env; |
||||
|
||||
import java.util.Properties; |
||||
|
||||
import org.springframework.core.env.PropertiesPropertySource; |
||||
import org.springframework.core.env.PropertySource; |
||||
|
||||
/** |
||||
* Simple {@link PropertySource} implementation for use in testing. Accepts |
||||
* a user-provided {@link Properties} object, or if omitted during construction, |
||||
* the implementation will initialize its own. |
||||
* |
||||
* The {@link #setProperty} and {@link #withProperty} methods are exposed for |
||||
* convenience, for example: |
||||
* <pre> |
||||
* {@code |
||||
* PropertySource<?> source = new MockPropertySource().withProperty("foo", "bar"); |
||||
* } |
||||
* </pre> |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
* @see MockEnvironment |
||||
*/ |
||||
public class MockPropertySource extends PropertiesPropertySource { |
||||
|
||||
/** |
||||
* {@value} is the default name for {@link MockPropertySource} instances not |
||||
* otherwise given an explicit name. |
||||
* @see #MockPropertySource() |
||||
* @see #MockPropertySource(String) |
||||
*/ |
||||
public static final String MOCK_PROPERTIES_PROPERTY_SOURCE_NAME = "mockProperties"; |
||||
|
||||
/** |
||||
* Create a new {@code MockPropertySource} named {@value #MOCK_PROPERTIES_PROPERTY_SOURCE_NAME} |
||||
* that will maintain its own internal {@link Properties} instance. |
||||
*/ |
||||
public MockPropertySource() { |
||||
this(new Properties()); |
||||
} |
||||
|
||||
/** |
||||
* Create a new {@code MockPropertySource} with the given name that will |
||||
* maintain its own internal {@link Properties} instance. |
||||
* @param name the {@linkplain #getName() name} of the property source |
||||
*/ |
||||
public MockPropertySource(String name) { |
||||
this(name, new Properties()); |
||||
} |
||||
|
||||
/** |
||||
* Create a new {@code MockPropertySource} named {@value #MOCK_PROPERTIES_PROPERTY_SOURCE_NAME} |
||||
* and backed by the given {@link Properties} object. |
||||
* @param properties the properties to use |
||||
*/ |
||||
public MockPropertySource(Properties properties) { |
||||
this(MOCK_PROPERTIES_PROPERTY_SOURCE_NAME, properties); |
||||
} |
||||
|
||||
/** |
||||
* Create a new {@code MockPropertySource} with with the given name and backed by the given |
||||
* {@link Properties} object |
||||
* @param name the {@linkplain #getName() name} of the property source |
||||
* @param properties the properties to use |
||||
*/ |
||||
public MockPropertySource(String name, Properties properties) { |
||||
super(name, properties); |
||||
} |
||||
|
||||
/** |
||||
* Set the given property on the underlying {@link Properties} object. |
||||
*/ |
||||
public void setProperty(String key, String value) { |
||||
this.source.put(key, value); |
||||
} |
||||
|
||||
/** |
||||
* Convenient synonym for {@link #setProperty} that returns the current instance. |
||||
* Useful for method chaining and fluent-style use. |
||||
* @return this {@link MockPropertySource} instance |
||||
*/ |
||||
public MockPropertySource withProperty(String key, String value) { |
||||
this.setProperty(key, value); |
||||
return this; |
||||
} |
||||
} |
||||
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
/* |
||||
* 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.mock.env; |
||||
|
||||
import java.util.Properties; |
||||
|
||||
import org.springframework.core.env.PropertiesPropertySource; |
||||
import org.springframework.core.env.PropertySource; |
||||
|
||||
/** |
||||
* Simple {@link PropertySource} implementation for use in testing. Accepts |
||||
* a user-provided {@link Properties} object, or if omitted during construction, |
||||
* the implementation will initialize its own. |
||||
* |
||||
* The {@link #setProperty} and {@link #withProperty} methods are exposed for |
||||
* convenience, for example: |
||||
* <pre> |
||||
* {@code |
||||
* PropertySource<?> source = new MockPropertySource().withProperty("foo", "bar"); |
||||
* } |
||||
* </pre> |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
* @see MockEnvironment |
||||
*/ |
||||
public class MockPropertySource extends PropertiesPropertySource { |
||||
|
||||
/** |
||||
* {@value} is the default name for {@link MockPropertySource} instances not |
||||
* otherwise given an explicit name. |
||||
* @see #MockPropertySource() |
||||
* @see #MockPropertySource(String) |
||||
*/ |
||||
public static final String MOCK_PROPERTIES_PROPERTY_SOURCE_NAME = "mockProperties"; |
||||
|
||||
/** |
||||
* Create a new {@code MockPropertySource} named {@value #MOCK_PROPERTIES_PROPERTY_SOURCE_NAME} |
||||
* that will maintain its own internal {@link Properties} instance. |
||||
*/ |
||||
public MockPropertySource() { |
||||
this(new Properties()); |
||||
} |
||||
|
||||
/** |
||||
* Create a new {@code MockPropertySource} with the given name that will |
||||
* maintain its own internal {@link Properties} instance. |
||||
* @param name the {@linkplain #getName() name} of the property source |
||||
*/ |
||||
public MockPropertySource(String name) { |
||||
this(name, new Properties()); |
||||
} |
||||
|
||||
/** |
||||
* Create a new {@code MockPropertySource} named {@value #MOCK_PROPERTIES_PROPERTY_SOURCE_NAME} |
||||
* and backed by the given {@link Properties} object. |
||||
* @param properties the properties to use |
||||
*/ |
||||
public MockPropertySource(Properties properties) { |
||||
this(MOCK_PROPERTIES_PROPERTY_SOURCE_NAME, properties); |
||||
} |
||||
|
||||
/** |
||||
* Create a new {@code MockPropertySource} with with the given name and backed by the given |
||||
* {@link Properties} object |
||||
* @param name the {@linkplain #getName() name} of the property source |
||||
* @param properties the properties to use |
||||
*/ |
||||
public MockPropertySource(String name, Properties properties) { |
||||
super(name, properties); |
||||
} |
||||
|
||||
/** |
||||
* Set the given property on the underlying {@link Properties} object. |
||||
*/ |
||||
public void setProperty(String key, String value) { |
||||
this.source.put(key, value); |
||||
} |
||||
|
||||
/** |
||||
* Convenient synonym for {@link #setProperty} that returns the current instance. |
||||
* Useful for method chaining and fluent-style use. |
||||
* @return this {@link MockPropertySource} instance |
||||
*/ |
||||
public MockPropertySource withProperty(String key, String value) { |
||||
this.setProperty(key, value); |
||||
return this; |
||||
} |
||||
} |
||||
@ -0,0 +1,79 @@
@@ -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)); |
||||
} |
||||
} |
||||
@ -0,0 +1,46 @@
@@ -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 @@
@@ -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); |
||||
} |
||||
} |
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue