All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.testng.internal.annotations.AnnotationHelper Maven / Gradle / Ivy

There is a newer version: 7.10.1
Show newest version
package org.testng.internal.annotations;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Map;

import org.testng.ITestNGMethod;
import org.testng.annotations.IAnnotation;
import org.testng.annotations.IConfigurationAnnotation;
import org.testng.annotations.IDataProviderAnnotation;
import org.testng.annotations.IFactoryAnnotation;
import org.testng.annotations.IParametersAnnotation;
import org.testng.annotations.ITestAnnotation;
import org.testng.collections.Maps;
import org.testng.internal.ConstructorOrMethod;
import org.testng.internal.TestNGMethod;
import org.testng.internal.Utils;
import org.testng.internal.reflect.ReflectionHelper;
import org.testng.xml.XmlTest;

/**
 * Helper methods to find @Test and @Configuration tags.  They minimize
 * the amount of casting we need to do.
 *
 * Created on Dec 20, 2005
 * @author cbeust
 */
public class AnnotationHelper {

  private static final Class[] ALL_ANNOTATIONS = new Class[] {
      ITestAnnotation.class,
      IBeforeClass.class, IAfterClass.class,
      IBeforeMethod.class, IAfterMethod.class,
      IDataProviderAnnotation.class,
      IFactoryAnnotation.class, IParametersAnnotation.class,
      IBeforeSuite.class, IAfterSuite.class,
      IBeforeTest.class, IAfterTest.class,
      IBeforeGroups.class, IAfterGroups.class
  };

  private static final Class[] CONFIGURATION_CLASSES = new Class[] {
      IBeforeSuite.class, IAfterSuite.class,
      IBeforeTest.class, IAfterTest.class,
      IBeforeGroups.class, IAfterGroups.class,
      IBeforeClass.class, IAfterClass.class,
      IBeforeMethod.class, IAfterMethod.class
  };

  private AnnotationHelper() {
    //Utility class.defeat instantiation.
  }

  public static ITestAnnotation findTest(IAnnotationFinder finder, Class cls) {
    return finder.findAnnotation(cls, ITestAnnotation.class);
  }

  public static ITestAnnotation findTest(IAnnotationFinder finder, Method m) {
    return finder.findAnnotation(m, ITestAnnotation.class);
  }

  public static ITestAnnotation findTest(IAnnotationFinder finder, ITestNGMethod m) {
    return finder.findAnnotation(m, ITestAnnotation.class);
  }

  public static IFactoryAnnotation findFactory(IAnnotationFinder finder, Method m) {
    return finder.findAnnotation(m, IFactoryAnnotation.class);
  }

  public static IFactoryAnnotation findFactory(IAnnotationFinder finder, Constructor c) {
    return finder.findAnnotation(c, IFactoryAnnotation.class);
  }

  public static ITestAnnotation findTest(IAnnotationFinder finder, Constructor ctor) {
    return finder.findAnnotation(ctor, ITestAnnotation.class);
  }

  public static IConfigurationAnnotation findConfiguration(IAnnotationFinder finder, ConstructorOrMethod m) {
    IConfigurationAnnotation result = null;
    IConfigurationAnnotation bs = (IConfigurationAnnotation) finder.findAnnotation(m, IBeforeSuite.class);
    IConfigurationAnnotation as = (IConfigurationAnnotation) finder.findAnnotation(m, IAfterSuite.class);
    IConfigurationAnnotation bt = (IConfigurationAnnotation) finder.findAnnotation(m, IBeforeTest.class);
    IConfigurationAnnotation at = (IConfigurationAnnotation) finder.findAnnotation(m, IAfterTest.class);
    IConfigurationAnnotation bg = (IConfigurationAnnotation) finder.findAnnotation(m, IBeforeGroups.class);
    IConfigurationAnnotation ag = (IConfigurationAnnotation) finder.findAnnotation(m, IAfterGroups.class);
    IConfigurationAnnotation bc = (IConfigurationAnnotation) finder.findAnnotation(m, IBeforeClass.class);
    IConfigurationAnnotation ac = (IConfigurationAnnotation) finder.findAnnotation(m, IAfterClass.class);
    IConfigurationAnnotation bm = (IConfigurationAnnotation) finder.findAnnotation(m, IBeforeMethod.class);
    IConfigurationAnnotation am = (IConfigurationAnnotation) finder.findAnnotation(m, IAfterMethod.class);

    if (bs != null || as != null || bt != null || at != null || bg != null || ag != null
            || bc != null || ac != null || bm != null || am != null) {
      result = createConfiguration(bs, as, bt, at, bg, ag, bc, ac, bm, am);
    }

    return result;
  }

