Commit a4240818 authored by Rubinson,Ethan(erubinson)'s avatar Rubinson,Ethan(erubinson) Committed by Andy Wilkinson

Copy conversion service when performing environment conversion

Previously, when a web environment was converted to a
StandardEnvironment, any customizations of the source environment's
ConversionService were lost.

This commit updates the logic that performs the conversion to copy
the source's ConversionService to the converted environment, thereby
ensuring that any customizations are retained.

Closes gh-9259
See gh-9246
parent 84721666
/*
* Copyright 2012-2017 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.boot;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.web.context.support.StandardServletEnvironment;
/**
* Utility class for converting one environment type to another.
*
* @author Ethan Rubinson
* @since 1.5.4
*/
final class EnvironmentConverter {
private static final Set<String> SERVLET_ENVIRONMENT_SOURCE_NAMES;
static {
final Set<String> names = new HashSet<String>();
names.add(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME);
names.add(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME);
names.add(StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME);
SERVLET_ENVIRONMENT_SOURCE_NAMES = Collections.unmodifiableSet(names);
}
private EnvironmentConverter() {
}
/**
* Converts the specified environment to a {@link StandardEnvironment}.
*
* @param environment The environment to convert.
* @return The converted environment.
*/
protected static ConfigurableEnvironment convertToStandardEnvironment(
ConfigurableEnvironment environment) {
final StandardEnvironment result = new StandardEnvironment();
/* Copy the profiles */
result.setActiveProfiles(environment.getActiveProfiles());
/* Copy the conversion service */
result.setConversionService(environment.getConversionService());
/*
* Copy over all of the property sources except those unrelated to a standard
* environment
*/
removeAllPropertySources(result.getPropertySources());
for (PropertySource<?> propertySource : environment.getPropertySources()) {
if (!SERVLET_ENVIRONMENT_SOURCE_NAMES.contains(propertySource.getName())) {
result.getPropertySources().addLast(propertySource);
}
}
return result;
}
private static void removeAllPropertySources(MutablePropertySources propertySources) {
final Set<String> names = new HashSet<String>();
for (PropertySource<?> propertySource : propertySources) {
names.add(propertySource.getName());
}
for (String name : names) {
propertySources.remove(name);
}
}
}
...@@ -140,6 +140,7 @@ import org.springframework.web.context.support.StandardServletEnvironment; ...@@ -140,6 +140,7 @@ import org.springframework.web.context.support.StandardServletEnvironment;
* @author Jeremy Rickard * @author Jeremy Rickard
* @author Craig Burke * @author Craig Burke
* @author Michael Simons * @author Michael Simons
* @author Ethan Rubinson
* @see #run(Object, String[]) * @see #run(Object, String[])
* @see #run(Object[], String[]) * @see #run(Object[], String[])
* @see #SpringApplication(Object...) * @see #SpringApplication(Object...)
...@@ -177,16 +178,6 @@ public class SpringApplication { ...@@ -177,16 +178,6 @@ public class SpringApplication {
private static final String SYSTEM_PROPERTY_JAVA_AWT_HEADLESS = "java.awt.headless"; private static final String SYSTEM_PROPERTY_JAVA_AWT_HEADLESS = "java.awt.headless";
private static final Set<String> SERVLET_ENVIRONMENT_SOURCE_NAMES;
static {
Set<String> names = new HashSet<String>();
names.add(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME);
names.add(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME);
names.add(StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME);
SERVLET_ENVIRONMENT_SOURCE_NAMES = Collections.unmodifiableSet(names);
}
private static final Log logger = LogFactory.getLog(SpringApplication.class); private static final Log logger = LogFactory.getLog(SpringApplication.class);
private final Set<Object> sources = new LinkedHashSet<Object>(); private final Set<Object> sources = new LinkedHashSet<Object>();
...@@ -335,7 +326,7 @@ public class SpringApplication { ...@@ -335,7 +326,7 @@ public class SpringApplication {
configureEnvironment(environment, applicationArguments.getSourceArgs()); configureEnvironment(environment, applicationArguments.getSourceArgs());
listeners.environmentPrepared(environment); listeners.environmentPrepared(environment);
if (isWebEnvironment(environment) && !this.webEnvironment) { if (isWebEnvironment(environment) && !this.webEnvironment) {
environment = convertToStandardEnvironment(environment); environment = EnvironmentConverter.convertToStandardEnvironment(environment);
} }
return environment; return environment;
} }
...@@ -465,29 +456,6 @@ public class SpringApplication { ...@@ -465,29 +456,6 @@ public class SpringApplication {
} }
} }
private ConfigurableEnvironment convertToStandardEnvironment(
ConfigurableEnvironment environment) {
StandardEnvironment result = new StandardEnvironment();
removeAllPropertySources(result.getPropertySources());
result.setActiveProfiles(environment.getActiveProfiles());
for (PropertySource<?> propertySource : environment.getPropertySources()) {
if (!SERVLET_ENVIRONMENT_SOURCE_NAMES.contains(propertySource.getName())) {
result.getPropertySources().addLast(propertySource);
}
}
return result;
}
private void removeAllPropertySources(MutablePropertySources propertySources) {
Set<String> names = new HashSet<String>();
for (PropertySource<?> propertySource : propertySources) {
names.add(propertySource.getName());
}
for (String name : names) {
propertySources.remove(name);
}
}
/** /**
* Add, remove or re-order any {@link PropertySource}s in this application's * Add, remove or re-order any {@link PropertySource}s in this application's
* environment. * environment.
......
/*
* Copyright 2012-2017 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.boot;
import org.bouncycastle.util.Arrays;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.convert.support.ConfigurableConversionService;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.mock.env.MockEnvironment;
/**
* Tests for the {@link EnvironmentConverter} methods
*
* @author Ethan Rubinson
*/
public class EnvironmentConverterTest {
@Test
public void testConvertAbstractEnvironmentToStandardEnvironment() throws Exception {
final AbstractEnvironment baseEnv = new MockEnvironment();
final CustomConversionService customConverterServce = new CustomConversionService(
baseEnv.getConversionService());
final String[] activeProfiles = new String[] { "activeProfile1", "activeProfile2" };
baseEnv.setActiveProfiles(activeProfiles);
baseEnv.setConversionService(customConverterServce);
ConfigurableEnvironment convertedEnv = EnvironmentConverter
.convertToStandardEnvironment(baseEnv);
Assert.assertTrue(Arrays.areEqual(activeProfiles,
convertedEnv.getActiveProfiles()));
Assert.assertEquals(customConverterServce, convertedEnv.getConversionService());
}
private class CustomConversionService implements ConfigurableConversionService {
private final ConfigurableConversionService delegate;
CustomConversionService(ConfigurableConversionService delegate) {
this.delegate = delegate;
}
@Override
public boolean canConvert(Class<?> sourceType, Class<?> targetType) {
return this.delegate.canConvert(sourceType, targetType);
}
@Override
public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.delegate.canConvert(sourceType, targetType);
}
@Override
public <T> T convert(Object source, Class<T> targetType) {
return this.delegate.convert(source, targetType);
}
@Override
public Object convert(Object source, TypeDescriptor sourceType,
TypeDescriptor targetType) {
return this.delegate.convert(source, sourceType, targetType);
}
@Override
public void addConverter(Converter<?, ?> converter) {
this.delegate.addConverter(converter);
}
@Override
public <S, T> void addConverter(Class<S> sourceType, Class<T> targetType,
Converter<? super S, ? extends T> converter) {
this.delegate.addConverter(sourceType, targetType, converter);
}
@Override
public void addConverter(GenericConverter converter) {
this.delegate.addConverter(converter);
}
@Override
public void addConverterFactory(ConverterFactory<?, ?> factory) {
this.delegate.addConverterFactory(factory);
}
@Override
public void removeConvertible(Class<?> sourceType, Class<?> targetType) {
this.delegate.removeConvertible(sourceType, targetType);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment