1 package com.fasterxml.jackson.databind.introspect; 2 3 import java.util.Objects; 4 5 import com.fasterxml.jackson.annotation.*; 6 import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; 7 8 import com.fasterxml.jackson.core.*; 9 10 import com.fasterxml.jackson.databind.*; 11 import com.fasterxml.jackson.databind.introspect.VisibilityChecker; 12 13 public class TestAutoDetect 14 extends BaseMapTest 15 { 16 static class PrivateBean { 17 String a; 18 PrivateBean()19 private PrivateBean() { } 20 PrivateBean(String a)21 private PrivateBean(String a) { this.a = a; } 22 } 23 24 // test for [databind#1347], config overrides for visibility 25 @JsonPropertyOrder(alphabetic=true) 26 static class Feature1347SerBean { 27 public int field = 2; 28 getValue()29 public int getValue() { return 3; } 30 } 31 32 // let's promote use of fields; but not block setters yet 33 @JsonAutoDetect(fieldVisibility=Visibility.NON_PRIVATE) 34 static class Feature1347DeserBean { 35 int value; 36 setValue(int x)37 public void setValue(int x) { 38 throw new IllegalArgumentException("Should NOT get called"); 39 } 40 } 41 42 // [databind#1947] 43 static class Entity1947 { 44 public int shouldBeDetected; 45 public String shouldNotBeDetected; 46 47 @JsonProperty getShouldBeDetected()48 public int getShouldBeDetected() { 49 return shouldBeDetected; 50 } 51 setShouldBeDetected(int shouldBeDetected)52 public void setShouldBeDetected(int shouldBeDetected) { 53 this.shouldBeDetected = shouldBeDetected; 54 } 55 getShouldNotBeDetected()56 public String getShouldNotBeDetected() { 57 return shouldNotBeDetected; 58 } 59 setShouldNotBeDetected(String shouldNotBeDetected)60 public void setShouldNotBeDetected(String shouldNotBeDetected) { 61 this.shouldNotBeDetected = shouldNotBeDetected; 62 } 63 } 64 65 // For [databind#2789] 66 67 @SuppressWarnings("unused") 68 @JsonAutoDetect( 69 getterVisibility = JsonAutoDetect.Visibility.NONE, 70 creatorVisibility = JsonAutoDetect.Visibility.NONE, 71 isGetterVisibility = JsonAutoDetect.Visibility.NONE, 72 fieldVisibility = JsonAutoDetect.Visibility.NONE, 73 setterVisibility = JsonAutoDetect.Visibility.NONE) 74 @JsonTypeInfo( 75 use = JsonTypeInfo.Id.NAME, 76 include = JsonTypeInfo.As.PROPERTY, 77 property = "type", 78 visible = true) 79 @JsonSubTypes({ 80 @JsonSubTypes.Type(name = "CLASS_A", value = DataClassA.class) 81 }) 82 private static abstract class DataParent2789 { 83 84 @JsonProperty("type") 85 @JsonTypeId 86 private final DataType2789 type; 87 DataParent2789()88 DataParent2789() { 89 super(); 90 this.type = null; 91 } 92 DataParent2789(final DataType2789 type)93 DataParent2789(final DataType2789 type) { 94 super(); 95 this.type = Objects.requireNonNull(type); 96 } 97 getType()98 public DataType2789 getType() { 99 return this.type; 100 } 101 } 102 103 private static final class DataClassA extends DataParent2789 { DataClassA()104 DataClassA() { 105 super(DataType2789.CLASS_A); 106 } 107 } 108 109 private enum DataType2789 { 110 CLASS_A; 111 } 112 113 /* 114 /******************************************************** 115 /* Unit tests 116 /******************************************************** 117 */ 118 119 private final ObjectMapper MAPPER = newJsonMapper(); 120 testPrivateCtor()121 public void testPrivateCtor() throws Exception 122 { 123 // first, default settings, with which construction works ok 124 ObjectMapper m = new ObjectMapper(); 125 PrivateBean bean = m.readValue("\"abc\"", PrivateBean.class); 126 assertEquals("abc", bean.a); 127 128 // then by increasing visibility requirement: 129 m = new ObjectMapper(); 130 VisibilityChecker<?> vc = m.getVisibilityChecker(); 131 vc = vc.withCreatorVisibility(JsonAutoDetect.Visibility.PUBLIC_ONLY); 132 m.setVisibility(vc); 133 try { 134 m.readValue("\"abc\"", PrivateBean.class); 135 fail("Expected exception for missing constructor"); 136 } catch (JsonProcessingException e) { 137 verifyException(e, "no String-argument constructor/factory"); 138 } 139 } 140 141 // [databind#1347] testVisibilityConfigOverridesForSer()142 public void testVisibilityConfigOverridesForSer() throws Exception 143 { 144 // first, by default, both field/method should be visible 145 final Feature1347SerBean input = new Feature1347SerBean(); 146 assertEquals(aposToQuotes("{'field':2,'value':3}"), 147 MAPPER.writeValueAsString(input)); 148 149 ObjectMapper mapper = new ObjectMapper(); 150 mapper.configOverride(Feature1347SerBean.class) 151 .setVisibility(JsonAutoDetect.Value.construct(PropertyAccessor.GETTER, 152 Visibility.NONE)); 153 assertEquals(aposToQuotes("{'field':2}"), 154 mapper.writeValueAsString(input)); 155 } 156 157 // [databind#1347] testVisibilityConfigOverridesForDeser()158 public void testVisibilityConfigOverridesForDeser() throws Exception 159 { 160 final String JSON = aposToQuotes("{'value':3}"); 161 162 // by default, should throw exception 163 try { 164 /*Feature1347DeserBean bean =*/ 165 MAPPER.readValue(JSON, Feature1347DeserBean.class); 166 fail("Should not pass"); 167 } catch (JsonMappingException e) { 168 verifyException(e, "Should NOT get called"); 169 } 170 171 // but when instructed to ignore setter, should work 172 ObjectMapper mapper = new ObjectMapper(); 173 mapper.configOverride(Feature1347DeserBean.class) 174 .setVisibility(JsonAutoDetect.Value.construct(PropertyAccessor.SETTER, 175 Visibility.NONE)); 176 Feature1347DeserBean result = mapper.readValue(JSON, Feature1347DeserBean.class); 177 assertEquals(3, result.value); 178 } 179 180 // [databind#1947] testDisablingAll()181 public void testDisablingAll() throws Exception 182 { 183 ObjectMapper mapper = jsonMapperBuilder() 184 .disable(MapperFeature.AUTO_DETECT_SETTERS) 185 .disable(MapperFeature.AUTO_DETECT_FIELDS) 186 .disable(MapperFeature.AUTO_DETECT_GETTERS) 187 .disable(MapperFeature.AUTO_DETECT_CREATORS) 188 .disable(MapperFeature.AUTO_DETECT_IS_GETTERS) 189 .build(); 190 String json = mapper.writeValueAsString(new Entity1947()); 191 JsonNode n = mapper.readTree(json); 192 assertEquals(1, n.size()); 193 assertTrue(n.has("shouldBeDetected")); 194 assertFalse(n.has("shouldNotBeDetected")); 195 } 196 197 // [databind#2789] testAnnotatedFieldIssue2789()198 public void testAnnotatedFieldIssue2789() throws Exception { 199 final String json = MAPPER.writeValueAsString(new DataClassA()); 200 final DataParent2789 copy = MAPPER.readValue(json, DataParent2789.class); 201 assertEquals(DataType2789.CLASS_A, copy.getType()); 202 } 203 } 204