1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.perfectjpattern.core.structural.adapter;
22
23 import java.lang.reflect.Method;
24 import java.util.*;
25
26 import org.apache.commons.lang.Validate;
27 import org.perfectjpattern.core.api.structural.adapter.IAdaptingStrategy;
28
29
30
31
32
33
34
35
36
37 public
38 class ExactMatchAdaptingStrategy
39 implements IAdaptingStrategy
40 {
41
42
43
44
45
46
47 public void
48 validate(Class<?> aTargetClass, Object anAdaptee, Object anAdapter)
49 throws NoSuchMethodError
50 {
51 Validate.notNull(aTargetClass, "'aTargetClass' must not be null");
52 Validate.notNull(anAdaptee, "'anAdaptee' must not be null");
53 Validate.notNull(anAdapter, "'anAdapter' must not be null");
54
55 Class<?> myAdapteeClass = anAdaptee.getClass();
56
57 Set<String> myTargetMethods = new HashSet<String>();
58
59
60 for (Method myTargetMethod : aTargetClass.getMethods())
61 {
62 String myTargetMethodName = myTargetMethod.getName();
63
64 try
65 {
66
67 Method myAdapteeMethod = myAdapteeClass.getMethod(
68 myTargetMethodName, myTargetMethod.getParameterTypes());
69
70 assert myAdapteeMethod != null :
71 "'myAdapteeMethod' must not be null";
72 }
73 catch (NoSuchMethodException anException)
74 {
75
76 myTargetMethods.add(myTargetMethodName);
77 }
78 }
79
80 if (myTargetMethods.size() > 0)
81 {
82 validate(aTargetClass, anAdapter, myTargetMethods);
83
84
85 if (myTargetMethods.size() > 0)
86 {
87 throw new NoSuchMethodError("Not all target methods " +
88 "are implemented: '" + Arrays.toString(myTargetMethods.
89 toArray()) + "'");
90 }
91 }
92 }
93
94
95
96
97
98 public Method
99 resolve(Class<?> aTargetClass, Object anAdaptee, Object anAdapter,
100 Method aTargetMethod)
101 throws IllegalArgumentException, NoSuchMethodError
102 {
103 Validate.notNull(aTargetClass, "'aTargetClass' must not be null");
104 Validate.notNull(anAdaptee, "'anAdaptee' must not be null");
105 Validate.notNull(anAdapter, "'anAdapter' must not be null");
106 Validate.notNull(aTargetMethod, "'aTargetMethod' must not be null");
107
108 Method myMethod = null;
109 try
110 {
111
112 myMethod = resolve(anAdapter, aTargetMethod);
113 }
114 catch (NoSuchMethodError anException)
115 {
116
117 myMethod = resolve(anAdaptee, aTargetMethod);
118 }
119
120 return myMethod;
121 }
122
123
124
125
126
127
128
129
130
131
132
133
134 protected void
135 validate(Class<?> anInterface, Object anImplementor,
136 Set<String> aTargetMethods)
137 {
138 assert anInterface != null : "'anInterface' must not be null";
139 assert anImplementor != null : "'anImplementor' must not be null";
140 assert aTargetMethods != null : "'aTargetMethods' must not be null";
141
142 for (Method myAdapterMethod : anImplementor.getClass().getMethods())
143 {
144 String myAdapterMethodName = myAdapterMethod.getName();
145 if (aTargetMethods.contains(myAdapterMethodName))
146 {
147 Class<?>[] myParameterTypes = myAdapterMethod.
148 getParameterTypes();
149
150 try
151 {
152 anInterface.getMethod(myAdapterMethodName,
153 myParameterTypes);
154
155 aTargetMethods.remove(myAdapterMethodName);
156 }
157
158 catch (Exception anException)
159
160 {
161
162 }
163 }
164 }
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178
179 protected Method
180 resolve(Object anObject, Method aMethodPrototype, String aMethodName)
181 throws NoSuchMethodError
182 {
183 assert anObject != null : "'anObject' must not be null";
184 assert aMethodPrototype != null : "'aMethod' must not be null";
185
186 Method myMethod = null;
187
188 try
189 {
190 Class<?> myClass = anObject.getClass();
191
192
193 myMethod = myClass.getMethod(aMethodName, aMethodPrototype.
194 getParameterTypes());
195
196 assert myMethod != null : "'myMethod' must not be null";
197
198 return myMethod;
199 }
200 catch (NoSuchMethodException anException)
201 {
202 throw new NoSuchMethodError("Method mismatch between Target " +
203 "and Adaptee/Adapter '" + aMethodPrototype.getName() + "'");
204 }
205 }
206
207
208
209
210
211
212
213
214
215
216
217
218 protected Method
219 resolve(Object anObject, Method aMethodPrototype)
220 throws NoSuchMethodError
221 {
222 String myMethodName = aMethodPrototype.getName();
223
224 return resolve(anObject, aMethodPrototype, myMethodName);
225 }
226 }