more examples

This commit is contained in:
2026-06-07 10:24:19 +02:00
parent 2ecc8e08de
commit c8975eddde
16 changed files with 811 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
HELP.md
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
#### added
*.png
*.dot
*.scxml.xml
Combined.java

View File

@@ -0,0 +1,42 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.5.3'
id 'io.spring.dependency-management' version '1.1.7'
}
group = 'click.kamil'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.statemachine:spring-statemachine-starter:3.2.0'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}

View File

@@ -0,0 +1,203 @@
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 AbstractFStateMachineConfiguration 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_2);
}
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.STATE11)
.state(States.STATE12)
.state(States.STATE13)
.state(States.STATE14)
.state(States.STATE15)
.state(States.STATE16)
.state(States.STATE17)
.state(States.STATE18)
.state(States.STATE19)
.state(States.STATE20)
.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)
.and()
.withExternal().source(States.STATE10).target(States.STATE11).event(Events.EVENT10)
.and()
.withExternal().source(States.STATE11).target(States.STATE12).event(Events.EVENT11)
.and()
.withExternal().source(States.STATE12).target(States.STATE13).event(Events.EVENT12)
.and()
.withExternal().source(States.STATE13).target(States.STATE14).event(Events.EVENT13)
.and()
.withExternal().source(States.STATE14).target(States.STATE15).event(Events.EVENT14)
.and()
.withExternal().source(States.STATE15).target(States.STATE16).event(Events.EVENT15);
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 (at least 10)
transitions
.withChoice()
.source(States.STATE16)
.first(States.STATE17, guardVarEquals("value1"))
.then(States.STATE18, guardVarEquals("value2"))
.last(States.STATE19)
.and()
.withChoice()
.source(States.STATE17)
.first(States.STATE20, guardEventHeaderEquals("header1", "foo"))
.last(States.STATE16)
.and()
.withChoice()
.source(States.STATE18)
.first(States.STATE19, guardVarEquals("value3"))
.last(States.STATE20)
.and()
.withChoice()
.source(States.STATE19)
.first(States.STATE1, guardVarEquals("reset"))
.last(States.STATE20)
.and()
.withChoice()
.source(States.STATE20)
.first(States.STATE5, guardEventHeaderEquals("header2", "bar"))
.last(States.STATE1)
.and()
.withChoice()
.source(States.STATE11)
.first(States.STATE13, guardVarEquals("goTo13"))
.then(States.STATE14, guardVarEquals("goTo14"))
.last(States.STATE15)
.and()
.withChoice()
.source(States.STATE12)
.first(States.STATE10, guardVarEquals("goBack10"))
.last(States.STATE11)
.and()
.withChoice()
.source(States.STATE14)
.first(States.STATE12, guardVarEquals("loop12"))
.last(States.STATE16)
.and()
.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,27 @@
package click.kamil.examples.statemachine.inheritanceextrafunctionsstate3;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.config.configurers.ExternalTransitionConfigurer;
import java.util.function.Consumer;
import java.util.stream.Stream;
class AbstractStateMachineConfiguration<S,E> extends StateMachineConfigurerAdapter<S,E> {
protected void addTransitionForMultipleEvents(
StateMachineTransitionConfigurer<S, E> transitions,
S source,
S target,
Consumer<ExternalTransitionConfigurer<S,E>> transitionCustomizer,
E... events) {
Stream.of(events).forEach(event -> {
try {
ExternalTransitionConfigurer<S, E> transitionConfigurer =
transitions.withExternal().event(event).source(source).target(target);
transitionCustomizer.accept(transitionConfigurer);
} catch (Exception e) {
throw new IllegalStateException(e);
}
});
}
}

View File

@@ -0,0 +1,9 @@
package click.kamil.examples.statemachine.inheritanceextrafunctionsstate3;
public enum Events {
EVENT1, EVENT2, EVENT3, EVENT4, EVENT5,
EVENT6, EVENT7, EVENT8, EVENT9, EVENT10,
EVENT11, EVENT12, EVENT13, EVENT14, EVENT15,
EVENTX, EVENTY, EVENTZ, EVENT_CANCEL, EVENT_CANCEL_2,
EVENT_1_1, EVENT_1_2, EVENT_1_3, EVENT_1_4, EVENT_1_5
}

View File

@@ -0,0 +1,40 @@
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 F1StateMachineConfiguration extends AbstractFStateMachineConfiguration {
@Override
protected void addAdditionalStates(StateConfigurer<States, Events> states) {
states.state(States.STATE_EXTRA_1);
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_1);
addAllCancellationTransitionsForSource(transitions, States.STATE_EXTRA_2);
}
@Override
protected void addAdditionalTransitions(ExternalTransitionConfigurer<States, Events> transitions) throws Exception {
transitions
.and()
.withExternal().event(Events.EVENTX)
.source(States.STATE2)
.target(States.STATE_EXTRA_1)
.and()
.withChoice()
.source(States.STATE2)
.first(States.STATE1, guardEventHeaderEquals("header1", "foo"))
.last(States.STATE_EXTRA_1)
.and()
.withExternal()
.source(States.STATE_EXTRA_1)
.event(Events.EVENTY)
.target(States.STATE_EXTRA_3);
}
}

View File

@@ -0,0 +1,12 @@
package click.kamil.examples.statemachine.inheritanceextrafunctionsstate3;
public enum States {
STATE1, STATE2, STATE3, STATE4, STATE5,
STATE6, STATE7, STATE8, STATE9, STATE10,
STATE11, STATE12, STATE13, STATE14, STATE15,
STATE16, STATE17, STATE18, STATE19, STATE20,
STATEX, STATEY, STATEZ,
STATE_EXTRA_1, STATE_EXTRA_2, STATE_EXTRA_3,
STATE_EXTRA_1_1, STATE_EXTRA_1_2, STATE_EXTRA_1_3,
CANCEL
}

View File

@@ -0,0 +1,11 @@
package click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
class StateMachineApplication {
public static void main(String[] args) {
SpringApplication.run(StateMachineApplication.class, args);
}
}

View File

@@ -0,0 +1 @@
spring.application.name=statemachinedemo

View File

@@ -0,0 +1,11 @@
package click.kamil.examples.statemachine;
import org.junit.jupiter.api.Test;
class MyTest {
@Test
void contextLoads() {
}
}