Package org.givwenzen

Source Code of org.givwenzen.DomainStepMethodLocator

package org.givwenzen;

import org.givwenzen.annotations.DomainStep;
import org.givwenzen.parse.StringToObjectParser;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Pattern;

public class DomainStepMethodLocator {

    private static String MULTI_STEP_DEF_MSG_PATTERN = "Multiple step definitions match \"%1$s\"\n";
    private static String MULTI_STEP_DEF_METHOD_MSG_PATTERN = "%1$s\"%2$s\"\n";

    private Collection<Object> stepDefinitions;
    private ICustomParserFinder customParserFinder;
    private Map<String, MethodAndInvocationTarget> steps;

    public DomainStepMethodLocator(Collection<Object> stepDefinitions, ICustomParserFinder customParserFinder) {
        this.stepDefinitions = stepDefinitions;
        this.customParserFinder = customParserFinder;
    }

    public MethodAndInvocationTarget getMethodWithAnnotatedPatternMatching(String methodString)
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        List<MethodAndInvocationTarget> possibleAmbiguities = findPossibleAmbiguities(methodString);

        if (possibleAmbiguities.size() > 1)
            return handleAmbiguousStepDefinitions(methodString, possibleAmbiguities);

        return possibleAmbiguities.get(0);
    }

    private List<MethodAndInvocationTarget> findPossibleAmbiguities(String methodString)
            throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
        List<MethodAndInvocationTarget> possibleAmbiguities = new ArrayList<MethodAndInvocationTarget>();
        for (MethodAndInvocationTarget methodAndTarget : getSteps()) {
            if (methodAndTarget.methodStringMatchesMethodPatern(methodString))
                possibleAmbiguities.add(methodAndTarget);
        }
        if (possibleAmbiguities.isEmpty()) {
            possibleAmbiguities.add(new MissingStepMethodAndInvocationTarget(getSteps()));
        }
        return possibleAmbiguities;
    }

    private MethodAndInvocationTarget handleAmbiguousStepDefinitions(String methodString,
                                                                     List<MethodAndInvocationTarget> matches) throws NoSuchMethodException, IllegalAccessException,
            InvocationTargetException {
        StringBuilder msgBuiler = new StringBuilder();
        msgBuiler.append(String.format(MULTI_STEP_DEF_MSG_PATTERN, methodString));
        for (MethodAndInvocationTarget match : matches) {
            msgBuiler.append(String.format(MULTI_STEP_DEF_METHOD_MSG_PATTERN,
                    match.getMethodAsString(), match.getDomainStepPattern()));
        }
        throw new GivWenZenException(msgBuiler.toString());
    }

    private Collection<MethodAndInvocationTarget> getSteps() throws InvocationTargetException, NoSuchMethodException,
            IllegalAccessException {
        if (steps == null) {
            steps = findMethodsOnTargets();
        }
        return steps.values();
    }

    private Map<String, MethodAndInvocationTarget> findMethodsOnTargets() throws InvocationTargetException,
            NoSuchMethodException, IllegalAccessException {
        Map<String, MethodAndInvocationTarget> methodTargetsByDescription = new HashMap<String, MethodAndInvocationTarget>();
        stepDefinitions = removeDuplicates(stepDefinitions);
        for (Object stepDefinition : stepDefinitions) {
            for (MethodAndInvocationTarget method : searchMethodsOnTarget(stepDefinition)) {
                Pattern pattern = method.getMethodDescriptionPattern();
                if (methodTargetsByDescription.containsKey(pattern.pattern())) {
                    return handleDuplicateStepDefinition(methodTargetsByDescription.get(pattern.pattern()), method, pattern);
                }
                methodTargetsByDescription.put(method.getMethodDescriptionPattern().pattern(), method);
            }
        }
        return methodTargetsByDescription;
    }

    private List<Object> removeDuplicates(Collection<Object> values) {
        List<Object> noDuplicates = new ArrayList<Object>(values.size());
        for (Object object : values) {
            if (collectionDoesNotContainInstanceOf(noDuplicates, object)) {
                noDuplicates.add(object);
            }
        }
        return noDuplicates;
    }

    private boolean collectionDoesNotContainInstanceOf(List<Object> noDuplicates, Object object) {
        for (Object possibleDup : noDuplicates) {
            if (possibleDup.getClass().equals(object.getClass())) {
                return false;
            }
        }
        return true;
    }

    private Map<String, MethodAndInvocationTarget> handleDuplicateStepDefinition(
            MethodAndInvocationTarget firstDefinition, MethodAndInvocationTarget secondDefinition, Pattern pattern) {
        String message = "Duplicate step definition: " + pattern.pattern();
        message += "\nfirst definition " + firstDefinition.getMethodAsString();
        message += "\nsecond definition " + secondDefinition.getMethodAsString();
        throw new GivWenZenException(message);
    }

    private List<MethodAndInvocationTarget> searchMethodsOnTarget(Object target) throws NoSuchMethodException,
            InvocationTargetException, IllegalAccessException {
        List<MethodAndInvocationTarget> targetMethods = new ArrayList<MethodAndInvocationTarget>();
        Method[] methods = target.getClass().getMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(DomainStep.class)) {
                StringToObjectParser parser = new StringToObjectParser(customParserFinder);
                targetMethods.add(new MethodAndInvocationTarget(method, target, parser));
            } else {
               // TODO - build a MethodAndInvocationTarget from the method name and parameters
               // must not conflict with defined methods
            }
        }
        return targetMethods;
    }

}
TOP

Related Classes of org.givwenzen.DomainStepMethodLocator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.