• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.annotation;
2 
3 import java.lang.annotation.*;
4 
5 import java.lang.reflect.Member;
6 import java.lang.reflect.Modifier;
7 
8 /**
9  * Class annotation that can be used to define which kinds of Methods
10  * are to be detected by auto-detection, and with what minimum access level.
11  * Auto-detection means using name conventions
12  * and/or signature templates to find methods to use for data binding.
13  * For example, so-called "getters" can be auto-detected by looking for
14  * public member methods that return a value, do not take argument,
15  * and have prefix "get" in their name.
16  *<p>
17  * Default setting for all accessors is {@link Visibility#DEFAULT}, which
18  * in turn means that the global defaults are used. Defaults
19  * are different for different accessor types (getters need to be public;
20  * setters can have any access modifier, for example).
21  * If you assign different {@link Visibility} type then it will override
22  * global defaults: for example, to require that all setters must be public,
23  * you would use:
24  *<pre>
25  *   &#64;JsonAutoDetect(setterVisibility=Visibility.PUBLIC_ONLY)
26  *</pre>
27  */
28 @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
29 @Retention(RetentionPolicy.RUNTIME)
30 @JacksonAnnotation
31 public @interface JsonAutoDetect
32 {
33     /**
34      * Enumeration for possible visibility thresholds (minimum visibility)
35      * that can be used to limit which methods (and fields) are
36      * auto-detected.
37      */
38     public enum Visibility {
39         /**
40          * Value that means that all kinds of access modifiers are acceptable,
41          * from private to public.
42          */
43         ANY,
44         /**
45          * Value that means that any other access modifier other than 'private'
46          * is considered auto-detectable.
47          */
48         NON_PRIVATE,
49         /**
50          * Value that means access modifiers 'protected' and 'public' are
51          * auto-detectable (and 'private' and "package access" == no modifiers
52          * are not)
53          */
54         PROTECTED_AND_PUBLIC,
55         /**
56          * Value to indicate that only 'public' access modifier is considered
57          * auto-detectable.
58          */
59         PUBLIC_ONLY,
60         /**
61          * Value that indicates that no access modifiers are auto-detectable:
62          * this can be used to explicitly disable auto-detection for specified
63          * types.
64          */
65         NONE,
66 
67         /**
68          * Value that indicates that default visibility level (whatever it is,
69          * depends on context) is to be used. This usually means that inherited
70          * value (from parent visibility settings) is to be used.
71          */
72         DEFAULT;
73 
isVisible(Member m)74         public boolean isVisible(Member m) {
75             switch (this) {
76             case ANY:
77                 return true;
78             case NONE:
79                 return false;
80             case NON_PRIVATE:
81                 return !Modifier.isPrivate(m.getModifiers());
82             case PROTECTED_AND_PUBLIC:
83                 if (Modifier.isProtected(m.getModifiers())) {
84                     return true;
85                 }
86                 // fall through to public case:
87             case PUBLIC_ONLY:
88                 return Modifier.isPublic(m.getModifiers());
89             default:
90                 return false;
91             }
92         }
93     }
94 
95     /**
96      * Minimum visibility required for auto-detecting regular getter methods.
97      */
getterVisibility()98     Visibility getterVisibility() default Visibility.DEFAULT;
99 
100     /**
101      * Minimum visibility required for auto-detecting is-getter methods.
102      */
isGetterVisibility()103     Visibility isGetterVisibility() default Visibility.DEFAULT;
104 
105     /**
106      * Minimum visibility required for auto-detecting setter methods.
107      */
setterVisibility()108     Visibility setterVisibility() default Visibility.DEFAULT;
109 
110     /**
111      * Minimum visibility required for auto-detecting Creator methods,
112      * except for no-argument constructors (which are always detected
113      * no matter what).
114      */
creatorVisibility()115     Visibility creatorVisibility() default Visibility.DEFAULT;
116 
117     /**
118      * Minimum visibility required for auto-detecting member fields.
119      */
fieldVisibility()120     Visibility fieldVisibility() default Visibility.DEFAULT;
121 
122     /*
123     /**********************************************************
124     /* Value class used to enclose information, allow for
125     /* merging of layered configuration settings.
126     /**********************************************************
127      */
128 
129     /**
130      * Helper class used to contain information from a single {@link JsonIgnoreProperties}
131      * annotation, as well as to provide possible overrides from non-annotation sources.
132      *
133      * @since 2.9
134      */
135     public static class Value
136         implements JacksonAnnotationValue<JsonAutoDetect>,
137             java.io.Serializable
138     {
139         private static final long serialVersionUID = 1L;
140 
141         private final static Visibility DEFAULT_FIELD_VISIBILITY = Visibility.PUBLIC_ONLY;
142 
143         /**
144          * Default instance with baseline visibility checking:
145          *<ul>
146          * <li>Only public fields visible</li>
147          * <li>Only public getters, is-getters visible</li>
148          * <li>All setters (regardless of access) visible</li>
149          * <li>Only public Creators visible</li>
150          *</ul>
151          */
152         protected final static Value DEFAULT = new Value(DEFAULT_FIELD_VISIBILITY,
153                 Visibility.PUBLIC_ONLY, Visibility.PUBLIC_ONLY, Visibility.ANY,
154                 Visibility.PUBLIC_ONLY);
155 
156         /**
157          * Empty instance that specifies no overrides, that is, all visibility
158          * levels set as {@link Visibility#DEFAULT}.
159          */
160         protected final static Value NO_OVERRIDES = new Value(Visibility.DEFAULT,
161                 Visibility.DEFAULT, Visibility.DEFAULT, Visibility.DEFAULT,
162                 Visibility.DEFAULT);
163 
164         protected final Visibility _fieldVisibility;
165         protected final Visibility _getterVisibility;
166         protected final Visibility _isGetterVisibility;
167         protected final Visibility _setterVisibility;
168         protected final Visibility _creatorVisibility;
169 
Value(Visibility fields, Visibility getters, Visibility isGetters, Visibility setters, Visibility creators)170         private Value(Visibility fields,
171                 Visibility getters, Visibility isGetters, Visibility setters,
172                 Visibility creators) {
173             _fieldVisibility = fields;
174             _getterVisibility = getters;
175             _isGetterVisibility = isGetters;
176             _setterVisibility = setters;
177             _creatorVisibility = creators;
178         }
179 
defaultVisibility()180         public static Value defaultVisibility() {
181             return DEFAULT;
182         }
183 
noOverrides()184         public static Value noOverrides() {
185             return NO_OVERRIDES;
186         }
187 
from(JsonAutoDetect src)188         public static Value from(JsonAutoDetect src) {
189             return construct(src.fieldVisibility(),
190                     src.getterVisibility(), src.isGetterVisibility(), src.setterVisibility(),
191                     src.creatorVisibility());
192 
193         }
194 
195         /**
196          * Factory method for cnstructing instance with visibility of specified accessor
197          * (or, in case of <code>ALL</code>, all of them) set as specified; and the
198          * rest (if any) set as {@link Visibility#DEFAULT}).
199          */
construct(PropertyAccessor acc, Visibility visibility)200         public static Value construct(PropertyAccessor acc, Visibility visibility) {
201             Visibility fields = Visibility.DEFAULT;
202             Visibility getters = Visibility.DEFAULT;
203             Visibility isGetters = Visibility.DEFAULT;
204             Visibility setters = Visibility.DEFAULT;
205             Visibility creators = Visibility.DEFAULT;
206             switch (acc) {
207             case CREATOR:
208                 creators = visibility;
209                 break;
210             case FIELD:
211                 fields = visibility;
212                 break;
213             case GETTER:
214                 getters = visibility;
215                 break;
216             case IS_GETTER:
217                 isGetters = visibility;
218                 break;
219             case NONE:
220                 break;
221             case SETTER:
222                 setters = visibility;
223                 break;
224             case ALL: // default
225                 fields = getters = isGetters = setters = creators = visibility;
226                 break;
227             }
228             return construct(fields, getters, isGetters, setters, creators);
229         }
230 
construct(Visibility fields, Visibility getters, Visibility isGetters, Visibility setters, Visibility creators)231         public static Value construct(Visibility fields,
232                 Visibility getters, Visibility isGetters, Visibility setters,
233                 Visibility creators)
234         {
235             Value v = _predefined(fields, getters, isGetters, setters, creators);
236             if (v == null) {
237                 v = new Value(fields, getters, isGetters, setters, creators);
238             }
239             return v;
240         }
241 
withFieldVisibility(Visibility v)242         public Value withFieldVisibility(Visibility v) {
243             return construct(v, _getterVisibility, _isGetterVisibility,
244                     _setterVisibility, _creatorVisibility);
245         }
246 
withGetterVisibility(Visibility v)247         public Value withGetterVisibility(Visibility v) {
248             return construct(_fieldVisibility, v, _isGetterVisibility,
249                     _setterVisibility, _creatorVisibility);
250         }
251 
withIsGetterVisibility(Visibility v)252         public Value withIsGetterVisibility(Visibility v) {
253             return construct(_fieldVisibility, _getterVisibility, v,
254                     _setterVisibility, _creatorVisibility);
255         }
256 
withSetterVisibility(Visibility v)257         public Value withSetterVisibility(Visibility v) {
258             return construct(_fieldVisibility, _getterVisibility, _isGetterVisibility,
259                     v, _creatorVisibility);
260         }
261 
withCreatorVisibility(Visibility v)262         public Value withCreatorVisibility(Visibility v) {
263             return construct(_fieldVisibility, _getterVisibility, _isGetterVisibility,
264                     _setterVisibility, v);
265         }
266 
merge(Value base, Value overrides)267         public static Value merge(Value base, Value overrides)
268         {
269             return (base == null) ? overrides
270                     : base.withOverrides(overrides);
271         }
272 
withOverrides(Value overrides)273         public Value withOverrides(Value overrides) {
274             if ((overrides == null) || (overrides == NO_OVERRIDES) || (overrides == this)) {
275                 return this;
276             }
277             if (_equals(this, overrides)) {
278                 return this;
279             }
280             Visibility fields = overrides._fieldVisibility;
281             if (fields == Visibility.DEFAULT) {
282                 fields = _fieldVisibility;
283             }
284             Visibility getters = overrides._getterVisibility;
285             if (getters == Visibility.DEFAULT) {
286                 getters = _getterVisibility;
287             }
288             Visibility isGetters = overrides._isGetterVisibility;
289             if (isGetters == Visibility.DEFAULT) {
290                 isGetters = _isGetterVisibility;
291             }
292             Visibility setters = overrides._setterVisibility;
293             if (setters == Visibility.DEFAULT) {
294                 setters = _setterVisibility;
295             }
296             Visibility creators = overrides._creatorVisibility;
297             if (creators == Visibility.DEFAULT) {
298                 creators = _creatorVisibility;
299             }
300             return construct(fields, getters, isGetters, setters, creators);
301         }
302 
303         @Override
valueFor()304         public Class<JsonAutoDetect> valueFor() {
305             return JsonAutoDetect.class;
306         }
307 
getFieldVisibility()308         public Visibility getFieldVisibility() { return _fieldVisibility; }
getGetterVisibility()309         public Visibility getGetterVisibility() { return _getterVisibility; }
getIsGetterVisibility()310         public Visibility getIsGetterVisibility() { return _isGetterVisibility; }
getSetterVisibility()311         public Visibility getSetterVisibility() { return _setterVisibility; }
getCreatorVisibility()312         public Visibility getCreatorVisibility() { return _creatorVisibility; }
313 
314         // for JDK serialization
readResolve()315         protected Object readResolve() {
316             Value v = _predefined(_fieldVisibility, _getterVisibility, _isGetterVisibility,
317                     _setterVisibility, _creatorVisibility);
318             return (v == null) ? this : v;
319         }
320 
321         @Override
toString()322         public String toString() {
323             return String.format(
324 "JsonAutoDetect.Value(fields=%s,getters=%s,isGetters=%s,setters=%s,creators=%s)",
325 _fieldVisibility, _getterVisibility, _isGetterVisibility, _setterVisibility, _creatorVisibility
326                     );
327         }
328 
329         @Override
hashCode()330         public int hashCode() {
331             return 1 + _fieldVisibility.ordinal()
332                 ^ (3 * _getterVisibility.ordinal())
333                 - (7 * _isGetterVisibility.ordinal())
334                 + (11 * _setterVisibility.ordinal())
335                 ^ (13 * _creatorVisibility.ordinal())
336                     ;
337         }
338 
339         @Override
equals(Object o)340         public boolean equals(Object o) {
341             if (o == this) return true;
342             if (o == null) return false;
343             return (o.getClass() == getClass()) && _equals(this, (Value) o);
344         }
345 
_predefined(Visibility fields, Visibility getters, Visibility isGetters, Visibility setters, Visibility creators)346         private static Value _predefined(Visibility fields,
347                 Visibility getters, Visibility isGetters, Visibility setters,
348                 Visibility creators)
349         {
350             if (fields == DEFAULT_FIELD_VISIBILITY) {
351                 if ((getters == DEFAULT._getterVisibility)
352                     && (isGetters == DEFAULT._isGetterVisibility)
353                     && (setters == DEFAULT._setterVisibility)
354                     && (creators == DEFAULT._creatorVisibility)) {
355                     return DEFAULT;
356                 }
357             } else if (fields == Visibility.DEFAULT) {
358                 if ((getters == Visibility.DEFAULT)
359                         && (isGetters == Visibility.DEFAULT)
360                         && (setters == Visibility.DEFAULT)
361                         && (creators == Visibility.DEFAULT)) {
362                     return NO_OVERRIDES;
363                 }
364             }
365             return null;
366         }
367 
_equals(Value a, Value b)368         private static boolean _equals(Value a, Value b)
369         {
370             return (a._fieldVisibility == b._fieldVisibility)
371                     && (a._getterVisibility == b._getterVisibility)
372                     && (a._isGetterVisibility == b._isGetterVisibility)
373                     && (a._setterVisibility == b._setterVisibility)
374                     && (a._creatorVisibility == b._creatorVisibility)
375                     ;
376         }
377     }
378 }
379