InvocationContainerImpl.java revision e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7
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 org.mockito.internal.invocation.InvocationMatcher;
8import org.mockito.internal.invocation.StubInfoImpl;
9import org.mockito.internal.progress.MockingProgress;
10import org.mockito.internal.stubbing.answers.AnswersValidator;
11import org.mockito.internal.verification.DefaultRegisteredInvocations;
12import org.mockito.internal.verification.RegisteredInvocations;
13import org.mockito.internal.verification.SingleRegisteredInvocation;
14import org.mockito.invocation.Invocation;
15import org.mockito.mock.MockCreationSettings;
16import org.mockito.stubbing.Answer;
17
18import java.io.Serializable;
19import java.util.ArrayList;
20import java.util.LinkedList;
21import java.util.List;
22
23@SuppressWarnings("unchecked")
24public class InvocationContainerImpl implements InvocationContainer, Serializable {
25
26    private static final long serialVersionUID = -5334301962749537177L;
27    private final LinkedList<StubbedInvocationMatcher> stubbed = new LinkedList<StubbedInvocationMatcher>();
28    private final MockingProgress mockingProgress;
29    private final List<Answer> answersForStubbing = new ArrayList<Answer>();
30    private final RegisteredInvocations registeredInvocations;
31
32    private InvocationMatcher invocationForStubbing;
33
34    public InvocationContainerImpl(MockingProgress mockingProgress, MockCreationSettings mockSettings) {
35        this.mockingProgress = mockingProgress;
36        this.registeredInvocations = createRegisteredInvocations(mockSettings);
37    }
38
39    public void setInvocationForPotentialStubbing(InvocationMatcher invocation) {
40        registeredInvocations.add(invocation.getInvocation());
41        this.invocationForStubbing = invocation;
42    }
43
44    public void resetInvocationForPotentialStubbing(InvocationMatcher invocationMatcher) {
45        this.invocationForStubbing = invocationMatcher;
46    }
47
48    public void addAnswer(Answer answer) {
49        registeredInvocations.removeLast();
50        addAnswer(answer, false);
51    }
52
53    public void addConsecutiveAnswer(Answer answer) {
54        addAnswer(answer, true);
55    }
56
57    public void addAnswer(Answer answer, boolean isConsecutive) {
58        Invocation invocation = invocationForStubbing.getInvocation();
59        mockingProgress.stubbingCompleted(invocation);
60        AnswersValidator answersValidator = new AnswersValidator();
61        answersValidator.validate(answer, invocation);
62
63        synchronized (stubbed) {
64            if (isConsecutive) {
65                stubbed.getFirst().addAnswer(answer);
66            } else {
67                stubbed.addFirst(new StubbedInvocationMatcher(invocationForStubbing, answer));
68            }
69        }
70    }
71
72    Object answerTo(Invocation invocation) throws Throwable {
73        return findAnswerFor(invocation).answer(invocation);
74    }
75
76    public StubbedInvocationMatcher findAnswerFor(Invocation invocation) {
77        synchronized (stubbed) {
78            for (StubbedInvocationMatcher s : stubbed) {
79                if (s.matches(invocation)) {
80                    s.markStubUsed(invocation);
81                    invocation.markStubbed(new StubInfoImpl(s));
82                    return s;
83                }
84            }
85        }
86
87        return null;
88    }
89
90    public void addAnswerForVoidMethod(Answer answer) {
91        answersForStubbing.add(answer);
92    }
93
94    public void setAnswersForStubbing(List<Answer> answers) {
95        answersForStubbing.addAll(answers);
96    }
97
98    public boolean hasAnswersForStubbing() {
99        return !answersForStubbing.isEmpty();
100    }
101
102    public boolean hasInvocationForPotentialStubbing() {
103        return !registeredInvocations.isEmpty();
104    }
105
106    public void setMethodForStubbing(InvocationMatcher invocation) {
107        invocationForStubbing = invocation;
108        assert hasAnswersForStubbing();
109        for (int i = 0; i < answersForStubbing.size(); i++) {
110            addAnswer(answersForStubbing.get(i), i != 0);
111        }
112        answersForStubbing.clear();
113    }
114
115    @Override
116    public String toString() {
117        return "invocationForStubbing: " + invocationForStubbing;
118    }
119
120    public List<Invocation> getInvocations() {
121        return registeredInvocations.getAll();
122    }
123
124    public List<StubbedInvocationMatcher> getStubbedInvocations() {
125        return stubbed;
126    }
127
128    public Object invokedMock() {
129        return invocationForStubbing.getInvocation().getMock();
130    }
131
132    public InvocationMatcher getInvocationForStubbing() {
133    	return invocationForStubbing;
134    }
135
136    private RegisteredInvocations createRegisteredInvocations(MockCreationSettings mockSettings) {
137        return mockSettings.isStubOnly()
138          ? new SingleRegisteredInvocation()
139          : new DefaultRegisteredInvocations();
140    }
141}
142