1 package com.fasterxml.jackson.databind.introspect; 2 3 import java.lang.reflect.Field; 4 import java.lang.reflect.Member; 5 import java.lang.reflect.Method; 6 7 8 import com.fasterxml.jackson.annotation.JsonAutoDetect; 9 import com.fasterxml.jackson.annotation.PropertyAccessor; 10 import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; 11 12 /** 13 * Interface for object used for determine which property elements 14 * (methods, fields, constructors) can be auto-detected, with respect 15 * to their visibility modifiers. 16 *<p> 17 * Note on type declaration: funky recursive type is necessary to 18 * support builder/fluent pattern. 19 */ 20 public interface VisibilityChecker<T extends VisibilityChecker<T>> 21 { 22 // // Builder methods 23 24 /** 25 * Builder method that will return an instance that has same 26 * settings as this instance has, except for values that 27 * given annotation overrides. 28 */ with(JsonAutoDetect ann)29 public T with(JsonAutoDetect ann); 30 31 /** 32 * Method that can be used for merging default values from `this` 33 * instance with specified overrides; and either return `this` 34 * if overrides had no effect (that is, result would be equal), 35 * or a new instance with merged visibility settings. 36 * 37 * @since 2.9 38 */ withOverrides(JsonAutoDetect.Value vis)39 public T withOverrides(JsonAutoDetect.Value vis); 40 41 /** 42 * Builder method that will create and return an instance that has specified 43 * {@link Visibility} value to use for all property elements. 44 * Typical usage would be something like: 45 *<pre> 46 * mapper.setVisibilityChecker( 47 * mapper.getVisibilityChecker().with(Visibility.NONE)); 48 *</pre> 49 * (which would basically disable all auto-detection) 50 */ with(Visibility v)51 public T with(Visibility v); 52 53 /** 54 * Builder method that will create and return an instance that has specified 55 * {@link Visibility} value to use for specified property. 56 * Typical usage would be: 57 *<pre> 58 * mapper.setVisibilityChecker( 59 * mapper.getVisibilityChecker().withVisibility(JsonMethod.FIELD, Visibility.ANY)); 60 *</pre> 61 * (which would basically enable auto-detection for all member fields) 62 */ withVisibility(PropertyAccessor method, Visibility v)63 public T withVisibility(PropertyAccessor method, Visibility v); 64 65 /** 66 * Builder method that will return a checker instance that has 67 * specified minimum visibility level for regular ("getXxx") getters. 68 */ withGetterVisibility(Visibility v)69 public T withGetterVisibility(Visibility v); 70 71 /** 72 * Builder method that will return a checker instance that has 73 * specified minimum visibility level for "is-getters" ("isXxx"). 74 */ withIsGetterVisibility(Visibility v)75 public T withIsGetterVisibility(Visibility v); 76 77 /** 78 * Builder method that will return a checker instance that has 79 * specified minimum visibility level for setters. 80 */ withSetterVisibility(Visibility v)81 public T withSetterVisibility(Visibility v); 82 83 /** 84 * Builder method that will return a checker instance that has 85 * specified minimum visibility level for creator methods 86 * (constructors, factory methods) 87 */ withCreatorVisibility(Visibility v)88 public T withCreatorVisibility(Visibility v); 89 90 /** 91 * Builder method that will return a checker instance that has 92 * specified minimum visibility level for fields. 93 */ withFieldVisibility(Visibility v)94 public T withFieldVisibility(Visibility v); 95 96 // // Accessors 97 98 /** 99 * Method for checking whether given method is auto-detectable 100 * as regular getter, with respect to its visibility (not considering 101 * method signature or name, just visibility) 102 */ isGetterVisible(Method m)103 public boolean isGetterVisible(Method m); isGetterVisible(AnnotatedMethod m)104 public boolean isGetterVisible(AnnotatedMethod m); 105 106 /** 107 * Method for checking whether given method is auto-detectable 108 * as is-getter, with respect to its visibility (not considering 109 * method signature or name, just visibility) 110 */ isIsGetterVisible(Method m)111 public boolean isIsGetterVisible(Method m); isIsGetterVisible(AnnotatedMethod m)112 public boolean isIsGetterVisible(AnnotatedMethod m); 113 114 /** 115 * Method for checking whether given method is auto-detectable 116 * as setter, with respect to its visibility (not considering 117 * method signature or name, just visibility) 118 */ isSetterVisible(Method m)119 public boolean isSetterVisible(Method m); isSetterVisible(AnnotatedMethod m)120 public boolean isSetterVisible(AnnotatedMethod m); 121 122 /** 123 * Method for checking whether given method is auto-detectable 124 * as Creator, with respect to its visibility (not considering 125 * method signature or name, just visibility) 126 */ isCreatorVisible(Member m)127 public boolean isCreatorVisible(Member m); isCreatorVisible(AnnotatedMember m)128 public boolean isCreatorVisible(AnnotatedMember m); 129 130 /** 131 * Method for checking whether given field is auto-detectable 132 * as property, with respect to its visibility (not considering 133 * method signature or name, just visibility) 134 */ isFieldVisible(Field f)135 public boolean isFieldVisible(Field f); isFieldVisible(AnnotatedField f)136 public boolean isFieldVisible(AnnotatedField f); 137 138 /* 139 /******************************************************** 140 /* Standard implementation suitable for basic use 141 /******************************************************** 142 */ 143 144 /** 145 * Default standard implementation is purely based on visibility 146 * modifier of given class members, and its configured minimum 147 * levels. 148 * Implemented using "builder" (or "Fluent") pattern, whereas instances 149 * are immutable, and configuration is achieved by chainable factory 150 * methods. As a result, type is declared is funky recursive generic 151 * type, to allow for sub-classing of build methods with property type 152 * co-variance. 153 */ 154 public static class Std 155 implements VisibilityChecker<Std>, 156 java.io.Serializable 157 { 158 private static final long serialVersionUID = 1; 159 160 /** 161 * This is the canonical base instance, configured with default 162 * visibility values 163 */ 164 protected final static Std DEFAULT = new Std( 165 Visibility.PUBLIC_ONLY, // getter 166 Visibility.PUBLIC_ONLY, // is-getter 167 Visibility.ANY, // setter 168 Visibility.ANY, // creator -- legacy, to support single-arg ctors 169 Visibility.PUBLIC_ONLY // field 170 ); 171 172 protected final Visibility _getterMinLevel; 173 protected final Visibility _isGetterMinLevel; 174 protected final Visibility _setterMinLevel; 175 protected final Visibility _creatorMinLevel; 176 protected final Visibility _fieldMinLevel; 177 defaultInstance()178 public static Std defaultInstance() { return DEFAULT; } 179 180 /** 181 * Constructor used for building instance that has minumum visibility 182 * levels as indicated by given annotation instance 183 * 184 * @param ann Annotations to use for determining minimum visibility levels 185 */ Std(JsonAutoDetect ann)186 public Std(JsonAutoDetect ann) 187 { 188 // let's combine checks for enabled/disabled, with minimum level checks: 189 _getterMinLevel = ann.getterVisibility(); 190 _isGetterMinLevel = ann.isGetterVisibility(); 191 _setterMinLevel = ann.setterVisibility(); 192 _creatorMinLevel = ann.creatorVisibility(); 193 _fieldMinLevel = ann.fieldVisibility(); 194 } 195 196 /** 197 * Constructor that allows directly specifying minimum visibility levels to use 198 */ Std(Visibility getter, Visibility isGetter, Visibility setter, Visibility creator, Visibility field)199 public Std(Visibility getter, Visibility isGetter, Visibility setter, 200 Visibility creator, Visibility field) 201 { 202 _getterMinLevel = getter; 203 _isGetterMinLevel = isGetter; 204 _setterMinLevel = setter; 205 _creatorMinLevel = creator; 206 _fieldMinLevel = field; 207 } 208 209 /** 210 * Constructor that will assign given visibility value for all 211 * properties. 212 * 213 * @param v level to use for all property types 214 */ Std(Visibility v)215 public Std(Visibility v) 216 { 217 // typically we shouldn't get this value; but let's handle it if we do: 218 if (v == Visibility.DEFAULT) { 219 _getterMinLevel = DEFAULT._getterMinLevel; 220 _isGetterMinLevel = DEFAULT._isGetterMinLevel; 221 _setterMinLevel = DEFAULT._setterMinLevel; 222 _creatorMinLevel = DEFAULT._creatorMinLevel; 223 _fieldMinLevel = DEFAULT._fieldMinLevel; 224 } else { 225 _getterMinLevel = v; 226 _isGetterMinLevel = v; 227 _setterMinLevel = v; 228 _creatorMinLevel = v; 229 _fieldMinLevel = v; 230 } 231 } 232 233 /** 234 * @since 2.9 235 */ construct(JsonAutoDetect.Value vis)236 public static Std construct(JsonAutoDetect.Value vis) { 237 return DEFAULT.withOverrides(vis); 238 } 239 240 /* 241 /******************************************************** 242 /* Builder/fluent methods for instantiating configured 243 /* instances 244 /******************************************************** 245 */ 246 _with(Visibility g, Visibility isG, Visibility s, Visibility cr, Visibility f)247 protected Std _with(Visibility g, Visibility isG, Visibility s, 248 Visibility cr, Visibility f) { 249 if ((g == _getterMinLevel) 250 && (isG == _isGetterMinLevel) 251 && (s == _setterMinLevel) 252 && (cr == _creatorMinLevel) 253 && (f == _fieldMinLevel) 254 ) { 255 return this; 256 } 257 return new Std(g, isG, s, cr, f); 258 } 259 260 @Override with(JsonAutoDetect ann)261 public Std with(JsonAutoDetect ann) 262 { 263 Std curr = this; 264 if (ann != null) { 265 return _with( 266 _defaultOrOverride(_getterMinLevel, ann.getterVisibility()), 267 _defaultOrOverride(_isGetterMinLevel, ann.isGetterVisibility()), 268 _defaultOrOverride(_setterMinLevel, ann.setterVisibility()), 269 _defaultOrOverride(_creatorMinLevel, ann.creatorVisibility()), 270 _defaultOrOverride(_fieldMinLevel, ann.fieldVisibility()) 271 ); 272 } 273 return curr; 274 } 275 276 @Override // since 2.9 withOverrides(JsonAutoDetect.Value vis)277 public Std withOverrides(JsonAutoDetect.Value vis) 278 { 279 Std curr = this; 280 if (vis != null) { 281 return _with( 282 _defaultOrOverride(_getterMinLevel, vis.getGetterVisibility()), 283 _defaultOrOverride(_isGetterMinLevel, vis.getIsGetterVisibility()), 284 _defaultOrOverride(_setterMinLevel, vis.getSetterVisibility()), 285 _defaultOrOverride(_creatorMinLevel, vis.getCreatorVisibility()), 286 _defaultOrOverride(_fieldMinLevel, vis.getFieldVisibility()) 287 ); 288 } 289 return curr; 290 } 291 _defaultOrOverride(Visibility defaults, Visibility override)292 private Visibility _defaultOrOverride(Visibility defaults, Visibility override) { 293 if (override == Visibility.DEFAULT) { 294 return defaults; 295 } 296 return override; 297 } 298 299 @Override with(Visibility v)300 public Std with(Visibility v) 301 { 302 if (v == Visibility.DEFAULT) { 303 return DEFAULT; 304 } 305 return new Std(v); 306 } 307 308 @Override withVisibility(PropertyAccessor method, Visibility v)309 public Std withVisibility(PropertyAccessor method, Visibility v) 310 { 311 switch (method) { 312 case GETTER: 313 return withGetterVisibility(v); 314 case SETTER: 315 return withSetterVisibility(v); 316 case CREATOR: 317 return withCreatorVisibility(v); 318 case FIELD: 319 return withFieldVisibility(v); 320 case IS_GETTER: 321 return withIsGetterVisibility(v); 322 case ALL: 323 return with(v); 324 //case NONE: 325 default: 326 // break; 327 return this; 328 } 329 } 330 331 @Override withGetterVisibility(Visibility v)332 public Std withGetterVisibility(Visibility v) { 333 if (v == Visibility.DEFAULT) v = DEFAULT._getterMinLevel; 334 if (_getterMinLevel == v) return this; 335 return new Std(v, _isGetterMinLevel, _setterMinLevel, _creatorMinLevel, _fieldMinLevel); 336 } 337 338 @Override withIsGetterVisibility(Visibility v)339 public Std withIsGetterVisibility(Visibility v) { 340 if (v == Visibility.DEFAULT) v = DEFAULT._isGetterMinLevel; 341 if (_isGetterMinLevel == v) return this; 342 return new Std(_getterMinLevel, v, _setterMinLevel, _creatorMinLevel, _fieldMinLevel); 343 } 344 345 @Override withSetterVisibility(Visibility v)346 public Std withSetterVisibility(Visibility v) { 347 if (v == Visibility.DEFAULT) v = DEFAULT._setterMinLevel; 348 if (_setterMinLevel == v) return this; 349 return new Std(_getterMinLevel, _isGetterMinLevel, v, _creatorMinLevel, _fieldMinLevel); 350 } 351 352 @Override withCreatorVisibility(Visibility v)353 public Std withCreatorVisibility(Visibility v) { 354 if (v == Visibility.DEFAULT) v = DEFAULT._creatorMinLevel; 355 if (_creatorMinLevel == v) return this; 356 return new Std(_getterMinLevel, _isGetterMinLevel, _setterMinLevel, v, _fieldMinLevel); 357 } 358 359 @Override withFieldVisibility(Visibility v)360 public Std withFieldVisibility(Visibility v) { 361 if (v == Visibility.DEFAULT) v = DEFAULT._fieldMinLevel; 362 if (_fieldMinLevel == v) return this; 363 return new Std(_getterMinLevel, _isGetterMinLevel, _setterMinLevel, _creatorMinLevel, v); 364 } 365 366 /* 367 /******************************************************** 368 /* Public API impl 369 /******************************************************** 370 */ 371 372 @Override isCreatorVisible(Member m)373 public boolean isCreatorVisible(Member m) { 374 return _creatorMinLevel.isVisible(m); 375 } 376 377 @Override isCreatorVisible(AnnotatedMember m)378 public boolean isCreatorVisible(AnnotatedMember m) { 379 return isCreatorVisible(m.getMember()); 380 } 381 382 @Override isFieldVisible(Field f)383 public boolean isFieldVisible(Field f) { 384 return _fieldMinLevel.isVisible(f); 385 } 386 387 @Override isFieldVisible(AnnotatedField f)388 public boolean isFieldVisible(AnnotatedField f) { 389 return isFieldVisible(f.getAnnotated()); 390 } 391 392 @Override isGetterVisible(Method m)393 public boolean isGetterVisible(Method m) { 394 return _getterMinLevel.isVisible(m); 395 } 396 397 @Override isGetterVisible(AnnotatedMethod m)398 public boolean isGetterVisible(AnnotatedMethod m) { 399 return isGetterVisible(m.getAnnotated()); 400 } 401 402 @Override isIsGetterVisible(Method m)403 public boolean isIsGetterVisible(Method m) { 404 return _isGetterMinLevel.isVisible(m); 405 } 406 407 @Override isIsGetterVisible(AnnotatedMethod m)408 public boolean isIsGetterVisible(AnnotatedMethod m) { 409 return isIsGetterVisible(m.getAnnotated()); 410 } 411 412 @Override isSetterVisible(Method m)413 public boolean isSetterVisible(Method m) { 414 return _setterMinLevel.isVisible(m); 415 } 416 417 @Override isSetterVisible(AnnotatedMethod m)418 public boolean isSetterVisible(AnnotatedMethod m) { 419 return isSetterVisible(m.getAnnotated()); 420 } 421 422 /* 423 /******************************************************** 424 /* Standard methods 425 /******************************************************** 426 */ 427 428 @Override toString()429 public String toString() { 430 return String.format("[Visibility: getter=%s,isGetter=%s,setter=%s,creator=%s,field=%s]", 431 _getterMinLevel, _isGetterMinLevel, _setterMinLevel, _creatorMinLevel, _fieldMinLevel); 432 } 433 } 434 } 435