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,100 @@
package click.kamil.springstatemachineexporter.ast.common;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class CodebaseContextTest {
@TempDir
Path tempDir;
@Test
void shouldFindEntryPointByAnnotation() throws IOException {
String source = """
package com.example;
import org.springframework.statemachine.config.EnableStateMachine;
@EnableStateMachine
public class MyConfig {}
""";
Files.writeString(tempDir.resolve("MyConfig.java"), source);
CodebaseContext context = new CodebaseContext();
context.scan(tempDir);
List<TypeDeclaration> entryPoints = context.findEntryPointClasses(List.of("EnableStateMachine"));
assertThat(entryPoints).hasSize(1);
assertThat(entryPoints.get(0).getName().getIdentifier()).isEqualTo("MyConfig");
}
@Test
void shouldFindEntryPointByInheritance() throws IOException {
String baseSource = """
package com.example;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
public abstract class BaseConfig extends StateMachineConfigurerAdapter {}
""";
String leafSource = """
package com.example;
public class LeafConfig extends BaseConfig {}
""";
Files.writeString(tempDir.resolve("BaseConfig.java"), baseSource);
Files.writeString(tempDir.resolve("LeafConfig.java"), leafSource);
CodebaseContext context = new CodebaseContext();
context.scan(tempDir);
List<TypeDeclaration> entryPoints = context.findEntryPointClasses(List.of("EnableStateMachine"));
assertThat(entryPoints).hasSize(1);
assertThat(entryPoints.get(0).getName().getIdentifier()).isEqualTo("LeafConfig");
}
@Test
void shouldNotFindAbstractClassAsEntryPoint() throws IOException {
String source = """
package com.example;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
public abstract class MyConfig extends StateMachineConfigurerAdapter {}
""";
Files.writeString(tempDir.resolve("MyConfig.java"), source);
CodebaseContext context = new CodebaseContext();
context.scan(tempDir);
List<TypeDeclaration> entryPoints = context.findEntryPointClasses(List.of("EnableStateMachine"));
assertThat(entryPoints).isEmpty();
}
@Test
void shouldResolveInheritanceWithImports() throws IOException {
Files.createDirectories(tempDir.resolve("base"));
Files.createDirectories(tempDir.resolve("leaf"));
String baseSource = """
package com.example.base;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
public abstract class BaseConfig extends StateMachineConfigurerAdapter {}
""";
String leafSource = """
package com.example.leaf;
import com.example.base.BaseConfig;
public class LeafConfig extends BaseConfig {}
""";
Files.writeString(tempDir.resolve("base/BaseConfig.java"), baseSource);
Files.writeString(tempDir.resolve("leaf/LeafConfig.java"), leafSource);
CodebaseContext context = new CodebaseContext();
context.scan(tempDir);
List<TypeDeclaration> entryPoints = context.findEntryPointClasses(List.of("EnableStateMachine"));
assertThat(entryPoints).hasSize(1);
assertThat(entryPoints.get(0).getName().getIdentifier()).isEqualTo("LeafConfig");
}
}

View File

