1. extract state machines from this as well 2. extract from all possible formats (ask chatgpt) ```java import org.springframework.statemachine.StateMachine; import org.springframework.statemachine.config.builders.StateMachineBuilder; import java.util.EnumSet; public class DynamicStateMachineExample { public enum States { DRAFT, REVIEW, APPROVED } public enum Events { SUBMIT, APPROVE } public static StateMachine buildStateMachine() throws Exception { StateMachineBuilder.Builder builder = StateMachineBuilder.builder(); builder.configureStates() .withStates() .initial(States.DRAFT) .states(EnumSet.allOf(States.class)); builder.configureTransitions() .withExternal() .source(States.DRAFT).target(States.REVIEW).event(Events.SUBMIT) .and() .withExternal() .source(States.REVIEW).target(States.APPROVED).event(Events.APPROVE); return builder.build(); } public static void main(String[] args) throws Exception { StateMachine sm = buildStateMachine(); sm.start(); System.out.println("Current State: " + sm.getState().getId()); sm.sendEvent(Events.SUBMIT); System.out.println("After SUBMIT: " + sm.getState().getId()); sm.sendEvent(Events.APPROVE); System.out.println("After APPROVE: " + sm.getState().getId()); } } ``` 1. define how java function can be implemented 1.2. for this analyse bytecode manipulation such as project lombok 2. get a diagram 3. get a diagram with slicing, for example, slice by setValue on an ENUM field -> identify saga 1. make a list of all messages on message queues, how they're remapped and then who receives them NOTE ```java import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.expr.MethodCallExpr; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import java.io.File; import java.io.FileInputStream; import java.util.*; public class MethodCallGraphGenerator { static class MethodNode { String className; String methodName; public MethodNode(String className, String methodName) { this.className = className; this.methodName = methodName; } @Override public String toString() { return className + "." + methodName; } @Override public int hashCode() { return Objects.hash(className, methodName); } @Override public boolean equals(Object obj) { if (obj instanceof MethodNode other) { return this.className.equals(other.className) && this.methodName.equals(other.methodName); } return false; } } static Map> callGraph = new HashMap<>(); public static void main(String[] args) throws Exception { File sourceDir = new File("src"); // Change to your Java source directory parseDirectory(sourceDir); generateDotFile("callgraph.dot"); System.out.println("Call graph generated to callgraph.dot"); } private static void parseDirectory(File dir) throws Exception { for (File file : Objects.requireNonNull(dir.listFiles())) { if (file.isDirectory()) { parseDirectory(file); } else if (file.getName().endsWith(".java")) { parseFile(file); } } } private static void parseFile(File file) throws Exception { CompilationUnit cu = StaticJavaParser.parse(new FileInputStream(file)); cu.findAll(MethodDeclaration.class).forEach(method -> { String className = cu.getPrimaryTypeName().orElse("Unknown"); MethodNode caller = new MethodNode(className, method.getNameAsString()); callGraph.putIfAbsent(caller, new HashSet<>()); method.accept(new VoidVisitorAdapter() { @Override public void visit(MethodCallExpr call, Void arg) { super.visit(call, arg); String calleeName = call.getNameAsString(); MethodNode callee = new MethodNode("Unknown", calleeName); // Could be refined with better context callGraph.get(caller).add(callee); } }, null); }); } private static void generateDotFile(String filename) throws Exception { StringBuilder sb = new StringBuilder(); sb.append("digraph G {\n"); for (var caller : callGraph.keySet()) { for (var callee : callGraph.get(caller)) { sb.append(" \"").append(caller).append("\" -> \"").append(callee).append("\";\n"); } } sb.append("}"); java.nio.file.Files.writeString(new File(filename).toPath(), sb.toString()); } } ```