@@ -307,9 +307,8 @@ protected void collectAll()
307
307
_renameUsing (props , naming );
308
308
}
309
309
310
- // Sort by visibility (explicit over implicit); drop all but first
311
- // of member type (getter, setter etc) if there is visibility
312
- // difference
310
+ // Sort by visibility (explicit over implicit); drop all but first of member
311
+ // type (getter, setter etc) if there is visibility difference
313
312
for (POJOPropertyBuilder property : props .values ()) {
314
313
property .trimByVisibility ();
315
314
}
@@ -898,26 +897,25 @@ protected void _renameWithWrappers(Map<String, POJOPropertyBuilder> props)
898
897
/* Overridable internal methods, sorting, other stuff
899
898
/**********************************************************
900
899
*/
901
-
902
- /* First, explicit ordering and/or alphabetic
903
- * and then implicitly order creator properties before others.
904
- */
900
+
901
+ // First, order by(explicit ordering and/or alphabetic),
902
+ // then by (optional) index (if any)
903
+ // and then implicitly order creator properties before others)
904
+
905
905
protected void _sortProperties (Map <String , POJOPropertyBuilder > props )
906
906
{
907
907
// Then how about explicit ordering?
908
- AnnotationIntrospector intr = _annotationIntrospector ;
908
+ final AnnotationIntrospector intr = _annotationIntrospector ;
909
909
Boolean alpha = intr .findSerializationSortAlphabetically (_config , (Annotated ) _classDef );
910
- boolean sort ;
911
-
912
- if (alpha == null ) {
913
- sort = _config .shouldSortPropertiesAlphabetically ();
914
- } else {
915
- sort = alpha .booleanValue ();
916
- }
910
+ final boolean sort = (alpha == null )
911
+ ? _config .shouldSortPropertiesAlphabetically ()
912
+ : alpha .booleanValue ();
913
+ final boolean indexed = _anyIndexed (props .values ());
914
+
917
915
String [] propertyOrder = intr .findSerializationPropertyOrder (_config , _classDef );
918
916
919
917
// no sorting? no need to shuffle, then
920
- if (!sort && (_creatorProperties == null ) && (propertyOrder == null )) {
918
+ if (!sort && ! indexed && (_creatorProperties == null ) && (propertyOrder == null )) {
921
919
return ;
922
920
}
923
921
int size = props .size ();
@@ -932,11 +930,11 @@ protected void _sortProperties(Map<String, POJOPropertyBuilder> props)
932
930
for (POJOPropertyBuilder prop : props .values ()) {
933
931
all .put (prop .getName (), prop );
934
932
}
935
- Map <String ,POJOPropertyBuilder > ordered = new LinkedHashMap <String , POJOPropertyBuilder >(size +size );
933
+ Map <String ,POJOPropertyBuilder > ordered = new LinkedHashMap <>(size +size );
936
934
// Ok: primarily by explicit order
937
935
if (propertyOrder != null ) {
938
936
for (String name : propertyOrder ) {
939
- POJOPropertyBuilder w = all .get (name );
937
+ POJOPropertyBuilder w = all .remove (name );
940
938
if (w == null ) { // will also allow use of "implicit" names for sorting
941
939
for (POJOPropertyBuilder prop : props .values ()) {
942
940
if (name .equals (prop .getInternalName ())) {
@@ -952,7 +950,26 @@ protected void _sortProperties(Map<String, POJOPropertyBuilder> props)
952
950
}
953
951
}
954
952
}
955
- // And secondly by sorting Creator properties before other unordered properties
953
+
954
+ // Second (starting with 2.11): index, if any:
955
+ if (indexed ) {
956
+ Map <Integer ,POJOPropertyBuilder > byIndex = new TreeMap <>();
957
+ Iterator <Map .Entry <String ,POJOPropertyBuilder >> it = all .entrySet ().iterator ();
958
+ while (it .hasNext ()) {
959
+ Map .Entry <String ,POJOPropertyBuilder > entry = it .next ();
960
+ POJOPropertyBuilder prop = entry .getValue ();
961
+ Integer index = prop .getMetadata ().getIndex ();
962
+ if (index != null ) {
963
+ byIndex .put (index , prop );
964
+ it .remove ();
965
+ }
966
+ }
967
+ for (POJOPropertyBuilder prop : byIndex .values ()) {
968
+ ordered .put (prop .getName (), prop );
969
+ }
970
+ }
971
+
972
+ // Third by sorting Creator properties before other unordered properties
956
973
if (_creatorProperties != null ) {
957
974
/* As per [databind#311], this is bit delicate; but if alphabetic ordering
958
975
* is mandated, at least ensure creator properties are in alphabetic
@@ -974,6 +991,8 @@ protected void _sortProperties(Map<String, POJOPropertyBuilder> props)
974
991
// 16-Jan-2016, tatu: Related to [databind#1317], make sure not to accidentally
975
992
// add back pruned creator properties!
976
993
String name = prop .getName ();
994
+ // 27-Nov-2019, tatu: Not sure why, but we should NOT remove it from `all` tho:
995
+ // if (all.remove(name) != null) {
977
996
if (all .containsKey (name )) {
978
997
ordered .put (name , prop );
979
998
}
@@ -983,7 +1002,16 @@ protected void _sortProperties(Map<String, POJOPropertyBuilder> props)
983
1002
ordered .putAll (all );
984
1003
props .clear ();
985
1004
props .putAll (ordered );
986
- }
1005
+ }
1006
+
1007
+ private boolean _anyIndexed (Collection <POJOPropertyBuilder > props ) {
1008
+ for (POJOPropertyBuilder prop : props ) {
1009
+ if (prop .getMetadata ().hasIndex ()) {
1010
+ return true ;
1011
+ }
1012
+ }
1013
+ return false ;
1014
+ }
987
1015
988
1016
/*
989
1017
/**********************************************************
0 commit comments