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