Coverage Report - org.perfidix.element.BenchmarkMethod
 
Classes in this File Line Coverage Branch Coverage Complexity
BenchmarkMethod
82%
138/167
79%
91/114
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  
 }