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

io.github.yangziwen.quickstate.impl.StateMachineImpl Maven / Gradle / Ivy

There is a newer version: 0.0.5
Show newest version
package io.github.yangziwen.quickstate.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import io.github.yangziwen.quickstate.State;
import io.github.yangziwen.quickstate.StateMachine;
import io.github.yangziwen.quickstate.Transition;
import io.github.yangziwen.quickstate.Visitor;
import lombok.Getter;
import lombok.Setter;

public class StateMachineImpl implements StateMachine {

    @Getter
    private final String id;

    private final Map> stateMap;

    @Getter
    @Setter
    private boolean ready;

    public StateMachineImpl(String id, Map> stateMap) {
        this.id = id;
        this.stateMap = stateMap;
    }

    @Override
    public List> getAllStates() {
        return new ArrayList<>(stateMap.values());
    }

    @Override
    public List> getTransitions(S sourceId) {
        State source = ensureState(sourceId);
        return source.getAllTransitions();
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    @Override
    @SuppressWarnings("unchecked")
    public S fire(S sourceId, E event, C context) {
        if (!ready) {
            throw new StateMachineException("State machine[" + id + "] is not built yet, can not work");
        }
        if (context instanceof ContextImpl) {
            ContextImpl.class.cast(context).setStateMachine(this);
        }
        State source = ensureState(sourceId);
        State target = doTransition(source, event, context);
        return target != null ? target.getId() : null;
    }

    @Override
    public boolean canApply(S sourceId, E event) {
        State source = ensureState(sourceId);
        List> transitions = source.getTransitions(event);
        return CollectionUtils.isNotEmpty(transitions);
    }

    private State doTransition(State source, E event, C context) {
        List> transitions = source.getTransitions(event);
        if (CollectionUtils.isEmpty(transitions)) {
            return null;
        }
        for (Transition transition : transitions) {
            if (transition.test(context)) {
                return transition.transit(context);
            }
        }
        return null;
    }

    private State ensureState(S stateId) {
        State state = stateMap.get(stateId);
        if(state == null) {
            state = new StateImpl<>(stateId);
            stateMap.put(stateId, state);
        }
        return state;
    }

    @Override
    public String toString() {
        return "state machine[" + getId() + "] with states [" + StringUtils.join(stateMap.keySet().toArray(), ", ") + "]";
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy