package com.fasterxml.jackson.databind.introspect; import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.*; /** * Unit tests verifying handling of potential and actual * conflicts, regarding property handling. */ public class TestPropertyConflicts extends BaseMapTest { // error message for conflicting getters sub-optimal static class BeanWithConflict { public int getX() { return 3; } public boolean getx() { return false; } } // [databind#238] protected static class Getters1A { @JsonProperty protected int value = 3; public int getValue() { return value+1; } public boolean isValue() { return false; } } // variant where order of declarations is reversed; to try to // ensure declaration order won't break things protected static class Getters1B { public boolean isValue() { return false; } @JsonProperty protected int value = 3; public int getValue() { return value+1; } } protected static class InferingIntrospector extends JacksonAnnotationIntrospector { private static final long serialVersionUID = 1L; @Override public String findImplicitPropertyName(AnnotatedMember member) { String name = member.getName(); if (name.startsWith("_")) { return name.substring(1); } return null; } } static class Infernal { public String _name() { return "foo"; } public String getName() { return "Bob"; } public void setStuff(String value) { ; // ok } public void _stuff(String value) { throw new UnsupportedOperationException(); } } // For [databind#541] static class Bean541 { protected String str; @JsonCreator public Bean541(@JsonProperty("str") String str) { this.str = str; } @JsonProperty("s") public String getStr() { return str; } } /* /********************************************************** /* Test methods /********************************************************** */ public void testFailWithDupProps() throws Exception { BeanWithConflict bean = new BeanWithConflict(); try { String json = objectWriter().writeValueAsString(bean); fail("Should have failed due to conflicting accessor definitions; got JSON = "+json); } catch (JsonProcessingException e) { verifyException(e, "Conflicting getter definitions"); } } // [databind#238]: ok to have getter, "isGetter" public void testRegularAndIsGetter() throws Exception { final ObjectWriter writer = objectWriter(); // first, serialize without probs: assertEquals("{\"value\":4}", writer.writeValueAsString(new Getters1A())); assertEquals("{\"value\":4}", writer.writeValueAsString(new Getters1B())); // and similarly, deserialize ObjectMapper mapper = objectMapper(); assertEquals(1, mapper.readValue("{\"value\":1}", Getters1A.class).value); assertEquals(2, mapper.readValue("{\"value\":2}", Getters1B.class).value); } public void testInferredNameConflictsWithGetters() throws Exception { ObjectMapper mapper = jsonMapperBuilder() .annotationIntrospector(new InferingIntrospector()) .build(); String json = mapper.writeValueAsString(new Infernal()); assertEquals(aposToQuotes("{'name':'Bob'}"), json); } public void testInferredNameConflictsWithSetters() throws Exception { ObjectMapper mapper = new ObjectMapper(); mapper.setAnnotationIntrospector(new InferingIntrospector()); Infernal inf = mapper.readValue(aposToQuotes("{'stuff':'Bob'}"), Infernal.class); assertNotNull(inf); } public void testIssue541() throws Exception { ObjectMapper mapper = jsonMapperBuilder() .disable( MapperFeature.AUTO_DETECT_CREATORS, MapperFeature.AUTO_DETECT_FIELDS, MapperFeature.AUTO_DETECT_GETTERS, MapperFeature.AUTO_DETECT_IS_GETTERS, MapperFeature.AUTO_DETECT_SETTERS, MapperFeature.USE_GETTERS_AS_SETTERS ).build(); Bean541 data = mapper.readValue("{\"str\":\"the string\"}", Bean541.class); if (data == null) { throw new IllegalStateException("data is null"); } if (!"the string".equals(data.getStr())) { throw new IllegalStateException("bad value for data.str"); } } }