Skip to content

Commit f2e3034

Browse files
committed
#33 - Fix for matching getters/setters for boolean/Boolean types with "is" prefix isActive -> setActive() & getActive()
1 parent 9764fd9 commit f2e3034

File tree

4 files changed

+132
-5
lines changed

4 files changed

+132
-5
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package org.example.customer;
2+
3+
import io.avaje.jsonb.Json;
4+
5+
@Json
6+
public class PubFieldsAndAccessors {
7+
8+
public String name;
9+
public int score;
10+
11+
// match the setter for isActive to setActive()
12+
private boolean isActive;
13+
14+
// match the getter for isRegistered to getRegistered()
15+
private Boolean isRegistered;
16+
17+
public String getName() {
18+
return name;
19+
}
20+
21+
public PubFieldsAndAccessors setName(String name) {
22+
this.name = name;
23+
return this;
24+
}
25+
26+
public int getScore() {
27+
return score;
28+
}
29+
30+
public PubFieldsAndAccessors setScore(int score) {
31+
this.score = score;
32+
return this;
33+
}
34+
35+
public boolean isActive() {
36+
return isActive;
37+
}
38+
39+
public PubFieldsAndAccessors setActive(boolean active) {
40+
isActive = active;
41+
return this;
42+
}
43+
44+
public Boolean getRegistered() {
45+
return isRegistered;
46+
}
47+
48+
public void setRegistered(Boolean registered) {
49+
isRegistered = registered;
50+
}
51+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package org.example.customer;
2+
3+
import io.avaje.jsonb.Jsonb;
4+
import org.junit.jupiter.api.Test;
5+
6+
import static org.assertj.core.api.Assertions.assertThat;
7+
8+
class PubFieldsAndAccessorsTest {
9+
10+
Jsonb jsonb = Jsonb.builder().build();
11+
12+
@Test
13+
void toJsonFromJson() {
14+
var bean = new PubFieldsAndAccessors();
15+
bean.name = "foo";
16+
bean.score = 42;
17+
bean.setActive(true);
18+
bean.setRegistered(true);
19+
20+
String asJson = jsonb.toJson(bean);
21+
assertThat(asJson).isEqualTo("{\"name\":\"foo\",\"score\":42,\"isActive\":true,\"isRegistered\":true}");
22+
23+
PubFieldsAndAccessors fromJson = jsonb.type(PubFieldsAndAccessors.class).fromJson(asJson);
24+
assertThat(fromJson.name).isEqualTo("foo");
25+
assertThat(fromJson.score).isEqualTo(42);
26+
assertThat(fromJson.isActive()).isEqualTo(true);
27+
assertThat(fromJson.getRegistered()).isEqualTo(true);
28+
}
29+
30+
@Test
31+
void objectBooleanAsNull() {
32+
var bean = new PubFieldsAndAccessors();
33+
bean.name = "foo";
34+
35+
String asJson = jsonb.toJson(bean);
36+
assertThat(asJson).isEqualTo("{\"name\":\"foo\",\"score\":0,\"isActive\":false}");
37+
38+
PubFieldsAndAccessors fromJson = jsonb.type(PubFieldsAndAccessors.class).fromJson(asJson);
39+
assertThat(fromJson.name).isEqualTo("foo");
40+
assertThat(fromJson.score).isEqualTo(0);
41+
assertThat(fromJson.isActive()).isEqualTo(false);
42+
assertThat(fromJson.getRegistered()).isNull();
43+
44+
45+
PubFieldsAndAccessors fromJsonWithNull = jsonb.type(PubFieldsAndAccessors.class).fromJson("{\"name\":\"bar\",\"isRegistered\":null}");
46+
assertThat(fromJsonWithNull.name).isEqualTo("bar");
47+
assertThat(fromJsonWithNull.score).isEqualTo(0);
48+
assertThat(fromJsonWithNull.isActive()).isEqualTo(false);
49+
assertThat(fromJsonWithNull.getRegistered()).isNull();
50+
}
51+
}

jsonb-generator/src/main/java/io/avaje/jsonb/generator/FieldReader.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,18 @@ String propertyName() {
8484
return propertyName;
8585
}
8686

87+
boolean typeObjectBooleanWithIsPrefix() {
88+
return nameHasIsPrefix() && genericType.topType().equals("java.lang.Boolean");
89+
}
90+
91+
boolean typeBooleanWithIsPrefix() {
92+
return nameHasIsPrefix() && (genericType.topType().equals("boolean") || genericType.topType().equals("java.lang.Boolean"));
93+
}
94+
95+
private boolean nameHasIsPrefix() {
96+
return fieldName.length() > 2 && fieldName.startsWith("is") && Character.isUpperCase(fieldName.charAt(2));
97+
}
98+
8799
boolean isRaw() {
88100
return raw;
89101
}
@@ -215,10 +227,10 @@ void writeToJson(Append writer, String varName, String prefix) {
215227
}
216228

217229
private void writeGetValue(Append writer, String varName, String suffix) {
218-
if (publicField) {
219-
writer.append("%s.%s%s", varName, fieldName, suffix);
220-
} else if (getter != null) {
230+
if (getter != null) {
221231
writer.append("%s.%s()%s", varName, getter.getName(), suffix);
232+
} else if (publicField) {
233+
writer.append("%s.%s%s", varName, fieldName, suffix);
222234
} else {
223235
writer.append("FIXME: field %s is not public and has not getter ? ", fieldName);
224236
}

jsonb-generator/src/main/java/io/avaje/jsonb/generator/TypeReader.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,14 @@ private boolean matchFieldToSetter2(FieldReader field, boolean loose) {
171171
if (setter != null) {
172172
field.setterMethod(setter);
173173
return true;
174-
} else {
175-
setter = setterLookup(setterName(name), loose);
174+
}
175+
setter = setterLookup(setterName(name), loose);
176+
if (setter != null) {
177+
field.setterMethod(setter);
178+
return true;
179+
}
180+
if (field.typeBooleanWithIsPrefix()) { // isActive -> setActive() for boolean and Boolean
181+
setter = setterLookup(setterName(name.substring(2)), loose);
176182
if (setter != null) {
177183
field.setterMethod(setter);
178184
return true;
@@ -229,6 +235,13 @@ private boolean matchFieldToGetter2(FieldReader field, boolean loose) {
229235
field.getterMethod(getter);
230236
return true;
231237
}
238+
if (field.typeObjectBooleanWithIsPrefix()) { // isRegistered -> getRegistered() for Boolean
239+
getter = getterLookup(getterName(name.substring(2)), loose);
240+
if (getter != null) {
241+
field.getterMethod(getter);
242+
return true;
243+
}
244+
}
232245
return false;
233246
}
234247

0 commit comments

Comments
 (0)