com.darwinsys.diff.DiffObj Maven / Gradle / Ivy
package com.darwinsys.diff;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* Compare two objects and report in detail on the diffs;
* probably useful in audit logs, among other places.
*
* final List<DiffField> diffs = DiffObj.diffObj(oldObj, newObj);
* for (DiffObj.DiffField d : diffs) {
* auditlog.printf("User %s changed %s from %s to %s%n",
* userName, d.name, d.oldValue, d.newValue);
*
*/
public class DiffObj {
public static class DiffField {
public DiffField(String name, Object oldFieldValue, Object newFieldValue) {
this.name = name;
this.oldVal = oldFieldValue;
this.newVal = newFieldValue;
}
String name;
Object oldVal;
Object newVal;
}
public static List diffObj(Object oldValue, Object newValue) {
List allDiffs = new ArrayList<>();
Class cOld = oldValue.getClass(), cNew = newValue.getClass();
if (cOld != cNew) {
throw new IllegalArgumentException("Objects to be compared must be of identical class");
}
Class c;
for (c = cOld; c!= null; c = c.getSuperclass()) {
Field[] allF = c.getDeclaredFields();
for (Field f : allF) {
if (f.getName().startsWith("this$")) {
continue;
}
f.setAccessible(true);
try {
final Object oldFieldValue = f.get(oldValue);
final Object newFieldValue = f.get(newValue);
if (!oldFieldValue.equals(newFieldValue)) {
allDiffs.add(new DiffField(f.getName(), oldFieldValue, newFieldValue));
}
} catch (IllegalArgumentException | IllegalAccessException e) {
System.err.println("Ignoring error: " + e + " in field " + f);
}
}
}
return allDiffs;
}
}