DATAREDIS-509 - Fix handling of primitive arrays in MappingRedisConverter.

We now correctly convert arrays of primitive values.

Original pull request: #196.
This commit is contained in:
Christoph Strobl
2016-05-06 14:49:33 +02:00
committed by Mark Paluch
parent f2cee266e3
commit 16b692c899
4 changed files with 64 additions and 9 deletions

View File

@@ -17,11 +17,11 @@ package org.springframework.data.redis.core.convert;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -426,7 +426,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
persistentProperty.getTypeInformation().getComponentType(), sink);
} else if (property.getClass().isArray()) {
writeCollection(keyspace, propertyStringPath, Arrays.asList((Object[]) property),
writeCollection(keyspace, propertyStringPath, CollectionUtils.arrayToList(property),
persistentProperty.getTypeInformation().getComponentType(), sink);
} else {
@@ -592,7 +592,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
}
}
return isArray ? target.toArray((Object[]) Array.newInstance(valueType, target.size())) : target;
return isArray ? toArray(target, collectionType, valueType) : target;
}
/**
@@ -749,6 +749,30 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
return conversionService.convert(source, type);
}
/**
* Converts a given {@link Collection} into an array considering primitive types.
*
* @param source {@link Collection} of values to be added to the array.
* @param arrayType {@link Class} of array.
* @param valueType to be used for conversion before setting the actual value.
* @return
*/
private Object toArray(Collection<Object> source, Class<?> arrayType, Class<?> valueType) {
if (!ClassUtils.isPrimitiveArray(arrayType)) {
return source.toArray((Object[]) Array.newInstance(valueType, source.size()));
}
Object targetArray = Array.newInstance(valueType, source.size());
Iterator<Object> iterator = source.iterator();
int i = 0;
while (iterator.hasNext()) {
Array.set(targetArray, i, conversionService.convert(iterator.next(), valueType));
i++;
}
return targetArray;
}
/**
* Set {@link CustomConversions} to be applied.
*

View File

@@ -15,10 +15,8 @@
*/
package org.springframework.data.redis.core.convert;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -39,6 +37,7 @@ import org.springframework.data.redis.core.mapping.RedisPersistentEntity;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
/**
* {@link IndexResolver} implementation considering properties annotated with {@link Indexed} or paths set up in
@@ -124,17 +123,18 @@ public class PathIndexResolver implements IndexResolver {
if (Iterable.class.isAssignableFrom(propertyValue.getClass())) {
iterable = (Iterable) propertyValue;
} else if (propertyValue.getClass().isArray()) {
iterable = Arrays.asList((Object[]) propertyValue);
iterable = CollectionUtils.arrayToList(propertyValue);
} else {
throw new RuntimeException("Don't know how to handle " + propertyValue.getClass() + " type of collection");
throw new RuntimeException(
"Don't know how to handle " + propertyValue.getClass() + " type of collection");
}
for (Object listValue : iterable) {
if (listValue != null) {
TypeInformation<?> typeToUse = updateTypeHintForActualValue(typeHint, listValue);
indexes.addAll(
doResolveIndexesFor(keyspace, currentPath, typeToUse.getActualType(), persistentProperty, listValue));
indexes.addAll(doResolveIndexesFor(keyspace, currentPath, typeToUse.getActualType(), persistentProperty,
listValue));
}
}
}