2424import org .bson .types .BasicBSONList ;
2525import org .bson .types .ObjectId ;
2626
27+ import java .util .ArrayList ;
2728import java .util .Arrays ;
2829import java .util .Date ;
2930import java .util .LinkedHashMap ;
31+ import java .util .List ;
3032import java .util .Map ;
3133import java .util .Set ;
3234import java .util .TreeSet ;
@@ -339,12 +341,12 @@ public boolean equals( Object o ) {
339341 return false ;
340342 }
341343
342- return Arrays .equals (canonicalize (this ).encode (), canonicalize (other ).encode ());
344+ return Arrays .equals (canonicalizeBSONObject (this ).encode (), canonicalizeBSONObject (other ).encode ());
343345 }
344346
345347 @ Override
346348 public int hashCode () {
347- return Arrays .hashCode (canonicalize (this ).encode ());
349+ return Arrays .hashCode (canonicalizeBSONObject (this ).encode ());
348350 }
349351
350352 private byte [] encode () {
@@ -356,15 +358,43 @@ private BSONObject decode(final byte[] encodedBytes) {
356358 }
357359
358360 // create a copy of "from", but with keys ordered alphabetically
359- private static BasicBSONObject canonicalize (final BSONObject from ) {
361+ @ SuppressWarnings ("unchecked" )
362+ private static Object canonicalize (final Object from ) {
363+ if (from instanceof BSONObject && !(from instanceof BasicBSONList )) {
364+ return canonicalizeBSONObject ((BSONObject ) from );
365+ } else if (from instanceof List ) {
366+ return canonicalizeList ((List <Object >) from );
367+ } else if (from instanceof Map ) {
368+ return canonicalizeMap ((Map <String , Object >) from );
369+ } else {
370+ return from ;
371+ }
372+ }
373+
374+ private static Map <String , Object > canonicalizeMap (final Map <String , Object > from ) {
375+ Map <String , Object > canonicalized = new LinkedHashMap <String , Object >(from .size ());
376+ TreeSet <String > keysInOrder = new TreeSet <String >(from .keySet ());
377+ for (String key : keysInOrder ) {
378+ Object val = from .get (key );
379+ canonicalized .put (key , canonicalize (val ));
380+ }
381+ return canonicalized ;
382+ }
383+
384+ private static BasicBSONObject canonicalizeBSONObject (final BSONObject from ) {
360385 BasicBSONObject canonicalized = new BasicBSONObject ();
361386 TreeSet <String > keysInOrder = new TreeSet <String >(from .keySet ());
362387 for (String key : keysInOrder ) {
363388 Object val = from .get (key );
364- if (val instanceof BSONObject && ! (val instanceof BasicBSONList )) {
365- val = canonicalize ((BSONObject ) val );
366- }
367- canonicalized .put (key , val );
389+ canonicalized .put (key , canonicalize (val ));
390+ }
391+ return canonicalized ;
392+ }
393+
394+ private static List canonicalizeList (final List <Object > list ) {
395+ List <Object > canonicalized = new ArrayList <Object >(list .size ());
396+ for (Object cur : list ) {
397+ canonicalized .add (canonicalize (cur ));
368398 }
369399 return canonicalized ;
370400 }
0 commit comments