Skip to content

Commit bc43f2e

Browse files
committed
IdToEntityConverter defensively handles access to getDeclaredMethods
Issue: SPR-11758 (cherry picked from commit 381ccde)
1 parent 759bb33 commit bc43f2e

File tree

1 file changed

+26
-9
lines changed

1 file changed

+26
-9
lines changed

spring-core/src/main/java/org/springframework/core/convert/support/IdToEntityConverter.java

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -31,46 +31,63 @@
3131
* Converts an entity identifier to a entity reference by calling a static finder method
3232
* on the target entity type.
3333
*
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
3535
* {@code find[EntityName]([IdType])}, and return an instance of the desired entity type.
3636
*
3737
* @author Keith Donald
38+
* @author Juergen Hoeller
3839
* @since 3.0
3940
*/
4041
final class IdToEntityConverter implements ConditionalGenericConverter {
4142

4243
private final ConversionService conversionService;
4344

45+
4446
public IdToEntityConverter(ConversionService conversionService) {
4547
this.conversionService = conversionService;
4648
}
4749

50+
4851
public Set<ConvertiblePair> getConvertibleTypes() {
4952
return Collections.singleton(new ConvertiblePair(Object.class, Object.class));
5053
}
5154

5255
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
5356
Method finder = getFinder(targetType.getType());
54-
return finder != null && this.conversionService.canConvert(sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0]));
57+
return (finder != null &&
58+
this.conversionService.canConvert(sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0])));
5559
}
5660

5761
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
5862
if (source == null) {
5963
return null;
6064
}
6165
Method finder = getFinder(targetType.getType());
62-
Object id = this.conversionService.convert(source, sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0]));
66+
Object id = this.conversionService.convert(
67+
source, sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0]));
6368
return ReflectionUtils.invokeMethod(finder, source, id);
6469
}
6570

71+
6672
private Method getFinder(Class<?> entityClass) {
6773
String finderMethod = "find" + getEntityName(entityClass);
68-
Method[] methods = entityClass.getDeclaredMethods();
74+
Method[] methods;
75+
boolean localOnlyFiltered;
76+
try {
77+
methods = entityClass.getDeclaredMethods();
78+
localOnlyFiltered = true;
79+
}
80+
catch (SecurityException ex) {
81+
// Not allowed to access non-public methods...
82+
// Fallback: check locally declared public methods only.
83+
methods = entityClass.getMethods();
84+
localOnlyFiltered = false;
85+
}
6986
for (Method method : methods) {
70-
if (Modifier.isStatic(method.getModifiers()) && method.getParameterTypes().length == 1 && method.getReturnType().equals(entityClass)) {
71-
if (method.getName().equals(finderMethod)) {
72-
return method;
73-
}
87+
if (Modifier.isStatic(method.getModifiers()) && method.getName().equals(finderMethod) &&
88+
method.getParameterTypes().length == 1 && method.getReturnType().equals(entityClass) &&
89+
(localOnlyFiltered || method.getDeclaringClass().equals(entityClass))) {
90+
return method;
7491
}
7592
}
7693
return null;

0 commit comments

Comments
 (0)