diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mobile/DevceDelegatingViewResolverAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mobile/DevceDelegatingViewResolverAutoConfiguration.java new file mode 100644 index 0000000000..2d14e93d4c --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mobile/DevceDelegatingViewResolverAutoConfiguration.java @@ -0,0 +1,162 @@ +/* + * Copyright 2012-2014 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.autoconfigure.mobile; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration; +import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; +import org.springframework.boot.bind.RelaxedPropertyResolver; +import org.springframework.context.EnvironmentAware; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.env.Environment; +import org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.view.InternalResourceViewResolver; +import org.thymeleaf.spring4.view.ThymeleafViewResolver; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Spring Mobile's + * {@link LiteDeviceDelegatingViewResolver}. If {@link ThymeleafViewResolver} is available + * it is configured as the delegate view resolver. Otherwise, + * {@link InternalResourceViewResolver} is used as a fallback. + * + * @author Roy Clarkson + * @since 1.1.0 + */ +@Configuration +@ConditionalOnWebApplication +@ConditionalOnClass(LiteDeviceDelegatingViewResolver.class) +@AutoConfigureAfter(WebMvcAutoConfiguration.class) +public class DevceDelegatingViewResolverAutoConfiguration { + + private static Log logger = LogFactory.getLog(WebMvcConfigurerAdapter.class); + + public static final String DEFAULT_NORMAL_PREFIX = ""; + + public static final String DEFAULT_MOBILE_PREFIX = "mobile/"; + + public static final String DEFAULT_TABLET_PREFIX = "tablet/"; + + public static final String DEFAULT_NORMAL_SUFFIX = ""; + + public static final String DEFAULT_MOBILE_SUFFIX = ""; + + public static final String DEFAULT_TABLET_SUFFIX = ""; + + @Configuration + @ConditionalOnMissingBean(name = "deviceDelegatingViewResolver") + @ConditionalOnExpression("${spring.mobile.deviceDelegatingViewResolver.enabled:false}") + protected static class DevceDelegatingViewResolverConfiguration { + + @Configuration + @ConditionalOnBean(ThymeleafViewResolver.class) + @AutoConfigureAfter(ThymeleafAutoConfiguration.class) + protected static class ThymeleafViewResolverViewResolverDelegateConfiguration + extends AbstractDelegateConfiguration { + + @Autowired + private ThymeleafViewResolver thymeleafViewResolver; + + @Bean + public LiteDeviceDelegatingViewResolver deviceDelegatingViewResolver() { + if (logger.isDebugEnabled()) { + logger.debug("LiteDeviceDelegatingViewResolver delegates to ThymeleafViewResolver"); + } + return getConfiguredViewResolver(thymeleafViewResolver, + thymeleafViewResolver.getOrder()); + } + + } + + @Configuration + @ConditionalOnMissingBean(ThymeleafViewResolver.class) + @ConditionalOnBean(InternalResourceViewResolver.class) + protected static class InternalResourceViewResolverDelegateConfiguration extends + AbstractDelegateConfiguration { + + @Autowired + private InternalResourceViewResolver internalResourceViewResolver; + + @Bean + public LiteDeviceDelegatingViewResolver deviceDelegatingViewResolver() { + if (logger.isDebugEnabled()) { + logger.debug("LiteDeviceDelegatingViewResolver delegates to InternalResourceViewResolver"); + } + return getConfiguredViewResolver(internalResourceViewResolver, + internalResourceViewResolver.getOrder()); + } + + } + + private static abstract class AbstractDelegateConfiguration implements + EnvironmentAware { + + private RelaxedPropertyResolver environment; + + @Override + public void setEnvironment(Environment environment) { + this.environment = new RelaxedPropertyResolver(environment, + "spring.mobile.deviceDelegatingViewResolver."); + } + + protected LiteDeviceDelegatingViewResolver getConfiguredViewResolver( + ViewResolver delegate, int delegateOrder) { + LiteDeviceDelegatingViewResolver resolver = new LiteDeviceDelegatingViewResolver( + delegate); + resolver.setNormalPrefix(this.environment.getProperty("normalPrefix", + DEFAULT_NORMAL_PREFIX)); + resolver.setMobilePrefix(this.environment.getProperty("mobilePrefix", + DEFAULT_MOBILE_PREFIX)); + resolver.setTabletPrefix(this.environment.getProperty("tabletPrefix", + DEFAULT_TABLET_PREFIX)); + resolver.setNormalSuffix(this.environment.getProperty("normalSuffix", + DEFAULT_NORMAL_SUFFIX)); + resolver.setMobileSuffix(this.environment.getProperty("mobileSuffix", + DEFAULT_MOBILE_SUFFIX)); + resolver.setTabletSuffix(this.environment.getProperty("tabletSuffix", + DEFAULT_TABLET_SUFFIX)); + resolver.setOrder(getAdjustedOrder(delegateOrder)); + return resolver; + } + + private int getAdjustedOrder(int delegateViewResolverOrder) { + if (delegateViewResolverOrder == Ordered.HIGHEST_PRECEDENCE) { + return Ordered.HIGHEST_PRECEDENCE; + } else { + // The view resolver must be ordered higher than the delegate view + // resolver, otherwise the view names will not be adjusted + return delegateViewResolverOrder - 1; + } + } + + } + + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mobile/SitePreferenceAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mobile/SitePreferenceAutoConfiguration.java index 5551130e87..b15b309215 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mobile/SitePreferenceAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mobile/SitePreferenceAutoConfiguration.java @@ -45,9 +45,9 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter */ @Configuration @ConditionalOnClass({ SitePreferenceHandlerInterceptor.class, - SitePreferenceHandlerMethodArgumentResolver.class }) + SitePreferenceHandlerMethodArgumentResolver.class }) @AutoConfigureAfter(DeviceResolverAutoConfiguration.class) -@ConditionalOnExpression("${spring.mobile.enableSitePreference:true}") +@ConditionalOnExpression("${spring.mobile.sitePreference.enabled:true}") public class SitePreferenceAutoConfiguration { @Configuration diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index 7ac592d63a..c54471761b 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -29,6 +29,7 @@ org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\ org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\ org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\ +org.springframework.boot.autoconfigure.mobile.DevceDelegatingViewResolverAutoConfiguration,\ org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.MongoDataAutoConfiguration,\ diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mobile/DeviceDelegatingViewResolverAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mobile/DeviceDelegatingViewResolverAutoConfigurationTests.java new file mode 100644 index 0000000000..252681ca1f --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mobile/DeviceDelegatingViewResolverAutoConfigurationTests.java @@ -0,0 +1,356 @@ +/* + * Copyright 2012-2014 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.autoconfigure.mobile; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.lang.reflect.Field; + +import org.junit.After; +import org.junit.Test; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.autoconfigure.mobile.DevceDelegatingViewResolverAutoConfiguration.DevceDelegatingViewResolverConfiguration; +import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration; +import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; +import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext; +import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor; +import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; +import org.springframework.boot.context.embedded.MockEmbeddedServletContainerFactory; +import org.springframework.boot.test.EnvironmentTestUtils; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mobile.device.view.AbstractDeviceDelegatingViewResolver; +import org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver; +import org.springframework.util.ReflectionUtils; +import org.springframework.web.servlet.view.InternalResourceViewResolver; +import org.thymeleaf.spring4.view.ThymeleafViewResolver; + +/** + * Tests for {@link DevceDelegatingViewResolverAutoConfiguration}. + * + * @author Roy Clarkson + */ +public class DeviceDelegatingViewResolverAutoConfigurationTests { + + private static final MockEmbeddedServletContainerFactory containerFactory = new MockEmbeddedServletContainerFactory(); + + private AnnotationConfigEmbeddedWebApplicationContext context; + + @After + public void close() { + if (this.context != null) { + this.context.close(); + } + } + + @Test(expected = NoSuchBeanDefinitionException.class) + public void deviceDelegatingViewResolverDefaultDisabled() throws Exception { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + this.context.register(Config.class, + DevceDelegatingViewResolverConfiguration.class); + this.context.refresh(); + this.context.getBean("deviceDelegatingViewResolver", + AbstractDeviceDelegatingViewResolver.class); + } + + @Test + public void deviceDelegatingInternalResourceViewResolverEnabled() throws Exception { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + EnvironmentTestUtils.addEnvironment(context, + "spring.mobile.deviceDelegatingViewResolver.enabled:true"); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, + DevceDelegatingViewResolverConfiguration.class); + this.context.refresh(); + InternalResourceViewResolver internalResourceViewResolver = this.context.getBean(InternalResourceViewResolver.class); + AbstractDeviceDelegatingViewResolver deviceDelegatingViewResolver = this.context.getBean( + "deviceDelegatingViewResolver", + AbstractDeviceDelegatingViewResolver.class); + assertNotNull(internalResourceViewResolver); + assertNotNull(deviceDelegatingViewResolver); + assertTrue(deviceDelegatingViewResolver.getViewResolver() instanceof InternalResourceViewResolver); + try { + this.context.getBean(ThymeleafViewResolver.class); + } catch (NoSuchBeanDefinitionException e) { + // expected. ThymeleafViewResolver shouldn't be defined. + } + assertTrue(deviceDelegatingViewResolver.getOrder() == internalResourceViewResolver.getOrder() - 1); + } + + @Test(expected = NoSuchBeanDefinitionException.class) + public void deviceDelegatingInternalResourceViewResolverDisabled() throws Exception { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + EnvironmentTestUtils.addEnvironment(context, + "spring.mobile.deviceDelegatingViewResolver.enabled:false"); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, + DevceDelegatingViewResolverConfiguration.class); + this.context.refresh(); + assertNotNull(this.context.getBean(InternalResourceViewResolver.class)); + try { + this.context.getBean(ThymeleafViewResolver.class); + } catch (NoSuchBeanDefinitionException e) { + // expected. ThymeleafViewResolver shouldn't be defined. + } + this.context.getBean("deviceDelegatingViewResolver", + AbstractDeviceDelegatingViewResolver.class); + } + + @Test + public void deviceDelegatingThymeleafViewResolverEnabled() throws Exception { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + EnvironmentTestUtils.addEnvironment(context, + "spring.mobile.deviceDelegatingViewResolver.enabled:true"); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + ThymeleafAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, + DevceDelegatingViewResolverConfiguration.class); + this.context.refresh(); + ThymeleafViewResolver thymeleafViewResolver = this.context.getBean(ThymeleafViewResolver.class); + AbstractDeviceDelegatingViewResolver deviceDelegatingViewResolver = this.context.getBean( + "deviceDelegatingViewResolver", + AbstractDeviceDelegatingViewResolver.class); + assertNotNull(thymeleafViewResolver); + assertNotNull(deviceDelegatingViewResolver); + assertTrue(deviceDelegatingViewResolver.getViewResolver() instanceof ThymeleafViewResolver); + assertNotNull(this.context.getBean(InternalResourceViewResolver.class)); + assertNotNull(this.context.getBean(ThymeleafViewResolver.class)); + assertTrue(deviceDelegatingViewResolver.getOrder() == thymeleafViewResolver.getOrder() - 1); + } + + @Test(expected = NoSuchBeanDefinitionException.class) + public void deviceDelegatingThymeleafViewResolverDisabled() throws Exception { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + EnvironmentTestUtils.addEnvironment(context, + "spring.mobile.deviceDelegatingViewResolver.enabled:false"); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + ThymeleafAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, + DevceDelegatingViewResolverConfiguration.class); + this.context.refresh(); + assertNotNull(this.context.getBean(InternalResourceViewResolver.class)); + assertNotNull(this.context.getBean(ThymeleafViewResolver.class)); + this.context.getBean("deviceDelegatingViewResolver", + AbstractDeviceDelegatingViewResolver.class); + } + + @Test + public void defaultPropertyValues() throws Exception { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + EnvironmentTestUtils.addEnvironment(context, + "spring.mobile.deviceDelegatingViewResolver.enabled:true"); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, + DevceDelegatingViewResolverConfiguration.class); + this.context.refresh(); + LiteDeviceDelegatingViewResolver liteDeviceDelegatingViewResolver = this.context.getBean( + "deviceDelegatingViewResolver", LiteDeviceDelegatingViewResolver.class); + + Field normalPrefixField = ReflectionUtils.findField( + LiteDeviceDelegatingViewResolver.class, "normalPrefix"); + normalPrefixField.setAccessible(true); + String normalPrefix = (String) ReflectionUtils.getField(normalPrefixField, + liteDeviceDelegatingViewResolver); + assertEquals("", normalPrefix); + + Field mobilePrefixField = ReflectionUtils.findField( + LiteDeviceDelegatingViewResolver.class, "mobilePrefix"); + mobilePrefixField.setAccessible(true); + String mobilePrefix = (String) ReflectionUtils.getField(mobilePrefixField, + liteDeviceDelegatingViewResolver); + assertEquals("mobile/", mobilePrefix); + + Field tabletPrefixField = ReflectionUtils.findField( + LiteDeviceDelegatingViewResolver.class, "tabletPrefix"); + tabletPrefixField.setAccessible(true); + String tabletPrefix = (String) ReflectionUtils.getField(tabletPrefixField, + liteDeviceDelegatingViewResolver); + assertEquals("tablet/", tabletPrefix); + + Field normalSuffixField = ReflectionUtils.findField( + LiteDeviceDelegatingViewResolver.class, "normalSuffix"); + normalSuffixField.setAccessible(true); + String normalSuffix = (String) ReflectionUtils.getField(normalSuffixField, + liteDeviceDelegatingViewResolver); + assertEquals("", normalSuffix); + + Field mobileSuffixField = ReflectionUtils.findField( + LiteDeviceDelegatingViewResolver.class, "mobileSuffix"); + mobileSuffixField.setAccessible(true); + String mobileSuffix = (String) ReflectionUtils.getField(mobileSuffixField, + liteDeviceDelegatingViewResolver); + assertEquals("", mobileSuffix); + + Field tabletSuffixField = ReflectionUtils.findField( + LiteDeviceDelegatingViewResolver.class, "tabletSuffix"); + tabletSuffixField.setAccessible(true); + String tabletSuffix = (String) ReflectionUtils.getField(tabletSuffixField, + liteDeviceDelegatingViewResolver); + assertEquals("", tabletSuffix); + } + + @Test + public void overrideNormalPrefix() throws Exception { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + EnvironmentTestUtils.addEnvironment(context, + "spring.mobile.deviceDelegatingViewResolver.enabled:true", + "spring.mobile.deviceDelegatingViewResolver.normalPrefix:normal/"); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, + DevceDelegatingViewResolverConfiguration.class); + this.context.refresh(); + LiteDeviceDelegatingViewResolver liteDeviceDelegatingViewResolver = this.context.getBean( + "deviceDelegatingViewResolver", LiteDeviceDelegatingViewResolver.class); + Field normalPrefixField = ReflectionUtils.findField( + LiteDeviceDelegatingViewResolver.class, "normalPrefix"); + normalPrefixField.setAccessible(true); + String normalPrefix = (String) ReflectionUtils.getField(normalPrefixField, + liteDeviceDelegatingViewResolver); + assertEquals("normal/", normalPrefix); + } + + @Test + public void overrideMobilePrefix() throws Exception { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + EnvironmentTestUtils.addEnvironment(context, + "spring.mobile.deviceDelegatingViewResolver.enabled:true", + "spring.mobile.deviceDelegatingViewResolver.mobilePrefix:mob/"); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, + DevceDelegatingViewResolverConfiguration.class); + this.context.refresh(); + LiteDeviceDelegatingViewResolver liteDeviceDelegatingViewResolver = this.context.getBean( + "deviceDelegatingViewResolver", LiteDeviceDelegatingViewResolver.class); + Field mobilePrefixField = ReflectionUtils.findField( + LiteDeviceDelegatingViewResolver.class, "mobilePrefix"); + mobilePrefixField.setAccessible(true); + String mobilePrefix = (String) ReflectionUtils.getField(mobilePrefixField, + liteDeviceDelegatingViewResolver); + assertEquals("mob/", mobilePrefix); + } + + @Test + public void overrideTabletPrefix() throws Exception { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + EnvironmentTestUtils.addEnvironment(context, + "spring.mobile.deviceDelegatingViewResolver.enabled:true", + "spring.mobile.deviceDelegatingViewResolver.tabletPrefix:tab/"); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, + DevceDelegatingViewResolverConfiguration.class); + this.context.refresh(); + LiteDeviceDelegatingViewResolver liteDeviceDelegatingViewResolver = this.context.getBean( + "deviceDelegatingViewResolver", LiteDeviceDelegatingViewResolver.class); + Field tabletPrefixField = ReflectionUtils.findField( + LiteDeviceDelegatingViewResolver.class, "tabletPrefix"); + tabletPrefixField.setAccessible(true); + String tabletPrefix = (String) ReflectionUtils.getField(tabletPrefixField, + liteDeviceDelegatingViewResolver); + assertEquals("tab/", tabletPrefix); + } + + @Test + public void overrideNormalSuffix() throws Exception { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + EnvironmentTestUtils.addEnvironment(context, + "spring.mobile.deviceDelegatingViewResolver.enabled:true", + "spring.mobile.deviceDelegatingViewResolver.normalSuffix:.nor"); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, + DevceDelegatingViewResolverConfiguration.class); + this.context.refresh(); + LiteDeviceDelegatingViewResolver liteDeviceDelegatingViewResolver = this.context.getBean( + "deviceDelegatingViewResolver", LiteDeviceDelegatingViewResolver.class); + Field normalSuffixField = ReflectionUtils.findField( + LiteDeviceDelegatingViewResolver.class, "normalSuffix"); + normalSuffixField.setAccessible(true); + String normalSuffix = (String) ReflectionUtils.getField(normalSuffixField, + liteDeviceDelegatingViewResolver); + assertEquals(".nor", normalSuffix); + } + + @Test + public void overrideMobileSuffix() throws Exception { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + EnvironmentTestUtils.addEnvironment(context, + "spring.mobile.deviceDelegatingViewResolver.enabled:true", + "spring.mobile.deviceDelegatingViewResolver.mobileSuffix:.mob"); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, + DevceDelegatingViewResolverConfiguration.class); + this.context.refresh(); + LiteDeviceDelegatingViewResolver liteDeviceDelegatingViewResolver = this.context.getBean( + "deviceDelegatingViewResolver", LiteDeviceDelegatingViewResolver.class); + Field mobileSuffixField = ReflectionUtils.findField( + LiteDeviceDelegatingViewResolver.class, "mobileSuffix"); + mobileSuffixField.setAccessible(true); + String mobileSuffix = (String) ReflectionUtils.getField(mobileSuffixField, + liteDeviceDelegatingViewResolver); + assertEquals(".mob", mobileSuffix); + } + + @Test + public void overrideTabletSuffix() throws Exception { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + EnvironmentTestUtils.addEnvironment(context, + "spring.mobile.deviceDelegatingViewResolver.enabled:true", + "spring.mobile.deviceDelegatingViewResolver.tabletSuffix:.tab"); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, + DevceDelegatingViewResolverConfiguration.class); + this.context.refresh(); + LiteDeviceDelegatingViewResolver liteDeviceDelegatingViewResolver = this.context.getBean( + "deviceDelegatingViewResolver", LiteDeviceDelegatingViewResolver.class); + Field tabletSuffixField = ReflectionUtils.findField( + LiteDeviceDelegatingViewResolver.class, "tabletSuffix"); + tabletSuffixField.setAccessible(true); + String tabletSuffix = (String) ReflectionUtils.getField(tabletSuffixField, + liteDeviceDelegatingViewResolver); + assertEquals(".tab", tabletSuffix); + } + + @Configuration + protected static class Config { + + @Bean + public EmbeddedServletContainerFactory containerFactory() { + return containerFactory; + } + + @Bean + public EmbeddedServletContainerCustomizerBeanPostProcessor embeddedServletContainerCustomizerBeanPostProcessor() { + return new EmbeddedServletContainerCustomizerBeanPostProcessor(); + } + + } + +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mobile/SitePreferenceAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mobile/SitePreferenceAutoConfigurationTests.java index e5aa394a8b..40333035d9 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mobile/SitePreferenceAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mobile/SitePreferenceAutoConfigurationTests.java @@ -70,7 +70,7 @@ public class SitePreferenceAutoConfigurationTests { @Test public void sitePreferenceHandlerInterceptorEnabled() throws Exception { this.context = new AnnotationConfigWebApplicationContext(); - EnvironmentTestUtils.addEnvironment(context, "spring.mobile.enableSitePreference:true"); + EnvironmentTestUtils.addEnvironment(context, "spring.mobile.sitePreference.enabled:true"); this.context.register(SitePreferenceAutoConfiguration.class); this.context.refresh(); assertNotNull(this.context.getBean(SitePreferenceHandlerInterceptor.class)); @@ -79,7 +79,7 @@ public class SitePreferenceAutoConfigurationTests { @Test(expected = NoSuchBeanDefinitionException.class) public void sitePreferenceHandlerInterceptorDisabled() { this.context = new AnnotationConfigWebApplicationContext(); - EnvironmentTestUtils.addEnvironment(context, "spring.mobile.enableSitePreference:false"); + EnvironmentTestUtils.addEnvironment(context, "spring.mobile.sitePreference.enabled:false"); this.context.register(SitePreferenceAutoConfiguration.class); this.context.refresh(); this.context.getBean(SitePreferenceHandlerInterceptor.class); @@ -96,7 +96,7 @@ public class SitePreferenceAutoConfigurationTests { @Test public void sitePreferenceMethodArgumentResolverEnabled() throws Exception { this.context = new AnnotationConfigWebApplicationContext(); - EnvironmentTestUtils.addEnvironment(context, "spring.mobile.enableSitePreference:true"); + EnvironmentTestUtils.addEnvironment(context, "spring.mobile.sitePreference.enabled:true"); this.context.register(SitePreferenceAutoConfiguration.class); this.context.refresh(); assertNotNull(this.context.getBean(SitePreferenceHandlerMethodArgumentResolver.class)); @@ -105,7 +105,7 @@ public class SitePreferenceAutoConfigurationTests { @Test(expected = NoSuchBeanDefinitionException.class) public void sitePreferenceMethodArgumentResolverDisabled() { this.context = new AnnotationConfigWebApplicationContext(); - EnvironmentTestUtils.addEnvironment(context, "spring.mobile.enableSitePreference:false"); + EnvironmentTestUtils.addEnvironment(context, "spring.mobile.sitePreference.enabled:false"); this.context.register(SitePreferenceAutoConfiguration.class); this.context.refresh(); this.context.getBean(SitePreferenceHandlerMethodArgumentResolver.class); diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml index a19ec3870a..6cca2f6810 100644 --- a/spring-boot-dependencies/pom.xml +++ b/spring-boot-dependencies/pom.xml @@ -102,7 +102,7 @@ 0.12.0.RELEASE 4.0.2.RELEASE 1.2.0.RELEASE - 1.1.1.RELEASE + 1.1.2.RELEASE 1.1.0.RELEASE 1.1.1.RELEASE 1.1.0.RELEASE diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 8905da74cb..3a00aa2412 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -289,6 +289,18 @@ content into your application; rather pick only the properties that you need. spring.social.twitter.appId= # your application's Twitter App ID spring.social.twitter.appSecret= # your application's Twitter App Secret + # SPRING MOBILE SITE PREFERENCE ({sc-spring-boot-autoconfigure}/mobile/SitePreferenceAutoConfiguration.{sc-ext}[SitePreferenceAutoConfiguration]) + spring.mobile.sitePreference.enabled=true # enabled by default + + # SPRING MOBILE DEVICE VIEWS ({sc-spring-boot-autoconfigure}/mobile/DevceDelegatingViewResolverAutoConfiguration.{sc-ext}[DevceDelegatingViewResolverAutoConfiguration]) + spring.mobile.deviceDelegatingViewResolver.enabled=true # disabled by default + spring.mobile.deviceDelegatingViewResolver.normalPrefix=nor/ + spring.mobile.deviceDelegatingViewResolver.mobilePrefix=mob/ # default is "mobile/" + spring.mobile.deviceDelegatingViewResolver.tabletPrefix=tab/ # default is "tablet/" + spring.mobile.deviceDelegatingViewResolver.normalSuffix=.nor + spring.mobile.deviceDelegatingViewResolver.mobileSuffix=.mob + spring.mobile.deviceDelegatingViewResolver.tabletSuffix=.tab + # ---------------------------------------- # ACTUATOR PROPERTIES # ----------------------------------------