Support Spring Mobile for all template engines
Previously, Spring Mobile was only supported for Thymeleaf and JSPs. This commit improves the auto-configuration to also provide device delegating support for Freemarker, Groovy Templates and Mustache. Closes gh-5140
This commit is contained in:
parent
6dd8e71d06
commit
c024dc836a
|
@ -16,27 +16,27 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.mobile;
|
package org.springframework.boot.autoconfigure.mobile;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
|
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.mustache.web.MustacheViewResolver;
|
||||||
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
|
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
|
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.Ordered;
|
|
||||||
import org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver;
|
import org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver;
|
||||||
import org.springframework.web.servlet.ViewResolver;
|
|
||||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||||
|
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
|
||||||
|
import org.springframework.web.servlet.view.groovy.GroovyMarkupViewResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link EnableAutoConfiguration Auto-configuration} for Spring Mobile's
|
* {@link EnableAutoConfiguration Auto-configuration} for Spring Mobile's
|
||||||
|
@ -45,102 +45,96 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||||
* {@link InternalResourceViewResolver} is used as a fallback.
|
* {@link InternalResourceViewResolver} is used as a fallback.
|
||||||
*
|
*
|
||||||
* @author Roy Clarkson
|
* @author Roy Clarkson
|
||||||
|
* @author Stephane Nicoll
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnWebApplication
|
@ConditionalOnWebApplication
|
||||||
@ConditionalOnClass(LiteDeviceDelegatingViewResolver.class)
|
@ConditionalOnClass(LiteDeviceDelegatingViewResolver.class)
|
||||||
@AutoConfigureAfter({ WebMvcAutoConfiguration.class, ThymeleafAutoConfiguration.class })
|
@ConditionalOnProperty(prefix = "spring.mobile.devicedelegatingviewresolver", name = "enabled", havingValue = "true")
|
||||||
|
@EnableConfigurationProperties(DeviceDelegatingViewResolverProperties.class)
|
||||||
|
@AutoConfigureAfter({WebMvcAutoConfiguration.class, FreeMarkerAutoConfiguration.class,
|
||||||
|
GroovyTemplateAutoConfiguration.class, MustacheAutoConfiguration.class,
|
||||||
|
ThymeleafAutoConfiguration.class})
|
||||||
public class DeviceDelegatingViewResolverAutoConfiguration {
|
public class DeviceDelegatingViewResolverAutoConfiguration {
|
||||||
|
|
||||||
private static final Log logger = LogFactory
|
|
||||||
.getLog(DeviceDelegatingViewResolverAutoConfiguration.class);
|
|
||||||
|
|
||||||
private static abstract class AbstractDelegateConfiguration {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private DeviceDelegatingViewResolverProperties viewResolverProperties;
|
|
||||||
|
|
||||||
protected LiteDeviceDelegatingViewResolver getConfiguredViewResolver(
|
|
||||||
ViewResolver delegate, int delegateOrder) {
|
|
||||||
LiteDeviceDelegatingViewResolver resolver = new LiteDeviceDelegatingViewResolver(
|
|
||||||
delegate);
|
|
||||||
resolver.setEnableFallback(this.viewResolverProperties.isEnableFallback());
|
|
||||||
resolver.setNormalPrefix(this.viewResolverProperties.getNormalPrefix());
|
|
||||||
resolver.setNormalSuffix(this.viewResolverProperties.getNormalSuffix());
|
|
||||||
resolver.setMobilePrefix(this.viewResolverProperties.getMobilePrefix());
|
|
||||||
resolver.setMobileSuffix(this.viewResolverProperties.getMobileSuffix());
|
|
||||||
resolver.setTabletPrefix(this.viewResolverProperties.getTabletPrefix());
|
|
||||||
resolver.setTabletSuffix(this.viewResolverProperties.getTabletSuffix());
|
|
||||||
resolver.setOrder(getAdjustedOrder(delegateOrder));
|
|
||||||
return resolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getAdjustedOrder(int order) {
|
|
||||||
if (order == Ordered.HIGHEST_PRECEDENCE) {
|
|
||||||
return Ordered.HIGHEST_PRECEDENCE;
|
|
||||||
}
|
|
||||||
// The view resolver must be ordered higher than the delegate view
|
|
||||||
// resolver, otherwise the view names will not be adjusted
|
|
||||||
return order - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableConfigurationProperties(DeviceDelegatingViewResolverProperties.class)
|
protected static class LiteDeviceDelegatingViewResolverFactoryConfiguration {
|
||||||
@ConditionalOnMissingBean(name = "deviceDelegatingViewResolver")
|
|
||||||
@ConditionalOnProperty(prefix = "spring.mobile.devicedelegatingviewresolver", name = "enabled", havingValue = "true", matchIfMissing = false)
|
|
||||||
protected static class DeviceDelegatingViewResolverConfiguration {
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@ConditionalOnBean(name = "thymeleafViewResolver")
|
|
||||||
protected static class ThymeleafViewResolverViewResolverDelegateConfiguration
|
|
||||||
extends AbstractDelegateConfiguration {
|
|
||||||
|
|
||||||
private final ThymeleafViewResolver viewResolver;
|
|
||||||
|
|
||||||
protected ThymeleafViewResolverViewResolverDelegateConfiguration(
|
|
||||||
ThymeleafViewResolver viewResolver) {
|
|
||||||
this.viewResolver = viewResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public LiteDeviceDelegatingViewResolver deviceDelegatingViewResolver() {
|
public DeviceDelegatingViewResolverFactory deviceDelegatingViewResolverFactory(
|
||||||
if (logger.isDebugEnabled()) {
|
DeviceDelegatingViewResolverProperties properties) {
|
||||||
logger.debug("LiteDeviceDelegatingViewResolver delegates to "
|
return new DeviceDelegatingViewResolverFactory(properties);
|
||||||
+ "ThymeleafViewResolver");
|
|
||||||
}
|
|
||||||
return getConfiguredViewResolver(this.viewResolver,
|
|
||||||
this.viewResolver.getOrder());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableConfigurationProperties(DeviceDelegatingViewResolverProperties.class)
|
@ConditionalOnClass(FreeMarkerViewResolver.class)
|
||||||
@ConditionalOnMissingBean(name = "thymeleafViewResolver")
|
protected static class DeviceDelegatingFreemarkerViewResolverConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnBean(FreeMarkerViewResolver.class)
|
||||||
|
public LiteDeviceDelegatingViewResolver deviceDelegatingFreemarkerViewResolver(
|
||||||
|
DeviceDelegatingViewResolverFactory factory,
|
||||||
|
FreeMarkerViewResolver viewResolver) {
|
||||||
|
return factory.createViewResolver(viewResolver);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnClass(GroovyMarkupViewResolver.class)
|
||||||
|
protected static class DeviceDelegatingGroovyMarkupViewResolverConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnBean(GroovyMarkupViewResolver.class)
|
||||||
|
public LiteDeviceDelegatingViewResolver deviceDelegatingGroovyMarkupViewResolver(
|
||||||
|
DeviceDelegatingViewResolverFactory factory,
|
||||||
|
GroovyMarkupViewResolver viewResolver) {
|
||||||
|
return factory.createViewResolver(viewResolver);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnClass(InternalResourceViewResolver.class)
|
||||||
|
protected static class DeviceDelegatingJspViewResolverConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
@ConditionalOnBean(InternalResourceViewResolver.class)
|
@ConditionalOnBean(InternalResourceViewResolver.class)
|
||||||
protected static class InternalResourceViewResolverDelegateConfiguration
|
public LiteDeviceDelegatingViewResolver deviceDelegatingJspViewResolver(
|
||||||
extends AbstractDelegateConfiguration {
|
DeviceDelegatingViewResolverFactory factory,
|
||||||
|
|
||||||
private final InternalResourceViewResolver viewResolver;
|
|
||||||
|
|
||||||
protected InternalResourceViewResolverDelegateConfiguration(
|
|
||||||
InternalResourceViewResolver viewResolver) {
|
InternalResourceViewResolver viewResolver) {
|
||||||
this.viewResolver = viewResolver;
|
return factory.createViewResolver(viewResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnClass(MustacheViewResolver.class)
|
||||||
|
protected static class DeviceDelegatingMustacheViewResolverConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public LiteDeviceDelegatingViewResolver deviceDelegatingViewResolver() {
|
@ConditionalOnBean(MustacheViewResolver.class)
|
||||||
if (logger.isDebugEnabled()) {
|
public LiteDeviceDelegatingViewResolver deviceDelegatingMustacheViewResolver(
|
||||||
logger.debug("LiteDeviceDelegatingViewResolver delegates to "
|
DeviceDelegatingViewResolverFactory factory,
|
||||||
+ "InternalResourceViewResolver");
|
MustacheViewResolver viewResolver) {
|
||||||
|
return factory.createViewResolver(viewResolver);
|
||||||
}
|
}
|
||||||
return getConfiguredViewResolver(this.viewResolver,
|
|
||||||
this.viewResolver.getOrder());
|
}
|
||||||
}
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnClass(ThymeleafViewResolver.class)
|
||||||
|
protected static class DeviceDelegatingThymeleafViewResolverConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnBean(ThymeleafViewResolver.class)
|
||||||
|
public LiteDeviceDelegatingViewResolver deviceDelegatingThymeleafViewResolver(
|
||||||
|
DeviceDelegatingViewResolverFactory factory,
|
||||||
|
ThymeleafViewResolver viewResolver) {
|
||||||
|
return factory.createViewResolver(viewResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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.springframework.core.Ordered;
|
||||||
|
import org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver;
|
||||||
|
import org.springframework.web.servlet.ViewResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A factory for {@link LiteDeviceDelegatingViewResolver} that applies customizations
|
||||||
|
* of {@link DeviceDelegatingViewResolverProperties}.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
* @since 1.4.0
|
||||||
|
*/
|
||||||
|
public class DeviceDelegatingViewResolverFactory {
|
||||||
|
|
||||||
|
private final DeviceDelegatingViewResolverProperties properties;
|
||||||
|
|
||||||
|
public DeviceDelegatingViewResolverFactory(DeviceDelegatingViewResolverProperties properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a {@link LiteDeviceDelegatingViewResolver} delegating to the specified
|
||||||
|
* {@link ViewResolver}.
|
||||||
|
* @param delegate the view resolver to delegate to
|
||||||
|
* @param delegatingOrder the order of the {@link LiteDeviceDelegatingViewResolver}
|
||||||
|
* @return a {@link LiteDeviceDelegatingViewResolver} handling the specified resolver
|
||||||
|
*/
|
||||||
|
public LiteDeviceDelegatingViewResolver createViewResolver(
|
||||||
|
ViewResolver delegate, int delegatingOrder) {
|
||||||
|
LiteDeviceDelegatingViewResolver resolver = new LiteDeviceDelegatingViewResolver(
|
||||||
|
delegate);
|
||||||
|
resolver.setEnableFallback(this.properties.isEnableFallback());
|
||||||
|
resolver.setNormalPrefix(this.properties.getNormalPrefix());
|
||||||
|
resolver.setNormalSuffix(this.properties.getNormalSuffix());
|
||||||
|
resolver.setMobilePrefix(this.properties.getMobilePrefix());
|
||||||
|
resolver.setMobileSuffix(this.properties.getMobileSuffix());
|
||||||
|
resolver.setTabletPrefix(this.properties.getTabletPrefix());
|
||||||
|
resolver.setTabletSuffix(this.properties.getTabletSuffix());
|
||||||
|
resolver.setOrder(delegatingOrder);
|
||||||
|
return resolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a {@link LiteDeviceDelegatingViewResolver} delegating to the specified
|
||||||
|
* {@link ViewResolver} and computing a sensible order for it. The specified
|
||||||
|
* {@link ViewResolver} should implement {@link Ordered}, consider using
|
||||||
|
* {@link #createViewResolver(ViewResolver, int)} if that's not the case.
|
||||||
|
* @param delegate the view resolver to delegate to
|
||||||
|
* @return a {@link LiteDeviceDelegatingViewResolver} handling the specified resolver
|
||||||
|
*/
|
||||||
|
public LiteDeviceDelegatingViewResolver createViewResolver(ViewResolver delegate) {
|
||||||
|
if (!(delegate instanceof Ordered)) {
|
||||||
|
throw new IllegalStateException("ViewResolver " + delegate + "should implement " + Ordered.class.getName());
|
||||||
|
}
|
||||||
|
int delegateOrder = ((Ordered) delegate).getOrder();
|
||||||
|
return createViewResolver(delegate, adjustOrder(delegateOrder));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int adjustOrder(int order) {
|
||||||
|
if (order == Ordered.HIGHEST_PRECEDENCE) {
|
||||||
|
return Ordered.HIGHEST_PRECEDENCE;
|
||||||
|
}
|
||||||
|
// The view resolver must be ordered higher than the delegate view
|
||||||
|
// resolver, otherwise the view names will not be adjusted
|
||||||
|
return order - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,28 +16,36 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.mobile;
|
package org.springframework.boot.autoconfigure.mobile;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
|
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
|
||||||
|
|
||||||
import org.springframework.beans.DirectFieldAccessor;
|
import org.springframework.beans.DirectFieldAccessor;
|
||||||
import org.springframework.beans.PropertyAccessor;
|
import org.springframework.beans.PropertyAccessor;
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration.DeviceDelegatingViewResolverConfiguration;
|
import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.mustache.web.MustacheViewResolver;
|
||||||
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
|
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration;
|
import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
|
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.util.EnvironmentTestUtils;
|
import org.springframework.boot.test.util.EnvironmentTestUtils;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.mobile.device.view.AbstractDeviceDelegatingViewResolver;
|
|
||||||
import org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver;
|
import org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver;
|
||||||
|
import org.springframework.mock.web.MockServletContext;
|
||||||
|
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||||
|
import org.springframework.web.servlet.ViewResolver;
|
||||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||||
|
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
|
||||||
|
import org.springframework.web.servlet.view.groovy.GroovyMarkupViewResolver;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@ -49,9 +57,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
*/
|
*/
|
||||||
public class DeviceDelegatingViewResolverAutoConfigurationTests {
|
public class DeviceDelegatingViewResolverAutoConfigurationTests {
|
||||||
|
|
||||||
private static final MockEmbeddedServletContainerFactory containerFactory = new MockEmbeddedServletContainerFactory();
|
@Rule
|
||||||
|
public final ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
private AnnotationConfigEmbeddedWebApplicationContext context;
|
private AnnotationConfigWebApplicationContext context;
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void close() {
|
public void close() {
|
||||||
|
@ -60,123 +69,82 @@ public class DeviceDelegatingViewResolverAutoConfigurationTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = NoSuchBeanDefinitionException.class)
|
@Test
|
||||||
public void deviceDelegatingViewResolverDefaultDisabled() throws Exception {
|
public void deviceDelegatingViewResolverDefaultDisabled() throws Exception {
|
||||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
|
load();
|
||||||
this.context.register(Config.class,
|
this.thrown.expect(NoSuchBeanDefinitionException.class);
|
||||||
DeviceDelegatingViewResolverConfiguration.class);
|
this.context.getBean(LiteDeviceDelegatingViewResolver.class);
|
||||||
this.context.refresh();
|
|
||||||
this.context.getBean("deviceDelegatingViewResolver",
|
|
||||||
AbstractDeviceDelegatingViewResolver.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deviceDelegatingInternalResourceViewResolverEnabled() throws Exception {
|
public void deviceDelegatingJspResourceViewResolver() throws Exception {
|
||||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
|
load("spring.mobile.devicedelegatingviewresolver.enabled:true");
|
||||||
EnvironmentTestUtils.addEnvironment(this.context,
|
assertThat(this.context.getBeansOfType(LiteDeviceDelegatingViewResolver.class)).hasSize(1);
|
||||||
"spring.mobile.devicedelegatingviewresolver.enabled:true");
|
|
||||||
this.context.register(Config.class, WebMvcAutoConfiguration.class,
|
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
|
||||||
DeviceDelegatingViewResolverConfiguration.class);
|
|
||||||
this.context.refresh();
|
|
||||||
InternalResourceViewResolver internalResourceViewResolver = this.context
|
InternalResourceViewResolver internalResourceViewResolver = this.context
|
||||||
.getBean(InternalResourceViewResolver.class);
|
.getBean(InternalResourceViewResolver.class);
|
||||||
AbstractDeviceDelegatingViewResolver deviceDelegatingViewResolver = this.context
|
assertLiteDeviceDelegatingViewResolver(internalResourceViewResolver,
|
||||||
.getBean("deviceDelegatingViewResolver",
|
"deviceDelegatingJspViewResolver");
|
||||||
AbstractDeviceDelegatingViewResolver.class);
|
|
||||||
assertThat(internalResourceViewResolver).isNotNull();
|
|
||||||
assertThat(deviceDelegatingViewResolver).isNotNull();
|
|
||||||
assertThat(deviceDelegatingViewResolver.getViewResolver())
|
|
||||||
.isInstanceOf(InternalResourceViewResolver.class);
|
|
||||||
try {
|
|
||||||
this.context.getBean(ThymeleafViewResolver.class);
|
|
||||||
}
|
|
||||||
catch (NoSuchBeanDefinitionException ex) {
|
|
||||||
// expected. ThymeleafViewResolver shouldn't be defined.
|
|
||||||
}
|
|
||||||
assertThat(deviceDelegatingViewResolver.getOrder())
|
|
||||||
.isEqualTo(internalResourceViewResolver.getOrder() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = NoSuchBeanDefinitionException.class)
|
|
||||||
public void deviceDelegatingInternalResourceViewResolverDisabled() throws Exception {
|
|
||||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
|
|
||||||
EnvironmentTestUtils.addEnvironment(this.context,
|
|
||||||
"spring.mobile.devicedelegatingviewresolver.enabled:false");
|
|
||||||
this.context.register(Config.class, WebMvcAutoConfiguration.class,
|
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
|
||||||
DeviceDelegatingViewResolverConfiguration.class);
|
|
||||||
this.context.refresh();
|
|
||||||
assertThat(this.context.getBean(InternalResourceViewResolver.class)).isNotNull();
|
|
||||||
try {
|
|
||||||
this.context.getBean(ThymeleafViewResolver.class);
|
|
||||||
}
|
|
||||||
catch (NoSuchBeanDefinitionException ex) {
|
|
||||||
// expected. ThymeleafViewResolver shouldn't be defined.
|
|
||||||
}
|
|
||||||
this.context.getBean("deviceDelegatingViewResolver",
|
|
||||||
AbstractDeviceDelegatingViewResolver.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deviceDelegatingThymeleafViewResolverEnabled() throws Exception {
|
public void deviceDelegatingFreemarkerViewResolver() throws Exception {
|
||||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
|
load(Collections.<Class<?>>singletonList(FreeMarkerAutoConfiguration.class),
|
||||||
EnvironmentTestUtils.addEnvironment(this.context,
|
|
||||||
"spring.mobile.devicedelegatingviewresolver.enabled:true");
|
"spring.mobile.devicedelegatingviewresolver.enabled:true");
|
||||||
this.context.register(Config.class, WebMvcAutoConfiguration.class,
|
assertThat(this.context.getBeansOfType(LiteDeviceDelegatingViewResolver.class)).hasSize(2);
|
||||||
ThymeleafAutoConfiguration.class,
|
assertLiteDeviceDelegatingViewResolver(this.context.getBean(FreeMarkerViewResolver.class),
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
"deviceDelegatingFreemarkerViewResolver");
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
|
||||||
DeviceDelegatingViewResolverConfiguration.class);
|
|
||||||
this.context.refresh();
|
|
||||||
ThymeleafViewResolver thymeleafViewResolver = this.context
|
|
||||||
.getBean(ThymeleafViewResolver.class);
|
|
||||||
AbstractDeviceDelegatingViewResolver deviceDelegatingViewResolver = this.context
|
|
||||||
.getBean("deviceDelegatingViewResolver",
|
|
||||||
AbstractDeviceDelegatingViewResolver.class);
|
|
||||||
assertThat(thymeleafViewResolver).isNotNull();
|
|
||||||
assertThat(deviceDelegatingViewResolver).isNotNull();
|
|
||||||
assertThat(deviceDelegatingViewResolver.getViewResolver())
|
|
||||||
.isInstanceOf(ThymeleafViewResolver.class);
|
|
||||||
assertThat(this.context.getBean(InternalResourceViewResolver.class)).isNotNull();
|
|
||||||
assertThat(this.context.getBean(ThymeleafViewResolver.class)).isNotNull();
|
|
||||||
assertThat(deviceDelegatingViewResolver.getOrder())
|
|
||||||
.isEqualTo(thymeleafViewResolver.getOrder() - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = NoSuchBeanDefinitionException.class)
|
@Test
|
||||||
public void deviceDelegatingThymeleafViewResolverDisabled() throws Exception {
|
public void deviceDelegatingGroovyMarkupViewResolver() throws Exception {
|
||||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
|
load(Collections.<Class<?>>singletonList(GroovyTemplateAutoConfiguration.class),
|
||||||
EnvironmentTestUtils.addEnvironment(this.context,
|
"spring.mobile.devicedelegatingviewresolver.enabled:true");
|
||||||
|
assertThat(this.context.getBeansOfType(LiteDeviceDelegatingViewResolver.class)).hasSize(2);
|
||||||
|
assertLiteDeviceDelegatingViewResolver(this.context.getBean(GroovyMarkupViewResolver.class),
|
||||||
|
"deviceDelegatingGroovyMarkupViewResolver");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deviceDelegatingMustacheViewResolver() throws Exception {
|
||||||
|
load(Collections.<Class<?>>singletonList(MustacheAutoConfiguration.class),
|
||||||
|
"spring.mobile.devicedelegatingviewresolver.enabled:true");
|
||||||
|
assertThat(this.context.getBeansOfType(LiteDeviceDelegatingViewResolver.class)).hasSize(2);
|
||||||
|
assertLiteDeviceDelegatingViewResolver(this.context.getBean(MustacheViewResolver.class),
|
||||||
|
"deviceDelegatingMustacheViewResolver");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deviceDelegatingThymeleafViewResolver() throws Exception {
|
||||||
|
load(Collections.<Class<?>>singletonList(ThymeleafAutoConfiguration.class),
|
||||||
|
"spring.mobile.devicedelegatingviewresolver.enabled:true");
|
||||||
|
assertThat(this.context.getBeansOfType(LiteDeviceDelegatingViewResolver.class)).hasSize(2);
|
||||||
|
assertLiteDeviceDelegatingViewResolver(this.context.getBean(ThymeleafViewResolver.class),
|
||||||
|
"deviceDelegatingThymeleafViewResolver");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assertLiteDeviceDelegatingViewResolver(ViewResolver delegate, String delegatingBeanName) {
|
||||||
|
LiteDeviceDelegatingViewResolver deviceDelegatingViewResolver = this.context
|
||||||
|
.getBean(delegatingBeanName, LiteDeviceDelegatingViewResolver.class);
|
||||||
|
assertThat(deviceDelegatingViewResolver.getViewResolver())
|
||||||
|
.isSameAs(delegate);
|
||||||
|
assertThat(deviceDelegatingViewResolver.getOrder())
|
||||||
|
.isEqualTo(((Ordered) delegate).getOrder() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deviceDelegatingViewResolverDisabled() throws Exception {
|
||||||
|
load(Arrays.asList(FreeMarkerAutoConfiguration.class, GroovyTemplateAutoConfiguration.class,
|
||||||
|
MustacheAutoConfiguration.class, ThymeleafAutoConfiguration.class),
|
||||||
"spring.mobile.devicedelegatingviewresolver.enabled:false");
|
"spring.mobile.devicedelegatingviewresolver.enabled:false");
|
||||||
this.context.register(Config.class, WebMvcAutoConfiguration.class,
|
assertThat(this.context.getBeansOfType(LiteDeviceDelegatingViewResolver.class)).hasSize(0);
|
||||||
ThymeleafAutoConfiguration.class,
|
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
|
||||||
DeviceDelegatingViewResolverConfiguration.class);
|
|
||||||
this.context.refresh();
|
|
||||||
assertThat(this.context.getBean(InternalResourceViewResolver.class)).isNotNull();
|
|
||||||
assertThat(this.context.getBean(ThymeleafViewResolver.class)).isNotNull();
|
|
||||||
this.context.getBean("deviceDelegatingViewResolver",
|
|
||||||
AbstractDeviceDelegatingViewResolver.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void defaultPropertyValues() throws Exception {
|
public void defaultPropertyValues() throws Exception {
|
||||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
|
load("spring.mobile.devicedelegatingviewresolver.enabled:true");
|
||||||
EnvironmentTestUtils.addEnvironment(this.context,
|
|
||||||
"spring.mobile.devicedelegatingviewresolver.enabled:true");
|
|
||||||
this.context.register(Config.class, WebMvcAutoConfiguration.class,
|
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
|
||||||
DeviceDelegatingViewResolverConfiguration.class);
|
|
||||||
this.context.refresh();
|
|
||||||
LiteDeviceDelegatingViewResolver liteDeviceDelegatingViewResolver = this.context
|
LiteDeviceDelegatingViewResolver liteDeviceDelegatingViewResolver = this.context
|
||||||
.getBean("deviceDelegatingViewResolver",
|
.getBean("deviceDelegatingJspViewResolver",
|
||||||
LiteDeviceDelegatingViewResolver.class);
|
LiteDeviceDelegatingViewResolver.class);
|
||||||
|
|
||||||
DirectFieldAccessor accessor = new DirectFieldAccessor(
|
DirectFieldAccessor accessor = new DirectFieldAccessor(
|
||||||
liteDeviceDelegatingViewResolver);
|
liteDeviceDelegatingViewResolver);
|
||||||
assertThat(accessor.getPropertyValue("enableFallback")).isEqualTo(Boolean.FALSE);
|
assertThat(accessor.getPropertyValue("enableFallback")).isEqualTo(Boolean.FALSE);
|
||||||
|
@ -246,32 +214,29 @@ public class DeviceDelegatingViewResolverAutoConfigurationTests {
|
||||||
|
|
||||||
private PropertyAccessor getLiteDeviceDelegatingViewResolverAccessor(
|
private PropertyAccessor getLiteDeviceDelegatingViewResolverAccessor(
|
||||||
String... configuration) {
|
String... configuration) {
|
||||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
|
load(configuration);
|
||||||
EnvironmentTestUtils.addEnvironment(this.context, configuration);
|
|
||||||
this.context.register(Config.class, WebMvcAutoConfiguration.class,
|
|
||||||
HttpMessageConvertersAutoConfiguration.class,
|
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
|
||||||
DeviceDelegatingViewResolverConfiguration.class);
|
|
||||||
this.context.refresh();
|
|
||||||
LiteDeviceDelegatingViewResolver liteDeviceDelegatingViewResolver = this.context
|
LiteDeviceDelegatingViewResolver liteDeviceDelegatingViewResolver = this.context
|
||||||
.getBean("deviceDelegatingViewResolver",
|
.getBean("deviceDelegatingJspViewResolver",
|
||||||
LiteDeviceDelegatingViewResolver.class);
|
LiteDeviceDelegatingViewResolver.class);
|
||||||
return new DirectFieldAccessor(liteDeviceDelegatingViewResolver);
|
return new DirectFieldAccessor(liteDeviceDelegatingViewResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
public void load(String... environment) {
|
||||||
protected static class Config {
|
load(null, environment);
|
||||||
|
|
||||||
@Bean
|
|
||||||
public EmbeddedServletContainerFactory containerFactory() {
|
|
||||||
return containerFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public EmbeddedServletContainerCustomizerBeanPostProcessor embeddedServletContainerCustomizerBeanPostProcessor() {
|
|
||||||
return new EmbeddedServletContainerCustomizerBeanPostProcessor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void load(List<Class<?>> config, String... environment) {
|
||||||
|
this.context = new AnnotationConfigWebApplicationContext();
|
||||||
|
this.context.setServletContext(new MockServletContext());
|
||||||
|
if (config != null) {
|
||||||
|
this.context.register(config.toArray(new Class[config.size()]));
|
||||||
|
}
|
||||||
|
this.context.register(WebMvcAutoConfiguration.class,
|
||||||
|
HttpMessageConvertersAutoConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class,
|
||||||
|
DeviceDelegatingViewResolverAutoConfiguration.class);
|
||||||
|
EnvironmentTestUtils.addEnvironment(this.context, environment);
|
||||||
|
this.context.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue