Introduced a MethodParameterConversionService to help convert query parameters that might be annotated with specific converters.

This commit is contained in:
Jon Brisbin
2012-08-20 08:23:58 -05:00
committed by Jon Brisbin
parent 349c3b9777
commit 2000d07b32
4 changed files with 84 additions and 36 deletions

View File

@@ -16,6 +16,6 @@ import org.springframework.core.convert.converter.Converter;
@Inherited
public @interface ConvertWith {
Class<? extends Converter<String[], ?>> value();
Class<? extends Converter<?, ?>> value();
}

View File

@@ -0,0 +1,58 @@
package org.springframework.data.rest.repository.invoke;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.rest.repository.annotation.ConvertWith;
import org.springframework.util.Assert;
/**
* A special conversion service that can convert {@link MethodParameter}s and their values to a target type, taking
* into account any specific conversion instructions annotated on the parameter with {@link ConvertWith}.
*
* @author Jon Brisbin
*/
public class MethodParameterConversionService {
private final ConversionService delegateConversionService;
public MethodParameterConversionService(ConversionService delegateConversionService) {
Assert.notNull(delegateConversionService, "Delegate ConversionService cannot be null.");
this.delegateConversionService = delegateConversionService;
}
public boolean canConvert(Class<?> sourceType, MethodParameter param) {
return canConvert(TypeDescriptor.valueOf(sourceType), param);
}
public boolean canConvert(TypeDescriptor sourceType, MethodParameter param) {
return (delegateConversionService.canConvert(sourceType, new TypeDescriptor(param))
|| param.hasParameterAnnotation(ConvertWith.class));
}
@SuppressWarnings({"unchecked"})
public <T> T convert(Object source, MethodParameter param) {
return convert(source, TypeDescriptor.forObject(source), param);
}
@SuppressWarnings({"unchecked"})
public <T> T convert(Object source, TypeDescriptor sourceType, MethodParameter param) {
TypeDescriptor targetType = new TypeDescriptor(param);
try {
if(param.hasParameterAnnotation(ConvertWith.class)) {
Converter<Object, T> converter = (Converter<Object, T>)param.getParameterAnnotation(ConvertWith.class)
.value()
.newInstance();
return converter.convert(source);
} else {
return (T)delegateConversionService.convert(source, sourceType, targetType);
}
} catch(Exception e) {
throw new ConversionFailedException(sourceType, targetType, source, e);
}
}
}