1/*
2 * Copyright (c) 2016 Mockito contributors
3 * This program is made available under the terms of the MIT License.
4 */
5package org.mockito.internal.stubbing.answers;
6
7import org.mockito.invocation.InvocationOnMock;
8import org.mockito.stubbing.Answer;
9import org.mockito.stubbing.Answer1;
10import org.mockito.stubbing.Answer2;
11import org.mockito.stubbing.Answer3;
12import org.mockito.stubbing.Answer4;
13import org.mockito.stubbing.Answer5;
14import org.mockito.stubbing.VoidAnswer1;
15import org.mockito.stubbing.VoidAnswer2;
16import org.mockito.stubbing.VoidAnswer3;
17import org.mockito.stubbing.VoidAnswer4;
18import org.mockito.stubbing.VoidAnswer5;
19
20/**
21 * Functional interfaces to make it easy to implement answers in Java 8
22 *
23 * @since 2.1.0
24 */
25public class AnswerFunctionalInterfaces {
26	/**
27     * Hide constructor to avoid instantiation of class with only static methods
28     */
29    private AnswerFunctionalInterfaces() {
30    }
31
32    /**
33     * Construct an answer from a two parameter answer interface
34     * @param answer answer interface
35     * @param <T> return type
36     * @param <A> input parameter 1 type
37     * @return a new answer object
38     */
39    public static <T, A> Answer<T> toAnswer(final Answer1<T, A> answer) {
40        return new Answer<T>() {
41            @SuppressWarnings("unchecked")
42            public T answer(InvocationOnMock invocation) throws Throwable {
43                return answer.answer((A)invocation.getArgument(0));
44            }
45        };
46    }
47
48    /**
49     * Construct an answer from a two parameter answer interface
50     * @param answer answer interface
51     * @param <A> input parameter 1 type
52     * @return a new answer object
53     */
54    public static <A> Answer<Void> toAnswer(final VoidAnswer1<A> answer) {
55        return new Answer<Void>() {
56            @SuppressWarnings("unchecked")
57            public Void answer(InvocationOnMock invocation) throws Throwable {
58                answer.answer((A)invocation.getArgument(0));
59                return null;
60            }
61        };
62    }
63
64    /**
65     * Construct an answer from a two parameter answer interface
66     * @param answer answer interface
67     * @param <T> return type
68     * @param <A> input parameter 1 type
69     * @param <B> input parameter 2 type
70     * @return a new answer object
71     */
72    public static <T, A, B> Answer<T> toAnswer(final Answer2<T, A, B> answer) {
73        return new Answer<T>() {
74            @SuppressWarnings("unchecked")
75            public T answer(InvocationOnMock invocation) throws Throwable {
76                return answer.answer(
77                        (A)invocation.getArgument(0),
78                        (B)invocation.getArgument(1));
79            }
80        };
81    }
82
83    /**
84     * Construct an answer from a two parameter answer interface
85     * @param answer answer interface
86     * @param <A> input parameter 1 type
87     * @param <B> input parameter 2 type
88     * @return a new answer object
89     */
90    public static <A, B> Answer<Void> toAnswer(final VoidAnswer2<A, B> answer) {
91        return new Answer<Void>() {
92            @SuppressWarnings("unchecked")
93            public Void answer(InvocationOnMock invocation) throws Throwable {
94                answer.answer(
95                        (A)invocation.getArgument(0),
96                        (B)invocation.getArgument(1));
97                return null;
98            }
99        };
100    }
101
102    /**
103     * Construct an answer from a three parameter answer interface
104     * @param answer answer interface
105     * @param <T> return type
106     * @param <A> input parameter 1 type
107     * @param <B> input parameter 2 type
108     * @param <C> input parameter 3 type
109     * @return a new answer object
110     */
111    public static <T, A, B, C> Answer<T> toAnswer(final Answer3<T, A, B, C> answer) {
112        return new Answer<T>() {
113            @SuppressWarnings("unchecked")
114            public T answer(InvocationOnMock invocation) throws Throwable {
115                return answer.answer(
116                        (A)invocation.getArgument(0),
117                        (B)invocation.getArgument(1),
118                        (C)invocation.getArgument(2));
119            }
120        };
121    }
122
123    /**
124     * Construct an answer from a three parameter answer interface
125     * @param answer answer interface
126     * @param <A> input parameter 1 type
127     * @param <B> input parameter 2 type
128     * @param <C> input parameter 3 type
129     * @return a new answer object
130     */
131    public static <A, B, C> Answer<Void> toAnswer(final VoidAnswer3<A, B, C> answer) {
132        return new Answer<Void>() {
133            @SuppressWarnings("unchecked")
134            public Void answer(InvocationOnMock invocation) throws Throwable {
135                answer.answer(
136                        (A)invocation.getArgument(0),
137                        (B)invocation.getArgument(1),
138                        (C)invocation.getArgument(2));
139                return null;
140            }
141        };
142    }
143
144    /**
145     * Construct an answer from a four parameter answer interface
146     * @param answer answer interface
147     * @param <T> return type
148     * @param <A> input parameter 1 type
149     * @param <B> input parameter 2 type
150     * @param <C> input parameter 3 type
151     * @param <D> input parameter 4 type
152     * @return a new answer object
153     */
154    public static <T, A, B, C, D> Answer<T> toAnswer(final Answer4<T, A, B, C, D> answer) {
155        return new Answer<T>() {
156            @SuppressWarnings("unchecked")
157            public T answer(InvocationOnMock invocation) throws Throwable {
158                return answer.answer(
159                        (A)invocation.getArgument(0),
160                        (B)invocation.getArgument(1),
161                        (C)invocation.getArgument(2),
162                        (D)invocation.getArgument(3));
163            }
164        };
165    }
166
167    /**
168     * Construct an answer from a four parameter answer interface
169     * @param answer answer interface
170     * @param <A> input parameter 1 type
171     * @param <B> input parameter 2 type
172     * @param <C> input parameter 3 type
173     * @param <D> input parameter 4 type
174     * @return a new answer object
175     */
176    public static <A, B, C, D> Answer<Void> toAnswer(final VoidAnswer4<A, B, C, D> answer) {
177        return new Answer<Void>() {
178            @SuppressWarnings("unchecked")
179            public Void answer(InvocationOnMock invocation) throws Throwable {
180                answer.answer(
181                        (A)invocation.getArgument(0),
182                        (B)invocation.getArgument(1),
183                        (C)invocation.getArgument(2),
184                        (D)invocation.getArgument(3));
185                return null;
186            }
187        };
188    }
189
190    /**
191     * Construct an answer from a five parameter answer interface
192     * @param answer answer interface
193     * @param <T> return type
194     * @param <A> input parameter 1 type
195     * @param <B> input parameter 2 type
196     * @param <C> input parameter 3 type
197     * @param <D> input parameter 4 type
198     * @param <E> input parameter 5 type
199     * @return a new answer object
200     */
201    public static <T, A, B, C, D, E> Answer<T> toAnswer(final Answer5<T, A, B, C, D, E> answer) {
202        return new Answer<T>() {
203            @SuppressWarnings("unchecked")
204            public T answer(InvocationOnMock invocation) throws Throwable {
205                return answer.answer(
206                        (A)invocation.getArgument(0),
207                        (B)invocation.getArgument(1),
208                        (C)invocation.getArgument(2),
209                        (D)invocation.getArgument(3),
210                        (E)invocation.getArgument(4));
211            }
212        };
213    }
214
215    /**
216     * Construct an answer from a five parameter answer interface
217     * @param answer answer interface
218     * @param <A> input parameter 1 type
219     * @param <B> input parameter 2 type
220     * @param <C> input parameter 3 type
221     * @param <D> input parameter 4 type
222     * @param <E> input parameter 5 type
223     * @return a new answer object
224     */
225    public static <A, B, C, D, E> Answer<Void> toAnswer(final VoidAnswer5<A, B, C, D, E> answer) {
226        return new Answer<Void>() {
227            @SuppressWarnings("unchecked")
228            public Void answer(InvocationOnMock invocation) throws Throwable {
229                answer.answer(
230                        (A)invocation.getArgument(0),
231                        (B)invocation.getArgument(1),
232                        (C)invocation.getArgument(2),
233                        (D)invocation.getArgument(3),
234                        (E)invocation.getArgument(4));
235                return null;
236            }
237        };
238    }
239}
240