f821cf166643cf98690d826c2b84e6baebcb0a3e
[moon.git] /
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.aaa.authn.mdsal.store;
10
11 import java.lang.reflect.InvocationHandler;
12 import java.lang.reflect.Method;
13 import java.lang.reflect.Proxy;
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18
19 public class DataBrokerReadMocker implements InvocationHandler {
20     private Map<Method, List<StubContainer>> stubs = new HashMap<Method, List<StubContainer>>();
21     private Class<?> mokingClass = null;
22
23     @Override
24     public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
25         List<StubContainer> stList = stubs.get(arg1);
26         if (stList != null) {
27             for (StubContainer sc : stList) {
28                 if (sc.fitGeneric(arg2)) {
29                     return sc.returnObject;
30                 }
31             }
32         }
33         return null;
34     }
35
36     public DataBrokerReadMocker(Class<?> cls) {
37         this.mokingClass = cls;
38     }
39
40     public static Object addMock(Class<?> cls) {
41         return Proxy.newProxyInstance(cls.getClassLoader(), new Class[] { cls },
42                 new DataBrokerReadMocker(cls));
43     }
44
45     public static DataBrokerReadMocker getMocker(Object o) {
46         return (DataBrokerReadMocker) Proxy.getInvocationHandler(o);
47     }
48
49     public static Method findMethod(Class<?> cls, String name, Object args[]) {
50         Method methods[] = cls.getMethods();
51         for (Method m : methods) {
52             if (m.getName().equals(name)) {
53                 if ((m.getParameterTypes() == null || m.getParameterTypes().length == 0)
54                         && args == null) {
55                     return m;
56                 }
57                 boolean match = true;
58                 for (int i = 0; i < m.getParameterTypes().length; i++) {
59                     if (!m.getParameterTypes()[i].isAssignableFrom(args[i].getClass())) {
60                         match = false;
61                     }
62                 }
63                 if (match)
64                     return m;
65             }
66         }
67         return null;
68     }
69
70     public void addWhen(String methodName, Object[] args, Object returnThis)
71             throws NoSuchMethodException, SecurityException {
72         Method m = findMethod(this.mokingClass, methodName, args);
73         if (m == null)
74             throw new IllegalArgumentException("Unable to find method");
75         StubContainer sc = new StubContainer(args, returnThis);
76         List<StubContainer> lst = stubs.get(m);
77         if (lst == null) {
78             lst = new ArrayList<>();
79         }
80         lst.add(sc);
81         stubs.put(m, lst);
82     }
83
84     private class StubContainer {
85         private Class<?>[] parameters = null;
86         private Class<?>[] generics = null;
87         private Object args[] = null;
88         private Object returnObject;
89
90         public StubContainer(Object[] _args, Object ret) {
91             this.args = _args;
92             this.returnObject = ret;
93         }
94
95         public boolean fitGeneric(Object _args[]) {
96             if (args == null && _args != null)
97                 return false;
98             if (args != null && _args == null)
99                 return false;
100             if (args == null && _args == null)
101                 return true;
102             if (args.length != _args.length)
103                 return false;
104             for (int i = 0; i < args.length; i++) {
105                 if (!args[i].equals(_args[i])) {
106                     return false;
107                 }
108             }
109             return true;
110         }
111     }
112 }