<commit_before>package com.lynx.fsm;

import java.util.Collection;

import com.google.common.collect.Multimap;

/**
 * Abstract state machine providing validation and configuration operations
 * 
 * @author daniel.las
 *
 * @param <S>
 * @param <C>
 */
public abstract class StateMachine<S extends StateType, C extends StateHolder<S>, X> implements Forwardable<S>,
        ContextHolder<C>, BeanValidating, Secured, Configurable<S, C, X>, StateProvider<S>, ExecutionContextAware<X> {

    S state;
    C context;
    Multimap<S, Transition<S, C, X>> transitions;
    X executionContext;

    @Override
    public void forward() {
        if (state.isFinal()) {
            throw new StateMachineException("Machine is in FINAL state");
        }
        Collection<Transition<S, C, X>> possibleEnds = transitions.get(state);
        Transition<S, C, X> resolvedTransition = null;

        // There are no transitions for start state, no knowledge what to do
        if (possibleEnds.isEmpty()) {
            throw new StateMachineException(String.format("There are no transitions for start state %s", state));
        }
        // We have only one transition with given start
        if (possibleEnds.size() == 1) {
            resolvedTransition = possibleEnds.iterator().next();

            // There is condition which must be met
            if (resolvedTransition.getCondition() != null) {
                // Condition is not met
                if (!resolvedTransition.getCondition().check(resolvedTransition.getEnd(), context)) {
                    throw new StateMachineException(String.format("Condition for transition from %s to %s is not met",
                            state, resolvedTransition.getEnd()));
                }
            }
        } else {
            Transition<S, C, X> goodEnd = null;

            for (Transition<S, C, X> end : possibleEnds) {
                if (end.getCondition() == null) {
                    throw new StateMachineException(
                            String.format("There is no condition for possible transition from %s to %s. Decision can't be taken when no state is requested."));
                }
                if (end.getCondition().check(end.getEnd(), context)) {
                    // We already have good end so next state is ambiguous
                    if (goodEnd != null) {
                        throw new StateMachineException(
                                "There is more than one transition from state %s fullfilling condition");
                    }
                    goodEnd = end;
                }
            }
            resolvedTransition = goodEnd;
        }
        // No transition fulfilling conditions found
        if (resolvedTransition == null) {
            throw new StateMachineException(String.format(
                    "No transition fulfilling confition found for start state %s ", state));
        }
        // All is fine, we can validate, check permissions and move to next
        // state
        // Security is set, check permissions
        if (resolvedTransition.getRoles() != null) {
            checkPermissions(resolvedTransition.getRoles());
        }
        // Validation groups are set, process validation
        if (resolvedTransition.getValidationGroups() != null) {
            validate(resolvedTransition.getValidationGroups());
        }
        if (resolvedTransition.getValidator() != null) {
            resolvedTransition.getValidator().validate(resolvedTransition.getEnd(), context);
        }
        // Everything passed, we are good to go,
        state = resolvedTransition.getEnd();
        context.setState(state);
        // Run action if executor is set
        if (resolvedTransition.getAfterAction() != null) {
            resolvedTransition.getAfterAction().execute(executionContext, context);
        }
    }

    @Override
    public void forward(S requestedState) {
        if (state.isFinal()) {
            throw new StateMachineException("Machine is in FINAL state");
        }
        Collection<Transition<S, C, X>> possibleEnds = transitions.get(state);
        Transition<S, C, X> resolvedTransition = null;

        // There are no transitions for start state, no knowledge what to do
        if (possibleEnds.isEmpty()) {
            throw new StateMachineException(String.format("There are no transitions for start state %s", state));
        }
        // Find transition with end equals requestedState
        for (Transition<S, C, X> end : possibleEnds) {
            if (requestedState.equals(end.getEnd())) {
                resolvedTransition = end;
            }
        }
        // No transition found
        if (resolvedTransition == null) {
            throw new StateMachineException(String.format("No transition found for start state %s and end state %s",
                    state, requestedState));
        }
        // Good transition found, check condition if exists
        if (resolvedTransition.getCondition() != null) {
            if (!resolvedTransition.getCondition().check(requestedState, context)) {
                throw new StateMachineException(String.format(
                        "No transition fulfilling confition found for start state %s and requested state %s", state,
                        requestedState));
            }

        }
        // All is fine, we can validate, check permissions and move to next
        // state
        // Security is set, check permissions
        if (resolvedTransition.getRoles() != null) {
            checkPermissions(resolvedTransition.getRoles());
        }
        // Validation groups are set, process Bean validation
        if (resolvedTransition.getValidationGroups() != null) {
            validate(resolvedTransition.getValidationGroups());
        }
        // Business validator is set, process business validation
        if (resolvedTransition.getValidator() != null) {
            resolvedTransition.getValidator().validate(requestedState, context);
        }
        // Everything passed, we are good to go,
        state = resolvedTransition.getEnd();
        context.setState(state);
        // Run action if executor is set
        if (resolvedTransition.getAfterAction() != null) {
            resolvedTransition.getAfterAction().execute(executionContext, context);
        }
    }<commit_msg>Execution of before and after actions<commit_after>package com.lynx.fsm;

import java.util.Collection;

import com.google.common.collect.Multimap;

/**
 * Abstract state machine providing validation and configuration operations
 * 
 * @author daniel.las
 *
 * @param <S>
 * @param <C>
 */
public abstract class StateMachine<S extends StateType, C extends StateHolder<S>, X> implements Forwardable<S>,
        ContextHolder<C>, BeanValidating, Secured, Configurable<S, C, X>, StateProvider<S>, ExecutionContextAware<X> {

    S state;
    C context;
    Multimap<S, Transition<S, C, X>> transitions;
    X executionContext;

    @Override
    public void forward() {
        if (state.isFinal()) {
            throw new StateMachineException("Machine is in FINAL state");
        }
        Collection<Transition<S, C, X>> possibleEnds = transitions.get(state);
        Transition<S, C, X> resolvedTransition = null;

        // There are no transitions for start state, no knowledge what to do
        if (possibleEnds.isEmpty()) {
            throw new StateMachineException(String.format("There are no transitions for start state %s", state));
        }
        // We have only one transition with given start
        if (possibleEnds.size() == 1) {
            resolvedTransition = possibleEnds.iterator().next();

            // There is condition which must be met
            if (resolvedTransition.getCondition() != null) {
                // Condition is not met
                if (!resolvedTransition.getCondition().check(resolvedTransition.getEnd(), context)) {
                    throw new StateMachineException(String.format("Condition for transition from %s to %s is not met",
                            state, resolvedTransition.getEnd()));
                }
            }
        } else {
            Transition<S, C, X> goodEnd = null;

            for (Transition<S, C, X> end : possibleEnds) {
                if (end.getCondition() == null) {
                    throw new StateMachineException(
                            String.format("There is no condition for possible transition from %s to %s. Decision can't be taken when no state is requested."));
                }
                if (end.getCondition().check(end.getEnd(), context)) {
                    // We already have good end so next state is ambiguous
                    if (goodEnd != null) {
                        throw new StateMachineException(
                                "There is more than one transition from state %s fullfilling condition");
                    }
                    goodEnd = end;
                }
            }
            resolvedTransition = goodEnd;
        }
        // No transition fulfilling conditions found
        if (resolvedTransition == null) {
            throw new StateMachineException(String.format(
                    "No transition fulfilling confition found for start state %s ", state));
        }
        // All is fine, we can validate, check permissions and move to next
        // state
        // Security is set, check permissions
        if (resolvedTransition.getRoles() != null) {
            checkPermissions(resolvedTransition.getRoles());
        }
        // Run action if executor is set
        if (resolvedTransition.getBeforeAction() != null) {
            resolvedTransition.getBeforeAction().execute(executionContext, context);
        }
        // Validation groups are set, process validation
        if (resolvedTransition.getValidationGroups() != null) {
            validate(resolvedTransition.getValidationGroups());
        }
        if (resolvedTransition.getValidator() != null) {
            resolvedTransition.getValidator().validate(resolvedTransition.getEnd(), context);
        }
        // Everything passed, we are good to go,
        state = resolvedTransition.getEnd();
        context.setState(state);
        // Run action if executor is set
        if (resolvedTransition.getAfterAction() != null) {
            resolvedTransition.getAfterAction().execute(executionContext, context);
        }
    }

    @Override
    public void forward(S requestedState) {
        if (state.isFinal()) {
            throw new StateMachineException("Machine is in FINAL state");
        }
        Collection<Transition<S, C, X>> possibleEnds = transitions.get(state);
        Transition<S, C, X> resolvedTransition = null;

        // There are no transitions for start state, no knowledge what to do
        if (possibleEnds.isEmpty()) {
            throw new StateMachineException(String.format("There are no transitions for start state %s", state));
        }
        // Find transition with end equals requestedState
        for (Transition<S, C, X> end : possibleEnds) {
            if (requestedState.equals(end.getEnd())) {
                resolvedTransition = end;
            }
        }
        // No transition found
        if (resolvedTransition == null) {
            throw new StateMachineException(String.format("No transition found for start state %s and end state %s",
                    state, requestedState));
        }
        // Good transition found, check condition if exists
        if (resolvedTransition.getCondition() != null) {
            if (!resolvedTransition.getCondition().check(requestedState, context)) {
                throw new StateMachineException(String.format(
                        "No transition fulfilling confition found for start state %s and requested state %s", state,
                        requestedState));
            }

        }
        // All is fine, we can validate, check permissions and move to next
        // state
        // Security is set, check permissions
        if (resolvedTransition.getRoles() != null) {
            checkPermissions(resolvedTransition.getRoles());
        }
        // Run action if executor is set
        if (resolvedTransition.getBeforeAction() != null) {
            resolvedTransition.getBeforeAction().execute(executionContext, context);
        }
        // Validation groups are set, process Bean validation
        if (resolvedTransition.getValidationGroups() != null) {
            validate(resolvedTransition.getValidationGroups());
        }
        // Business validator is set, process business validation
        if (resolvedTransition.getValidator() != null) {
            resolvedTransition.getValidator().validate(requestedState, context);
        }
        // Everything passed, we are good to go,
        state = resolvedTransition.getEnd();
        context.setState(state);
        // Run action if executor is set
        if (resolvedTransition.getAfterAction() != null) {
            resolvedTransition.getAfterAction().execute(executionContext, context);
        }
    }
{'fraction_non_alphanumeric': 0.09368324687213915, 'fraction_numerical': 0.00015257857796765334, 'mean_word_length': 2.1019876952200662, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1681161', 'n_tokens_mistral': 3096, 'n_tokens_neox': 3000, 'n_words': 981}