2 Commits

Author SHA1 Message Date
0165da5f51 up 2026-07-04 07:25:11 +02:00
4d7cda56f5 up 2026-07-04 06:30:30 +02:00
8 changed files with 447 additions and 129 deletions

View File

@@ -58,6 +58,7 @@ tasks.named('test') {
task runGolden(type: JavaExec) {
mainClass = "click.kamil.springstatemachineexporter.GoldenUpdater"
classpath = sourceSets.test.runtimeClasspath
workingDir = rootProject.projectDir
}
task runGoldenFixed(type: JavaExec) {

View File

@@ -110,19 +110,82 @@ public class TransitionLinkerEnricher implements AnalysisEnricher {
if (constraint == null || machineName == null) return true;
String cleanMachine = machineName.substring(machineName.lastIndexOf('.') + 1).toUpperCase();
String constraintUpper = constraint.toUpperCase();
if (cleanMachine.endsWith("STATEMACHINECONFIGURATION")) {
cleanMachine = cleanMachine.substring(0, cleanMachine.length() - "STATEMACHINECONFIGURATION".length());
}
if (cleanMachine.endsWith("STATEMACHINE")) {
cleanMachine = cleanMachine.substring(0, cleanMachine.length() - "STATEMACHINE".length());
}
if (cleanMachine.endsWith("CONFIG")) {
cleanMachine = cleanMachine.substring(0, cleanMachine.length() - "CONFIG".length());
}
String expr = constraint;
java.util.List<String> allMachines = java.util.List.of("ORDER", "DOCUMENT", "USER");
for (String m : allMachines) {
if (!m.equals(cleanMachine)) {
if (constraintUpper.contains(m) && !constraintUpper.contains("!" + m) && !constraintUpper.contains("NOT")) {
if (constraintUpper.contains("\"" + m + "\"") || constraintUpper.contains("'" + m + "'") || constraintUpper.contains(m + ".")) {
return false;
}
boolean isCurrent = m.equals(cleanMachine);
String replacement = isCurrent ? "true" : "false";
String regex1 = "(?i)[\"']?" + m + "[\"']?\\s*\\.\\s*(equalsIgnoreCase|equals)\\s*\\([^)]*\\)";
String regex2 = "(?i)[a-zA-Z0-9._]+\\s*\\.\\s*(equalsIgnoreCase|equals)\\s*\\(\\s*[\"']?" + m + "[\"']?\\s*\\)";
String regex3 = "(?i)[a-zA-Z0-9._]+\\s*==\\s*[\"']?" + m + "[\"']?";
String regex4 = "(?i)[a-zA-Z0-9._]+\\s*!=\\s*[\"']?" + m + "[\"']?";
expr = expr.replaceAll(regex1, replacement);
expr = expr.replaceAll(regex2, replacement);
expr = expr.replaceAll(regex3, replacement);
expr = expr.replaceAll(regex4, isCurrent ? "false" : "true");
}
try {
return BooleanEvaluator.evaluate(expr);
} catch (Exception e) {
return !expr.contains("false");
}
}
private static class BooleanEvaluator {
public static boolean evaluate(String expr) {
expr = expr.replaceAll("\\s+", "");
return parseExpr(expr);
}
private static boolean parseExpr(String s) {
if (s.isEmpty()) return true;
int parenDepth = 0;
for (int i = s.length() - 1; i >= 0; i--) {
char c = s.charAt(i);
if (c == ')') parenDepth++;
else if (c == '(') parenDepth--;
else if (parenDepth == 0 && i > 0 && s.charAt(i) == '|' && s.charAt(i - 1) == '|') {
return parseExpr(s.substring(0, i - 1)) || parseExpr(s.substring(i + 1));
}
}
parenDepth = 0;
for (int i = s.length() - 1; i >= 0; i--) {
char c = s.charAt(i);
if (c == ')') parenDepth++;
else if (c == '(') parenDepth--;
else if (parenDepth == 0 && i > 0 && s.charAt(i) == '&' && s.charAt(i - 1) == '&') {
return parseExpr(s.substring(0, i - 1)) && parseExpr(s.substring(i + 1));
}
}
if (s.startsWith("!")) {
return !parseExpr(s.substring(1));
}
if (s.startsWith("(") && s.endsWith(")")) {
return parseExpr(s.substring(1, s.length() - 1));
}
if (s.equalsIgnoreCase("true")) return true;
if (s.equalsIgnoreCase("false")) return false;
return true;
}
return true;
}
private String simplify(String name) {

View File

@@ -408,4 +408,83 @@ class TransitionLinkerEnricherTest {
assertThat(resComp.getMetadata().getCallChains().get(2).getMatchedTransitions()).isNullOrEmpty(); // Groc
}
@Test
void shouldHandleMultipleNegations() {
Transition t1 = new Transition();
t1.setSourceStates(List.of(State.of("NEW", "NEW")));
t1.setTargetStates(List.of(State.of("PAID", "PAID")));
t1.setEvent(Event.of("PAY", "PAY"));
// Case 1: Double Negation on ORDER -> !(!(ORDER)) -> Should act as POSITIVE (meaning order is required).
// Since we are running OrderStateMachineConfiguration, it should match!
CallChain chain1 = CallChain.builder()
.triggerPoint(TriggerPoint.builder()
.event("PAY")
.constraint("!(!(ORDER.equals(type)))")
.build())
.build();
AnalysisResult resultOrder = AnalysisResult.builder()
.name("com.example.OrderStateMachineConfiguration")
.transitions(List.of(t1))
.metadata(CodebaseMetadata.builder().callChains(List.of(chain1)).build())
.build();
enricher.enrich(resultOrder, null, null);
assertThat(resultOrder.getMetadata().getCallChains().get(0).getMatchedTransitions()).hasSize(1);
// Case 2: Triple Negation on ORDER -> !(!(!(ORDER))) -> Should act as NEGATIVE (meaning order is rejected/forbidden).
// Under OrderStateMachineConfiguration, this chain should be rejected!
CallChain chain2 = CallChain.builder()
.triggerPoint(TriggerPoint.builder()
.event("PAY")
.constraint("!(!(!(ORDER.equals(type))))")
.build())
.build();
AnalysisResult resultOrder2 = AnalysisResult.builder()
.name("com.example.OrderStateMachineConfiguration")
.transitions(List.of(t1))
.metadata(CodebaseMetadata.builder().callChains(List.of(chain2)).build())
.build();
enricher.enrich(resultOrder2, null, null);
assertThat(resultOrder2.getMetadata().getCallChains().get(0).getMatchedTransitions()).isNullOrEmpty();
}
@Test
void shouldHandleComplexBooleanLogic() {
Transition t1 = new Transition();
t1.setSourceStates(List.of(State.of("NEW", "NEW")));
t1.setTargetStates(List.of(State.of("PAID", "PAID")));
t1.setEvent(Event.of("PAY", "PAY"));
// Case 1: OR expression -> "ORDER".equals(type) || "DOCUMENT".equals(type)
// Under OrderStateMachineConfiguration, it should match!
CallChain chain1 = CallChain.builder()
.triggerPoint(TriggerPoint.builder()
.event("PAY")
.constraint("\"ORDER\".equalsIgnoreCase(type) || \"DOCUMENT\".equalsIgnoreCase(type)")
.build())
.build();
AnalysisResult resultOrder = AnalysisResult.builder()
.name("com.example.OrderStateMachineConfiguration")
.transitions(List.of(t1))
.metadata(CodebaseMetadata.builder().callChains(List.of(chain1)).build())
.build();
enricher.enrich(resultOrder, null, null);
assertThat(resultOrder.getMetadata().getCallChains().get(0).getMatchedTransitions()).hasSize(1);
// Case 2: Under UserStateMachineConfiguration, it should be rejected!
AnalysisResult resultUser = AnalysisResult.builder()
.name("com.example.UserStateMachineConfiguration")
.transitions(List.of(t1))
.metadata(CodebaseMetadata.builder().callChains(List.of(chain1)).build())
.build();
enricher.enrich(resultUser, null, null);
assertThat(resultUser.getMetadata().getCallChains().get(0).getMatchedTransitions()).isNullOrEmpty();
}
}

View File

@@ -470,4 +470,71 @@ class HeuristicCallGraphEngineTypeTest {
assertThat(chain.getTriggerPoint().getPolymorphicEvents())
.containsExactly("<SYMBOLIC: MyEvents.*>");
}
@Test
void shouldResolveTernaryValueOf(@TempDir Path tempDir) throws IOException {
String source = """
package com.example;
public class Dispatcher {
public void dispatch(String type, String eventStr) {
StateMachine sm = new StateMachine();
if ("ORDER".equals(type)) {
OrderEvent ev = OrderEvent.valueOf(eventStr);
sm.sendEvent(ev);
} else {
UserEvent ev = UserEvent.valueOf(eventStr);
sm.sendEvent(ev);
}
}
}
enum OrderEvent { PAY }
enum UserEvent { VERIFY }
class StateMachine {
public void sendEvent(Object e) {}
}
""";
Files.writeString(tempDir.resolve("Dispatcher.java"), source);
CodebaseContext context = new CodebaseContext();
context.scan(tempDir);
HeuristicCallGraphEngine builder = new HeuristicCallGraphEngine(context);
EntryPoint entry = EntryPoint.builder()
.className("com.example.Dispatcher")
.methodName("dispatch")
.build();
TriggerPoint trigger = TriggerPoint.builder()
.className("com.example.StateMachine")
.methodName("sendEvent")
.event("e")
.build();
List<CallChain> chains = builder.findChains(List.of(entry), List.of(trigger));
assertThat(chains).hasSize(1);
assertThat(chains.get(0).getTriggerPoint().getPolymorphicEvents())
.containsExactlyInAnyOrder("<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: UserEvent.*>");
}
@Test
void testEnterpriseDispatcherResolution() throws IOException {
CodebaseContext context = new CodebaseContext();
context.scan(Path.of("../state_machines/state_machine_enterprise"));
HeuristicCallGraphEngine builder = new HeuristicCallGraphEngine(context);
EntryPoint entry = EntryPoint.builder()
.className("click.kamil.enterprise.web.StateMachineController")
.methodName("transition")
.build();
TriggerPoint trigger = TriggerPoint.builder()
.className("click.kamil.enterprise.web.StateMachineDispatcher")
.methodName("dispatch")
.event("event")
.build();
List<CallChain> chains = builder.findChains(List.of(entry), List.of(trigger));
assertThat(chains).isNotEmpty();
assertThat(chains.get(0).getTriggerPoint().getPolymorphicEvents())
.containsExactlyInAnyOrder("<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>");
}
}

View File

@@ -282,4 +282,48 @@ class JdtCallGraphEngineIntegrationTest {
"click.kamil.examples.statemachine.extended.service.QualifierQuirkService.doQuirk"
);
}
@Test
void testEnterpriseDispatcherResolutionJdt() throws IOException {
Path projectRoot = Path.of("../state_machines/state_machine_enterprise").toAbsolutePath().normalize();
CodebaseContext ctx = new CodebaseContext();
ctx.setProjectRoot(projectRoot);
ctx.setSourcepath(List.of(projectRoot.resolve("src/main/java").toString()));
DynamicClasspathResolver resolver = new DynamicClasspathResolver();
List<String> cp = resolver.resolveClasspath(projectRoot);
if (!cp.isEmpty()) {
ctx.setClasspath(cp);
}
ctx.setResolveBindings(true);
ctx.scan(Set.of(projectRoot), Collections.emptySet());
SpringBeanRegistry reg = new SpringBeanRegistry();
SpringContextScanner scanner = new SpringContextScanner(reg);
for (var cu : ctx.getCompilationUnits()) {
cu.accept(scanner);
}
SpringDependencyResolver dependencyResolver = new SpringDependencyResolver(reg);
InjectionPointAnalyzer injectionAnalyzer = new InjectionPointAnalyzer(dependencyResolver);
JdtCallGraphEngine jdtEngine = new JdtCallGraphEngine(ctx, injectionAnalyzer);
EntryPoint entry = EntryPoint.builder()
.className("click.kamil.enterprise.web.StateMachineController")
.methodName("transition")
.build();
TriggerPoint trigger = TriggerPoint.builder()
.className("click.kamil.enterprise.web.StateMachineDispatcher")
.methodName("dispatch")
.event("event")
.build();
List<CallChain> chains = jdtEngine.findChains(List.of(entry), List.of(trigger));
assertThat(chains).isNotEmpty();
assertThat(chains.get(0).getTriggerPoint().getPolymorphicEvents())
.containsExactlyInAnyOrder("<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>");
}
}

View File

@@ -9,7 +9,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 30,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.order.OrderEvent.SHIP",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -19,7 +21,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 37,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.SUBMIT",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -29,7 +33,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 44,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.APPROVE",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -39,7 +45,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 51,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.REJECT",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -49,7 +57,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 58,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.user.UserEvent.VERIFY",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -59,7 +69,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 65,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.user.UserEvent.SUSPEND",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -69,7 +81,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 72,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "event",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -79,7 +93,9 @@
"stateMachineId" : null,
"sourceState" : "ORDER",
"lineNumber" : 81,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)"
}, {
"event" : "event",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -89,7 +105,9 @@
"stateMachineId" : null,
"sourceState" : "DOCUMENT",
"lineNumber" : 87,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)"
}, {
"event" : "event",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -99,7 +117,9 @@
"stateMachineId" : null,
"sourceState" : "USER",
"lineNumber" : 93,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)"
} ],
"entryPoints" : [ {
"type" : "REST",
@@ -257,7 +277,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 30,
"polymorphicEvents" : [ "OrderEvent.PAY" ]
"polymorphicEvents" : [ "OrderEvent.PAY" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : null
@@ -288,7 +310,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 37,
"polymorphicEvents" : [ "OrderEvent.SHIP" ]
"polymorphicEvents" : [ "OrderEvent.SHIP" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : null
@@ -319,7 +343,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 44,
"polymorphicEvents" : [ "DocumentEvent.SUBMIT" ]
"polymorphicEvents" : [ "DocumentEvent.SUBMIT" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : [ {
@@ -354,7 +380,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 51,
"polymorphicEvents" : [ "DocumentEvent.APPROVE" ]
"polymorphicEvents" : [ "DocumentEvent.APPROVE" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : [ {
@@ -389,7 +417,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 58,
"polymorphicEvents" : [ "DocumentEvent.REJECT" ]
"polymorphicEvents" : [ "DocumentEvent.REJECT" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : [ {
@@ -424,7 +454,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 65,
"polymorphicEvents" : [ "UserEvent.VERIFY" ]
"polymorphicEvents" : [ "UserEvent.VERIFY" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : null
@@ -455,7 +487,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 72,
"polymorphicEvents" : [ "UserEvent.SUSPEND" ]
"polymorphicEvents" : [ "UserEvent.SUSPEND" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : null
@@ -494,22 +528,12 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 81,
"polymorphicEvents" : [ ]
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
"external" : true,
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)"
},
"contextMachineId" : null,
"matchedTransitions" : [ {
"sourceState" : "DocumentState.DRAFT",
"targetState" : "DocumentState.IN_REVIEW",
"event" : "DocumentEvent.SUBMIT"
}, {
"sourceState" : "DocumentState.IN_REVIEW",
"targetState" : "DocumentState.APPROVED",
"event" : "DocumentEvent.APPROVE"
}, {
"sourceState" : "DocumentState.IN_REVIEW",
"targetState" : "DocumentState.DRAFT",
"event" : "DocumentEvent.REJECT"
} ]
"matchedTransitions" : null
}, {
"entryPoint" : {
"type" : "REST",
@@ -545,7 +569,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 87,
"polymorphicEvents" : [ ]
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
"external" : true,
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)"
},
"contextMachineId" : null,
"matchedTransitions" : [ {
@@ -596,22 +622,12 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 93,
"polymorphicEvents" : [ ]
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
"external" : true,
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)"
},
"contextMachineId" : null,
"matchedTransitions" : [ {
"sourceState" : "DocumentState.DRAFT",
"targetState" : "DocumentState.IN_REVIEW",
"event" : "DocumentEvent.SUBMIT"
}, {
"sourceState" : "DocumentState.IN_REVIEW",
"targetState" : "DocumentState.APPROVED",
"event" : "DocumentEvent.APPROVE"
}, {
"sourceState" : "DocumentState.IN_REVIEW",
"targetState" : "DocumentState.DRAFT",
"event" : "DocumentEvent.REJECT"
} ]
"matchedTransitions" : null
} ],
"properties" : {
"default" : { }

View File

@@ -9,7 +9,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 30,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.order.OrderEvent.SHIP",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -19,7 +21,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 37,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.SUBMIT",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -29,7 +33,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 44,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.APPROVE",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -39,7 +45,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 51,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.REJECT",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -49,7 +57,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 58,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.user.UserEvent.VERIFY",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -59,7 +69,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 65,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.user.UserEvent.SUSPEND",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -69,7 +81,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 72,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "event",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -79,7 +93,9 @@
"stateMachineId" : null,
"sourceState" : "ORDER",
"lineNumber" : 81,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)"
}, {
"event" : "event",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -89,7 +105,9 @@
"stateMachineId" : null,
"sourceState" : "DOCUMENT",
"lineNumber" : 87,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)"
}, {
"event" : "event",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -99,7 +117,9 @@
"stateMachineId" : null,
"sourceState" : "USER",
"lineNumber" : 93,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)"
} ],
"entryPoints" : [ {
"type" : "REST",
@@ -257,7 +277,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 30,
"polymorphicEvents" : [ "OrderEvent.PAY" ]
"polymorphicEvents" : [ "OrderEvent.PAY" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : [ {
@@ -292,7 +314,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 37,
"polymorphicEvents" : [ "OrderEvent.SHIP" ]
"polymorphicEvents" : [ "OrderEvent.SHIP" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : [ {
@@ -327,7 +351,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 44,
"polymorphicEvents" : [ "DocumentEvent.SUBMIT" ]
"polymorphicEvents" : [ "DocumentEvent.SUBMIT" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : null
@@ -358,7 +384,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 51,
"polymorphicEvents" : [ "DocumentEvent.APPROVE" ]
"polymorphicEvents" : [ "DocumentEvent.APPROVE" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : null
@@ -389,7 +417,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 58,
"polymorphicEvents" : [ "DocumentEvent.REJECT" ]
"polymorphicEvents" : [ "DocumentEvent.REJECT" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : null
@@ -420,7 +450,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 65,
"polymorphicEvents" : [ "UserEvent.VERIFY" ]
"polymorphicEvents" : [ "UserEvent.VERIFY" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : null
@@ -451,7 +483,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 72,
"polymorphicEvents" : [ "UserEvent.SUSPEND" ]
"polymorphicEvents" : [ "UserEvent.SUSPEND" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : null
@@ -490,7 +524,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 81,
"polymorphicEvents" : [ ]
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
"external" : true,
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)"
},
"contextMachineId" : null,
"matchedTransitions" : [ {
@@ -537,18 +573,12 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 87,
"polymorphicEvents" : [ ]
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
"external" : true,
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)"
},
"contextMachineId" : null,
"matchedTransitions" : [ {
"sourceState" : "OrderState.NEW",
"targetState" : "OrderState.PENDING",
"event" : "OrderEvent.PAY"
}, {
"sourceState" : "OrderState.PENDING",
"targetState" : "OrderState.SHIPPED",
"event" : "OrderEvent.SHIP"
} ]
"matchedTransitions" : null
}, {
"entryPoint" : {
"type" : "REST",
@@ -584,18 +614,12 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 93,
"polymorphicEvents" : [ ]
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
"external" : true,
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)"
},
"contextMachineId" : null,
"matchedTransitions" : [ {
"sourceState" : "OrderState.NEW",
"targetState" : "OrderState.PENDING",
"event" : "OrderEvent.PAY"
}, {
"sourceState" : "OrderState.PENDING",
"targetState" : "OrderState.SHIPPED",
"event" : "OrderEvent.SHIP"
} ]
"matchedTransitions" : null
} ],
"properties" : {
"default" : { }

View File

@@ -9,7 +9,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 30,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.order.OrderEvent.SHIP",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -19,7 +21,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 37,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.SUBMIT",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -29,7 +33,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 44,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.APPROVE",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -39,7 +45,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 51,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.REJECT",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -49,7 +57,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 58,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.user.UserEvent.VERIFY",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -59,7 +69,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 65,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "click.kamil.enterprise.machines.user.UserEvent.SUSPEND",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -69,7 +81,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 72,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
}, {
"event" : "event",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -79,7 +93,9 @@
"stateMachineId" : null,
"sourceState" : "ORDER",
"lineNumber" : 81,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)"
}, {
"event" : "event",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -89,7 +105,9 @@
"stateMachineId" : null,
"sourceState" : "DOCUMENT",
"lineNumber" : 87,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)"
}, {
"event" : "event",
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
@@ -99,7 +117,9 @@
"stateMachineId" : null,
"sourceState" : "USER",
"lineNumber" : 93,
"polymorphicEvents" : null
"polymorphicEvents" : null,
"external" : false,
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)"
} ],
"entryPoints" : [ {
"type" : "REST",
@@ -257,7 +277,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 30,
"polymorphicEvents" : [ "OrderEvent.PAY" ]
"polymorphicEvents" : [ "OrderEvent.PAY" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : null
@@ -288,7 +310,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 37,
"polymorphicEvents" : [ "OrderEvent.SHIP" ]
"polymorphicEvents" : [ "OrderEvent.SHIP" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : null
@@ -319,7 +343,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 44,
"polymorphicEvents" : [ "DocumentEvent.SUBMIT" ]
"polymorphicEvents" : [ "DocumentEvent.SUBMIT" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : null
@@ -350,7 +376,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 51,
"polymorphicEvents" : [ "DocumentEvent.APPROVE" ]
"polymorphicEvents" : [ "DocumentEvent.APPROVE" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : null
@@ -381,7 +409,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 58,
"polymorphicEvents" : [ "DocumentEvent.REJECT" ]
"polymorphicEvents" : [ "DocumentEvent.REJECT" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : null
@@ -412,7 +442,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 65,
"polymorphicEvents" : [ "UserEvent.VERIFY" ]
"polymorphicEvents" : [ "UserEvent.VERIFY" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : [ {
@@ -447,7 +479,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 72,
"polymorphicEvents" : [ "UserEvent.SUSPEND" ]
"polymorphicEvents" : [ "UserEvent.SUSPEND" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : null
@@ -486,18 +520,12 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 81,
"polymorphicEvents" : [ ]
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
"external" : true,
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)"
},
"contextMachineId" : null,
"matchedTransitions" : [ {
"sourceState" : "UserState.GUEST",
"targetState" : "UserState.REGISTERED",
"event" : "UserEvent.REGISTER"
}, {
"sourceState" : "UserState.REGISTERED",
"targetState" : "UserState.VERIFIED",
"event" : "UserEvent.VERIFY"
} ]
"matchedTransitions" : null
}, {
"entryPoint" : {
"type" : "REST",
@@ -533,18 +561,12 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 87,
"polymorphicEvents" : [ ]
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
"external" : true,
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)"
},
"contextMachineId" : null,
"matchedTransitions" : [ {
"sourceState" : "UserState.GUEST",
"targetState" : "UserState.REGISTERED",
"event" : "UserEvent.REGISTER"
}, {
"sourceState" : "UserState.REGISTERED",
"targetState" : "UserState.VERIFIED",
"event" : "UserEvent.VERIFY"
} ]
"matchedTransitions" : null
}, {
"entryPoint" : {
"type" : "REST",
@@ -580,7 +602,9 @@
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 93,
"polymorphicEvents" : [ ]
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
"external" : true,
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)"
},
"contextMachineId" : null,
"matchedTransitions" : [ {