From 92402e7715fc1dfdf4cba8eb00e1fc787d434bcf Mon Sep 17 00:00:00 2001 From: Siva Prasad Valluru Date: Sun, 15 Dec 2013 18:15:04 +0530 Subject: [PATCH] Add initial support for MVC namespace view resolution config now allows to configure easily view resolvers. Issue: SPR-7093 --- .../servlet/config/MvcNamespaceHandler.java | 3 +- .../ViewResolversBeanDefinitionParser.java | 158 ++++++++++++++++++ .../web/servlet/config/spring-mvc-4.0.xsd | 28 ++++ .../web/servlet/config/MvcNamespaceTests.java | 35 ++++ .../config/mvc-config-view-resolvers.xml | 17 ++ spring-webmvc/src/test/resources/tiles.xml | 20 +++ 6 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java create mode 100644 spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolvers.xml create mode 100644 spring-webmvc/src/test/resources/tiles.xml diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceHandler.java index 9c099ede53..16c48d081f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceHandler.java @@ -28,13 +28,14 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport; */ public class MvcNamespaceHandler extends NamespaceHandlerSupport { - @Override + public void init() { registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser()); registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser()); registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser()); registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser()); registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser()); + registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser()); } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java new file mode 100644 index 0000000000..bbe5057a4e --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java @@ -0,0 +1,158 @@ +package org.springframework.web.servlet.config; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.parsing.BeanComponentDefinition; +import org.springframework.beans.factory.parsing.CompositeComponentDefinition; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.xml.DomUtils; +import org.springframework.web.servlet.view.BeanNameViewResolver; +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.tiles2.TilesConfigurer; +import org.springframework.web.servlet.view.tiles2.TilesView; +import org.springframework.web.servlet.view.tiles2.TilesViewResolver; +import org.w3c.dom.Element; + + +public class ViewResolversBeanDefinitionParser implements BeanDefinitionParser { + + private static final String INTERNAL_VIEW_RESOLVER_BEAN_NAME = + "org.springframework.web.servlet.view.InternalResourceViewResolver"; + private static final String TILES2_VIEW_RESOLVER_BEAN_NAME = + "org.springframework.web.servlet.view.tiles2.TilesViewResolver"; + private static final String TILES2_CONFIGURER_BEAN_NAME = + "org.springframework.web.servlet.view.tiles2.TilesConfigurer"; + private static final String BEANNAME_VIEW_RESOLVER_BEAN_NAME = + "org.springframework.web.servlet.view.BeanNameViewResolver"; + private static final String FREEMARKER_CONFIGURER_BEAN_NAME = + "org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"; + private static final String FREEMARKER_VIEW_RESOLVER_BEAN_NAME = + "org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"; + + private ParserContext parserContext; + private Object source; + + public BeanDefinition parse(Element element, ParserContext parserContext) { + + this.parserContext=parserContext; + + source= parserContext.extractSource(element); + CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(),source); + parserContext.pushContainingComponent(compDefinition); + + + + List viewResolverElements = //DomUtils.getChildElements(element); + DomUtils.getChildElementsByTagName(element, new String[] { "jsp", "tiles","bean-name","freemarker" }); + for (Element viewResolverElement : viewResolverElements) { + + if ("jsp".equals(viewResolverElement.getLocalName())) { + registerInternalResourceViewResolverBean(parserContext,viewResolverElement); + System.out.println("Registered Internalresource view resolver"); + } + + if("bean-name".equals(viewResolverElement.getLocalName())){ + registerBeanNameViewResolverBean(parserContext,viewResolverElement); + System.out.println("Registered BeanNameViewResolverBean view resolver"); + } + if ("tiles".equals(viewResolverElement.getLocalName())) { + registerTilesViewResolverBean(parserContext,viewResolverElement); + registerTilesConfigurerBean(parserContext,viewResolverElement); + } + if("freemarker".equals(viewResolverElement.getLocalName())){ + registerFreemarkerViewResolverBean(parserContext,viewResolverElement); + registerFreemarkerConfigurerBean(parserContext,viewResolverElement); + } + + } + + // MvcNamespaceUtils.registerDefaultComponents(parserContext, source); + parserContext.popAndRegisterContainingComponent(); + return null; + + + } + + private void registerBean(String beanName,Map propertyMap,Class beanClass ){ + RootBeanDefinition beanDef = new RootBeanDefinition(beanClass); + beanDef.setSource(source); + beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); + + for(String propertyName:propertyMap.keySet()){ + beanDef.getPropertyValues().add(propertyName, propertyMap.get(propertyName)); + } + parserContext.getRegistry().registerBeanDefinition(beanName, beanDef); + parserContext.registerComponent(new BeanComponentDefinition(beanDef, beanName)); + + + } + + private void registerFreemarkerConfigurerBean(ParserContext parserContext, Element viewResolverElement) { + String templateLoaderPath=viewResolverElement.getAttribute("templateLoaderPath"); + Map propertyMap= new HashMap(); + propertyMap.put("templateLoaderPath", templateLoaderPath); + + registerBean(FREEMARKER_CONFIGURER_BEAN_NAME, propertyMap, FreeMarkerConfigurer.class); + + } + + private void registerFreemarkerViewResolverBean(ParserContext parserContext, Element viewResolverElement) { + if (!parserContext.getRegistry().containsBeanDefinition(FREEMARKER_VIEW_RESOLVER_BEAN_NAME)) { + + Map propertyMap= new HashMap(); + propertyMap.put("prefix", viewResolverElement.getAttribute("prefix")); + propertyMap.put("suffix", viewResolverElement.getAttribute("suffix")); + propertyMap.put("order", 4); + registerBean(FREEMARKER_VIEW_RESOLVER_BEAN_NAME, propertyMap, FreeMarkerViewResolver.class); + } + } + + private void registerBeanNameViewResolverBean(ParserContext parserContext, Element viewResolverElement) { + if (!parserContext.getRegistry().containsBeanDefinition(BEANNAME_VIEW_RESOLVER_BEAN_NAME)) { + Map propertyMap= new HashMap(); + propertyMap.put("order", 3); + registerBean(BEANNAME_VIEW_RESOLVER_BEAN_NAME, propertyMap, BeanNameViewResolver.class); + System.out.println("Registered BeanNameViewResolverBean view resolver"); + } + } + + private void registerTilesConfigurerBean(ParserContext parserContext,Element viewResolverElement) { + if (!parserContext.getRegistry().containsBeanDefinition(TILES2_CONFIGURER_BEAN_NAME)) { + Map propertyMap= new HashMap(); + propertyMap.put("definitions", viewResolverElement.getAttribute("definitions")); + registerBean(TILES2_CONFIGURER_BEAN_NAME, propertyMap, TilesConfigurer.class); + } + } + + private void registerTilesViewResolverBean(ParserContext parserContext, Element viewResolverElement) { + + if (!parserContext.getRegistry().containsBeanDefinition(TILES2_VIEW_RESOLVER_BEAN_NAME)) { + Map propertyMap= new HashMap(); + propertyMap.put("viewClass", TilesView.class); + propertyMap.put("order", 1); + registerBean(TILES2_VIEW_RESOLVER_BEAN_NAME, propertyMap, TilesViewResolver.class); + } + } + private void registerInternalResourceViewResolverBean(ParserContext parserContext, Element viewResolverElement) { + if (!parserContext.getRegistry().containsBeanDefinition(INTERNAL_VIEW_RESOLVER_BEAN_NAME)) { + Map propertyMap= new HashMap(); + propertyMap.put("prefix", viewResolverElement.getAttribute("prefix")); + propertyMap.put("suffix", viewResolverElement.getAttribute("suffix")); + propertyMap.put("order", 2); + registerBean(INTERNAL_VIEW_RESOLVER_BEAN_NAME, propertyMap, InternalResourceViewResolver.class); + } + + + } + + + +} diff --git a/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.0.xsd b/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.0.xsd index 5846e0f391..81ddc92171 100644 --- a/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.0.xsd +++ b/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.0.xsd @@ -515,5 +515,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java index 0696ef5d50..aa325747a9 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java @@ -84,6 +84,13 @@ import org.springframework.web.servlet.resource.ResourceResolver; import org.springframework.web.servlet.resource.ResourceTransformer; import org.springframework.web.servlet.theme.ThemeChangeInterceptor; import org.springframework.web.util.UrlPathHelper; +import org.springframework.web.servlet.view.BeanNameViewResolver; +import org.springframework.web.servlet.view.InternalResourceView; +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.tiles2.TilesConfigurer; +import org.springframework.web.servlet.view.tiles2.TilesViewResolver; import static org.junit.Assert.*; @@ -114,6 +121,7 @@ public class MvcNamespaceTests { handlerMethod = new InvocableHandlerMethod(handler, method); } + @Test public void testDefaultConfig() throws Exception { loadBeanDefinitions("mvc-config.xml", 13); @@ -546,6 +554,33 @@ public class MvcNamespaceTests { (DeferredResultProcessingInterceptor[]) fieldAccessor.getPropertyValue("deferredResultInterceptors"); assertEquals(1, deferredResultInterceptors.length); } + + @Test + public void testViewResolvers() throws Exception{ + loadBeanDefinitions("mvc-config-view-resolvers.xml", 6); + InternalResourceViewResolver internalResourceViewResolver=appContext.getBean(InternalResourceViewResolver.class); + assertNotNull(internalResourceViewResolver); + InternalResourceView jstlView=(InternalResourceView) internalResourceViewResolver.resolveViewName("xyz", Locale.ENGLISH); + assertEquals(jstlView.getUrl(), "/WEB-INF/xyz.jsp"); + + BeanNameViewResolver beanNameUrlHandlerMapping=appContext.getBean(BeanNameViewResolver.class); + assertNotNull(beanNameUrlHandlerMapping); + + TilesConfigurer tilesConfigurer=appContext.getBean(TilesConfigurer.class); + assertNotNull(tilesConfigurer); + + TilesViewResolver tilesViewResolver=appContext.getBean(TilesViewResolver.class); + assertNotNull(tilesViewResolver); + + FreeMarkerConfigurer freeMarkerConfigurer=appContext.getBean(FreeMarkerConfigurer.class); + assertNotNull(freeMarkerConfigurer); + + FreeMarkerViewResolver freeMarkerViewResolver=appContext.getBean(FreeMarkerViewResolver.class); + assertNotNull(freeMarkerViewResolver); + + + } + @Test public void testPathMatchingHandlerMappings() throws Exception { diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolvers.xml b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolvers.xml new file mode 100644 index 0000000000..2e6fb59c04 --- /dev/null +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolvers.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-webmvc/src/test/resources/tiles.xml b/spring-webmvc/src/test/resources/tiles.xml new file mode 100644 index 0000000000..9e2af2edc3 --- /dev/null +++ b/spring-webmvc/src/test/resources/tiles.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file