|
|
|
@ -15,6 +15,7 @@ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
package org.springframework.data.relational.core.conversion; |
|
|
|
package org.springframework.data.relational.core.conversion; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.lang.reflect.Array; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Collection; |
|
|
|
import java.util.Collection; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.Collections; |
|
|
|
@ -161,55 +162,81 @@ public class BasicRelationalConverter implements RelationalConverter { |
|
|
|
|
|
|
|
|
|
|
|
if (getConversions().isSimpleType(value.getClass())) { |
|
|
|
if (getConversions().isSimpleType(value.getClass())) { |
|
|
|
|
|
|
|
|
|
|
|
if (TypeInformation.OBJECT != type) { |
|
|
|
if (TypeInformation.OBJECT != type && conversionService.canConvert(value.getClass(), type.getType())) { |
|
|
|
|
|
|
|
|
|
|
|
if (conversionService.canConvert(value.getClass(), type.getType())) { |
|
|
|
|
|
|
|
value = conversionService.convert(value, type.getType()); |
|
|
|
value = conversionService.convert(value, type.getType()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return getPotentiallyConvertedSimpleWrite(value); |
|
|
|
return getPotentiallyConvertedSimpleWrite(value); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// TODO: We should add conversion support for arrays, however,
|
|
|
|
if (value.getClass().isArray()) { |
|
|
|
// these should consider multi-dimensional arrays as well.
|
|
|
|
return writeArray(value, type); |
|
|
|
if (value.getClass().isArray() //
|
|
|
|
|
|
|
|
&& !value.getClass().getComponentType().isEnum() //
|
|
|
|
|
|
|
|
&& (TypeInformation.OBJECT.equals(type) //
|
|
|
|
|
|
|
|
|| type.isCollectionLike()) //
|
|
|
|
|
|
|
|
) { |
|
|
|
|
|
|
|
return value; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (value instanceof Collection<?>) { |
|
|
|
if (value instanceof Collection<?>) { |
|
|
|
|
|
|
|
return writeCollection((Iterable<?>) value, type); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
List<Object> mapped = new ArrayList<>(); |
|
|
|
RelationalPersistentEntity<?> persistentEntity = context.getPersistentEntity(value.getClass()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (persistentEntity != null) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Object id = persistentEntity.getIdentifierAccessor(value).getIdentifier(); |
|
|
|
|
|
|
|
return writeValue(id, type); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return conversionService.convert(value, type.getType()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Object writeArray(Object value, TypeInformation<?> type) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Class<?> componentType = value.getClass().getComponentType(); |
|
|
|
|
|
|
|
Optional<Class<?>> optionalWriteTarget = getConversions().getCustomWriteTarget(componentType); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (optionalWriteTarget.isEmpty() && !componentType.isEnum()) { |
|
|
|
|
|
|
|
return value; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Class<?> customWriteTarget = optionalWriteTarget |
|
|
|
|
|
|
|
.orElseGet(() -> componentType.isEnum() ? String.class : componentType); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// optimization: bypass identity conversion
|
|
|
|
|
|
|
|
if (customWriteTarget.equals(componentType)) { |
|
|
|
|
|
|
|
return value; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
TypeInformation<?> component = TypeInformation.OBJECT; |
|
|
|
TypeInformation<?> component = TypeInformation.OBJECT; |
|
|
|
if (type.isCollectionLike() && type.getActualType() != null) { |
|
|
|
if (type.isCollectionLike() && type.getActualType() != null) { |
|
|
|
component = type.getRequiredComponentType(); |
|
|
|
component = type.getRequiredComponentType(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (Object o : (Iterable<?>) value) { |
|
|
|
int length = Array.getLength(value); |
|
|
|
mapped.add(writeValue(o, component)); |
|
|
|
Object target = Array.newInstance(customWriteTarget, length); |
|
|
|
|
|
|
|
for (int i = 0; i < length; i++) { |
|
|
|
|
|
|
|
Array.set(target, i, writeValue(Array.get(value, i), component)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (type.getType().isInstance(mapped) || !type.isCollectionLike()) { |
|
|
|
return target; |
|
|
|
return mapped; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return conversionService.convert(mapped, type.getType()); |
|
|
|
private Object writeCollection(Iterable<?> value, TypeInformation<?> type) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RelationalPersistentEntity<?> persistentEntity = context.getPersistentEntity(value.getClass()); |
|
|
|
List<Object> mapped = new ArrayList<>(); |
|
|
|
|
|
|
|
|
|
|
|
if (persistentEntity != null) { |
|
|
|
TypeInformation<?> component = TypeInformation.OBJECT; |
|
|
|
|
|
|
|
if (type.isCollectionLike() && type.getActualType() != null) { |
|
|
|
|
|
|
|
component = type.getRequiredComponentType(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Object id = persistentEntity.getIdentifierAccessor(value).getIdentifier(); |
|
|
|
for (Object o : value) { |
|
|
|
return writeValue(id, type); |
|
|
|
mapped.add(writeValue(o, component)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return conversionService.convert(value, type.getType()); |
|
|
|
if (type.getType().isInstance(mapped) || !type.isCollectionLike()) { |
|
|
|
|
|
|
|
return mapped; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return conversionService.convert(mapped, type.getType()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
|