From 792b7b9d114b4075c3bbe111ffdf056261c60562 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 22 May 2015 11:19:17 +0200 Subject: [PATCH] ByteBufferConverter explicitly declares applicability to byte[] Includes an optimization for simple ByteBuffer duplication. Issue: SPR-13056 --- .../convert/support/ByteBufferConverter.java | 22 +++++++++++-------- .../support/ByteBufferConverterTests.java | 6 +++-- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java index 16fd466cafb..878808d7208 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java @@ -31,6 +31,7 @@ import org.springframework.core.convert.converter.ConditionalGenericConverter; * to any type that the {@link ConversionService} support via {@code byte[]}. * * @author Phillip Webb + * @author Juergen Hoeller * @since 4.0 */ final class ByteBufferConverter implements ConditionalGenericConverter { @@ -40,8 +41,11 @@ final class ByteBufferConverter implements ConditionalGenericConverter { private static final TypeDescriptor BYTE_ARRAY_TYPE = TypeDescriptor.valueOf(byte[].class); private static final Set CONVERTIBLE_PAIRS; + static { - Set convertiblePairs = new HashSet(); + Set convertiblePairs = new HashSet(4); + convertiblePairs.add(new ConvertiblePair(ByteBuffer.class, byte[].class)); + convertiblePairs.add(new ConvertiblePair(byte[].class, ByteBuffer.class)); convertiblePairs.add(new ConvertiblePair(ByteBuffer.class, Object.class)); convertiblePairs.add(new ConvertiblePair(Object.class, ByteBuffer.class)); CONVERTIBLE_PAIRS = Collections.unmodifiableSet(convertiblePairs); @@ -63,13 +67,11 @@ final class ByteBufferConverter implements ConditionalGenericConverter { @Override public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { + boolean byteBufferTarget = targetType.isAssignableTo(BYTE_BUFFER_TYPE); if (sourceType.isAssignableTo(BYTE_BUFFER_TYPE)) { - return matchesFromByteBuffer(targetType); - } - if (targetType.isAssignableTo(BYTE_BUFFER_TYPE)) { - return matchesToByteBuffer(sourceType); + return (byteBufferTarget || matchesFromByteBuffer(targetType)); } - return false; + return (byteBufferTarget && matchesToByteBuffer(sourceType)); } private boolean matchesFromByteBuffer(TypeDescriptor targetType) { @@ -84,10 +86,12 @@ final class ByteBufferConverter implements ConditionalGenericConverter { @Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - if (sourceType.isAssignableTo(BYTE_BUFFER_TYPE)) { - return convertFromByteBuffer((ByteBuffer) source, targetType); + boolean byteBufferTarget = targetType.isAssignableTo(BYTE_BUFFER_TYPE); + if (source instanceof ByteBuffer) { + ByteBuffer buffer = (ByteBuffer) source; + return (byteBufferTarget ? buffer.duplicate() : convertFromByteBuffer(buffer, targetType)); } - if (targetType.isAssignableTo(BYTE_BUFFER_TYPE)) { + if (byteBufferTarget) { return convertToByteBuffer(source, sourceType); } // Should not happen diff --git a/spring-core/src/test/java/org/springframework/core/convert/support/ByteBufferConverterTests.java b/spring-core/src/test/java/org/springframework/core/convert/support/ByteBufferConverterTests.java index 3fc8d74fdf9..d23a2ad680f 100644 --- a/spring-core/src/test/java/org/springframework/core/convert/support/ByteBufferConverterTests.java +++ b/spring-core/src/test/java/org/springframework/core/convert/support/ByteBufferConverterTests.java @@ -30,6 +30,7 @@ import static org.junit.Assert.*; * Tests for {@link ByteBufferConverter}. * * @author Phillip Webb + * @author Juergen Hoeller */ public class ByteBufferConverterTests { @@ -38,8 +39,7 @@ public class ByteBufferConverterTests { @Before public void setup() { - this.conversionService = new GenericConversionService(); - this.conversionService.addConverter(new ByteBufferConverter(conversionService)); + this.conversionService = new DefaultConversionService(); this.conversionService.addConverter(new ByteArrayToOtherTypeConverter()); this.conversionService.addConverter(new OtherTypeToByteArrayConverter()); } @@ -87,6 +87,8 @@ public class ByteBufferConverterTests { ByteBuffer convert = this.conversionService.convert(byteBuffer, ByteBuffer.class); assertThat(convert, not(sameInstance(byteBuffer.rewind()))); assertThat(convert, equalTo(byteBuffer.rewind())); + assertThat(convert, equalTo(ByteBuffer.wrap(bytes))); + assertThat(convert.array(), equalTo(bytes)); }