package com.fasterxml.jackson.databind.introspect;
import java.util.*;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.BaseMapTest;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.*;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
/**
* Unit tests to verify functioning of {@link PropertyNamingStrategy}.
*/
@SuppressWarnings("serial")
public class TestNamingStrategyCustom extends BaseMapTest
{
/*
/**********************************************************************
/* Helper classes
/**********************************************************************
*/
static class PrefixStrategy extends PropertyNamingStrategy
{
@Override
public String nameForField(MapperConfig<?> config,
AnnotatedField field, String defaultName)
{
return "Field-"+defaultName;
}
@Override
public String nameForGetterMethod(MapperConfig<?> config,
AnnotatedMethod method, String defaultName)
{
return "Get-"+defaultName;
}
@Override
public String nameForSetterMethod(MapperConfig<?> config,
AnnotatedMethod method, String defaultName)
{
return "Set-"+defaultName;
}
}
static class CStyleStrategy extends PropertyNamingStrategy
{
@Override
public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName)
{
return convert(defaultName);
}
@Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
{
return convert(defaultName);
}
@Override
public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
{
return convert(defaultName);
}
private String convert(String input)
{
// easy: replace capital letters with underscore, lower-cases equivalent
StringBuilder result = new StringBuilder();
for (int i = 0, len = input.length(); i < len; ++i) {
char c = input.charAt(i);
if (Character.isUpperCase(c)) {
result.append('_');
c = Character.toLowerCase(c);
}
result.append(c);
}
return result.toString();
}
}
static class GetterBean {
public int getKey() { return 123; }
}
static class SetterBean {
protected int value;
public void setKey(int v) {
value = v;
}
}
static class FieldBean {
public int key;
public FieldBean() { this(0); }
public FieldBean(int v) { key = v; }
}
@JsonPropertyOrder({"first_name", "last_name"})
static class PersonBean {
public String firstName;
public String lastName;
public int age;
public PersonBean() { this(null, null, 0); }
public PersonBean(String f, String l, int a)
{
firstName = f;
lastName = l;
age = a;
}
}
static class Value {
public int intValue;
public Value() { this(0); }
public Value(int v) { intValue = v; }
}
static class SetterlessWithValue
{
protected ArrayList<Value> values = new ArrayList<Value>();
public List<Value> getValueList() { return values; }
public SetterlessWithValue add(int v) {
values.add(new Value(v));
return this;
}
}
static class LcStrategy extends PropertyNamingStrategy.PropertyNamingStrategyBase
{
@Override
public String translate(String propertyName) {
return propertyName.toLowerCase();
}
}
static class RenamedCollectionBean
{
// @JsonDeserialize
@JsonProperty
private List<String> theValues = Collections.emptyList();
// intentionally odd name, to be renamed by naming strategy
public List<String> getTheValues() { return theValues; }
}
// [Issue#45]: Support @JsonNaming
@JsonNaming(PrefixStrategy.class)
static class BeanWithPrefixNames
{
protected int a = 3;
public int getA() { return a; }
public void setA(int value) { a = value; }
}
/*
/**********************************************************************
/* Test methods
/**********************************************************************
*/
public void testSimpleGetters() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new PrefixStrategy());
assertEquals("{\"Get-key\":123}", mapper.writeValueAsString(new GetterBean()));
}
public void testSimpleSetters() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new PrefixStrategy());
SetterBean bean = mapper.readValue("{\"Set-key\":13}", SetterBean.class);
assertEquals(13, bean.value);
}
public void testSimpleFields() throws Exception
{
// First serialize
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new PrefixStrategy());
String json = mapper.writeValueAsString(new FieldBean(999));
assertEquals("{\"Field-key\":999}", json);
// then deserialize
FieldBean result = mapper.readValue(json, FieldBean.class);
assertEquals(999, result.key);
}
public void testCStyleNaming() throws Exception
{
// First serialize
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new CStyleStrategy());
String json = mapper.writeValueAsString(new PersonBean("Joe", "Sixpack", 42));
assertEquals("{\"first_name\":\"Joe\",\"last_name\":\"Sixpack\",\"age\":42}", json);
// then deserialize
PersonBean result = mapper.readValue(json, PersonBean.class);
assertEquals("Joe", result.firstName);
assertEquals("Sixpack", result.lastName);
assertEquals(42, result.age);
}
public void testWithGetterAsSetter() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new CStyleStrategy());
SetterlessWithValue input = new SetterlessWithValue().add(3);
String json = mapper.writeValueAsString(input);
assertEquals("{\"value_list\":[{\"int_value\":3}]}", json);
SetterlessWithValue result = mapper.readValue(json, SetterlessWithValue.class);
assertNotNull(result.values);
assertEquals(1, result.values.size());
assertEquals(3, result.values.get(0).intValue);
}
public void testLowerCase() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new LcStrategy());
// mapper.disable(DeserializationConfig.DeserializationFeature.USE_GETTERS_AS_SETTERS);
RenamedCollectionBean result = mapper.readValue("{\"thevalues\":[\"a\"]}",
RenamedCollectionBean.class);
assertNotNull(result.getTheValues());
assertEquals(1, result.getTheValues().size());
assertEquals("a", result.getTheValues().get(0));
}
// @JsonNaming / [databind#45]
public void testPerClassAnnotation() throws Exception
{
final ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new LcStrategy());
BeanWithPrefixNames input = new BeanWithPrefixNames();
String json = mapper.writeValueAsString(input);
assertEquals("{\"Get-a\":3}", json);
BeanWithPrefixNames output = mapper.readValue("{\"Set-a\":7}",
BeanWithPrefixNames.class);
assertEquals(7, output.a);
}
}