
org.squirrelframework.foundation.fsm.impl.StateMachineDataImpl Maven / Gradle / Ivy
package org.squirrelframework.foundation.fsm.impl;
import static com.google.common.base.Preconditions.checkState;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.squirrelframework.foundation.fsm.*;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Maps;
public class StateMachineDataImpl, S, E, C>
implements StateMachineData,
StateMachineData.Reader,
StateMachineData.Writer {
private static final long serialVersionUID = 4102325896046410596L;
private static final Logger logger = LoggerFactory
.getLogger(StateMachineDataImpl.class);
private S currentState;
private S lastState;
private S initialState;
private final Map lastActiveChildStateStore = Maps.newHashMap();
private final ListMultimap parallelStatesStore = ArrayListMultimap.create();
private Class extends T> stateMachineType;
private Class stateType;
private Class eventType;
private Class contextType;
private String identifier;
private Object startContext;
private final transient Map> states;
private Map, S, E, C>> linkStateDataStore;
public StateMachineDataImpl(Map> states) {
this.states = Collections.unmodifiableMap(states);
}
public StateMachineDataImpl() {
this.states = null;
}
@Override
public Map> originalStates() {
if (states == null) {
return Collections.emptyMap();
}
return states;
}
private void clear() {
currentState = null;
lastState = null;
initialState = null;
stateMachineType = null;
stateType = null;
eventType = null;
contextType = null;
identifier = null;
startContext = null;
if(lastActiveChildStateStore!=null) {
lastActiveChildStateStore.clear();
}
if(parallelStatesStore!=null) {
parallelStatesStore.clear();
}
if(linkStateDataStore!=null) {
linkStateDataStore.clear();
}
}
@Override
public void dump(StateMachineData.Reader src) {
clear();
this.write().typeOfStateMachine(src.typeOfStateMachine());
this.write().typeOfState(src.typeOfState());
this.write().typeOfEvent(src.typeOfEvent());
this.write().typeOfContext(src.typeOfContext());
this.write().identifier(src.identifier());
this.write().currentState(src.currentState());
this.write().lastState(src.lastState());
this.write().initialState(src.initialState());
// write start context of state machine
this.write().startContext(src.startContext());
for (S state : src.activeParentStates()) {
S lastActiveChildState = src.lastActiveChildStateOf(state);
if (lastActiveChildState != null) {
this.write().lastActiveChildStateFor(state, lastActiveChildState);
}
}
for (S state : src.parallelStates()) {
List subStates = src.subStatesOn(state);
if (subStates != null && !subStates.isEmpty()) {
for (S subState : subStates) {
// ignore parallel state check in subStateFor as no states
// for reference
// this.write().subStateFor(state, subState);
parallelStatesStore.put(state, subState);
}
}
}
}
private Map, S, E, C>> getLinkedStateData() {
if (linkStateDataStore == null) {
linkStateDataStore = Maps.newHashMap();
}
return linkStateDataStore;
}
@Override
public StateMachineData.Reader read() {
return this;
}
@Override
public StateMachineData.Writer write() {
return this;
}
@Override
public void currentState(S currentStateId) {
this.currentState = currentStateId;
}
@Override
public void lastState(S lastStateId) {
this.lastState = lastStateId;
}
@Override
public void initialState(S initialStateId) {
this.initialState = initialStateId;
}
@Override
public void startContext(C context) {
if(context!=null && context instanceof Serializable)
startContext = context;
}
@Override
public void lastActiveChildStateFor(S parentStateId, S childStateId) {
lastActiveChildStateStore.put(parentStateId, childStateId);
}
@Override
public void subStateFor(S parentStateId, S subStateId) {
if (rawStateFrom(parentStateId) != null
&& rawStateFrom(parentStateId).isParallelState()
&& !parallelStatesStore.containsEntry(parentStateId, subStateId)) {
parallelStatesStore.put(parentStateId, subStateId);
} else {
logger.warn("Cannot set sub states on none parallel state {}.",
parentStateId);
}
}
@Override
public void removeSubState(S parentStateId, S subStateId) {
if (rawStateFrom(parentStateId) != null
&& rawStateFrom(parentStateId).isParallelState()) {
parallelStatesStore.remove(parentStateId, subStateId);
} else {
logger.warn("Cannot remove sub states on none parallel state {}.",
parentStateId);
}
}
@Override
public void removeSubStatesOn(S parentStateId) {
if (rawStateFrom(parentStateId).isParallelState()) {
parallelStatesStore.removeAll(parentStateId);
}
}
@Override
public void identifier(String id) {
this.identifier = id;
}
@Override
public String identifier() {
return identifier;
}
@Override
public S currentState() {
return currentState;
}
@Override
public S lastState() {
return lastState;
}
@Override
public S initialState() {
return initialState;
}
@Override
public S lastActiveChildStateOf(S parentStateId) {
return lastActiveChildStateStore.get(parentStateId);
}
@Override
public C startContext() {
return (C)startContext;
}
@Override
public Collection activeParentStates() {
return Collections.unmodifiableCollection(lastActiveChildStateStore.keySet());
}
@Override
public List subStatesOn(S parentStateId) {
List subStates = parallelStatesStore.get(parentStateId);
return subStates != null ? Collections.unmodifiableList(subStates)
: Collections. emptyList();
}
@Override
public ImmutableState currentRawState() {
return currentState!=null ? rawStateFrom(currentState) : null;
}
@Override
public ImmutableState lastRawState() {
return rawStateFrom(lastState);
}
@Override
public ImmutableState rawStateFrom(S stateId) {
if(stateId==null) return null;
ImmutableState rawState = originalStates().get(stateId);
return rawState!=null ? rawState.getThis() : null;
}
@Override
public ImmutableState initialRawState() {
return rawStateFrom(initialState());
}
@Override
public Class extends T> typeOfStateMachine() {
return stateMachineType;
}
@Override
public Class typeOfState() {
return stateType;
}
@Override
public Class typeOfEvent() {
return eventType;
}
@Override
public Class typeOfContext() {
return contextType;
}
@Override
public void typeOfStateMachine(Class extends T> stateMachineType) {
checkState(this.stateMachineType==null);
this.stateMachineType = stateMachineType;
}
@Override
public void typeOfState(Class stateClass) {
checkState(this.stateType==null);
this.stateType = stateClass;
}
@Override
public void typeOfEvent(Class eventClass) {
checkState(this.eventType==null);
this.eventType = eventClass;
}
@Override
public void typeOfContext(Class contextClass) {
checkState(this.contextType==null);
this.contextType = contextClass;
}
@Override
public Collection> rawStates() {
return Collections.unmodifiableCollection(originalStates().values());
}
@Override
public Collection states() {
return Collections.unmodifiableCollection(originalStates().keySet());
}
@Override
public Collection parallelStates() {
return Collections.unmodifiableCollection(parallelStatesStore.keySet());
}
@Override
public Collection linkedStates() {
if (linkStateDataStore == null || linkStateDataStore.isEmpty()) {
return Collections.emptySet();
}
return Collections.unmodifiableCollection(linkStateDataStore.keySet());
}
@Override
public StateMachineData.Reader extends StateMachine, S, E, C>, S, E, C> linkedStateDataOf(
S linkedState) {
if (linkStateDataStore != null && !linkStateDataStore.isEmpty())
return linkStateDataStore.get(linkedState);
return null;
}
@Override
public void linkedStateDataOn(S linkedState,
StateMachineData.Reader extends StateMachine, S, E, C>, S, E, C> linkStateData) {
getLinkedStateData().put(linkedState, linkStateData);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy