Expose accessor index toggling through ExportService and picocli, lock in layered_dispatcher_sample exports as golden fixtures, and document the static analysis pipeline in the README. Co-authored-by: Cursor <cursoragent@cursor.com>
Spring State Machine Explorer
Static analysis tool to extract and visualize Spring State Machines with deep code traceability.
Core Modules
state_machine_exporter: Java AST analyzer. Scans source code, resolves local Maven/Gradle dependencies, and extracts logic (Lambdas, Actions, Guards) into JSON/PUML.state_machine_exporter_html: Generates an interactive HTML portal with SVG diagrams and rich tooltips.
Usage
1. Extract Metadata (JSON)
./gradlew :state_machine_exporter:run --args="-i ./my-project -o ./out -f json"
2. Generate Interactive Portal (HTML)
./gradlew :state_machine_exporter_html:run --args="-i ./my-project -o ./out_html"
Supports --profiles prod to resolve Spring property placeholders.
Business Flows
Define sequence of events in src/main/resources/flows.json:
[
{
"name": "Order Success",
"description": "Happy path for order placement",
"steps": ["PAY", "CHECK_AVAILABILITY->PENDING", "SHIP"]
}
]
JSON Structure
metadata.entryPoints: REST, WebFlux, and JMS entry points.metadata.callChains: Trace from API call to machine trigger (sendEvent).transitions.actions[].internalLogic: Extracted source code/lambdas.metadata.properties: Dictionary of all detected Spring profiles.
Static analysis: accessor inlining
During scan, the exporter builds an accessor index of trivial getters, setters, record components, and constant-returning methods. At analysis time, AccessorResolver uses this index first (O(1) lookup), then falls back to constructor/field tracing and method-body evaluation.
This improves resolution of DTO/event chains such as request.getPayload().getType() without running Maven or Gradle on the target project.
# Enabled by default; disable for debugging or A/B comparison
./gradlew :state_machine_exporter:run --args="-i ./my-project -o ./out --no-inline-accessors"
Pipeline components live under analysis/pipeline/ (AccessorResolver, ResolutionBudget, MethodInvocationUnwrapper, FieldInitializerFinder, LibraryUnwrapRegistry).