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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
103 public boolean isGetterVisible(Method 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 */
111 public boolean isIsGetterVisible(Method 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 */
119 public boolean isSetterVisible(Method 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 */
127 public boolean isCreatorVisible(Member 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 */
135 public boolean isFieldVisible(Field 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
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 */
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 */
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 */
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 */
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
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
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
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
292 private Visibility _defaultOrOverride(Visibility defaults, Visibility override) {
293 if (override == Visibility.DEFAULT) {
294 return defaults;
295 }
296 return override;
297 }
298
299 @Override
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
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
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
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
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
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
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
373 public boolean isCreatorVisible(Member m) {
374 return _creatorMinLevel.isVisible(m);
375 }
376
377 @Override
378 public boolean isCreatorVisible(AnnotatedMember m) {
379 return isCreatorVisible(m.getMember());
380 }
381
382 @Override
383 public boolean isFieldVisible(Field f) {
384 return _fieldMinLevel.isVisible(f);
385 }
386
387 @Override
388 public boolean isFieldVisible(AnnotatedField f) {
389 return isFieldVisible(f.getAnnotated());
390 }
391
392 @Override
393 public boolean isGetterVisible(Method m) {
394 return _getterMinLevel.isVisible(m);
395 }
396
397 @Override
398 public boolean isGetterVisible(AnnotatedMethod m) {
399 return isGetterVisible(m.getAnnotated());
400 }
401
402 @Override
403 public boolean isIsGetterVisible(Method m) {
404 return _isGetterMinLevel.isVisible(m);
405 }
406
407 @Override
408 public boolean isIsGetterVisible(AnnotatedMethod m) {
409 return isIsGetterVisible(m.getAnnotated());
410 }
411
412 @Override
413 public boolean isSetterVisible(Method m) {
414 return _setterMinLevel.isVisible(m);
415 }
416
417 @Override
418 public boolean isSetterVisible(AnnotatedMethod m) {
419 return isSetterVisible(m.getAnnotated());
420 }
421
422 /*
423 /********************************************************
424 /* Standard methods
425 /********************************************************
426 */
427
428 @Override
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