|
|
|
@ -1,5 +1,5 @@ |
|
|
|
|
/* |
|
|
|
|
* Copyright 2002-2012 the original author or authors. |
|
|
|
|
* Copyright 2002-2014 the original author or authors. |
|
|
|
|
* |
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
@ -31,20 +31,23 @@ import org.springframework.util.ReflectionUtils; |
|
|
|
|
* Converts an entity identifier to a entity reference by calling a static finder method |
|
|
|
|
* on the target entity type. |
|
|
|
|
* |
|
|
|
|
* <p>For this converter to match, the finder method must be public, static, have the signature |
|
|
|
|
* <p>For this converter to match, the finder method must be static, have the signature |
|
|
|
|
* {@code find[EntityName]([IdType])}, and return an instance of the desired entity type. |
|
|
|
|
* |
|
|
|
|
* @author Keith Donald |
|
|
|
|
* @author Juergen Hoeller |
|
|
|
|
* @since 3.0 |
|
|
|
|
*/ |
|
|
|
|
final class IdToEntityConverter implements ConditionalGenericConverter { |
|
|
|
|
|
|
|
|
|
private final ConversionService conversionService; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public IdToEntityConverter(ConversionService conversionService) { |
|
|
|
|
this.conversionService = conversionService; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public Set<ConvertiblePair> getConvertibleTypes() { |
|
|
|
|
return Collections.singleton(new ConvertiblePair(Object.class, Object.class)); |
|
|
|
@ -53,7 +56,8 @@ final class IdToEntityConverter implements ConditionalGenericConverter { |
|
|
|
|
@Override |
|
|
|
|
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { |
|
|
|
|
Method finder = getFinder(targetType.getType()); |
|
|
|
|
return finder != null && this.conversionService.canConvert(sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0])); |
|
|
|
|
return (finder != null && |
|
|
|
|
this.conversionService.canConvert(sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0]))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@ -62,20 +66,33 @@ final class IdToEntityConverter implements ConditionalGenericConverter { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
Method finder = getFinder(targetType.getType()); |
|
|
|
|
Object id = this.conversionService.convert(source, sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0])); |
|
|
|
|
Object id = this.conversionService.convert( |
|
|
|
|
source, sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0])); |
|
|
|
|
return ReflectionUtils.invokeMethod(finder, source, id); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Method getFinder(Class<?> entityClass) { |
|
|
|
|
String finderMethod = "find" + getEntityName(entityClass); |
|
|
|
|
Method[] methods = entityClass.getDeclaredMethods(); |
|
|
|
|
Method[] methods; |
|
|
|
|
boolean localOnlyFiltered; |
|
|
|
|
try { |
|
|
|
|
methods = entityClass.getDeclaredMethods(); |
|
|
|
|
localOnlyFiltered = true; |
|
|
|
|
} |
|
|
|
|
catch (SecurityException ex) { |
|
|
|
|
// Not allowed to access non-public methods...
|
|
|
|
|
// Fallback: check locally declared public methods only.
|
|
|
|
|
methods = entityClass.getMethods(); |
|
|
|
|
localOnlyFiltered = false; |
|
|
|
|
} |
|
|
|
|
for (Method method : methods) { |
|
|
|
|
if (Modifier.isStatic(method.getModifiers()) && method.getParameterTypes().length == 1 && method.getReturnType().equals(entityClass)) { |
|
|
|
|
if (method.getName().equals(finderMethod)) { |
|
|
|
|
if (Modifier.isStatic(method.getModifiers()) && method.getName().equals(finderMethod) && |
|
|
|
|
method.getParameterTypes().length == 1 && method.getReturnType().equals(entityClass) && |
|
|
|
|
(localOnlyFiltered || method.getDeclaringClass().equals(entityClass))) { |
|
|
|
|
return method; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|