@@ -81,6 +81,22 @@ public class POJOPropertiesCollector
81
81
protected LinkedHashMap <String , POJOPropertyBuilder > _properties ;
82
82
83
83
protected LinkedList <POJOPropertyBuilder > _creatorProperties ;
84
+
85
+ /**
86
+ * A set of "field renamings" that have been discovered, indicating
87
+ * intended renaming of other accesors: key is the implicit original
88
+ * name and value intended name to use instead.
89
+ *<p>
90
+ * Note that these renamings are applied earlier than "regular" (explicit)
91
+ * renamings and affect implicit name: their effect may be changed by
92
+ * further renaming based on explicit indicators.
93
+ * The main use case is to effectively relink accessors based on fields
94
+ * discovered, and used to sort of correct otherwise missing linkage between
95
+ * fields and other accessors.
96
+ *
97
+ * @since 2.11
98
+ */
99
+ protected Map <PropertyName , PropertyName > _fieldRenameMappings ;
84
100
85
101
protected LinkedList <AnnotatedMember > _anyGetters ;
86
102
@@ -280,7 +296,7 @@ protected void collectAll()
280
296
LinkedHashMap <String , POJOPropertyBuilder > props = new LinkedHashMap <String , POJOPropertyBuilder >();
281
297
282
298
// First: gather basic data
283
- _addFields (props );
299
+ _addFields (props ); // note: populates _fieldRenameMappings
284
300
_addMethods (props );
285
301
// 25-Jan-2016, tatu: Avoid introspecting (constructor-)creators for non-static
286
302
// inner classes, see [databind#1502]
@@ -289,9 +305,6 @@ protected void collectAll()
289
305
}
290
306
_addInjectables (props );
291
307
292
- // 27-Dec-2019, tatu: [databind#2527] initial re-linking by Field needs to
293
- // be applied before other processing
294
-
295
308
// Remove ignored properties, first; this MUST precede annotation merging
296
309
// since logic relies on knowing exactly which accessor has which annotation
297
310
_removeUnwantedProperties (props );
@@ -368,15 +381,20 @@ protected void _addFields(Map<String, POJOPropertyBuilder> props)
368
381
if (implName == null ) {
369
382
implName = f .getName ();
370
383
}
384
+ final PropertyName implNameP = _propNameFromSimple (implName );
371
385
372
386
// [databind#2527: Field-based renaming can be applied early (here),
373
387
// or at a later point, but probably must be done before pruning
374
388
// final fields. So let's do it early here
375
- final PropertyName rename = ai .findRenameByField (_config , f , _propNameFromSimple (implName ));
376
- if (rename != null ) {
389
+ final PropertyName rename = ai .findRenameByField (_config , f , implNameP );
390
+ if ((rename != null ) && !rename .equals (implNameP )) {
391
+ if (_fieldRenameMappings == null ) {
392
+ _fieldRenameMappings = new HashMap <>();
393
+ }
394
+ _fieldRenameMappings .put (rename , implNameP );
377
395
// todo
378
396
}
379
-
397
+
380
398
PropertyName pn ;
381
399
382
400
if (_forSerialization ) {
@@ -479,9 +497,12 @@ protected void _addCreatorParam(Map<String, POJOPropertyBuilder> props,
479
497
pn = PropertyName .construct (impl );
480
498
}
481
499
500
+ // 27-Dec-2019, tatu: [databind#2527] may need to rename according to field
501
+ impl = _checkRenameByField (impl );
502
+
482
503
// shouldn't need to worry about @JsonIgnore, since creators only added
483
504
// if so annotated
484
-
505
+
485
506
/* 13-May-2015, tatu: We should try to start with implicit name, similar to how
486
507
* fields and methods work; but unlike those, we don't necessarily have
487
508
* implicit name to use (pre-Java8 at least). So:
@@ -499,11 +520,11 @@ protected void _addMethods(Map<String, POJOPropertyBuilder> props)
499
520
{
500
521
final AnnotationIntrospector ai = _annotationIntrospector ;
501
522
for (AnnotatedMethod m : _classDef .memberMethods ()) {
502
- /* For methods, handling differs between getters and setters; and
503
- * we will also only consider entries that either follow the bean
504
- * naming convention or are explicitly marked: just being visible
505
- * is not enough (unlike with fields)
506
- */
523
+ // For methods, handling differs between getters and setters; and
524
+ // we will also only consider entries that either follow the bean
525
+ // naming convention or are explicitly marked: just being visible
526
+ // is not enough (unlike with fields)
527
+
507
528
int argCount = m .getParameterCount ();
508
529
if (argCount == 0 ) { // getters (including 'any getter')
509
530
_addGetterMethod (props , m , ai );
@@ -584,6 +605,8 @@ protected void _addGetterMethod(Map<String, POJOPropertyBuilder> props,
584
605
}
585
606
visible = true ;
586
607
}
608
+ // 27-Dec-2019, tatu: [databind#2527] may need to rename according to field
609
+ implName = _checkRenameByField (implName );
587
610
boolean ignore = ai .hasIgnoreMarker (_config , m );
588
611
_property (props , implName ).addGetter (m , pn , nameExplicit , visible , ignore );
589
612
}
@@ -621,6 +644,8 @@ protected void _addSetterMethod(Map<String, POJOPropertyBuilder> props,
621
644
}
622
645
visible = true ;
623
646
}
647
+ // 27-Dec-2019, tatu: [databind#2527] may need to rename according to field
648
+ implName = _checkRenameByField (implName );
624
649
boolean ignore = (ai == null ) ? false : ai .hasIgnoreMarker (_config , m );
625
650
_property (props , implName ).addSetter (m , pn , nameExplicit , visible , ignore );
626
651
}
@@ -666,6 +691,18 @@ private PropertyName _propNameFromSimple(String simpleName) {
666
691
return PropertyName .construct (simpleName , null );
667
692
}
668
693
694
+ private String _checkRenameByField (String implName ) {
695
+ if (_fieldRenameMappings != null ) {
696
+ PropertyName p = _fieldRenameMappings .get (_propNameFromSimple (implName ));
697
+ if (p != null ) {
698
+ implName = p .getSimpleName ();
699
+ return implName ;
700
+
701
+ }
702
+ }
703
+ return implName ;
704
+ }
705
+
669
706
/*
670
707
/**********************************************************************
671
708
/* Internal methods; removing ignored properties
0 commit comments