@@ -89,6 +89,22 @@ public class POJOPropertiesCollector
89
89
protected LinkedHashMap <String , POJOPropertyBuilder > _properties ;
90
90
91
91
protected LinkedList <POJOPropertyBuilder > _creatorProperties ;
92
+
93
+ /**
94
+ * A set of "field renamings" that have been discovered, indicating
95
+ * intended renaming of other accesors: key is the implicit original
96
+ * name and value intended name to use instead.
97
+ *<p>
98
+ * Note that these renamings are applied earlier than "regular" (explicit)
99
+ * renamings and affect implicit name: their effect may be changed by
100
+ * further renaming based on explicit indicators.
101
+ * The main use case is to effectively relink accessors based on fields
102
+ * discovered, and used to sort of correct otherwise missing linkage between
103
+ * fields and other accessors.
104
+ *
105
+ * @since 2.11
106
+ */
107
+ protected Map <PropertyName , PropertyName > _fieldRenameMappings ;
92
108
93
109
protected LinkedList <AnnotatedMember > _anyGetters ;
94
110
@@ -305,7 +321,7 @@ protected void collectAll()
305
321
LinkedHashMap <String , POJOPropertyBuilder > props = new LinkedHashMap <String , POJOPropertyBuilder >();
306
322
307
323
// First: gather basic data
308
- _addFields (props );
324
+ _addFields (props ); // note: populates _fieldRenameMappings
309
325
_addMethods (props );
310
326
// 25-Jan-2016, tatu: Avoid introspecting (constructor-)creators for non-static
311
327
// inner classes, see [databind#1502]
@@ -314,9 +330,6 @@ protected void collectAll()
314
330
}
315
331
_addInjectables (props );
316
332
317
- // 27-Dec-2019, tatu: [databind#2527] initial re-linking by Field needs to
318
- // be applied before other processing
319
-
320
333
// Remove ignored properties, first; this MUST precede annotation merging
321
334
// since logic relies on knowing exactly which accessor has which annotation
322
335
_removeUnwantedProperties (props );
@@ -397,15 +410,20 @@ protected void _addFields(Map<String, POJOPropertyBuilder> props)
397
410
if (implName == null ) {
398
411
implName = f .getName ();
399
412
}
413
+ final PropertyName implNameP = _propNameFromSimple (implName );
400
414
401
415
// [databind#2527: Field-based renaming can be applied early (here),
402
416
// or at a later point, but probably must be done before pruning
403
417
// final fields. So let's do it early here
404
- final PropertyName rename = ai .findRenameByField (_config , f , _propNameFromSimple (implName ));
405
- if (rename != null ) {
418
+ final PropertyName rename = ai .findRenameByField (_config , f , implNameP );
419
+ if ((rename != null ) && !rename .equals (implNameP )) {
420
+ if (_fieldRenameMappings == null ) {
421
+ _fieldRenameMappings = new HashMap <>();
422
+ }
423
+ _fieldRenameMappings .put (rename , implNameP );
406
424
// todo
407
425
}
408
-
426
+
409
427
PropertyName pn ;
410
428
411
429
if (_forSerialization ) {
@@ -511,9 +529,12 @@ protected void _addCreatorParam(Map<String, POJOPropertyBuilder> props,
511
529
pn = PropertyName .construct (impl );
512
530
}
513
531
532
+ // 27-Dec-2019, tatu: [databind#2527] may need to rename according to field
533
+ impl = _checkRenameByField (impl );
534
+
514
535
// shouldn't need to worry about @JsonIgnore, since creators only added
515
536
// if so annotated
516
-
537
+
517
538
/* 13-May-2015, tatu: We should try to start with implicit name, similar to how
518
539
* fields and methods work; but unlike those, we don't necessarily have
519
540
* implicit name to use (pre-Java8 at least). So:
@@ -531,11 +552,11 @@ protected void _addMethods(Map<String, POJOPropertyBuilder> props)
531
552
{
532
553
final AnnotationIntrospector ai = _annotationIntrospector ;
533
554
for (AnnotatedMethod m : _classDef .memberMethods ()) {
534
- /* For methods, handling differs between getters and setters; and
535
- * we will also only consider entries that either follow the bean
536
- * naming convention or are explicitly marked: just being visible
537
- * is not enough (unlike with fields)
538
- */
555
+ // For methods, handling differs between getters and setters; and
556
+ // we will also only consider entries that either follow the bean
557
+ // naming convention or are explicitly marked: just being visible
558
+ // is not enough (unlike with fields)
559
+
539
560
int argCount = m .getParameterCount ();
540
561
if (argCount == 0 ) { // getters (including 'any getter')
541
562
_addGetterMethod (props , m , ai );
@@ -616,6 +637,8 @@ protected void _addGetterMethod(Map<String, POJOPropertyBuilder> props,
616
637
}
617
638
visible = true ;
618
639
}
640
+ // 27-Dec-2019, tatu: [databind#2527] may need to rename according to field
641
+ implName = _checkRenameByField (implName );
619
642
boolean ignore = ai .hasIgnoreMarker (m );
620
643
_property (props , implName ).addGetter (m , pn , nameExplicit , visible , ignore );
621
644
}
@@ -653,6 +676,8 @@ protected void _addSetterMethod(Map<String, POJOPropertyBuilder> props,
653
676
}
654
677
visible = true ;
655
678
}
679
+ // 27-Dec-2019, tatu: [databind#2527] may need to rename according to field
680
+ implName = _checkRenameByField (implName );
656
681
boolean ignore = (ai == null ) ? false : ai .hasIgnoreMarker (m );
657
682
_property (props , implName ).addSetter (m , pn , nameExplicit , visible , ignore );
658
683
}
@@ -697,7 +722,20 @@ protected void _doAddInjectable(JacksonInject.Value injectable, AnnotatedMember
697
722
private PropertyName _propNameFromSimple (String simpleName ) {
698
723
return PropertyName .construct (simpleName , null );
699
724
}
700
-
725
+
726
+ // @since 2.11
727
+ private String _checkRenameByField (String implName ) {
728
+ if (_fieldRenameMappings != null ) {
729
+ PropertyName p = _fieldRenameMappings .get (_propNameFromSimple (implName ));
730
+ if (p != null ) {
731
+ implName = p .getSimpleName ();
732
+ return implName ;
733
+
734
+ }
735
+ }
736
+ return implName ;
737
+ }
738
+
701
739
/*
702
740
/**********************************************************
703
741
/* Internal methods; removing ignored properties
0 commit comments