move files into modules

This commit is contained in:
2026-06-06 15:07:03 +02:00
parent 00161b294c
commit cc66b7517b
88 changed files with 1090 additions and 79 deletions

View File

@@ -0,0 +1,180 @@
package click.kamil.springstatemachineexporter.springbased;
import click.kamil.examples.statemachine.simple.OrderEvents;
import click.kamil.examples.statemachine.simple.OrderStates;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.config.StateMachineFactory;
import org.springframework.statemachine.state.PseudoStateKind;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.transition.Transition;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.PrintWriter;
public class SpringExporter {
}
@Component
@Slf4j
@RequiredArgsConstructor
class Runner implements ApplicationRunner {
private final DotExporter dotExporter;
private final PlantUmlExporter plantUmlExporter;
private final ScxmlExporter scxmlExporter;
@Override
public void run(ApplicationArguments args) throws Exception {
dotExporter.export("stateMachine.dot");
plantUmlExporter.export("stateMachine.uml.dot");
scxmlExporter.export("stateMachine.scxml.xml");
}
}
abstract class BaseExporter {
protected final StateMachineFactory<OrderStates, OrderEvents> factory;
protected BaseExporter(@Qualifier("simpleEnumStateMachineFactory") StateMachineFactory<OrderStates, OrderEvents> factory) {
this.factory = factory;
}
abstract void export(String name) throws Exception;
protected StateMachine<OrderStates, OrderEvents> createStateMachine() {
return factory.getStateMachine("order");
}
}
@Component
class DotExporter extends BaseExporter {
public DotExporter(@Qualifier("simpleEnumStateMachineFactory") StateMachineFactory<OrderStates, OrderEvents> factory) {
super(factory);
}
@Override
public void export(String filename) throws Exception {
try (PrintWriter writer = new PrintWriter(filename)) {
StateMachine<OrderStates, OrderEvents> machine = createStateMachine();
writer.println("digraph stateMachine {");
for (State<OrderStates, OrderEvents> state : machine.getStates()) {
writer.printf(" %s;%n", state.getId());
}
for (Transition<OrderStates, OrderEvents> transition : machine.getTransitions()) {
if (transition.getSource() != null && transition.getTarget() != null) {
writer.printf(" %s -> %s [label=\"%s\"];%n",
transition.getSource().getId(),
transition.getTarget().getId(),
transition.getTrigger() != null ? transition.getTrigger().getEvent() : "");
}
}
writer.println("}");
}
}
}
@Component
class PlantUmlExporter extends BaseExporter {
public PlantUmlExporter(@Qualifier("simpleEnumStateMachineFactory") StateMachineFactory<OrderStates, OrderEvents> factory) {
super(factory);
}
@Override
public void export(String filename) throws Exception {
try (PrintWriter writer = new PrintWriter(filename)) {
StateMachine<OrderStates, OrderEvents> machine = createStateMachine();
writer.println("@startuml");
writer.println("[*] --> " + machine.getInitialState().getId());
for (Transition<OrderStates, OrderEvents> transition : machine.getTransitions()) {
if (transition.getSource() != null && transition.getTarget() != null) {
String source = transition.getSource().getId().toString();
String target = transition.getTarget().getId().toString();
String label = "";
if (transition.getTrigger() != null && transition.getTrigger().getEvent() != null) {
label += transition.getTrigger().getEvent().toString();
}
if (transition.getGuard() != null) {
if (!label.isEmpty()) label += " ";
label += "[guard]";
}
writer.printf("%s --> %s%s%n", source, target, !label.isEmpty() ? " : " + label : "");
}
}
for (State<OrderStates, OrderEvents> state : machine.getStates()) {
if (state.getPseudoState() != null && state.getPseudoState().getKind() == PseudoStateKind.END) {
writer.printf("%s --> [*]%n", state.getId());
}
}
writer.println("@enduml");
}
}
}
@Component
class ScxmlExporter extends BaseExporter {
public ScxmlExporter(@Qualifier("simpleEnumStateMachineFactory") StateMachineFactory<OrderStates, OrderEvents> factory) {
super(factory);
}
@Override
public void export(String filename) throws Exception {
StateMachine<OrderStates, OrderEvents> machine = createStateMachine();
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.newDocument();
Element scxml = doc.createElement("scxml");
scxml.setAttribute("version", "1.0");
doc.appendChild(scxml);
Element statesElement = doc.createElement("states");
scxml.appendChild(statesElement);
for (State<OrderStates, OrderEvents> state : machine.getStates()) {
Element stateEl = doc.createElement("state");
stateEl.setAttribute("id", state.getId().toString());
statesElement.appendChild(stateEl);
}
Element transitionsElement = doc.createElement("transitions");
scxml.appendChild(transitionsElement);
for (Transition<OrderStates, OrderEvents> transition : machine.getTransitions()) {
Element t = doc.createElement("transition");
t.setAttribute("from", transition.getSource().getId().toString());
t.setAttribute("to", transition.getTarget().getId().toString());
t.setAttribute("event", String.valueOf(transition.getTrigger()));
transitionsElement.appendChild(t);
}
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new DOMSource(doc), new StreamResult(new File(filename)));
}
}

View File

@@ -0,0 +1,13 @@
package click.kamil.springstatemachineexporter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
//@ComponentScan(basePackages = {"click.kamil."})
class StatemachinedemoApplication {
public static void main(String[] args) {
SpringApplication.run(StatemachinedemoApplication.class, args);
}
}

View File

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