Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 39b783e

Browse files
committed
Consider getters using get as getter for boolean Kotlin properties.
We now additionally consider get-prefixed methods in addition to is-prefixed methods as getters for boolean properties. Closes #3249
1 parent 47a1f07 commit 39b783e

File tree

4 files changed

+95
-11
lines changed

4 files changed

+95
-11
lines changed

‎src/main/java/org/springframework/data/util/KotlinBeanInfoFactory.java‎

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,18 +94,9 @@ private static void collectKotlinProperties(Class<?> beanClass, Collection<KCall
9494

9595
if (member instanceof KProperty<?> property) {
9696

97-
Method getter = ReflectJvmMapping.getJavaGetter(property);
9897
Method setter = property instanceof KMutableProperty<?> kmp ? ReflectJvmMapping.getJavaSetter(kmp) : null;
99-
100-
if (getter == null) {
101-
Type javaType = ReflectJvmMapping.getJavaType(property.getReturnType());
102-
getter = ReflectionUtils.findMethod(beanClass,
103-
javaType == Boolean.TYPE ? "is" : "get" + StringUtils.capitalize(property.getName()));
104-
}
105-
106-
if (getter != null) {
107-
getter = ClassUtils.getMostSpecificMethod(getter, beanClass);
108-
}
98+
Type javaType = ReflectJvmMapping.getJavaType(property.getReturnType());
99+
Method getter = findGetter(beanClass, property, javaType);
109100

110101
if (getter != null && (Modifier.isStatic(getter.getModifiers()) || getter.getParameterCount() != 0)) {
111102
continue;
@@ -123,6 +114,21 @@ private static void collectKotlinProperties(Class<?> beanClass, Collection<KCall
123114
}
124115
}
125116

117+
private static @Nullable Method findGetter(Class<?> beanClass, KProperty<?> property, Type javaType) {
118+
119+
Method getter = ReflectJvmMapping.getJavaGetter(property);
120+
121+
if (getter == null && javaType == Boolean.TYPE) {
122+
getter = ReflectionUtils.findMethod(beanClass, "is" + StringUtils.capitalize(property.getName()));
123+
}
124+
125+
if (getter == null) {
126+
getter = ReflectionUtils.findMethod(beanClass, "get" + StringUtils.capitalize(property.getName()));
127+
}
128+
129+
return getter != null ? ClassUtils.getMostSpecificMethod(getter, beanClass) : null;
130+
}
131+
126132
private static void collectBasicJavaProperties(Class<?> beanClass, Map<String, PropertyDescriptor> descriptors)
127133
throws IntrospectionException {
128134

@@ -204,5 +210,7 @@ public void setWriteMethod(@Nullable Method writeMethod) {
204210
public Method getWriteMethod() {
205211
return this.writeMethod;
206212
}
213+
207214
}
215+
208216
}

‎src/test/java/org/springframework/data/projection/ProxyProjectionFactoryUnitTests.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ void supportsNullableWrapperDateToLocalDateTimeConversion() {
342342
assertThat(excerpt.getBirthdate()).contains(LocalDateTime.of(1967, 1, 9, 0, 0));
343343
}
344344

345+
345346
interface Contact {}
346347

347348
interface CustomerWithLocalDateTime {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.projection
17+
18+
open class KClassWithJavaGetter() {
19+
20+
private var fromOuterSpace: Boolean = false
21+
22+
open fun getFromOuterSpace() = fromOuterSpace
23+
24+
open fun setFromOuterSpace(newValue: Boolean) {
25+
this.fromOuterSpace = newValue
26+
}
27+
28+
}
29+
30+
open class KClassWithIsGetter() {
31+
32+
private var fromOuterSpace: Boolean = false
33+
34+
open fun isFromOuterSpace() = fromOuterSpace
35+
36+
open fun setFromOuterSpace(newValue: Boolean) {
37+
this.fromOuterSpace = newValue
38+
}
39+
40+
}

‎src/test/kotlin/org/springframework/data/util/KotlinBeanInfoFactoryUnitTests.kt‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ class KotlinBeanInfoFactoryUnitTests {
5858
assertThat(pds).hasSize(1).extracting("name").contains("value")
5959
}
6060

61+
@Test // GH-3249
62+
internal fun considersBooleanGetAndIsGetters() {
63+
64+
val isAndGet = BeanUtils.getPropertyDescriptors(KClassWithIsGetter::class.java)
65+
assertThat(isAndGet[0].readMethod.name).isEqualTo("isFromOuterSpace")
66+
67+
val getOnly = BeanUtils.getPropertyDescriptors(KClassWithGetGetter::class.java)
68+
assertThat(getOnly[0].readMethod.name).isEqualTo("getFromOuterSpace")
69+
}
70+
6171
@Test
6272
internal fun determinesInlineClassConsumerProperties() {
6373

@@ -200,4 +210,29 @@ class KotlinBeanInfoFactoryUnitTests {
200210
class User : AbstractAuditable() {
201211
var name: String? = null
202212
}
213+
214+
open class KClassWithGetGetter() {
215+
216+
private var fromOuterSpace: Boolean = false
217+
218+
open fun getFromOuterSpace() = fromOuterSpace
219+
220+
open fun setFromOuterSpace(newValue: Boolean) {
221+
this.fromOuterSpace = newValue
222+
}
223+
}
224+
225+
open class KClassWithIsGetter() {
226+
227+
private var fromOuterSpace: Boolean = false
228+
229+
open fun isFromOuterSpace() = fromOuterSpace
230+
231+
open fun getFromOuterSpace() = fromOuterSpace
232+
233+
open fun setFromOuterSpace(newValue: Boolean) {
234+
this.fromOuterSpace = newValue
235+
}
236+
}
237+
203238
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /