1 package com.android.dx.mockito.inline;
2 
3 import org.mockito.invocation.MockHandler;
4 import org.mockito.mock.MockCreationSettings;
5 
6 import java.util.AbstractMap;
7 import java.util.Collection;
8 import java.util.HashMap;
9 import java.util.HashSet;
10 import java.util.Map;
11 import java.util.Set;
12 
13 /**
14  * A map for mock marker object -> {@link InvocationHandlerAdapter} but
15  * does not use the mock marker object as the key directly.
16  * The problem of not doing so is that the object's real hashCode() and equals() =
17  * methods will be invoked during
18  * {@link InlineStaticMockMaker#createMock(MockCreationSettings, MockHandler)}. This poses a
19  * potential test runtime error depending on the object's hashCode() implementation
20  */
21 class MarkerToHandlerMap implements Map<Object, InvocationHandlerAdapter> {
22 
23     private final Map<MockMarkerKey, InvocationHandlerAdapter> markerToHandler = new HashMap<>();
24 
25     @Override
size()26     public int size() {
27         return markerToHandler.size();
28     }
29 
30     @Override
isEmpty()31     public boolean isEmpty() {
32         return markerToHandler.isEmpty();
33     }
34 
35     @Override
containsKey(Object key)36     public boolean containsKey(Object key) {
37         return markerToHandler.containsKey(new MockMarkerKey(key));
38     }
39 
40     @Override
containsValue(Object value)41     public boolean containsValue(Object value) {
42         return markerToHandler.containsValue(value);
43     }
44 
45     @Override
get(Object key)46     public InvocationHandlerAdapter get(Object key) {
47         return markerToHandler.get(new MockMarkerKey(key));
48     }
49 
50     @Override
put(Object key, InvocationHandlerAdapter value)51     public InvocationHandlerAdapter put(Object key, InvocationHandlerAdapter value) {
52         return markerToHandler.put(new MockMarkerKey(key), value);
53     }
54 
55     @Override
remove(Object key)56     public InvocationHandlerAdapter remove(Object key) {
57         return markerToHandler.remove(new MockMarkerKey(key));
58     }
59 
60     @Override
putAll(Map<?, ? extends InvocationHandlerAdapter> m)61     public void putAll(Map<?, ? extends InvocationHandlerAdapter> m) {
62         for (Entry<?, ? extends InvocationHandlerAdapter> entry : m.entrySet()) {
63             put(new MockMarkerKey(entry.getKey()), entry.getValue());
64         }
65     }
66 
67     @Override
clear()68     public void clear() {
69         markerToHandler.clear();
70     }
71 
72     @Override
keySet()73     public Set<Object> keySet() {
74         Set<Object> set = new HashSet<>(entrySet().size());
75         for (MockMarkerKey key : markerToHandler.keySet()) {
76             set.add(key.mockMarker);
77         }
78         return set;
79     }
80 
81     @Override
values()82     public Collection<InvocationHandlerAdapter> values() {
83         return markerToHandler.values();
84     }
85 
86     @Override
entrySet()87     public Set<Entry<Object, InvocationHandlerAdapter>> entrySet() {
88         Set<Entry<Object, InvocationHandlerAdapter>> set = new HashSet<>(entrySet().size());
89         for (Entry<MockMarkerKey, InvocationHandlerAdapter> entry : markerToHandler.entrySet()) {
90             set.add(new AbstractMap.SimpleImmutableEntry<>(entry.getKey().mockMarker, entry.getValue()));
91         }
92         return set;
93     }
94 
95     private static class MockMarkerKey {
96 
97         private final Object mockMarker;
98 
MockMarkerKey(Object mockMarker)99         public MockMarkerKey(Object mockMarker) {
100             this.mockMarker = mockMarker;
101         }
102 
103         @Override
equals(Object o)104         public boolean equals(Object o) {
105             if (this == o) return true;
106             if (o == null || getClass() != o.getClass()) return false;
107 
108             MockMarkerKey mockMarkerKey = (MockMarkerKey) o;
109 
110             return mockMarker == mockMarkerKey.mockMarker;
111         }
112 
113         @Override
hashCode()114         public int hashCode() {
115             return System.identityHashCode(mockMarker);
116         }
117     }
118 }
119