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

io.microlam.hsm.impl.BasicHsm Maven / Gradle / Ivy

package io.microlam.hsm.impl;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.microlam.hsm.Action;
import io.microlam.hsm.EntryExitAction;
import io.microlam.hsm.Event;
import io.microlam.hsm.Hsm;
import io.microlam.hsm.State;

public class BasicHsm implements Hsm {

	private static Logger LOGGER = LoggerFactory.getLogger(BasicHsm.class);

	protected final String name;
	protected final String initialState;
	protected Map> states = new HashMap<>();
	protected State resolvedInitState;

	public BasicHsm(String name, String initialState) {
		this.name = name;
		this.initialState = initialState;
	}
	
	public void registerState(State state) {
		states.put(state.getName(), state);
	}
	
	@Override
	public State resolveState(String name) {
		return states.get(name);
	}

	@Override
	public Hsm getHsm() {
		return this;
	}

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

	@Override
	public State getParentState() {
		return resolveInitState().getParentState();
	}

	@Override
	public State getChildInitialState() {
		return resolveInitState().getChildInitialState();
	}

	@Override
	public EntryExitAction getEntryAction() {
		return resolveInitState().getEntryAction();
	}

	@Override
	public Action getInnerAction() {
		return resolveInitState().getInnerAction();
	}

	@Override
	public EntryExitAction getExitAction() {
		return resolveInitState().getExitAction();
	}
	
	private State goToLeaf(State child, Event event, C context) {
		if (child.getEntryAction() != null) {
			child.getEntryAction().process(null, context);
		}
		if (child.getChildInitialState() != null) {
			return goToLeaf(child.getChildInitialState(), event, context);
		}
		return child;
	}
	
	@Override
	public String process(Event event, C context) {
		State leaf = goToLeaf(resolveState(initialState), event, context);
		LOGGER.debug("Go to leaf state [{}] from state [{}]", leaf.getName(), getName());
		return leaf.process(event, context);
	}

	public StateBuilder stateBuilder() {
		return new StateBuilder<>(this);
	}
	
	@Override
	public State initState(C context) {
		return goToLeaf(resolveState(initialState), context);
	}
	
	
	public State goToLeaf(State child, C context) {
		if (child.getEntryAction() != null) {
			child.getEntryAction().process(null, context);
		}
		if (child.getChildInitialState() != null) {
			return goToLeaf(child.getChildInitialState(), null, context);
		}
		return child;
	}

	
	private State resolveInitState() {
		State currentState;
		State  childState;
		currentState = resolveState(initialState);
		childState = currentState;
		while(childState != null) {
			childState = currentState.getChildInitialState();
			if (childState != null) {
				currentState = childState;
			}
		}
		return currentState;
	}


	@Override
	public boolean isDescendentOf(String name) {
		//return resolveState(initialState).isDescendentOf(name);
		return false;
	}


}