package change
This commit is contained in:
@@ -4,7 +4,7 @@ plugins {
|
||||
id 'io.spring.dependency-management' version '1.1.7'
|
||||
}
|
||||
|
||||
group = 'com.example'
|
||||
group = 'click.kamil'
|
||||
version = '0.0.1-SNAPSHOT'
|
||||
|
||||
java {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.statemachinedemo;
|
||||
package click.kamil.springstatemachineexporter;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
@@ -1,16 +1,16 @@
|
||||
package com.example.statemachinedemo;
|
||||
package click.kamil.springstatemachineexporter.ast;
|
||||
|
||||
import com.example.statemachinedemo.app.AstTransitionParser;
|
||||
import com.example.statemachinedemo.app.StateMachineStateConfigurationMethodFinder;
|
||||
import com.example.statemachinedemo.app.StateMachineTransitionConfigurationMethodFinder;
|
||||
import com.example.statemachinedemo.app.TransitionStateUtils;
|
||||
import com.example.statemachinedemo.app.domain.Transition;
|
||||
import com.example.statemachinedemo.common.FileUtils;
|
||||
import com.example.statemachinedemo.in.AstFileFinder;
|
||||
import com.example.statemachinedemo.out.Dot;
|
||||
import com.example.statemachinedemo.out.PlantUml;
|
||||
import com.example.statemachinedemo.out.Scxml;
|
||||
import com.example.statemachinedemo.out.StateMachineExporter;
|
||||
import click.kamil.springstatemachineexporter.ast.app.AstTransitionParser;
|
||||
import click.kamil.springstatemachineexporter.ast.app.StateMachineStateConfigurationMethodFinder;
|
||||
import click.kamil.springstatemachineexporter.ast.app.StateMachineTransitionConfigurationMethodFinder;
|
||||
import click.kamil.springstatemachineexporter.ast.app.TransitionStateUtils;
|
||||
import click.kamil.springstatemachineexporter.ast.app.domain.Transition;
|
||||
import click.kamil.springstatemachineexporter.ast.common.FileUtils;
|
||||
import click.kamil.springstatemachineexporter.ast.in.AstFileFinder;
|
||||
import click.kamil.springstatemachineexporter.ast.out.Dot;
|
||||
import click.kamil.springstatemachineexporter.ast.out.PlantUml;
|
||||
import click.kamil.springstatemachineexporter.ast.out.Scxml;
|
||||
import click.kamil.springstatemachineexporter.ast.out.StateMachineExporter;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.example.statemachinedemo.app;
|
||||
package click.kamil.springstatemachineexporter.ast.app;
|
||||
|
||||
import com.example.statemachinedemo.app.domain.Transition;
|
||||
import click.kamil.springstatemachineexporter.ast.app.domain.Transition;
|
||||
import org.eclipse.jdt.core.dom.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.statemachinedemo.app;
|
||||
package click.kamil.springstatemachineexporter.ast.app;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.eclipse.jdt.core.dom.*;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.statemachinedemo.app;
|
||||
package click.kamil.springstatemachineexporter.ast.app;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.eclipse.jdt.core.dom.*;
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.example.statemachinedemo.app;
|
||||
package click.kamil.springstatemachineexporter.ast.app;
|
||||
|
||||
import com.example.statemachinedemo.app.domain.Transition;
|
||||
import click.kamil.springstatemachineexporter.ast.app.domain.Transition;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.statemachinedemo.app.domain;
|
||||
package click.kamil.springstatemachineexporter.ast.app.domain;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.statemachinedemo.common;
|
||||
package click.kamil.springstatemachineexporter.ast.common;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.statemachinedemo.in;
|
||||
package click.kamil.springstatemachineexporter.ast.in;
|
||||
|
||||
import org.eclipse.jdt.core.dom.*;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.example.statemachinedemo.out;
|
||||
package click.kamil.springstatemachineexporter.ast.out;
|
||||
|
||||
import com.example.statemachinedemo.app.domain.Transition;
|
||||
import click.kamil.springstatemachineexporter.ast.app.domain.Transition;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.example.statemachinedemo.out;
|
||||
package click.kamil.springstatemachineexporter.ast.out;
|
||||
|
||||
import com.example.statemachinedemo.app.domain.Transition;
|
||||
import click.kamil.springstatemachineexporter.ast.app.domain.Transition;
|
||||
import io.micrometer.common.util.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
@@ -8,6 +8,20 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class PlantUml implements StateMachineExporter {
|
||||
// Color palette for choices
|
||||
private final List<String> choiceColors = List.of("FF6347", "4682B4", "32CD32", "FFD700", "6A5ACD", "FF69B4");
|
||||
private String getColor(Transition t, String source, Map<String, String> choiceStateColorMap) {
|
||||
return switch (t.getType()) {
|
||||
case "withChoice" -> choiceStateColorMap.getOrDefault(source, "000000");
|
||||
case "withExternal" -> "1E90FF";
|
||||
case "withInternal" -> "32CD32";
|
||||
case "withLocal" -> "FFA500";
|
||||
case "withJunction" -> "FF69B4";
|
||||
case "withJoin" -> "8A2BE2";
|
||||
case "withFork" -> "20B2AA";
|
||||
default -> "000000";
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String export(List<Transition> transitions,
|
||||
@@ -44,9 +58,6 @@ public class PlantUml implements StateMachineExporter {
|
||||
}
|
||||
sb.append("\n");
|
||||
|
||||
// Color palette for choices
|
||||
List<String> choiceColors = List.of("FF6347", "4682B4", "32CD32", "FFD700", "6A5ACD", "FF69B4");
|
||||
|
||||
// Assign color to each choice state
|
||||
Map<String, String> choiceStateColorMap = new HashMap<>();
|
||||
int colorIndex = 0;
|
||||
@@ -168,17 +179,4 @@ public class PlantUml implements StateMachineExporter {
|
||||
|
||||
return String.join(" ", parts);
|
||||
}
|
||||
|
||||
private String getColor(Transition t, String source, Map<String, String> choiceStateColorMap) {
|
||||
return switch (t.getType()) {
|
||||
case "withChoice" -> choiceStateColorMap.getOrDefault(source, "000000");
|
||||
case "withExternal" -> "1E90FF";
|
||||
case "withInternal" -> "32CD32";
|
||||
case "withLocal" -> "FFA500";
|
||||
case "withJunction" -> "FF69B4";
|
||||
case "withJoin" -> "8A2BE2";
|
||||
case "withFork" -> "20B2AA";
|
||||
default -> "000000";
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.example.statemachinedemo.out;
|
||||
package click.kamil.springstatemachineexporter.ast.out;
|
||||
|
||||
import com.example.statemachinedemo.app.domain.Transition;
|
||||
import click.kamil.springstatemachineexporter.ast.app.domain.Transition;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.example.statemachinedemo.out;
|
||||
package click.kamil.springstatemachineexporter.ast.out;
|
||||
|
||||
import com.example.statemachinedemo.app.domain.Transition;
|
||||
import click.kamil.springstatemachineexporter.ast.app.domain.Transition;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -0,0 +1,180 @@
|
||||
package click.kamil.springstatemachineexporter.springbased;
|
||||
|
||||
import click.kamil.springstatemachineexporter.statemachine.OrderEvents;
|
||||
import click.kamil.springstatemachineexporter.statemachine.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 {
|
||||
@Qualifier("simpleEnumStateMachineFactory")
|
||||
protected final StateMachineFactory<OrderStates, OrderEvents> factory;
|
||||
|
||||
protected BaseExporter(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)));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.statemachinedemo.z.statemachine;
|
||||
package click.kamil.springstatemachineexporter.statemachine;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.statemachine.action.Action;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.statemachinedemo.z.statemachine;
|
||||
package click.kamil.springstatemachineexporter.statemachine;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.statemachine.action.Action;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.statemachinedemo.z.statemachine;
|
||||
package click.kamil.springstatemachineexporter.statemachine;
|
||||
|
||||
public enum OrderEvents {
|
||||
FULFILL, PAY, CANCEL,
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.statemachinedemo.z.statemachine;
|
||||
package click.kamil.springstatemachineexporter.statemachine;
|
||||
|
||||
public enum OrderStates {
|
||||
SUBMITTED, PAID, FULFILLED, CANCELED
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.statemachinedemo.z.statemachine;
|
||||
package click.kamil.springstatemachineexporter.statemachine;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -1,224 +0,0 @@
|
||||
package com.example.statemachinedemo.z.notgoodspringbased;
|
||||
|
||||
import com.example.statemachinedemo.z.statemachine.OrderEvents;
|
||||
import com.example.statemachinedemo.z.statemachine.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.FileNotFoundException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collection;
|
||||
|
||||
public class SpringExporter {
|
||||
}
|
||||
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
class Runner implements ApplicationRunner {
|
||||
// private final StateMachineFactory<OrderStates, OrderEvents> simpleEnumStateMachineConfiguration;
|
||||
// @Override
|
||||
// public void run(ApplicationArguments args) throws Exception {
|
||||
// StateMachine<OrderStates, OrderEvents> stateMachine = factory.getStateMachine("order");
|
||||
// stateMachine.start();
|
||||
// log.info("Current state is {}", stateMachine.getState().getId());
|
||||
//
|
||||
// }
|
||||
private final Config1 c;
|
||||
private final Config2 c2;
|
||||
private final Config3 c3;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
c.a();
|
||||
c2.a();
|
||||
c3.exportToSCXML();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class StateMachineDotExporter {
|
||||
public static <S, E> void export(StateMachine<S, E> stateMachine, PrintWriter writer) {
|
||||
writer.println("digraph stateMachine {");
|
||||
|
||||
for (State<S, E> state : stateMachine.getStates()) {
|
||||
writer.printf(" %s;%n", state.getId());
|
||||
}
|
||||
|
||||
for (Transition<S, E> transition : stateMachine.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("}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class StateMachinePlantUMLExporter {
|
||||
|
||||
public static <S, E> void export(StateMachine<S, E> stateMachine, PrintWriter writer) {
|
||||
writer.println("@startuml");
|
||||
|
||||
// Initial state
|
||||
writer.println("[*] --> " + stateMachine.getInitialState().getId());
|
||||
|
||||
for (Transition<S, E> transition : stateMachine.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 event is empty but there’s a guard, still label it meaningfully
|
||||
if (!label.isEmpty()) {
|
||||
label += " ";
|
||||
}
|
||||
label += "[guard]";
|
||||
}
|
||||
|
||||
// If there's no label at all, don't include ":"
|
||||
if (!label.isEmpty()) {
|
||||
writer.printf("%s --> %s : %s%n", source, target, label);
|
||||
} else {
|
||||
writer.printf("%s --> %s%n", source, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// End states
|
||||
for (State<S, E> state : stateMachine.getStates()) {
|
||||
if (state.getPseudoState() != null &&
|
||||
state.getPseudoState().getKind() == PseudoStateKind.END) {
|
||||
writer.printf("%s --> [*]%n", state.getId());
|
||||
}
|
||||
}
|
||||
|
||||
writer.println("@enduml");
|
||||
}
|
||||
}
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
class Config1 {
|
||||
@Qualifier("simpleEnumStateMachineFactory")
|
||||
private final StateMachineFactory<OrderStates, OrderEvents> simpleEnumStateMachineConfiguration;
|
||||
public void a() throws FileNotFoundException {
|
||||
StateMachine<OrderStates, OrderEvents> stateMachine = simpleEnumStateMachineConfiguration.getStateMachine("order");
|
||||
|
||||
StateMachineDotExporter exporter = new StateMachineDotExporter();
|
||||
try (PrintWriter out = new PrintWriter("statemachine.dot")) {
|
||||
StateMachineDotExporter.export(stateMachine, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
class Config2 {
|
||||
@Qualifier("simpleEnumStateMachineFactory")
|
||||
private final StateMachineFactory<OrderStates, OrderEvents> simpleEnumStateMachineConfiguration;
|
||||
public void a() throws FileNotFoundException {
|
||||
StateMachine<OrderStates, OrderEvents> stateMachine = simpleEnumStateMachineConfiguration.getStateMachine("order");
|
||||
|
||||
try (PrintWriter out = new PrintWriter("statemachine.uml.dot")) {
|
||||
StateMachinePlantUMLExporter.export(stateMachine, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
class Config3 {
|
||||
@Qualifier("simpleEnumStateMachineFactory")
|
||||
private final StateMachineFactory<OrderStates, OrderEvents> simpleEnumStateMachineConfiguration;
|
||||
public void exportToSCXML() throws Exception {
|
||||
StateMachine<OrderStates, OrderEvents> stateMachine = simpleEnumStateMachineConfiguration.getStateMachine("order");
|
||||
|
||||
SCXMLExporter exporter = new SCXMLExporter();
|
||||
File file = new File("statemachine.scxml.xml");
|
||||
exporter.exportToSCXML(stateMachine);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Component
|
||||
class SCXMLExporter {
|
||||
|
||||
// This method assumes you already have a state machine
|
||||
public <S, E> void exportToSCXML(StateMachine<S, E> stateMachine) throws Exception {
|
||||
// Create a document to represent the SCXML structure
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
Document doc = builder.newDocument();
|
||||
|
||||
// Root SCXML element
|
||||
Element scxmlElement = doc.createElement("scxml");
|
||||
scxmlElement.setAttribute("version", "1.0");
|
||||
doc.appendChild(scxmlElement);
|
||||
|
||||
// Define the states
|
||||
Element statesElement = doc.createElement("states");
|
||||
scxmlElement.appendChild(statesElement);
|
||||
|
||||
// Iterate over the states of the state machine
|
||||
Collection<State<S, E>> states = stateMachine.getStates();
|
||||
for (State<S, E> state : states) {
|
||||
Element stateElement = doc.createElement("state");
|
||||
stateElement.setAttribute("id", state.getId().toString());
|
||||
statesElement.appendChild(stateElement);
|
||||
}
|
||||
|
||||
// Define the transitions
|
||||
Element transitionsElement = doc.createElement("transitions");
|
||||
scxmlElement.appendChild(transitionsElement);
|
||||
|
||||
Collection<org.springframework.statemachine.transition.Transition<S, E>> transitions = stateMachine.getTransitions();
|
||||
for (Transition<S, E> transition : transitions) {
|
||||
Element transitionElement = doc.createElement("transition");
|
||||
transitionElement.setAttribute("from", transition.getSource().getId().toString());
|
||||
transitionElement.setAttribute("to", transition.getTarget().getId().toString());
|
||||
transitionElement.setAttribute("event", String.valueOf(transition.getTrigger()));
|
||||
transitionsElement.appendChild(transitionElement);
|
||||
}
|
||||
|
||||
// Write to file
|
||||
File file = new File("stateMachine.scxml");
|
||||
saveDocumentToFile(doc, file);
|
||||
}
|
||||
|
||||
private void saveDocumentToFile(Document doc, File file) throws Exception {
|
||||
// Serialize the document to a file (you can use your preferred XML writer)
|
||||
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
||||
StreamResult result = new StreamResult(file);
|
||||
DOMSource source = new DOMSource(doc);
|
||||
transformer.transform(source, result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package click.kamil.springstatemachineexporter;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
|
||||
@SpringBootTest
|
||||
class StatemachinedemoApplicationTests {
|
||||
|
||||
@MockitoBean
|
||||
CommandLineRunner commandLineRunner;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.example.statemachinedemo;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class StatemachinedemoApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user