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