1/*
2 * Copyright 2001-2009 OFFIS, Tammo Freese
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.easymock.internal;
17
18import java.io.Serializable;
19import java.lang.reflect.Method;
20import java.util.concurrent.locks.ReentrantLock;
21
22import org.easymock.IAnswer;
23
24public class ReplayState implements IMocksControlState, Serializable {
25
26    private static final long serialVersionUID = 6314142602251047572L;
27
28    private final IMocksBehavior behavior;
29
30    private final ReentrantLock lock = new ReentrantLock();
31
32    public ReplayState(IMocksBehavior behavior) {
33        this.behavior = behavior;
34    }
35
36    public Object invoke(Invocation invocation) throws Throwable {
37
38        behavior.checkThreadSafety();
39
40        if (behavior.isThreadSafe()) {
41            // If thread safe, synchronize the mock
42            lock.lock();
43            try {
44                return invokeInner(invocation);
45            }
46            finally {
47                lock.unlock();
48            }
49        }
50
51        return invokeInner(invocation);
52    }
53
54    private Object invokeInner(Invocation invocation) throws Throwable {
55        LastControl.pushCurrentInvocation(invocation);
56        try {
57            Result result = behavior.addActual(invocation);
58            try {
59                return result.answer();
60            } catch (Throwable t) {
61                if (result.shouldFillInStackTrace()) {
62                    throw new ThrowableWrapper(t);
63                }
64                throw t;
65            }
66        } finally {
67            LastControl.popCurrentInvocation();
68        }
69    }
70
71    public void verify() {
72        behavior.verify();
73    }
74
75    public void replay() {
76        throwWrappedIllegalStateException();
77    }
78
79    public void callback(Runnable runnable) {
80        throwWrappedIllegalStateException();
81    }
82
83    public void checkOrder(boolean value) {
84        throwWrappedIllegalStateException();
85    }
86
87    public void makeThreadSafe(boolean threadSafe) {
88        throwWrappedIllegalStateException();
89    }
90
91    public void checkIsUsedInOneThread(boolean shouldBeUsedInOneThread) {
92        throwWrappedIllegalStateException();
93    }
94
95    public void andReturn(Object value) {
96        throwWrappedIllegalStateException();
97    }
98
99    public void andThrow(Throwable throwable) {
100        throwWrappedIllegalStateException();
101    }
102
103    public void andAnswer(IAnswer<?> answer) {
104        throwWrappedIllegalStateException();
105    }
106
107    public void andDelegateTo(Object answer) {
108        throwWrappedIllegalStateException();
109    }
110
111    public void andStubReturn(Object value) {
112        throwWrappedIllegalStateException();
113    }
114
115    public void andStubThrow(Throwable throwable) {
116        throwWrappedIllegalStateException();
117    }
118
119    public void andStubAnswer(IAnswer<?> answer) {
120        throwWrappedIllegalStateException();
121    }
122
123    public void andStubDelegateTo(Object delegateTo) {
124        throwWrappedIllegalStateException();
125    }
126
127    public void asStub() {
128        throwWrappedIllegalStateException();
129    }
130
131    public void times(Range range) {
132        throwWrappedIllegalStateException();
133    }
134
135    @SuppressWarnings("deprecation")
136    public void setMatcher(Method method, org.easymock.ArgumentsMatcher matcher) {
137        throwWrappedIllegalStateException();
138    }
139
140    @SuppressWarnings("deprecation")
141    public void setDefaultMatcher(org.easymock.ArgumentsMatcher matcher) {
142        throwWrappedIllegalStateException();
143    }
144
145    public void setDefaultReturnValue(Object value) {
146        throwWrappedIllegalStateException();
147    }
148
149    public void setDefaultThrowable(Throwable throwable) {
150        throwWrappedIllegalStateException();
151    }
152
153    public void setDefaultVoidCallable() {
154        throwWrappedIllegalStateException();
155    }
156
157    private void throwWrappedIllegalStateException() {
158        throw new RuntimeExceptionWrapper(new IllegalStateException(
159                "This method must not be called in replay state."));
160    }
161
162    public void assertRecordState() {
163        throwWrappedIllegalStateException();
164    }
165}
166