1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.callbackparams.internal;
18
19 import java.lang.reflect.Method;
20 import java.lang.reflect.Type;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30
31
32
33
34
35
36
37 class NoargMethodProxyMap {
38
39 private final Set
40 private final Map
41 private final Map
42 private final Map
43 private final Set
44
45
46
47
48 NoargMethodProxyMap(Class template) {
49 for (; Object.class != template ; template = template.getSuperclass()) {
50 final Method[] declaredMethods = template.getDeclaredMethods();
51 for (int i = 0 ; i < declaredMethods.length ; ++i) {
52 final Method m = declaredMethods[i];
53 if (0 == m.getParameterTypes().length) {
54 originalMethodNames.add(m.getName());
55 }
56 }
57 }
58 }
59
60 private String newNoargMethodName(String callbackMethodName) {
61 StringBuffer sb = (StringBuffer)
62 methodNameBuilders.get(callbackMethodName);
63 if (null == sb) {
64 String suffixBase = "$callbackProxy";
65 sb = new StringBuffer(
66 callbackMethodName.length() + suffixBase.length() + 4)
67 .append(callbackMethodName)
68 .append(suffixBase);
69 methodNameBuilders.put(callbackMethodName, sb);
70 String candidate = sb.toString();
71 sb.append("_1");
72 if (false == originalMethodNames.contains(candidate)) {
73 return candidate;
74 }
75 }
76 String candidate;
77 do {
78 candidate = increase(sb);
79 } while (originalMethodNames.contains(candidate));
80 return candidate;
81 }
82
83 private String increase(StringBuffer sb) {
84 for (int i = sb.length() - 1 ; true ; --i) {
85 char loopChar = sb.charAt(i);
86 switch (loopChar) {
87 case '9':
88 sb.setCharAt(i, '0');
89 continue;
90 case '_':
91 return sb.insert(++i, '1').toString();
92 default:
93 sb.setCharAt(i, ++loopChar);
94 return sb.toString();
95 }
96 }
97 }
98
99
100
101
102
103 String addMethodToBeProxied(Method m) {
104 declaringClassNames.add(m.getDeclaringClass().getName());
105
106 String noargProxyMethodName = findProxyNameOfOverriddenMethod(m);
107 if (null == noargProxyMethodName) {
108 noargProxyMethodName = newNoargMethodName(m.getName());
109 ((List)noArgMethodNames.get(m.getName())).add(noargProxyMethodName);
110 proxiedMethods.put(noargProxyMethodName, new ArrayList(4));
111 }
112 ((List)proxiedMethods.get(noargProxyMethodName)).add(m);
113 return noargProxyMethodName;
114 }
115
116 private String findProxyNameOfOverriddenMethod(Method m) {
117 List
118 (List) noArgMethodNames.get(m.getName());
119 if (null == existingProxyNames) {
120 noArgMethodNames.put(m.getName(), new ArrayList());
121 return null;
122
123 } else {
124 final Type[] parameterTypes = m.getGenericParameterTypes();
125 for (Iterator iterNames = existingProxyNames.iterator()
126 ; iterNames.hasNext() ;) {
127 final String eachName = (String) iterNames.next();
128 for (Iterator iterOo = ((List)proxiedMethods.get(eachName))
129 .iterator() ; iterOo.hasNext() ;) {
130 final Method oo = (Method) iterOo.next();
131 if (oo.getDeclaringClass()
132 .isAssignableFrom(m.getDeclaringClass())
133 || m.getDeclaringClass().isAssignableFrom(
134 oo.getDeclaringClass())) {
135 if (Arrays.equals(parameterTypes,
136 oo.getGenericParameterTypes())){
137 return eachName;
138 }
139 }
140 }
141 }
142 return null;
143 }
144 }
145
146 Map
147 if (false == declaringClassNames.contains(className)) {
148 return Collections.EMPTY_MAP;
149 }
150
151 Map
152 for (Iterator iterEntr = proxiedMethods.entrySet().iterator()
153 ; iterEntr.hasNext() ;) {
154 final Map.Entry
155 (Map.Entry) iterEntr.next();
156 Iterator iterProxiedMethods =
157 ((List)eachProxyEntry.getValue()).iterator();
158 while (iterProxiedMethods.hasNext()) {
159 final Method proxiedMethod = (Method) iterProxiedMethods.next();
160 if (className.equals(proxiedMethod.getDeclaringClass().getName())) {
161 methodsForClass.put(eachProxyEntry.getKey(), proxiedMethod);
162 }
163 }
164 }
165 return methodsForClass;
166 }
167
168 String getNameOfProxiedMethod(String proxyMethodName) {
169 List
170 return null == methods || methods.isEmpty() ? null
171 : ((Method)methods.get(0)).getName();
172 }
173 }