Modify <faces:resources> to add portlet variant
The ResourcesBeanDefinitionParser will now automatically register an additional portlet resource resolver when a portlet environment and and relevant Spring portlet classes are detected. Issues: SWF-1500
This commit is contained in:
committed by
Rossen Stoyanchev
parent
c5471f4403
commit
d904786083
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2004-2012 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.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.faces.config;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -22,6 +23,7 @@ import org.springframework.beans.factory.support.ManagedMap;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.faces.webflow.JsfRuntimeInformation;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
||||
@@ -31,51 +33,98 @@ import org.w3c.dom.Element;
|
||||
* Parser for the resources tag.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class ResourcesBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
static final String RESOURCE_HANDLER_BEAN_NAME = "jsfResourceRequestHandler";
|
||||
static final String RESOURCE_HANDLER_CLASS_NAME = "org.springframework.faces.webflow.JsfResourceRequestHandler";
|
||||
static final String SERVLET_RESOURCE_HANDLER_BEAN_NAME = "jsfResourceRequestHandler";
|
||||
|
||||
static final String PORTLET_RESOURCE_HANDLER_BEAN_NAME = "jsfPortletResourceRequestHandler";
|
||||
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
Object source = parserContext.extractSource(element);
|
||||
registerHandlerAdapterIfNecessary(parserContext, source);
|
||||
registerResourceHandler(parserContext, source);
|
||||
registerHandlerMappings(element, parserContext, source);
|
||||
new ServletRegistrar(element, parserContext).register();
|
||||
if (JsfRuntimeInformation.isSpringPortletPresent()) {
|
||||
new PortletRegistrar(element, parserContext).register();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void registerHandlerMappings(Element element, ParserContext parserContext, Object source) {
|
||||
Map<String, String> urlMap = new ManagedMap<String, String>();
|
||||
urlMap.put("/javax.faces.resource/**", RESOURCE_HANDLER_BEAN_NAME);
|
||||
private static abstract class Registrar {
|
||||
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
beanDefinition.getPropertyValues().add("urlMap", urlMap);
|
||||
protected final Element element;
|
||||
|
||||
String order = element.getAttribute("order");
|
||||
beanDefinition.getPropertyValues().add("order", StringUtils.hasText(order) ? order : 0);
|
||||
parserContext.getReaderContext().registerWithGeneratedName(beanDefinition);
|
||||
}
|
||||
protected final ParserContext parserContext;
|
||||
|
||||
private void registerResourceHandler(ParserContext parserContext, Object source) {
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(RESOURCE_HANDLER_CLASS_NAME);
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
parserContext.getRegistry().registerBeanDefinition(RESOURCE_HANDLER_BEAN_NAME, beanDefinition);
|
||||
}
|
||||
protected final Object source;
|
||||
|
||||
private void registerHandlerAdapterIfNecessary(ParserContext parserContext, Object source) {
|
||||
if (parserContext.getRegistry().containsBeanDefinition(
|
||||
"org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter")) {
|
||||
return;
|
||||
public Registrar(Element element, ParserContext parserContext) {
|
||||
this.element = element;
|
||||
this.parserContext = parserContext;
|
||||
this.source = parserContext.extractSource(element);
|
||||
}
|
||||
|
||||
public abstract void register();
|
||||
}
|
||||
|
||||
private static class ServletRegistrar extends Registrar {
|
||||
|
||||
public ServletRegistrar(Element element, ParserContext parserContext) {
|
||||
super(element, parserContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
registerHandlerAdapterIfNecessary();
|
||||
registerResourceHandler();
|
||||
registerHandlerMappings();
|
||||
}
|
||||
|
||||
private void registerHandlerAdapterIfNecessary() {
|
||||
if (parserContext.getRegistry().containsBeanDefinition("org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter")) {
|
||||
return;
|
||||
}
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(HttpRequestHandlerAdapter.class);
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
parserContext.getReaderContext().registerWithGeneratedName(beanDefinition);
|
||||
}
|
||||
|
||||
private void registerResourceHandler() {
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition("org.springframework.faces.webflow.JsfResourceRequestHandler");
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
parserContext.getRegistry().registerBeanDefinition(SERVLET_RESOURCE_HANDLER_BEAN_NAME, beanDefinition);
|
||||
}
|
||||
|
||||
private void registerHandlerMappings() {
|
||||
Map<String, String> urlMap = new ManagedMap<String, String>();
|
||||
urlMap.put("/javax.faces.resource/**", SERVLET_RESOURCE_HANDLER_BEAN_NAME);
|
||||
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
beanDefinition.getPropertyValues().add("urlMap", urlMap);
|
||||
|
||||
String order = element.getAttribute("order");
|
||||
beanDefinition.getPropertyValues().add("order", StringUtils.hasText(order) ? order : 0);
|
||||
parserContext.getReaderContext().registerWithGeneratedName(beanDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
private static class PortletRegistrar extends Registrar {
|
||||
|
||||
public PortletRegistrar(Element element, ParserContext parserContext) {
|
||||
super(element, parserContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition("org.springframework.faces.webflow.context.portlet.JsfResourceRequestHandler");
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
parserContext.getRegistry().registerBeanDefinition(PORTLET_RESOURCE_HANDLER_BEAN_NAME, beanDefinition);
|
||||
}
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(HttpRequestHandlerAdapter.class);
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
parserContext.getReaderContext().registerWithGeneratedName(beanDefinition);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -42,7 +42,13 @@ public class JsfRuntimeInformation {
|
||||
|
||||
private static final int jsfVersion;
|
||||
|
||||
private static final boolean myFacesPresent = ClassUtils.isPresent("org.apache.myfaces.webapp.MyFacesServlet", JsfUtils.class.getClassLoader());
|
||||
private static final ClassLoader CLASS_LOADER = JsfUtils.class.getClassLoader();
|
||||
|
||||
private static final boolean myFacesPresent = ClassUtils.isPresent("org.apache.myfaces.webapp.MyFacesServlet", CLASS_LOADER);
|
||||
|
||||
private static boolean portletPresent = ClassUtils.isPresent("javax.portlet.Portlet", CLASS_LOADER);
|
||||
|
||||
private static boolean springPortletPresent = ClassUtils.isPresent("org.springframework.web.portlet.DispatcherPortlet", CLASS_LOADER);
|
||||
|
||||
static {
|
||||
if (ReflectionUtils.findMethod(FacesContext.class, "isPostback") != null) {
|
||||
@@ -82,6 +88,15 @@ public class JsfRuntimeInformation {
|
||||
return myFacesPresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the container has support for portlets and if Spring MVC portlet support is available
|
||||
*
|
||||
* @return <tt>true</tt> if a portlet environment is detected
|
||||
*/
|
||||
public static boolean isSpringPortletPresent() {
|
||||
return portletPresent && springPortletPresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the specified {@link FacesContext} is from a portlet request.
|
||||
*
|
||||
|
||||
@@ -24,16 +24,21 @@ public class ResourcesBeanDefinitionParserTests extends TestCase {
|
||||
Map<String, ?> map = this.context.getBeansOfType(HttpRequestHandlerAdapter.class);
|
||||
assertEquals(1, map.values().size());
|
||||
|
||||
Object resourceHandler = this.context.getBean(ResourcesBeanDefinitionParser.RESOURCE_HANDLER_BEAN_NAME);
|
||||
Object resourceHandler = this.context.getBean(ResourcesBeanDefinitionParser.SERVLET_RESOURCE_HANDLER_BEAN_NAME);
|
||||
assertNotNull(resourceHandler);
|
||||
assertTrue(resourceHandler instanceof JsfResourceRequestHandler);
|
||||
|
||||
map = this.context.getBeansOfType(SimpleUrlHandlerMapping.class);
|
||||
assertEquals(1, map.values().size());
|
||||
SimpleUrlHandlerMapping handlerMapping = (SimpleUrlHandlerMapping) map.values().iterator().next();
|
||||
assertEquals(ResourcesBeanDefinitionParser.RESOURCE_HANDLER_BEAN_NAME,
|
||||
assertEquals(ResourcesBeanDefinitionParser.SERVLET_RESOURCE_HANDLER_BEAN_NAME,
|
||||
handlerMapping.getUrlMap().get("/javax.faces.resource/**"));
|
||||
assertEquals(0, handlerMapping.getOrder());
|
||||
}
|
||||
|
||||
|
||||
public void testConfigurePortlet() {
|
||||
Object resourceHandler = this.context.getBean(ResourcesBeanDefinitionParser.PORTLET_RESOURCE_HANDLER_BEAN_NAME);
|
||||
assertNotNull(resourceHandler);
|
||||
assertTrue(resourceHandler instanceof org.springframework.faces.webflow.context.portlet.JsfResourceRequestHandler);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user