better finding state machines

This commit is contained in:
2026-06-07 10:24:33 +02:00
parent c8975eddde
commit f780620cf9
10 changed files with 383 additions and 29 deletions

View File

@@ -0,0 +1,139 @@
package click.kamil.examples.statemachine.inheritanceextrafunctionsstate3;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.config.configurers.ExternalTransitionConfigurer;
import org.springframework.statemachine.config.configurers.StateConfigurer;
import org.springframework.statemachine.guard.Guard;
abstract class AbstractGStateMachineConfiguration extends AbstractStateMachineConfiguration<States, Events> {
protected abstract void addAdditionalStates(StateConfigurer<States, Events> states);
protected abstract void addAdditionalCancellationTransitions(StateMachineTransitionConfigurer<States, Events> transitions);
protected abstract void addAdditionalTransitions(ExternalTransitionConfigurer<States, Events> transitions) throws Exception;
protected void addAllCancellationTransitionsForSource(StateMachineTransitionConfigurer<States, Events> transitions, States source) {
addCancellationTransitionForCancelEvents(transitions, source, Events.EVENT_CANCEL);
}
private void addCancellationTransitionForCancelEvents(
StateMachineTransitionConfigurer<States, Events> transitions,
States source,
Events... cancelEvents) {
addTransitionForMultipleEvents(
transitions,
source,
States.CANCEL,
transitionConfigurer -> transitionConfigurer.action((context) -> System.out.println(context.getEvent().toString() + " " + context.getTransition().toString())),
cancelEvents
);
}
@Override
public void configure(StateMachineConfigurationConfigurer<States, Events> config) throws Exception {
config
.withConfiguration()
.autoStartup(true);
}
@Override
public void configure(StateMachineStateConfigurer<States, Events> states) throws Exception {
StateConfigurer<States, Events> end = states
.withStates()
.initial(States.STATE1)
.state(States.STATE2)
.state(States.STATE3)
.state(States.STATE4)
.state(States.STATE5)
.state(States.STATE6)
.state(States.STATE7)
.state(States.STATE8)
.state(States.STATE9)
.state(States.STATE10)
.state(States.STATEX)
.choice(States.STATEY)
.end(States.STATEZ);
addAdditionalStates(end);
}
@Override
public void configure(StateMachineTransitionConfigurer<States, Events> transitions) throws Exception {
// External transitions
ExternalTransitionConfigurer<States, Events> t1 = transitions
.withExternal().source(States.STATE1).target(States.STATE2).event(Events.EVENT1)
.and()
.withExternal().source(States.STATE2).target(States.STATE3).event(Events.EVENT2)
.and()
.withExternal().source(States.STATE3).target(States.STATE4).event(Events.EVENT3)
.and()
.withExternal().source(States.STATE4).target(States.STATE5).event(Events.EVENT4)
.and()
.withExternal().source(States.STATE5).target(States.STATE6).event(Events.EVENT5)
.and()
.withExternal().source(States.STATE6).target(States.STATE7).event(Events.EVENT6)
.and()
.withExternal().source(States.STATE7).target(States.STATE8).event(Events.EVENT7)
.and()
.withExternal().source(States.STATE8).target(States.STATE9).event(Events.EVENT8)
.and()
.withExternal().source(States.STATE9).target(States.STATE10).event(Events.EVENT9);
transitions.withExternal().source(States.STATE1).target(States.CANCEL).event(Events.EVENT_CANCEL)
.and()
.withExternal().source(States.STATE2).target(States.CANCEL).event(Events.EVENT_CANCEL)
.and()
.withExternal().source(States.STATE3).target(States.CANCEL).event(Events.EVENT_CANCEL)
.and()
.withExternal().source(States.STATE4).target(States.CANCEL).event(Events.EVENT_CANCEL)
.and()
.withExternal().source(States.STATE5).target(States.CANCEL).event(Events.EVENT_CANCEL);
// EXTRA CHOICE
transitions.withExternal().source(States.STATE4).target(States.STATEY).event(Events.EVENTY);
transitions.withChoice().source(States.STATEY).first(States.STATEX, guardVarEquals("value1")).last(States.STATEZ);
// Choice transitions
transitions
.withChoice()
.source(States.STATE9)
.first(States.STATE8, guardVarEquals("stepBack"))
.then(States.STATE7, guardVarEquals("stepBackMore"))
.last(States.STATE6)
.and()
.withChoice()
.source(States.STATE8)
.first(States.STATE9, guardVarEquals("forward9"))
.last(States.STATE10);
addAdditionalTransitions(t1);
addAdditionalCancellationTransitions(transitions);
}
protected Guard<States, Events> guardVarEquals(String expected) {
return context -> {
Object var = context.getExtendedState().getVariables().get("var");
return expected.equals(var);
};
}
protected Guard<States, Events> guardEventHeaderEquals(String headerName, String expected) {
return context -> {
Object header = context.getMessageHeader(headerName);
return expected.equals(header);
};
}
private Action<States, Events> logEntryAction(String msg) {
return context -> System.out.println(msg);
}
private Action<States, Events> logExitAction(String msg) {
return context -> System.out.println(msg);
}
}

