1 package com.fasterxml.jackson.databind.util; 2 3 import java.util.Collections; 4 import java.util.Iterator; 5 6 import com.fasterxml.jackson.annotation.JsonInclude; 7 8 import com.fasterxml.jackson.databind.*; 9 import com.fasterxml.jackson.databind.cfg.MapperConfig; 10 import com.fasterxml.jackson.databind.introspect.*; 11 import com.fasterxml.jackson.databind.type.TypeFactory; 12 13 /** 14 * Simple immutable {@link BeanPropertyDefinition} implementation that can 15 * be wrapped around a {@link AnnotatedMember} that is a simple 16 * accessor (getter) or mutator (setter, constructor parameter) 17 * (or both, for fields). 18 */ 19 public class SimpleBeanPropertyDefinition 20 extends BeanPropertyDefinition 21 { 22 protected final AnnotationIntrospector _annotationIntrospector; 23 24 /** 25 * Member that defines logical property. Assumption is that it 26 * should be a 'simple' accessor; meaning a zero-argument getter, 27 * single-argument setter or constructor parameter. 28 *<p> 29 * NOTE: for "virtual" properties, this is null. 30 */ 31 protected final AnnotatedMember _member; 32 33 /** 34 * @since 2.5 35 */ 36 protected final PropertyMetadata _metadata; 37 38 /** 39 * @since 2.5 40 */ 41 protected final PropertyName _fullName; 42 43 /** 44 * @since 2.5 45 */ 46 protected final JsonInclude.Value _inclusion; 47 48 /* 49 /********************************************************** 50 /* Construction 51 /********************************************************** 52 */ 53 54 /** 55 * @since 2.9 56 */ SimpleBeanPropertyDefinition(AnnotationIntrospector intr, AnnotatedMember member, PropertyName fullName, PropertyMetadata metadata, JsonInclude.Value inclusion)57 protected SimpleBeanPropertyDefinition(AnnotationIntrospector intr, 58 AnnotatedMember member, PropertyName fullName, PropertyMetadata metadata, 59 JsonInclude.Value inclusion) 60 { 61 _annotationIntrospector = intr; 62 _member = member; 63 _fullName = fullName; 64 _metadata = (metadata == null) ? PropertyMetadata.STD_OPTIONAL: metadata; 65 _inclusion = inclusion; 66 } 67 68 /** 69 * @since 2.2 70 */ construct(MapperConfig<?> config, AnnotatedMember member)71 public static SimpleBeanPropertyDefinition construct(MapperConfig<?> config, 72 AnnotatedMember member) 73 { 74 return new SimpleBeanPropertyDefinition(config.getAnnotationIntrospector(), 75 member, PropertyName.construct(member.getName()), null, EMPTY_INCLUDE); 76 } 77 78 /** 79 * @since 2.5 80 */ construct(MapperConfig<?> config, AnnotatedMember member, PropertyName name)81 public static SimpleBeanPropertyDefinition construct(MapperConfig<?> config, 82 AnnotatedMember member, PropertyName name) { 83 return construct(config, member, name, null, EMPTY_INCLUDE); 84 } 85 86 /** 87 * Method called to create instance for virtual properties. 88 * 89 * @since 2.5 90 */ construct(MapperConfig<?> config, AnnotatedMember member, PropertyName name, PropertyMetadata metadata, JsonInclude.Include inclusion)91 public static SimpleBeanPropertyDefinition construct(MapperConfig<?> config, 92 AnnotatedMember member, PropertyName name, PropertyMetadata metadata, 93 JsonInclude.Include inclusion) 94 { 95 JsonInclude.Value inclValue 96 = ((inclusion == null) || (inclusion == JsonInclude.Include.USE_DEFAULTS)) 97 ? EMPTY_INCLUDE : JsonInclude.Value.construct(inclusion, null); 98 return new SimpleBeanPropertyDefinition(config.getAnnotationIntrospector(), 99 member, name, metadata, inclValue); 100 } 101 102 /** 103 * @since 2.7 104 */ construct(MapperConfig<?> config, AnnotatedMember member, PropertyName name, PropertyMetadata metadata, JsonInclude.Value inclusion)105 public static SimpleBeanPropertyDefinition construct(MapperConfig<?> config, 106 AnnotatedMember member, PropertyName name, PropertyMetadata metadata, 107 JsonInclude.Value inclusion) { 108 return new SimpleBeanPropertyDefinition(config.getAnnotationIntrospector(), 109 member, name, metadata, inclusion); 110 } 111 112 /* 113 /********************************************************** 114 /* Fluent factories 115 /********************************************************** 116 */ 117 118 @Override withSimpleName(String newName)119 public BeanPropertyDefinition withSimpleName(String newName) { 120 if (_fullName.hasSimpleName(newName) && !_fullName.hasNamespace()) { 121 return this; 122 } 123 return new SimpleBeanPropertyDefinition(_annotationIntrospector, 124 _member, new PropertyName(newName), _metadata, _inclusion); 125 } 126 127 @Override withName(PropertyName newName)128 public BeanPropertyDefinition withName(PropertyName newName) { 129 if (_fullName.equals(newName)) { 130 return this; 131 } 132 return new SimpleBeanPropertyDefinition(_annotationIntrospector, 133 _member, newName, _metadata, _inclusion); 134 } 135 136 /** 137 * @since 2.5 138 */ withMetadata(PropertyMetadata metadata)139 public BeanPropertyDefinition withMetadata(PropertyMetadata metadata) { 140 if (metadata.equals(_metadata)) { 141 return this; 142 } 143 return new SimpleBeanPropertyDefinition(_annotationIntrospector, 144 _member, _fullName, metadata, _inclusion); 145 } 146 147 /** 148 * @since 2.5 149 */ withInclusion(JsonInclude.Value inclusion)150 public BeanPropertyDefinition withInclusion(JsonInclude.Value inclusion) { 151 if (_inclusion == inclusion) { 152 return this; 153 } 154 return new SimpleBeanPropertyDefinition(_annotationIntrospector, 155 _member, _fullName, _metadata, inclusion); 156 } 157 158 /* 159 /********************************************************** 160 /* Basic property information, name, type 161 /********************************************************** 162 */ 163 164 @Override getName()165 public String getName() { return _fullName.getSimpleName(); } 166 167 @Override getFullName()168 public PropertyName getFullName() { return _fullName; } 169 170 @Override hasName(PropertyName name)171 public boolean hasName(PropertyName name) { 172 return _fullName.equals(name); 173 } 174 175 @Override getInternalName()176 public String getInternalName() { return getName(); } 177 178 @Override getWrapperName()179 public PropertyName getWrapperName() { 180 if ((_annotationIntrospector == null) || (_member == null)) { 181 return null; 182 } 183 return _annotationIntrospector.findWrapperName(_member); 184 } 185 186 // hmmh. what should we claim here? 187 isExplicitlyIncluded()188 @Override public boolean isExplicitlyIncluded() { return false; } isExplicitlyNamed()189 @Override public boolean isExplicitlyNamed() { return false; } 190 191 /** 192 * We will indicate that property is optional, since there is nothing 193 * to indicate whether it might be required. 194 */ 195 @Override getMetadata()196 public PropertyMetadata getMetadata() { 197 return _metadata; 198 } 199 200 @Override getPrimaryType()201 public JavaType getPrimaryType() { 202 if (_member == null) { 203 return TypeFactory.unknownType(); 204 } 205 return _member.getType(); 206 } 207 208 @Override getRawPrimaryType()209 public Class<?> getRawPrimaryType() { 210 if (_member == null) { 211 return Object.class; 212 } 213 return _member.getRawType(); 214 } 215 216 @Override findInclusion()217 public JsonInclude.Value findInclusion() { 218 return _inclusion; 219 } 220 221 /* 222 /********************************************************** 223 /* Access to accessors (fields, methods etc) 224 /********************************************************** 225 */ 226 227 @Override hasGetter()228 public boolean hasGetter() { return (getGetter() != null); } 229 230 @Override hasSetter()231 public boolean hasSetter() { return (getSetter() != null); } 232 233 @Override hasField()234 public boolean hasField() { return (_member instanceof AnnotatedField); } 235 236 @Override hasConstructorParameter()237 public boolean hasConstructorParameter() { return (_member instanceof AnnotatedParameter); } 238 239 @Override getGetter()240 public AnnotatedMethod getGetter() { 241 if ((_member instanceof AnnotatedMethod) 242 && ((AnnotatedMethod) _member).getParameterCount() == 0) { 243 return (AnnotatedMethod) _member; 244 } 245 return null; 246 } 247 248 @Override getSetter()249 public AnnotatedMethod getSetter() { 250 if ((_member instanceof AnnotatedMethod) 251 && ((AnnotatedMethod) _member).getParameterCount() == 1) { 252 return (AnnotatedMethod) _member; 253 } 254 return null; 255 } 256 257 @Override getField()258 public AnnotatedField getField() { 259 return (_member instanceof AnnotatedField) ? (AnnotatedField) _member : null; 260 } 261 262 @Override getConstructorParameter()263 public AnnotatedParameter getConstructorParameter() { 264 return (_member instanceof AnnotatedParameter) ? (AnnotatedParameter) _member : null; 265 } 266 267 @Override getConstructorParameters()268 public Iterator<AnnotatedParameter> getConstructorParameters() { 269 AnnotatedParameter param = getConstructorParameter(); 270 if (param == null) { 271 return ClassUtil.emptyIterator(); 272 } 273 return Collections.singleton(param).iterator(); 274 } 275 276 @Override getPrimaryMember()277 public AnnotatedMember getPrimaryMember() { return _member; } 278 } 279