private static void compareMaps ( Delta delta , Collection deltas , LinkedList stack , ID idFetcher ) { Map < Object , Object > srcMap = ( Map < Object , Object > ) delta . srcValue ; Map < Object , Object > targetMap = ( Map < Object , Object > ) delta . targetValue ; // Walk source Map keys and see if they exist in target map. If not, that entry needs to be removed. // If the key exists in both, then the value must tested for equivalence. If !equal, then a PUT command // is created to re-associate target value to key. final String sysId = "(" + System . identityHashCode ( srcMap ) + ' ' ; for ( Map . Entry entry : srcMap . entrySet ( ) ) { Object srcKey = entry . getKey ( ) ; Object srcValue = entry . getValue ( ) ; String srcPtr = sysId + "['" + System . identityHashCode ( srcKey ) + "']" ; if ( targetMap . containsKey ( srcKey ) ) { Object targetValue = targetMap . get ( srcKey ) ; if ( srcValue == null || targetValue == null ) { // Null value in either source or target if ( srcValue != targetValue ) { // Value differed, must create PUT command to overwrite source value associated to key addMapPutDelta ( delta , deltas , srcPtr , targetValue , srcKey ) ; } } else if ( isIdObject ( srcValue , idFetcher ) && isIdObject ( targetValue , idFetcher ) ) { // Both source and destination have same object (by id) as the value, add delta to stack (field-by-field check for item). if ( idFetcher . getId ( srcValue ) . equals ( idFetcher . getId ( targetValue ) ) ) { stack . push ( new Delta ( delta . id , delta . fieldName , srcPtr , srcValue , targetValue , null ) ) ; } else { // Different ID associated to same key, must create PUT command to overwrite source value associated to key addMapPutDelta ( delta , deltas , srcPtr , targetValue , srcKey ) ; } } else if ( ! DeepEquals . deepEquals ( srcValue , targetValue ) ) { // Non-null, non-ID value associated to key, and the two values are not equal. Create PUT command to overwrite. addMapPutDelta ( delta , deltas , srcPtr , targetValue , srcKey ) ; } } else { // target does not have this Key in it's map, therefore create REMOVE command to remove it from source map. Delta removeDelta = new Delta ( delta . id , delta . fieldName , srcPtr , srcValue , null , srcKey ) ; removeDelta . setCmd ( MAP_REMOVE ) ; deltas . add ( removeDelta ) ; } } for ( Map . Entry entry : targetMap . entrySet ( ) ) { Object targetKey = entry . getKey ( ) ; String srcPtr = sysId + "['" + System . identityHashCode ( targetKey ) + "']" ; if ( ! srcMap . containsKey ( targetKey ) ) { // Add Delta command map.put Delta putDelta = new Delta ( delta . id , delta . fieldName , srcPtr , null , entry . getValue ( ) , targetKey ) ; putDelta . setCmd ( MAP_PUT ) ; deltas . add ( putDelta ) ; } } // TODO: If LinkedHashMap, may need to issue commands to reorder... }
Deeply compare two Maps and generate the appropriate put or remove commands to rectify their differences .