Skip to content

Commit c2342fd

Browse files
Test and fix for #202
1 parent 9e581bb commit c2342fd

File tree

2 files changed

+74
-50
lines changed

2 files changed

+74
-50
lines changed

src/main/scala/com/fasterxml/jackson/module/scala/introspect/BeanIntrospector.scala

+6-6
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ object BeanIntrospector {
8383

8484
def isNotSyntheticOrBridge(m: Method): Boolean = !(m.isBridge || m.isSynthetic)
8585

86-
def findMethod(cls: Class[_], name: String): Option[Method] =
87-
listMethods(cls).filter(isNotSyntheticOrBridge).find(m => NameTransformer.decode(m.getName) == name).headOption
86+
def findMethod(cls: Class[_], name: String): Seq[Method] =
87+
listMethods(cls).filter(isNotSyntheticOrBridge).filter(m => NameTransformer.decode(m.getName) == name)
8888

8989
def listFields(cls: Class[_]): Stream[Field] = cls match {
9090
case null => Stream.empty
@@ -109,11 +109,11 @@ object BeanIntrospector {
109109
}
110110

111111
def findGetter(cls: Class[_], propertyName: String): Option[Method] = {
112-
findMethod(cls, propertyName).filter(isAcceptableGetter)
112+
findMethod(cls, propertyName).find(isAcceptableGetter)
113113
}
114114

115115
def findBeanGetter(cls: Class[_], propertyName: String): Option[Method] = {
116-
findMethod(cls, "get" + propertyName.capitalize).filter(isAcceptableGetter)
116+
findMethod(cls, "get" + propertyName.capitalize).find(isAcceptableGetter)
117117
}
118118

119119
//True if the method fits the 'getter' pattern
@@ -122,11 +122,11 @@ object BeanIntrospector {
122122
}
123123

124124
def findSetter(cls: Class[_], propertyName: String): Option[Method] = {
125-
findMethod(cls, propertyName + "_=").filter(isAcceptableSetter)
125+
findMethod(cls, propertyName + "_=").find(isAcceptableSetter)
126126
}
127127

128128
def findBeanSetter(cls: Class[_], propertyName: String): Option[Method] = {
129-
findMethod(cls, "set" + propertyName.capitalize).filter(isAcceptableSetter)
129+
findMethod(cls, "set" + propertyName.capitalize).find(isAcceptableSetter)
130130
}
131131

132132
//True if the method fits the 'setter' pattern

src/test/scala/com/fasterxml/jackson/module/scala/introspect/BeanIntrospectorTest.scala

+68-44
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.fasterxml.jackson.module.scala.introspect
22

3+
import com.fasterxml.jackson.module.scala.introspect.BeanIntrospectorTest.DecodedNameMatcher
34
import org.junit.runner.RunWith
45
import org.scalatest.junit.JUnitRunner
56
import org.scalatest.{Inside, OptionValues, LoneElement, FlatSpec}
@@ -8,63 +9,76 @@ import reflect.NameTransformer
89
import com.fasterxml.jackson.module.scala.BaseSpec
910
import java.lang.reflect.Member
1011

11-
class PlainCtorBean(`field-name`: Int)
12-
{
13-
// This needs to exist otherwise it gets optimized away
14-
def x = `field-name`
15-
}
12+
object BeanIntrospectorTest {
1613

17-
class ValCtorBean(val `field-name`: Int)
18-
case class ValCaseBean(`field-name`: Int)
14+
class PlainCtorBean(`field-name`: Int) {
15+
// This needs to exist otherwise it gets optimized away
16+
def x = `field-name`
17+
}
1918

20-
class VarCtorBean(var `field-name`: Int)
21-
case class VarCaseBean(var `field-name`: Int)
19+
class ValCtorBean(val `field-name`: Int)
2220

23-
class MethodBean
24-
{
25-
def `field-name` = 0
26-
def `field-name_=`(v: Int) { }
27-
}
21+
case class ValCaseBean(`field-name`: Int)
2822

29-
//adding @SerialVersionUID puts a public static final int field on the generated class
30-
//this field should be ignored
31-
@SerialVersionUID(8675309)
32-
case class SerialIDBean(field: String) {
33-
@transient val shouldBeExluded = 10
34-
@volatile var alsoExcluded = 20
35-
}
23+
class VarCtorBean(var `field-name`: Int)
3624

37-
class StaticMethodBean extends JavaStaticMethods {
38-
val included = "included"
39-
}
25+
case class VarCaseBean(var `field-name`: Int)
4026

41-
class Parent {
42-
var parentValue = "parentValue"
43-
}
27+
class MethodBean {
28+
def `field-name` = 0
4429

45-
class Child extends Parent {
46-
var childValue = "childValue"
47-
}
30+
def `field-name_=`(v: Int) {}
31+
}
32+
33+
//adding @SerialVersionUID puts a public static final int field on the generated class
34+
//this field should be ignored
35+
@SerialVersionUID(8675309)
36+
case class SerialIDBean(field: String) {
37+
@transient val shouldBeExluded = 10
38+
@volatile var alsoExcluded = 20
39+
}
40+
41+
class StaticMethodBean extends JavaStaticMethods {
42+
val included = "included"
43+
}
44+
45+
class Parent {
46+
var parentValue = "parentValue"
47+
}
4848

49-
case class PrivateDefaultBean(private val privateField: String = "defaultValue")
50-
51-
trait DecodedNameMatcher {
52-
def decodedName(expectedValue: String) =
53-
new HavePropertyMatcher[Member, String] {
54-
def apply(member: Member) = {
55-
val decodedName = NameTransformer.decode(member.getName)
56-
HavePropertyMatchResult(
57-
decodedName == expectedValue,
58-
"name",
59-
expectedValue,
60-
decodedName
61-
)
49+
class Child extends Parent {
50+
var childValue = "childValue"
51+
}
52+
53+
case class PrivateDefaultBean(private val privateField: String = "defaultValue")
54+
55+
trait DecodedNameMatcher {
56+
def decodedName(expectedValue: String) =
57+
new HavePropertyMatcher[Member, String] {
58+
def apply(member: Member) = {
59+
val decodedName = NameTransformer.decode(member.getName)
60+
HavePropertyMatchResult(
61+
decodedName == expectedValue,
62+
"name",
63+
expectedValue,
64+
decodedName
65+
)
66+
}
6267
}
63-
}
68+
}
69+
70+
class OverloadedGetter {
71+
var firstName: String = ""
72+
var lastName: String = ""
73+
74+
def firstName(firstName: String) {}
75+
def lastName(lastName: String) {}
76+
}
6477
}
6578

6679
@RunWith(classOf[JUnitRunner])
6780
class BeanIntrospectorTest extends BaseSpec with Inside with LoneElement with OptionValues with DecodedNameMatcher {
81+
import BeanIntrospectorTest._
6882

6983
behavior of "BeanIntrospector"
7084

@@ -280,6 +294,16 @@ class BeanIntrospectorTest extends BaseSpec with Inside with LoneElement with Op
280294
props should have size 1
281295
props.head.name shouldBe "privateField"
282296
}
297+
298+
it should "find getters among overloads" in {
299+
type Bean = OverloadedGetter
300+
301+
val beanDesc = BeanIntrospector[Bean](classOf[Bean])
302+
val props = beanDesc.properties
303+
304+
props should have size 2
305+
props.forall ( _.getter.isDefined ) shouldBe true
306+
}
283307
}
284308

285309

0 commit comments

Comments
 (0)