22
22
* use cases for that, nor is such usage tested or supported.
23
23
* Separation from API is mostly to isolate some implementation details
24
24
* here and keep API simple.
25
+ *<p>
26
+ * Note that since 2.6 this class has been a thin shell around
27
+ * {@link POJOPropertiesCollector}, which handles most of actual work.
25
28
*/
26
29
public class BasicBeanDescription extends BeanDescription
27
30
{
@@ -31,6 +34,13 @@ public class BasicBeanDescription extends BeanDescription
31
34
/**********************************************************
32
35
*/
33
36
37
+ /**
38
+ * We will hold a reference to the collector in cases where
39
+ * information is lazily accessed and constructed; properties
40
+ * are only accessed when they are actually needed.
41
+ */
42
+ final protected POJOPropertiesCollector _propCollector ;
43
+
34
44
final protected MapperConfig <?> _config ;
35
45
36
46
final protected AnnotationIntrospector _annotationIntrospector ;
@@ -53,80 +63,66 @@ public class BasicBeanDescription extends BeanDescription
53
63
*/
54
64
55
65
/**
56
- * Properties collected for the POJO.
66
+ * Properties collected for the POJO; initialized as needed .
57
67
*/
58
- protected final List <BeanPropertyDefinition > _properties ;
68
+ protected List <BeanPropertyDefinition > _properties ;
59
69
60
70
/**
61
71
* Details of Object Id to include, if any
62
72
*/
63
73
protected ObjectIdInfo _objectIdInfo ;
64
74
65
- // // for deserialization
66
-
67
- protected AnnotatedMethod _anySetterMethod ;
68
-
69
- protected Map <Object , AnnotatedMember > _injectables ;
70
-
71
- /**
72
- * Set of properties that can be ignored during deserialization, due
73
- * to being marked as ignored.
74
- */
75
- protected Set <String > _ignoredPropertyNames ;
76
-
77
- // // for serialization
78
-
79
- protected AnnotatedMethod _jsonValueMethod ;
80
-
81
- protected AnnotatedMember _anyGetter ;
82
-
83
75
/*
84
76
/**********************************************************
85
77
/* Life-cycle
86
78
/**********************************************************
87
79
*/
88
80
81
+ protected BasicBeanDescription (POJOPropertiesCollector coll ,
82
+ JavaType type , AnnotatedClass classDef )
83
+ {
84
+ super (type );
85
+ _propCollector = coll ;
86
+ _config = coll .getConfig ();
87
+ _annotationIntrospector = (_config == null ) ? null : _config .getAnnotationIntrospector ();
88
+ _classInfo = classDef ;
89
+ }
90
+
91
+ /**
92
+ * Alternate constructor used in cases where property information is not needed,
93
+ * only class info.
94
+ */
89
95
protected BasicBeanDescription (MapperConfig <?> config ,
90
- JavaType type , AnnotatedClass classDef ,
91
- List <BeanPropertyDefinition > props )
96
+ JavaType type , AnnotatedClass classDef , List <BeanPropertyDefinition > props )
92
97
{
93
98
super (type );
99
+ _propCollector = null ;
94
100
_config = config ;
95
- _annotationIntrospector = (config == null ) ? null : config .getAnnotationIntrospector ();
101
+ _annotationIntrospector = (_config == null ) ? null : _config .getAnnotationIntrospector ();
96
102
_classInfo = classDef ;
97
103
_properties = props ;
98
104
}
99
105
100
106
protected BasicBeanDescription (POJOPropertiesCollector coll )
101
107
{
102
- this (coll . getConfig () , coll .getType (), coll .getClassDef (), coll . getProperties ());
108
+ this (coll , coll .getType (), coll .getClassDef ());
103
109
_objectIdInfo = coll .getObjectIdInfo ();
104
110
}
105
111
106
112
/**
107
113
* Factory method to use for constructing an instance to use for building
108
114
* deserializers.
109
115
*/
110
- public static BasicBeanDescription forDeserialization (POJOPropertiesCollector coll )
111
- {
112
- BasicBeanDescription desc = new BasicBeanDescription (coll );
113
- desc ._anySetterMethod = coll .getAnySetterMethod ();
114
- desc ._ignoredPropertyNames = coll .getIgnoredPropertyNames ();
115
- desc ._injectables = coll .getInjectables ();
116
- desc ._jsonValueMethod = coll .getJsonValueMethod ();
117
- return desc ;
116
+ public static BasicBeanDescription forDeserialization (POJOPropertiesCollector coll ) {
117
+ return new BasicBeanDescription (coll );
118
118
}
119
119
120
120
/**
121
121
* Factory method to use for constructing an instance to use for building
122
122
* serializers.
123
123
*/
124
- public static BasicBeanDescription forSerialization (POJOPropertiesCollector coll )
125
- {
126
- BasicBeanDescription desc = new BasicBeanDescription (coll );
127
- desc ._jsonValueMethod = coll .getJsonValueMethod ();
128
- desc ._anyGetter = coll .getAnyGetter ();
129
- return desc ;
124
+ public static BasicBeanDescription forSerialization (POJOPropertiesCollector coll ) {
125
+ return new BasicBeanDescription (coll );
130
126
}
131
127
132
128
/**
@@ -141,6 +137,13 @@ public static BasicBeanDescription forOtherUse(MapperConfig<?> config,
141
137
ac , Collections .<BeanPropertyDefinition >emptyList ());
142
138
}
143
139
140
+ protected List <BeanPropertyDefinition > _properties () {
141
+ if (_properties == null ) {
142
+ _properties = _propCollector .getProperties ();
143
+ }
144
+ return _properties ;
145
+ }
146
+
144
147
/*
145
148
/**********************************************************
146
149
/* Limited modifications by core databind functionality
@@ -156,7 +159,7 @@ public static BasicBeanDescription forOtherUse(MapperConfig<?> config,
156
159
*/
157
160
public boolean removeProperty (String propName )
158
161
{
159
- Iterator <BeanPropertyDefinition > it = _properties .iterator ();
162
+ Iterator <BeanPropertyDefinition > it = _properties () .iterator ();
160
163
while (it .hasNext ()) {
161
164
BeanPropertyDefinition prop = it .next ();
162
165
if (prop .getName ().equals (propName )) {
@@ -173,7 +176,7 @@ public boolean addProperty(BeanPropertyDefinition def)
173
176
if (hasProperty (def .getFullName ())) {
174
177
return false ;
175
178
}
176
- _properties .add (def );
179
+ _properties () .add (def );
177
180
return true ;
178
181
}
179
182
@@ -189,7 +192,7 @@ public boolean hasProperty(PropertyName name) {
189
192
*/
190
193
public BeanPropertyDefinition findProperty (PropertyName name )
191
194
{
192
- for (BeanPropertyDefinition prop : _properties ) {
195
+ for (BeanPropertyDefinition prop : _properties () ) {
193
196
if (prop .hasName (name )) {
194
197
return prop ;
195
198
}
@@ -211,20 +214,23 @@ public BeanPropertyDefinition findProperty(PropertyName name)
211
214
212
215
@ Override
213
216
public List <BeanPropertyDefinition > findProperties () {
214
- return _properties ;
217
+ return _properties () ;
215
218
}
216
219
217
220
@ Override
218
221
public AnnotatedMethod findJsonValueMethod () {
219
- return _jsonValueMethod ;
222
+ return (_propCollector == null ) ? null
223
+ : _propCollector .getJsonValueMethod ();
220
224
}
221
225
222
226
@ Override
223
227
public Set <String > getIgnoredPropertyNames () {
224
- if (_ignoredPropertyNames == null ) {
228
+ Set <String > ign = (_propCollector == null ) ? null
229
+ : _propCollector .getIgnoredPropertyNames ();
230
+ if (ign == null ) {
225
231
return Collections .emptySet ();
226
232
}
227
- return _ignoredPropertyNames ;
233
+ return ign ;
228
234
}
229
235
230
236
@ Override
@@ -262,7 +268,9 @@ public AnnotatedConstructor findDefaultConstructor() {
262
268
@ Override
263
269
public AnnotatedMethod findAnySetter () throws IllegalArgumentException
264
270
{
265
- if (_anySetterMethod != null ) {
271
+ AnnotatedMethod anySetter = (_propCollector == null ) ? null
272
+ : _propCollector .getAnySetterMethod ();
273
+ if (anySetter != null ) {
266
274
/* Also, let's be somewhat strict on how field name is to be
267
275
* passed; String, Object make sense, others not
268
276
* so much.
@@ -271,17 +279,20 @@ public AnnotatedMethod findAnySetter() throws IllegalArgumentException
271
279
* requested; easy enough for devs to add support within
272
280
* method.
273
281
*/
274
- Class <?> type = _anySetterMethod .getRawParameterType (0 );
282
+ Class <?> type = anySetter .getRawParameterType (0 );
275
283
if (type != String .class && type != Object .class ) {
276
- throw new IllegalArgumentException ("Invalid 'any-setter' annotation on method " +_anySetterMethod .getName ()+"(): first argument not of type String or Object, but " +type .getName ());
284
+ throw new IllegalArgumentException ("Invalid 'any-setter' annotation on method " +anySetter .getName ()+"(): first argument not of type String or Object, but " +type .getName ());
277
285
}
278
286
}
279
- return _anySetterMethod ;
287
+ return anySetter ;
280
288
}
281
289
282
290
@ Override
283
291
public Map <Object , AnnotatedMember > findInjectables () {
284
- return _injectables ;
292
+ if (_propCollector != null ) {
293
+ return _propCollector .getInjectables ();
294
+ }
295
+ return Collections .emptyMap ();
285
296
}
286
297
287
298
@ Override
@@ -387,25 +398,27 @@ public JsonInclude.Include findSerializationInclusionForContent(JsonInclude.Incl
387
398
@ Override
388
399
public AnnotatedMember findAnyGetter () throws IllegalArgumentException
389
400
{
390
- if (_anyGetter != null ) {
401
+ AnnotatedMember anyGetter = (_propCollector == null ) ? null
402
+ : _propCollector .getAnyGetter ();
403
+ if (anyGetter != null ) {
391
404
/* For now let's require a Map; in future can add support for other
392
405
* types like perhaps Iterable<Map.Entry>?
393
406
*/
394
- Class <?> type = _anyGetter .getRawType ();
407
+ Class <?> type = anyGetter .getRawType ();
395
408
if (!Map .class .isAssignableFrom (type )) {
396
- throw new IllegalArgumentException ("Invalid 'any-getter' annotation on method " +_anyGetter .getName ()+"(): return type is not instance of java.util.Map" );
409
+ throw new IllegalArgumentException ("Invalid 'any-getter' annotation on method " +anyGetter .getName ()+"(): return type is not instance of java.util.Map" );
397
410
}
398
411
}
399
- return _anyGetter ;
412
+ return anyGetter ;
400
413
}
401
-
414
+
402
415
@ Override
403
416
public Map <String ,AnnotatedMember > findBackReferenceProperties ()
404
417
{
405
418
HashMap <String ,AnnotatedMember > result = null ;
406
419
// boolean hasIgnored = (_ignoredPropertyNames != null);
407
420
408
- for (BeanPropertyDefinition property : _properties ) {
421
+ for (BeanPropertyDefinition property : _properties () ) {
409
422
/* 23-Sep-2014, tatu: As per [Databind#426], we _should_ try to avoid
410
423
* calling accessor, as it triggers exception from seeming conflict.
411
424
* But the problem is that _ignoredPropertyNames here only contains
@@ -636,7 +649,7 @@ public LinkedHashMap<String,AnnotatedField> _findPropertyFields(
636
649
Collection <String > ignoredProperties , boolean forSerialization )
637
650
{
638
651
LinkedHashMap <String ,AnnotatedField > results = new LinkedHashMap <String ,AnnotatedField >();
639
- for (BeanPropertyDefinition property : _properties ) {
652
+ for (BeanPropertyDefinition property : _properties () ) {
640
653
AnnotatedField f = property .getField ();
641
654
if (f != null ) {
642
655
String name = property .getName ();
0 commit comments