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

com.cmt.statemachine.impl.TransitionImpl Maven / Gradle / Ivy

The newest version!
package com.cmt.statemachine.impl;

import com.cmt.statemachine.*;

/**
 * TransitionImpl。
 *
 * This should be designed to be immutable, so that there is no thread-safe risk
 *
 * @author Frank Zhang
 * @date 2020-02-07 10:32 PM
 */
public class TransitionImpl implements Transition {

    private State source;

    private State target;

    private E event;

    private Condition condition;

    private String conditionDesc;

    private Action action;

    private TransitionType type = TransitionType.EXTERNAL;

    @Override
    public State getSource() {
        return source;
    }

    @Override
    public void setSource(State state) {
        this.source = state;
    }

    @Override
    public E getEvent() {
        return this.event;
    }

    @Override
    public void setEvent(E event) {
        this.event = event;
    }

    @Override
    public void setType(TransitionType type) {
        this.type = type;
    }

    @Override
    public State getTarget() {
        return this.target;
    }

    @Override
    public void setTarget(State target) {
        this.target = target;
    }

    @Override
    public Condition getCondition() {
        return this.condition;
    }

    @Override
    public  void setCondition(Condition condition) {
        this.condition = condition;
    }

    @Override
    public  void setCondition(Condition condition, String conditionDesc) {
        this.condition = condition;
        this.conditionDesc = conditionDesc;
    }

    @Override
    public  Action getAction() {
        return (Action) this.action;
    }

    @Override
    public  void setAction(Action action) {
        this.action = action;
    }

    @Override
    public  State transit(C request) {
        Debugger.debug("Do transition: "+this);
        this.verify();

        Condition cond = (Condition) condition;
        Action ac = (Action) action;
        if(cond == null || cond.isSatisfied(request)){
            setNextState(target,request);
            if(ac != null){
                ac.execute(request);
            }
            return target;
        }

        Debugger.debug("Condition is not satisfied, stay at the "+source+" state ");
        setNextState(source,request);
        return source;
    }

    @Override
    public  T transitWithResult(C request) {
        Debugger.debug("Do transition: "+this);
        this.verify();
        Condition cond = (Condition) condition;
        Action ac = (Action) action;
        return nullIfNotSatisfied(cond,request,ac,request);
    }

    @Override
    public final String toString() {
        return source + "-[" + event.toString() +", "+type+"]->" + target;
    }

    @Override
    public boolean equals(Object anObject){
        if(anObject instanceof Transition){
            Transition other = (Transition)anObject;
            if(this.event.equals(other.getEvent())
                    && this.source.equals(other.getSource())
                    && this.target.equals(other.getTarget())){
                return true;
            }
        }
        return false;
    }

    @Override
    public void verify() {
        if(type== TransitionType.INTERNAL && source != target) {
            throw new StateMachineException(String.format("Internal transition source state '%s' " +
                    "and target state '%s' must be same.", source, target));
        }
    }

    @Override
    public  T transitWithResult(C cond, R request) {
        Debugger.debug("Do transition: "+this);
        this.verify();
        Condition func = (Condition) condition;
        Action ac = (Action) action;
        return nullIfNotSatisfied(func,cond,ac,request);
    }

    @Override
    public String getConditionDesc() {
        return conditionDesc;
    }

    private  T nullIfNotSatisfied(Condition func, C cond, Action ac, R request) {
        if(func == null || func.isSatisfied(cond)){
            T t = null;
            setNextState(target,request);
            if(ac != null){
                t = ac.execute(request);
            }
            return t;
        }
        setNextState(source,request);
        return null;
    }

    private  void setNextState(State s, C request){
        if(request instanceof StateAware){
            ((StateAware) request).setNextState(s.getId());
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy