Avoid defensive checks against Java 8 API (java.util.Optional etc)
This commit also fixes broken javadoc links and code references. Issue: SPR-13188
This commit is contained in:
@@ -38,9 +38,7 @@ import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.convert.ConversionException;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.lang.UsesJava8;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -75,19 +73,6 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
*/
|
||||
private static final Log logger = LogFactory.getLog(AbstractNestablePropertyAccessor.class);
|
||||
|
||||
private static Class<?> javaUtilOptionalClass = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
javaUtilOptionalClass =
|
||||
ClassUtils.forName("java.util.Optional", AbstractNestablePropertyAccessor.class.getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Java 8 not available - Optional references simply not supported then.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int autoGrowCollectionLimit = Integer.MAX_VALUE;
|
||||
|
||||
Object wrappedObject;
|
||||
@@ -202,13 +187,8 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
* @param rootObject the root object at the top of the path
|
||||
*/
|
||||
public void setWrappedInstance(Object object, String nestedPath, Object rootObject) {
|
||||
Assert.notNull(object, "Target object must not be null");
|
||||
if (object.getClass() == javaUtilOptionalClass) {
|
||||
this.wrappedObject = OptionalUnwrapper.unwrap(object);
|
||||
}
|
||||
else {
|
||||
this.wrappedObject = object;
|
||||
}
|
||||
this.wrappedObject = ObjectUtils.unwrapOptional(object);
|
||||
Assert.notNull(this.wrappedObject, "Target object must not be null");
|
||||
this.nestedPath = (nestedPath != null ? nestedPath : "");
|
||||
this.rootObject = (!"".equals(this.nestedPath) ? rootObject : this.wrappedObject);
|
||||
this.nestedPropertyAccessors = null;
|
||||
@@ -834,7 +814,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
PropertyTokenHolder tokens = getPropertyNameTokens(nestedProperty);
|
||||
String canonicalName = tokens.canonicalName;
|
||||
Object value = getPropertyValue(tokens);
|
||||
if (value == null || (value.getClass() == javaUtilOptionalClass && OptionalUnwrapper.isEmpty(value))) {
|
||||
if (value == null || (value instanceof Optional && !((Optional) value).isPresent())) {
|
||||
if (isAutoGrowNestedPaths()) {
|
||||
value = setDefaultValue(tokens);
|
||||
}
|
||||
@@ -845,8 +825,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
|
||||
// Lookup cached sub-PropertyAccessor, create new one if not found.
|
||||
AbstractNestablePropertyAccessor nestedPa = this.nestedPropertyAccessors.get(canonicalName);
|
||||
if (nestedPa == null || nestedPa.getWrappedInstance() !=
|
||||
(value.getClass() == javaUtilOptionalClass ? OptionalUnwrapper.unwrap(value) : value)) {
|
||||
if (nestedPa == null || nestedPa.getWrappedInstance() != ObjectUtils.unwrapOptional(value)) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Creating new nested " + getClass().getSimpleName() + " for property '" + canonicalName + "'");
|
||||
}
|
||||
@@ -1037,24 +1016,4 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
|
||||
public String[] keys;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inner class to avoid a hard dependency on Java 8.
|
||||
*/
|
||||
@UsesJava8
|
||||
private static class OptionalUnwrapper {
|
||||
|
||||
public static Object unwrap(Object optionalObject) {
|
||||
Optional<?> optional = (Optional<?>) optionalObject;
|
||||
Assert.isTrue(optional.isPresent(), "Optional value must be present");
|
||||
Object result = optional.get();
|
||||
Assert.isTrue(!(result instanceof Optional), "Multi-level Optional usage not supported");
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(Object optionalObject) {
|
||||
return !((Optional<?>) optionalObject).isPresent();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -54,20 +55,6 @@ class TypeConverterDelegate {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(TypeConverterDelegate.class);
|
||||
|
||||
/** Java 8's java.util.Optional.empty() instance */
|
||||
private static Object javaUtilOptionalEmpty = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class<?> clazz = ClassUtils.forName("java.util.Optional", TypeConverterDelegate.class.getClassLoader());
|
||||
javaUtilOptionalEmpty = ClassUtils.getMethod(clazz, "empty").invoke(null);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Java 8 not available - conversion to Optional not supported then.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final PropertyEditorRegistrySupport propertyEditorRegistry;
|
||||
|
||||
private final Object targetObject;
|
||||
@@ -269,8 +256,8 @@ class TypeConverterDelegate {
|
||||
}
|
||||
else {
|
||||
// convertedValue == null
|
||||
if (javaUtilOptionalEmpty != null && requiredType.equals(javaUtilOptionalEmpty.getClass())) {
|
||||
convertedValue = javaUtilOptionalEmpty;
|
||||
if (requiredType == Optional.class) {
|
||||
convertedValue = Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,6 @@ import org.springframework.beans.factory.config.DependencyDescriptor;
|
||||
import org.springframework.core.OrderComparator;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.lang.UsesJava8;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CompositeIterator;
|
||||
@@ -114,18 +113,9 @@ import org.springframework.util.StringUtils;
|
||||
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
|
||||
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
|
||||
|
||||
private static Class<?> javaUtilOptionalClass = null;
|
||||
|
||||
private static Class<?> javaxInjectProviderClass = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
javaUtilOptionalClass =
|
||||
ClassUtils.forName("java.util.Optional", DefaultListableBeanFactory.class.getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Java 8 not available - Optional references simply not supported then.
|
||||
}
|
||||
try {
|
||||
javaxInjectProviderClass =
|
||||
ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());
|
||||
@@ -1002,8 +992,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
|
||||
|
||||
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
|
||||
if (descriptor.getDependencyType().equals(javaUtilOptionalClass)) {
|
||||
return new OptionalDependencyFactory().createOptionalDependency(descriptor, beanName);
|
||||
if (descriptor.getDependencyType() == Optional.class) {
|
||||
return createOptionalDependency(descriptor, beanName);
|
||||
}
|
||||
else if (ObjectFactory.class == descriptor.getDependencyType() ||
|
||||
ObjectProvider.class == descriptor.getDependencyType()) {
|
||||
@@ -1403,6 +1393,23 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
"Dependency annotations: " + ObjectUtils.nullSafeToString(descriptor.getAnnotations()));
|
||||
}
|
||||
|
||||
private Optional<?> createOptionalDependency(DependencyDescriptor descriptor, String beanName, final Object... args) {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(descriptor) {
|
||||
@Override
|
||||
public boolean isRequired() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveCandidate(String beanName, BeanFactory beanFactory) {
|
||||
return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, args) :
|
||||
super.resolveCandidate(beanName, beanFactory));
|
||||
}
|
||||
};
|
||||
descriptorToUse.increaseNestingLevel();
|
||||
return Optional.ofNullable(doResolveDependency(descriptorToUse, beanName, null, null));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@@ -1466,30 +1473,6 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Separate inner class for avoiding a hard dependency on the {@code javax.inject} API.
|
||||
*/
|
||||
@UsesJava8
|
||||
private class OptionalDependencyFactory {
|
||||
|
||||
public Object createOptionalDependency(DependencyDescriptor descriptor, String beanName, final Object... args) {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(descriptor) {
|
||||
@Override
|
||||
public boolean isRequired() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public Object resolveCandidate(String beanName, BeanFactory beanFactory) {
|
||||
return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, args) :
|
||||
super.resolveCandidate(beanName, beanFactory));
|
||||
}
|
||||
};
|
||||
descriptorToUse.increaseNestingLevel();
|
||||
return Optional.ofNullable(doResolveDependency(descriptorToUse, beanName, null, null));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializable ObjectFactory/ObjectProvider for lazy resolution of a dependency.
|
||||
*/
|
||||
@@ -1504,14 +1487,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
public DependencyObjectProvider(DependencyDescriptor descriptor, String beanName) {
|
||||
this.descriptor = new DependencyDescriptor(descriptor);
|
||||
this.descriptor.increaseNestingLevel();
|
||||
this.optional = this.descriptor.getDependencyType().equals(javaUtilOptionalClass);
|
||||
this.optional = (this.descriptor.getDependencyType() == Optional.class);
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject() throws BeansException {
|
||||
if (this.optional) {
|
||||
return new OptionalDependencyFactory().createOptionalDependency(this.descriptor, this.beanName);
|
||||
return createOptionalDependency(this.descriptor, this.beanName);
|
||||
}
|
||||
else {
|
||||
return doResolveDependency(this.descriptor, this.beanName, null, null);
|
||||
@@ -1521,7 +1504,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
@Override
|
||||
public Object getObject(final Object... args) throws BeansException {
|
||||
if (this.optional) {
|
||||
return new OptionalDependencyFactory().createOptionalDependency(this.descriptor, this.beanName, args);
|
||||
return createOptionalDependency(this.descriptor, this.beanName, args);
|
||||
}
|
||||
else {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(descriptor) {
|
||||
@@ -1537,7 +1520,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
@Override
|
||||
public Object getIfAvailable() throws BeansException {
|
||||
if (this.optional) {
|
||||
return new OptionalDependencyFactory().createOptionalDependency(this.descriptor, this.beanName);
|
||||
return createOptionalDependency(this.descriptor, this.beanName);
|
||||
}
|
||||
else {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(descriptor) {
|
||||
@@ -1563,7 +1546,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
}
|
||||
};
|
||||
if (this.optional) {
|
||||
return new OptionalDependencyFactory().createOptionalDependency(descriptorToUse, this.beanName);
|
||||
return createOptionalDependency(descriptorToUse, this.beanName);
|
||||
}
|
||||
else {
|
||||
return doResolveDependency(descriptorToUse, this.beanName, null, null);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,8 +19,6 @@ package org.springframework.beans.propertyeditors;
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.time.ZoneId;
|
||||
|
||||
import org.springframework.lang.UsesJava8;
|
||||
|
||||
/**
|
||||
* Editor for {@code java.time.ZoneId}, translating zone ID Strings into {@code ZoneId}
|
||||
* objects. Exposes the {@code TimeZone} ID as a text representation.
|
||||
@@ -30,7 +28,6 @@ import org.springframework.lang.UsesJava8;
|
||||
* @see java.time.ZoneId
|
||||
* @see TimeZoneEditor
|
||||
*/
|
||||
@UsesJava8
|
||||
public class ZoneIdEditor extends PropertyEditorSupport {
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user