extended analysis

This commit is contained in:
2026-06-14 16:32:51 +02:00
parent 2251a587d9
commit ab474c0766
125 changed files with 4180 additions and 317 deletions

View File

@@ -28,8 +28,7 @@ import static org.assertj.core.api.Assertions.assertThat;
public class PlantUmlE2ETest {
private final List<StateMachineExporter> exporters = List.of(new PlantUml());
private final EnrichmentService enrichmentService = new EnrichmentService(Collections.emptyList());
private final ExportService exportService = new ExportService(exporters, enrichmentService);
private final ExportService exportService = new ExportService(exporters);
private static Path findProjectRoot() {
Path current = Path.of(".").toAbsolutePath();
@@ -107,6 +106,31 @@ public class PlantUmlE2ETest {
root.resolve("state_machines/inheritance_extra_functions3_state_machine"),
Path.of("src/test/resources/golden/G2StateMachineConfiguration"),
"G2StateMachineConfiguration"
),
new TestScenario(
"Extended Analysis Sample",
root.resolve("state_machines/extended_analysis_sample"),
Path.of("src/test/resources/golden/ExtendedStateMachineConfig"),
"ExtendedStateMachineConfig"
),
new TestScenario(
"Extended Analysis Sample (PROD)",
root.resolve("state_machines/extended_analysis_sample"),
Path.of("src/test/resources/golden/ExtendedStateMachineConfig_PROD"),
"ExtendedStateMachineConfig",
List.of("prod")
),
new TestScenario(
"Inheritance Sample",
root.resolve("state_machines/inheritance_sample"),
Path.of("src/test/resources/golden/InheritanceStateMachineConfig"),
"InheritanceStateMachineConfig"
),
new TestScenario(
"Enterprise Order System",
root.resolve("state_machines/enterprise_order_system"),
Path.of("src/test/resources/golden/EnterpriseStateMachineConfig"),
"EnterpriseStateMachineConfig"
)
);
}
@@ -115,7 +139,7 @@ public class PlantUmlE2ETest {
@MethodSource("provideTestScenarios")
void testPngGenerationMatchesGolden(TestScenario scenario, @TempDir Path tempDir) throws Exception {
// 1. Generate PUML
exportService.runExporter(scenario.inputPath(), tempDir, List.of("puml"), true);
exportService.runExporter(scenario.inputPath(), tempDir, List.of("puml"), true, scenario.activeProfiles());
List<Path> generatedDirs;
try (var stream = Files.list(tempDir)) {
@@ -129,34 +153,42 @@ public class PlantUmlE2ETest {
.orElseThrow(() -> new IllegalArgumentException("No output directory found for " + targetBaseName));
String actualBaseName = actualDir.getFileName().toString();
Path pumlFile = actualDir.resolve(actualBaseName + ".puml");
assertThat(pumlFile).exists();
// 2. Render PNG using PlantUML library
String pumlContent = Files.readString(pumlFile);
SourceStringReader reader = new SourceStringReader(pumlContent);
ByteArrayOutputStream os = new ByteArrayOutputStream();
reader.outputImage(os, new FileFormatOption(FileFormat.PNG));
byte[] actualPngBytes = os.toByteArray();
List<Path> pumlFiles;
try (var stream = Files.list(actualDir)) {
pumlFiles = stream.filter(p -> p.toString().endsWith(".puml")).toList();
}
// 3. Compare with Golden
Path goldenPngFile = scenario.goldenPath().resolve(targetBaseName + ".png");
if (Boolean.getBoolean("updateGolden")) {
Files.createDirectories(goldenPngFile.getParent());
Files.write(goldenPngFile, actualPngBytes);
System.out.println("Updated golden PNG: " + goldenPngFile);
} else {
assertThat(goldenPngFile)
.as("Golden PNG file %s should exist", goldenPngFile)
.exists();
for (Path pumlFile : pumlFiles) {
String fileName = pumlFile.getFileName().toString();
String baseNoExt = fileName.substring(0, fileName.lastIndexOf('.'));
String goldenBaseNoExt = baseNoExt.replace(actualBaseName, targetBaseName);
byte[] expectedPngBytes = Files.readAllBytes(goldenPngFile);
assertThat(actualPngBytes)
.as("Visual regression detected for %s. PNG output does not match golden reference.", scenario.name())
.containsExactly(expectedPngBytes);
// 2. Render PNG using PlantUML library
String pumlContent = Files.readString(pumlFile);
SourceStringReader reader = new SourceStringReader(pumlContent);
ByteArrayOutputStream os = new ByteArrayOutputStream();
reader.outputImage(os, new FileFormatOption(FileFormat.PNG));
byte[] actualPngBytes = os.toByteArray();
// 3. Compare with Golden
Path goldenPngFile = scenario.goldenPath().resolve(goldenBaseNoExt + ".png");
if (System.getProperty("updateGolden", "false").equals("true")) {
Files.createDirectories(scenario.goldenPath());
Files.write(goldenPngFile, actualPngBytes);
System.out.println("Updated golden PNG: " + goldenPngFile);
} else {
assertThat(goldenPngFile)
.as("Golden PNG missing for %s", fileName)
.exists();
byte[] expectedPngBytes = Files.readAllBytes(goldenPngFile);
assertThat(actualPngBytes)
.as("Visual regression detected for %s (%s). PNG output does not match golden reference.", scenario.name(), fileName)
.containsExactly(expectedPngBytes);
}
}
}
}

View File

@@ -22,8 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat;
public class RegressionTest {
private final List<StateMachineExporter> exporters = List.of(new PlantUml(), new Dot(), new Scxml(), new JsonExporter());
private final EnrichmentService enrichmentService = new EnrichmentService(Collections.emptyList());
private final ExportService exportService = new ExportService(exporters, enrichmentService);
private final ExportService exportService = new ExportService(exporters);
private static Path findProjectRoot() {
Path current = Path.of(".").toAbsolutePath();
@@ -101,6 +100,31 @@ public class RegressionTest {
root.resolve("state_machines/inheritance_extra_functions3_state_machine"),
Path.of("src/test/resources/golden/G2StateMachineConfiguration"),
"G2StateMachineConfiguration"
),
new TestScenario(
"Extended Analysis Sample",
root.resolve("state_machines/extended_analysis_sample"),
Path.of("src/test/resources/golden/ExtendedStateMachineConfig"),
"ExtendedStateMachineConfig"
),
new TestScenario(
"Extended Analysis Sample (PROD)",
root.resolve("state_machines/extended_analysis_sample"),
Path.of("src/test/resources/golden/ExtendedStateMachineConfig_PROD"),
"ExtendedStateMachineConfig",
List.of("prod")
),
new TestScenario(
"Inheritance Sample",
root.resolve("state_machines/inheritance_sample"),
Path.of("src/test/resources/golden/InheritanceStateMachineConfig"),
"InheritanceStateMachineConfig"
),
new TestScenario(
"Enterprise Order System",
root.resolve("state_machines/enterprise_order_system"),
Path.of("src/test/resources/golden/EnterpriseStateMachineConfig"),
"EnterpriseStateMachineConfig"
)
);
}
@@ -108,7 +132,12 @@ public class RegressionTest {
@ParameterizedTest(name = "{0}")
@MethodSource("provideTestScenarios")
void testOutputMatchesGolden(TestScenario scenario, @TempDir Path tempDir) throws Exception {
exportService.runExporter(scenario.inputPath(), tempDir, null, true);
System.out.println("Running test for " + scenario.name());
if (exportService == null) System.out.println("exportService is NULL");
if (scenario.inputPath() == null) System.out.println("inputPath is NULL");
if (tempDir == null) System.out.println("tempDir is NULL");
exportService.runExporter(scenario.inputPath(), tempDir, List.of("puml", "dot", "scxml", "json"), true, scenario.activeProfiles());
// Find the generated directory (it might be named with FQN)
List<Path> generatedDirs;
@@ -121,28 +150,33 @@ public class RegressionTest {
.filter(d -> d.getFileName().toString().endsWith(targetBaseName))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No output directory found for " + targetBaseName + " in " + generatedDirs));
String actualBaseName = actualDir.getFileName().toString();
String actualBaseName = actualDir.getFileName().toString();
List<Path> generatedFiles;
try (var stream = Files.list(actualDir)) {
generatedFiles = stream.filter(Files::isRegularFile).toList();
}
for (StateMachineExporter exporter : exporters) {
String fileName = actualBaseName + exporter.getFileExtension();
String goldenFileName = targetBaseName + exporter.getFileExtension();
for (Path actualFile : generatedFiles) {
String fileName = actualFile.getFileName().toString();
// Map actual filename to golden filename (handle FQN difference)
String goldenFileName = fileName.replace(actualBaseName, targetBaseName);
Path goldenFile = scenario.goldenPath().resolve(goldenFileName);
Path actualFile = actualDir.resolve(fileName);
Path goldenFile = scenario.goldenPath().resolve(goldenFileName);
if (System.getProperty("updateGolden", "false").equals("true")) {
Files.createDirectories(scenario.goldenPath());
Files.copy(actualFile, goldenFile, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
System.out.println("Updated golden file: " + goldenFile);
} else {
assertThat(goldenFile)
.as("Golden file missing for %s", fileName)
.exists();
if (Boolean.getBoolean("updateGolden")) {
Files.createDirectories(goldenFile.getParent());
Files.copy(actualFile, goldenFile, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
} else {
assertThat(actualFile)
.as("File %s should exist in output", fileName)
.exists();
assertThat(actualFile)
.as("Content mismatch for %s", fileName)
.content().isEqualTo(Files.readString(goldenFile));
}
}
assertThat(actualFile)
.as("Content mismatch for %s", fileName)
.content().isEqualTo(Files.readString(goldenFile));
}
}
}
}

View File

@@ -0,0 +1,83 @@
package click.kamil.springstatemachineexporter.analysis;
import click.kamil.springstatemachineexporter.analysis.resolver.ConstantResolver;
import click.kamil.springstatemachineexporter.analysis.resolver.PropertyResolver;
import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
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 java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
public class AnalysisFoundationTest {
@Test
void testPropertyResolver(@TempDir Path tempDir) throws IOException {
Files.writeString(tempDir.resolve("application.properties"), "app.event=SUBMIT\napp.path=/api/v1");
PropertyResolver resolver = new PropertyResolver();
Map<String, String> props = resolver.resolveProperties(tempDir);
assertThat(props).containsEntry("app.event", "SUBMIT");
assertThat(props).containsEntry("app.path", "/api/v1");
}
@Test
void testConstantResolverManualFallback(@TempDir Path tempDir) throws IOException {
// Create a class with a constant
Path constDir = tempDir.resolve("com/example");
Files.createDirectories(constDir);
Files.writeString(constDir.resolve("Events.java"),
"package com.example;\n" +
"public class Events {\n" +
" public static final String SUBMIT = \"SUBMIT_EVENT\";\n" +
"}");
// Create a class that uses the constant
Files.writeString(constDir.resolve("Usage.java"),
"package com.example;\n" +
"public class Usage {\n" +
" String e = Events.SUBMIT;\n" +
"}");
CodebaseContext context = new CodebaseContext();
context.scan(tempDir);
TypeDeclaration usageTd = context.getTypeDeclaration("com.example.Usage");
FieldDeclaration field = usageTd.getFields()[0];
VariableDeclarationFragment fragment = (VariableDeclarationFragment) field.fragments().get(0);
Expression initializer = fragment.getInitializer();
ConstantResolver resolver = new ConstantResolver();
String value = resolver.resolve(initializer, context);
assertThat(value).isEqualTo("SUBMIT_EVENT");
}
@Test
void testPropertyResolverWithProfiles(@TempDir Path tempDir) throws IOException {
Files.writeString(tempDir.resolve("application.properties"), "app.event=BASE");
Files.writeString(tempDir.resolve("application-prod.properties"), "app.event=PROD");
PropertyResolver resolver = new PropertyResolver();
// 1. Base only
Map<String, String> baseProps = resolver.resolveProperties(tempDir);
assertThat(baseProps).containsEntry("app.event", "BASE");
// 2. With prod profile
resolver.setActiveProfiles(List.of("prod"));
Map<String, String> prodProps = resolver.resolveProperties(tempDir);
assertThat(prodProps).containsEntry("app.event", "PROD");
}
}

View File

@@ -1,48 +0,0 @@
package click.kamil.springstatemachineexporter.exporter;
import click.kamil.springstatemachineexporter.analysis.model.AnalysisResult;
import click.kamil.springstatemachineexporter.analysis.model.CodebaseMetadata;
import click.kamil.springstatemachineexporter.model.State;
import click.kamil.springstatemachineexporter.model.Transition;
import click.kamil.springstatemachineexporter.model.TransitionType;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
class PlantUmlCustomStyleTest {
@Test
void shouldApplyCustomStyleFromMetadata() {
PlantUml exporter = new PlantUml();
Transition transition = new Transition();
transition.setType(TransitionType.EXTERNAL);
transition.setSourceStates(List.of(State.of("S1")));
transition.setTargetStates(List.of(State.of("S2")));
transition.setEvent("E1");
AnalysisResult result = AnalysisResult.builder()
.name("TestSM")
.transitions(List.of(transition))
.startStates(Set.of("S1"))
.endStates(Set.of("S2"))
.metadata(CodebaseMetadata.builder()
.properties(Map.of("plantuml.style", "skinparam stateBackgroundColor Red"))
.build())
.build();
String puml = exporter.export(result, ExportOptions.builder().build());
assertThat(puml)
.contains("skinparam stateBackgroundColor Red")
.contains("@enduml");
// Ensure it's inserted before @enduml
int styleIndex = puml.indexOf("skinparam stateBackgroundColor Red");
int endumlIndex = puml.indexOf("@enduml");
assertThat(styleIndex).isLessThan(endumlIndex);
}
}

View File

@@ -1,5 +1,6 @@
package click.kamil.springstatemachineexporter.service;
import click.kamil.springstatemachineexporter.analysis.model.AnalysisResult;
import click.kamil.springstatemachineexporter.model.StateMachineModel;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@@ -39,4 +40,33 @@ class JsonImportServiceTest {
assertThat(model.getStartStates()).containsExactly("S1");
assertThat(model.getEndStates()).containsExactly("S2");
}
@Test
void shouldImportRichAnalysisResultFromJson(@TempDir Path tempDir) throws IOException {
Path jsonFile = tempDir.resolve("rich.json");
String json = """
{
"name" : "RichSM",
"transitions" : [],
"startStates" : [],
"endStates" : [],
"metadata" : {
"entryPoints" : [ {
"type" : "REST",
"name" : "POST /rich",
"className" : "RichController",
"methodName" : "submit"
} ]
}
}
""";
Files.writeString(jsonFile, json);
JsonImportService importService = new JsonImportService();
AnalysisResult result = importService.importAnalysisResult(jsonFile);
assertThat(result.getName()).isEqualTo("RichSM");
assertThat(result.getMetadata().getEntryPoints()).hasSize(1);
assertThat(result.getMetadata().getEntryPoints().get(0).getName()).isEqualTo("POST /rich");
}
}

View File

@@ -1,10 +1,17 @@
package click.kamil.springstatemachineexporter.utils;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
public record TestScenario(
String name,
Path inputPath,
Path goldenPath,
String baseName
) {}
String baseName,
List<String> activeProfiles
) {
public TestScenario(String name, Path inputPath, Path goldenPath, String baseName) {
this(name, inputPath, goldenPath, baseName, Collections.emptyList());
}
}

View File

@@ -1,5 +1,15 @@
{
"metadata" : {
"triggers" : [ ],
"entryPoints" : [ ],
"callChains" : [ ],
"properties" : {
"spring.application.name" : "statemachinedemo"
}
},
"name" : "click.kamil.examples.statemachine.complex.ComplexStateMachineConfig",
"renderChoicesAsDiamonds" : true,
"startStates" : [ "States.STATE1" ],
"transitions" : [ {
"type" : "EXTERNAL",
"sourceStates" : [ {
@@ -572,7 +582,5 @@
"actions" : [ ],
"order" : 1
} ],
"startStates" : [ "States.STATE1" ],
"endStates" : [ ],
"renderChoicesAsDiamonds" : true
"endStates" : [ ]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

After

Width:  |  Height:  |  Size: 171 KiB

View File

@@ -1,4 +1,28 @@
@startuml
!pragma layout smetana
hide empty description
hide stereotype
state STATE1
state STATE2
state STATE3
state STATE4
state STATE5
state STATE6
state STATE7
state STATE8
state STATE9
state STATE10
state STATE11
state STATE12
state STATE13
state STATE14
state STATE15
state STATE16
state STATE17
state STATE18
state STATE19
state STATE20
<style>
state {
.choice {

View File

@@ -0,0 +1,22 @@
digraph statemachine {
rankdir=LR;
node [shape=rounded, style=filled, fillcolor=white, fontname="Arial"];
edge [fontname="Arial", fontsize=10];
CHECK_AVAILABILITY_choice [shape=diamond, label="", fillcolor="blue", width=0.2, height=0.2];
CHECK_AVAILABILITY -> CHECK_AVAILABILITY_choice [style=dotted, color="blue"];
_start [shape=circle, label="", fillcolor=black, width=0.1];
_start -> NEW;
CANCELLED [fillcolor=lightgray];
DELIVERED [fillcolor=lightgray];
RETURNED [fillcolor=lightgray];
NEW -> CHECK_AVAILABILITY [label="PLACE_ORDER", style="solid", color="black"];
CHECK_AVAILABILITY_choice -> PENDING_PAYMENT [label="[λ] (order=0)", style="solid", color="blue"];
CHECK_AVAILABILITY_choice -> CANCELLED [label="(order=1)", style="solid", color="blue"];
PENDING_PAYMENT -> PAID [label="PAY_ORDER", style="solid", color="black"];
PAID -> SHIPPED [label="SHIP_ORDER", style="solid", color="black"];
SHIPPED -> DELIVERED [label="FINALIZE", style="solid", color="black"];
PAID -> CANCELLED [label="CANCEL_ORDER", style="solid", color="black"];
DELIVERED -> RETURNED [label="RETURN_ORDER", style="solid", color="black"];
}

View File

@@ -0,0 +1,284 @@
{
"metadata" : {
"triggers" : [ {
"event" : "AUDIT_EVENT",
"className" : "click.kamil.examples.enterprise.api.SecurityInterceptor",
"methodName" : "preHandle",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 17
}, {
"event" : "PLACE_ORDER",
"className" : "click.kamil.examples.enterprise.service.OrderServiceImpl",
"methodName" : "place",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 16
}, {
"event" : "CANCEL_ORDER",
"className" : "click.kamil.examples.enterprise.service.OrderServiceImpl",
"methodName" : "cancel",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 21
}, {
"event" : "PAY_ORDER",
"className" : "click.kamil.examples.enterprise.service.ReactivePaymentService",
"methodName" : "processPayment",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 18
}, {
"event" : "SHIP_ORDER",
"className" : "click.kamil.examples.enterprise.messaging.ShippingJmsListener",
"methodName" : "onShippingReady",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 17
}, {
"event" : "RETURN_ORDER",
"className" : "click.kamil.examples.enterprise.messaging.ReturnsRabbitListener",
"methodName" : "onReturn",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 17
} ],
"entryPoints" : [ {
"type" : "REST",
"name" : "POST /api/enterprise/orders/place",
"className" : "click.kamil.examples.enterprise.api.OrderController",
"methodName" : "placeOrder",
"metadata" : {
"path" : "/api/enterprise/orders/place",
"verb" : "POST"
}
}, {
"type" : "REST",
"name" : "POST /api/enterprise/orders/{id}/cancel",
"className" : "click.kamil.examples.enterprise.api.OrderController",
"methodName" : "cancelOrder",
"metadata" : {
"path" : "/api/enterprise/orders/{id}/cancel",
"verb" : "POST"
}
}, {
"type" : "CUSTOM",
"name" : "INTERCEPTOR: SecurityInterceptor.preHandle",
"className" : "click.kamil.examples.enterprise.api.SecurityInterceptor",
"methodName" : "preHandle",
"metadata" : {
"interceptorType" : "Spring MVC Interceptor"
}
}, {
"type" : "REST",
"name" : "POST /api/enterprise/payments",
"className" : "click.kamil.examples.enterprise.api.ReactivePaymentController",
"methodName" : "pay",
"metadata" : {
"path" : "/api/enterprise/payments",
"verb" : "POST"
}
} ],
"callChains" : [ {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/enterprise/orders/place",
"className" : "click.kamil.examples.enterprise.api.OrderController",
"methodName" : "placeOrder",
"metadata" : {
"path" : "/api/enterprise/orders/place",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.enterprise.api.OrderController.placeOrder", "click.kamil.examples.enterprise.service.OrderServiceImpl.place" ],
"triggerPoint" : {
"event" : "PLACE_ORDER",
"className" : "click.kamil.examples.enterprise.service.OrderServiceImpl",
"methodName" : "place",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 16
}
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/enterprise/orders/{id}/cancel",
"className" : "click.kamil.examples.enterprise.api.OrderController",
"methodName" : "cancelOrder",
"metadata" : {
"path" : "/api/enterprise/orders/{id}/cancel",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.enterprise.api.OrderController.cancelOrder", "click.kamil.examples.enterprise.service.OrderServiceImpl.cancel" ],
"triggerPoint" : {
"event" : "CANCEL_ORDER",
"className" : "click.kamil.examples.enterprise.service.OrderServiceImpl",
"methodName" : "cancel",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 21
}
}, {
"entryPoint" : {
"type" : "CUSTOM",
"name" : "INTERCEPTOR: SecurityInterceptor.preHandle",
"className" : "click.kamil.examples.enterprise.api.SecurityInterceptor",
"methodName" : "preHandle",
"metadata" : {
"interceptorType" : "Spring MVC Interceptor"
}
},
"methodChain" : [ "click.kamil.examples.enterprise.api.SecurityInterceptor.preHandle" ],
"triggerPoint" : {
"event" : "AUDIT_EVENT",
"className" : "click.kamil.examples.enterprise.api.SecurityInterceptor",
"methodName" : "preHandle",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 17
}
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/enterprise/payments",
"className" : "click.kamil.examples.enterprise.api.ReactivePaymentController",
"methodName" : "pay",
"metadata" : {
"path" : "/api/enterprise/payments",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.enterprise.api.ReactivePaymentController.pay", "click.kamil.examples.enterprise.service.ReactivePaymentService.processPayment" ],
"triggerPoint" : {
"event" : "PAY_ORDER",
"className" : "click.kamil.examples.enterprise.service.ReactivePaymentService",
"methodName" : "processPayment",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 18
}
} ],
"properties" : { }
},
"name" : "click.kamil.examples.enterprise.config.EnterpriseStateMachineConfig",
"renderChoicesAsDiamonds" : true,
"startStates" : [ "NEW" ],
"transitions" : [ {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"NEW\"",
"fullIdentifier" : "NEW"
} ],
"targetStates" : [ {
"rawName" : "\"CHECK_AVAILABILITY\"",
"fullIdentifier" : "CHECK_AVAILABILITY"
} ],
"event" : "PLACE_ORDER",
"guard" : null,
"actions" : [ ],
"order" : null
}, {
"type" : "CHOICE",
"sourceStates" : [ {
"rawName" : "\"CHECK_AVAILABILITY\"",
"fullIdentifier" : "CHECK_AVAILABILITY"
} ],
"targetStates" : [ {
"rawName" : "\"PENDING_PAYMENT\"",
"fullIdentifier" : "PENDING_PAYMENT"
} ],
"event" : null,
"guard" : {
"expression" : "(c) -> true",
"isLambda" : true
},
"actions" : [ ],
"order" : 0
}, {
"type" : "CHOICE",
"sourceStates" : [ {
"rawName" : "\"CHECK_AVAILABILITY\"",
"fullIdentifier" : "CHECK_AVAILABILITY"
} ],
"targetStates" : [ {
"rawName" : "\"CANCELLED\"",
"fullIdentifier" : "CANCELLED"
} ],
"event" : null,
"guard" : null,
"actions" : [ ],
"order" : 1
}, {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"PENDING_PAYMENT\"",
"fullIdentifier" : "PENDING_PAYMENT"
} ],
"targetStates" : [ {
"rawName" : "\"PAID\"",
"fullIdentifier" : "PAID"
} ],
"event" : "PAY_ORDER",
"guard" : null,
"actions" : [ ],
"order" : null
}, {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"PAID\"",
"fullIdentifier" : "PAID"
} ],
"targetStates" : [ {
"rawName" : "\"SHIPPED\"",
"fullIdentifier" : "SHIPPED"
} ],
"event" : "SHIP_ORDER",
"guard" : null,
"actions" : [ ],
"order" : null
}, {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"SHIPPED\"",
"fullIdentifier" : "SHIPPED"
} ],
"targetStates" : [ {
"rawName" : "\"DELIVERED\"",
"fullIdentifier" : "DELIVERED"
} ],
"event" : "FINALIZE",
"guard" : null,
"actions" : [ ],
"order" : null
}, {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"PAID\"",
"fullIdentifier" : "PAID"
} ],
"targetStates" : [ {
"rawName" : "\"CANCELLED\"",
"fullIdentifier" : "CANCELLED"
} ],
"event" : "CANCEL_ORDER",
"guard" : null,
"actions" : [ ],
"order" : null
}, {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"DELIVERED\"",
"fullIdentifier" : "DELIVERED"
} ],
"targetStates" : [ {
"rawName" : "\"RETURNED\"",
"fullIdentifier" : "RETURNED"
} ],
"event" : "RETURN_ORDER",
"guard" : null,
"actions" : [ ],
"order" : null
} ],
"endStates" : [ "CANCELLED", "DELIVERED", "RETURNED" ]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -0,0 +1,78 @@
@startuml
!pragma layout smetana
hide empty description
hide stereotype
state NEW
state CHECK_AVAILABILITY
state PENDING_PAYMENT
state CANCELLED
state PAID
state SHIPPED
state DELIVERED
state RETURNED
<style>
state {
.choice {
BackgroundColor LightYellow
}
}
arrow {
LineThickness 1
.external { LineColor #1E90FF }
.internal { LineColor #32CD32 }
.local { LineColor #FFA500 }
.junction { LineColor #FF69B4 }
.join { LineColor #8A2BE2 }
.fork { LineColor #20B2AA }
.choice_type { LineColor #000000 }
.choice_color_0 { LineColor #FF6347 }
.choice_color_1 { LineColor #4682B4 }
.choice_color_2 { LineColor #32CD32 }
.choice_color_3 { LineColor #FFD700 }
.choice_color_4 { LineColor #6A5ACD }
.choice_color_5 { LineColor #FF69B4 }
}
/* Example: Highlight all transitions for a specific event */
/* .e_MY_EVENT { LineColor red } */
</style>
hide <<external>> stereotype
hide <<internal>> stereotype
hide <<local>> stereotype
hide <<junction>> stereotype
hide <<join>> stereotype
hide <<fork>> stereotype
hide <<choice_type>> stereotype
hide <<choice_color_0>> stereotype
hide <<choice_color_1>> stereotype
hide <<choice_color_2>> stereotype
hide <<choice_color_3>> stereotype
hide <<choice_color_4>> stereotype
hide <<choice_color_5>> stereotype
[*] --> NEW
state CHECK_AVAILABILITY <<choice>>
NEW -[#1E90FF,bold]-> CHECK_AVAILABILITY <<external>> <<e_PLACE_ORDER>> : PLACE_ORDER
CHECK_AVAILABILITY -[#FF6347,bold]-> PENDING_PAYMENT <<choice_color_0>> : [λ] (order=0)
CHECK_AVAILABILITY -[#FF6347,bold]-> CANCELLED <<choice_color_0>> : (order=1)
PENDING_PAYMENT -[#1E90FF,bold]-> PAID <<external>> <<e_PAY_ORDER>> : PAY_ORDER
PAID -[#1E90FF,bold]-> SHIPPED <<external>> <<e_SHIP_ORDER>> : SHIP_ORDER
SHIPPED -[#1E90FF,bold]-> DELIVERED <<external>> <<e_FINALIZE>> : FINALIZE
PAID -[#1E90FF,bold]-> CANCELLED <<external>> <<e_CANCEL_ORDER>> : CANCEL_ORDER
DELIVERED -[#1E90FF,bold]-> RETURNED <<external>> <<e_RETURN_ORDER>> : RETURN_ORDER
hide <<e_PLACE_ORDER>> stereotype
hide <<e_PAY_ORDER>> stereotype
hide <<e_SHIP_ORDER>> stereotype
hide <<e_FINALIZE>> stereotype
hide <<e_CANCEL_ORDER>> stereotype
hide <<e_RETURN_ORDER>> stereotype
CANCELLED --> [*]
DELIVERED --> [*]
RETURNED --> [*]
@enduml

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="NEW">
<state id="NEW">
<transition target="CHECK_AVAILABILITY" event="PLACE_ORDER"/>
</state>
<state id="CHECK_AVAILABILITY">
<transition target="PENDING_PAYMENT" cond="λ">
<!-- order=0 -->
</transition>
<transition target="CANCELLED">
<!-- order=1 -->
</transition>
</state>
<state id="PENDING_PAYMENT">
<transition target="PAID" event="PAY_ORDER"/>
</state>
<state id="CANCELLED">
</state>
<state id="PAID">
<transition target="SHIPPED" event="SHIP_ORDER"/>
<transition target="CANCELLED" event="CANCEL_ORDER"/>
</state>
<state id="SHIPPED">
<transition target="DELIVERED" event="FINALIZE"/>
</state>
<state id="DELIVERED">
<transition target="RETURNED" event="RETURN_ORDER"/>
</state>
<state id="RETURNED">
</state>
</scxml>

View File

@@ -0,0 +1,17 @@
digraph statemachine {
rankdir=LR;
node [shape=rounded, style=filled, fillcolor=white, fontname="Arial"];
edge [fontname="Arial", fontsize=10];
_start [shape=circle, label="", fillcolor=black, width=0.1];
_start -> INIT_STATE;
CANCELLED [fillcolor=lightgray];
COMPLETED [fillcolor=lightgray];
START -> PROCESSING [label="SUBMIT_EVENT", style="solid", color="black"];
PROCESSING -> COMPLETED [label="FINISH", style="solid", color="black"];
PROCESSING -> CANCELLED [label="CANCEL_EVENT", style="solid", color="black"];
START -> PROCESSING [label="REACTIVE_EVENT", style="solid", color="black"];
START -> START [label="AUDIT_EVENT", style="solid", color="black"];
START -> PROCESSING [label="EXTERNAL_TRIGGER", style="solid", color="black"];
}

View File

@@ -0,0 +1,340 @@
{
"metadata" : {
"triggers" : [ {
"event" : "FINISH",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "finishOrder",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 34
}, {
"event" : "AUDIT_EVENT",
"className" : "click.kamil.examples.statemachine.extended.web.AuditInterceptor",
"methodName" : "preHandle",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 16
}, {
"event" : "EXTERNAL_TRIGGER",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "processSubmit",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 19
}, {
"event" : "SUBMIT_EVENT",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "processSubmit",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 20
}, {
"event" : "CANCEL_EVENT",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "processCancel",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 25
}, {
"event" : "[LIFECYCLE:RESTORE]",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "resumeOrder",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 29
}, {
"event" : "REACTIVE_EVENT",
"className" : "click.kamil.examples.statemachine.extended.service.ReactiveOrderService",
"methodName" : "processReactive",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 18
} ],
"entryPoints" : [ {
"type" : "REST",
"name" : "POST /api/orders/submit",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "submitOrder",
"metadata" : {
"path" : "/api/orders/submit",
"verb" : "POST"
}
}, {
"type" : "REST",
"name" : "POST /api/orders/cancel",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "cancelOrder",
"metadata" : {
"path" : "/api/orders/cancel",
"verb" : "POST"
}
}, {
"type" : "REST",
"name" : "POST /api/orders/finish",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "finishOrder",
"metadata" : {
"path" : "/api/orders/finish",
"verb" : "POST"
}
}, {
"type" : "REST",
"name" : "POST /api/orders/resume",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "resumeOrder",
"metadata" : {
"path" : "/api/orders/resume",
"verb" : "POST"
}
}, {
"type" : "REST",
"name" : "POST /api/orders/reactive",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "reactiveOrder",
"metadata" : {
"path" : "/api/orders/reactive",
"verb" : "POST"
}
}, {
"type" : "CUSTOM",
"name" : "INTERCEPTOR: AuditInterceptor.preHandle",
"className" : "click.kamil.examples.statemachine.extended.web.AuditInterceptor",
"methodName" : "preHandle",
"metadata" : {
"interceptorType" : "Spring MVC Interceptor"
}
} ],
"callChains" : [ {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/orders/submit",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "submitOrder",
"metadata" : {
"path" : "/api/orders/submit",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.statemachine.extended.web.OrderController.submitOrder", "click.kamil.examples.statemachine.extended.service.OrderService.processSubmit" ],
"triggerPoint" : {
"event" : "EXTERNAL_TRIGGER",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "processSubmit",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 19
}
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/orders/submit",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "submitOrder",
"metadata" : {
"path" : "/api/orders/submit",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.statemachine.extended.web.OrderController.submitOrder", "click.kamil.examples.statemachine.extended.service.OrderService.processSubmit" ],
"triggerPoint" : {
"event" : "SUBMIT_EVENT",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "processSubmit",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 20
}
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/orders/cancel",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "cancelOrder",
"metadata" : {
"path" : "/api/orders/cancel",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.statemachine.extended.web.OrderController.cancelOrder", "click.kamil.examples.statemachine.extended.service.OrderService.processCancel" ],
"triggerPoint" : {
"event" : "CANCEL_EVENT",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "processCancel",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 25
}
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/orders/finish",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "finishOrder",
"metadata" : {
"path" : "/api/orders/finish",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.statemachine.extended.web.OrderController.finishOrder" ],
"triggerPoint" : {
"event" : "FINISH",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "finishOrder",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 34
}
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/orders/resume",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "resumeOrder",
"metadata" : {
"path" : "/api/orders/resume",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.statemachine.extended.web.OrderController.resumeOrder", "click.kamil.examples.statemachine.extended.service.OrderService.resumeOrder" ],
"triggerPoint" : {
"event" : "[LIFECYCLE:RESTORE]",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "resumeOrder",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 29
}
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/orders/reactive",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "reactiveOrder",
"metadata" : {
"path" : "/api/orders/reactive",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.statemachine.extended.web.OrderController.reactiveOrder", "click.kamil.examples.statemachine.extended.service.ReactiveOrderService.processReactive" ],
"triggerPoint" : {
"event" : "REACTIVE_EVENT",
"className" : "click.kamil.examples.statemachine.extended.service.ReactiveOrderService",
"methodName" : "processReactive",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 18
}
}, {
"entryPoint" : {
"type" : "CUSTOM",
"name" : "INTERCEPTOR: AuditInterceptor.preHandle",
"className" : "click.kamil.examples.statemachine.extended.web.AuditInterceptor",
"methodName" : "preHandle",
"metadata" : {
"interceptorType" : "Spring MVC Interceptor"
}
},
"methodChain" : [ "click.kamil.examples.statemachine.extended.web.AuditInterceptor.preHandle" ],
"triggerPoint" : {
"event" : "AUDIT_EVENT",
"className" : "click.kamil.examples.statemachine.extended.web.AuditInterceptor",
"methodName" : "preHandle",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 16
}
} ],
"properties" : {
"app.states.initial" : "INIT_STATE"
}
},
"name" : "click.kamil.examples.statemachine.extended.config.ExtendedStateMachineConfig",
"renderChoicesAsDiamonds" : true,
"startStates" : [ "INIT_STATE" ],
"transitions" : [ {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"START\"",
"fullIdentifier" : "START"
} ],
"targetStates" : [ {
"rawName" : "\"PROCESSING\"",
"fullIdentifier" : "PROCESSING"
} ],
"event" : "SUBMIT_EVENT",
"guard" : null,
"actions" : [ ],
"order" : null
}, {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"PROCESSING\"",
"fullIdentifier" : "PROCESSING"
} ],
"targetStates" : [ {
"rawName" : "\"COMPLETED\"",
"fullIdentifier" : "COMPLETED"
} ],
"event" : "FINISH",
"guard" : null,
"actions" : [ ],
"order" : null
}, {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"PROCESSING\"",
"fullIdentifier" : "PROCESSING"
} ],
"targetStates" : [ {
"rawName" : "\"CANCELLED\"",
"fullIdentifier" : "CANCELLED"
} ],
"event" : "CANCEL_EVENT",
"guard" : null,
"actions" : [ ],
"order" : null
}, {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"START\"",
"fullIdentifier" : "START"
} ],
"targetStates" : [ {
"rawName" : "\"PROCESSING\"",
"fullIdentifier" : "PROCESSING"
} ],
"event" : "REACTIVE_EVENT",
"guard" : null,
"actions" : [ ],
"order" : null
}, {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"START\"",
"fullIdentifier" : "START"
} ],
"targetStates" : [ {
"rawName" : "\"START\"",
"fullIdentifier" : "START"
} ],
"event" : "AUDIT_EVENT",
"guard" : null,
"actions" : [ ],
"order" : null
}, {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"START\"",
"fullIdentifier" : "START"
} ],
"targetStates" : [ {
"rawName" : "\"PROCESSING\"",
"fullIdentifier" : "PROCESSING"
} ],
"event" : "EXTERNAL_TRIGGER",
"guard" : null,
"actions" : [ ],
"order" : null
} ],
"endStates" : [ "CANCELLED", "COMPLETED" ]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,70 @@
@startuml
!pragma layout smetana
hide empty description
hide stereotype
state START
state PROCESSING
state COMPLETED
state CANCELLED
<style>
state {
.choice {
BackgroundColor LightYellow
}
}
arrow {
LineThickness 1
.external { LineColor #1E90FF }
.internal { LineColor #32CD32 }
.local { LineColor #FFA500 }
.junction { LineColor #FF69B4 }
.join { LineColor #8A2BE2 }
.fork { LineColor #20B2AA }
.choice_type { LineColor #000000 }
.choice_color_0 { LineColor #FF6347 }
.choice_color_1 { LineColor #4682B4 }
.choice_color_2 { LineColor #32CD32 }
.choice_color_3 { LineColor #FFD700 }
.choice_color_4 { LineColor #6A5ACD }
.choice_color_5 { LineColor #FF69B4 }
}
/* Example: Highlight all transitions for a specific event */
/* .e_MY_EVENT { LineColor red } */
</style>
hide <<external>> stereotype
hide <<internal>> stereotype
hide <<local>> stereotype
hide <<junction>> stereotype
hide <<join>> stereotype
hide <<fork>> stereotype
hide <<choice_type>> stereotype
hide <<choice_color_0>> stereotype
hide <<choice_color_1>> stereotype
hide <<choice_color_2>> stereotype
hide <<choice_color_3>> stereotype
hide <<choice_color_4>> stereotype
hide <<choice_color_5>> stereotype
[*] --> INIT_STATE
START -[#1E90FF,bold]-> PROCESSING <<external>> <<e_SUBMIT_EVENT>> : SUBMIT_EVENT
PROCESSING -[#1E90FF,bold]-> COMPLETED <<external>> <<e_FINISH>> : FINISH
PROCESSING -[#1E90FF,bold]-> CANCELLED <<external>> <<e_CANCEL_EVENT>> : CANCEL_EVENT
START -[#1E90FF,bold]-> PROCESSING <<external>> <<e_REACTIVE_EVENT>> : REACTIVE_EVENT
START -[#1E90FF,bold]-> START <<external>> <<e_AUDIT_EVENT>> : AUDIT_EVENT
START -[#1E90FF,bold]-> PROCESSING <<external>> <<e_EXTERNAL_TRIGGER>> : EXTERNAL_TRIGGER
hide <<e_SUBMIT_EVENT>> stereotype
hide <<e_FINISH>> stereotype
hide <<e_CANCEL_EVENT>> stereotype
hide <<e_REACTIVE_EVENT>> stereotype
hide <<e_AUDIT_EVENT>> stereotype
hide <<e_EXTERNAL_TRIGGER>> stereotype
CANCELLED --> [*]
COMPLETED --> [*]
@enduml

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="INIT_STATE">
<state id="START">
<transition target="PROCESSING" event="SUBMIT_EVENT"/>
<transition target="PROCESSING" event="REACTIVE_EVENT"/>
<transition target="START" event="AUDIT_EVENT"/>
<transition target="PROCESSING" event="EXTERNAL_TRIGGER"/>
</state>
<state id="PROCESSING">
<transition target="COMPLETED" event="FINISH"/>
<transition target="CANCELLED" event="CANCEL_EVENT"/>
</state>
<state id="COMPLETED">
</state>
<state id="CANCELLED">
</state>
<state id="INIT_STATE">
</state>
</scxml>

View File

@@ -0,0 +1,17 @@
digraph statemachine {
rankdir=LR;
node [shape=rounded, style=filled, fillcolor=white, fontname="Arial"];
edge [fontname="Arial", fontsize=10];
_start [shape=circle, label="", fillcolor=black, width=0.1];
_start -> PROD_INITIAL;
CANCELLED [fillcolor=lightgray];
COMPLETED [fillcolor=lightgray];
START -> PROCESSING [label="SUBMIT_EVENT", style="solid", color="black"];
PROCESSING -> COMPLETED [label="FINISH", style="solid", color="black"];
PROCESSING -> CANCELLED [label="CANCEL_EVENT", style="solid", color="black"];
START -> PROCESSING [label="REACTIVE_EVENT", style="solid", color="black"];
START -> START [label="AUDIT_EVENT", style="solid", color="black"];
START -> PROCESSING [label="EXTERNAL_TRIGGER", style="solid", color="black"];
}

View File

@@ -0,0 +1,340 @@
{
"metadata" : {
"triggers" : [ {
"event" : "FINISH",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "finishOrder",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 34
}, {
"event" : "AUDIT_EVENT",
"className" : "click.kamil.examples.statemachine.extended.web.AuditInterceptor",
"methodName" : "preHandle",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 16
}, {
"event" : "EXTERNAL_TRIGGER",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "processSubmit",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 19
}, {
"event" : "SUBMIT_EVENT",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "processSubmit",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 20
}, {
"event" : "CANCEL_EVENT",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "processCancel",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 25
}, {
"event" : "[LIFECYCLE:RESTORE]",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "resumeOrder",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 29
}, {
"event" : "REACTIVE_EVENT",
"className" : "click.kamil.examples.statemachine.extended.service.ReactiveOrderService",
"methodName" : "processReactive",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 18
} ],
"entryPoints" : [ {
"type" : "REST",
"name" : "POST /api/orders/submit",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "submitOrder",
"metadata" : {
"path" : "/api/orders/submit",
"verb" : "POST"
}
}, {
"type" : "REST",
"name" : "POST /api/orders/cancel",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "cancelOrder",
"metadata" : {
"path" : "/api/orders/cancel",
"verb" : "POST"
}
}, {
"type" : "REST",
"name" : "POST /api/orders/finish",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "finishOrder",
"metadata" : {
"path" : "/api/orders/finish",
"verb" : "POST"
}
}, {
"type" : "REST",
"name" : "POST /api/orders/resume",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "resumeOrder",
"metadata" : {
"path" : "/api/orders/resume",
"verb" : "POST"
}
}, {
"type" : "REST",
"name" : "POST /api/orders/reactive",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "reactiveOrder",
"metadata" : {
"path" : "/api/orders/reactive",
"verb" : "POST"
}
}, {
"type" : "CUSTOM",
"name" : "INTERCEPTOR: AuditInterceptor.preHandle",
"className" : "click.kamil.examples.statemachine.extended.web.AuditInterceptor",
"methodName" : "preHandle",
"metadata" : {
"interceptorType" : "Spring MVC Interceptor"
}
} ],
"callChains" : [ {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/orders/submit",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "submitOrder",
"metadata" : {
"path" : "/api/orders/submit",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.statemachine.extended.web.OrderController.submitOrder", "click.kamil.examples.statemachine.extended.service.OrderService.processSubmit" ],
"triggerPoint" : {
"event" : "EXTERNAL_TRIGGER",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "processSubmit",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 19
}
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/orders/submit",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "submitOrder",
"metadata" : {
"path" : "/api/orders/submit",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.statemachine.extended.web.OrderController.submitOrder", "click.kamil.examples.statemachine.extended.service.OrderService.processSubmit" ],
"triggerPoint" : {
"event" : "SUBMIT_EVENT",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "processSubmit",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 20
}
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/orders/cancel",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "cancelOrder",
"metadata" : {
"path" : "/api/orders/cancel",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.statemachine.extended.web.OrderController.cancelOrder", "click.kamil.examples.statemachine.extended.service.OrderService.processCancel" ],
"triggerPoint" : {
"event" : "CANCEL_EVENT",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "processCancel",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 25
}
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/orders/finish",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "finishOrder",
"metadata" : {
"path" : "/api/orders/finish",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.statemachine.extended.web.OrderController.finishOrder" ],
"triggerPoint" : {
"event" : "FINISH",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "finishOrder",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 34
}
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/orders/resume",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "resumeOrder",
"metadata" : {
"path" : "/api/orders/resume",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.statemachine.extended.web.OrderController.resumeOrder", "click.kamil.examples.statemachine.extended.service.OrderService.resumeOrder" ],
"triggerPoint" : {
"event" : "[LIFECYCLE:RESTORE]",
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
"methodName" : "resumeOrder",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 29
}
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/orders/reactive",
"className" : "click.kamil.examples.statemachine.extended.web.OrderController",
"methodName" : "reactiveOrder",
"metadata" : {
"path" : "/api/orders/reactive",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.statemachine.extended.web.OrderController.reactiveOrder", "click.kamil.examples.statemachine.extended.service.ReactiveOrderService.processReactive" ],
"triggerPoint" : {
"event" : "REACTIVE_EVENT",
"className" : "click.kamil.examples.statemachine.extended.service.ReactiveOrderService",
"methodName" : "processReactive",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 18
}
}, {
"entryPoint" : {
"type" : "CUSTOM",
"name" : "INTERCEPTOR: AuditInterceptor.preHandle",
"className" : "click.kamil.examples.statemachine.extended.web.AuditInterceptor",
"methodName" : "preHandle",
"metadata" : {
"interceptorType" : "Spring MVC Interceptor"
}
},
"methodChain" : [ "click.kamil.examples.statemachine.extended.web.AuditInterceptor.preHandle" ],
"triggerPoint" : {
"event" : "AUDIT_EVENT",
"className" : "click.kamil.examples.statemachine.extended.web.AuditInterceptor",
"methodName" : "preHandle",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 16
}
} ],
"properties" : {
"app.states.initial" : "PROD_INITIAL"
}
},
"name" : "click.kamil.examples.statemachine.extended.config.ExtendedStateMachineConfig",
"renderChoicesAsDiamonds" : true,
"startStates" : [ "PROD_INITIAL" ],
"transitions" : [ {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"START\"",
"fullIdentifier" : "START"
} ],
"targetStates" : [ {
"rawName" : "\"PROCESSING\"",
"fullIdentifier" : "PROCESSING"
} ],
"event" : "SUBMIT_EVENT",
"guard" : null,
"actions" : [ ],
"order" : null
}, {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"PROCESSING\"",
"fullIdentifier" : "PROCESSING"
} ],
"targetStates" : [ {
"rawName" : "\"COMPLETED\"",
"fullIdentifier" : "COMPLETED"
} ],
"event" : "FINISH",
"guard" : null,
"actions" : [ ],
"order" : null
}, {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"PROCESSING\"",
"fullIdentifier" : "PROCESSING"
} ],
"targetStates" : [ {
"rawName" : "\"CANCELLED\"",
"fullIdentifier" : "CANCELLED"
} ],
"event" : "CANCEL_EVENT",
"guard" : null,
"actions" : [ ],
"order" : null
}, {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"START\"",
"fullIdentifier" : "START"
} ],
"targetStates" : [ {
"rawName" : "\"PROCESSING\"",
"fullIdentifier" : "PROCESSING"
} ],
"event" : "REACTIVE_EVENT",
"guard" : null,
"actions" : [ ],
"order" : null
}, {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"START\"",
"fullIdentifier" : "START"
} ],
"targetStates" : [ {
"rawName" : "\"START\"",
"fullIdentifier" : "START"
} ],
"event" : "AUDIT_EVENT",
"guard" : null,
"actions" : [ ],
"order" : null
}, {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"START\"",
"fullIdentifier" : "START"
} ],
"targetStates" : [ {
"rawName" : "\"PROCESSING\"",
"fullIdentifier" : "PROCESSING"
} ],
"event" : "EXTERNAL_TRIGGER",
"guard" : null,
"actions" : [ ],
"order" : null
} ],
"endStates" : [ "CANCELLED", "COMPLETED" ]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,70 @@
@startuml
!pragma layout smetana
hide empty description
hide stereotype
state START
state PROCESSING
state COMPLETED
state CANCELLED
<style>
state {
.choice {
BackgroundColor LightYellow
}
}
arrow {
LineThickness 1
.external { LineColor #1E90FF }
.internal { LineColor #32CD32 }
.local { LineColor #FFA500 }
.junction { LineColor #FF69B4 }
.join { LineColor #8A2BE2 }
.fork { LineColor #20B2AA }
.choice_type { LineColor #000000 }
.choice_color_0 { LineColor #FF6347 }
.choice_color_1 { LineColor #4682B4 }
.choice_color_2 { LineColor #32CD32 }
.choice_color_3 { LineColor #FFD700 }
.choice_color_4 { LineColor #6A5ACD }
.choice_color_5 { LineColor #FF69B4 }
}
/* Example: Highlight all transitions for a specific event */
/* .e_MY_EVENT { LineColor red } */
</style>
hide <<external>> stereotype
hide <<internal>> stereotype
hide <<local>> stereotype
hide <<junction>> stereotype
hide <<join>> stereotype
hide <<fork>> stereotype
hide <<choice_type>> stereotype
hide <<choice_color_0>> stereotype
hide <<choice_color_1>> stereotype
hide <<choice_color_2>> stereotype
hide <<choice_color_3>> stereotype
hide <<choice_color_4>> stereotype
hide <<choice_color_5>> stereotype
[*] --> PROD_INITIAL
START -[#1E90FF,bold]-> PROCESSING <<external>> <<e_SUBMIT_EVENT>> : SUBMIT_EVENT
PROCESSING -[#1E90FF,bold]-> COMPLETED <<external>> <<e_FINISH>> : FINISH
PROCESSING -[#1E90FF,bold]-> CANCELLED <<external>> <<e_CANCEL_EVENT>> : CANCEL_EVENT
START -[#1E90FF,bold]-> PROCESSING <<external>> <<e_REACTIVE_EVENT>> : REACTIVE_EVENT
START -[#1E90FF,bold]-> START <<external>> <<e_AUDIT_EVENT>> : AUDIT_EVENT
START -[#1E90FF,bold]-> PROCESSING <<external>> <<e_EXTERNAL_TRIGGER>> : EXTERNAL_TRIGGER
hide <<e_SUBMIT_EVENT>> stereotype
hide <<e_FINISH>> stereotype
hide <<e_CANCEL_EVENT>> stereotype
hide <<e_REACTIVE_EVENT>> stereotype
hide <<e_AUDIT_EVENT>> stereotype
hide <<e_EXTERNAL_TRIGGER>> stereotype
CANCELLED --> [*]
COMPLETED --> [*]
@enduml

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="PROD_INITIAL">
<state id="START">
<transition target="PROCESSING" event="SUBMIT_EVENT"/>
<transition target="PROCESSING" event="REACTIVE_EVENT"/>
<transition target="START" event="AUDIT_EVENT"/>
<transition target="PROCESSING" event="EXTERNAL_TRIGGER"/>
</state>
<state id="PROCESSING">
<transition target="COMPLETED" event="FINISH"/>
<transition target="CANCELLED" event="CANCEL_EVENT"/>
</state>
<state id="COMPLETED">
</state>
<state id="CANCELLED">
</state>
<state id="PROD_INITIAL">
</state>
</scxml>

View File

@@ -1,5 +1,15 @@
{
"metadata" : {
"triggers" : [ ],
"entryPoints" : [ ],
"callChains" : [ ],
"properties" : {
"spring.application.name" : "statemachinedemo"
}
},
"name" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.F1StateMachineConfiguration",
"renderChoicesAsDiamonds" : true,
"startStates" : [ "States.STATE1" ],
"transitions" : [ {
"type" : "EXTERNAL",
"sourceStates" : [ {
@@ -774,7 +784,5 @@
"actions" : [ ],
"order" : null
} ],
"startStates" : [ "States.STATE1" ],
"endStates" : [ "States.STATEZ" ],
"renderChoicesAsDiamonds" : true
"endStates" : [ "States.STATEZ" ]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 KiB

After

Width:  |  Height:  |  Size: 210 KiB

View File

@@ -1,4 +1,35 @@
@startuml
!pragma layout smetana
hide empty description
hide stereotype
state STATE1
state STATE2
state STATE3
state STATE4
state STATE5
state STATE6
state STATE7
state STATE8
state STATE9
state STATE10
state STATE11
state STATE12
state STATE13
state STATE14
state STATE15
state STATE16
state CANCEL
state STATEY
state STATEX
state STATEZ
state STATE17
state STATE18
state STATE19
state STATE20
state STATE_EXTRA_1
state STATE_EXTRA_3
state STATE_EXTRA_2
<style>
state {
.choice {

View File

@@ -1,5 +1,15 @@
{
"metadata" : {
"triggers" : [ ],
"entryPoints" : [ ],
"callChains" : [ ],
"properties" : {
"spring.application.name" : "statemachinedemo"
}
},
"name" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.F2StateMachineConfiguration",
"renderChoicesAsDiamonds" : true,
"startStates" : [ "States.STATE1" ],
"transitions" : [ {
"type" : "EXTERNAL",
"sourceStates" : [ {
@@ -788,7 +798,5 @@
"actions" : [ ],
"order" : null
} ],
"startStates" : [ "States.STATE1" ],
"endStates" : [ "States.STATEZ" ],
"renderChoicesAsDiamonds" : true
"endStates" : [ "States.STATEZ" ]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 KiB

After

Width:  |  Height:  |  Size: 249 KiB

View File

@@ -1,4 +1,36 @@
@startuml
!pragma layout smetana
hide empty description
hide stereotype
state STATE1
state STATE2
state STATE3
state STATE4
state STATE5
state STATE6
state STATE7
state STATE8
state STATE9
state STATE10
state STATE11
state STATE12
state STATE13
state STATE14
state STATE15
state STATE16
state CANCEL
state STATEY
state STATEX
state STATEZ
state STATE17
state STATE18
state STATE19
state STATE20
state STATE_EXTRA_1_1
state STATE_EXTRA_1_2
state STATE_EXTRA_1_3
state STATE_EXTRA_1
<style>
state {
.choice {

View File

@@ -1,5 +1,15 @@
{
"metadata" : {
"triggers" : [ ],
"entryPoints" : [ ],
"callChains" : [ ],
"properties" : {
"spring.application.name" : "statemachinedemo"
}
},
"name" : "click.kamil.examples.statemachine.forkjoin.ForkJoinStateMachineConfig",
"renderChoicesAsDiamonds" : true,
"startStates" : [ "States.START" ],
"transitions" : [ {
"type" : "EXTERNAL",
"sourceStates" : [ {
@@ -91,7 +101,5 @@
"actions" : [ ],
"order" : null
} ],
"startStates" : [ "States.START" ],
"endStates" : [ "States.END" ],
"renderChoicesAsDiamonds" : true
"endStates" : [ "States.END" ]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -1,4 +1,16 @@
@startuml
!pragma layout smetana
hide empty description
hide stereotype
state START
state FORK
state REGION1_STATE1
state REGION2_STATE1
state REGION1_STATE2
state REGION2_STATE2
state JOIN
state END
<style>
state {
.choice {

View File

@@ -1,5 +1,15 @@
{
"metadata" : {
"triggers" : [ ],
"entryPoints" : [ ],
"callChains" : [ ],
"properties" : {
"spring.application.name" : "statemachinedemo"
}
},
"name" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.G1StateMachineConfiguration",
"renderChoicesAsDiamonds" : true,
"startStates" : [ "States.STATE1" ],
"transitions" : [ {
"type" : "EXTERNAL",
"sourceStates" : [ {
@@ -363,7 +373,5 @@
"actions" : [ ],
"order" : null
} ],
"startStates" : [ "States.STATE1" ],
"endStates" : [ "States.STATEZ" ],
"renderChoicesAsDiamonds" : true
"endStates" : [ "States.STATEZ" ]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 90 KiB

View File

@@ -1,4 +1,24 @@
@startuml
!pragma layout smetana
hide empty description
hide stereotype
state STATE1
state STATE2
state STATE3
state STATE4
state STATE5
state STATE6
state STATE7
state STATE8
state STATE9
state STATE10
state CANCEL
state STATEY
state STATEX
state STATEZ
state STATE_EXTRA_2
state STATE_EXTRA_3
<style>
state {
.choice {

View File

@@ -1,5 +1,15 @@
{
"metadata" : {
"triggers" : [ ],
"entryPoints" : [ ],
"callChains" : [ ],
"properties" : {
"spring.application.name" : "statemachinedemo"
}
},
"name" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.G2StateMachineConfiguration",
"renderChoicesAsDiamonds" : true,
"startStates" : [ "States.STATE1" ],
"transitions" : [ {
"type" : "EXTERNAL",
"sourceStates" : [ {
@@ -377,7 +387,5 @@
"actions" : [ ],
"order" : null
} ],
"startStates" : [ "States.STATE1" ],
"endStates" : [ "States.STATEZ" ],
"renderChoicesAsDiamonds" : true
"endStates" : [ "States.STATEZ" ]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 98 KiB

View File

@@ -1,4 +1,24 @@
@startuml
!pragma layout smetana
hide empty description
hide stereotype
state STATE1
state STATE2
state STATE3
state STATE4
state STATE5
state STATE6
state STATE7
state STATE8
state STATE9
state STATE10
state CANCEL
state STATEY
state STATEX
state STATEZ
state STATE_EXTRA_1
state STATE_EXTRA_2
<style>
state {
.choice {

View File

@@ -0,0 +1,11 @@
digraph statemachine {
rankdir=LR;
node [shape=rounded, style=filled, fillcolor=white, fontname="Arial"];
edge [fontname="Arial", fontsize=10];
_start [shape=circle, label="", fillcolor=black, width=0.1];
_start -> START;
WORKING [fillcolor=lightgray];
START -> WORKING [label="INHERITED_SUBMIT", style="solid", color="black"];
}

View File

@@ -0,0 +1,63 @@
{
"metadata" : {
"triggers" : [ {
"event" : "INHERITED_SUBMIT",
"className" : "click.kamil.examples.statemachine.inheritance.service.ProcessingServiceImpl",
"methodName" : "doProcess",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 15
} ],
"entryPoints" : [ {
"type" : "REST",
"name" : "POST /api/v2/orders/submit",
"className" : "click.kamil.examples.statemachine.inheritance.api.OrderControllerImpl",
"methodName" : "submitOrder",
"metadata" : {
"path" : "/api/v2/orders/submit",
"verb" : "POST"
}
} ],
"callChains" : [ {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/v2/orders/submit",
"className" : "click.kamil.examples.statemachine.inheritance.api.OrderControllerImpl",
"methodName" : "submitOrder",
"metadata" : {
"path" : "/api/v2/orders/submit",
"verb" : "POST"
}
},
"methodChain" : [ "click.kamil.examples.statemachine.inheritance.api.OrderControllerImpl.submitOrder", "click.kamil.examples.statemachine.inheritance.service.ProcessingServiceImpl.doProcess" ],
"triggerPoint" : {
"event" : "INHERITED_SUBMIT",
"className" : "click.kamil.examples.statemachine.inheritance.service.ProcessingServiceImpl",
"methodName" : "doProcess",
"sourceModule" : null,
"stateMachineId" : null,
"lineNumber" : 15
}
} ],
"properties" : { }
},
"name" : "click.kamil.examples.statemachine.inheritance.config.InheritanceStateMachineConfig",
"renderChoicesAsDiamonds" : true,
"startStates" : [ "START" ],
"transitions" : [ {
"type" : "EXTERNAL",
"sourceStates" : [ {
"rawName" : "\"START\"",
"fullIdentifier" : "START"
} ],
"targetStates" : [ {
"rawName" : "\"WORKING\"",
"fullIdentifier" : "WORKING"
} ],
"event" : "INHERITED_SUBMIT",
"guard" : null,
"actions" : [ ],
"order" : null
} ],
"endStates" : [ "WORKING" ]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -0,0 +1,57 @@
@startuml
!pragma layout smetana
hide empty description
hide stereotype
state START
state WORKING
<style>
state {
.choice {
BackgroundColor LightYellow
}
}
arrow {
LineThickness 1
.external { LineColor #1E90FF }
.internal { LineColor #32CD32 }
.local { LineColor #FFA500 }
.junction { LineColor #FF69B4 }
.join { LineColor #8A2BE2 }
.fork { LineColor #20B2AA }
.choice_type { LineColor #000000 }
.choice_color_0 { LineColor #FF6347 }
.choice_color_1 { LineColor #4682B4 }
.choice_color_2 { LineColor #32CD32 }
.choice_color_3 { LineColor #FFD700 }
.choice_color_4 { LineColor #6A5ACD }
.choice_color_5 { LineColor #FF69B4 }
}
/* Example: Highlight all transitions for a specific event */
/* .e_MY_EVENT { LineColor red } */
</style>
hide <<external>> stereotype
hide <<internal>> stereotype
hide <<local>> stereotype
hide <<junction>> stereotype
hide <<join>> stereotype
hide <<fork>> stereotype
hide <<choice_type>> stereotype
hide <<choice_color_0>> stereotype
hide <<choice_color_1>> stereotype
hide <<choice_color_2>> stereotype
hide <<choice_color_3>> stereotype
hide <<choice_color_4>> stereotype
hide <<choice_color_5>> stereotype
[*] --> START
START -[#1E90FF,bold]-> WORKING <<external>> <<e_INHERITED_SUBMIT>> : INHERITED_SUBMIT
hide <<e_INHERITED_SUBMIT>> stereotype
WORKING --> [*]
@enduml

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="START">
<state id="START">
<transition target="WORKING" event="INHERITED_SUBMIT"/>
</state>
<state id="WORKING">
</state>
</scxml>

View File

@@ -1,5 +1,15 @@
{
"metadata" : {
"triggers" : [ ],
"entryPoints" : [ ],
"callChains" : [ ],
"properties" : {
"spring.application.name" : "statemachinedemo"
}
},
"name" : "click.kamil.examples.statemachine.enumstate.KamilEnumStateMachineConfiguration",
"renderChoicesAsDiamonds" : true,
"startStates" : [ "OrderStates.SUBMITTED" ],
"transitions" : [ {
"type" : "EXTERNAL",
"sourceStates" : [ {
@@ -195,7 +205,5 @@
} ],
"order" : null
} ],
"startStates" : [ "OrderStates.SUBMITTED" ],
"endStates" : [ "OrderStates.CANCELED", "OrderStates.FULFILLED" ],
"renderChoicesAsDiamonds" : true
"endStates" : [ "OrderStates.CANCELED", "OrderStates.FULFILLED" ]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -1,4 +1,16 @@
@startuml
!pragma layout smetana
hide empty description
hide stereotype
state SUBMITTED
state PAID
state FULFILLED
state CANCELED
state PAID1
state PAID2
state PAID3
state HAPPEN
<style>
state {
.choice {

View File

@@ -1,5 +1,15 @@
{
"metadata" : {
"triggers" : [ ],
"entryPoints" : [ ],
"callChains" : [ ],
"properties" : {
"spring.application.name" : "statemachinedemo"
}
},
"name" : "click.kamil.examples.statemachine.inheritancestate.OneStateMachineConfiguration",
"renderChoicesAsDiamonds" : true,
"startStates" : [ "States.STATE1" ],
"transitions" : [ {
"type" : "EXTERNAL",
"sourceStates" : [ {
@@ -631,7 +641,5 @@
"actions" : [ ],
"order" : null
} ],
"startStates" : [ "States.STATE1" ],
"endStates" : [ "States.STATEZ" ],
"renderChoicesAsDiamonds" : true
"endStates" : [ "States.STATEZ" ]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

After

Width:  |  Height:  |  Size: 190 KiB

View File

@@ -1,4 +1,32 @@
@startuml
!pragma layout smetana
hide empty description
hide stereotype
state STATE1
state STATE2
state STATE3
state STATE4
state STATE5
state STATE6
state STATE7
state STATE8
state STATE9
state STATE10
state STATE11
state STATE12
state STATE13
state STATE14
state STATE15
state STATE16
state STATEY
state STATEX
state STATEZ
state STATE17
state STATE18
state STATE19
state STATE20
state STATE_EXTRA_1
<style>
state {
.choice {

View File

@@ -1,5 +1,15 @@
{
"metadata" : {
"triggers" : [ ],
"entryPoints" : [ ],
"callChains" : [ ],
"properties" : {
"spring.application.name" : "statemachinedemo"
}
},
"name" : "click.kamil.examples.statemachine.simple.SimpleEnumStateMachineConfiguration",
"renderChoicesAsDiamonds" : true,
"startStates" : [ "OrderStates.SUBMITTED" ],
"transitions" : [ {
"type" : "EXTERNAL",
"sourceStates" : [ {
@@ -212,7 +222,5 @@
} ],
"order" : null
} ],
"startStates" : [ "OrderStates.SUBMITTED" ],
"endStates" : [ "OrderStates.CANCELED", "OrderStates.FULFILLED" ],
"renderChoicesAsDiamonds" : true
"endStates" : [ "OrderStates.CANCELED", "OrderStates.FULFILLED" ]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -1,4 +1,16 @@
@startuml
!pragma layout smetana
hide empty description
hide stereotype
state SUBMITTED
state PAID
state FULFILLED
state CANCELED
state PAID2
state PAID3
state PAID1
state HAPPEN
<style>
state {
.choice {

View File

@@ -1,5 +1,15 @@
{
"metadata" : {
"triggers" : [ ],
"entryPoints" : [ ],
"callChains" : [ ],
"properties" : {
"spring.application.name" : "statemachinedemo"
}
},
"name" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.ThreeStateMachineConfiguration",
"renderChoicesAsDiamonds" : true,
"startStates" : [ "States.STATE1" ],
"transitions" : [ {
"type" : "EXTERNAL",
"sourceStates" : [ {
@@ -774,7 +784,5 @@
"actions" : [ ],
"order" : null
} ],
"startStates" : [ "States.STATE1" ],
"endStates" : [ "States.STATEZ" ],
"renderChoicesAsDiamonds" : true
"endStates" : [ "States.STATEZ" ]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 KiB

After

Width:  |  Height:  |  Size: 210 KiB

View File

@@ -1,4 +1,35 @@
@startuml
!pragma layout smetana
hide empty description
hide stereotype
state STATE1
state STATE2
state STATE3
state STATE4
state STATE5
state STATE6
state STATE7
state STATE8
state STATE9
state STATE10
state STATE11
state STATE12
state STATE13
state STATE14
state STATE15
state STATE16
state CANCEL
state STATEY
state STATEX
state STATEZ
state STATE17
state STATE18
state STATE19
state STATE20
state STATE_EXTRA_1
state STATE_EXTRA_3
state STATE_EXTRA_2
<style>
state {
.choice {

View File

@@ -1,5 +1,15 @@
{
"metadata" : {
"triggers" : [ ],
"entryPoints" : [ ],
"callChains" : [ ],
"properties" : {
"spring.application.name" : "statemachinedemo"
}
},
"name" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate.TwoStateMachineConfiguration",
"renderChoicesAsDiamonds" : true,
"startStates" : [ "States.STATE1" ],
"transitions" : [ {
"type" : "EXTERNAL",
"sourceStates" : [ {
@@ -729,7 +739,5 @@
"actions" : [ ],
"order" : null
} ],
"startStates" : [ "States.STATE1" ],
"endStates" : [ "States.STATEZ" ],
"renderChoicesAsDiamonds" : true
"endStates" : [ "States.STATEZ" ]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 KiB

After

Width:  |  Height:  |  Size: 219 KiB

View File

@@ -1,4 +1,33 @@
@startuml
!pragma layout smetana
hide empty description
hide stereotype
state STATE1
state STATE2
state STATE3
state STATE4
state STATE5
state STATE6
state STATE7
state STATE8
state STATE9
state STATE10
state STATE11
state STATE12
state STATE13
state STATE14
state STATE15
state STATE16
state CANCEL
state STATEY
state STATEX
state STATEZ
state STATE17
state STATE18
state STATE19
state STATE20
state STATE_EXTRA_1
<style>
state {
.choice {