Skip to content

Commit e3df890

Browse files
committed
DATACMNS-678 - Improved RepositoryInvoker.invokeQueryMethod(…).
Introduced a new overload for invokeQueryMethod(…) that uses a MultiValueMap with effective values of type Object so that clients can hand non-String values to the invocation. This is particularly useful if certain values shall trigger dedicated Converters registered in the ConversionService of ReflectionRepositoryInvoker. Related tickets: DATAREST-502.
1 parent b021191 commit e3df890

File tree

2 files changed

+56
-5
lines changed

2 files changed

+56
-5
lines changed

src/main/java/org/springframework/data/repository/support/ReflectionRepositoryInvoker.java

+39-5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Arrays;
2121
import java.util.List;
2222
import java.util.Map;
23+
import java.util.Map.Entry;
2324

2425
import org.springframework.core.MethodParameter;
2526
import org.springframework.core.convert.ConversionService;
@@ -30,6 +31,8 @@
3031
import org.springframework.data.repository.core.RepositoryMetadata;
3132
import org.springframework.data.repository.query.Param;
3233
import org.springframework.util.Assert;
34+
import org.springframework.util.LinkedMultiValueMap;
35+
import org.springframework.util.MultiValueMap;
3336
import org.springframework.util.ReflectionUtils;
3437
import org.springframework.util.StringUtils;
3538

@@ -164,12 +167,32 @@ public void invokeDelete(Serializable id) {
164167
}
165168
}
166169

170+
/*
171+
* (non-Javadoc)
172+
* @see org.springframework.data.repository.support.RepositoryInvoker#invokeQueryMethod(java.lang.reflect.Method, java.util.Map, org.springframework.data.domain.Pageable, org.springframework.data.domain.Sort)
173+
*/
174+
@Override
175+
public Object invokeQueryMethod(Method method, Map<String, String[]> parameters, Pageable pageable, Sort sort) {
176+
177+
Assert.notNull(method, "Method must not be null!");
178+
Assert.notNull(parameters, "Parameters must not be null!");
179+
180+
MultiValueMap<String, String> forward = new LinkedMultiValueMap<String, String>(parameters.size());
181+
182+
for (Entry<String, String[]> entry : parameters.entrySet()) {
183+
forward.put(entry.getKey(), Arrays.asList(entry.getValue()));
184+
}
185+
186+
return invokeQueryMethod(method, forward, pageable, sort);
187+
}
188+
167189
/*
168190
* (non-Javadoc)
169191
* @see org.springframework.data.rest.core.invoke.RepositoryInvoker#invokeQueryMethod(java.lang.reflect.Method, java.util.Map, org.springframework.data.domain.Pageable, org.springframework.data.domain.Sort)
170192
*/
171193
@Override
172-
public Object invokeQueryMethod(Method method, Map<String, String[]> parameters, Pageable pageable, Sort sort) {
194+
public Object invokeQueryMethod(Method method, MultiValueMap<String, ? extends Object> parameters, Pageable pageable,
195+
Sort sort) {
173196

174197
Assert.notNull(method, "Method must not be null!");
175198
Assert.notNull(parameters, "Parameters must not be null!");
@@ -179,7 +202,8 @@ public Object invokeQueryMethod(Method method, Map<String, String[]> parameters,
179202
return invoke(method, prepareParameters(method, parameters, pageable, sort));
180203
}
181204

182-
private Object[] prepareParameters(Method method, Map<String, String[]> rawParameters, Pageable pageable, Sort sort) {
205+
private Object[] prepareParameters(Method method, MultiValueMap<String, ? extends Object> rawParameters,
206+
Pageable pageable, Sort sort) {
183207

184208
List<MethodParameter> parameters = new MethodParameters(method, PARAM_ANNOTATION).getParameters();
185209

@@ -208,10 +232,10 @@ private Object[] prepareParameters(Method method, Map<String, String[]> rawParam
208232
+ " for parameter " + parameterName);
209233
}
210234

211-
String[] parameterValue = rawParameters.get(parameterName);
212-
Object value = parameterValue == null ? null : parameterValue.length == 1 ? parameterValue[0] : parameterValue;
235+
Object value = unwrapSingleElement(rawParameters.get(parameterName));
213236

214-
result[i] = conversionService.convert(value, TypeDescriptor.forObject(value), new TypeDescriptor(param));
237+
result[i] = targetType.isInstance(value) ? value : conversionService.convert(value,
238+
TypeDescriptor.forObject(value), new TypeDescriptor(param));
215239
}
216240
}
217241

@@ -275,4 +299,14 @@ protected Iterable<Object> invokeFindAllReflectively(Sort sort) {
275299

276300
return invoke(method, sort);
277301
}
302+
303+
/**
304+
* Unwraps the first item if the given source has exactly one element.
305+
*
306+
* @param source can be {@literal null}.
307+
* @return
308+
*/
309+
private static Object unwrapSingleElement(List<? extends Object> source) {
310+
return source == null ? null : source.size() == 1 ? source.get(0) : source;
311+
}
278312
}

src/main/java/org/springframework/data/repository/support/RepositoryInvoker.java

+17
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.springframework.data.domain.Pageable;
2323
import org.springframework.data.domain.Sort;
24+
import org.springframework.util.MultiValueMap;
2425

2526
/**
2627
* API to invoke (CRUD) methods on Spring Data repository instances independently of the base interface they expose.
@@ -96,6 +97,22 @@ public interface RepositoryInvoker extends RepositoryInvocationInformation {
9697
* @param pageable can be {@literal null}.
9798
* @param sort can be {@literal null}.
9899
* @return the result of the invoked query method.
100+
* @deprecated use {@link #invokeQueryMethod(Method, MultiValueMap, Pageable, Sort)} instead.
99101
*/
102+
@Deprecated
100103
Object invokeQueryMethod(Method method, Map<String, String[]> parameters, Pageable pageable, Sort sort);
104+
105+
/**
106+
* Invokes the query method backed by the given {@link Method} using the given parameters, {@link Pageable} and
107+
* {@link Sort}.
108+
*
109+
* @param method must not be {@literal null}.
110+
* @param parameters must not be {@literal null}.
111+
* @param pageable can be {@literal null}.
112+
* @param sort can be {@literal null}.
113+
* @return the result of the invoked query method.
114+
* @since 1.11
115+
*/
116+
Object invokeQueryMethod(Method method, MultiValueMap<String, ? extends Object> parameters, Pageable pageable,
117+
Sort sort);
101118
}

0 commit comments

Comments
 (0)