Skip to content

Commit

Permalink
Fix #2543: Skip delegating creator arguments when collecting properties
Browse files Browse the repository at this point in the history
  • Loading branch information
kirmerzlikin committed Mar 11, 2024
1 parent 6493f5f commit 05ab176
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,10 @@ private void _addCreatorParam(Map<String, POJOPropertyBuilder> props,
// ...or is a Records canonical constructor
boolean isCanonicalConstructor = recordComponentName != null;

if ((creatorMode == null || creatorMode == JsonCreator.Mode.DISABLED) && !isCanonicalConstructor) {
if ((creatorMode == null
|| creatorMode == JsonCreator.Mode.DISABLED
|| creatorMode == JsonCreator.Mode.DELEGATING)
&& !isCanonicalConstructor) {
return;
}
pn = PropertyName.construct(impl);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.fasterxml.jackson.databind.deser.creators;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.*;
import org.junit.Test;

import static com.fasterxml.jackson.annotation.JsonCreator.Mode.DELEGATING;
import static com.fasterxml.jackson.annotation.JsonCreator.Mode.PROPERTIES;
import static com.fasterxml.jackson.databind.testutil.DatabindTestUtil.a2q;
import static java.util.Objects.requireNonNull;
import static org.assertj.core.api.Assertions.assertThatNoException;

public class DelegatingCreatorImplicitNames2543Test {
static class Data {

final String part1;
final String part2;

// this creator is considered a source of settable bean properties,
// used during deserialization
@JsonCreator(mode = PROPERTIES)
public Data(@JsonProperty("part1") String part1,
@JsonProperty("part2") String part2) {
this.part1 = part1;
this.part2 = part2;
}

// no properties should be collected from this creator,
// even though it has an argument with an implicit name
@JsonCreator(mode = DELEGATING)
public static Data fromFullData(String fullData) {
String[] parts = fullData.split("\\s+", 2);
return new Data(parts[0], parts[1]);
}
}

private static class DelegatingCreatorNamedArgumentIntrospector
extends JacksonAnnotationIntrospector {
public String findImplicitPropertyName(AnnotatedMember member) {
if (member instanceof AnnotatedParameter p) {
if (p.getOwner() instanceof AnnotatedMethod m) {
if (requireNonNull(m.getAnnotation(JsonCreator.class)).mode() == DELEGATING)
return "fullData";
}
}
return super.findImplicitPropertyName(member);
}
}

private static final ObjectMapper MAPPER = new ObjectMapper()
.setAnnotationIntrospector(new DelegatingCreatorNamedArgumentIntrospector());

@Test
public void testDeserialization() {
assertThatNoException()
.isThrownBy(() -> MAPPER.readValue(a2q("{'part1':'a','part2':'b'}"), Data.class));
}

@Test
public void testDelegatingDeserialization() {
assertThatNoException()
.isThrownBy(() -> MAPPER.readValue(a2q("'a b'"), Data.class));
}
}

0 comments on commit 05ab176

Please sign in to comment.