Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.microlam.hsm.impl.BasicState Maven / Gradle / Ivy
package io.microlam.hsm.impl;
import java.util.Set;
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 BasicState implements State {
private static Logger LOGGER = LoggerFactory.getLogger(BasicState.class);
protected final BasicHsm hsm;
protected final String name;
protected final String parent;
protected final String initialChild;
protected final Action inner;
protected final EntryExitAction entry, exit;
protected Set descendents;
public BasicState(BasicHsm hsm, String name, String parent, String initialChild, EntryExitAction entry, EntryExitAction exit, Action inner) {
this.hsm = hsm;
this.name = name;
this.parent = parent;
this.initialChild = initialChild;
this.entry = entry;
this.exit = exit;
this.inner = inner;
}
public boolean isDescendentOf(String name) {
if (parent != null) {
if (parent.equals(name)) {
return true;
}
else {
return hsm.resolveState(parent).isDescendentOf(name);
}
}
else {
return false;
}
}
@Override
public State initState(C context) {
return goToLeaf(hsm.resolveState(initialChild), 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;
}
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;
}
State goToState(State from, State to, Event event, C context) {
LOGGER.debug("Go to state [{}] from state [{}]", to.getName(), from.getName());
if (from == to) {
if (from.getExitAction() != null) {
from.getExitAction().process(event, context);
}
if (from.getEntryAction() != null) {
from.getEntryAction().process(event, context);
}
LOGGER.debug("Same state [{}] so exit and enter", from.getName());
}
else if (to.isDescendentOf(from.getName())) {
goToDescendent(from, to, event, context);
LOGGER.debug("Go to descendent state [{}] from state [{}]", to.getName(), from.getName());
}
else if (from.isDescendentOf(to.getName())) {
goToAscendent(from, to, event, context);
if (to.getEntryAction() != null) {
to.getEntryAction().process(event, context);
}
LOGGER.debug("Go to ascendent state [{}] from state [{}]", to.getName(), from.getName());
}
else {
State commonAscendent = goToCommonAscendentOf(from, to, event, context);
LOGGER.debug("Go to common ascendent state [{}] of states [{}] and [{}]", commonAscendent.getName(), from.getName(), to.getName());
goToDescendent(from, to, event, context);
LOGGER.debug("Go to descendent state [{}] from state [{}]", to.getName(), commonAscendent.getName());
}
return to;
}
State goToDescendent(State from, State to, Event event, C context) {
if ((from != to) && (to.getParentState() != null)) {
goToDescendent(from, to.getParentState(), event, context);
if (to.getEntryAction() != null) {
to.getEntryAction().process(event, context);
}
}
return to;
}
State goToAscendent(State from, State to, Event event, C context) {
if (from.getExitAction() != null) {
from.getExitAction().process(event, context);
}
if ((from != to) && (from.getParentState() != null)) {
return goToAscendent(from.getParentState(), to, event, context);
}
return to;
}
State goUpToAscendent(State from, State to, Event event, C context) {
if (from.getExitAction() != null) {
from.getExitAction().process(event, context);
}
if (from.getParentState() == to) {
return from;
}
if ((from.getParentState() != to) && (from.getParentState() != null)) {
return goUpToAscendent(from.getParentState(), to, event, context);
}
return null;
}
State goToCommonAscendentOf(State from, State to, Event event, C context) {
if (to.isDescendentOf(from.getName())) {
return from;
}
if (from.getExitAction() != null) {
from.getExitAction().process(event, context);
}
if (from.getParentState() != null) {
return goToCommonAscendentOf(from.getParentState(), to, event, context);
}
return null;
}
@Override
public String process(Event event, C context) {
if (initialChild != null) {
State leaf = goToLeaf(hsm.resolveState(initialChild), event, context);
LOGGER.debug("Go to leaf state [{}] from state [{}]", leaf.getName(), getName());
return leaf.process(event, context);
}
String result = inner.process(event, context);
if (result != null) {
State newState = goToState(this, hsm.resolveState(result), event, context);
return newState.process(event, context);
}
else {
SourceResult sourceResult = callParentsInnerForSourceResult(hsm.resolveState(parent), event, context);
result = sourceResult.result;
if (result != null) {
LOGGER.debug("Exit up to Source State [{}]:", sourceResult.source.getName());
goUpToAscendent(this, sourceResult.source, event, context);
goToState(sourceResult.source, hsm.resolveState(result), event, context);
if (hsm.resolveState(result).getChildInitialState() != null) {
State leaf = goToLeaf(hsm.resolveState(result).getChildInitialState(), event, context);
LOGGER.debug("Go to leaf state [{}] from state [{}]", leaf.getName(), hsm.resolveState(result).getName());
return leaf.getName();
}
return result;
}
}
LOGGER.debug("Ignoring... and staying on State [{}]", getName());
return getName();
}
private SourceResult callParentsInnerForSourceResult(State parent, Event event, C context) {
SourceResult sourceResult = null;
String result = parent.getInnerAction().process(event, context);
if (result != null) {
sourceResult = new SourceResult(parent, result);
}
if ((result == null) && (parent.getParentState() != null)) {
sourceResult = callParentsInnerForSourceResult(parent.getParentState(), event, context);
result = sourceResult.result;
}
else if (result == null) {
sourceResult = new SourceResult(parent, result);
}
return sourceResult;
}
// private String callParentsInner(State parent, Event event, C context) {
// String result = parent.getInnerAction().process(event, context);
// if ((result == null) && (parent.getParentState() != null)) {
// result = callParentsInner(parent.getParentState(), event, context);
// }
// return result;
// }
@Override
public Hsm getHsm() {
return hsm;
}
@Override
public String getName() {
return name;
}
@Override
public State getParentState() {
return hsm.resolveState(parent);
}
@Override
public State getChildInitialState() {
return hsm.resolveState(initialChild);
}
@Override
public EntryExitAction getEntryAction() {
return entry;
}
@Override
public Action getInnerAction() {
return inner;
}
@Override
public EntryExitAction getExitAction() {
return exit;
}
class SourceResult {
final State source;
final String result;
public SourceResult(State source, String result) {
this.source = source;
this.result = result;
}
}
}