1
1
/*
2
- * Copyright 2002-2012 the original author or authors.
2
+ * Copyright 2002-2014 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
31
31
* Converts an entity identifier to a entity reference by calling a static finder method
32
32
* on the target entity type.
33
33
*
34
- * <p>For this converter to match, the finder method must be public, static, have the signature
34
+ * <p>For this converter to match, the finder method must be static, have the signature
35
35
* {@code find[EntityName]([IdType])}, and return an instance of the desired entity type.
36
36
*
37
37
* @author Keith Donald
38
+ * @author Juergen Hoeller
38
39
* @since 3.0
39
40
*/
40
41
final class IdToEntityConverter implements ConditionalGenericConverter {
41
42
42
43
private final ConversionService conversionService ;
43
44
45
+
44
46
public IdToEntityConverter (ConversionService conversionService ) {
45
47
this .conversionService = conversionService ;
46
48
}
47
49
50
+
48
51
@ Override
49
52
public Set <ConvertiblePair > getConvertibleTypes () {
50
53
return Collections .singleton (new ConvertiblePair (Object .class , Object .class ));
@@ -53,7 +56,8 @@ public Set<ConvertiblePair> getConvertibleTypes() {
53
56
@ Override
54
57
public boolean matches (TypeDescriptor sourceType , TypeDescriptor targetType ) {
55
58
Method finder = getFinder (targetType .getType ());
56
- return finder != null && this .conversionService .canConvert (sourceType , TypeDescriptor .valueOf (finder .getParameterTypes ()[0 ]));
59
+ return (finder != null &&
60
+ this .conversionService .canConvert (sourceType , TypeDescriptor .valueOf (finder .getParameterTypes ()[0 ])));
57
61
}
58
62
59
63
@ Override
@@ -62,18 +66,31 @@ public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor t
62
66
return null ;
63
67
}
64
68
Method finder = getFinder (targetType .getType ());
65
- Object id = this .conversionService .convert (source , sourceType , TypeDescriptor .valueOf (finder .getParameterTypes ()[0 ]));
69
+ Object id = this .conversionService .convert (
70
+ source , sourceType , TypeDescriptor .valueOf (finder .getParameterTypes ()[0 ]));
66
71
return ReflectionUtils .invokeMethod (finder , source , id );
67
72
}
68
73
74
+
69
75
private Method getFinder (Class <?> entityClass ) {
70
76
String finderMethod = "find" + getEntityName (entityClass );
71
- Method [] methods = entityClass .getDeclaredMethods ();
77
+ Method [] methods ;
78
+ boolean localOnlyFiltered ;
79
+ try {
80
+ methods = entityClass .getDeclaredMethods ();
81
+ localOnlyFiltered = true ;
82
+ }
83
+ catch (SecurityException ex ) {
84
+ // Not allowed to access non-public methods...
85
+ // Fallback: check locally declared public methods only.
86
+ methods = entityClass .getMethods ();
87
+ localOnlyFiltered = false ;
88
+ }
72
89
for (Method method : methods ) {
73
- if (Modifier .isStatic (method .getModifiers ()) && method .getParameterTypes ().length == 1 && method . getReturnType (). equals (entityClass )) {
74
- if ( method .getName ().equals (finderMethod )) {
75
- return method ;
76
- }
90
+ if (Modifier .isStatic (method .getModifiers ()) && method .getName ().equals (finderMethod ) &&
91
+ method . getParameterTypes (). length == 1 && method .getReturnType ().equals (entityClass ) &&
92
+ ( localOnlyFiltered || method . getDeclaringClass (). equals ( entityClass ))) {
93
+ return method ;
77
94
}
78
95
}
79
96
return null ;
0 commit comments