11ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot/*  Copyright (c) 2000-2006 hamcrest.org
21ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot */
31ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabotpackage org.hamcrest.core;
41ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot
51ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabotimport org.hamcrest.Description;
61ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabotimport org.hamcrest.Matcher;
71ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabotimport org.hamcrest.Factory;
81ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabotimport org.hamcrest.BaseMatcher;
91ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot
101ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabotimport java.lang.reflect.Array;
111ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot
121ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot
131ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot/**
141ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot * Is the value equal to another value, as tested by the
151ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot * {@link java.lang.Object#equals} invokedMethod?
161ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot */
171ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabotpublic class IsEqual<T> extends BaseMatcher<T> {
181ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    private final Object object;
191ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot
201ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    public IsEqual(T equalArg) {
211ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot        object = equalArg;
221ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    }
231ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot
241ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    public boolean matches(Object arg) {
251ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot        return areEqual(object, arg);
261ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    }
271ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot
281ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    public void describeTo(Description description) {
291ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot        description.appendValue(object);
301ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    }
311ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot
321ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    private static boolean areEqual(Object o1, Object o2) {
331ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot        if (o1 == null || o2 == null) {
341ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot            return o1 == null && o2 == null;
351ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot        } else if (isArray(o1)) {
361ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot            return isArray(o2) && areArraysEqual(o1, o2);
371ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot        } else {
381ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot            return o1.equals(o2);
391ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot        }
401ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    }
411ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot
421ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    private static boolean areArraysEqual(Object o1, Object o2) {
431ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot        return areArrayLengthsEqual(o1, o2)
441ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot                && areArrayElementsEqual(o1, o2);
451ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    }
461ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot
471ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    private static boolean areArrayLengthsEqual(Object o1, Object o2) {
481ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot        return Array.getLength(o1) == Array.getLength(o2);
491ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    }
501ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot
511ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    private static boolean areArrayElementsEqual(Object o1, Object o2) {
521ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot        for (int i = 0; i < Array.getLength(o1); i++) {
531ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot            if (!areEqual(Array.get(o1, i), Array.get(o2, i))) return false;
541ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot        }
551ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot        return true;
561ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    }
571ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot
581ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    private static boolean isArray(Object o) {
591ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot        return o.getClass().isArray();
601ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    }
611ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot
621ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    /**
631ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot     * Is the value equal to another value, as tested by the
641ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot     * {@link java.lang.Object#equals} invokedMethod?
651ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot     */
661ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    @Factory
671ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    public static <T> Matcher<T> equalTo(T operand) {
681ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot        return new IsEqual<T>(operand);
691ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot    }
701ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot
711ecfda91236a8970119144e59e0ba6113dc22c0fBrett Chabot}
72