From 4eeab94d5981c9100a45d888c8aae1f3f1182459 Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Wed, 4 Jul 2012 12:25:19 -0400 Subject: [PATCH] INT-2650 Don't Convert byte[] The problem reported by INT-2630 was more extensive. For example, the unconditional parameter conversion causes arrays to be copied unnecessarily. The BeanFactoryTypeConverter now does a no-op conversion whenever the source type is assignable to the target type. This effectively reverts to the Spring 3.0 behavior, where this assertion resulted in the argument not being added to the argsRequiringConversion array. Polishing Add a couple more tests --- .../util/BeanFactoryTypeConverter.java | 11 ++----- .../util/BeanFactoryTypeConverterTests.java | 33 +++++++++++++++++++ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/util/BeanFactoryTypeConverter.java b/spring-integration-core/src/main/java/org/springframework/integration/util/BeanFactoryTypeConverter.java index add7805133..e6e8dd6e9b 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/util/BeanFactoryTypeConverter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/util/BeanFactoryTypeConverter.java @@ -27,8 +27,6 @@ import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.support.ConversionServiceFactory; import org.springframework.expression.TypeConverter; -import org.springframework.integration.MessageHeaders; -import org.springframework.integration.history.MessageHistory; /** * @author Dave Syer @@ -104,13 +102,10 @@ public class BeanFactoryTypeConverter implements TypeConverter, BeanFactoryAware /* * INT-2630 Spring 3.1 now converts ALL arguments; we know we don't need to convert MessageHeaders * or MessageHistory; the MapToMap converter requires a no-arg constructor. + * Also INT-2650 - don't convert large byte[] + * This reverts the effective logic to Spring 3.0. */ - if (sourceType != null && sourceType.getType() == MessageHeaders.class - && targetType.getType() == MessageHeaders.class) { - return value; - } - if (sourceType != null && sourceType.getType() == MessageHistory.class - && targetType.getType() == MessageHistory.class) { + if (sourceType != null && sourceType.isAssignableTo(targetType)) { return value; } if (conversionService.canConvert(sourceType, targetType)) { diff --git a/spring-integration-core/src/test/java/org/springframework/integration/util/BeanFactoryTypeConverterTests.java b/spring-integration-core/src/test/java/org/springframework/integration/util/BeanFactoryTypeConverterTests.java index 8cfafca517..a67f80db8e 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/util/BeanFactoryTypeConverterTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/util/BeanFactoryTypeConverterTests.java @@ -5,6 +5,9 @@ package org.springframework.integration.util; import static junit.framework.Assert.assertEquals; import static org.junit.Assert.assertSame; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.Arrays; @@ -13,6 +16,7 @@ import java.util.List; import org.junit.Test; import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.integration.Message; import org.springframework.integration.MessageHeaders; @@ -78,4 +82,33 @@ public class BeanFactoryTypeConverterTests { MessageHistory history = MessageHistory.read(message); assertSame(history, typeConverter.convertValue(history, TypeDescriptor.valueOf(MessageHeaders.class), TypeDescriptor.valueOf(MessageHeaders.class))); } + + @Test + public void testByteArrayNotConverted() { + BeanFactoryTypeConverter typeConverter = new BeanFactoryTypeConverter(); + typeConverter.setBeanFactory(new DefaultListableBeanFactory()); + byte[] bytes = new byte[1]; + assertSame(bytes, typeConverter.convertValue(bytes, TypeDescriptor.valueOf(byte[].class), TypeDescriptor.valueOf(byte[].class))); + } + + @Test + public void testStringToObjectNotConverted() { + BeanFactoryTypeConverter typeConverter = new BeanFactoryTypeConverter(); + typeConverter.setBeanFactory(new DefaultListableBeanFactory()); + String string = "foo"; + assertSame(string, typeConverter.convertValue(string, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Object.class))); + } + + @Test + public void testObjectToStringIsConverted() { + ConversionService conversionService = mock(ConversionService.class); + when(conversionService.canConvert(any(TypeDescriptor.class), any(TypeDescriptor.class))) + .thenReturn(true); + when(conversionService.convert(any(), any(TypeDescriptor.class), any(TypeDescriptor.class))) + .thenReturn("foo"); + BeanFactoryTypeConverter typeConverter = new BeanFactoryTypeConverter(conversionService); + typeConverter.setBeanFactory(new DefaultListableBeanFactory()); + Object object = new Object(); + assertEquals("foo", typeConverter.convertValue(object, TypeDescriptor.valueOf(Object.class), TypeDescriptor.valueOf(String.class))); + } }