1/*
2 * Copyright (c) 2007 Mockito contributors
3 * This program is made available under the terms of the MIT License.
4 */
5package org.mockito.internal.stubbing;
6
7import static org.mockito.internal.exceptions.Reporter.notAMockPassedToWhenMethod;
8import static org.mockito.internal.exceptions.Reporter.nullPassedToWhenMethod;
9import static org.mockito.internal.stubbing.answers.DoesNothing.doesNothing;
10
11import java.util.LinkedList;
12import java.util.List;
13
14import org.mockito.internal.stubbing.answers.CallsRealMethods;
15import org.mockito.internal.stubbing.answers.Returns;
16import org.mockito.internal.stubbing.answers.ThrowsException;
17import org.mockito.internal.stubbing.answers.ThrowsExceptionClass;
18import org.mockito.internal.util.MockUtil;
19import org.mockito.stubbing.Answer;
20import org.mockito.stubbing.Stubber;
21
22@SuppressWarnings("unchecked")
23public class StubberImpl implements Stubber {
24
25    private final List<Answer<?>> answers = new LinkedList<Answer<?>>();
26
27    @Override
28    public <T> T when(T mock) {
29        if (mock == null) {
30            throw nullPassedToWhenMethod();
31        }
32
33		if (!MockUtil.isMock(mock)) {
34			throw notAMockPassedToWhenMethod();
35		}
36
37		MockUtil.getMockHandler(mock).setAnswersForStubbing(answers);
38        return mock;
39    }
40
41    @Override
42    public Stubber doReturn(Object toBeReturned) {
43        return doReturnValues(toBeReturned);
44    }
45
46    @Override
47    public Stubber doReturn(Object toBeReturned, Object... nextToBeReturned) {
48        return doReturnValues(toBeReturned).doReturnValues(nextToBeReturned);
49    }
50
51    private StubberImpl doReturnValues(Object... toBeReturned) {
52        if(toBeReturned == null) {
53            answers.add(new Returns(null));
54            return this;
55        }
56        for (Object r : toBeReturned) {
57            answers.add(new Returns(r));
58        }
59        return this;
60    }
61
62    @Override
63    public Stubber doThrow(Throwable... toBeThrown) {
64        if(toBeThrown == null) {
65            answers.add(new ThrowsException(null));
66            return this;
67        }
68        for (Throwable throwable : toBeThrown) {
69            answers.add(new ThrowsException(throwable));
70        }
71        return this;
72    }
73
74    @Override
75    public Stubber doThrow(Class<? extends Throwable> toBeThrown) {
76        return doThrowClasses(toBeThrown);
77    }
78
79    @Override
80    public Stubber doThrow(Class<? extends Throwable> toBeThrown, Class<? extends Throwable>... nextToBeThrown) {
81        return doThrowClasses(toBeThrown).doThrowClasses(nextToBeThrown);
82    }
83
84    private StubberImpl doThrowClasses(Class<? extends Throwable>... toBeThrown) {
85        for (Class<? extends Throwable> throwable: toBeThrown) {
86            answers.add(new ThrowsExceptionClass(throwable));
87        }
88        return this;
89    }
90
91    @Override
92    public Stubber doNothing() {
93        answers.add(doesNothing());
94        return this;
95    }
96
97    @Override
98    public Stubber doAnswer(Answer answer) {
99        answers.add(answer);
100        return this;
101    }
102
103    @Override
104    public Stubber doCallRealMethod() {
105        answers.add(new CallsRealMethods());
106        return this;
107    }
108}
109