diff --git a/build.gradle b/build.gradle index dbbccb73cd..90a3daff0e 100644 --- a/build.gradle +++ b/build.gradle @@ -910,7 +910,6 @@ project("spring-test") { optional("xmlunit:xmlunit:1.5") testCompile(project(":spring-context-support")) testCompile(project(":spring-oxm")) - testCompile(project(":spring-webmvc-tiles2")) testCompile("javax.mail:javax.mail-api:1.5.2") testCompile("javax.ejb:ejb-api:3.0") testCompile("org.hibernate:hibernate-core:${hibernate4Version}") diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java index 076ce79b25..03b105a77e 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java @@ -35,6 +35,7 @@ import org.springframework.test.web.servlet.samples.context.JavaConfigTests.WebC import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.config.annotation.*; +import org.springframework.web.servlet.view.tiles3.TilesConfigurer; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; @@ -99,7 +100,7 @@ public class JavaConfigTests { @Configuration @EnableWebMvc - static class WebConfig extends WebMvcConfigurerAdapter { + static class WebConfig extends WebMvcConfigurerAdapter implements TilesWebMvcConfigurer { @Autowired private RootConfig rootConfig; @@ -126,9 +127,13 @@ public class JavaConfigTests { @Override public void configureViewResolution(ViewResolutionRegistry registry) { - registry.tiles().definition("/WEB-INF/**/tiles.xml"); + registry.tiles(); } + @Override + public void configureTiles(TilesConfigurer configurer) { + configurer.setDefinitions("/WEB-INF/**/tiles.xml"); + } } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/BeanTypeNotPresentCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/BeanTypeNotPresentCondition.java new file mode 100644 index 0000000000..fec1d85929 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/BeanTypeNotPresentCondition.java @@ -0,0 +1,67 @@ +/* + * Copyright 2002-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.web.servlet.config.annotation; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.ConfigurationCondition; +import org.springframework.core.type.AnnotatedTypeMetadata; +import org.springframework.util.ObjectUtils; + +/** + * A simple configuration condition that checks for the absence of any beans + * of a given type. + * + * @author Rossen Stoyanchev + * @since 4.1 + */ +class BeanTypeNotPresentCondition implements ConfigurationCondition { + + private static final Log logger = + LogFactory.getLog("org.springframework.web.servlet.config.annotation.ViewResolution"); + + private final Class beanType; + + + BeanTypeNotPresentCondition(Class beanType) { + this.beanType = beanType; + } + + + @Override + public ConfigurationPhase getConfigurationPhase() { + return ConfigurationPhase.PARSE_CONFIGURATION; + } + + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + ListableBeanFactory factory = context.getBeanFactory(); + String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory, this.beanType, false, false); + if (ObjectUtils.isEmpty(names)) { + logger.debug("No bean of type [" + this.beanType + "]. Conditional configuration applies."); + return true; + } + else { + logger.debug("Found bean of type [" + this.beanType + "]. Conditional configuration does not apply."); + return false; + } + } + +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java index fc585fd72e..63f46f422d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java @@ -90,6 +90,6 @@ import org.springframework.context.annotation.Import; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented -@Import({DelegatingWebMvcConfiguration.class, ViewConfigurationsImportSelector.class}) +@Import({DelegatingWebMvcConfiguration.class, ViewResolutionImportSelector.class}) public @interface EnableWebMvc { } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerConfigurerConfigurationSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerConfigurerConfigurationSupport.java deleted file mode 100644 index bb5bce3314..0000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerConfigurerConfigurationSupport.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2002-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.web.servlet.config.annotation; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; - -import java.util.List; - -/** - * This class creates a FreeMarkerConfigurer bean. - * It is typically imported by adding {@link EnableWebMvc @EnableWebMvc} to an - * application {@link Configuration @Configuration} class when FreeMarker is - * in the classpath. - * - * @author Sebastien Deleuze - * @since 4.1 - * @see org.springframework.web.servlet.config.annotation.ViewConfigurationsImportSelector - */ -@Configuration -public class FreeMarkerConfigurerConfigurationSupport { - - private List webMvcConfigurationSupports; - - @Autowired(required = false) - public void setWebMvcConfigurationSupports(List webMvcConfigurationSupports) { - this.webMvcConfigurationSupports = webMvcConfigurationSupports; - } - - @Bean - public FreeMarkerConfigurer freeMarkerConfigurer() { - FreeMarkerConfigurer configurer = null; - if(webMvcConfigurationSupports != null) { - for(WebMvcConfigurationSupport configurationSupport : webMvcConfigurationSupports) { - configurer = configurationSupport.getViewResolutionRegistry().getFreeMarkerConfigurer(); - if(configurer != null) { - break; - } - } - } - return configurer; - } -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerRegistration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerRegistration.java index 65cdfda880..5d743b95aa 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerRegistration.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerRegistration.java @@ -16,12 +16,8 @@ package org.springframework.web.servlet.config.annotation; -import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver; -import java.util.Arrays; -import java.util.List; - /** * Encapsulates information required to create a * {@link org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver} and a @@ -33,15 +29,11 @@ import java.util.List; */ public class FreeMarkerRegistration extends ViewResolutionRegistration { - private final FreeMarkerConfigurer configurer; - private List templateLoaderPaths; public FreeMarkerRegistration(ViewResolutionRegistry registry) { super(registry, new FreeMarkerViewResolver()); - this.configurer = new FreeMarkerConfigurer(); this.prefix(""); this.suffix(".ftl"); - this.templateLoaderPath("/WEB-INF/"); } /** @@ -74,21 +66,4 @@ public class FreeMarkerRegistration extends ViewResolutionRegistrationAn {@code @EnableWebMvc}-annotated configuration classes can implement + * this interface to customize the {@code FreeMarkerConfigurer}. + * + * @author Rossen Stoyanchev + * @since 4.1 + */ +public interface FreeMarkerWebMvcConfigurer { + + void configureFreeMarker(FreeMarkerConfigurer configurer); + +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesConfigurerConfigurationSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesConfigurerConfigurationSupport.java deleted file mode 100644 index c41627fd5b..0000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesConfigurerConfigurationSupport.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2002-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.web.servlet.config.annotation; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.view.tiles3.TilesConfigurer; - -import java.util.List; - -/** - * This class creates a TilesConfigurer bean. - * It is typically imported by adding {@link EnableWebMvc @EnableWebMvc} to an - * application {@link Configuration @Configuration} class when Tiles 3 is - * in the classpath. - * - * @author Sebastien Deleuze - * @since 4.1 - * @see org.springframework.web.servlet.config.annotation.ViewConfigurationsImportSelector - */ -@Configuration -public class TilesConfigurerConfigurationSupport { - - private List webMvcConfigurationSupports; - - @Autowired(required = false) - public void setWebMvcConfigurationSupports(List webMvcConfigurationSupports) { - this.webMvcConfigurationSupports = webMvcConfigurationSupports; - } - - @Bean - public TilesConfigurer tilesConfigurer() { - TilesConfigurer configurer = null; - if(webMvcConfigurationSupports != null) { - for(WebMvcConfigurationSupport configurationSupport : webMvcConfigurationSupports) { - configurer = configurationSupport.getViewResolutionRegistry().getTilesConfigurer(); - if(configurer != null) { - break; - } - } - } - return configurer; - } -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesRegistration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesRegistration.java index 718ee4e260..80908ef0a1 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesRegistration.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesRegistration.java @@ -16,13 +16,8 @@ package org.springframework.web.servlet.config.annotation; -import org.springframework.web.servlet.view.tiles3.TilesConfigurer; import org.springframework.web.servlet.view.tiles3.TilesViewResolver; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - /** * Encapsulates information required to create a * {@link org.springframework.web.servlet.view.tiles3.TilesViewResolver} and a @@ -35,8 +30,6 @@ import java.util.List; */ public class TilesRegistration extends ViewResolutionRegistration { - private List definitions; - private Boolean checkRefresh; public TilesRegistration(ViewResolutionRegistry registry) { super(registry, new TilesViewResolver()); @@ -62,38 +55,4 @@ public class TilesRegistration extends ViewResolutionRegistration(); - } - this.definitions.addAll(Arrays.asList(definitions)); - return this; - } - - /** - * Set whether to check Tiles definition files for a refresh at runtime. - * - * @see TilesConfigurer#setCheckRefresh(boolean) - */ - public TilesRegistration checkRefresh(boolean checkRefresh) { - this.checkRefresh = checkRefresh; - return this; - } - - protected TilesConfigurer getTilesConfigurer() { - TilesConfigurer tilesConfigurer = new TilesConfigurer(); - if(this.definitions != null && !this.definitions.isEmpty()) { - tilesConfigurer.setDefinitions(this.definitions.toArray(new String[0])); - } - if(this.checkRefresh != null) { - tilesConfigurer.setCheckRefresh(this.checkRefresh); - } - return tilesConfigurer; - } - } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesWebMvcConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesWebMvcConfigurer.java new file mode 100644 index 0000000000..f2f9d62ce8 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesWebMvcConfigurer.java @@ -0,0 +1,35 @@ +/* + * Copyright 2002-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.web.servlet.config.annotation; + +import org.springframework.web.servlet.view.tiles3.TilesConfigurer; + +/** + * Defines a callback method to customize the + * {@link org.springframework.web.servlet.view.tiles3.TilesConfigurer + * TilesConfigurer} bean provided when using {@code @EnableWebMvc}. + * + *

An {@code @EnableWebMvc}-annotated configuration classes can implement + * this interface to customize the {@code TilesConfigurer}. + * + * @author Rossen Stoyanchev + * @since 4.1 + */ +public interface TilesWebMvcConfigurer { + + void configureTiles(TilesConfigurer configurer); + +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityConfigurerConfigurationSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityConfigurerConfigurationSupport.java deleted file mode 100644 index dee57694a4..0000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityConfigurerConfigurationSupport.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2002-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.web.servlet.config.annotation; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.view.velocity.VelocityConfigurer; - -import java.util.List; - -/** - * This class creates the VelocityConfigurer bean. - * It is typically imported by adding {@link EnableWebMvc @EnableWebMvc} to an - * application {@link Configuration @Configuration} class when Velocity in the classpath. - * - * @author Sebastien Deleuze - * @since 4.1 - * @see org.springframework.web.servlet.config.annotation.ViewConfigurationsImportSelector - */ -@Configuration -public class VelocityConfigurerConfigurationSupport { - - private List webMvcConfigurationSupports; - - @Autowired(required = false) - public void setWebMvcConfigurationSupports(List webMvcConfigurationSupports) { - this.webMvcConfigurationSupports = webMvcConfigurationSupports; - } - - @Bean - public VelocityConfigurer velocityConfigurer() { - VelocityConfigurer configurer = null; - if(webMvcConfigurationSupports != null) { - for(WebMvcConfigurationSupport configurationSupport : webMvcConfigurationSupports) { - configurer = configurationSupport.getViewResolutionRegistry().getVelocityConfigurer(); - if(configurer != null) { - break; - } - } - } - return configurer; - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityRegistration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityRegistration.java index bbf4e75843..05f7bc28f6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityRegistration.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityRegistration.java @@ -16,7 +16,6 @@ package org.springframework.web.servlet.config.annotation; -import org.springframework.web.servlet.view.velocity.VelocityConfigurer; import org.springframework.web.servlet.view.velocity.VelocityViewResolver; /** @@ -30,24 +29,11 @@ import org.springframework.web.servlet.view.velocity.VelocityViewResolver; */ public class VelocityRegistration extends ViewResolutionRegistration { - private final VelocityConfigurer configurer; public VelocityRegistration(ViewResolutionRegistry registry) { super(registry, new VelocityViewResolver()); - this.configurer = new VelocityConfigurer(); this.prefix(""); this.suffix(".vm"); - this.resourceLoaderPath("/WEB-INF/"); - } - - /** - * Set the Velocity resource loader path via a Spring resource location. - * - * @see org.springframework.web.servlet.view.velocity.VelocityConfigurer#setResourceLoaderPath(String) - */ - public VelocityRegistration resourceLoaderPath(String resourceLoaderPath) { - this.configurer.setResourceLoaderPath(resourceLoaderPath); - return this; } /** @@ -80,7 +66,4 @@ public class VelocityRegistration extends ViewResolutionRegistrationAn {@code @EnableWebMvc}-annotated configuration classes can implement + * this interface to customize the {@code VelocityConfigurer}. + * + * @author Rossen Stoyanchev + * @since 4.1 + */ +public interface VelocityWebMvcConfigurer { + + void configureVelocity(VelocityConfigurer configurer); + +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewConfigurationImportSelector.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewConfigurationImportSelector.java new file mode 100644 index 0000000000..379e92eb30 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewConfigurationImportSelector.java @@ -0,0 +1,64 @@ +/* + * Copyright 2002-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.web.servlet.config.annotation; + +import org.springframework.context.annotation.DeferredImportSelector; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.util.ClassUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * Selectively imports configuration required to configure Tiles, Freemarker, or + * Velocity for view resolution depending on whether those 3rd party libraries + * are available on the classpath. + * + * @author Sebastien Deleuze + * @author Rossen Stoyanchev + * @since 4.1 + * + * @see WebMvcFreeMarkerConfiguration + */ +public class ViewConfigurationImportSelector implements DeferredImportSelector { + + private static final boolean tilesPresent = ClassUtils.isPresent( + "org.apache.tiles.startup.TilesInitializer", ViewConfigurationImportSelector.class.getClassLoader()); + + private static final boolean velocityPresent = ClassUtils.isPresent( + "org.apache.velocity.app.VelocityEngine", ViewConfigurationImportSelector.class.getClassLoader()); + + private static final boolean freeMarkerPresent = ClassUtils.isPresent( + "freemarker.template.Configuration", ViewConfigurationImportSelector.class.getClassLoader()); + + + @Override + public String[] selectImports(AnnotationMetadata importingClassMetadata) { + List classes = new ArrayList(3); + if (tilesPresent) { + classes.add(WebMvcTilesConfiguration.class.getName()); + } + if (velocityPresent) { + classes.add(WebMvcVelocityConfiguration.class.getName()); + } + if (freeMarkerPresent) { + classes.add(WebMvcFreeMarkerConfiguration.class.getName()); + } + return classes.toArray(new String[0]); + } + +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewConfigurationsImportSelector.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewConfigurationsImportSelector.java deleted file mode 100644 index 7d801a9e3c..0000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewConfigurationsImportSelector.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2002-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.web.servlet.config.annotation; - -import org.springframework.context.annotation.ImportSelector; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.util.ClassUtils; - -import java.util.ArrayList; -import java.util.List; - -/** - * This class imports @{@link org.springframework.context.annotation.Configuration} - * classes for view configurers based on a classpath criteria. - * - * @author Sebastien Deleuze - * @since 4.1 - */ -public class ViewConfigurationsImportSelector implements ImportSelector { - - private static final boolean tilesPresent = - ClassUtils.isPresent("org.apache.tiles.startup.TilesInitializer", ViewConfigurationsImportSelector.class.getClassLoader()); - - private static final boolean velocityPresent = - ClassUtils.isPresent("org.apache.velocity.app.VelocityEngine", ViewConfigurationsImportSelector.class.getClassLoader()); - - private static final boolean freeMarkerPresent = - ClassUtils.isPresent("freemarker.template.Configuration", ViewConfigurationsImportSelector.class.getClassLoader()); - - @Override - public String[] selectImports(AnnotationMetadata importingClassMetadata) { - List configurationClasses = new ArrayList(); - if(tilesPresent) { - configurationClasses.add(TilesConfigurerConfigurationSupport.class.getName()); - } - if(velocityPresent) { - configurationClasses.add(VelocityConfigurerConfigurationSupport.class.getName()); - } - if(freeMarkerPresent) { - configurationClasses.add(FreeMarkerConfigurerConfigurationSupport.class.getName()); - } - return configurationClasses.toArray(new String[0]); - } -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistry.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistry.java index 489bbfea42..e37dde4744 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistry.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistry.java @@ -16,8 +16,13 @@ package org.springframework.web.servlet.config.annotation; +import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.beans.factory.BeanInitializationException; +import org.springframework.context.ApplicationContext; +import org.springframework.util.ObjectUtils; import org.springframework.web.servlet.View; import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.view.freemarker.FreeMarkerConfig; import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; import org.springframework.web.servlet.view.tiles3.TilesConfigurer; import org.springframework.web.servlet.view.velocity.VelocityConfigurer; @@ -35,6 +40,14 @@ public class ViewResolutionRegistry { private final List> registrations = new ArrayList>(); + private final ApplicationContext applicationContext; + + + public ViewResolutionRegistry(ApplicationContext context) { + this.applicationContext = context; + } + + /** * Register a custom {@link ViewResolver} bean. */ @@ -79,6 +92,12 @@ public class ViewResolutionRegistry { * default "/WEB-INF/tiles.xml" definition and no Tiles definition check refresh. */ public TilesRegistration tiles() { + if (!hasBeanOfType(TilesConfigurer.class)) { + throw new BeanInitializationException( + "It looks like you're trying to configure Tiles view resolution. " + + "If not using @EnableWebMvc you must import WebMvcTilesConfiguration, " + + "or declare your own TilesConfigurer bean."); + } TilesRegistration registration = new TilesRegistration(this); addAndCheckViewResolution(registration); return registration; @@ -90,6 +109,12 @@ public class ViewResolutionRegistry { * default "" prefix, ".vm" suffix and "/WEB-INF/" resourceLoaderPath. */ public VelocityRegistration velocity() { + if (!hasBeanOfType(VelocityConfigurer.class)) { + throw new BeanInitializationException( + "It looks like you're trying to configure Velocity view resolution. " + + "If not using @EnableWebMvc you must import WebMvcVelocityConfiguration, " + + "or declare your own VelocityConfigurer bean."); + } VelocityRegistration registration = new VelocityRegistration(this); addAndCheckViewResolution(registration); return registration; @@ -101,11 +126,22 @@ public class ViewResolutionRegistry { * "" prefix, ".ftl" suffix and "/WEB-INF/" templateLoaderPath. */ public FreeMarkerRegistration freemarker() { + if (!hasBeanOfType(FreeMarkerConfigurer.class)) { + throw new BeanInitializationException( + "It looks like you're trying to configure FreeMarker view resolution. " + + "If not using @EnableWebMvc you must import WebMvcFreeMarkerConfiguration, " + + "or declare your own FreeMarkerConfigurer bean."); + } FreeMarkerRegistration registration = new FreeMarkerRegistration(this); addAndCheckViewResolution(registration); return registration; } + protected boolean hasBeanOfType(Class beanType) { + return !ObjectUtils.isEmpty(BeanFactoryUtils.beanNamesForTypeIncludingAncestors( + this.applicationContext, beanType, false, false)); + } + /** * Register a {@link org.springframework.web.servlet.view.ContentNegotiatingViewResolver} bean. */ @@ -118,40 +154,12 @@ public class ViewResolutionRegistry { protected List getViewResolvers() { List viewResolvers = new ArrayList(); - for(ViewResolutionRegistration registration : this.registrations) { viewResolvers.add(registration.getViewResolver()); } return viewResolvers; } - protected TilesConfigurer getTilesConfigurer() { - for(ViewResolutionRegistration registration : this.registrations) { - if(registration instanceof TilesRegistration) { - return ((TilesRegistration) registration).getTilesConfigurer(); - } - } - return null; - } - - protected FreeMarkerConfigurer getFreeMarkerConfigurer() { - for(ViewResolutionRegistration registration : this.registrations) { - if(registration instanceof FreeMarkerRegistration) { - return ((FreeMarkerRegistration) registration).getConfigurer(); - } - } - return null; - } - - protected VelocityConfigurer getVelocityConfigurer() { - for(ViewResolutionRegistration registration : this.registrations) { - if(registration instanceof VelocityRegistration) { - return ((VelocityRegistration) registration).getConfigurer(); - } - } - return null; - } - private void addAndCheckViewResolution(ViewResolutionRegistration registration) { for(ViewResolutionRegistration existingRegistration : this.registrations) { if(existingRegistration.getClass().equals(registration.getClass())) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java index 24e7e85848..b23d1dc0e6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java @@ -152,8 +152,7 @@ import org.springframework.web.util.UrlPathHelper; *

When extending directly from this class instead of using * {@link EnableWebMvc @EnableWebMvc}, an extra step is needed if you want to use Tiles, FreeMarker * or Velocity view resolution configuration. Since view configurer beans are registered in their own - * {@link org.springframework.web.servlet.config.annotation.TilesConfigurerConfigurationSupport}, - * {@link org.springframework.web.servlet.config.annotation.FreeMarkerConfigurerConfigurationSupport} + * {@link org.springframework.web.servlet.config.annotation.TilesConfigurerConfigurationSupport} * and {@link org.springframework.web.servlet.config.annotation.VelocityConfigurerConfigurationSupport} * classes, you should also extend those configuration classes (only the ones * related to the view technology you are using), or register your own @@ -825,7 +824,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv protected ViewResolutionRegistry getViewResolutionRegistry() { if(this.viewResolutionRegistry == null) { - this.viewResolutionRegistry = new ViewResolutionRegistry(); + this.viewResolutionRegistry = new ViewResolutionRegistry(this.applicationContext); configureViewResolution(this.viewResolutionRegistry); } return this.viewResolutionRegistry; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcFreeMarkerConfiguration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcFreeMarkerConfiguration.java new file mode 100644 index 0000000000..7defb00b29 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcFreeMarkerConfiguration.java @@ -0,0 +1,76 @@ +/* + * Copyright 2002-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.web.servlet.config.annotation; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; +import org.springframework.util.CollectionUtils; +import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; + +import java.util.ArrayList; +import java.util.List; + +/** + * Configuration class that declares a + * {@link org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer + * FreeMarkerConfigurer} bean. The configuration is conditional and applies + * only if there is no {@code FreeMarkerConfigurer} bean already declared. + * + *

This configuration is imported when using {@link EnableWebMvc} if + * FreeMarker is available on the classpath. It can be customized by + * implementing {@link FreeMarkerWebMvcConfigurer}. + * + * @author Rossen Stoyanchev + * @since 4.1 + */ +@Configuration +@Conditional(WebMvcFreeMarkerConfiguration.FreeMarkerConfigurerNotPresentCondition.class) +public class WebMvcFreeMarkerConfiguration { + + private final List webMvcConfigurers = new ArrayList(1); + + + @Autowired(required = false) + public void setWebMvcConfigurers(List webMvcConfigurers) { + if (!CollectionUtils.isEmpty(webMvcConfigurers)) { + this.webMvcConfigurers.addAll(webMvcConfigurers); + } + } + + @Bean + @Lazy + public FreeMarkerConfigurer freeMarkerConfigurer() { + FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); + configurer.setTemplateLoaderPath("/WEB-INF/"); + for (FreeMarkerWebMvcConfigurer webMvcConfigurer : this.webMvcConfigurers) { + webMvcConfigurer.configureFreeMarker(configurer); + } + return configurer; + } + + + static class FreeMarkerConfigurerNotPresentCondition extends BeanTypeNotPresentCondition { + + private FreeMarkerConfigurerNotPresentCondition() { + super(FreeMarkerConfigurer.class); + } + } + +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcTilesConfiguration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcTilesConfiguration.java new file mode 100644 index 0000000000..8d55e4a3df --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcTilesConfiguration.java @@ -0,0 +1,94 @@ +/* + * Copyright 2002-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.web.servlet.config.annotation; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ResourceLoaderAware; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.util.CollectionUtils; +import org.springframework.web.servlet.view.tiles3.TilesConfigurer; + +import java.util.ArrayList; +import java.util.List; + +/** + * Configuration class that declares a + * {@link org.springframework.web.servlet.view.tiles3.TilesConfigurer + * TilesConfigurer} bean. The configuration is conditional and applies + * only if there is no {@code TilesConfigurer} bean already declared. + * + *

This configuration is imported when using {@link EnableWebMvc} if Tiles 3 + * is available on the classpath. It can be customized by implementing + * {@link TilesWebMvcConfigurer}. + * + * @author Rossen Stoyanchev + * @since 4.1 + */ +@Configuration +@Conditional(WebMvcTilesConfiguration.TilesConfigurerNotPresentCondition.class) +public class WebMvcTilesConfiguration implements ResourceLoaderAware { + + private final List webMvcConfigurers = new ArrayList(1); + + private ResourceLoader resourceLoader; + + + @Autowired(required = false) + public void setWebMvcConfigurers(List webMvcConfigurers) { + if (!CollectionUtils.isEmpty(webMvcConfigurers)) { + this.webMvcConfigurers.addAll(webMvcConfigurers); + } + } + + @Override + public void setResourceLoader(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + + + @Bean + public TilesConfigurer tilesConfigurer() { + TilesConfigurer configurer = new TilesConfigurer(); + if (!this.webMvcConfigurers.isEmpty()) { + for (TilesWebMvcConfigurer webMvcConfigurer : this.webMvcConfigurers) { + webMvcConfigurer.configureTiles(configurer); + } + } + else { + Resource resource = this.resourceLoader.getResource("/WEB-INF/tiles.xml"); + if (!resource.exists()) { + String[] noTilesDefinitions = new String[0]; + configurer.setDefinitions(noTilesDefinitions); + } + } + return configurer; + } + + + static class TilesConfigurerNotPresentCondition extends BeanTypeNotPresentCondition { + + private TilesConfigurerNotPresentCondition() { + super(TilesConfigurer.class); + } + } + +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcVelocityConfiguration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcVelocityConfiguration.java new file mode 100644 index 0000000000..02f0296dd1 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcVelocityConfiguration.java @@ -0,0 +1,76 @@ +/* + * Copyright 2002-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.web.servlet.config.annotation; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; +import org.springframework.util.CollectionUtils; +import org.springframework.web.servlet.view.velocity.VelocityConfigurer; + +import java.util.ArrayList; +import java.util.List; + +/** + * Configuration class that declares a + * {@link org.springframework.web.servlet.view.velocity.VelocityConfigurer + * VelocityConfigurer} bean. The configuration is conditional and applies + * only if there is no {@code VelocityConfigurer} bean already declared. + * + *

This configuration is imported when using {@link EnableWebMvc} if + * Velocity is available on the classpath. It can be customized by + * implementing {@link VelocityWebMvcConfigurer}. + * + * @author Rossen Stoyanchev + * @since 4.1 + */ +@Configuration +@Conditional(WebMvcVelocityConfiguration.VelocityConfigurerNotPresentCondition.class) +public class WebMvcVelocityConfiguration { + + private final List webMvcConfigurers = new ArrayList(1); + + + @Autowired(required = false) + public void setWebMvcConfigurers(List webMvcConfigurers) { + if (!CollectionUtils.isEmpty(webMvcConfigurers)) { + this.webMvcConfigurers.addAll(webMvcConfigurers); + } + } + + @Bean + @Lazy + public VelocityConfigurer velocityConfigurer() { + VelocityConfigurer configurer = new VelocityConfigurer(); + configurer.setResourceLoaderPath("/WEB-INF/"); + for (VelocityWebMvcConfigurer webMvcConfigurer : this.webMvcConfigurers) { + webMvcConfigurer.configureVelocity(configurer); + } + return configurer; + } + + + static class VelocityConfigurerNotPresentCondition extends BeanTypeNotPresentCondition { + + private VelocityConfigurerNotPresentCondition() { + super(VelocityConfigurer.class); + } + } + +} diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionIntegrationTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionIntegrationTests.java new file mode 100644 index 0000000000..5780e07134 --- /dev/null +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionIntegrationTests.java @@ -0,0 +1,239 @@ +/* + * Copyright 2002-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.web.servlet.config.annotation; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mock.web.test.MockHttpServletRequest; +import org.springframework.mock.web.test.MockHttpServletResponse; +import org.springframework.mock.web.test.MockServletConfig; +import org.springframework.mock.web.test.MockServletContext; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; +import org.springframework.web.servlet.DispatcherServlet; +import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; +import org.springframework.web.servlet.view.tiles3.TilesConfigurer; +import org.springframework.web.servlet.view.velocity.VelocityConfigurer; + +import javax.servlet.ServletException; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +/** + * Integration tests for view resolution with {@code @EnableWebMvc}. + * + * @author Rossen Stoyanchev + * @since 4.1 + */ +public class ViewResolutionIntegrationTests { + + @Rule + public final ExpectedException thrown = ExpectedException.none(); + + + @Test + public void minimalFreemarkerConfig() throws Exception { + MockHttpServletResponse response = runTest(MinimalFreeMarkerWebConfig.class); + assertEquals("Hello World!", response.getContentAsString()); + } + + @Test + public void minimalVelocityConfig() throws Exception { + MockHttpServletResponse response = runTest(MinimalVelocityWebConfig.class); + assertEquals("Hello World!", response.getContentAsString()); + } + + @Test + public void minimalTilesConfig() throws Exception { + MockHttpServletResponse response = runTest(MinimalTilesWebConfig.class); + assertEquals("/WEB-INF/index.jsp", response.getForwardedUrl()); + } + + @Test + public void freemarker() throws Exception { + MockHttpServletResponse response = runTest(FreeMarkerWebConfig.class); + assertEquals("Hello World!", response.getContentAsString()); + } + + @Test + public void velocity() throws Exception { + MockHttpServletResponse response = runTest(VelocityWebConfig.class); + assertEquals("Hello World!", response.getContentAsString()); + } + + @Test + public void tiles() throws Exception { + MockHttpServletResponse response = runTest(TilesWebConfig.class); + assertEquals("/WEB-INF/index.jsp", response.getForwardedUrl()); + } + + @Test + public void freemarkerInvalidConfig() throws Exception { + this.thrown.expectMessage("It looks like you're trying to configure FreeMarker view resolution."); + runTest(InvalidFreeMarkerWebConfig.class); + } + + @Test + public void velocityInvalidConfig() throws Exception { + this.thrown.expectMessage("It looks like you're trying to configure Velocity view resolution."); + runTest(InvalidVelocityWebConfig.class); + } + + @Test + public void tilesInvalidConfig() throws Exception { + this.thrown.expectMessage("It looks like you're trying to configure Tiles view resolution."); + runTest(InvalidTilesWebConfig.class); + } + + + private MockHttpServletResponse runTest(Class configClass) throws ServletException, IOException { + String basePath = "org/springframework/web/servlet/config/annotation"; + MockServletContext servletContext = new MockServletContext(basePath); + MockServletConfig servletConfig = new MockServletConfig(servletContext); + MockHttpServletRequest request = new MockHttpServletRequest("GET", "/"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + context.register(configClass); + context.setServletContext(servletContext); + context.refresh(); + DispatcherServlet servlet = new DispatcherServlet(context); + servlet.init(servletConfig); + servlet.service(request, response); + return response; + } + + + @Controller + static class SampleController { + + @RequestMapping(value = "/", method = RequestMethod.GET) + public String tiles(@ModelAttribute("model") ModelMap model) { + model.addAttribute("hello", "Hello World!"); + return "index"; + } + } + + @EnableWebMvc + static abstract class AbstractWebConfig extends WebMvcConfigurerAdapter { + @Bean + public SampleController sampleController() { + return new SampleController(); + } + } + + @Configuration + static class MinimalFreeMarkerWebConfig extends AbstractWebConfig { + @Override + public void configureViewResolution(ViewResolutionRegistry registry) { + registry.freemarker(); + } + } + + @Configuration + static class MinimalVelocityWebConfig extends AbstractWebConfig { + @Override + public void configureViewResolution(ViewResolutionRegistry registry) { + registry.velocity(); + } + } + + @Configuration + static class MinimalTilesWebConfig extends AbstractWebConfig { + @Override + public void configureViewResolution(ViewResolutionRegistry registry) { + registry.tiles(); + } + } + + @Configuration + static class FreeMarkerWebConfig extends AbstractWebConfig implements FreeMarkerWebMvcConfigurer { + @Override + public void configureViewResolution(ViewResolutionRegistry registry) { + registry.freemarker(); + } + @Override + public void configureFreeMarker(FreeMarkerConfigurer configurer) { + configurer.setTemplateLoaderPath("/WEB-INF/"); + } + } + + @Configuration + static class VelocityWebConfig extends AbstractWebConfig implements VelocityWebMvcConfigurer { + @Override + public void configureViewResolution(ViewResolutionRegistry registry) { + registry.velocity(); + } + @Override + public void configureVelocity(VelocityConfigurer configurer) { + configurer.setResourceLoaderPath("/WEB-INF/"); + } + } + + @Configuration + static class TilesWebConfig extends AbstractWebConfig implements TilesWebMvcConfigurer { + @Override + public void configureViewResolution(ViewResolutionRegistry registry) { + registry.tiles(); + } + @Override + public void configureTiles(TilesConfigurer configurer) { + configurer.setDefinitions("/WEB-INF/tiles.xml"); + } + } + @Configuration + static class InvalidFreeMarkerWebConfig extends WebMvcConfigurationSupport { + + // No @EnableWebMvc and no FreeMarkerConfigurer bean + + @Override + public void configureViewResolution(ViewResolutionRegistry registry) { + registry.freemarker(); + } + } + + @Configuration + static class InvalidVelocityWebConfig extends WebMvcConfigurationSupport { + + // No @EnableWebMvc and no VelocityConfigurer bean + + @Override + public void configureViewResolution(ViewResolutionRegistry registry) { + registry.velocity(); + } + } + + @Configuration + static class InvalidTilesWebConfig extends WebMvcConfigurationSupport { + + // No @EnableWebMvc and no TilesConfigurer bean + + @Override + public void configureViewResolution(ViewResolutionRegistry registry) { + registry.tiles(); + } + } + +} diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistryTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistryTests.java index 666f941d47..6ef68dd926 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistryTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistryTests.java @@ -19,15 +19,13 @@ package org.springframework.web.servlet.config.annotation; import org.junit.Before; import org.junit.Test; import org.springframework.beans.DirectFieldAccessor; +import org.springframework.web.context.support.StaticWebApplicationContext; import org.springframework.web.servlet.view.BeanNameViewResolver; import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; import org.springframework.web.servlet.view.InternalResourceViewResolver; -import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver; import org.springframework.web.servlet.view.json.MappingJackson2JsonView; -import org.springframework.web.servlet.view.tiles3.TilesConfigurer; import org.springframework.web.servlet.view.tiles3.TilesViewResolver; -import org.springframework.web.servlet.view.velocity.VelocityConfigurer; import org.springframework.web.servlet.view.velocity.VelocityViewResolver; import static org.junit.Assert.*; @@ -44,7 +42,7 @@ public class ViewResolutionRegistryTests { @Before public void setUp() { - registry = new ViewResolutionRegistry(); + registry = new ViewResolutionRegistry(new StaticWebApplicationContext()); } @Test @@ -100,25 +98,15 @@ public class ViewResolutionRegistryTests { @Test public void tilesViewResolution() { - registry.tiles().checkRefresh(true).definition("def1").definition("def2"); - assertNotNull(registry.getViewResolvers()); - assertEquals(1, registry.getViewResolvers().size()); - assertEquals(TilesViewResolver.class, registry.getViewResolvers().get(0).getClass()); - - assertNotNull(registry.getTilesConfigurer()); - TilesConfigurer configurer = registry.getTilesConfigurer(); - DirectFieldAccessor configurerDirectFieldAccessor = new DirectFieldAccessor(configurer); - assertTrue((boolean) configurerDirectFieldAccessor.getPropertyValue("checkRefresh")); - assertNotNull(configurerDirectFieldAccessor.getPropertyValue("definitions")); - String[] definitions = (String[])configurerDirectFieldAccessor.getPropertyValue("definitions"); - assertEquals(2, definitions.length); - assertEquals("def1", definitions[0]); - assertEquals("def2", definitions[1]); + this.registry.tiles(); + assertNotNull(this.registry.getViewResolvers()); + assertEquals(1, this.registry.getViewResolvers().size()); + assertEquals(TilesViewResolver.class, this.registry.getViewResolvers().get(0).getClass()); } @Test public void velocityViewResolution() { - registry.velocity().prefix("/").suffix(".vm").cache(true).resourceLoaderPath("testResourceLoaderPath"); + registry.velocity().prefix("/").suffix(".vm").cache(true); assertNotNull(registry.getViewResolvers()); assertEquals(1, registry.getViewResolvers().size()); assertEquals(VelocityViewResolver.class, registry.getViewResolvers().get(0).getClass()); @@ -127,11 +115,6 @@ public class ViewResolutionRegistryTests { assertEquals("/", resolverDirectFieldAccessor.getPropertyValue("prefix")); assertEquals(".vm", resolverDirectFieldAccessor.getPropertyValue("suffix")); assertEquals(1024, resolverDirectFieldAccessor.getPropertyValue("cacheLimit")); - - assertNotNull(registry.getVelocityConfigurer()); - VelocityConfigurer configurer = registry.getVelocityConfigurer(); - DirectFieldAccessor configurerDirectFieldAccessor = new DirectFieldAccessor(configurer); - assertEquals("testResourceLoaderPath", configurerDirectFieldAccessor.getPropertyValue("resourceLoaderPath")); } @Test @@ -144,16 +127,11 @@ public class ViewResolutionRegistryTests { DirectFieldAccessor resolverDirectFieldAccessor = new DirectFieldAccessor(resolver); assertEquals("", resolverDirectFieldAccessor.getPropertyValue("prefix")); assertEquals(".vm", resolverDirectFieldAccessor.getPropertyValue("suffix")); - - assertNotNull(registry.getVelocityConfigurer()); - VelocityConfigurer configurer = registry.getVelocityConfigurer(); - DirectFieldAccessor configurerDirectFieldAccessor = new DirectFieldAccessor(configurer); - assertEquals("/WEB-INF/", configurerDirectFieldAccessor.getPropertyValue("resourceLoaderPath")); } @Test public void freeMarkerViewResolution() { - registry.freemarker().prefix("/").suffix(".fmt").cache(false).templateLoaderPath("path1", "path2"); + registry.freemarker().prefix("/").suffix(".fmt").cache(false); assertNotNull(registry.getViewResolvers()); assertEquals(1, registry.getViewResolvers().size()); assertEquals(FreeMarkerViewResolver.class, registry.getViewResolvers().get(0).getClass()); @@ -162,15 +140,6 @@ public class ViewResolutionRegistryTests { assertEquals("/", resolverDirectFieldAccessor.getPropertyValue("prefix")); assertEquals(".fmt", resolverDirectFieldAccessor.getPropertyValue("suffix")); assertEquals(0, resolverDirectFieldAccessor.getPropertyValue("cacheLimit")); - - assertNotNull(registry.getFreeMarkerConfigurer()); - FreeMarkerConfigurer configurer = registry.getFreeMarkerConfigurer(); - DirectFieldAccessor configurerDirectFieldAccessor = new DirectFieldAccessor(configurer); - assertNotNull(configurerDirectFieldAccessor.getPropertyValue("templateLoaderPaths")); - String[] templateLoaderPaths = (String[])configurerDirectFieldAccessor.getPropertyValue("templateLoaderPaths"); - assertEquals(2, templateLoaderPaths.length); - assertEquals("path1", templateLoaderPaths[0]); - assertEquals("path2", templateLoaderPaths[1]); } @Test @@ -183,8 +152,6 @@ public class ViewResolutionRegistryTests { DirectFieldAccessor resolverDirectFieldAccessor = new DirectFieldAccessor(resolver); assertEquals("", resolverDirectFieldAccessor.getPropertyValue("prefix")); assertEquals(".ftl", resolverDirectFieldAccessor.getPropertyValue("suffix")); - DirectFieldAccessor configurerDirectFieldAccessor = new DirectFieldAccessor(registry.getFreeMarkerConfigurer()); - assertArrayEquals(new String[]{"/WEB-INF/"}, (String[])configurerDirectFieldAccessor.getPropertyValue("templateLoaderPaths")); } @Test diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/annotation/WEB-INF/index.ftl b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/annotation/WEB-INF/index.ftl new file mode 100644 index 0000000000..fe9a8f9b85 --- /dev/null +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/annotation/WEB-INF/index.ftl @@ -0,0 +1 @@ +${model.hello} \ No newline at end of file diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/annotation/WEB-INF/index.jsp b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/annotation/WEB-INF/index.jsp new file mode 100644 index 0000000000..c76e72290a --- /dev/null +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/annotation/WEB-INF/index.jsp @@ -0,0 +1,12 @@ +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> + + + + + My First Web Application Using Spring MVC + + +${model.hello} + + + diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/annotation/WEB-INF/index.vm b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/annotation/WEB-INF/index.vm new file mode 100644 index 0000000000..fe9a8f9b85 --- /dev/null +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/annotation/WEB-INF/index.vm @@ -0,0 +1 @@ +${model.hello} \ No newline at end of file diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/annotation/WEB-INF/tiles.xml b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/annotation/WEB-INF/tiles.xml new file mode 100644 index 0000000000..7da601da16 --- /dev/null +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/annotation/WEB-INF/tiles.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file