SingleArgCreatorTest.java
package com.fasterxml.jackson.databind.deser.creators;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.AnnotatedParameter;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.fasterxml.jackson.databind.json.JsonMapper;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static com.fasterxml.jackson.databind.testutil.DatabindTestUtil.*;
public class SingleArgCreatorTest
{
// [databind#430]: single arg BUT named; should not delegate
static class SingleNamedStringBean {
final String _ss;
@JsonCreator
public SingleNamedStringBean(@JsonProperty("") String ss){
this._ss = ss;
}
public String getSs() { return _ss; }
}
// For [databind#614]
static class SingleNamedButStillDelegating {
protected final String value;
@JsonCreator(mode=JsonCreator.Mode.DELEGATING)
public SingleNamedButStillDelegating(@JsonProperty("foobar") String v) {
value = v;
}
public String getFoobar() { return "x"; }
}
// For [databind#557]
static class StringyBean
{
public final String value;
private StringyBean(String value) { this.value = value; }
public String getValue() {
return value;
}
}
static class StringyBeanWithProps
{
public final String value;
@JsonCreator
private StringyBeanWithProps(String v) { value = v; }
public String getValue() {
return value;
}
}
@SuppressWarnings("serial")
static class MyParamIntrospector extends JacksonAnnotationIntrospector
{
private final String name;
public MyParamIntrospector(String n) { name = n; }
@Override
public String findImplicitPropertyName(AnnotatedMember param) {
if (param instanceof AnnotatedParameter) {
AnnotatedParameter ap = (AnnotatedParameter) param;
switch (ap.getIndex()) {
case 0: return name;
}
return "param"+ap.getIndex();
}
return super.findImplicitPropertyName(param);
}
}
// [databind#660]
static class ExplicitFactoryBeanA {
private String value;
private ExplicitFactoryBeanA(String str) {
throw new IllegalStateException("Should not get called!");
}
private ExplicitFactoryBeanA(String str, boolean b) {
value = str;
}
@JsonCreator
public static ExplicitFactoryBeanA create(String str) {
ExplicitFactoryBeanA bean = new ExplicitFactoryBeanA(str, false);
bean.value = str;
return bean;
}
public String value() { return value; }
}
// [databind#660]
static class ExplicitFactoryBeanB {
private String value;
@JsonCreator
private ExplicitFactoryBeanB(String str) {
value = str;
}
public static ExplicitFactoryBeanB valueOf(String str) {
return new ExplicitFactoryBeanB(null);
}
public String value() { return value; }
}
static class XY {
public int x, y;
}
// [databind#1383]
static class SingleArgWithImplicit {
protected XY _value;
private SingleArgWithImplicit() {
throw new Error("Should not get called");
}
private SingleArgWithImplicit(XY v, boolean bogus) {
_value = v;
}
@JsonCreator
public static SingleArgWithImplicit from(XY v) {
return new SingleArgWithImplicit(v, true);
}
public XY getFoobar() { return _value; }
}
// [databind#3062]
static class DecVector3062 {
List<Double> elems;
public DecVector3062() { super(); }
public DecVector3062(List<Double> e) { elems = e; }
public DecVector3062(double elem) { elems = Arrays.asList(elem); }
public DecVector3062(Double elem) { elems = Arrays.asList(elem); }
public List<Double> getElems() { return elems; }
}
/*
/**********************************************************************
/* Test methods
/**********************************************************************
*/
private final ObjectMapper MAPPER = newJsonMapper();
@Test
public void testNamedSingleArg() throws Exception
{
SingleNamedStringBean bean = MAPPER.readValue(q("foobar"),
SingleNamedStringBean.class);
assertEquals("foobar", bean._ss);
}
@Test
public void testSingleStringArgWithImplicitName() throws Exception
{
final ObjectMapper mapper = JsonMapper.builder()
.annotationIntrospector(new MyParamIntrospector("value"))
.build();
// 23-May-2024, tatu: [databind#4515] Clarifies handling to make
// 1-param Constructor with implicit name auto-discoverable
// This is compatibility change so hopefully won't bite us but...
// it seems like the right thing to do.
// StringyBean bean = mapper.readValue(q("foobar"), StringyBean.class);
StringyBean bean = mapper.readValue(a2q("{'value':'foobar'}"), StringyBean.class);
assertEquals("foobar", bean.getValue());
}
// [databind#714]
@Test
public void testSingleImplicitlyNamedNotDelegating() throws Exception
{
final ObjectMapper mapper = JsonMapper.builder()
.annotationIntrospector(new MyParamIntrospector("value"))
.build();
StringyBeanWithProps bean = mapper.readValue("{\"value\":\"x\"}", StringyBeanWithProps.class);
assertEquals("x", bean.getValue());
}
// [databind#714]
@Test
public void testSingleExplicitlyNamedButDelegating() throws Exception
{
SingleNamedButStillDelegating bean = MAPPER.readValue(q("xyz"),
SingleNamedButStillDelegating.class);
assertEquals("xyz", bean.value);
}
@Test
public void testExplicitFactory660a() throws Exception
{
// First, explicit override for factory
ExplicitFactoryBeanA bean = MAPPER.readValue(q("abc"), ExplicitFactoryBeanA.class);
assertNotNull(bean);
assertEquals("abc", bean.value());
}
@Test
public void testExplicitFactory660b() throws Exception
{
// and then one for private constructor
ExplicitFactoryBeanB bean2 = MAPPER.readValue(q("def"), ExplicitFactoryBeanB.class);
assertNotNull(bean2);
assertEquals("def", bean2.value());
}
// [databind#1383]
@Test
public void testSingleImplicitDelegating() throws Exception
{
final ObjectMapper mapper = new ObjectMapper();
mapper.setAnnotationIntrospector(new MyParamIntrospector("value"));
SingleArgWithImplicit bean = mapper.readValue(a2q("{'x':1,'y':2}"),
SingleArgWithImplicit.class);
XY v = bean.getFoobar();
assertNotNull(v);
assertEquals(1, v.x);
assertEquals(2, v.y);
}
// [databind#3062]
@Test
public void testMultipleDoubleCreators3062() throws Exception
{
DecVector3062 vector = new DecVector3062(Arrays.asList(1.0, 2.0, 3.0));
String result = MAPPER.writeValueAsString(vector);
DecVector3062 deser = MAPPER.readValue(result, DecVector3062.class);
assertEquals(vector.elems, deser.elems);
}
}