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:
@@ -20,9 +20,7 @@ import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.lang.UsesJava7;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Base class for decorating ClassLoaders such as {@link OverridingClassLoader}
|
||||
@@ -33,20 +31,10 @@ import org.springframework.util.ClassUtils;
|
||||
* @author Rod Johnson
|
||||
* @since 2.5.2
|
||||
*/
|
||||
@UsesJava7
|
||||
public abstract class DecoratingClassLoader extends ClassLoader {
|
||||
|
||||
/**
|
||||
* Java 7+ {@code ClassLoader.registerAsParallelCapable()} available?
|
||||
* @since 4.1.2
|
||||
*/
|
||||
protected static final boolean parallelCapableClassLoaderAvailable =
|
||||
ClassUtils.hasMethod(ClassLoader.class, "registerAsParallelCapable");
|
||||
|
||||
static {
|
||||
if (parallelCapableClassLoaderAvailable) {
|
||||
ClassLoader.registerAsParallelCapable();
|
||||
}
|
||||
ClassLoader.registerAsParallelCapable();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.core;
|
||||
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Default implementation of the {@link ParameterNameDiscoverer} strategy interface,
|
||||
* using the Java 8 standard reflection mechanism (if available), and falling back
|
||||
@@ -33,14 +31,8 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
public class DefaultParameterNameDiscoverer extends PrioritizedParameterNameDiscoverer {
|
||||
|
||||
private static final boolean standardReflectionAvailable = ClassUtils.isPresent(
|
||||
"java.lang.reflect.Executable", DefaultParameterNameDiscoverer.class.getClassLoader());
|
||||
|
||||
|
||||
public DefaultParameterNameDiscoverer() {
|
||||
if (standardReflectionAvailable) {
|
||||
addDiscoverer(new StandardReflectionParameterNameDiscoverer());
|
||||
}
|
||||
addDiscoverer(new StandardReflectionParameterNameDiscoverer());
|
||||
addDiscoverer(new LocalVariableTableParameterNameDiscoverer());
|
||||
}
|
||||
|
||||
|
||||
@@ -85,10 +85,9 @@ public abstract class MethodIntrospector {
|
||||
|
||||
/**
|
||||
* Select methods on the given target type based on a filter.
|
||||
* <p>Callers define methods of interest through the
|
||||
* {@link ReflectionUtils.MethodFilter} parameter.
|
||||
* <p>Callers define methods of interest through the {@code MethodFilter} parameter.
|
||||
* @param targetType the target type to search methods on
|
||||
* @param methodFilter a {@link ReflectionUtils.MethodFilter} to help
|
||||
* @param methodFilter a {@code MethodFilter} to help
|
||||
* recognize handler methods of interest
|
||||
* @return the selected methods, or an empty set in case of no match
|
||||
*/
|
||||
|
||||
@@ -25,9 +25,9 @@ import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Helper class that encapsulates the specification of a method parameter, i.e. a {@link Method}
|
||||
@@ -48,21 +48,6 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
public class MethodParameter {
|
||||
|
||||
private static final Class<?> javaUtilOptionalClass;
|
||||
|
||||
static {
|
||||
Class<?> clazz;
|
||||
try {
|
||||
clazz = ClassUtils.forName("java.util.Optional", MethodParameter.class.getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Java 8 not available - Optional references simply not supported then.
|
||||
clazz = null;
|
||||
}
|
||||
javaUtilOptionalClass = clazz;
|
||||
}
|
||||
|
||||
|
||||
private final Method method;
|
||||
|
||||
private final Constructor<?> constructor;
|
||||
@@ -320,7 +305,7 @@ public class MethodParameter {
|
||||
* @since 4.3
|
||||
*/
|
||||
public boolean isOptional() {
|
||||
return (getParameterType() == javaUtilOptionalClass);
|
||||
return (getParameterType() == Optional.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.springframework.core;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.springframework.lang.UsesJava7;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
@@ -34,7 +33,6 @@ import org.springframework.util.FileCopyUtils;
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0.1
|
||||
*/
|
||||
@UsesJava7
|
||||
public class OverridingClassLoader extends DecoratingClassLoader {
|
||||
|
||||
/** Packages that are excluded by default */
|
||||
@@ -44,9 +42,7 @@ public class OverridingClassLoader extends DecoratingClassLoader {
|
||||
private static final String CLASS_FILE_SUFFIX = ".class";
|
||||
|
||||
static {
|
||||
if (parallelCapableClassLoaderAvailable) {
|
||||
ClassLoader.registerAsParallelCapable();
|
||||
}
|
||||
ClassLoader.registerAsParallelCapable();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -20,8 +20,6 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
|
||||
import org.springframework.lang.UsesJava8;
|
||||
|
||||
/**
|
||||
* {@link ParameterNameDiscoverer} implementation which uses JDK 8's reflection facilities
|
||||
* for introspecting parameter names (based on the "-parameters" compiler flag).
|
||||
@@ -30,7 +28,6 @@ import org.springframework.lang.UsesJava8;
|
||||
* @since 4.0
|
||||
* @see java.lang.reflect.Parameter#getName()
|
||||
*/
|
||||
@UsesJava8
|
||||
public class StandardReflectionParameterNameDiscoverer implements ParameterNameDiscoverer {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -28,7 +28,6 @@ import java.util.stream.Stream;
|
||||
import org.springframework.core.MethodParameter;
|
||||
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.ObjectUtils;
|
||||
@@ -49,9 +48,6 @@ public class TypeDescriptor implements Serializable {
|
||||
|
||||
static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
|
||||
|
||||
private static final boolean streamAvailable = ClassUtils.isPresent(
|
||||
"java.util.stream.Stream", TypeDescriptor.class.getClassLoader());
|
||||
|
||||
private static final Map<Class<?>, TypeDescriptor> commonTypesCache = new HashMap<Class<?>, TypeDescriptor>(18);
|
||||
|
||||
private static final Class<?>[] CACHED_COMMON_TYPES = {
|
||||
@@ -340,10 +336,10 @@ public class TypeDescriptor implements Serializable {
|
||||
if (this.resolvableType.isArray()) {
|
||||
return new TypeDescriptor(this.resolvableType.getComponentType(), null, this.annotations);
|
||||
}
|
||||
if (streamAvailable && StreamDelegate.isStream(this.type)) {
|
||||
return StreamDelegate.getStreamElementType(this);
|
||||
if (Stream.class.isAssignableFrom(this.type)) {
|
||||
return getRelatedIfResolvable(this, this.resolvableType.as(Stream.class).getGeneric(0));
|
||||
}
|
||||
return getRelatedIfResolvable(this, this.resolvableType.asCollection().getGeneric());
|
||||
return getRelatedIfResolvable(this, this.resolvableType.asCollection().getGeneric(0));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -694,20 +690,4 @@ public class TypeDescriptor implements Serializable {
|
||||
return new TypeDescriptor(type, null, source.annotations);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inner class to avoid a hard dependency on Java 8.
|
||||
*/
|
||||
@UsesJava8
|
||||
private static class StreamDelegate {
|
||||
|
||||
public static boolean isStream(Class<?> type) {
|
||||
return Stream.class.isAssignableFrom(type);
|
||||
}
|
||||
|
||||
public static TypeDescriptor getStreamElementType(TypeDescriptor source) {
|
||||
return getRelatedIfResolvable(source, source.resolvableType.as(Stream.class).getGeneric());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,19 +40,10 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
public class DefaultConversionService extends GenericConversionService {
|
||||
|
||||
/** Java 8's java.util.Optional class available? */
|
||||
private static final boolean javaUtilOptionalClassAvailable =
|
||||
ClassUtils.isPresent("java.util.Optional", DefaultConversionService.class.getClassLoader());
|
||||
|
||||
/** Java 8's java.time package available? */
|
||||
private static final boolean jsr310Available =
|
||||
ClassUtils.isPresent("java.time.ZoneId", DefaultConversionService.class.getClassLoader());
|
||||
|
||||
/** Java 8's java.util.stream.Stream class available? */
|
||||
private static final boolean streamAvailable = ClassUtils.isPresent(
|
||||
"java.util.stream.Stream", DefaultConversionService.class.getClassLoader());
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code DefaultConversionService} with the set of
|
||||
@@ -83,9 +74,7 @@ public class DefaultConversionService extends GenericConversionService {
|
||||
converterRegistry.addConverter(new ObjectToObjectConverter());
|
||||
converterRegistry.addConverter(new IdToEntityConverter((ConversionService) converterRegistry));
|
||||
converterRegistry.addConverter(new FallbackObjectToStringConverter());
|
||||
if (javaUtilOptionalClassAvailable) {
|
||||
converterRegistry.addConverter(new ObjectToOptionalConverter((ConversionService) converterRegistry));
|
||||
}
|
||||
converterRegistry.addConverter(new ObjectToOptionalConverter((ConversionService) converterRegistry));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,9 +106,7 @@ public class DefaultConversionService extends GenericConversionService {
|
||||
converterRegistry.addConverter(new CollectionToObjectConverter(conversionService));
|
||||
converterRegistry.addConverter(new ObjectToCollectionConverter(conversionService));
|
||||
|
||||
if (streamAvailable) {
|
||||
converterRegistry.addConverter(new StreamConverter(conversionService));
|
||||
}
|
||||
converterRegistry.addConverter(new StreamConverter(conversionService));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
@@ -72,20 +73,6 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
private static final GenericConverter NO_MATCH = new NoOpConverter("NO_MATCH");
|
||||
|
||||
|
||||
/** Java 8's java.util.Optional.empty() */
|
||||
private static Object javaUtilOptionalEmpty = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class<?> clazz = ClassUtils.forName("java.util.Optional", GenericConversionService.class.getClassLoader());
|
||||
javaUtilOptionalEmpty = ClassUtils.getMethod(clazz, "empty").invoke(null);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Java 8 not available - conversion to Optional not supported then.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final Converters converters = new Converters();
|
||||
|
||||
private final Map<ConverterCacheKey, GenericConverter> converterCache =
|
||||
@@ -231,8 +218,8 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
* @return the converted null object
|
||||
*/
|
||||
protected Object convertNullSource(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
if (javaUtilOptionalEmpty != null && targetType.getObjectType() == javaUtilOptionalEmpty.getClass()) {
|
||||
return javaUtilOptionalEmpty;
|
||||
if (targetType.getObjectType() == Optional.class) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -23,7 +23,6 @@ import java.util.Set;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.ConditionalGenericConverter;
|
||||
import org.springframework.lang.UsesJava8;
|
||||
|
||||
/**
|
||||
* Convert an Object to {@code java.util.Optional<T>} if necessary using the
|
||||
@@ -34,7 +33,6 @@ import org.springframework.lang.UsesJava8;
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.1
|
||||
*/
|
||||
@UsesJava8
|
||||
final class ObjectToOptionalConverter implements ConditionalGenericConverter {
|
||||
|
||||
private final ConversionService conversionService;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -26,7 +26,6 @@ import java.util.stream.Stream;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.ConditionalGenericConverter;
|
||||
import org.springframework.lang.UsesJava8;
|
||||
|
||||
/**
|
||||
* Converts a {@link Stream} to and from a collection or array, converting the
|
||||
@@ -35,7 +34,6 @@ import org.springframework.lang.UsesJava8;
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.2
|
||||
*/
|
||||
@UsesJava8
|
||||
class StreamConverter implements ConditionalGenericConverter {
|
||||
|
||||
private static final TypeDescriptor STREAM_TYPE = TypeDescriptor.valueOf(Stream.class);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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,7 +19,6 @@ package org.springframework.core.convert.support;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.lang.UsesJava8;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -28,7 +27,6 @@ import org.springframework.util.StringUtils;
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.2
|
||||
*/
|
||||
@UsesJava8
|
||||
class StringToTimeZoneConverter implements Converter<String, TimeZone> {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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.
|
||||
@@ -20,7 +20,6 @@ import java.time.ZoneId;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.lang.UsesJava8;
|
||||
|
||||
/**
|
||||
* Simple converter from Java 8's {@link java.time.ZoneId} to {@link java.util.TimeZone}.
|
||||
@@ -35,7 +34,6 @@ import org.springframework.lang.UsesJava8;
|
||||
* @since 4.0
|
||||
* @see TimeZone#getTimeZone(java.time.ZoneId)
|
||||
*/
|
||||
@UsesJava8
|
||||
final class ZoneIdToTimeZoneConverter implements Converter<ZoneId, TimeZone> {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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.
|
||||
@@ -21,7 +21,6 @@ import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.lang.UsesJava8;
|
||||
|
||||
/**
|
||||
* Simple converter from Java 8's {@link java.time.ZonedDateTime} to {@link java.util.Calendar}.
|
||||
@@ -36,7 +35,6 @@ import org.springframework.lang.UsesJava8;
|
||||
* @since 4.0.1
|
||||
* @see java.util.GregorianCalendar#from(java.time.ZonedDateTime)
|
||||
*/
|
||||
@UsesJava8
|
||||
final class ZonedDateTimeToCalendarConverter implements Converter<ZonedDateTime, Calendar> {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -28,7 +28,6 @@ import java.nio.file.OpenOption;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.springframework.lang.UsesJava7;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -41,7 +40,6 @@ import org.springframework.util.Assert;
|
||||
* @since 4.0
|
||||
* @see java.nio.file.Path
|
||||
*/
|
||||
@UsesJava7
|
||||
public class PathResource extends AbstractResource implements WritableResource {
|
||||
|
||||
private final Path path;
|
||||
|
||||
@@ -32,5 +32,6 @@ import java.lang.annotation.Target;
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE})
|
||||
@Documented
|
||||
@Deprecated
|
||||
public @interface UsesJava7 {
|
||||
}
|
||||
|
||||
@@ -32,5 +32,6 @@ import java.lang.annotation.Target;
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE})
|
||||
@Documented
|
||||
@Deprecated
|
||||
public @interface UsesJava8 {
|
||||
}
|
||||
|
||||
@@ -18,62 +18,22 @@ package org.springframework.util;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Base64;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
import org.springframework.lang.UsesJava8;
|
||||
|
||||
/**
|
||||
* A simple utility class for Base64 encoding and decoding.
|
||||
*
|
||||
* <p>Adapts to either Java 8's {@link java.util.Base64} class or Apache Commons Codec's
|
||||
* {@link org.apache.commons.codec.binary.Base64} class. With neither Java 8 nor Commons
|
||||
* Codec present, {@link #encode}/{@link #decode} calls will throw an IllegalStateException.
|
||||
* However, as of Spring 4.2, {@link #encodeToString} and {@link #decodeFromString} will
|
||||
* nevertheless work since they can delegate to the JAXB DatatypeConverter as a fallback.
|
||||
* However, this does not apply when using the ...UrlSafe... methods for RFC 4648 "URL and
|
||||
* Filename Safe Alphabet"; a delegate is required.
|
||||
* <p>
|
||||
* <em>Note:</em> Apache Commons Codec does not add padding ({@code =}) when encoding with
|
||||
* the URL and Filename Safe Alphabet.
|
||||
* <p>Adapts to Java 8's {@link java.util.Base64} in a convenience fashion.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Gary Russell
|
||||
* @since 4.1
|
||||
* @see java.util.Base64
|
||||
* @see org.apache.commons.codec.binary.Base64
|
||||
* @see javax.xml.bind.DatatypeConverter#printBase64Binary
|
||||
* @see javax.xml.bind.DatatypeConverter#parseBase64Binary
|
||||
*/
|
||||
public abstract class Base64Utils {
|
||||
|
||||
private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
|
||||
|
||||
|
||||
private static final Base64Delegate delegate;
|
||||
|
||||
static {
|
||||
Base64Delegate delegateToUse = null;
|
||||
// JDK 8's java.util.Base64 class present?
|
||||
if (ClassUtils.isPresent("java.util.Base64", Base64Utils.class.getClassLoader())) {
|
||||
delegateToUse = new JdkBase64Delegate();
|
||||
}
|
||||
// Apache Commons Codec present on the classpath?
|
||||
else if (ClassUtils.isPresent("org.apache.commons.codec.binary.Base64", Base64Utils.class.getClassLoader())) {
|
||||
delegateToUse = new CommonsCodecBase64Delegate();
|
||||
}
|
||||
delegate = delegateToUse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that Byte64 encoding between byte arrays is actually supported.
|
||||
* @throws IllegalStateException if neither Java 8 nor Apache Commons Codec is present
|
||||
*/
|
||||
private static void assertDelegateAvailable() {
|
||||
Assert.state(delegate != null,
|
||||
"Neither Java 8 nor Apache Commons Codec found - Base64 encoding between byte arrays not supported");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Base64-encode the given byte array.
|
||||
* @param src the original byte array (may be {@code null})
|
||||
@@ -82,8 +42,10 @@ public abstract class Base64Utils {
|
||||
* supported, i.e. neither Java 8 nor Apache Commons Codec is present at runtime
|
||||
*/
|
||||
public static byte[] encode(byte[] src) {
|
||||
assertDelegateAvailable();
|
||||
return delegate.encode(src);
|
||||
if (src == null || src.length == 0) {
|
||||
return src;
|
||||
}
|
||||
return Base64.getEncoder().encode(src);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,8 +56,10 @@ public abstract class Base64Utils {
|
||||
* supported, i.e. neither Java 8 nor Apache Commons Codec is present at runtime
|
||||
*/
|
||||
public static byte[] decode(byte[] src) {
|
||||
assertDelegateAvailable();
|
||||
return delegate.decode(src);
|
||||
if (src == null || src.length == 0) {
|
||||
return src;
|
||||
}
|
||||
return Base64.getDecoder().decode(src);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,8 +72,10 @@ public abstract class Base64Utils {
|
||||
* @since 4.2.4
|
||||
*/
|
||||
public static byte[] encodeUrlSafe(byte[] src) {
|
||||
assertDelegateAvailable();
|
||||
return delegate.encodeUrlSafe(src);
|
||||
if (src == null || src.length == 0) {
|
||||
return src;
|
||||
}
|
||||
return Base64.getUrlEncoder().encode(src);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,8 +88,10 @@ public abstract class Base64Utils {
|
||||
* @since 4.2.4
|
||||
*/
|
||||
public static byte[] decodeUrlSafe(byte[] src) {
|
||||
assertDelegateAvailable();
|
||||
return delegate.decodeUrlSafe(src);
|
||||
if (src == null || src.length == 0) {
|
||||
return src;
|
||||
}
|
||||
return Base64.getUrlDecoder().decode(src);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,15 +107,7 @@ public abstract class Base64Utils {
|
||||
if (src.length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (delegate != null) {
|
||||
// Full encoder available
|
||||
return new String(delegate.encode(src), DEFAULT_CHARSET);
|
||||
}
|
||||
else {
|
||||
// JAXB fallback for String case
|
||||
return DatatypeConverter.printBase64Binary(src);
|
||||
}
|
||||
return new String(encode(src), DEFAULT_CHARSET);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,15 +122,7 @@ public abstract class Base64Utils {
|
||||
if (src.length() == 0) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
if (delegate != null) {
|
||||
// Full encoder available
|
||||
return delegate.decode(src.getBytes(DEFAULT_CHARSET));
|
||||
}
|
||||
else {
|
||||
// JAXB fallback for String case
|
||||
return DatatypeConverter.parseBase64Binary(src);
|
||||
}
|
||||
return decode(src.getBytes(DEFAULT_CHARSET));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,8 +135,7 @@ public abstract class Base64Utils {
|
||||
* supported, i.e. neither Java 8 nor Apache Commons Codec is present at runtime
|
||||
*/
|
||||
public static String encodeToUrlSafeString(byte[] src) {
|
||||
assertDelegateAvailable();
|
||||
return new String(delegate.encodeUrlSafe(src), DEFAULT_CHARSET);
|
||||
return new String(encodeUrlSafe(src), DEFAULT_CHARSET);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,89 +147,7 @@ public abstract class Base64Utils {
|
||||
* supported, i.e. neither Java 8 nor Apache Commons Codec is present at runtime
|
||||
*/
|
||||
public static byte[] decodeFromUrlSafeString(String src) {
|
||||
assertDelegateAvailable();
|
||||
return delegate.decodeUrlSafe(src.getBytes(DEFAULT_CHARSET));
|
||||
}
|
||||
|
||||
|
||||
interface Base64Delegate {
|
||||
|
||||
byte[] encode(byte[] src);
|
||||
|
||||
byte[] decode(byte[] src);
|
||||
|
||||
byte[] encodeUrlSafe(byte[] src);
|
||||
|
||||
byte[] decodeUrlSafe(byte[] src);
|
||||
}
|
||||
|
||||
|
||||
@UsesJava8
|
||||
static class JdkBase64Delegate implements Base64Delegate {
|
||||
|
||||
@Override
|
||||
public byte[] encode(byte[] src) {
|
||||
if (src == null || src.length == 0) {
|
||||
return src;
|
||||
}
|
||||
return Base64.getEncoder().encode(src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decode(byte[] src) {
|
||||
if (src == null || src.length == 0) {
|
||||
return src;
|
||||
}
|
||||
return Base64.getDecoder().decode(src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encodeUrlSafe(byte[] src) {
|
||||
if (src == null || src.length == 0) {
|
||||
return src;
|
||||
}
|
||||
return Base64.getUrlEncoder().encode(src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeUrlSafe(byte[] src) {
|
||||
if (src == null || src.length == 0) {
|
||||
return src;
|
||||
}
|
||||
return Base64.getUrlDecoder().decode(src);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static class CommonsCodecBase64Delegate implements Base64Delegate {
|
||||
|
||||
private final org.apache.commons.codec.binary.Base64 base64 =
|
||||
new org.apache.commons.codec.binary.Base64();
|
||||
|
||||
private final org.apache.commons.codec.binary.Base64 base64UrlSafe =
|
||||
new org.apache.commons.codec.binary.Base64(0, null, true);
|
||||
|
||||
@Override
|
||||
public byte[] encode(byte[] src) {
|
||||
return this.base64.encode(src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decode(byte[] src) {
|
||||
return this.base64.decode(src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encodeUrlSafe(byte[] src) {
|
||||
return this.base64UrlSafe.encode(src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] decodeUrlSafe(byte[] src) {
|
||||
return this.base64UrlSafe.decode(src);
|
||||
}
|
||||
|
||||
return decodeUrlSafe(src.getBytes(DEFAULT_CHARSET));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,13 +24,12 @@ import java.security.NoSuchAlgorithmException;
|
||||
/**
|
||||
* Miscellaneous methods for calculating digests.
|
||||
* <p>Mainly for internal use within the framework; consider
|
||||
* <a href="http://commons.apache.org/codec/">Apache Commons Codec</a> for a
|
||||
* more comprehensive suite of digest utilities.
|
||||
* <a href="http://commons.apache.org/codec/">Apache Commons Codec</a>
|
||||
* for a more comprehensive suite of digest utilities.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Craig Andrews
|
||||
* @since 3.0
|
||||
* @see org.apache.commons.codec.digest.DigestUtils
|
||||
*/
|
||||
public abstract class DigestUtils {
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Miscellaneous object utility methods.
|
||||
@@ -109,6 +110,7 @@ public abstract class ObjectUtils {
|
||||
* Determine whether the given object is empty.
|
||||
* <p>This method supports the following object types.
|
||||
* <ul>
|
||||
* <li>{@code Optional}: considered empty if {@link Optional#empty()}</li>
|
||||
* <li>{@code Array}: considered empty if its length is zero</li>
|
||||
* <li>{@link CharSequence}: considered empty if its length is zero</li>
|
||||
* <li>{@link Collection}: delegates to {@link Collection#isEmpty()}</li>
|
||||
@@ -119,6 +121,7 @@ public abstract class ObjectUtils {
|
||||
* @param obj the object to check
|
||||
* @return {@code true} if the object is {@code null} or <em>empty</em>
|
||||
* @since 4.2
|
||||
* @see Optional#isPresent()
|
||||
* @see ObjectUtils#isEmpty(Object[])
|
||||
* @see StringUtils#hasLength(CharSequence)
|
||||
* @see StringUtils#isEmpty(Object)
|
||||
@@ -131,6 +134,9 @@ public abstract class ObjectUtils {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj instanceof Optional) {
|
||||
return !((Optional) obj).isPresent();
|
||||
}
|
||||
if (obj.getClass().isArray()) {
|
||||
return Array.getLength(obj) == 0;
|
||||
}
|
||||
@@ -148,6 +154,26 @@ public abstract class ObjectUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwrap the given object which is potentially a {@link java.util.Optional}.
|
||||
* @param obj the candidate object
|
||||
* @return either the value held within the {@code Optional}, {@code null}
|
||||
* if the {@code Optional} is empty, or simply the given object as-is
|
||||
* @since 5.0
|
||||
*/
|
||||
public static Object unwrapOptional(Object obj) {
|
||||
if (obj instanceof Optional) {
|
||||
Optional<?> optional = (Optional<?>) obj;
|
||||
if (!optional.isPresent()) {
|
||||
return null;
|
||||
}
|
||||
Object result = optional.get();
|
||||
Assert.isTrue(!(result instanceof Optional), "Multi-level Optional usage not supported");
|
||||
return result;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given array contains the given element.
|
||||
* @param array the array to check (may be {@code null},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -22,22 +22,19 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.springframework.lang.UsesJava8;
|
||||
|
||||
|
||||
/**
|
||||
* Adapts a {@link CompletableFuture} into a {@link ListenableFuture}.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @since 4.2
|
||||
*/
|
||||
@UsesJava8
|
||||
public class CompletableToListenableFutureAdapter<T> implements ListenableFuture<T> {
|
||||
|
||||
private final CompletableFuture<T> completableFuture;
|
||||
|
||||
private final ListenableFutureCallbackRegistry<T> callbacks = new ListenableFutureCallbackRegistry<T>();
|
||||
|
||||
|
||||
public CompletableToListenableFutureAdapter(CompletableFuture<T> completableFuture) {
|
||||
this.completableFuture = completableFuture;
|
||||
this.completableFuture.handle(new BiFunction<T, Throwable, Object>() {
|
||||
@@ -54,6 +51,7 @@ public class CompletableToListenableFutureAdapter<T> implements ListenableFuture
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addCallback(ListenableFutureCallback<? super T> callback) {
|
||||
this.callbacks.addCallback(callback);
|
||||
|
||||
Reference in New Issue
Block a user