  public static IConfigurationAnnotation findConfiguration(IAnnotationFinder finder, Constructor ctor) {
    return findConfiguration(finder, new ConstructorOrMethod(ctor));
  }

  public static IConfigurationAnnotation findConfiguration(IAnnotationFinder finder, Method m) {
    return findConfiguration(finder, new ConstructorOrMethod(m));
  }

  private static IConfigurationAnnotation createConfiguration(IConfigurationAnnotation bs, IConfigurationAnnotation as,
      IConfigurationAnnotation bt, IConfigurationAnnotation at, IConfigurationAnnotation bg, IConfigurationAnnotation ag,
      IConfigurationAnnotation bc, IConfigurationAnnotation ac, IConfigurationAnnotation bm, IConfigurationAnnotation am)
  {
    ConfigurationAnnotation result = new ConfigurationAnnotation();

    if (bs != null) {
      result.setBeforeSuite(true);
      finishInitialize(result, bs);
    }
    if (as != null) {
      result.setAfterSuite(true);
      finishInitialize(result, as);
    }
    if (bt != null) {
      result.setBeforeTest(true);
      finishInitialize(result, bt);
    }
    if (at != null) {
      result.setAfterTest(true);
      finishInitialize(result, at);
    }
    if (bg != null) {
      result.setBeforeGroups(bg.getBeforeGroups());
      finishInitialize(result, bg);
    }
    if (ag != null) {
      result.setAfterGroups(ag.getAfterGroups());
      finishInitialize(result, ag);
    }
    if (bc != null) {
      result.setBeforeTestClass(true);
      finishInitialize(result, bc);
    }
    if (ac != null) {
      result.setAfterTestClass(true);
      finishInitialize(result, ac);
    }
    if (bm != null) {
      result.setBeforeTestMethod(true);
      finishInitialize(result, bm);
    }
    if (am != null) {
      result.setAfterTestMethod(true);
      finishInitialize(result, am);
    }

    return result;
  }

  @SuppressWarnings({"deprecation"})
  private static void finishInitialize(ConfigurationAnnotation result, IConfigurationAnnotation bs) {
    result.setFakeConfiguration(true);
    result.setAlwaysRun(bs.getAlwaysRun());
    result.setDependsOnGroups(bs.getDependsOnGroups());
    result.setDependsOnMethods(bs.getDependsOnMethods());
    result.setDescription(bs.getDescription());
    result.setEnabled(bs.getEnabled());
    result.setGroups(bs.getGroups());
    result.setInheritGroups(bs.getInheritGroups());
    result.setParameters(bs.getParameters());
    result.setTimeOut(bs.getTimeOut());
  }



  public static Class[] getAllAnnotations() {
    return ALL_ANNOTATIONS;
  }

