|
27 | 27 |
|
28 | 28 | import org.aopalliance.intercept.MethodInterceptor; |
29 | 29 | import org.aopalliance.intercept.MethodInvocation; |
30 | | - |
31 | 30 | import org.springframework.core.CollectionFactory; |
32 | 31 | import org.springframework.core.convert.ConversionService; |
33 | 32 | import org.springframework.data.util.ClassTypeInformation; |
|
45 | 44 | * |
46 | 45 | * @author Oliver Gierke |
47 | 46 | * @author Mark Paluch |
| 47 | + * @author Christoph Strobl |
48 | 48 | * @since 1.10 |
49 | 49 | */ |
50 | 50 | class ProjectingMethodInterceptor implements MethodInterceptor { |
@@ -98,20 +98,22 @@ protected Object potentiallyConvertResult(TypeInformation<?> type, @Nullable Obj |
98 | 98 | return null; |
99 | 99 | } |
100 | 100 |
|
101 | | - if (type.isCollectionLike() && !ClassUtils.isPrimitiveArray(type.getType())) { |
| 101 | + Class<?> targetType = type.getType(); |
| 102 | + |
| 103 | + if (type.isCollectionLike() && !ClassUtils.isPrimitiveArray(targetType)) { |
102 | 104 | return projectCollectionElements(asCollection(result), type); |
103 | 105 | } else if (type.isMap()) { |
104 | 106 | return projectMapValues((Map<?, ?>) result, type); |
105 | | - } else if (conversionRequiredAndPossible(result, type.getType())) { |
106 | | - return conversionService.convert(result, type.getType()); |
107 | | - } else if (ClassUtils.isAssignable(type.getType(), result.getClass())) { |
| 107 | + } else if (ClassUtils.isAssignable(targetType, result.getClass())) { |
108 | 108 | return result; |
109 | | - } else if (type.getType().isInterface()) { |
110 | | - return getProjection(result, type.getType()); |
| 109 | + } else if (conversionService.canConvert(result.getClass(), targetType)) { |
| 110 | + return conversionService.convert(result, targetType); |
| 111 | + } else if (targetType.isInterface()) { |
| 112 | + return getProjection(result, targetType); |
111 | 113 | } else { |
112 | | - throw new UnsupportedOperationException(String.format( |
113 | | - "Cannot convert value '%s' of type '%s' to '%s' and cannot create a projection as the target type is not an interface", |
114 | | - result, ClassUtils.getDescriptiveType(result), ClassUtils.getQualifiedName(type.getType()))); |
| 114 | + throw new UnsupportedOperationException( |
| 115 | + String.format("Cannot project %s to %s. Target type is not an interface and no matching Converter found!", |
| 116 | + ClassUtils.getDescriptiveType(result), ClassUtils.getQualifiedName(targetType))); |
115 | 117 | } |
116 | 118 | } |
117 | 119 |
|
@@ -166,23 +168,6 @@ private Object getProjection(@Nullable Object result, Class<?> returnType) { |
166 | 168 | : factory.createProjection(returnType, result); |
167 | 169 | } |
168 | 170 |
|
169 | | - /** |
170 | | - * Returns whether the source object needs to be converted to the given target type and whether we can convert it at |
171 | | - * all. |
172 | | - * |
173 | | - * @param source can be {@literal null}. |
174 | | - * @param targetType must not be {@literal null}. |
175 | | - * @return |
176 | | - */ |
177 | | - private boolean conversionRequiredAndPossible(Object source, Class<?> targetType) { |
178 | | - |
179 | | - if (source == null || targetType.isInstance(source)) { |
180 | | - return false; |
181 | | - } |
182 | | - |
183 | | - return conversionService.canConvert(source.getClass(), targetType); |
184 | | - } |
185 | | - |
186 | 171 | /** |
187 | 172 | * Turns the given value into a {@link Collection}. Will turn an array into a collection an wrap all other values into |
188 | 173 | * a single-element collection. |
|
0 commit comments