1 package com.fasterxml.jackson.databind.introspect; 2 3 import java.util.Iterator; 4 5 import com.fasterxml.jackson.annotation.JsonInclude; 6 7 import com.fasterxml.jackson.databind.*; 8 import com.fasterxml.jackson.databind.util.ClassUtil; 9 import com.fasterxml.jackson.databind.util.Named; 10 11 /** 12 * Simple value classes that contain definitions of properties, 13 * used during introspection of properties to use for 14 * serialization and deserialization purposes. 15 * These instances are created before actual {@link BeanProperty} 16 * instances are created, i.e. they are used earlier in the process 17 * flow, and are typically use to construct actual 18 * {@link BeanProperty} instances. 19 */ 20 public abstract class BeanPropertyDefinition 21 implements Named 22 { 23 protected final static JsonInclude.Value EMPTY_INCLUDE = JsonInclude.Value.empty(); 24 25 /* 26 /********************************************************** 27 /* Fluent factory methods for creating modified copies 28 /********************************************************** 29 */ 30 31 /** 32 * Method that can be used to create a definition with 33 * same settings as this one, but with different 34 * (external) name; that is, one for which 35 * {@link #getName()} would return <code>newName</code>. 36 * 37 * @since 2.3 38 */ withName(PropertyName newName)39 public abstract BeanPropertyDefinition withName(PropertyName newName); 40 41 /** 42 * Alternate "mutant factory" that will only change simple name, but 43 * leave other optional parts (like namespace) as is. 44 * 45 * @since 2.3 46 */ withSimpleName(String newSimpleName)47 public abstract BeanPropertyDefinition withSimpleName(String newSimpleName); 48 49 /* 50 /********************************************************** 51 /* Property name information 52 /********************************************************** 53 */ 54 55 /** 56 * Accessor for name used for external representation (in JSON). 57 */ 58 @Override // from Named getName()59 public abstract String getName(); 60 getFullName()61 public abstract PropertyName getFullName(); 62 63 /** 64 * @since 2.6 65 */ hasName(PropertyName name)66 public boolean hasName(PropertyName name) { 67 return getFullName().equals(name); 68 } 69 70 /** 71 * Accessor that can be used to determine implicit name from underlying 72 * element(s) before possible renaming. This is the "internal" 73 * name derived from accessor ("x" from "getX"), and is not based on 74 * annotations or naming strategy. 75 */ getInternalName()76 public abstract String getInternalName(); 77 78 /** 79 * Accessor for finding wrapper name to use for property (if any). 80 * 81 * @since 2.2 82 */ getWrapperName()83 public abstract PropertyName getWrapperName(); 84 85 /** 86 * Accessor that can be called to check whether property was included 87 * due to an explicit marker (usually annotation), or just by naming 88 * convention. 89 * 90 * @return True if property was explicitly included (usually by having 91 * one of components being annotated); false if inclusion was purely 92 * due to naming or visibility definitions (that is, implicit) 93 */ isExplicitlyIncluded()94 public abstract boolean isExplicitlyIncluded(); 95 96 /** 97 * Accessor that can be called to check whether property name was 98 * due to an explicit marker (usually annotation), or just by naming 99 * convention or use of "use-default-name" marker (annotation). 100 *<p> 101 * Note that entries that return true from this method will always 102 * return true for {@link #isExplicitlyIncluded()}, but not necessarily 103 * vice versa. 104 * 105 * @since 2.4 106 */ isExplicitlyNamed()107 public boolean isExplicitlyNamed() { 108 return isExplicitlyIncluded(); 109 } 110 111 /* 112 /********************************************************** 113 /* Basic property metadata 114 /********************************************************** 115 */ 116 117 /** 118 * @since 2.9 119 */ getPrimaryType()120 public abstract JavaType getPrimaryType(); 121 122 /** 123 * @since 2.9 124 */ getRawPrimaryType()125 public abstract Class<?> getRawPrimaryType(); 126 127 /** 128 * Method for accessing additional metadata. 129 * NOTE: will never return null, so de-referencing return value 130 * is safe. 131 * 132 * @since 2.3 133 */ getMetadata()134 public abstract PropertyMetadata getMetadata(); 135 136 /** 137 * Method used to check if this property is expected to have a value; 138 * and if none found, should either be considered invalid (and most likely 139 * fail deserialization), or handled by other means (by providing default 140 * value) 141 */ isRequired()142 public boolean isRequired() { 143 return getMetadata().isRequired(); 144 } 145 146 /* 147 /********************************************************** 148 /* Capabilities 149 /********************************************************** 150 */ 151 couldDeserialize()152 public boolean couldDeserialize() { return getMutator() != null; } couldSerialize()153 public boolean couldSerialize() { return getAccessor() != null; } 154 155 /* 156 /********************************************************** 157 /* Access to accessors (fields, methods etc) 158 /********************************************************** 159 */ 160 hasGetter()161 public abstract boolean hasGetter(); hasSetter()162 public abstract boolean hasSetter(); hasField()163 public abstract boolean hasField(); hasConstructorParameter()164 public abstract boolean hasConstructorParameter(); 165 getGetter()166 public abstract AnnotatedMethod getGetter(); getSetter()167 public abstract AnnotatedMethod getSetter(); getField()168 public abstract AnnotatedField getField(); getConstructorParameter()169 public abstract AnnotatedParameter getConstructorParameter(); 170 171 /** 172 * Additional method that may be called instead of {@link #getConstructorParameter()} 173 * to get access to all constructor parameters, not just the highest priority one. 174 * 175 * @since 2.5 176 */ getConstructorParameters()177 public Iterator<AnnotatedParameter> getConstructorParameters() { 178 return ClassUtil.emptyIterator(); 179 } 180 181 /** 182 * Method used to find accessor (getter, field to access) to use for accessing 183 * value of the property. 184 * Null if no such member exists. 185 */ getAccessor()186 public AnnotatedMember getAccessor() 187 { 188 AnnotatedMember m = getGetter(); 189 if (m == null) { 190 m = getField(); 191 } 192 return m; 193 } 194 195 /** 196 * Method used to find mutator (constructor parameter, setter, field) to use for 197 * changing value of the property. 198 * Null if no such member exists. 199 */ getMutator()200 public AnnotatedMember getMutator() { 201 AnnotatedMember acc = getConstructorParameter(); 202 if (acc == null) { 203 acc = getSetter(); 204 if (acc == null) { 205 acc = getField(); 206 } 207 } 208 return acc; 209 } 210 211 /** 212 * @since 2.3 213 */ getNonConstructorMutator()214 public AnnotatedMember getNonConstructorMutator() { 215 AnnotatedMember m = getSetter(); 216 if (m == null) { 217 m = getField(); 218 } 219 return m; 220 } 221 222 /** 223 * Method used to find the property member (getter, setter, field) that has 224 * the highest precedence in current context (getter method when serializing, 225 * if available, and so forth), if any. 226 *<p> 227 * Note: may throw {@link IllegalArgumentException} in case problems are found 228 * trying to getter or setter info. 229 *<p> 230 * Note: abstract since 2.5 231 * 232 * @since 2.1 233 */ getPrimaryMember()234 public abstract AnnotatedMember getPrimaryMember(); 235 236 /* 237 /********************************************************** 238 /* More refined access to configuration features 239 /* (usually based on annotations and/or config overrides) 240 /* Since most trivial implementations do not support 241 /* these methods, they are implemented as no-ops. 242 /********************************************************** 243 */ 244 245 /** 246 * Method used to find View-inclusion definitions for the property. 247 */ findViews()248 public Class<?>[] findViews() { return null; } 249 250 /** 251 * Method used to find whether property is part of a bi-directional 252 * reference. 253 */ findReferenceType()254 public AnnotationIntrospector.ReferenceProperty findReferenceType() { return null; } 255 256 /** 257 * @since 2.9 258 */ findReferenceName()259 public String findReferenceName() { 260 AnnotationIntrospector.ReferenceProperty ref = findReferenceType(); 261 return (ref == null) ? null : ref.getName(); 262 } 263 264 /** 265 * Method used to check whether this logical property has a marker 266 * to indicate it should be used as the type id for polymorphic type 267 * handling. 268 */ isTypeId()269 public boolean isTypeId() { return false; } 270 271 /** 272 * Method used to check whether this logical property indicates that 273 * value POJOs should be written using additional Object Identifier 274 * (or, when multiple references exist, all but first AS Object Identifier). 275 */ findObjectIdInfo()276 public ObjectIdInfo findObjectIdInfo() { return null; } 277 278 /** 279 * Method used to check if this property has specific inclusion override 280 * associated with it or not. 281 * It should NOT check for any default settings (global, per-type, or 282 * containing POJO settings) 283 * 284 * @since 2.5 285 */ findInclusion()286 public abstract JsonInclude.Value findInclusion(); 287 } 288