  /**
   * Delegation method for creating the list of ITestMethods to be
   * analysed.
   */
  public static ITestNGMethod[] findMethodsWithAnnotation(Class rootClass,
      Class annotationClass, IAnnotationFinder annotationFinder,
      XmlTest xmlTest)
  {
    // Keep a map of the methods we saw so that we ignore a method in a superclass if it's
    // already been seen in a child class
    Map vResult = Maps.newHashMap();

    try {
      vResult = Maps.newHashMap();
//    Class[] classes = rootClass.getTestClasses();
      Class cls = rootClass;

      //
      // If the annotation is on the class or superclass, it applies to all public methods
      // except methods marked with @Configuration
      //

      //
      // Otherwise walk through all the methods and keep those
      // that have the annotation
      //
//    for (Class cls : classes) {
        while (null != cls) {
          boolean hasClassAnnotation = isAnnotationPresent(annotationFinder, cls, annotationClass);
          Method[] methods = ReflectionHelper.getLocalMethods(cls);
          for (Method m : methods) {
            boolean hasMethodAnnotation = isAnnotationPresent(annotationFinder, m, annotationClass);
            boolean hasTestNGAnnotation =
              isAnnotationPresent(annotationFinder, m, IFactoryAnnotation.class) ||
              isAnnotationPresent(annotationFinder, m, ITestAnnotation.class) ||
              isAnnotationPresent(annotationFinder, m, CONFIGURATION_CLASSES);
            boolean isPublic = Modifier.isPublic(m.getModifiers());
            boolean isSynthetic = m.isSynthetic();            
            if ((isPublic && hasClassAnnotation && !isSynthetic && (! hasTestNGAnnotation)) || hasMethodAnnotation) {

              // Small hack to allow users to specify @Configuration classes even though
              // a class-level @Test annotation is present.  In this case, don't count
              // that method as a @Test
              if (isAnnotationPresent(annotationFinder, m, IConfigurationAnnotation.class) &&
                  isAnnotationPresent(annotationFinder, cls, ITestAnnotation.class))
              {
                Utils.log("", 3, "Method " + m + " has a configuration annotation"
                    + " and a class-level @Test. This method will only be kept as a"
                    + " configuration method.");

                continue;
              }

              // Skip the method if it has a return type
              if (m.getReturnType() != void.class && ! xmlTest.getAllowReturnValues()) {
                Utils.log("", 2, "Method " + m + " has a @Test annotation"
                    + " but also a return value:"
                    + " ignoring it. Use  to fix this");
                continue;
              }

              String key = createMethodKey(m);
              if (null == vResult.get(key)) {
                ITestNGMethod tm = new TestNGMethod(/* m.getDeclaringClass(), */ m,
                    annotationFinder, xmlTest, null); /* @@@ */
                vResult.put(key,tm);
              }
            }
          } // for
          // Now explore the superclass
          cls = cls.getSuperclass();
        } // while

    }
    catch (SecurityException e) {
      e.printStackTrace();
    }
    return vResult.values().toArray(new ITestNGMethod[vResult.size()]);
    }

  public static  A  findAnnotationSuperClasses(Class annotationClass, Class parameterClass) {
    Class c = parameterClass;
    while (c != null) {
      Annotation result = c.getAnnotation(annotationClass);
      if (result != null) {
        return (A) result;
      }
      else {
        c = c.getSuperclass();
      }
    }
    return null;
  }

  private static boolean isAnnotationPresent(IAnnotationFinder annotationFinder,
      Method m, Class[] annotationClasses)
  {
    for (Class a : annotationClasses) {
      if (annotationFinder.findAnnotation(m, a) != null) {
        return true;
      }
    }

    return false;
  }

  private static boolean isAnnotationPresent(IAnnotationFinder annotationFinder, Method m,
      Class annotationClass) {
    if (!annotationClass.equals(IConfigurationAnnotation.class)) {
      return annotationFinder.findAnnotation(m, annotationClass) != null;
    }
    boolean found = false;
    for (Class clazz : CONFIGURATION_CLASSES) {
      if (annotationFinder.findAnnotation(m, clazz) != null) {
        found = true;
        break;
      }
    }
    return found;
  }

  private static boolean isAnnotationPresent(IAnnotationFinder annotationFinder, Class cls,
      Class annotationClass) {
    return annotationFinder.findAnnotation(cls, annotationClass) != null;
  }

  /**
   * @return A hashcode representing the name of this method and its parameters,
   * but without its class
   */
  private static String createMethodKey(Method m) {
    StringBuilder result = new StringBuilder(m.getName());
    for (Class paramClass : m.getParameterTypes()) {
      result.append(' ').append(paramClass.toString());
    }

    return result.toString();
  }
  
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy