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

com.tatateo.test.ExtendedMethod Maven / Gradle / Ivy

The newest version!
package com.tatateo.test;

import org.junit.runners.model.FrameworkMethod;

import java.lang.annotation.Annotation;
import java.util.*;

/**
 * extend the method with info from our annotation
 */
public class ExtendedMethod extends FrameworkMethod {
    List dependencies = new ArrayList();
    int priority = 0;
    // reversed dependency - the followers have this method as a dependency
    List followers = new ArrayList();

    public ExtendedMethod(FrameworkMethod method) {
        super(method.getMethod());

        // compute dependencies of the method
        for (Annotation a : method.getAnnotations()) {
            Class type = a.annotationType();
            if (type.equals(Conditions.class)) {
                priority = ((Conditions) a).priority();
                dependencies.addAll(Arrays.asList(((Conditions) a).dependsOn()));
                break;
            }
        }
    }

    @Override
    public String toString() {
        return getName();
    }

    public static List extend(List initial) {
        final List extended = new ArrayList(initial.size());
        for (FrameworkMethod d : initial) {
            extended.add(new ExtendedMethod(d));
        }
        return extended;
    }

    public static void computeFollowers(Map methods) {
        for (Map.Entry entry : methods.entrySet()) {
            if (null != entry.getValue().dependencies) {
                for (String d : entry.getValue().dependencies) {
                    ExtendedMethod m = methods.get(d);
                    if (null == m) {
                        throw new AssertionError("The dependency '" + d + "' declared by '" + entry.getKey() + "' is not a method.");
                    }
                    m.followers.add(entry.getKey());
                }
            }
        }
    }

    public static List sortByDependencies(Map methods) {
        final LinkedList result = new LinkedList();
        final HashSet visited = new HashSet();
        final HashSet extended = new HashSet();
        /* Fire off a DFS from each node in the graph. */
        for (ExtendedMethod node : methods.values()) {
            explore(node, methods, result, visited, extended);
        }
        return result;
    }

    /**
     * Recursively performs a DFS from the specified node, marking all nodes
     * encountered by the search.
     * Based on: http://www.keithschwarz.com/interesting/code/?dir=topological-sort
     *
     * @param node     The node to begin the search from.
     * @param methods  The graph in which to perform the search.
     * @param ordering A list holding the topological sortByDependencies of the graph.
     * @param visited  A set of nodes that have already been visited.
     * @param expanded A set of nodes that have been fully expanded.
     */
    private static void explore(ExtendedMethod node,
                                Map methods,
                                LinkedList ordering,
                                Set visited,
                                Set expanded) {
        /* Check whether we've been here before.  If so, we should stop the
         * search.
         */
        if (visited.contains(node)) {
            /* There are two cases to consider.  First, if this node has
             * already been expanded, then it's already been assigned a
             * position in the final topological sortByDependencies and we don't need to
             * explore it again.  However, if it hasn't been expanded, it means
             * that we've just found a node that is currently being explored,
             * and therefore is part of a cycle.  In that case, we should
             * report an error.
             */
            if (expanded.contains(node)) return;
            throw new IllegalArgumentException("Graph contains a cycle.");
        }

        /* Mark that we've been here */
        visited.add(node);

        /* Recursively explore all of the node's predecessors. */
        for (String pre : node.followers) {
            ExtendedMethod predecessor = methods.get(pre);
            explore(predecessor, methods, ordering, visited, expanded);
        }

        /* Having explored all of the node's predecessors, we can now add this
         * node to the sorted ordering.
         */
        ordering.addFirst(node);

        /* Similarly, mark that this node is done being expanded. */
        expanded.add(node);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy