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

com.thoughtworks.gauge.registry.HooksRegistry Maven / Gradle / Ivy

There is a newer version: 0.11.0
Show newest version
/*----------------------------------------------------------------
 *  Copyright (c) ThoughtWorks, Inc.
 *  Licensed under the Apache License, Version 2.0
 *  See LICENSE.txt in the project root for license information.
 *----------------------------------------------------------------*/
package com.thoughtworks.gauge.registry;

import com.thoughtworks.gauge.AfterClassSteps;
import com.thoughtworks.gauge.AfterScenario;
import com.thoughtworks.gauge.AfterSpec;
import com.thoughtworks.gauge.AfterStep;
import com.thoughtworks.gauge.AfterSuite;
import com.thoughtworks.gauge.BeforeClassSteps;
import com.thoughtworks.gauge.BeforeScenario;
import com.thoughtworks.gauge.BeforeSpec;
import com.thoughtworks.gauge.BeforeStep;
import com.thoughtworks.gauge.BeforeSuite;
import com.thoughtworks.gauge.Logger;
import com.thoughtworks.gauge.Operator;
import com.thoughtworks.gauge.hook.Hook;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

public class HooksRegistry {
    // Names of methods defined in each Hook annotation. Do not rename these methods in any Hook Class.
    private static final String TAGS_METHOD = "tags";
    private static final String TAG_AGGREGATION_METHOD = "tagAggregation";

    private static ConcurrentHashMap> registryMap = new ConcurrentHashMap<>();

    public static List getBeforeSpecHooks() {
        return sort(registryMap.get(BeforeSpec.class));
    }

    public static void addBeforeSpecHooks(Set methods) {
        addHooksWithTags(methods, BeforeSpec.class);
    }

    public static List getAfterSpecHooks() {
        return sortReverse(registryMap.get(AfterSpec.class));
    }

    public static void addAfterSpecHooks(Set methods) {
        addHooksWithTags(methods, AfterSpec.class);
    }

    public static List getBeforeScenarioHooks() {
        return sort(registryMap.get(BeforeScenario.class));
    }

    private static List sort(Set hooks) {
        return hooks.stream().sorted().collect(toList());
    }

    private static List sortReverse(Set hooks) {
        return hooks.stream().sorted(Comparator.reverseOrder()).collect(toList());
    }

    public static void addBeforeScenarioHooks(Set methods) {
        addHooksWithTags(methods, BeforeScenario.class);
    }

    public static List getAfterScenarioHooks() {
        return sortReverse(registryMap.get(AfterScenario.class));
    }

    public static void addAfterScenarioHooks(Set methods) {
        addHooksWithTags(methods, AfterScenario.class);
    }

    public static List getBeforeStepHooks() {
        return sort(registryMap.get(BeforeStep.class));
    }

    public static void addBeforeStepHooks(Set methods) {
        addHooksWithTags(methods, BeforeStep.class);
    }

    public static List getAfterStepHooks() {
        return sortReverse(registryMap.get(AfterStep.class));
    }

    public static void setAfterStepHooks(Set methods) {
        addHooksWithTags(methods, AfterStep.class);
    }

    public static List getBeforeSuiteHooks() {
        return sort(registryMap.get(BeforeSuite.class));
    }

    public static void addBeforeSuiteHooks(Set methods) {
        addHooks(methods, BeforeSuite.class);
    }

    public static List getAfterSuiteHooks() {
        return sortReverse(registryMap.get(AfterSuite.class));
    }

    public static void addAfterSuiteHooks(Set methods) {
        addHooks(methods, AfterSuite.class);
    }

    public static void addAfterClassStepsHooks(Set methods) {
        addHooksWithTags(methods, AfterClassSteps.class);
    }

    public static void addBeforeClassStepsHooks(Set methods) {
        addHooksWithTags(methods, BeforeClassSteps.class);
    }

    public static List getBeforeClassStepsHooksOfClass(Class aClass) {
        return sort(findClassHooksForClass(getBeforeClassHooks(), aClass));
    }

    public static List getAfterClassStepsHooksOfClass(Class aClass) {
        return sortReverse(findClassHooksForClass(getAfterClassHooks(), aClass));
    }

    private static Set findClassHooksForClass(List allClassHooks, Class aClass) {
        return allClassHooks.stream().filter(hook -> hook.getMethod().getDeclaringClass().equals(aClass)).collect(Collectors.toSet());
    }

    private static void addHooks(Set methods, Class hookClass) {
        registryMap.putIfAbsent(hookClass, new HashSet<>());
        registryMap.get(hookClass).addAll(methods.stream().map(Hook::new).collect(toList()));
    }

    private static void addHooksWithTags(Set methods, Class hookClass) {
        registryMap.putIfAbsent(hookClass, new HashSet<>());
        for (Method method : methods) {
            Annotation annotation = method.getAnnotation(hookClass);
            try {
                //Hack: Invoking methods on the annotation to avoid repeating logic. There is no hierarchy possible in annotations
                String[] tags = (String[]) annotation.getClass().getMethod(TAGS_METHOD).invoke(annotation);
                Operator tagsAggregation = (Operator) annotation.getClass().getMethod(TAG_AGGREGATION_METHOD).invoke(annotation);
                registryMap.get(hookClass).add(new Hook(method, tags, tagsAggregation));
            } catch (Exception e) {
                Logger.warning("Unable to add hooks", e);
                continue;
            }
        }
    }

    private static List getBeforeClassHooks() {
        return sort(registryMap.get(BeforeClassSteps.class));
    }

    private static List getAfterClassHooks() {
        return sortReverse(registryMap.get(AfterClassSteps.class));
    }

    static void remove(Class hookType) {
        registryMap.remove(hookType);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy