1e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonpackage org.mockito.internal.matchers;
2e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
3e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonimport org.hamcrest.Description;
4e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonimport org.mockito.ArgumentMatcher;
5e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonimport org.mockito.exceptions.Reporter;
6e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
7e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonimport java.io.Serializable;
8e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonimport java.lang.reflect.Array;
9e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonimport java.util.Arrays;
10e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonimport java.util.Collections;
11e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonimport java.util.LinkedList;
12e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonimport java.util.List;
13e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
14e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
15e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson@SuppressWarnings("unchecked")
16e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonpublic class VarargCapturingMatcher<T> extends ArgumentMatcher<T> implements CapturesArguments, VarargMatcher, Serializable {
17e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    private static final long serialVersionUID = 4057053345838026645L;
18e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    private LinkedList<List<T>> arguments = new LinkedList<List<T>>();
19e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
20e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    public boolean matches(Object argument) {
21e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        return true;
22e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    }
23e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
24e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    public void describeTo(Description description) {
25e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        description.appendText("<Capturing variable argument>");
26e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    }
27e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
28e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    public List<T> getLastVarargs() {
29e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        if (arguments.isEmpty()) {
30e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson            new Reporter().noArgumentValueWasCaptured();
31e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson            return null;
32e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        } else {
33e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson            return arguments.getLast();
34e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        }
35e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    }
36e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
37e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    public List<List<T>> getAllVarargs() {
38e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        return arguments;
39e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    }
40e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
41e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    public void captureFrom(Object varArgArray) {
42e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        List<T> vararg = unpackAsList(varArgArray);
43e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        this.arguments.add(vararg);
44e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    }
45e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
46e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    private List<T> unpackAsList(Object varArgArray) {
47e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        if (varArgArray instanceof Object[]) {
48e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson            return Arrays.asList((T[]) varArgArray);
49e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        } else if (varArgArray.getClass().isArray()) {
50e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson            Object[] primitiveArray = new Object[Array.getLength(varArgArray)];
51e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson            for (int i = 0; i < primitiveArray.length; i++) {
52e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson                primitiveArray[i] = Array.get(varArgArray, i);
53e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson            }
54e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson            return Arrays.asList((T[]) primitiveArray);
55e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        } else {
56e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson            return Collections.singletonList((T) varArgArray);
57e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        }
58e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    }
59e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson}
60