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.ArrayList;
21import java.util.Iterator;
22import java.util.List;
23
24import org.easymock.IArgumentMatcher;
25import org.easymock.internal.matchers.Equals;
26
27public class ExpectedInvocation implements Serializable {
28
29    private static final long serialVersionUID = -5554816464613350531L;
30
31    private final Invocation invocation;
32
33    @SuppressWarnings("deprecation")
34    private final org.easymock.ArgumentsMatcher matcher;
35
36    private final List<IArgumentMatcher> matchers;
37
38    public ExpectedInvocation(Invocation invocation,
39            List<IArgumentMatcher> matchers) {
40        this(invocation, matchers, null);
41    }
42
43    private ExpectedInvocation(Invocation invocation,
44            List<IArgumentMatcher> matchers, @SuppressWarnings("deprecation")
45            org.easymock.ArgumentsMatcher matcher) {
46        this.invocation = invocation;
47        this.matcher = matcher;
48        this.matchers = (matcher == null) ? createMissingMatchers(invocation,
49                matchers) : null;
50    }
51
52    private List<IArgumentMatcher> createMissingMatchers(Invocation invocation,
53            List<IArgumentMatcher> matchers) {
54        if (matchers != null) {
55            if (matchers.size() != invocation.getArguments().length) {
56                throw new IllegalStateException(""
57                        + invocation.getArguments().length
58                        + " matchers expected, " + matchers.size()
59                        + " recorded.");
60            }
61            return matchers;
62        }
63        List<IArgumentMatcher> result = new ArrayList<IArgumentMatcher>();
64        for (Object argument : invocation.getArguments()) {
65            result.add(new Equals(argument));
66        }
67        return result;
68    }
69
70    @Override
71    public boolean equals(Object o) {
72        if (o == null || !this.getClass().equals(o.getClass()))
73            return false;
74
75        ExpectedInvocation other = (ExpectedInvocation) o;
76        return this.invocation.equals(other.invocation)
77                && ((this.matcher == null && other.matcher == null) || (this.matcher != null && this.matcher
78                        .equals(other.matcher)))
79                && ((this.matchers == null && other.matchers == null) || (this.matchers != null && this.matchers
80                        .equals(other.matchers)));
81    }
82
83    @Override
84    public int hashCode() {
85        throw new UnsupportedOperationException("hashCode() is not implemented");
86    }
87
88    public boolean matches(Invocation actual) {
89        return matchers != null ? this.invocation.getMock().equals(
90                actual.getMock())
91                && this.invocation.getMethod().equals(actual.getMethod())
92                && matches(actual.getArguments()) : this.invocation.matches(
93                actual, matcher);
94    }
95
96    private boolean matches(Object[] arguments) {
97        if (arguments.length != matchers.size()) {
98            return false;
99        }
100        for (int i = 0; i < arguments.length; i++) {
101            if (!matchers.get(i).matches(arguments[i])) {
102                return false;
103            }
104        }
105        return true;
106    }
107
108    @Override
109    public String toString() {
110        return matchers != null ? myToString() : invocation.toString(matcher);
111    }
112
113    private String myToString() {
114        StringBuffer result = new StringBuffer();
115        result.append(invocation.getMockAndMethodName());
116        result.append("(");
117        for (Iterator<IArgumentMatcher> it = matchers.iterator(); it.hasNext();) {
118            it.next().appendTo(result);
119            if (it.hasNext()) {
120                result.append(", ");
121            }
122        }
123        result.append(")");
124        return result.toString();
125    }
126
127    public Method getMethod() {
128        return invocation.getMethod();
129    }
130
131    public ExpectedInvocation withMatcher(@SuppressWarnings("deprecation")
132    org.easymock.ArgumentsMatcher matcher) {
133        return new ExpectedInvocation(invocation, null, matcher);
134    }
135}
136