View File

@@ -0,0 +1,42 @@
package click.kamil.examples.statemachine.inheritanceextrafunctionsstate3;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.config.configurers.ExternalTransitionConfigurer;
import org.springframework.statemachine.config.configurers.StateConfigurer;
class F2StateMachineConfiguration extends AbstractFStateMachineConfiguration {
@Override
protected void addAdditionalStates(StateConfigurer<States, Events> states) {
states.state(States.STATE_EXTRA_1_1);
states.state(States.STATE_EXTRA_1_2);
states.state(States.STATE_EXTRA_1);
states.state(States.STATE_EXTRA_1_3);
}
@Override
protected void addAdditionalCancellationTransitions(StateMachineTransitionConfigurer<States, Events> transitions) {
addAllCancellationTransitionsForSource(transitions, States.STATE_EXTRA_1_1);
addAllCancellationTransitionsForSource(transitions, States.STATE_EXTRA_1_2);
addAllCancellationTransitionsForSource(transitions, States.STATE_EXTRA_1);
}
@Override
protected void addAdditionalTransitions(ExternalTransitionConfigurer<States, Events> transitions) throws Exception {
transitions
.and()
.withExternal().event(Events.EVENT_1_1)
.source(States.STATE9)
.target(States.STATE_EXTRA_1_1)
.and()
.withChoice()
.source(States.STATE_EXTRA_1_2)
.first(States.STATE_EXTRA_1_1, guardEventHeaderEquals("header1", "foo"))
.last(States.STATE_EXTRA_1_3)
.and()
.withExternal()
.source(States.STATE_EXTRA_1_3)
.event(Events.EVENT_1_2)
.target(States.STATE_EXTRA_1);
}
}

View File

@@ -0,0 +1,32 @@
package click.kamil.examples.statemachine.inheritanceextrafunctionsstate3;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.config.configurers.ExternalTransitionConfigurer;
import org.springframework.statemachine.config.configurers.StateConfigurer;
class G1StateMachineConfiguration extends AbstractGStateMachineConfiguration {
@Override
protected void addAdditionalStates(StateConfigurer<States, Events> states) {
states.state(States.STATE_EXTRA_2);
states.state(States.STATE_EXTRA_3);
}
@Override
protected void addAdditionalCancellationTransitions(StateMachineTransitionConfigurer<States, Events> transitions) {
addAllCancellationTransitionsForSource(transitions, States.STATE_EXTRA_3);
}
@Override
protected void addAdditionalTransitions(ExternalTransitionConfigurer<States, Events> transitions) throws Exception {
transitions
.and()
.withExternal().event(Events.EVENT_1_2)
.source(States.STATE3)
.target(States.STATE_EXTRA_2)
.and()
.withExternal().event(Events.EVENT_1_2)
.source(States.STATE_EXTRA_2)
.target(States.STATE_EXTRA_3);
}
}

View File

@@ -0,0 +1,32 @@
package click.kamil.examples.statemachine.inheritanceextrafunctionsstate3;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.config.configurers.ExternalTransitionConfigurer;
import org.springframework.statemachine.config.configurers.StateConfigurer;
class G2StateMachineConfiguration extends AbstractGStateMachineConfiguration {
@Override
protected void addAdditionalStates(StateConfigurer<States, Events> states) {
states.state(States.STATE_EXTRA_1);
states.state(States.STATE_EXTRA_2);
}
@Override
protected void addAdditionalCancellationTransitions(StateMachineTransitionConfigurer<States, Events> transitions) {
addAllCancellationTransitionsForSource(transitions, States.STATE_EXTRA_1);
addAllCancellationTransitionsForSource(transitions, States.STATE_EXTRA_2);
}
@Override
protected void addAdditionalTransitions(ExternalTransitionConfigurer<States, Events> transitions) throws Exception {
transitions
.and()
.withExternal().event(Events.EVENT_1_2)
.source(States.STATE3)
.target(States.STATE_EXTRA_1)
.and()
.withExternal().event(Events.EVENT_1_3)
.source(States.STATE_EXTRA_1)
.target(States.STATE_EXTRA_2);
}
}