Skip to content
This repository was archived by the owner on Aug 17, 2025. It is now read-only.

Commit 100ada3

Browse files
fix: JsonAlias on getters / setters (#5660)
1 parent 2d075c1 commit 100ada3

File tree

3 files changed

+94
-5
lines changed

3 files changed

+94
-5
lines changed

jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/ModuleBuilder.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -886,8 +886,12 @@ private void buildDataElement(Data.Builder data, DotName className, Visibility v
886886
if (!Modifier.isStatic(field.flags())) {
887887
Field.Builder builder = Field.newBuilder().setName(field.name())
888888
.setType(buildType(field.type(), visibility, field));
889-
if (field.hasAnnotation(JsonAlias.class)) {
890-
var aliases = field.annotation(JsonAlias.class);
889+
MethodInfo getter = clazz.method(accessorName(field));
890+
var aliases = field.annotation(JsonAlias.class);
891+
if (aliases == null && getter != null) {
892+
aliases = getter.annotation(JsonAlias.class);
893+
}
894+
if (aliases != null) {
891895
if (aliases.value() != null) {
892896
for (var alias : aliases.value().asStringArray()) {
893897
builder.addMetadata(
@@ -897,8 +901,11 @@ private void buildDataElement(Data.Builder data, DotName className, Visibility v
897901
}
898902
}
899903
}
900-
if (field.hasAnnotation(JsonProperty.class)) {
901-
var jsonProperty = field.annotation(JsonProperty.class);
904+
var jsonProperty = field.annotation(JsonProperty.class);
905+
if (jsonProperty == null && getter != null) {
906+
jsonProperty = getter.annotation(JsonProperty.class);
907+
}
908+
if (jsonProperty != null) {
902909
if (jsonProperty.value() != null && !jsonProperty.value().asString().isEmpty()) {
903910
builder.setName(jsonProperty.value().asString());
904911
}
@@ -909,6 +916,14 @@ private void buildDataElement(Data.Builder data, DotName className, Visibility v
909916
buildDataElement(data, clazz.superName(), visibility);
910917
}
911918

919+
private String accessorName(FieldInfo field) {
920+
if (field.type().kind() == org.jboss.jandex.Type.Kind.PRIMITIVE
921+
&& field.type().asPrimitiveType().primitive() == PrimitiveType.Primitive.BOOLEAN) {
922+
return "is" + Character.toUpperCase(field.name().charAt(0)) + field.name().substring(1);
923+
}
924+
return "get" + Character.toUpperCase(field.name().charAt(0)) + field.name().substring(1);
925+
}
926+
912927
public ModuleBuilder addDecls(Decl decl) {
913928
if (decl.hasData()) {
914929
if (this.decls.containsKey(decl.getData().getName())) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package xyz.block.ftl.kotlin.deployment.test.seralization;
2+
3+
import org.jboss.shrinkwrap.api.ShrinkWrap;
4+
import org.jboss.shrinkwrap.api.spec.JavaArchive;
5+
import org.junit.jupiter.api.Assertions;
6+
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.api.extension.RegisterExtension;
8+
9+
import com.fasterxml.jackson.annotation.JsonAlias;
10+
11+
import io.quarkus.test.QuarkusUnitTest;
12+
import xyz.block.ftl.Data;
13+
import xyz.block.ftl.kotlin.deployment.test.SchemaUtil;
14+
import xyz.block.ftl.schema.v1.Decl;
15+
16+
public class JsonAliasTest {
17+
18+
// Start unit test with your extension loaded
19+
@RegisterExtension
20+
static final QuarkusUnitTest unitTest = new QuarkusUnitTest()
21+
.setArchiveProducer(() -> {
22+
var archive = ShrinkWrap.create(JavaArchive.class);
23+
archive.addClass(SchemaUtil.class);
24+
return archive;
25+
});
26+
27+
@Test
28+
public void testDataWithJsonAlias() throws Exception {
29+
var module = SchemaUtil.getSchema();
30+
Assertions.assertEquals(1, module.getDeclsCount());
31+
var e = module.getDeclsList().stream().filter(Decl::hasData).findFirst().orElseThrow();
32+
Assertions.assertEquals("Person", e.getData().getName());
33+
Assertions.assertEquals(2, e.getData().getFieldsCount());
34+
for (var field : e.getData().getFieldsList()) {
35+
switch (field.getName()) {
36+
case "first" -> {
37+
Assertions.assertEquals("given", field.getMetadata(0).getAlias().getAlias());
38+
Assertions.assertTrue(field.getType().hasString());
39+
}
40+
case "last" -> {
41+
Assertions.assertEquals("surname", field.getMetadata(0).getAlias().getAlias());
42+
Assertions.assertTrue(field.getType().hasString());
43+
}
44+
default -> throw new AssertionError("Unexpected field: " + field.getName());
45+
}
46+
47+
}
48+
}
49+
50+
@Data
51+
public static class Person {
52+
@JsonAlias("given")
53+
String first;
54+
55+
String last;
56+
57+
@JsonAlias("surname")
58+
public String getLast() {
59+
return last;
60+
}
61+
62+
public void setLast(String last) {
63+
this.last = last;
64+
}
65+
66+
public String getFirst() {
67+
return first;
68+
}
69+
70+
public void setFirst(String first) {
71+
this.first = first;
72+
}
73+
}
74+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package xyz.block.ftl.kotlin.deployment.test.seralization.verbs;
1+
package xyz.block.ftl.kotlin.deployment.test.seralization;
22

33
import org.jboss.shrinkwrap.api.ShrinkWrap;
44
import org.jboss.shrinkwrap.api.spec.JavaArchive;

0 commit comments

Comments
 (0)