Skip to content

Commit

Permalink
Merge branch '2.18'
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Mar 12, 2024
2 parents a92c4f2 + 4dd5a79 commit 2e923da
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 1 deletion.
5 changes: 5 additions & 0 deletions release-notes/CREDITS-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -1756,3 +1756,8 @@ Jesper Blomquist (jebl01@github)
András Péteri (apeteri@github)
* Suggested #4416: Deprecate `JsonNode.asText(String)`
(2.17.0)
Kyrylo Merzlikin (kirmerzlikin@github)
* Contributed fix for #2543: Introspection includes delegating ctor's
only parameter as a property in `BeanDescription`
(2.17.0)
4 changes: 4 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ No changes since 2.17
#736: `MapperFeature.REQUIRE_SETTERS_FOR_GETTERS` has no effect
(reported by @migel)
(fix contributed by Joo-Hyuk K)
#2543: Introspection includes delegating ctor's only parameter as
a property in `BeanDescription`
(reported by @nikita2206)
(fix contributed by Kyrylo M)
#4160: Deprecate `DefaultTyping.EVERYTHING` in `2.x` and remove in `3.0`
(contributed by Joo-Hyuk K)
#4194: Add `JsonNodeFeature.FAIL_ON_NAN_TO_BIG_DECIMAL_COERCION` option to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,11 @@ 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
// 12-Mar-2024: [databind#2543] need to skip delegating as well
|| 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,84 @@
package tools.jackson.databind.deser.creators;

import java.util.Objects;

import org.junit.Test;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.cfg.MapperConfig;
import tools.jackson.databind.introspect.*;
import tools.jackson.databind.json.JsonMapper;
import tools.jackson.databind.testutil.DatabindTestUtil;

import static org.assertj.core.api.Assertions.assertThat;

import static com.fasterxml.jackson.annotation.JsonCreator.Mode.DELEGATING;
import static com.fasterxml.jackson.annotation.JsonCreator.Mode.PROPERTIES;

public class DelegatingCreatorImplicitNames2543Test
extends DatabindTestUtil
{
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]);
}
}

static class DelegatingCreatorNamedArgumentIntrospector
extends JacksonAnnotationIntrospector {
private static final long serialVersionUID = 1L;

@Override
public String findImplicitPropertyName(MapperConfig<?> config, AnnotatedMember member) {
if (member instanceof AnnotatedParameter) {
AnnotatedWithParams owner = ((AnnotatedParameter) member).getOwner();
if (owner instanceof AnnotatedMethod) {
AnnotatedMethod method = (AnnotatedMethod) owner;
if (Objects.requireNonNull(method.getAnnotation(JsonCreator.class)).mode() == DELEGATING)
return "fullData";
}
}
return super.findImplicitPropertyName(config, member);
}
}

private static final ObjectMapper MAPPER = JsonMapper.builder()
.annotationIntrospector(new DelegatingCreatorNamedArgumentIntrospector())
.build();

@Test
public void testDeserialization() throws Exception {
Data data = MAPPER.readValue(a2q("{'part1':'a','part2':'b'}"), Data.class);

assertThat(data.part1).isEqualTo("a");
assertThat(data.part2).isEqualTo("b");
}

@Test
public void testDelegatingDeserialization() throws Exception {
Data data = MAPPER.readValue(a2q("'a b'"), Data.class);

assertThat(data.part1).isEqualTo("a");
assertThat(data.part2).isEqualTo("b");
}
}

0 comments on commit 2e923da

Please sign in to comment.