|
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