Skip to content

Commit

Permalink
Unwrapped/nested properties don't work with Builder (#955)
Browse files Browse the repository at this point in the history
* Unwrapped/nested properties don't work with Builder

* graalvm 1.2.4

* Fix unwrapped builder

---------

Co-authored-by: Denis Stepanov <denis.s.stepanov@oracle.com>
  • Loading branch information
radovanradic and dstepanov authored Oct 25, 2024
1 parent 9c00389 commit b23e436
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
fetch-depth: 0

- name: "🔧 Setup GraalVM CE"
uses: graalvm/setup-graalvm@v1.2.3
uses: graalvm/setup-graalvm@v1.2.4
with:
distribution: 'graalvm'
java-version: ${{ matrix.java }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -957,4 +957,56 @@ class SubClass extends SuperClass {
context.close()
}

void "test @JsonUnwrapped - with Builder"() {
given:
def ctx = buildContext("""
package unwrapped.test;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import io.micronaut.core.annotation.Introspected;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.serde.annotation.Serdeable;
import io.micronaut.serde.jackson.builder.introspected.Address;
@Serdeable
class TestNestedEntity {
private String value;
@JsonUnwrapped(prefix = "addr_")
private Address address;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
""")

when:
def nestedJsonStr = '{"value":"test1","addr_street":"Blvd 11","addr_city":"NY"}'
def deserNestedEntity = jsonMapper.readValue(nestedJsonStr, Argument.of(ctx.classLoader.loadClass('unwrapped.test.TestNestedEntity')))

then:
deserNestedEntity
deserNestedEntity.value == "test1"
deserNestedEntity.address.city == "NY"
deserNestedEntity.address.street == "Blvd 11"

cleanup:
ctx.close()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package io.micronaut.serde.jackson.builder.introspected;

import io.micronaut.core.annotation.Introspected;
import io.micronaut.serde.annotation.Serdeable;

@Serdeable
@Introspected(builder = @Introspected.IntrospectionBuilder(builderClass = Address.Builder.class))
public class Address {

private final String city;

private final String street;

public Address(String city, String street) {
this.city = city;
this.street = street;
}

public String getStreet() {
return street;
}

public String getCity() {
return city;
}

public static class Builder {

private String city;
private String street;

public Builder city(String city) {
this.city = city;
return this;
}

public Builder street(String street) {
this.street = street;
return this;
}

public Address build() {
return new Address(city, street);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ public DeserBean(DeserializationConfiguration defaultDeserializationConfiguratio
Optional<BeanProperty<T, Object>> matchingOuterProperty = introspection.getProperty(builderArgument.getName());
PropertyNamingStrategy propertyNamingStrategy = getPropertyNamingStrategy(annotationMetadata, decoderContext, entityPropertyNamingStrategy);
final String jsonProperty = resolveName(
serdeArgumentConf,
builderArgument,
matchingOuterProperty
.map(outer -> List.of(annotationMetadata, outer.getAnnotationMetadata()))
Expand Down Expand Up @@ -585,14 +586,23 @@ private String resolveName(@Nullable SerdeArgumentConf serdeArgumentConf,
AnnotatedElement annotatedElement,
AnnotationMetadata annotationMetadata,
PropertyNamingStrategy namingStrategy) {
String name = resolveName(annotatedElement, List.of(annotationMetadata), namingStrategy);
return resolveName(serdeArgumentConf, annotatedElement, List.of(annotationMetadata), namingStrategy);
}

private String resolveName(@Nullable SerdeArgumentConf serdeArgumentConf,
AnnotatedElement annotatedElement,
List<AnnotationMetadata> annotationMetadata,
PropertyNamingStrategy namingStrategy) {
String name = resolveName(annotatedElement, annotationMetadata, namingStrategy);
if (serdeArgumentConf != null) {
return serdeArgumentConf.applyPrefixSuffix(name);
}
return name;
}

private String resolveName(AnnotatedElement annotatedElement, List<AnnotationMetadata> annotationMetadata, PropertyNamingStrategy namingStrategy) {
private String resolveName(AnnotatedElement annotatedElement,
List<AnnotationMetadata> annotationMetadata,
PropertyNamingStrategy namingStrategy) {
for (AnnotationMetadata metadataElement : annotationMetadata) {
Optional<String> serde = metadataElement.stringValue(SerdeConfig.class, SerdeConfig.PROPERTY);
if (serde.isPresent()) {
Expand Down

0 comments on commit b23e436

Please sign in to comment.