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.behavioral.visitor; |
22 |
|
|
23 |
|
import java.lang.reflect.*; |
24 |
|
import java.util.*; |
25 |
|
|
26 |
|
import org.apache.commons.lang.*; |
27 |
|
import org.perfectjpattern.core.api.behavioral.visitor.*; |
28 |
|
import org.perfectjpattern.core.extras.delegate.*; |
29 |
|
|
30 |
|
|
31 |
|
|
32 |
|
|
33 |
|
|
34 |
|
|
35 |
|
@see |
36 |
|
|
37 |
|
@param |
38 |
|
|
39 |
|
@author |
40 |
|
@version |
41 |
|
|
42 |
|
public abstract |
|
|
| 95.1% |
Uncovered Elements: 2 (41) |
Complexity: 13 |
Complexity Density: 0.46 |
|
43 |
|
class AbstractVisitor<E> |
44 |
|
implements IVisitor<E> |
45 |
|
{ |
46 |
|
|
47 |
|
|
48 |
|
|
49 |
|
|
50 |
|
@inheritDoc |
51 |
|
|
|
|
| 87.5% |
Uncovered Elements: 2 (16) |
Complexity: 4 |
Complexity Density: 0.4 |
|
52 |
28
|
@SuppressWarnings("unchecked")... |
53 |
|
public final void |
54 |
|
visit(E anElement) |
55 |
|
{ |
56 |
28
|
Validate.notNull(anElement, "'anElement' must not be null"); |
57 |
|
|
58 |
28
|
String myElementClassName = anElement.getClass().getName(); |
59 |
|
|
60 |
|
|
61 |
28
|
if (!theLookup.containsKey(myElementClassName)) |
62 |
|
{ |
63 |
|
|
64 |
12
|
Class myElementType = anElement.getClass(); |
65 |
12
|
Class myVisitorType = this.getClass(); |
66 |
|
|
67 |
12
|
Method myMethod = findVisitorMethod(myElementType, |
68 |
|
myVisitorType, theDelegator); |
69 |
|
|
70 |
|
|
71 |
12
|
if (myMethod != null) |
72 |
|
{ |
73 |
12
|
theLookup.put(myElementClassName, theDelegator.build( |
74 |
|
this, myMethod.getName())); |
75 |
|
} |
76 |
|
} |
77 |
|
|
78 |
|
|
79 |
28
|
if (theLookup.containsKey(myElementClassName)) |
80 |
|
{ |
81 |
|
|
82 |
28
|
theLookup.get(myElementClassName).visit(anElement); |
83 |
|
} |
84 |
|
} |
85 |
|
|
86 |
|
|
87 |
|
|
88 |
|
|
89 |
|
|
90 |
|
|
91 |
|
|
92 |
|
@param |
93 |
|
|
94 |
|
@param |
95 |
|
@param |
96 |
|
@throws |
97 |
|
@throws |
98 |
|
@throws |
99 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (13) |
Complexity: 3 |
Complexity Density: 0.27 |
|
100 |
23
|
@SuppressWarnings("unchecked")... |
101 |
|
public static <E> void |
102 |
|
reusableVisit(IVisitor<E> aVisitor, E... anElements) |
103 |
|
throws IllegalArgumentException |
104 |
|
{ |
105 |
23
|
Validate.notNull(aVisitor, "'aVisitor' must not be null"); |
106 |
23
|
Validate.notNull(anElements, "'anElements' must not be null"); |
107 |
23
|
Validate.notEmpty(anElements, "'anElements' must not be empty."); |
108 |
|
|
109 |
23
|
for (E myElement : anElements) |
110 |
|
{ |
111 |
|
|
112 |
31
|
Class myElementType = myElement.getClass(); |
113 |
31
|
Class myVisitorType = aVisitor.getClass(); |
114 |
|
|
115 |
31
|
VisitorDelegator myDelegator = new VisitorDelegator(IVisitor.class); |
116 |
|
|
117 |
31
|
Method myMethod = findVisitorMethod(myElementType, myVisitorType, |
118 |
|
myDelegator); |
119 |
|
|
120 |
|
|
121 |
31
|
if (myMethod != null) |
122 |
|
{ |
123 |
23
|
IVisitor<E> myRealVisitor = |
124 |
|
(IVisitor) myDelegator.build(aVisitor, myMethod.getName()); |
125 |
|
|
126 |
|
|
127 |
23
|
myRealVisitor.visit(myElement); |
128 |
|
} |
129 |
|
} |
130 |
|
} |
131 |
|
|
132 |
|
|
133 |
|
|
134 |
|
|
135 |
|
|
136 |
|
|
137 |
|
|
138 |
|
@SuppressWarnings("unchecked") |
139 |
|
private static |
|
|
| 88.9% |
Uncovered Elements: 2 (18) |
Complexity: 6 |
Complexity Density: 0.6 |
|
140 |
|
class VisitorDelegator<E> |
141 |
|
extends Delegator<IVisitor<E>> |
142 |
|
{ |
143 |
|
|
144 |
|
|
145 |
|
|
146 |
|
|
147 |
|
|
148 |
|
@param |
149 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
150 |
44
|
public ... |
151 |
|
VisitorDelegator(Class<IVisitor<E>> aClass) |
152 |
|
{ |
153 |
44
|
super(aClass); |
154 |
|
} |
155 |
|
|
156 |
|
|
157 |
|
|
158 |
|
@inheritDoc |
159 |
|
|
|
|
| 81.8% |
Uncovered Elements: 2 (11) |
Complexity: 3 |
Complexity Density: 0.43 |
|
160 |
35
|
@Override... |
161 |
|
protected boolean |
162 |
|
isSuitableMethod(Method aTestMethod, Class aReturnClass, |
163 |
|
Class... anArguments) |
164 |
|
{ |
165 |
35
|
Class[] myMethodArguments = aTestMethod.getParameterTypes(); |
166 |
70
|
for (int i = 0; i < myMethodArguments.length; i++) |
167 |
|
{ |
168 |
35
|
Class myArgument = myMethodArguments[i]; |
169 |
|
|
170 |
35
|
if (!anArguments[i].isAssignableFrom(myArgument)) |
171 |
|
{ |
172 |
0
|
return false; |
173 |
|
} |
174 |
|
|
175 |
|
} |
176 |
|
|
177 |
35
|
isValidReturn(aTestMethod, aReturnClass); |
178 |
|
|
179 |
35
|
return true; |
180 |
|
} |
181 |
|
|
182 |
|
|
183 |
|
|
184 |
|
@inheritDoc |
185 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
186 |
294
|
@Override... |
187 |
|
protected boolean |
188 |
|
isValidReturn(Method aTestMethod, Class aReturnClass) |
189 |
|
{ |
190 |
294
|
return (aReturnClass == null |
191 |
|
|| aTestMethod.getReturnType() == aReturnClass |
192 |
|
|| aTestMethod.getReturnType().equals(aReturnClass) |
193 |
|
|| aTestMethod.getReturnType().isAssignableFrom(aReturnClass)); |
194 |
|
} |
195 |
|
|
196 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
197 |
78
|
@Override... |
198 |
|
public Class |
199 |
|
getReturn() |
200 |
|
{ |
201 |
78
|
return super.getReturn(); |
202 |
|
} |
203 |
|
} |
204 |
|
|
205 |
|
|
206 |
|
|
207 |
|
|
208 |
|
|
209 |
|
|
210 |
|
|
211 |
|
|
212 |
|
@param |
213 |
|
@param |
214 |
|
@param |
215 |
|
@return |
216 |
|
|
217 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (9) |
Complexity: 6 |
Complexity Density: 0.86 |
|
218 |
43
|
@SuppressWarnings("unchecked")... |
219 |
|
private static Method |
220 |
|
findVisitorMethod(Class anElementType, Class aVisitorType, |
221 |
|
VisitorDelegator aDelegator) |
222 |
|
{ |
223 |
43
|
Class myReturnClass = aDelegator.getReturn(); |
224 |
43
|
Method myResult = null; |
225 |
43
|
for (Method myMethod : aVisitorType.getMethods()) |
226 |
|
{ |
227 |
259
|
if (aDelegator.isValidReturn(myMethod, myReturnClass) |
228 |
|
&& Modifier.isPublic(myMethod.getModifiers()) |
229 |
|
&& myMethod.getParameterTypes().length == 1 |
230 |
|
&& myMethod.getParameterTypes()[0].equals(anElementType)) |
231 |
|
{ |
232 |
35
|
myResult = myMethod; |
233 |
35
|
break; |
234 |
|
} |
235 |
|
} |
236 |
|
|
237 |
43
|
return myResult; |
238 |
|
} |
239 |
|
|
240 |
|
|
241 |
|
|
242 |
|
|
243 |
|
|
244 |
|
|
245 |
|
|
246 |
|
|
247 |
|
private final Map<String, IVisitor<E>> theLookup = new HashMap<String, |
248 |
|
IVisitor<E>>(); |
249 |
|
|
250 |
|
|
251 |
|
|
252 |
|
|
253 |
|
|
254 |
|
@SuppressWarnings("unchecked") |
255 |
|
private final VisitorDelegator<E> theDelegator = new VisitorDelegator( |
256 |
|
IVisitor.class); |
257 |
|
} |