@@ -0,0 +1,76 @@
@startuml
skinparam state {
BackgroundColor<<choice>> LightYellow
}
[*] --> STATE1
state STATE17 <<choice>>
state STATE16 <<choice>>
state STATE2 <<choice>>
state STATE14 <<choice>>
state STATE12 <<choice>>
state STATE11 <<choice>>
state STATE8 <<choice>>
state STATEY <<choice>>
state STATE20 <<choice>>
state STATE9 <<choice>>
state STATE19 <<choice>>
state STATE18 <<choice>>
STATE1 -[#1E90FF,bold]-> STATE2 : EVENT1
STATE2 -[#1E90FF,bold]-> STATE3 : EVENT2
STATE3 -[#1E90FF,bold]-> STATE4 : EVENT3
STATE4 -[#1E90FF,bold]-> STATE5 : EVENT4
STATE5 -[#1E90FF,bold]-> STATE6 : EVENT5
STATE6 -[#1E90FF,bold]-> STATE7 : EVENT6
STATE7 -[#1E90FF,bold]-> STATE8 : EVENT7
STATE8 -[#1E90FF,bold]-> STATE9 : EVENT8
STATE9 -[#1E90FF,bold]-> STATE10 : EVENT9
STATE10 -[#1E90FF,bold]-> STATE11 : EVENT10
STATE11 -[#1E90FF,bold]-> STATE12 : EVENT11
STATE12 -[#1E90FF,bold]-> STATE13 : EVENT12
STATE13 -[#1E90FF,bold]-> STATE14 : EVENT13
STATE14 -[#1E90FF,bold]-> STATE15 : EVENT14
STATE15 -[#1E90FF,bold]-> STATE16 : EVENT15
STATE1 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE2 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE3 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE4 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE5 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE4 -[#1E90FF,bold]-> STATEY : EVENTY
STATEY -[#4682B4,bold]-> STATEX : [guardVarEquals("value1")] (order=0)
STATEY -[#4682B4,bold]-> STATEZ : (order=1)
STATE16 -[#4682B4,bold]-> STATE17 : [guardVarEquals("value1")] (order=0)
STATE16 -[#4682B4,bold]-> STATE18 : [guardVarEquals("value2")] (order=1)
STATE16 -[#4682B4,bold]-> STATE19 : (order=2)
STATE17 -[#FF6347,bold]-> STATE20 : [guardEventHeaderEquals("header1","foo")] (order=0)
STATE17 -[#FF6347,bold]-> STATE16 : (order=1)
STATE18 -[#FF69B4,bold]-> STATE19 : [guardVarEquals("value3")] (order=0)
STATE18 -[#FF69B4,bold]-> STATE20 : (order=1)
STATE19 -[#6A5ACD,bold]-> STATE1 : [guardVarEquals("reset")] (order=0)
STATE19 -[#6A5ACD,bold]-> STATE20 : (order=1)
STATE20 -[#32CD32,bold]-> STATE5 : [guardEventHeaderEquals("header2","bar")] (order=0)
STATE20 -[#32CD32,bold]-> STATE1 : (order=1)
STATE11 -[#FF69B4,bold]-> STATE13 : [guardVarEquals("goTo13")] (order=0)
STATE11 -[#FF69B4,bold]-> STATE14 : [guardVarEquals("goTo14")] (order=1)
STATE11 -[#FF69B4,bold]-> STATE15 : (order=2)
STATE12 -[#6A5ACD,bold]-> STATE10 : [guardVarEquals("goBack10")] (order=0)
STATE12 -[#6A5ACD,bold]-> STATE11 : (order=1)
STATE14 -[#FFD700,bold]-> STATE12 : [guardVarEquals("loop12")] (order=0)
STATE14 -[#FFD700,bold]-> STATE16 : (order=1)
STATE9 -[#FFD700,bold]-> STATE8 : [guardVarEquals("stepBack")] (order=0)
STATE9 -[#FFD700,bold]-> STATE7 : [guardVarEquals("stepBackMore")] (order=1)
STATE9 -[#FFD700,bold]-> STATE6 : (order=2)
STATE8 -[#FF6347,bold]-> STATE9 : [guardVarEquals("forward9")] (order=0)
STATE8 -[#FF6347,bold]-> STATE10 : (order=1)
STATE2 -[#1E90FF,bold]-> STATE_EXTRA_1 : EVENTX
STATE2 -[#32CD32,bold]-> STATE1 : [guardEventHeaderEquals("header1","foo")] (order=0)
STATE2 -[#32CD32,bold]-> STATE_EXTRA_1 : (order=1)
STATE_EXTRA_1 -[#1E90FF,bold]-> STATE_EXTRA_3 : EVENTY
STATE_EXTRA_1 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL_2
STATE_EXTRA_2 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL_2
STATEZ --> [*]
@enduml

View File

@@ -0,0 +1,77 @@
@startuml
skinparam state {
BackgroundColor<<choice>> LightYellow
}
[*] --> STATE1
state STATE17 <<choice>>
state STATE16 <<choice>>
state STATE14 <<choice>>
state STATE12 <<choice>>
state STATE11 <<choice>>
state STATE8 <<choice>>
state STATEY <<choice>>
state STATE20 <<choice>>
state STATE9 <<choice>>
state STATE_EXTRA_1_2 <<choice>>
state STATE19 <<choice>>
state STATE18 <<choice>>
STATE1 -[#1E90FF,bold]-> STATE2 : EVENT1
STATE2 -[#1E90FF,bold]-> STATE3 : EVENT2
STATE3 -[#1E90FF,bold]-> STATE4 : EVENT3
STATE4 -[#1E90FF,bold]-> STATE5 : EVENT4
STATE5 -[#1E90FF,bold]-> STATE6 : EVENT5
STATE6 -[#1E90FF,bold]-> STATE7 : EVENT6
STATE7 -[#1E90FF,bold]-> STATE8 : EVENT7
STATE8 -[#1E90FF,bold]-> STATE9 : EVENT8
STATE9 -[#1E90FF,bold]-> STATE10 : EVENT9
STATE10 -[#1E90FF,bold]-> STATE11 : EVENT10
STATE11 -[#1E90FF,bold]-> STATE12 : EVENT11
STATE12 -[#1E90FF,bold]-> STATE13 : EVENT12
STATE13 -[#1E90FF,bold]-> STATE14 : EVENT13
STATE14 -[#1E90FF,bold]-> STATE15 : EVENT14
STATE15 -[#1E90FF,bold]-> STATE16 : EVENT15
STATE1 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE2 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE3 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE4 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE5 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE4 -[#1E90FF,bold]-> STATEY : EVENTY
STATEY -[#FF6347,bold]-> STATEX : [guardVarEquals("value1")] (order=0)
STATEY -[#FF6347,bold]-> STATEZ : (order=1)
STATE16 -[#4682B4,bold]-> STATE17 : [guardVarEquals("value1")] (order=0)
STATE16 -[#4682B4,bold]-> STATE18 : [guardVarEquals("value2")] (order=1)
STATE16 -[#4682B4,bold]-> STATE19 : (order=2)
STATE17 -[#FF6347,bold]-> STATE20 : [guardEventHeaderEquals("header1","foo")] (order=0)
STATE17 -[#FF6347,bold]-> STATE16 : (order=1)
STATE18 -[#FF69B4,bold]-> STATE19 : [guardVarEquals("value3")] (order=0)
STATE18 -[#FF69B4,bold]-> STATE20 : (order=1)
STATE19 -[#6A5ACD,bold]-> STATE1 : [guardVarEquals("reset")] (order=0)
STATE19 -[#6A5ACD,bold]-> STATE20 : (order=1)
STATE20 -[#4682B4,bold]-> STATE5 : [guardEventHeaderEquals("header2","bar")] (order=0)
STATE20 -[#4682B4,bold]-> STATE1 : (order=1)
STATE11 -[#6A5ACD,bold]-> STATE13 : [guardVarEquals("goTo13")] (order=0)
STATE11 -[#6A5ACD,bold]-> STATE14 : [guardVarEquals("goTo14")] (order=1)
STATE11 -[#6A5ACD,bold]-> STATE15 : (order=2)
STATE12 -[#FFD700,bold]-> STATE10 : [guardVarEquals("goBack10")] (order=0)
STATE12 -[#FFD700,bold]-> STATE11 : (order=1)
STATE14 -[#32CD32,bold]-> STATE12 : [guardVarEquals("loop12")] (order=0)
STATE14 -[#32CD32,bold]-> STATE16 : (order=1)
STATE9 -[#32CD32,bold]-> STATE8 : [guardVarEquals("stepBack")] (order=0)
STATE9 -[#32CD32,bold]-> STATE7 : [guardVarEquals("stepBackMore")] (order=1)
STATE9 -[#32CD32,bold]-> STATE6 : (order=2)
STATE8 -[#FF69B4,bold]-> STATE9 : [guardVarEquals("forward9")] (order=0)
STATE8 -[#FF69B4,bold]-> STATE10 : (order=1)
STATE9 -[#1E90FF,bold]-> STATE_EXTRA_1_1 : EVENT_1_1
STATE_EXTRA_1_2 -[#FFD700,bold]-> STATE_EXTRA_1_1 : [guardEventHeaderEquals("header1","foo")] (order=0)
STATE_EXTRA_1_2 -[#FFD700,bold]-> STATE_EXTRA_1_3 : (order=1)
STATE_EXTRA_1_3 -[#1E90FF,bold]-> STATE_EXTRA_1 : EVENT_1_2
STATE_EXTRA_1_1 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL_2
STATE_EXTRA_1_2 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL_2
STATE_EXTRA_1 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL_2
STATEZ --> [*]
@enduml

View File

@@ -0,0 +1,40 @@
@startuml
skinparam state {
BackgroundColor<<choice>> LightYellow
}
[*] --> STATE1
state STATE8 <<choice>>
state STATEY <<choice>>
state STATE9 <<choice>>
STATE1 -[#1E90FF,bold]-> STATE2 : EVENT1
STATE2 -[#1E90FF,bold]-> STATE3 : EVENT2
STATE3 -[#1E90FF,bold]-> STATE4 : EVENT3
STATE4 -[#1E90FF,bold]-> STATE5 : EVENT4
STATE5 -[#1E90FF,bold]-> STATE6 : EVENT5
STATE6 -[#1E90FF,bold]-> STATE7 : EVENT6
STATE7 -[#1E90FF,bold]-> STATE8 : EVENT7
STATE8 -[#1E90FF,bold]-> STATE9 : EVENT8
STATE9 -[#1E90FF,bold]-> STATE10 : EVENT9
STATE1 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE2 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE3 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE4 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE5 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE4 -[#1E90FF,bold]-> STATEY : EVENTY
STATEY -[#4682B4,bold]-> STATEX : [guardVarEquals("value1")] (order=0)
STATEY -[#4682B4,bold]-> STATEZ : (order=1)
STATE9 -[#32CD32,bold]-> STATE8 : [guardVarEquals("stepBack")] (order=0)
STATE9 -[#32CD32,bold]-> STATE7 : [guardVarEquals("stepBackMore")] (order=1)
STATE9 -[#32CD32,bold]-> STATE6 : (order=2)
STATE8 -[#FF6347,bold]-> STATE9 : [guardVarEquals("forward9")] (order=0)
STATE8 -[#FF6347,bold]-> STATE10 : (order=1)
STATE3 -[#1E90FF,bold]-> STATE_EXTRA_2 : EVENT_1_2
STATE_EXTRA_2 -[#1E90FF,bold]-> STATE_EXTRA_3 : EVENT_1_2
STATE_EXTRA_3 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATEZ --> [*]
@enduml

View File

@@ -0,0 +1,41 @@
@startuml
skinparam state {
BackgroundColor<<choice>> LightYellow
}
[*] --> STATE1
state STATE8 <<choice>>
state STATEY <<choice>>
state STATE9 <<choice>>
STATE1 -[#1E90FF,bold]-> STATE2 : EVENT1
STATE2 -[#1E90FF,bold]-> STATE3 : EVENT2
STATE3 -[#1E90FF,bold]-> STATE4 : EVENT3
STATE4 -[#1E90FF,bold]-> STATE5 : EVENT4
STATE5 -[#1E90FF,bold]-> STATE6 : EVENT5
STATE6 -[#1E90FF,bold]-> STATE7 : EVENT6
STATE7 -[#1E90FF,bold]-> STATE8 : EVENT7
STATE8 -[#1E90FF,bold]-> STATE9 : EVENT8
STATE9 -[#1E90FF,bold]-> STATE10 : EVENT9
STATE1 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE2 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE3 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE4 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE5 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE4 -[#1E90FF,bold]-> STATEY : EVENTY
STATEY -[#4682B4,bold]-> STATEX : [guardVarEquals("value1")] (order=0)
STATEY -[#4682B4,bold]-> STATEZ : (order=1)
STATE9 -[#32CD32,bold]-> STATE8 : [guardVarEquals("stepBack")] (order=0)
STATE9 -[#32CD32,bold]-> STATE7 : [guardVarEquals("stepBackMore")] (order=1)
STATE9 -[#32CD32,bold]-> STATE6 : (order=2)
STATE8 -[#FF6347,bold]-> STATE9 : [guardVarEquals("forward9")] (order=0)
STATE8 -[#FF6347,bold]-> STATE10 : (order=1)
STATE3 -[#1E90FF,bold]-> STATE_EXTRA_1 : EVENT_1_2
STATE_EXTRA_1 -[#1E90FF,bold]-> STATE_EXTRA_2 : EVENT_1_3
STATE_EXTRA_1 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE_EXTRA_2 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATEZ --> [*]
@enduml

View File

@@ -0,0 +1,76 @@
@startuml
skinparam state {
BackgroundColor<<choice>> LightYellow
}
[*] --> STATE1
state STATE17 <<choice>>
state STATE16 <<choice>>
state STATE2 <<choice>>
state STATE14 <<choice>>
state STATE12 <<choice>>
state STATE11 <<choice>>
state STATE8 <<choice>>
state STATEY <<choice>>
state STATE20 <<choice>>
state STATE9 <<choice>>
state STATE19 <<choice>>
state STATE18 <<choice>>
STATE1 -[#1E90FF,bold]-> STATE2 : EVENT1
STATE2 -[#1E90FF,bold]-> STATE3 : EVENT2
STATE3 -[#1E90FF,bold]-> STATE4 : EVENT3
STATE4 -[#1E90FF,bold]-> STATE5 : EVENT4
STATE5 -[#1E90FF,bold]-> STATE6 : EVENT5
STATE6 -[#1E90FF,bold]-> STATE7 : EVENT6
STATE7 -[#1E90FF,bold]-> STATE8 : EVENT7
STATE8 -[#1E90FF,bold]-> STATE9 : EVENT8
STATE9 -[#1E90FF,bold]-> STATE10 : EVENT9
STATE10 -[#1E90FF,bold]-> STATE11 : EVENT10
STATE11 -[#1E90FF,bold]-> STATE12 : EVENT11
STATE12 -[#1E90FF,bold]-> STATE13 : EVENT12
STATE13 -[#1E90FF,bold]-> STATE14 : EVENT13
STATE14 -[#1E90FF,bold]-> STATE15 : EVENT14
STATE15 -[#1E90FF,bold]-> STATE16 : EVENT15
STATE1 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE2 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE3 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE4 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE5 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL
STATE4 -[#1E90FF,bold]-> STATEY : EVENTY
STATEY -[#4682B4,bold]-> STATEX : [guardVarEquals("value1")] (order=0)
STATEY -[#4682B4,bold]-> STATEZ : (order=1)
STATE16 -[#4682B4,bold]-> STATE17 : [guardVarEquals("value1")] (order=0)
STATE16 -[#4682B4,bold]-> STATE18 : [guardVarEquals("value2")] (order=1)
STATE16 -[#4682B4,bold]-> STATE19 : (order=2)
STATE17 -[#FF6347,bold]-> STATE20 : [guardEventHeaderEquals("header1","foo")] (order=0)
STATE17 -[#FF6347,bold]-> STATE16 : (order=1)
STATE18 -[#FF69B4,bold]-> STATE19 : [guardVarEquals("value3")] (order=0)
STATE18 -[#FF69B4,bold]-> STATE20 : (order=1)
STATE19 -[#6A5ACD,bold]-> STATE1 : [guardVarEquals("reset")] (order=0)
STATE19 -[#6A5ACD,bold]-> STATE20 : (order=1)
STATE20 -[#32CD32,bold]-> STATE5 : [guardEventHeaderEquals("header2","bar")] (order=0)
STATE20 -[#32CD32,bold]-> STATE1 : (order=1)
STATE11 -[#FF69B4,bold]-> STATE13 : [guardVarEquals("goTo13")] (order=0)
STATE11 -[#FF69B4,bold]-> STATE14 : [guardVarEquals("goTo14")] (order=1)
STATE11 -[#FF69B4,bold]-> STATE15 : (order=2)
STATE12 -[#6A5ACD,bold]-> STATE10 : [guardVarEquals("goBack10")] (order=0)
STATE12 -[#6A5ACD,bold]-> STATE11 : (order=1)
STATE14 -[#FFD700,bold]-> STATE12 : [guardVarEquals("loop12")] (order=0)
STATE14 -[#FFD700,bold]-> STATE16 : (order=1)
STATE9 -[#FFD700,bold]-> STATE8 : [guardVarEquals("stepBack")] (order=0)
STATE9 -[#FFD700,bold]-> STATE7 : [guardVarEquals("stepBackMore")] (order=1)
STATE9 -[#FFD700,bold]-> STATE6 : (order=2)
STATE8 -[#FF6347,bold]-> STATE9 : [guardVarEquals("forward9")] (order=0)
STATE8 -[#FF6347,bold]-> STATE10 : (order=1)
STATE2 -[#1E90FF,bold]-> STATE_EXTRA_1 : EVENTX
STATE2 -[#32CD32,bold]-> STATE1 : [guardEventHeaderEquals("header1","foo")] (order=0)
STATE2 -[#32CD32,bold]-> STATE_EXTRA_1 : (order=1)
STATE_EXTRA_1 -[#1E90FF,bold]-> STATE_EXTRA_3 : EVENTY
STATE_EXTRA_1 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL_2
STATE_EXTRA_2 -[#1E90FF,bold]-> CANCEL : EVENT_CANCEL_2
STATEZ --> [*]
@enduml

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() {
}
}