1 package com.fasterxml.jackson.databind.introspect; 2 3 import java.util.Collections; 4 import java.util.Map; 5 6 import com.fasterxml.jackson.annotation.JsonProperty; 7 import com.fasterxml.jackson.databind.*; 8 import com.fasterxml.jackson.databind.cfg.MapperConfig; 9 import com.fasterxml.jackson.databind.introspect.AnnotatedField; 10 import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; 11 import com.fasterxml.jackson.databind.util.BeanUtil; 12 13 // [databind#2527] Support Kotlin-style "is" properties 14 public class IsGetterRenaming2527Test extends BaseMapTest 15 { 16 static class POJO2527 { 17 private boolean isEnabled; 18 POJO2527()19 protected POJO2527() { } POJO2527(boolean b)20 public POJO2527(boolean b) { 21 isEnabled = b; 22 } 23 getEnabled()24 public boolean getEnabled() { return isEnabled; } setEnabled(boolean b)25 public void setEnabled(boolean b) { isEnabled = b; } 26 } 27 28 static class POJO2527PublicField { 29 public boolean isEnabled; 30 POJO2527PublicField()31 protected POJO2527PublicField() { } POJO2527PublicField(boolean b)32 public POJO2527PublicField(boolean b) { 33 isEnabled = b; 34 } 35 getEnabled()36 public boolean getEnabled() { return isEnabled; } setEnabled(boolean b)37 public void setEnabled(boolean b) { isEnabled = b; } 38 } 39 40 static class POJO2527Creator { 41 private final boolean isEnabled; 42 POJO2527Creator(@sonProperty"enabled") boolean b)43 public POJO2527Creator(@JsonProperty("enabled") boolean b) { 44 isEnabled = b; 45 } 46 getEnabled()47 public boolean getEnabled() { return isEnabled; } 48 } 49 50 @SuppressWarnings("serial") 51 static class MyIntrospector extends JacksonAnnotationIntrospector 52 { 53 @Override findRenameByField(MapperConfig<?> config, AnnotatedField f, PropertyName implName)54 public PropertyName findRenameByField(MapperConfig<?> config, 55 AnnotatedField f, PropertyName implName) 56 { 57 final String origSimple = implName.getSimpleName(); 58 if (origSimple.startsWith("is")) { 59 String mangledName = BeanUtil.stdManglePropertyName(origSimple, 2); 60 // Needs to be valid ("is" -> null), and different from original 61 if ((mangledName != null) && !mangledName.equals(origSimple)) { 62 return PropertyName.construct(mangledName); 63 } 64 } 65 return null; 66 } 67 } 68 69 private final ObjectMapper MAPPER = jsonMapperBuilder() 70 .annotationIntrospector(new MyIntrospector()) 71 .build(); 72 testIsPropertiesStdKotlin()73 public void testIsPropertiesStdKotlin() throws Exception 74 { 75 POJO2527 input = new POJO2527(true); 76 final String json = MAPPER.writeValueAsString(input); 77 78 Map<?, ?> props = MAPPER.readValue(json, Map.class); 79 assertEquals(Collections.singletonMap("isEnabled", Boolean.TRUE), 80 props); 81 82 POJO2527 output = MAPPER.readValue(json, POJO2527.class); 83 assertEquals(input.isEnabled, output.isEnabled); 84 } 85 testIsPropertiesWithPublicField()86 public void testIsPropertiesWithPublicField() throws Exception 87 { 88 POJO2527PublicField input = new POJO2527PublicField(true); 89 final String json = MAPPER.writeValueAsString(input); 90 91 Map<?, ?> props = MAPPER.readValue(json, Map.class); 92 assertEquals(Collections.singletonMap("isEnabled", Boolean.TRUE), 93 props); 94 95 POJO2527PublicField output = MAPPER.readValue(json, POJO2527PublicField.class); 96 assertEquals(input.isEnabled, output.isEnabled); 97 } 98 testIsPropertiesViaCreator()99 public void testIsPropertiesViaCreator() throws Exception 100 { 101 POJO2527Creator input = new POJO2527Creator(true); 102 final String json = MAPPER.writeValueAsString(input); 103 104 Map<?, ?> props = MAPPER.readValue(json, Map.class); 105 assertEquals(Collections.singletonMap("isEnabled", Boolean.TRUE), 106 props); 107 108 POJO2527Creator output = MAPPER.readValue(json, POJO2527Creator.class); 109 assertEquals(input.isEnabled, output.isEnabled); 110 } 111 } 112