Mise en œuvre basée sur quickfix.Message.toXML()
logique d'itération. Le résultat de la comparaison est une carte triée de la clé composite (si le champ fait partie du groupe) et de la paire d'états "avant" et "après".
import static java.lang.Math.min;
import static java.util.Collections.emptySet;
import static java.util.stream.Collectors.toList;
import static org.apache.commons.collections4.CollectionUtils.subtract;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import quickfix.Field;
import quickfix.FieldMap;
import quickfix.Group;
import quickfix.Message;
public class FixDiff {
private static final CompositeKeyComparator COMPARATOR = new CompositeKeyComparator();
private Set<Integer> ignored;
public FixDiff() {
this(emptySet());
}
public FixDiff(Set<Integer> ignored) {
this.ignored = ignored;
}
public Map<List<Integer>, Pair<String, String>> compare(Message expected, Message actual) {
Map<List<Integer>, String> expectedMap = toHierarchialMap(expected);
Map<List<Integer>, String> actualMap = toHierarchialMap(actual);
Collection<List<Integer>> missing = subtract(expectedMap.keySet(), actualMap.keySet());
Collection<List<Integer>> extra = subtract(actualMap.keySet(), expectedMap.keySet());
Collection<List<Integer>> diff = expectedMap.entrySet().stream()
.filter(e -> !missing.contains(e.getKey()) && !extra.contains(e.getKey()))
.filter(e -> !e.getValue().equals(actualMap.get(e.getKey())))
.map(Entry::getKey)
.collect(toList());
TreeMap<List<Integer>, Pair<String, String>> discrepancies = new TreeMap<List<Integer>, Pair<String, String>>(COMPARATOR);
missing.forEach(key -> discrepancies.put(key, new ImmutablePair<String, String>(expectedMap.get(key), null)));
extra.forEach(key -> discrepancies.put(key, new ImmutablePair<String, String>(null, actualMap.get(key))));
diff.forEach(key -> discrepancies.put(key, new ImmutablePair<String, String>(expectedMap.get(key), actualMap.get(key))));
return discrepancies;
}
private Map<List<Integer>, String> toHierarchialMap(Message message) {
Map<List<Integer>, String> result = new HashMap<List<Integer>, String>();
toHierarchialMap(result, new ArrayList<Integer>(), message.getHeader());
toHierarchialMap(result, new ArrayList<Integer>(), message);
toHierarchialMap(result, new ArrayList<Integer>(), message.getTrailer());
return result;
}
private void toHierarchialMap(Map<List<Integer>, String> map, ArrayList<Integer> segmentKey, FieldMap segment) {
Iterator<Field<?>> iterator = segment.iterator();
while (iterator.hasNext()) {
Field<?> field = iterator.next();
if (!ignored.contains(field.getTag()) && field.getObject() != null)
map.put(compositeKey(segmentKey, field.getTag()), field.getObject().toString());
}
Iterator<Integer> groupKeyIterator = segment.groupKeyIterator();
while (iterator.hasNext()) {
Integer groupKey = groupKeyIterator.next();
if (ignored.contains(groupKey))
continue;
for (Group group : segment.getGroups(groupKey))
toHierarchialMap(map, compositeKey(segmentKey, groupKey), group);
}
}
private ArrayList<Integer> compositeKey(ArrayList<Integer> parent, Integer tag) {
ArrayList<Integer> copy = new ArrayList<>(parent);
copy.add(tag);
return copy;
}
private static class CompositeKeyComparator implements Comparator<List<Integer>> {
@Override
public int compare(List<Integer> o1, List<Integer> o2) {
for (int i = 0; i < min(o1.size(), o2.size()); i++) {
if (o1.get(i) != o2.get(i))
return o1.get(i) - o2.get(i);
}
return o1.size() - o2.size();
}
}
}