/*
 * ObjectDiffer.java
 *
 * Created on May 24, 2006, 3:49 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package usda.weru.util.diff.differs;

import usda.weru.util.diff.*;

/**
 *
 * @author Joseph Levin
 */
public class ObjectDiffer implements Differ {

    /**
     *
     * @param a
     * @param b
     * @return
     * @throws IncomparableObjectsException
     */
    @Override
    public int diff(Object a, Object b) throws IncomparableObjectsException {
        test(Object.class, a, b);
        if (a == null && b == null) {
            return DIFF_SAME;
        } else if (a == null) {
            return DIFF_ADDED;
        } else if (b == null) {
            return DIFF_REMOVED;
        } else if (a.toString().equals(b.toString())) {
            return DIFF_SAME;
        } else {
            return DIFF_CHANGED;
        }
    }

    /**
     *
     * @return
     */
    @Override
    public String toString() {
        return getClass().getSimpleName();
    }

    /**
     *
     * @param objectType
     * @param a
     * @param b
     * @throws IncomparableObjectsException
     */
    protected void test(Class<?> objectType, Object a, Object b) throws IncomparableObjectsException {
        boolean test;
        if (a == null && b == null) {
            test = true;
        } else if (a == null && objectType.isAssignableFrom(b.getClass())) {
            test = true;
        } else if (b == null && objectType.isAssignableFrom(a.getClass())) {
            test = true;
        } else if (objectType.isAssignableFrom(a.getClass()) && objectType.isAssignableFrom(b.getClass())) {
            test = true;
        } else {
            test = false;
        }

        if (!test) {
            Class<?> gcc = DiffEngine.greatestCommonClass(a, b);
            throw new IncomparableObjectsException("Unable to diff " + gcc.getSimpleName()
                    + ".  Expected " + objectType.getSimpleName() + ".");
        }
    }

}
