Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
BenchmarkMethod |
|
| 7.357142857142857;7.357 |
1 | /** | |
2 | * Copyright (c) 2012, University of Konstanz, Distributed Systems Group | |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions are met: | |
7 | * * Redistributions of source code must retain the above copyright | |
8 | * notice, this list of conditions and the following disclaimer. | |
9 | * * Redistributions in binary form must reproduce the above copyright | |
10 | * notice, this list of conditions and the following disclaimer in the | |
11 | * documentation and/or other materials provided with the distribution. | |
12 | * * Neither the name of the University of Konstanz nor the | |
13 | * names of its contributors may be used to endorse or promote products | |
14 | * derived from this software without specific prior written permission. | |
15 | * | |
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
19 | * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY | |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 | */ | |
27 | package org.perfidix.element; | |
28 | ||
29 | import java.lang.annotation.Annotation; | |
30 | import java.lang.reflect.Method; | |
31 | import java.lang.reflect.Modifier; | |
32 | import java.util.ArrayList; | |
33 | import java.util.List; | |
34 | ||
35 | import org.perfidix.annotation.AfterBenchClass; | |
36 | import org.perfidix.annotation.AfterEachRun; | |
37 | import org.perfidix.annotation.AfterLastRun; | |
38 | import org.perfidix.annotation.BeforeBenchClass; | |
39 | import org.perfidix.annotation.BeforeEachRun; | |
40 | import org.perfidix.annotation.BeforeFirstRun; | |
41 | import org.perfidix.annotation.Bench; | |
42 | import org.perfidix.annotation.BenchClass; | |
43 | import org.perfidix.annotation.SkipBench; | |
44 | import org.perfidix.exceptions.PerfidixMethodCheckException; | |
45 | ||
46 | /** | |
47 | * Class to mark one method which are possible benchmarkable. The method hold | |
48 | * helping methods and additional functionality for benchmarkable methods like | |
49 | * returning possible {@link BeforeBenchClass}, {@link BeforeFirstRun}, {@link BeforeEachRun}, | |
50 | * {@link AfterEachRun}, {@link AfterLastRun} and {@link AfterBenchClass} annotated related methods. | |
51 | * | |
52 | * @see AfterBenchClass | |
53 | * @see AfterLastRun | |
54 | * @see AfterEachRun | |
55 | * @see BeforeEachRun | |
56 | * @see BeforeFirstRun | |
57 | * @see BeforeBenchClass | |
58 | * @author Sebastian Graf, University of Konstanz | |
59 | */ | |
60 | public final class BenchmarkMethod { | |
61 | ||
62 | /** | |
63 | * Method to be benched. | |
64 | */ | |
65 | private transient final Method methodToBench; | |
66 | ||
67 | /** | |
68 | * Constructor, with a definite method to bench. The method has to be | |
69 | * checked with {@link BenchmarkMethod#isBenchmarkable(Method)} first, | |
70 | * otherwise an IllegalArgumentException could arise. | |
71 | * | |
72 | * @param paramMethod | |
73 | * method to be benched (eventually) | |
74 | */ | |
75 | 325 | public BenchmarkMethod(final Method paramMethod) { |
76 | 325 | methodToBench = paramMethod; |
77 | 325 | if (!isBenchmarkable(methodToBench)) { |
78 | 0 | throw new IllegalArgumentException(new StringBuilder( |
79 | "Only benchmarkable methods allowed but method ").append(paramMethod).append( | |
80 | " is not benchmarkable.").toString()); | |
81 | } | |
82 | 325 | } |
83 | ||
84 | /** | |
85 | * Method to find a {@link BeforeFirstRun} annotation. This method should be | |
86 | * invoked for all methods. The corresponding class is searched after | |
87 | * suitable methods and checks for integrity are made. If there are multiple {@link BeforeFirstRun} | |
88 | * -annotated methods available, an exception is | |
89 | * thrown. If there are designated special {@link BeforeFirstRun} methods as | |
90 | * given in the parameter of the {@link Bench}-annotation, this method is | |
91 | * taken with any further checking of the other methods in the class. | |
92 | * | |
93 | * @see BeforeFirstRun | |
94 | * @see Bench | |
95 | * @return Annotated method with BeforeFirstRun annotation, null of none | |
96 | * exists | |
97 | * @throws PerfidixMethodCheckException | |
98 | * if integrity check of class and method fails. | |
99 | */ | |
100 | public Method[] findBeforeFirstRun() throws PerfidixMethodCheckException { | |
101 | ||
102 | 100 | Method method = null; |
103 | ||
104 | 100 | final Bench benchAnno = getMethodToBench().getAnnotation(Bench.class); |
105 | 100 | if (benchAnno != null && !benchAnno.beforeFirstRun().equals("")) { |
106 | 5 | List<Method> returnval = new ArrayList<Method>(); |
107 | ||
108 | try { | |
109 | // variable to instantiate the method by name. | |
110 | 5 | final Class<?>[] setUpParams = {}; |
111 | ||
112 | 5 | String[] methods = benchAnno.beforeFirstRun().split(","); |
113 | 15 | for (String methodString : methods) { |
114 | // getting the method by name | |
115 | 10 | method = |
116 | getMethodToBench().getDeclaringClass().getDeclaredMethod(methodString.trim(), setUpParams); | |
117 | ||
118 | 10 | if (isReflectedExecutable(method, BeforeFirstRun.class)) { |
119 | 10 | returnval.add(method); |
120 | } else { | |
121 | 0 | throw new PerfidixMethodCheckException(new IllegalAccessException(new StringBuilder( |
122 | "Failed to execute BeforeFirstRun-annotated method ").append(method).toString()), | |
123 | method, BeforeFirstRun.class); | |
124 | } | |
125 | } | |
126 | 5 | return returnval.toArray(new Method[returnval.size()]); |
127 | ||
128 | 0 | } catch (final SecurityException e) { |
129 | 0 | throw new PerfidixMethodCheckException(e, method, BeforeFirstRun.class); |
130 | 0 | } catch (final NoSuchMethodException e) { |
131 | 0 | throw new PerfidixMethodCheckException(e, method, BeforeFirstRun.class); |
132 | } | |
133 | } | |
134 | ||
135 | // if there was no name, a scan over the class occurs, otherwise the | |
136 | // designated method is checked. | |
137 | ||
138 | else { | |
139 | 95 | Method meth = |
140 | findAndCheckAnyMethodByAnnotation(getMethodToBench().getDeclaringClass(), | |
141 | BeforeFirstRun.class); | |
142 | 95 | if (meth == null) { |
143 | 35 | return new Method[0]; |
144 | } else { | |
145 | 60 | return new Method[] { |
146 | meth | |
147 | }; | |
148 | } | |
149 | } | |
150 | ||
151 | } | |
152 | ||
153 | /** | |
154 | * Method to find a {@link BeforeEachRun} annotation. This method should be | |
155 | * invoked for all methods. The corresponding class is searched after | |
156 | * suitable methods and checks for integrity are made. If there are multiple {@link BeforeEachRun} | |
157 | * -annotated methods available, an exception is | |
158 | * thrown. If there are designated special {@link BeforeEachRun} methods as | |
159 | * given in the parameter of the {@link Bench}-annotation, this method is | |
160 | * taken with any further checking of the other methods in the class. | |
161 | * | |
162 | * @see BeforeEachRun | |
163 | * @see Bench | |
164 | * @return Annotated method with BeforeEachRun annotation, null of none | |
165 | * exists | |
166 | * @throws PerfidixMethodCheckException | |
167 | * if integrity check of class and method fails. | |
168 | */ | |
169 | public Method[] findBeforeEachRun() throws PerfidixMethodCheckException { | |
170 | ||
171 | 3945 | Method method = null; |
172 | ||
173 | 3945 | final Bench benchAnno = getMethodToBench().getAnnotation(Bench.class); |
174 | 3945 | if (benchAnno != null && !benchAnno.beforeEachRun().equals("")) { |
175 | 1505 | List<Method> returnval = new ArrayList<Method>(); |
176 | try { | |
177 | // variable to instantiate the method by name. | |
178 | 1505 | final Class<?>[] setUpParams = {}; |
179 | ||
180 | 1505 | String[] methods = benchAnno.beforeEachRun().split(","); |
181 | 3015 | for (String methodString : methods) { |
182 | ||
183 | // getting the method by name | |
184 | 1510 | method = |
185 | getMethodToBench().getDeclaringClass().getDeclaredMethod(methodString.trim(), setUpParams); | |
186 | ||
187 | 1510 | if (isReflectedExecutable(method, BeforeEachRun.class)) { |
188 | 1510 | returnval.add(method); |
189 | } else { | |
190 | 0 | throw new PerfidixMethodCheckException(new IllegalAccessException(new StringBuilder( |
191 | " Failed to execute BeforeEachRun-annotated method ").append(method).toString()), | |
192 | method, BeforeEachRun.class); | |
193 | } | |
194 | } | |
195 | 1505 | return returnval.toArray(new Method[returnval.size()]); |
196 | ||
197 | 0 | } catch (SecurityException e) { |
198 | 0 | throw new PerfidixMethodCheckException(e, method, BeforeEachRun.class); |
199 | 0 | } catch (NoSuchMethodException e) { |
200 | 0 | throw new PerfidixMethodCheckException(e, method, BeforeEachRun.class); |
201 | } | |
202 | } else { | |
203 | ||
204 | // if there was no name, a scan over the class occurs, otherwise the | |
205 | // designated method is checked. | |
206 | 2440 | Method meth = |
207 | findAndCheckAnyMethodByAnnotation(getMethodToBench().getDeclaringClass(), BeforeEachRun.class); | |
208 | 2440 | if (meth == null) { |
209 | 1550 | return new Method[0]; |
210 | } else { | |
211 | 890 | return new Method[] { |
212 | meth | |
213 | }; | |
214 | } | |
215 | ||
216 | } | |
217 | } | |
218 | ||
219 | /** | |
220 | * Method to find a {@link AfterEachRun} annotation. This method should be | |
221 | * invoked for all methods. The corresponding class is searched after | |
222 | * suitable methods and checks for integrity are made. If there are multiple {@link AfterEachRun} | |
223 | * -annotated methods available, an exception is | |
224 | * thrown. If there are designated special {@link AfterEachRun} methods as | |
225 | * given in the parameter of the {@link Bench}-annotation, this method is | |
226 | * taken with any further checking of the other methods in the class. | |
227 | * | |
228 | * @see AfterEachRun | |
229 | * @see Bench | |
230 | * @return Annotated method with AfterEachRun annotation, null of none | |
231 | * exists | |
232 | * @throws PerfidixMethodCheckException | |
233 | * if integrity check of class and method fails. | |
234 | */ | |
235 | public Method[] findAfterEachRun() throws PerfidixMethodCheckException { | |
236 | ||
237 | 3945 | Method method = null; |
238 | ||
239 | 3945 | final Bench benchAnno = getMethodToBench().getAnnotation(Bench.class); |
240 | 3945 | if (benchAnno != null && !benchAnno.afterEachRun().equals("")) { |
241 | 5 | List<Method> returnval = new ArrayList<Method>(); |
242 | try { | |
243 | // variable to instantiate the method by name. | |
244 | 5 | final Class<?>[] setUpParams = {}; |
245 | ||
246 | 5 | String[] methods = benchAnno.afterEachRun().split(","); |
247 | 15 | for (String methodString : methods) { |
248 | // getting the method by name | |
249 | 10 | method = |
250 | getMethodToBench().getDeclaringClass().getDeclaredMethod(methodString.trim(), setUpParams); | |
251 | 10 | if (isReflectedExecutable(method, AfterEachRun.class)) { |
252 | 10 | returnval.add(method); |
253 | } else { | |
254 | 0 | throw new PerfidixMethodCheckException(new IllegalAccessException(new StringBuilder( |
255 | "AfterEachRun-annotated method ").append(method).append(" is not executable.") | |
256 | .toString()), method, AfterEachRun.class); | |
257 | } | |
258 | } | |
259 | 5 | return returnval.toArray(new Method[returnval.size()]); |
260 | 0 | } catch (SecurityException e) { |
261 | 0 | throw new PerfidixMethodCheckException(e, method, AfterEachRun.class); |
262 | 0 | } catch (NoSuchMethodException e) { |
263 | 0 | throw new PerfidixMethodCheckException(e, method, AfterEachRun.class); |
264 | } | |
265 | } else { | |
266 | // if there was no name, a scan over the class occurs, otherwise the | |
267 | // designated method is checked. | |
268 | 3940 | Method meth = |
269 | findAndCheckAnyMethodByAnnotation(getMethodToBench().getDeclaringClass(), AfterEachRun.class); | |
270 | 3940 | if (meth == null) { |
271 | 3050 | return new Method[0]; |
272 | } else { | |
273 | 890 | return new Method[] { |
274 | meth | |
275 | }; | |
276 | } | |
277 | ||
278 | } | |
279 | } | |
280 | ||
281 | /** | |
282 | * Method to find a {@link AfterLastRun} annotation. This method should be | |
283 | * invoked for all methods. The corresponding class is searched after | |
284 | * suitable methods and checks for integrity are made. If there are multiple {@link AfterLastRun} | |
285 | * -annotated methods available, an exception is | |
286 | * thrown. If there are designated special {@link AfterLastRun} methods as | |
287 | * given in the parameter of the {@link Bench}-annotation, this method is | |
288 | * taken with any further checking of the other methods in the class. | |
289 | * | |
290 | * @see AfterLastRun | |
291 | * @see Bench | |
292 | * @return Annotated method with AfterLastRun annotation, null of none | |
293 | * exists | |
294 | * @throws PerfidixMethodCheckException | |
295 | * if integrity check of class and method fails. | |
296 | */ | |
297 | public Method[] findAfterLastRun() throws PerfidixMethodCheckException { | |
298 | ||
299 | 100 | Method method = null; |
300 | ||
301 | 100 | final Bench benchAnno = getMethodToBench().getAnnotation(Bench.class); |
302 | 100 | if (benchAnno != null && !benchAnno.afterLastRun().equals("")) { |
303 | 5 | List<Method> returnval = new ArrayList<Method>(); |
304 | try { | |
305 | // variable to instantiate the method by name. | |
306 | 5 | final Class<?>[] setUpParams = {}; |
307 | ||
308 | 5 | String[] methods = benchAnno.afterLastRun().split(","); |
309 | 15 | for (String methodString : methods) { |
310 | // getting the method by name | |
311 | 10 | method = |
312 | getMethodToBench().getDeclaringClass().getDeclaredMethod(methodString.trim(), setUpParams); | |
313 | ||
314 | 10 | if (isReflectedExecutable(method, AfterLastRun.class)) { |
315 | 10 | returnval.add(method); |
316 | } else { | |
317 | 0 | throw new PerfidixMethodCheckException(new IllegalAccessException(new StringBuilder( |
318 | "AfterLastRun-annotated method ").append(method).append(" is not executable.") | |
319 | .toString()), method, AfterLastRun.class); | |
320 | } | |
321 | } | |
322 | 5 | return returnval.toArray(new Method[returnval.size()]); |
323 | 0 | } catch (final SecurityException e) { |
324 | 0 | throw new PerfidixMethodCheckException(e, method, AfterLastRun.class); |
325 | 0 | } catch (final NoSuchMethodException e) { |
326 | 0 | throw new PerfidixMethodCheckException(e, method, AfterLastRun.class); |
327 | } | |
328 | } else { | |
329 | // if there was no name, a scan over the class occurs, otherwise the | |
330 | // designated method is checked. | |
331 | 95 | Method meth = |
332 | findAndCheckAnyMethodByAnnotation(getMethodToBench().getDeclaringClass(), AfterLastRun.class); | |
333 | 95 | if (meth == null) { |
334 | 35 | return new Method[0]; |
335 | } else { | |
336 | 60 | return new Method[] { |
337 | meth | |
338 | }; | |
339 | } | |
340 | } | |
341 | } | |
342 | ||
343 | /** | |
344 | * Simple getter for encapsulated method. | |
345 | * | |
346 | * @return the methodToBench | |
347 | */ | |
348 | public Method getMethodToBench() { | |
349 | 31393 | return methodToBench; |
350 | } | |
351 | ||
352 | /** | |
353 | * Getting the number of runs corresponding to a given method. The method | |
354 | * MUST be a benchmarkable method, otherwise an IllegalStateException | |
355 | * exception arises. The number of runs of an annotated method is more | |
356 | * powerful than the number of runs as denoted by the benchclass annotation. | |
357 | * | |
358 | * @param meth | |
359 | * to be checked | |
360 | * @return the number of runs of this benchmarkable-method | |
361 | */ | |
362 | public static int getNumberOfAnnotatedRuns(final Method meth) { | |
363 | 300 | if (!isBenchmarkable(meth)) { |
364 | 5 | throw new IllegalArgumentException(new StringBuilder("Method ").append(meth).append( |
365 | " must be a benchmarkable method.").toString()); | |
366 | } | |
367 | 295 | final Bench benchAnno = meth.getAnnotation(Bench.class); |
368 | 295 | final BenchClass benchClassAnno = meth.getDeclaringClass().getAnnotation(BenchClass.class); |
369 | int returnVal; | |
370 | 295 | if (benchAnno == null) { |
371 | 5 | returnVal = benchClassAnno.runs(); |
372 | } else { | |
373 | 290 | returnVal = benchAnno.runs(); |
374 | // use runs from @BenchClass if none is set on method (issue #4) | |
375 | 290 | if((returnVal == Bench.NONE_RUN) && (benchClassAnno != null)) { |
376 | 5 | returnVal = benchClassAnno.runs(); |
377 | } | |
378 | } | |
379 | 295 | return returnVal; |
380 | } | |
381 | ||
382 | /** | |
383 | * This class finds any method with a given annotation. The method is | |
384 | * allowed to occure only once in the class and should match the | |
385 | * requirements for Perfidix for an execution by reflection. | |
386 | * | |
387 | * @param anno | |
388 | * of the method to be found | |
389 | * @param clazz | |
390 | * class to be searched | |
391 | * @return a method annotated by the annotation given. The method occurs | |
392 | * only once in the class and matched the requirements of | |
393 | * perfidix-reflective-invocation. | |
394 | * @throws PerfidixMethodCheckException | |
395 | * if these integrity checks fail | |
396 | */ | |
397 | public static Method findAndCheckAnyMethodByAnnotation(final Class<?> clazz, | |
398 | final Class<? extends Annotation> anno) throws PerfidixMethodCheckException { | |
399 | // needed variables, one for check for duplicates | |
400 | 6670 | Method anyMethod = null; |
401 | ||
402 | // Scanning all methods | |
403 | 6670 | final Method[] possAnnoMethods = clazz.getDeclaredMethods(); |
404 | 75845 | for (final Method meth : possAnnoMethods) { |
405 | 69180 | if (meth.getAnnotation(anno) != null) { |
406 | // Check if there are multiple annotated methods, throwing | |
407 | // IllegalAccessException otherwise. | |
408 | 1970 | if (anyMethod == null) { |
409 | // Check if method is valid (no param, no returnval, | |
410 | // etc.), throwing IllegalAccessException otherwise. | |
411 | 1965 | if (isReflectedExecutable(meth, anno)) { |
412 | 1965 | anyMethod = meth; |
413 | } else { | |
414 | 0 | throw new PerfidixMethodCheckException(new IllegalAccessException(new StringBuilder( |
415 | anno.toString()).append("-annotated method ").append(meth).append( | |
416 | " is not executable.").toString()), meth, anno); | |
417 | } | |
418 | } else { | |
419 | 5 | throw new PerfidixMethodCheckException(new IllegalAccessException(new StringBuilder( |
420 | "Please use only one ").append(anno.toString()).append("-annotation in one class.") | |
421 | .toString()), meth, anno); | |
422 | } | |
423 | } | |
424 | } | |
425 | ||
426 | 6665 | return anyMethod; |
427 | } | |
428 | ||
429 | /** | |
430 | * This method should act as a check to guarantee that only specific | |
431 | * Benchmarkables are used for benching. | |
432 | * | |
433 | * @param meth | |
434 | * method to be checked. | |
435 | * @return true if an instance of this interface is benchmarkable, false | |
436 | * otherwise. | |
437 | */ | |
438 | public static boolean isBenchmarkable(final Method meth) { | |
439 | 1500 | boolean returnVal = true; |
440 | ||
441 | // Check if bench-anno is given. For testing purposes against | |
442 | // before/after annos | |
443 | 1500 | final Bench benchAnno = meth.getAnnotation(Bench.class); |
444 | ||
445 | // if method is annotated with SkipBench, the method is never | |
446 | // benchmarkable. | |
447 | 1500 | final SkipBench skipBenchAnno = meth.getAnnotation(SkipBench.class); |
448 | 1500 | if (skipBenchAnno != null) { |
449 | 10 | returnVal = false; |
450 | } | |
451 | ||
452 | // Check if method is defined as beforeClass, beforeFirstRun, | |
453 | // beforeEachRun, afterEachRun, afterLastRun, afterClass. A method can | |
454 | // either be a before/after class or afterwards be benchmarkable through | |
455 | // the BenchClass annotation. | |
456 | 1500 | final BeforeBenchClass beforeClass = meth.getAnnotation(BeforeBenchClass.class); |
457 | 1500 | if (beforeClass != null && benchAnno == null) { |
458 | 50 | returnVal = false; |
459 | } | |
460 | ||
461 | 1500 | final BeforeFirstRun beforeFirstRun = meth.getAnnotation(BeforeFirstRun.class); |
462 | 1500 | if (beforeFirstRun != null && benchAnno == null) { |
463 | 45 | returnVal = false; |
464 | } | |
465 | ||
466 | 1500 | final BeforeEachRun beforeEachRun = meth.getAnnotation(BeforeEachRun.class); |
467 | 1500 | if (beforeEachRun != null && benchAnno == null) { |
468 | 45 | returnVal = false; |
469 | } | |
470 | ||
471 | 1500 | final AfterEachRun afterEachRun = meth.getAnnotation(AfterEachRun.class); |
472 | 1500 | if (afterEachRun != null && benchAnno == null) { |
473 | 45 | returnVal = false; |
474 | } | |
475 | ||
476 | 1500 | final AfterLastRun afterLastRun = meth.getAnnotation(AfterLastRun.class); |
477 | 1500 | if (afterLastRun != null && benchAnno == null) { |
478 | 45 | returnVal = false; |
479 | } | |
480 | ||
481 | 1500 | final AfterBenchClass afterClass = meth.getAnnotation(AfterBenchClass.class); |
482 | 1500 | if (afterClass != null && benchAnno == null) { |
483 | 30 | returnVal = false; |
484 | } | |
485 | ||
486 | // if method is not annotated with Bench and class is not annotated with | |
487 | // BenchClass, the method is never benchmarkable. | |
488 | ||
489 | 1500 | final BenchClass classBenchAnno = meth.getDeclaringClass().getAnnotation(BenchClass.class); |
490 | 1500 | if (benchAnno == null && classBenchAnno == null) { |
491 | 585 | returnVal = false; |
492 | } | |
493 | ||
494 | // check if method is executable for perfidix purposes. | |
495 | 1500 | if (!isReflectedExecutable(meth, Bench.class)) { |
496 | 290 | returnVal = false; |
497 | } | |
498 | 1500 | return returnVal; |
499 | } | |
500 | ||
501 | /** | |
502 | * Checks if this method is executable via reflection for perfidix purposes. | |
503 | * That means that the method has no parameters, no return-value, is | |
504 | * non-static, is public and throws no exceptions. | |
505 | * | |
506 | * @param meth | |
507 | * method to be checked | |
508 | * @param anno | |
509 | * anno for method to be check, necessary since different | |
510 | * attributes are possible depending on the anno | |
511 | * @return true if method matches requirements. | |
512 | */ | |
513 | public static boolean isReflectedExecutable(final Method meth, final Class<? extends Annotation> anno) { | |
514 | 8475 | boolean returnVal = true; |
515 | // if method has parameters, the method is not benchmarkable | |
516 | 8475 | if (meth.getGenericParameterTypes().length > 0) { |
517 | 20 | returnVal = false; |
518 | } | |
519 | // if method is static, the method is not benchmarkable | |
520 | 8475 | if (!(anno.equals(BeforeBenchClass.class)) && Modifier.isStatic(meth.getModifiers())) { |
521 | 285 | returnVal = false; |
522 | } | |
523 | // if method is not public, the method is not benchmarkable | |
524 | 8475 | if (!Modifier.isPublic(meth.getModifiers())) { |
525 | 5 | returnVal = false; |
526 | } | |
527 | // if method has another returnValue than void, the method is not | |
528 | // benchmarkable | |
529 | 8475 | if (!meth.getGenericReturnType().equals(Void.TYPE)) { |
530 | 255 | returnVal = false; |
531 | } | |
532 | ||
533 | 8475 | return returnVal; |
534 | } | |
535 | ||
536 | /** {@inheritDoc} */ | |
537 | @Override | |
538 | public int hashCode() { | |
539 | 49475 | final int prime = 31; |
540 | 49475 | int result = 1; |
541 | 49475 | if (methodToBench == null) { |
542 | 0 | result = prime * result; |
543 | } else { | |
544 | 49475 | result = prime * result + methodToBench.hashCode(); |
545 | } | |
546 | ||
547 | 49475 | return result; |
548 | } | |
549 | ||
550 | /** {@inheritDoc} */ | |
551 | @Override | |
552 | public boolean equals(final Object obj) { | |
553 | 47390 | boolean returnVal = true; |
554 | 47390 | if (this == obj) { |
555 | 42935 | returnVal = true; |
556 | } | |
557 | 47390 | if (obj == null) { |
558 | 0 | returnVal = false; |
559 | } | |
560 | 47390 | if (getClass() != obj.getClass()) { |
561 | 0 | returnVal = false; |
562 | } | |
563 | 47390 | final BenchmarkMethod other = (BenchmarkMethod)obj; |
564 | 47390 | if (methodToBench == null) { |
565 | 0 | if (other.methodToBench != null) { |
566 | 0 | returnVal = false; |
567 | } | |
568 | } else { | |
569 | 47390 | if (!methodToBench.equals(other.methodToBench)) { |
570 | 0 | returnVal = false; |
571 | ||
572 | } | |
573 | } | |
574 | 47390 | return returnVal; |
575 | } | |
576 | ||
577 | /** | |
578 | * {@inheritDoc} | |
579 | */ | |
580 | @Override | |
581 | public String toString() { | |
582 | 0 | return new StringBuilder(methodToBench.getName()).toString(); |
583 | } | |
584 | ||
585 | /** | |
586 | * This method returns the fully qualified name consisting of its own name | |
587 | * and its class name | |
588 | * | |
589 | * @return the {@link String} name von the bench method consisting of fully | |
590 | * qualified name of its class and its own name | |
591 | */ | |
592 | public String getMethodWithClassName() { | |
593 | ||
594 | 20 | return new StringBuilder(methodToBench.getDeclaringClass().getName() + "." + methodToBench.getName()) |
595 | .toString(); | |
596 | } | |
597 | } |