package dbfit.diff; import dbfit.api.Diff; import dbfit.util.MatchResult; import dbfit.util.DiffListener; import java.util.Collection; import java.util.ArrayList; public abstract class DiffBase<T1, T2> implements Diff<T1, T2> { protected Collection<DiffListener> listeners; protected abstract Class getType(); protected abstract DiffRunner getDiffRunner(MatchResult<T1, T2> request); public DiffBase(final Collection<DiffListener> listeners) { this.listeners = listeners; } public DiffBase() { this(new ArrayList<DiffListener>()); } @Override public void diff(final T1 object1, final T2 object2) { diff(MatchResult.create(object1, object2, getType())); } public void diff(final MatchResult<T1, T2> request) { getDiffRunner(request).runDiff(); } @Override public void addListener(final DiffListener listener) { listeners.add(listener); } @Override public void removeListener(final DiffListener listener) { listeners.remove(listener); } @Override public void addListeners(final Collection<DiffListener> newListeneres) { listeners.addAll(newListeneres); } @Override public void removeListeners(final Collection<DiffListener> removed) { listeners.removeAll(removed); } protected void notifyListeners(final MatchResult result) { for (DiffListener listener: listeners) { listener.onEvent(result); } } protected abstract class DiffRunner { protected final T1 obj1; protected final T2 obj2; protected final MatchResult<T1, T2> result; abstract protected void uncheckedDiff(); public DiffRunner(final MatchResult<T1, T2> result) { this.result = result; this.obj1 = result.getObject1(); this.obj2 = result.getObject2(); } public void runDiff() { try { beforeDiff(); uncheckedDiff(); } catch (Exception ex) { getResult().setException(ex); } finally { afterDiff(); notifyListeners(getResult()); } } public final MatchResult getResult() { return result; } protected void beforeDiff() {} protected void afterDiff() {} } }