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;
19
20import org.easymock.IAnswer;
21import org.easymock.IExpectationSetters;
22import org.easymock.IMocksControl;
23
24public class MocksControl implements IMocksControl, IExpectationSetters<Object>, Serializable {
25
26    private static final long serialVersionUID = 443604921336702014L;
27
28    private IMocksControlState state;
29
30    private IMocksBehavior behavior;
31
32    public enum MockType {
33        NICE, DEFAULT, STRICT
34    }
35
36    private MockType type;
37
38    public MocksControl(MockType type) {
39        this.type = type;
40        reset();
41    }
42
43    public IMocksControlState getState() {
44        return state;
45    }
46
47    public <T> T createMock(Class<T> toMock) {
48        try {
49            state.assertRecordState();
50            IProxyFactory<T> proxyFactory = createProxyFactory(toMock);
51            return proxyFactory.createProxy(toMock, new ObjectMethodsFilter(
52                    toMock, new MockInvocationHandler(this), null));
53        } catch (RuntimeExceptionWrapper e) {
54            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
55        }
56    }
57
58    public <T> T createMock(String name, Class<T> toMock) {
59        try {
60            state.assertRecordState();
61            IProxyFactory<T> proxyFactory = createProxyFactory(toMock);
62            return proxyFactory.createProxy(toMock, new ObjectMethodsFilter(
63                    toMock, new MockInvocationHandler(this), name));
64        } catch (RuntimeExceptionWrapper e) {
65            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
66        }
67    }
68
69    protected <T> IProxyFactory<T> createProxyFactory(Class<T> toMock) {
70        return new JavaProxyFactory<T>();
71    }
72
73    public final void reset() {
74        behavior = new MocksBehavior(type == MockType.NICE);
75        behavior.checkOrder(type == MockType.STRICT);
76        state = new RecordState(behavior);
77        LastControl.reportLastControl(null);
78    }
79
80    public void resetToNice() {
81        type = MockType.NICE;
82        reset();
83    }
84
85    public void resetToDefault() {
86        type = MockType.DEFAULT;
87        reset();
88    }
89
90    public void resetToStrict() {
91        type = MockType.STRICT;
92        reset();
93    }
94
95    public void replay() {
96        try {
97            state.replay();
98            state = new ReplayState(behavior);
99            LastControl.reportLastControl(null);
100        } catch (RuntimeExceptionWrapper e) {
101            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
102        }
103    }
104
105    public void verify() {
106        try {
107            state.verify();
108        } catch (RuntimeExceptionWrapper e) {
109            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
110        } catch (AssertionErrorWrapper e) {
111            throw (AssertionError) e.getAssertionError().fillInStackTrace();
112        }
113    }
114
115    public void checkOrder(boolean value) {
116        try {
117            state.checkOrder(value);
118        } catch (RuntimeExceptionWrapper e) {
119            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
120        }
121    }
122
123    public void makeThreadSafe(boolean threadSafe) {
124        try {
125            state.makeThreadSafe(threadSafe);
126        } catch (RuntimeExceptionWrapper e) {
127            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
128        }
129    }
130
131    public void checkIsUsedInOneThread(boolean shouldBeUsedInOneThread) {
132        try {
133            state.checkIsUsedInOneThread(shouldBeUsedInOneThread);
134        } catch (RuntimeExceptionWrapper e) {
135            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
136        }
137    }
138
139    // methods from IBehaviorSetters
140
141    public IExpectationSetters<Object> andReturn(Object value) {
142        try {
143            state.andReturn(value);
144            return this;
145        } catch (RuntimeExceptionWrapper e) {
146            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
147        }
148    }
149
150    public IExpectationSetters<Object> andThrow(Throwable throwable) {
151        try {
152            state.andThrow(throwable);
153            return this;
154        } catch (RuntimeExceptionWrapper e) {
155            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
156        }
157    }
158
159    public IExpectationSetters<Object> andAnswer(IAnswer<? extends Object> answer) {
160        try {
161            state.andAnswer(answer);
162            return this;
163        } catch (RuntimeExceptionWrapper e) {
164            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
165        }
166    }
167
168    public IExpectationSetters<Object> andDelegateTo(Object answer) {
169        try {
170            state.andDelegateTo(answer);
171            return this;
172        } catch (RuntimeExceptionWrapper e) {
173            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
174        }
175    }
176
177    public void andStubReturn(Object value) {
178        try {
179            state.andStubReturn(value);
180        } catch (RuntimeExceptionWrapper e) {
181            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
182        }
183    }
184
185    public void andStubThrow(Throwable throwable) {
186        try {
187            state.andStubThrow(throwable);
188        } catch (RuntimeExceptionWrapper e) {
189            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
190        }
191    }
192
193    public void andStubAnswer(IAnswer<? extends Object> answer) {
194        try {
195            state.andStubAnswer(answer);
196        } catch (RuntimeExceptionWrapper e) {
197            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
198        }
199    }
200
201
202    public void andStubDelegateTo(Object delegateTo) {
203        try {
204            state.andStubDelegateTo(delegateTo);
205        } catch (RuntimeExceptionWrapper e) {
206            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
207        }
208    }
209
210    public void asStub() {
211        try {
212            state.asStub();
213        } catch (RuntimeExceptionWrapper e) {
214            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
215        }
216    }
217
218    public IExpectationSetters<Object> times(int times) {
219        try {
220            state.times(new Range(times));
221            return this;
222        } catch (RuntimeExceptionWrapper e) {
223            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
224        }
225    }
226
227    public IExpectationSetters<Object> times(int min, int max) {
228        try {
229            state.times(new Range(min, max));
230            return this;
231        } catch (RuntimeExceptionWrapper e) {
232            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
233        }
234    }
235
236    public IExpectationSetters<Object> once() {
237        try {
238            state.times(ONCE);
239            return this;
240        } catch (RuntimeExceptionWrapper e) {
241            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
242        }
243    }
244
245    public IExpectationSetters<Object> atLeastOnce() {
246        try {
247            state.times(AT_LEAST_ONCE);
248            return this;
249        } catch (RuntimeExceptionWrapper e) {
250            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
251        }
252    }
253
254    public IExpectationSetters<Object> anyTimes() {
255        try {
256            state.times(ZERO_OR_MORE);
257            return this;
258        } catch (RuntimeExceptionWrapper e) {
259            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
260        }
261    }
262
263    /**
264     * Exactly one call.
265     */
266    public static final Range ONCE = new Range(1);
267
268    /**
269     * One or more calls.
270     */
271    public static final Range AT_LEAST_ONCE = new Range(1, Integer.MAX_VALUE);
272
273    /**
274     * Zero or more calls.
275     */
276    public static final Range ZERO_OR_MORE = new Range(0, Integer.MAX_VALUE);
277
278    @SuppressWarnings("deprecation")
279    public void setLegacyDefaultMatcher(org.easymock.ArgumentsMatcher matcher) {
280        try {
281            state.setDefaultMatcher(matcher);
282        } catch (RuntimeExceptionWrapper e) {
283            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
284        }
285    }
286
287    @SuppressWarnings("deprecation")
288    public void setLegacyMatcher(org.easymock.ArgumentsMatcher matcher) {
289        try {
290            state.setMatcher(null, matcher);
291        } catch (RuntimeExceptionWrapper e) {
292            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
293        }
294    }
295
296    public void setLegacyDefaultReturnValue(Object value) {
297        try {
298            state.setDefaultReturnValue(value);
299        } catch (RuntimeExceptionWrapper e) {
300            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
301        }
302    }
303
304    public void setLegacyDefaultVoidCallable() {
305        state.setDefaultVoidCallable();
306    }
307
308    public void setLegacyDefaultThrowable(Throwable throwable) {
309        try {
310            state.setDefaultThrowable(throwable);
311        } catch (RuntimeExceptionWrapper e) {
312            throw (RuntimeException) e.getRuntimeException().fillInStackTrace();
313        }
314    }
315}
316