From 7ade1b8c81e0bd6f012115c89b6759a5673e8bdc Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 2 Feb 2017 13:59:51 -0500 Subject: [PATCH] Catch up with the latest Spring Framework 5 snapshot --- build.gradle | 2 +- .../convert/converters/ArrayToCollection.java | 5 +- .../converters/CollectionToCollection.java | 4 +- .../converters/ObjectToCollection.java | 4 +- .../faces/webflow/FlowELResolver.java | 23 +---- .../el/SpringBeanWebFlowELResolver.java | 85 ++++++++++++++++++- 6 files changed, 92 insertions(+), 31 deletions(-) diff --git a/build.gradle b/build.gradle index c33455a6..ec351938 100644 --- a/build.gradle +++ b/build.gradle @@ -67,7 +67,7 @@ subprojects { subproject -> log4jVersion = "2.7" servletVersion = "3.1.0" slf4jVersion = "1.7.22" - springVersion = "5.0.0.M4" + springVersion = "5.0.0.BUILD-SNAPSHOT" springSecurityVersion = "4.2.1.RELEASE" tiles3Version = "3.0.7" } diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/converters/ArrayToCollection.java b/spring-binding/src/main/java/org/springframework/binding/convert/converters/ArrayToCollection.java index b3922f7e..e4e5f82c 100644 --- a/spring-binding/src/main/java/org/springframework/binding/convert/converters/ArrayToCollection.java +++ b/spring-binding/src/main/java/org/springframework/binding/convert/converters/ArrayToCollection.java @@ -27,7 +27,7 @@ import java.util.TreeSet; import org.springframework.binding.convert.ConversionExecutor; import org.springframework.binding.convert.ConversionService; -import org.springframework.core.GenericCollectionTypeResolver; +import org.springframework.core.ResolvableType; /** * Special converter that converts from a source array to a target collection. Supports the selection of an @@ -137,8 +137,7 @@ public class ArrayToCollection implements TwoWayConverter { if (elementConverter != null) { return elementConverter; } else { - Class elementType = GenericCollectionTypeResolver - .getCollectionType((Class>) targetClass); + Class elementType = ResolvableType.forClass(targetClass).asCollection().resolveGeneric(0); if (elementType != null) { Class componentType = source.getClass().getComponentType(); return conversionService.getConversionExecutor(componentType, elementType); diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/converters/CollectionToCollection.java b/spring-binding/src/main/java/org/springframework/binding/convert/converters/CollectionToCollection.java index b5467fbd..1e233f1d 100644 --- a/spring-binding/src/main/java/org/springframework/binding/convert/converters/CollectionToCollection.java +++ b/spring-binding/src/main/java/org/springframework/binding/convert/converters/CollectionToCollection.java @@ -5,7 +5,7 @@ import java.util.Collection; import org.springframework.binding.convert.ConversionExecutor; import org.springframework.binding.convert.ConversionService; import org.springframework.core.CollectionFactory; -import org.springframework.core.GenericCollectionTypeResolver; +import org.springframework.core.ResolvableType; /** * A converter that can convert from one collection type to another. @@ -66,7 +66,7 @@ public class CollectionToCollection implements Converter { if (elementConverter != null) { return elementConverter; } else { - Class elementType = GenericCollectionTypeResolver.getCollectionType(targetClass); + Class elementType = ResolvableType.forClass(targetClass).asCollection().resolveGeneric(0); if (elementType != null) { Class componentType = source.getClass().getComponentType(); return conversionService.getConversionExecutor(componentType, elementType); diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/converters/ObjectToCollection.java b/spring-binding/src/main/java/org/springframework/binding/convert/converters/ObjectToCollection.java index b5f63985..fc1645f0 100644 --- a/spring-binding/src/main/java/org/springframework/binding/convert/converters/ObjectToCollection.java +++ b/spring-binding/src/main/java/org/springframework/binding/convert/converters/ObjectToCollection.java @@ -20,7 +20,7 @@ import java.util.Collection; import org.springframework.binding.convert.ConversionExecutor; import org.springframework.binding.convert.ConversionService; import org.springframework.core.CollectionFactory; -import org.springframework.core.GenericCollectionTypeResolver; +import org.springframework.core.ResolvableType; /** * Special two-way converter that converts an object to an single-element collection. Supports type conversion of the @@ -82,7 +82,7 @@ public class ObjectToCollection implements Converter { if (elementConverter != null) { return elementConverter; } else { - Class elementType = GenericCollectionTypeResolver.getCollectionType(targetClass); + Class elementType = ResolvableType.forClass(targetClass).asCollection().resolveGeneric(0); if (elementType != null) { Class componentType = source.getClass().getComponentType(); return conversionService.getConversionExecutor(componentType, elementType); diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowELResolver.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowELResolver.java index 14a8063d..16d98f4c 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowELResolver.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowELResolver.java @@ -16,19 +16,14 @@ package org.springframework.faces.webflow; import javax.el.CompositeELResolver; -import javax.el.ELContext; import javax.el.ELResolver; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.access.el.SpringBeanELResolver; -import org.springframework.beans.factory.support.StaticListableBeanFactory; import org.springframework.binding.expression.el.MapAdaptableELResolver; -import org.springframework.webflow.execution.RequestContext; -import org.springframework.webflow.execution.RequestContextHolder; import org.springframework.webflow.expression.el.FlowResourceELResolver; import org.springframework.webflow.expression.el.ImplicitFlowVariableELResolver; import org.springframework.webflow.expression.el.RequestContextELResolver; import org.springframework.webflow.expression.el.ScopeSearchingELResolver; +import org.springframework.webflow.expression.el.SpringBeanWebFlowELResolver; /** * Custom {@link ELResolver} for resolving web flow specific expressions. @@ -46,21 +41,7 @@ public class FlowELResolver extends CompositeELResolver { add(new FlowResourceELResolver()); add(new ScopeSearchingELResolver()); add(new MapAdaptableELResolver()); - add(new BeanELResolver()); - } - - private static class BeanELResolver extends SpringBeanELResolver { - - private static final BeanFactory EMPTY_BEAN_FACTORY = new StaticListableBeanFactory(); - - protected BeanFactory getBeanFactory(ELContext elContext) { - RequestContext requestContext = RequestContextHolder.getRequestContext(); - if (requestContext == null) { - return EMPTY_BEAN_FACTORY; - } - BeanFactory beanFactory = requestContext.getActiveFlow().getApplicationContext(); - return beanFactory != null ? beanFactory : EMPTY_BEAN_FACTORY; - } + add(new SpringBeanWebFlowELResolver()); } } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/SpringBeanWebFlowELResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/SpringBeanWebFlowELResolver.java index a8323b14..1ead9fbc 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/SpringBeanWebFlowELResolver.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/SpringBeanWebFlowELResolver.java @@ -15,10 +15,17 @@ */ package org.springframework.webflow.expression.el; +import java.beans.FeatureDescriptor; +import java.util.Iterator; import javax.el.ELContext; +import javax.el.ELException; +import javax.el.ELResolver; +import javax.el.PropertyNotWritableException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.access.el.SpringBeanELResolver; import org.springframework.beans.factory.support.StaticListableBeanFactory; import org.springframework.webflow.execution.RequestContext; import org.springframework.webflow.execution.RequestContextHolder; @@ -27,7 +34,9 @@ import org.springframework.webflow.execution.RequestContextHolder; * EL resolver for resolving Spring Beans accessible by a flow's bean factory. * @author Jeremy Grelle */ -public class SpringBeanWebFlowELResolver extends SpringBeanELResolver { +public class SpringBeanWebFlowELResolver extends ELResolver { + + private static final Log logger = LogFactory.getLog(SpringBeanWebFlowELResolver.class); private static final BeanFactory EMPTY_BEAN_FACTORY = new StaticListableBeanFactory(); @@ -53,4 +62,76 @@ public class SpringBeanWebFlowELResolver extends SpringBeanELResolver { return requestContext != null ? requestContext : RequestContextHolder.getRequestContext(); } + // ELResolver implementatio... + + @Override + public Object getValue(ELContext elContext, Object base, Object property) throws ELException { + if (base == null) { + String beanName = property.toString(); + BeanFactory bf = getBeanFactory(elContext); + if (bf.containsBean(beanName)) { + if (logger.isTraceEnabled()) { + logger.trace("Successfully resolved variable '" + beanName + "' in Spring BeanFactory"); + } + elContext.setPropertyResolved(true); + return bf.getBean(beanName); + } + } + return null; + } + + @Override + public Class getType(ELContext elContext, Object base, Object property) throws ELException { + if (base == null) { + String beanName = property.toString(); + BeanFactory bf = getBeanFactory(elContext); + if (bf.containsBean(beanName)) { + elContext.setPropertyResolved(true); + return bf.getType(beanName); + } + } + return null; + } + + @Override + public void setValue(ELContext elContext, Object base, Object property, Object value) throws ELException { + if (base == null) { + String beanName = property.toString(); + BeanFactory bf = getBeanFactory(elContext); + if (bf.containsBean(beanName)) { + if (value == bf.getBean(beanName)) { + // Setting the bean reference to the same value is alright - can simply be ignored... + elContext.setPropertyResolved(true); + } + else { + throw new PropertyNotWritableException( + "Variable '" + beanName + "' refers to " + + "a Spring bean which by definition is not writable"); + } + } + } + } + + @Override + public boolean isReadOnly(ELContext elContext, Object base, Object property) throws ELException { + if (base == null) { + String beanName = property.toString(); + BeanFactory bf = getBeanFactory(elContext); + if (bf.containsBean(beanName)) { + return true; + } + } + return false; + } + + @Override + public Iterator getFeatureDescriptors(ELContext elContext, Object base) { + return null; + } + + @Override + public Class getCommonPropertyType(ELContext elContext, Object base) { + return Object.class; + } + }