Compare commits
10 Commits
8d4ba0697e
...
ai-branch
| Author | SHA1 | Date | |
|---|---|---|---|
| d6b1571f18 | |||
| e617fb1754 | |||
| 06dc0ba641 | |||
| ba412b905e | |||
| 198c5d830e | |||
| a383de5a5f | |||
| ef9ebe3512 | |||
| b480dc83ef | |||
| 0a23daae05 | |||
| e894566112 |
@@ -54,6 +54,30 @@ public class ConstantResolver {
|
|||||||
return resolveManual(sn, context, visited);
|
return resolveManual(sn, context, visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (expr instanceof MethodInvocation mi) {
|
||||||
|
IMethodBinding mb = mi.resolveMethodBinding();
|
||||||
|
if (mb != null) {
|
||||||
|
ITypeBinding returnType = mb.getReturnType();
|
||||||
|
if (returnType != null) {
|
||||||
|
java.util.List<String> values = context.getEnumValues(returnType.getQualifiedName());
|
||||||
|
if (values != null && !values.isEmpty()) {
|
||||||
|
return "ENUM_SET:" + String.join(",", values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TypeDeclaration td = findEnclosingType(mi);
|
||||||
|
if (td != null) {
|
||||||
|
MethodDeclaration md = context.findMethodDeclaration(td, mi.getName().getIdentifier(), true);
|
||||||
|
if (md != null && md.getReturnType2() != null) {
|
||||||
|
java.util.List<String> values = context.getEnumValues(md.getReturnType2().toString());
|
||||||
|
if (values != null && !values.isEmpty()) {
|
||||||
|
return "ENUM_SET:" + String.join(",", values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,47 +58,73 @@ public class CallGraphBuilder {
|
|||||||
String event = tp.getEvent();
|
String event = tp.getEvent();
|
||||||
if (event == null || event.isEmpty() || event.contains("\"")) return tp;
|
if (event == null || event.isEmpty() || event.contains("\"")) return tp;
|
||||||
|
|
||||||
TypeDeclaration td = context.getTypeDeclaration(tp.getClassName());
|
String currentParamName = event;
|
||||||
if (td != null) {
|
String resolvedValue = event;
|
||||||
MethodDeclaration md = context.findMethodDeclaration(td, tp.getMethodName(), true);
|
|
||||||
if (md != null) {
|
// Walk backwards up the call chain
|
||||||
int paramIndex = -1;
|
for (int i = path.size() - 1; i > 0; i--) {
|
||||||
for (int i = 0; i < md.parameters().size(); i++) {
|
String target = path.get(i);
|
||||||
SingleVariableDeclaration svd = (SingleVariableDeclaration) md.parameters().get(i);
|
String caller = path.get(i - 1);
|
||||||
if (svd.getName().getIdentifier().equals(event)) {
|
|
||||||
paramIndex = i;
|
// Find parameter index in target method
|
||||||
break;
|
int paramIndex = getParameterIndex(target, currentParamName);
|
||||||
}
|
if (paramIndex < 0) {
|
||||||
}
|
break; // Parameter name changed or not found, stop tracing
|
||||||
|
}
|
||||||
if (paramIndex >= 0) {
|
|
||||||
String caller = path.get(path.size() - 2);
|
// Find the edge from caller to target to get the argument passed
|
||||||
String target = path.get(path.size() - 1);
|
List<CallEdge> edges = callGraph.get(caller);
|
||||||
List<CallEdge> edges = callGraph.get(caller);
|
boolean found = false;
|
||||||
if (edges != null) {
|
if (edges != null) {
|
||||||
for (CallEdge edge : edges) {
|
for (CallEdge edge : edges) {
|
||||||
if (edge.getTargetMethod().equals(target) || isHeuristicMatch(edge.getTargetMethod(), target)) {
|
if (edge.getTargetMethod().equals(target) || isHeuristicMatch(edge.getTargetMethod(), target)) {
|
||||||
if (paramIndex < edge.getArguments().size()) {
|
if (paramIndex < edge.getArguments().size()) {
|
||||||
String resolvedValue = edge.getArguments().get(paramIndex);
|
String arg = edge.getArguments().get(paramIndex);
|
||||||
if (resolvedValue != null) {
|
if (arg != null) {
|
||||||
return TriggerPoint.builder()
|
currentParamName = arg;
|
||||||
.event(resolvedValue)
|
resolvedValue = arg;
|
||||||
.className(tp.getClassName())
|
found = true;
|
||||||
.methodName(tp.getMethodName())
|
break;
|
||||||
.sourceFile(tp.getSourceFile())
|
|
||||||
.lineNumber(tp.getLineNumber())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!found) break; // Could not map argument
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!resolvedValue.equals(event)) {
|
||||||
|
return TriggerPoint.builder()
|
||||||
|
.event(resolvedValue)
|
||||||
|
.className(tp.getClassName())
|
||||||
|
.methodName(tp.getMethodName())
|
||||||
|
.sourceFile(tp.getSourceFile())
|
||||||
|
.lineNumber(tp.getLineNumber())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getParameterIndex(String methodFqn, String paramName) {
|
||||||
|
if (methodFqn == null || !methodFqn.contains(".")) return -1;
|
||||||
|
String className = methodFqn.substring(0, methodFqn.lastIndexOf('.'));
|
||||||
|
String methodName = methodFqn.substring(methodFqn.lastIndexOf('.') + 1);
|
||||||
|
TypeDeclaration td = context.getTypeDeclaration(className);
|
||||||
|
if (td != null) {
|
||||||
|
MethodDeclaration md = context.findMethodDeclaration(td, methodName, true);
|
||||||
|
if (md != null) {
|
||||||
|
for (int i = 0; i < md.parameters().size(); i++) {
|
||||||
|
SingleVariableDeclaration svd = (SingleVariableDeclaration) md.parameters().get(i);
|
||||||
|
if (svd.getName().getIdentifier().equals(paramName)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
private String extractContextMachineId(List<String> path, Map<String, List<CallEdge>> callGraph) {
|
private String extractContextMachineId(List<String> path, Map<String, List<CallEdge>> callGraph) {
|
||||||
for (String node : path) {
|
for (String node : path) {
|
||||||
List<CallEdge> edges = callGraph.get(node);
|
List<CallEdge> edges = callGraph.get(node);
|
||||||
@@ -138,6 +164,20 @@ public class CallGraphBuilder {
|
|||||||
for (String calledMethod : calledMethods) {
|
for (String calledMethod : calledMethods) {
|
||||||
graph.computeIfAbsent(currentMethodFqn, k -> new ArrayList<>()).add(new CallEdge(calledMethod, args));
|
graph.computeIfAbsent(currentMethodFqn, k -> new ArrayList<>()).add(new CallEdge(calledMethod, args));
|
||||||
}
|
}
|
||||||
|
for (Object argObj : node.arguments()) {
|
||||||
|
if (argObj instanceof ExpressionMethodReference emr) {
|
||||||
|
String typeName = emr.getExpression().toString();
|
||||||
|
if ("this".equals(typeName) || "super".equals(typeName)) {
|
||||||
|
TypeDeclaration td = findEnclosingType(node);
|
||||||
|
if (td != null) {
|
||||||
|
String refMethod = resolveMethodInType(td, emr.getName().getIdentifier());
|
||||||
|
if (refMethod != null) {
|
||||||
|
graph.computeIfAbsent(currentMethodFqn, k -> new ArrayList<>()).add(new CallEdge(refMethod, args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return super.visit(node);
|
return super.visit(node);
|
||||||
}
|
}
|
||||||
@@ -174,6 +214,45 @@ public class CallGraphBuilder {
|
|||||||
List<String> args = new ArrayList<>();
|
List<String> args = new ArrayList<>();
|
||||||
for (Object argObj : astArguments) {
|
for (Object argObj : astArguments) {
|
||||||
Expression expr = (Expression) argObj;
|
Expression expr = (Expression) argObj;
|
||||||
|
|
||||||
|
// Extract from lambda
|
||||||
|
if (expr instanceof LambdaExpression le) {
|
||||||
|
ASTNode body = le.getBody();
|
||||||
|
if (body instanceof Expression bodyExpr) {
|
||||||
|
expr = bodyExpr;
|
||||||
|
} else if (body instanceof Block block) {
|
||||||
|
for (Object stmtObj : block.statements()) {
|
||||||
|
if (stmtObj instanceof ReturnStatement rs && rs.getExpression() != null) {
|
||||||
|
expr = rs.getExpression();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expr instanceof ExpressionMethodReference emr) {
|
||||||
|
TypeDeclaration td = findEnclosingType(expr);
|
||||||
|
if (td != null) {
|
||||||
|
MethodDeclaration md = context.findMethodDeclaration(td, emr.getName().getIdentifier(), true);
|
||||||
|
if (md != null && md.getBody() != null) {
|
||||||
|
for (Object stmtObj : md.getBody().statements()) {
|
||||||
|
if (stmtObj instanceof ReturnStatement rs && rs.getExpression() != null) {
|
||||||
|
expr = rs.getExpression();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract from constructor args (e.g., new CustomMessage(OrderEvent.PROCESS, ...))
|
||||||
|
expr = traceVariable(expr);
|
||||||
|
if (expr instanceof ClassInstanceCreation cic) {
|
||||||
|
if (!cic.arguments().isEmpty()) {
|
||||||
|
expr = (Expression) cic.arguments().get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String val = constantResolver.resolve(expr, context);
|
String val = constantResolver.resolve(expr, context);
|
||||||
if (val == null) {
|
if (val == null) {
|
||||||
val = expr.toString(); // Fallback to raw string (handles Enums, 'new Class()', etc)
|
val = expr.toString(); // Fallback to raw string (handles Enums, 'new Class()', etc)
|
||||||
@@ -275,4 +354,41 @@ public class CallGraphBuilder {
|
|||||||
}
|
}
|
||||||
return (TypeDeclaration) parent;
|
return (TypeDeclaration) parent;
|
||||||
}
|
}
|
||||||
|
private Expression traceVariable(Expression expr) {
|
||||||
|
if (expr instanceof SimpleName sn) {
|
||||||
|
String varName = sn.getIdentifier();
|
||||||
|
MethodDeclaration enclosingMethod = findEnclosingMethod(expr);
|
||||||
|
if (enclosingMethod != null) {
|
||||||
|
final Expression[] initializer = new Expression[1];
|
||||||
|
enclosingMethod.accept(new ASTVisitor() {
|
||||||
|
@Override
|
||||||
|
public boolean visit(VariableDeclarationFragment node) {
|
||||||
|
if (node.getName().getIdentifier().equals(varName) && node.getInitializer() != null) {
|
||||||
|
initializer[0] = node.getInitializer();
|
||||||
|
}
|
||||||
|
return super.visit(node);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean visit(Assignment node) {
|
||||||
|
if (node.getLeftHandSide() instanceof SimpleName asn && asn.getIdentifier().equals(varName)) {
|
||||||
|
initializer[0] = node.getRightHandSide();
|
||||||
|
}
|
||||||
|
return super.visit(node);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (initializer[0] != null) {
|
||||||
|
return traceVariable(initializer[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MethodDeclaration findEnclosingMethod(ASTNode node) {
|
||||||
|
ASTNode parent = node.getParent();
|
||||||
|
while (parent != null && !(parent instanceof MethodDeclaration)) {
|
||||||
|
parent = parent.getParent();
|
||||||
|
}
|
||||||
|
return (MethodDeclaration) parent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,10 +47,12 @@ public class GenericEventDetector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void processSendEvent(MethodInvocation node, CompilationUnit cu, List<TriggerPoint> triggers) {
|
private void processSendEvent(MethodInvocation node, CompilationUnit cu, List<TriggerPoint> triggers) {
|
||||||
TriggerPoint trigger = buildTriggerPoint(node, cu, null);
|
List<TriggerPoint> builtTriggers = buildTriggerPoints(node, cu, null);
|
||||||
if (trigger != null) {
|
if (builtTriggers != null) {
|
||||||
log.debug("Successfully built trigger point: {}", trigger.getEvent());
|
for (TriggerPoint trigger : builtTriggers) {
|
||||||
triggers.add(trigger);
|
log.debug("Successfully built trigger point: {}", trigger.getEvent());
|
||||||
|
triggers.add(trigger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,10 +64,12 @@ public class GenericEventDetector {
|
|||||||
|
|
||||||
for (LibraryHint hint : hints) {
|
for (LibraryHint hint : hints) {
|
||||||
if (calledMethod.equals(hint.getMethodFqn()) || isHintMatch(calledMethod, hint.getMethodFqn())) {
|
if (calledMethod.equals(hint.getMethodFqn()) || isHintMatch(calledMethod, hint.getMethodFqn())) {
|
||||||
TriggerPoint trigger = buildTriggerPoint(node, cu, hint.getEvent());
|
List<TriggerPoint> builtTriggers = buildTriggerPoints(node, cu, hint.getEvent());
|
||||||
if (trigger != null) {
|
if (builtTriggers != null) {
|
||||||
log.debug("Successfully built synthetic trigger point from hint: {}", trigger.getEvent());
|
for (TriggerPoint trigger : builtTriggers) {
|
||||||
triggers.add(trigger);
|
log.debug("Successfully built synthetic trigger point from hint: {}", trigger.getEvent());
|
||||||
|
triggers.add(trigger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,12 +106,12 @@ public class GenericEventDetector {
|
|||||||
return receiver.toString() + "." + methodName;
|
return receiver.toString() + "." + methodName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TriggerPoint buildTriggerPoint(MethodInvocation node, CompilationUnit cu, String forcedEvent) {
|
private List<TriggerPoint> buildTriggerPoints(MethodInvocation node, CompilationUnit cu, String forcedEvent) {
|
||||||
String eventValue = null;
|
String eventValue = null;
|
||||||
if (forcedEvent != null) {
|
if (forcedEvent != null) {
|
||||||
eventValue = context.resolveString(forcedEvent);
|
eventValue = context.resolveString(forcedEvent);
|
||||||
} else {
|
} else {
|
||||||
if (node.arguments().isEmpty()) return null;
|
if (node.arguments().isEmpty()) return Collections.emptyList();
|
||||||
Expression eventExpr = (Expression) node.arguments().get(0);
|
Expression eventExpr = (Expression) node.arguments().get(0);
|
||||||
|
|
||||||
// Try MessageBuilder extraction first
|
// Try MessageBuilder extraction first
|
||||||
@@ -123,18 +127,37 @@ public class GenericEventDetector {
|
|||||||
MethodDeclaration method = findEnclosingMethod(node);
|
MethodDeclaration method = findEnclosingMethod(node);
|
||||||
TypeDeclaration type = findEnclosingType(node);
|
TypeDeclaration type = findEnclosingType(node);
|
||||||
|
|
||||||
if (type == null) return null;
|
if (type == null) return Collections.emptyList();
|
||||||
|
|
||||||
String sourceState = extractSourceState(node);
|
String sourceState = extractSourceState(node);
|
||||||
|
|
||||||
|
List<TriggerPoint> results = new ArrayList<>();
|
||||||
|
if (eventValue != null && eventValue.startsWith("ENUM_SET:")) {
|
||||||
|
String[] parts = eventValue.substring(9).split(",");
|
||||||
|
for (String part : parts) {
|
||||||
|
if (!part.trim().isEmpty()) {
|
||||||
|
results.add(TriggerPoint.builder()
|
||||||
|
.event(part.trim())
|
||||||
|
.sourceState(sourceState)
|
||||||
|
.className(context.getFqn(type))
|
||||||
|
.methodName(method != null ? method.getName().getIdentifier() : "initializer")
|
||||||
|
.sourceFile(context.getRelativePath(context.getFqn(type)))
|
||||||
|
.lineNumber(cu.getLineNumber(node.getStartPosition()))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
results.add(TriggerPoint.builder()
|
||||||
|
.event(eventValue)
|
||||||
|
.sourceState(sourceState)
|
||||||
|
.className(context.getFqn(type))
|
||||||
|
.methodName(method != null ? method.getName().getIdentifier() : "initializer")
|
||||||
|
.sourceFile(context.getRelativePath(context.getFqn(type)))
|
||||||
|
.lineNumber(cu.getLineNumber(node.getStartPosition()))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
return TriggerPoint.builder()
|
return results;
|
||||||
.event(eventValue)
|
|
||||||
.sourceState(sourceState)
|
|
||||||
.className(context.getFqn(type))
|
|
||||||
.methodName(method != null ? method.getName().getIdentifier() : "initializer")
|
|
||||||
.sourceFile(context.getRelativePath(context.getFqn(type)))
|
|
||||||
.lineNumber(cu.getLineNumber(node.getStartPosition()))
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String extractSourceState(ASTNode node) {
|
private String extractSourceState(ASTNode node) {
|
||||||
@@ -193,6 +216,10 @@ public class GenericEventDetector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String extractEventFromMessageBuilder(Expression expr) {
|
private String extractEventFromMessageBuilder(Expression expr) {
|
||||||
|
if (expr instanceof CastExpression ce) {
|
||||||
|
return extractEventFromMessageBuilder(ce.getExpression());
|
||||||
|
}
|
||||||
|
|
||||||
if (expr instanceof SimpleName sn) {
|
if (expr instanceof SimpleName sn) {
|
||||||
String varName = sn.getIdentifier();
|
String varName = sn.getIdentifier();
|
||||||
MethodDeclaration enclosingMethod = findEnclosingMethod(expr);
|
MethodDeclaration enclosingMethod = findEnclosingMethod(expr);
|
||||||
@@ -218,6 +245,15 @@ public class GenericEventDetector {
|
|||||||
if (initializer[0] != null) {
|
if (initializer[0] != null) {
|
||||||
return extractEventFromMessageBuilder(initializer[0]); // recursive
|
return extractEventFromMessageBuilder(initializer[0]); // recursive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If it has NO initializer, it might be a method parameter!
|
||||||
|
for (Object paramObj : enclosingMethod.parameters()) {
|
||||||
|
if (paramObj instanceof SingleVariableDeclaration svd) {
|
||||||
|
if (svd.getName().getIdentifier().equals(varName)) {
|
||||||
|
return varName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,10 +276,22 @@ public class GenericEventDetector {
|
|||||||
if (resolved != null) return resolved;
|
if (resolved != null) return resolved;
|
||||||
|
|
||||||
// If not a constant, it might be a parameter like 'event'
|
// If not a constant, it might be a parameter like 'event'
|
||||||
|
if (payloadExpr instanceof CastExpression ce) {
|
||||||
|
payloadExpr = ce.getExpression();
|
||||||
|
}
|
||||||
|
|
||||||
if (payloadExpr instanceof SimpleName sn) {
|
if (payloadExpr instanceof SimpleName sn) {
|
||||||
return sn.getIdentifier(); // Return the parameter name so the call graph can fill it
|
String extracted = extractEventFromMessageBuilder(payloadExpr);
|
||||||
|
if (extracted != null) {
|
||||||
|
return extracted;
|
||||||
|
}
|
||||||
|
return sn.getIdentifier(); // Fall back to returning the parameter name
|
||||||
}
|
}
|
||||||
return payloadExpr.toString();
|
return payloadExpr.toString();
|
||||||
|
} else if (current.arguments().isEmpty() && current.getExpression() instanceof SimpleName sn) {
|
||||||
|
// If the event is obtained by calling a method on a provider/supplier parameter,
|
||||||
|
// return the provider's name so CallGraphBuilder can trace the lambda argument
|
||||||
|
return sn.getIdentifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression receiver = current.getExpression();
|
Expression receiver = current.getExpression();
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ public class MessagingDetector {
|
|||||||
.name(protocolName + ": " + destination)
|
.name(protocolName + ": " + destination)
|
||||||
.className(context.getFqn((TypeDeclaration) method.getParent()))
|
.className(context.getFqn((TypeDeclaration) method.getParent()))
|
||||||
.methodName(method.getName().getIdentifier())
|
.methodName(method.getName().getIdentifier())
|
||||||
|
.sourceFile(context.getRelativePath(context.getFqn((TypeDeclaration) method.getParent())))
|
||||||
.metadata(metadata)
|
.metadata(metadata)
|
||||||
.parameters(extractParameters(method))
|
.parameters(extractParameters(method))
|
||||||
.build());
|
.build());
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ public class AstTransitionParser {
|
|||||||
t.setEvent(Event.of(QuotedExpression.of(resolved).toStringWithoutQuotes()));
|
t.setEvent(Event.of(QuotedExpression.of(resolved).toStringWithoutQuotes()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "guard" -> {
|
case "guard", "guardExpression" -> {
|
||||||
Expression resolved = resolveArg((Expression) args.get(0), argsMap);
|
Expression resolved = resolveArg((Expression) args.get(0), argsMap);
|
||||||
parseGuard(resolved, t, cu, context);
|
parseGuard(resolved, t, cu, context);
|
||||||
}
|
}
|
||||||
@@ -248,6 +248,10 @@ public class AstTransitionParser {
|
|||||||
Expression resolved = resolveArg((Expression) args.get(0), argsMap);
|
Expression resolved = resolveArg((Expression) args.get(0), argsMap);
|
||||||
parseAction(resolved, t, cu, context);
|
parseAction(resolved, t, cu, context);
|
||||||
}
|
}
|
||||||
|
case "timer", "timerOnce" -> {
|
||||||
|
Expression resolved = resolveArg((Expression) args.get(0), argsMap);
|
||||||
|
t.setEvent(Event.of(methodName + "(" + resolved.toString() + ")", methodName + "(" + resolved.toString() + ")"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ public class CodebaseContext {
|
|||||||
private final List<CompilationUnit> allCus = new ArrayList<>();
|
private final List<CompilationUnit> allCus = new ArrayList<>();
|
||||||
|
|
||||||
private final Map<String, List<String>> interfaceToImpls = new HashMap<>();
|
private final Map<String, List<String>> interfaceToImpls = new HashMap<>();
|
||||||
|
private final Map<String, List<String>> enumValues = new HashMap<>();
|
||||||
|
|
||||||
public void scan(Set<Path> rootDirs, Set<String> customIgnorePatterns) throws IOException {
|
public void scan(Set<Path> rootDirs, Set<String> customIgnorePatterns) throws IOException {
|
||||||
this.allProperties = propertyResolver.resolveAllProperties(rootDirs);
|
this.allProperties = propertyResolver.resolveAllProperties(rootDirs);
|
||||||
@@ -188,6 +189,8 @@ public class CodebaseContext {
|
|||||||
for (Object type : cu.types()) {
|
for (Object type : cu.types()) {
|
||||||
if (type instanceof TypeDeclaration td) {
|
if (type instanceof TypeDeclaration td) {
|
||||||
indexType(td, packageName, javaFile);
|
indexType(td, packageName, javaFile);
|
||||||
|
} else if (type instanceof EnumDeclaration ed) {
|
||||||
|
indexEnum(ed, packageName, javaFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,11 +233,53 @@ public class CodebaseContext {
|
|||||||
|
|
||||||
// Try FQN match if input was simple name
|
// Try FQN match if input was simple name
|
||||||
String fqn = simpleNameToFqn.get(interfaceName);
|
String fqn = simpleNameToFqn.get(interfaceName);
|
||||||
if (fqn != null) return interfaceToImpls.getOrDefault(fqn, Collections.emptyList());
|
if (fqn != null && interfaceToImpls.containsKey(fqn)) {
|
||||||
|
return interfaceToImpls.get(fqn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try simple name match if input was FQN
|
||||||
|
if (interfaceName.contains(".")) {
|
||||||
|
String simpleName = interfaceName.substring(interfaceName.lastIndexOf('.') + 1);
|
||||||
|
List<String> simpleImpls = interfaceToImpls.get(simpleName);
|
||||||
|
if (simpleImpls != null) {
|
||||||
|
// To be perfectly safe, we could check if simpleNameToFqn matches,
|
||||||
|
// but for call graphs, returning potential implementations is fine.
|
||||||
|
return simpleImpls;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void indexEnum(EnumDeclaration ed, String parentFqn, Path javaFile) {
|
||||||
|
String simpleName = ed.getName().getIdentifier();
|
||||||
|
String fqn = parentFqn.isEmpty() ? simpleName : parentFqn + "." + simpleName;
|
||||||
|
|
||||||
|
classes.put(fqn, (CompilationUnit) ed.getRoot());
|
||||||
|
classPaths.put(fqn, javaFile);
|
||||||
|
|
||||||
|
List<String> values = new ArrayList<>();
|
||||||
|
for (Object o : ed.enumConstants()) {
|
||||||
|
if (o instanceof EnumConstantDeclaration ecd) {
|
||||||
|
values.add(fqn + "." + ecd.getName().getIdentifier());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumValues.put(fqn, values);
|
||||||
|
if (!simpleNameToFqn.containsKey(simpleName)) {
|
||||||
|
simpleNameToFqn.put(simpleName, fqn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getEnumValues(String fqnOrSimpleName) {
|
||||||
|
if (fqnOrSimpleName == null) return null;
|
||||||
|
List<String> values = enumValues.get(fqnOrSimpleName);
|
||||||
|
if (values != null) return values;
|
||||||
|
String fqn = simpleNameToFqn.get(fqnOrSimpleName);
|
||||||
|
if (fqn != null) return enumValues.get(fqn);
|
||||||
|
// Also try stripping array or generic types if any (e.g. MyEnum[])
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public State resolveState(Expression expr, CompilationUnit cu) {
|
public State resolveState(Expression expr, CompilationUnit cu) {
|
||||||
if (expr == null)
|
if (expr == null)
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ public class FileUtils {
|
|||||||
return paths
|
return paths
|
||||||
.filter(p -> Files.isRegularFile(p) && p.toString().endsWith(extension))
|
.filter(p -> Files.isRegularFile(p) && p.toString().endsWith(extension))
|
||||||
.filter(p -> matchers.stream().noneMatch(m -> m.matches(p)))
|
.filter(p -> matchers.stream().noneMatch(m -> m.matches(p)))
|
||||||
|
.map(Path::toAbsolutePath)
|
||||||
|
.map(Path::normalize)
|
||||||
|
.distinct()
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,23 +116,23 @@ public class PlantUml implements StateMachineExporter {
|
|||||||
|
|
||||||
sb.append(" <<").append(styleClass).append(">>");
|
sb.append(" <<").append(styleClass).append(">>");
|
||||||
|
|
||||||
if (t.getEvent() != null) {
|
|
||||||
String eventStr = options.formatEvent(t.getEvent());
|
|
||||||
if (eventStr != null && !eventStr.isBlank()) {
|
|
||||||
sb.append(" <<e_").append(normalize(eventStr)).append(">>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String label = buildLabel(t, options);
|
String label = buildLabel(t, options);
|
||||||
if (options.isEmbedIdentifiers()) {
|
if (options.isEmbedIdentifiers()) {
|
||||||
String eventStr = t.getEvent() != null ? options.formatEvent(t.getEvent()) : null;
|
String eventStr = t.getEvent() != null ? options.formatEvent(t.getEvent()) : null;
|
||||||
String linkId = eventStr != null && !eventStr.isBlank() ? "link_" + normalize(source) + "__" + normalize(eventStr) : "link_anon_" + normalize(source) + "_" + normalize(target);
|
String linkId = eventStr != null && !eventStr.isBlank() ? "link_" + normalize(source) + "__" + normalize(eventStr) : "link_anon_" + normalize(source) + "_" + normalize(target);
|
||||||
// Force a label even if empty to ensure the link group exists in SVG
|
|
||||||
String displayLabel = label.isEmpty() ? " " : label;
|
sb.append(" : [[#").append(linkId).append(" ");
|
||||||
// Brackets [...] in the label break PlantUML link syntax [[url label]],
|
if (!label.isEmpty()) {
|
||||||
// so we strip them for the interactive identification label.
|
String sanitized = label.replace("[", "[")
|
||||||
String safeLabel = displayLabel.replaceAll("[\\[\\]]", "");
|
.replace("]", "]")
|
||||||
sb.append(" : ").append("[[#").append(linkId).append(" ").append(safeLabel).append("]]");
|
.replace("<", "<")
|
||||||
|
.replace(">", ">");
|
||||||
|
sb.append(sanitized);
|
||||||
|
} else {
|
||||||
|
sb.append(".");
|
||||||
|
}
|
||||||
|
sb.append("]]");
|
||||||
} else if (!label.isEmpty()) {
|
} else if (!label.isEmpty()) {
|
||||||
sb.append(" : ").append(label);
|
sb.append(" : ").append(label);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,6 +137,12 @@ public class RegressionTest {
|
|||||||
root.resolve("state_machines/maven_multi_module/core-module"),
|
root.resolve("state_machines/maven_multi_module/core-module"),
|
||||||
Path.of("src/test/resources/golden/MavenOrderStateMachine"),
|
Path.of("src/test/resources/golden/MavenOrderStateMachine"),
|
||||||
"MavenOrderStateMachine"
|
"MavenOrderStateMachine"
|
||||||
|
),
|
||||||
|
new TestScenario(
|
||||||
|
"Complex Multi-Module Sample",
|
||||||
|
root.resolve("state_machines/complex_multi_module_sm"),
|
||||||
|
Path.of("src/test/resources/golden/StateMachineConfig"),
|
||||||
|
"StateMachineConfig"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,4 +44,42 @@ public class GenericEventDetectorTest {
|
|||||||
assertThat(triggers.get(0).getEvent()).isEqualTo("myEvent");
|
assertThat(triggers.get(0).getEvent()).isEqualTo("myEvent");
|
||||||
assertThat(triggers.get(0).getMethodName()).isEqualTo("a");
|
assertThat(triggers.get(0).getMethodName()).isEqualTo("a");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEnumGetterUnionExtraction(@TempDir Path tempDir) throws IOException {
|
||||||
|
Path dir = tempDir.resolve("com/example");
|
||||||
|
Files.createDirectories(dir);
|
||||||
|
Files.writeString(dir.resolve("MyEnum.java"),
|
||||||
|
"package com.example;\n" +
|
||||||
|
"public enum MyEnum {\n" +
|
||||||
|
" STATE_A, STATE_B;\n" +
|
||||||
|
"}\n");
|
||||||
|
|
||||||
|
Files.writeString(dir.resolve("MyService.java"),
|
||||||
|
"package com.example;\n" +
|
||||||
|
"import org.springframework.statemachine.StateMachine;\n" +
|
||||||
|
"public class MyService {\n" +
|
||||||
|
" private StateMachine<String, String> stateMachine;\n" +
|
||||||
|
" public MyEnum getEvent() { return MyEnum.STATE_A; }\n" + // Pretend it returns the enum
|
||||||
|
" public void trigger() {\n" +
|
||||||
|
" stateMachine.sendEvent(this.getEvent());\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}\n");
|
||||||
|
|
||||||
|
CodebaseContext context = new CodebaseContext();
|
||||||
|
context.scan(tempDir);
|
||||||
|
|
||||||
|
GenericEventDetector detector = new GenericEventDetector(context, new ConstantResolver(), List.of());
|
||||||
|
|
||||||
|
CompilationUnit serviceCu = context.getCompilationUnits().stream()
|
||||||
|
.filter(cu -> cu.getJavaElement() == null || cu.getJavaElement().getElementName().contains("MyService"))
|
||||||
|
.findFirst().orElseThrow();
|
||||||
|
|
||||||
|
List<TriggerPoint> triggers = detector.detect(serviceCu);
|
||||||
|
|
||||||
|
System.out.println("TRIGGERS: " + triggers);
|
||||||
|
assertThat(triggers).hasSize(2);
|
||||||
|
assertThat(triggers).anyMatch(t -> t.getEvent().equals("com.example.MyEnum.STATE_A"));
|
||||||
|
assertThat(triggers).anyMatch(t -> t.getEvent().equals("com.example.MyEnum.STATE_B"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package click.kamil.springstatemachineexporter.exporter;
|
package click.kamil.springstatemachineexporter.exporter;
|
||||||
|
|
||||||
import click.kamil.springstatemachineexporter.analysis.model.AnalysisResult;
|
|
||||||
import click.kamil.springstatemachineexporter.model.Event;
|
|
||||||
import click.kamil.springstatemachineexporter.model.State;
|
import click.kamil.springstatemachineexporter.model.State;
|
||||||
import click.kamil.springstatemachineexporter.model.Transition;
|
import click.kamil.springstatemachineexporter.model.Transition;
|
||||||
import click.kamil.springstatemachineexporter.model.TransitionType;
|
import click.kamil.springstatemachineexporter.model.TransitionType;
|
||||||
|
import click.kamil.springstatemachineexporter.model.Guard;
|
||||||
|
import click.kamil.springstatemachineexporter.model.Action;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -15,53 +15,41 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
class PlantUmlTest {
|
class PlantUmlTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldFormatTransitionsWithDifferentEnumFormats() {
|
void testExportSanitizesLabels() {
|
||||||
// Given
|
PlantUml plantUml = new PlantUml();
|
||||||
PlantUml exporter = new PlantUml();
|
ExportOptions options = ExportOptions.builder()
|
||||||
Transition transition = new Transition();
|
.embedIdentifiers(true)
|
||||||
transition.setType(TransitionType.EXTERNAL);
|
.useLambdaGuards(false)
|
||||||
transition.setSourceStates(List.of(State.of("States.S1", "com.example.States.S1")));
|
|
||||||
transition.setTargetStates(List.of(State.of("States.S2", "com.example.States.S2")));
|
|
||||||
transition.setEvent(Event.of("Events.E1", "com.example.Events.E1"));
|
|
||||||
|
|
||||||
AnalysisResult result = AnalysisResult.builder()
|
|
||||||
.name("TestSM")
|
|
||||||
.transitions(List.of(transition))
|
|
||||||
.startStates(Set.of("States.S1"))
|
|
||||||
.endStates(Set.of("States.S2"))
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Test FN (Full Name - Default)
|
State state1 = State.of("State1");
|
||||||
ExportOptions optionsFn = ExportOptions.builder()
|
State state2 = State.of("State2");
|
||||||
.stateFormat(EnumFormat.fn)
|
|
||||||
.eventFormat(EnumFormat.fn)
|
|
||||||
.build();
|
|
||||||
String pumlFn = exporter.export(result, optionsFn);
|
|
||||||
assertThat(pumlFn)
|
|
||||||
.contains("States.S1 -[#")
|
|
||||||
.contains("]-> States.S2")
|
|
||||||
.contains(" : Events.E1");
|
|
||||||
|
|
||||||
// Test FQN (Fully Qualified Name)
|
Transition t = new Transition();
|
||||||
ExportOptions optionsFqn = ExportOptions.builder()
|
t.setType(TransitionType.EXTERNAL);
|
||||||
.stateFormat(EnumFormat.fqn)
|
t.setSourceStates(List.of(state1));
|
||||||
.eventFormat(EnumFormat.fqn)
|
t.setTargetStates(List.of(state2));
|
||||||
.build();
|
|
||||||
String pumlFqn = exporter.export(result, optionsFqn);
|
// Add a guard and action containing problematic characters
|
||||||
assertThat(pumlFqn)
|
t.setGuard(Guard.of("list.size() < 5", false, null, null, null, null));
|
||||||
.contains("com.example.States.S1 -[#")
|
t.setActions(List.of(Action.of("doSomething(new int[]{1, 2})", false, null, null, null, null)));
|
||||||
.contains("]-> com.example.States.S2")
|
|
||||||
.contains(" : com.example.Events.E1");
|
|
||||||
|
|
||||||
// Test SN (Short Name)
|
String result = plantUml.export(
|
||||||
ExportOptions optionsSn = ExportOptions.builder()
|
"TestMachine",
|
||||||
.stateFormat(EnumFormat.sn)
|
List.of(t),
|
||||||
.eventFormat(EnumFormat.sn)
|
Set.of("State1"),
|
||||||
.build();
|
Set.of("State2"),
|
||||||
String pumlSn = exporter.export(result, optionsSn);
|
options
|
||||||
assertThat(pumlSn)
|
);
|
||||||
.contains("S1 -[#")
|
|
||||||
.contains("]-> S2")
|
// Verify that < and > are replaced with HTML entities
|
||||||
.contains(" : E1");
|
assertThat(result).doesNotContain("< 5");
|
||||||
|
assertThat(result).contains("< 5");
|
||||||
|
|
||||||
|
// Verify that [ and ] are replaced with HTML entities inside the link
|
||||||
|
assertThat(result).doesNotContain("[list.size() < 5]");
|
||||||
|
assertThat(result).doesNotContain("new int[]{1, 2}");
|
||||||
|
assertThat(result).contains("[list.size() < 5]");
|
||||||
|
assertThat(result).contains("new int[]{1, 2}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 157 KiB After Width: | Height: | Size: 157 KiB |
@@ -34,21 +34,21 @@ state States.STATE14 <<choice>>
|
|||||||
state States.STATE9 <<choice>>
|
state States.STATE9 <<choice>>
|
||||||
state States.STATE8 <<choice>>
|
state States.STATE8 <<choice>>
|
||||||
|
|
||||||
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> <<e_Events_EVENT1>> : Events.EVENT1
|
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> : Events.EVENT1
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> <<e_Events_EVENT2>> : Events.EVENT2
|
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> : Events.EVENT2
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> <<e_Events_EVENT3>> : Events.EVENT3
|
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> : Events.EVENT3
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> <<e_Events_EVENT4>> : Events.EVENT4
|
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> : Events.EVENT4
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> <<e_Events_EVENT5>> : Events.EVENT5
|
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> : Events.EVENT5
|
||||||
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> <<e_Events_EVENT6>> : Events.EVENT6
|
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> : Events.EVENT6
|
||||||
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> <<e_Events_EVENT7>> : Events.EVENT7
|
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> : Events.EVENT7
|
||||||
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> <<e_Events_EVENT8>> : Events.EVENT8
|
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> : Events.EVENT8
|
||||||
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> <<e_Events_EVENT9>> : Events.EVENT9
|
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> : Events.EVENT9
|
||||||
States.STATE10 -[#1E90FF,bold]-> States.STATE11 <<external>> <<e_Events_EVENT10>> : Events.EVENT10
|
States.STATE10 -[#1E90FF,bold]-> States.STATE11 <<external>> : Events.EVENT10
|
||||||
States.STATE11 -[#1E90FF,bold]-> States.STATE12 <<external>> <<e_Events_EVENT11>> : Events.EVENT11
|
States.STATE11 -[#1E90FF,bold]-> States.STATE12 <<external>> : Events.EVENT11
|
||||||
States.STATE12 -[#1E90FF,bold]-> States.STATE13 <<external>> <<e_Events_EVENT12>> : Events.EVENT12
|
States.STATE12 -[#1E90FF,bold]-> States.STATE13 <<external>> : Events.EVENT12
|
||||||
States.STATE13 -[#1E90FF,bold]-> States.STATE14 <<external>> <<e_Events_EVENT13>> : Events.EVENT13
|
States.STATE13 -[#1E90FF,bold]-> States.STATE14 <<external>> : Events.EVENT13
|
||||||
States.STATE14 -[#1E90FF,bold]-> States.STATE15 <<external>> <<e_Events_EVENT14>> : Events.EVENT14
|
States.STATE14 -[#1E90FF,bold]-> States.STATE15 <<external>> : Events.EVENT14
|
||||||
States.STATE15 -[#1E90FF,bold]-> States.STATE16 <<external>> <<e_Events_EVENT15>> : Events.EVENT15
|
States.STATE15 -[#1E90FF,bold]-> States.STATE16 <<external>> : Events.EVENT15
|
||||||
States.STATE16 -[#FF6347,bold]-> States.STATE17 <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
States.STATE16 -[#FF6347,bold]-> States.STATE17 <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
||||||
States.STATE16 -[#FF6347,bold]-> States.STATE18 <<choice_type>> : [guardVarEquals("value2")] (order=1)
|
States.STATE16 -[#FF6347,bold]-> States.STATE18 <<choice_type>> : [guardVarEquals("value2")] (order=1)
|
||||||
States.STATE16 -[#FF6347,bold]-> States.STATE19 <<choice_type>> : (order=2)
|
States.STATE16 -[#FF6347,bold]-> States.STATE19 <<choice_type>> : (order=2)
|
||||||
|
|||||||
@@ -137,7 +137,7 @@
|
|||||||
"name" : "JMS: shipping.queue",
|
"name" : "JMS: shipping.queue",
|
||||||
"className" : "click.kamil.examples.enterprise.messaging.ShippingJmsListener",
|
"className" : "click.kamil.examples.enterprise.messaging.ShippingJmsListener",
|
||||||
"methodName" : "onShippingReady",
|
"methodName" : "onShippingReady",
|
||||||
"sourceFile" : null,
|
"sourceFile" : "src/main/java/click/kamil/examples/enterprise/messaging/ShippingJmsListener.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"protocol" : "JMS",
|
"protocol" : "JMS",
|
||||||
"destination" : "shipping.queue"
|
"destination" : "shipping.queue"
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
"name" : "RABBIT: returns.queue",
|
"name" : "RABBIT: returns.queue",
|
||||||
"className" : "click.kamil.examples.enterprise.messaging.ReturnsRabbitListener",
|
"className" : "click.kamil.examples.enterprise.messaging.ReturnsRabbitListener",
|
||||||
"methodName" : "onReturn",
|
"methodName" : "onReturn",
|
||||||
"sourceFile" : null,
|
"sourceFile" : "src/main/java/click/kamil/examples/enterprise/messaging/ReturnsRabbitListener.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"protocol" : "RABBIT",
|
"protocol" : "RABBIT",
|
||||||
"destination" : "returns.queue"
|
"destination" : "returns.queue"
|
||||||
@@ -292,7 +292,7 @@
|
|||||||
"name" : "JMS: shipping.queue",
|
"name" : "JMS: shipping.queue",
|
||||||
"className" : "click.kamil.examples.enterprise.messaging.ShippingJmsListener",
|
"className" : "click.kamil.examples.enterprise.messaging.ShippingJmsListener",
|
||||||
"methodName" : "onShippingReady",
|
"methodName" : "onShippingReady",
|
||||||
"sourceFile" : null,
|
"sourceFile" : "src/main/java/click/kamil/examples/enterprise/messaging/ShippingJmsListener.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"protocol" : "JMS",
|
"protocol" : "JMS",
|
||||||
"destination" : "shipping.queue"
|
"destination" : "shipping.queue"
|
||||||
@@ -326,7 +326,7 @@
|
|||||||
"name" : "RABBIT: returns.queue",
|
"name" : "RABBIT: returns.queue",
|
||||||
"className" : "click.kamil.examples.enterprise.messaging.ReturnsRabbitListener",
|
"className" : "click.kamil.examples.enterprise.messaging.ReturnsRabbitListener",
|
||||||
"methodName" : "onReturn",
|
"methodName" : "onReturn",
|
||||||
"sourceFile" : null,
|
"sourceFile" : "src/main/java/click/kamil/examples/enterprise/messaging/ReturnsRabbitListener.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"protocol" : "RABBIT",
|
"protocol" : "RABBIT",
|
||||||
"destination" : "returns.queue"
|
"destination" : "returns.queue"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
@@ -25,14 +25,14 @@ skinparam svgLinkTarget _self
|
|||||||
|
|
||||||
state CHECK_AVAILABILITY <<choice>>
|
state CHECK_AVAILABILITY <<choice>>
|
||||||
|
|
||||||
NEW -[#1E90FF,bold]-> CHECK_AVAILABILITY <<external>> <<e_PLACE_ORDER>> : PLACE_ORDER
|
NEW -[#1E90FF,bold]-> CHECK_AVAILABILITY <<external>> : PLACE_ORDER
|
||||||
CHECK_AVAILABILITY -[#FF6347,bold]-> PENDING_PAYMENT <<choice_type>> : [λ] (order=0)
|
CHECK_AVAILABILITY -[#FF6347,bold]-> PENDING_PAYMENT <<choice_type>> : [λ] (order=0)
|
||||||
CHECK_AVAILABILITY -[#FF6347,bold]-> CANCELLED <<choice_type>> : (order=1)
|
CHECK_AVAILABILITY -[#FF6347,bold]-> CANCELLED <<choice_type>> : (order=1)
|
||||||
PENDING_PAYMENT -[#1E90FF,bold]-> PAID <<external>> <<e_PAY_ORDER>> : PAY_ORDER
|
PENDING_PAYMENT -[#1E90FF,bold]-> PAID <<external>> : PAY_ORDER
|
||||||
PAID -[#1E90FF,bold]-> SHIPPED <<external>> <<e_SHIP_ORDER>> : SHIP_ORDER
|
PAID -[#1E90FF,bold]-> SHIPPED <<external>> : SHIP_ORDER
|
||||||
SHIPPED -[#1E90FF,bold]-> DELIVERED <<external>> <<e_FINALIZE>> : FINALIZE
|
SHIPPED -[#1E90FF,bold]-> DELIVERED <<external>> : FINALIZE
|
||||||
PAID -[#1E90FF,bold]-> CANCELLED <<external>> <<e_CANCEL_ORDER>> : CANCEL_ORDER
|
PAID -[#1E90FF,bold]-> CANCELLED <<external>> : CANCEL_ORDER
|
||||||
DELIVERED -[#1E90FF,bold]-> RETURNED <<external>> <<e_RETURN_ORDER>> : RETURN_ORDER
|
DELIVERED -[#1E90FF,bold]-> RETURNED <<external>> : RETURN_ORDER
|
||||||
|
|
||||||
CANCELLED --> [*]
|
CANCELLED --> [*]
|
||||||
DELIVERED --> [*]
|
DELIVERED --> [*]
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 19 KiB |
@@ -24,12 +24,12 @@ skinparam svgLinkTarget _self
|
|||||||
[*] --> INIT_STATE
|
[*] --> INIT_STATE
|
||||||
|
|
||||||
|
|
||||||
START -[#1E90FF,bold]-> PROCESSING <<external>> <<e_SUBMIT_EVENT>> : SUBMIT_EVENT
|
START -[#1E90FF,bold]-> PROCESSING <<external>> : SUBMIT_EVENT
|
||||||
PROCESSING -[#1E90FF,bold]-> COMPLETED <<external>> <<e_FINISH>> : FINISH
|
PROCESSING -[#1E90FF,bold]-> COMPLETED <<external>> : FINISH
|
||||||
PROCESSING -[#1E90FF,bold]-> CANCELLED <<external>> <<e_CANCEL_EVENT>> : CANCEL_EVENT
|
PROCESSING -[#1E90FF,bold]-> CANCELLED <<external>> : CANCEL_EVENT
|
||||||
START -[#1E90FF,bold]-> PROCESSING <<external>> <<e_REACTIVE_EVENT>> : REACTIVE_EVENT
|
START -[#1E90FF,bold]-> PROCESSING <<external>> : REACTIVE_EVENT
|
||||||
START -[#1E90FF,bold]-> START <<external>> <<e_AUDIT_EVENT>> : AUDIT_EVENT
|
START -[#1E90FF,bold]-> START <<external>> : AUDIT_EVENT
|
||||||
START -[#1E90FF,bold]-> PROCESSING <<external>> <<e_EXTERNAL_TRIGGER>> : EXTERNAL_TRIGGER
|
START -[#1E90FF,bold]-> PROCESSING <<external>> : EXTERNAL_TRIGGER
|
||||||
|
|
||||||
CANCELLED --> [*]
|
CANCELLED --> [*]
|
||||||
COMPLETED --> [*]
|
COMPLETED --> [*]
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
@@ -24,12 +24,12 @@ skinparam svgLinkTarget _self
|
|||||||
[*] --> PROD_INITIAL
|
[*] --> PROD_INITIAL
|
||||||
|
|
||||||
|
|
||||||
START -[#1E90FF,bold]-> PROCESSING <<external>> <<e_SUBMIT_EVENT>> : SUBMIT_EVENT
|
START -[#1E90FF,bold]-> PROCESSING <<external>> : SUBMIT_EVENT
|
||||||
PROCESSING -[#1E90FF,bold]-> COMPLETED <<external>> <<e_FINISH>> : FINISH
|
PROCESSING -[#1E90FF,bold]-> COMPLETED <<external>> : FINISH
|
||||||
PROCESSING -[#1E90FF,bold]-> CANCELLED <<external>> <<e_CANCEL_EVENT>> : CANCEL_EVENT
|
PROCESSING -[#1E90FF,bold]-> CANCELLED <<external>> : CANCEL_EVENT
|
||||||
START -[#1E90FF,bold]-> PROCESSING <<external>> <<e_REACTIVE_EVENT>> : REACTIVE_EVENT
|
START -[#1E90FF,bold]-> PROCESSING <<external>> : REACTIVE_EVENT
|
||||||
START -[#1E90FF,bold]-> START <<external>> <<e_AUDIT_EVENT>> : AUDIT_EVENT
|
START -[#1E90FF,bold]-> START <<external>> : AUDIT_EVENT
|
||||||
START -[#1E90FF,bold]-> PROCESSING <<external>> <<e_EXTERNAL_TRIGGER>> : EXTERNAL_TRIGGER
|
START -[#1E90FF,bold]-> PROCESSING <<external>> : EXTERNAL_TRIGGER
|
||||||
|
|
||||||
CANCELLED --> [*]
|
CANCELLED --> [*]
|
||||||
COMPLETED --> [*]
|
COMPLETED --> [*]
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 223 KiB |
@@ -36,27 +36,27 @@ state States.STATE9 <<choice>>
|
|||||||
state States.STATE8 <<choice>>
|
state States.STATE8 <<choice>>
|
||||||
state States.STATE2 <<choice>>
|
state States.STATE2 <<choice>>
|
||||||
|
|
||||||
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> <<e_Events_EVENT1>> : Events.EVENT1
|
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> : Events.EVENT1
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> <<e_Events_EVENT2>> : Events.EVENT2
|
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> : Events.EVENT2
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> <<e_Events_EVENT3>> : Events.EVENT3
|
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> : Events.EVENT3
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> <<e_Events_EVENT4>> : Events.EVENT4
|
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> : Events.EVENT4
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> <<e_Events_EVENT5>> : Events.EVENT5
|
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> : Events.EVENT5
|
||||||
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> <<e_Events_EVENT6>> : Events.EVENT6
|
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> : Events.EVENT6
|
||||||
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> <<e_Events_EVENT7>> : Events.EVENT7
|
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> : Events.EVENT7
|
||||||
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> <<e_Events_EVENT8>> : Events.EVENT8
|
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> : Events.EVENT8
|
||||||
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> <<e_Events_EVENT9>> : Events.EVENT9
|
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> : Events.EVENT9
|
||||||
States.STATE10 -[#1E90FF,bold]-> States.STATE11 <<external>> <<e_Events_EVENT10>> : Events.EVENT10
|
States.STATE10 -[#1E90FF,bold]-> States.STATE11 <<external>> : Events.EVENT10
|
||||||
States.STATE11 -[#1E90FF,bold]-> States.STATE12 <<external>> <<e_Events_EVENT11>> : Events.EVENT11
|
States.STATE11 -[#1E90FF,bold]-> States.STATE12 <<external>> : Events.EVENT11
|
||||||
States.STATE12 -[#1E90FF,bold]-> States.STATE13 <<external>> <<e_Events_EVENT12>> : Events.EVENT12
|
States.STATE12 -[#1E90FF,bold]-> States.STATE13 <<external>> : Events.EVENT12
|
||||||
States.STATE13 -[#1E90FF,bold]-> States.STATE14 <<external>> <<e_Events_EVENT13>> : Events.EVENT13
|
States.STATE13 -[#1E90FF,bold]-> States.STATE14 <<external>> : Events.EVENT13
|
||||||
States.STATE14 -[#1E90FF,bold]-> States.STATE15 <<external>> <<e_Events_EVENT14>> : Events.EVENT14
|
States.STATE14 -[#1E90FF,bold]-> States.STATE15 <<external>> : Events.EVENT14
|
||||||
States.STATE15 -[#1E90FF,bold]-> States.STATE16 <<external>> <<e_Events_EVENT15>> : Events.EVENT15
|
States.STATE15 -[#1E90FF,bold]-> States.STATE16 <<external>> : Events.EVENT15
|
||||||
States.STATE1 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE1 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE2 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE3 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE4 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE5 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.STATEY <<external>> <<e_Events_EVENTY>> : Events.EVENTY
|
States.STATE4 -[#1E90FF,bold]-> States.STATEY <<external>> : Events.EVENTY
|
||||||
States.STATEY -[#FF6347,bold]-> States.STATEX <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
States.STATEY -[#FF6347,bold]-> States.STATEX <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
||||||
States.STATEY -[#FF6347,bold]-> States.STATEZ <<choice_type>> : (order=1)
|
States.STATEY -[#FF6347,bold]-> States.STATEZ <<choice_type>> : (order=1)
|
||||||
States.STATE16 -[#FF6347,bold]-> States.STATE17 <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
States.STATE16 -[#FF6347,bold]-> States.STATE17 <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
||||||
@@ -82,12 +82,12 @@ States.STATE9 -[#FF6347,bold]-> States.STATE7 <<choice_type>> : [guardVarEquals(
|
|||||||
States.STATE9 -[#FF6347,bold]-> States.STATE6 <<choice_type>> : (order=2)
|
States.STATE9 -[#FF6347,bold]-> States.STATE6 <<choice_type>> : (order=2)
|
||||||
States.STATE8 -[#FF6347,bold]-> States.STATE9 <<choice_type>> : [guardVarEquals("forward9")] (order=0)
|
States.STATE8 -[#FF6347,bold]-> States.STATE9 <<choice_type>> : [guardVarEquals("forward9")] (order=0)
|
||||||
States.STATE8 -[#FF6347,bold]-> States.STATE10 <<choice_type>> : (order=1)
|
States.STATE8 -[#FF6347,bold]-> States.STATE10 <<choice_type>> : (order=1)
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.STATE_EXTRA_1 <<external>> <<e_Events_EVENTX>> : Events.EVENTX
|
States.STATE2 -[#1E90FF,bold]-> States.STATE_EXTRA_1 <<external>> : Events.EVENTX
|
||||||
States.STATE2 -[#FF6347,bold]-> States.STATE1 <<choice_type>> : [guardEventHeaderEquals("header1","foo")] (order=0)
|
States.STATE2 -[#FF6347,bold]-> States.STATE1 <<choice_type>> : [guardEventHeaderEquals("header1","foo")] (order=0)
|
||||||
States.STATE2 -[#FF6347,bold]-> States.STATE_EXTRA_1 <<choice_type>> : (order=1)
|
States.STATE2 -[#FF6347,bold]-> States.STATE_EXTRA_1 <<choice_type>> : (order=1)
|
||||||
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.STATE_EXTRA_3 <<external>> <<e_Events_EVENTY>> : Events.EVENTY
|
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.STATE_EXTRA_3 <<external>> : Events.EVENTY
|
||||||
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL_2>> : Events.EVENT_CANCEL_2
|
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL_2
|
||||||
States.STATE_EXTRA_2 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL_2>> : Events.EVENT_CANCEL_2
|
States.STATE_EXTRA_2 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL_2
|
||||||
|
|
||||||
States.STATEZ --> [*]
|
States.STATEZ --> [*]
|
||||||
@enduml
|
@enduml
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 258 KiB After Width: | Height: | Size: 257 KiB |
@@ -36,27 +36,27 @@ state States.STATE9 <<choice>>
|
|||||||
state States.STATE8 <<choice>>
|
state States.STATE8 <<choice>>
|
||||||
state States.STATE_EXTRA_1_2 <<choice>>
|
state States.STATE_EXTRA_1_2 <<choice>>
|
||||||
|
|
||||||
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> <<e_Events_EVENT1>> : Events.EVENT1
|
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> : Events.EVENT1
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> <<e_Events_EVENT2>> : Events.EVENT2
|
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> : Events.EVENT2
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> <<e_Events_EVENT3>> : Events.EVENT3
|
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> : Events.EVENT3
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> <<e_Events_EVENT4>> : Events.EVENT4
|
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> : Events.EVENT4
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> <<e_Events_EVENT5>> : Events.EVENT5
|
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> : Events.EVENT5
|
||||||
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> <<e_Events_EVENT6>> : Events.EVENT6
|
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> : Events.EVENT6
|
||||||
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> <<e_Events_EVENT7>> : Events.EVENT7
|
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> : Events.EVENT7
|
||||||
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> <<e_Events_EVENT8>> : Events.EVENT8
|
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> : Events.EVENT8
|
||||||
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> <<e_Events_EVENT9>> : Events.EVENT9
|
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> : Events.EVENT9
|
||||||
States.STATE10 -[#1E90FF,bold]-> States.STATE11 <<external>> <<e_Events_EVENT10>> : Events.EVENT10
|
States.STATE10 -[#1E90FF,bold]-> States.STATE11 <<external>> : Events.EVENT10
|
||||||
States.STATE11 -[#1E90FF,bold]-> States.STATE12 <<external>> <<e_Events_EVENT11>> : Events.EVENT11
|
States.STATE11 -[#1E90FF,bold]-> States.STATE12 <<external>> : Events.EVENT11
|
||||||
States.STATE12 -[#1E90FF,bold]-> States.STATE13 <<external>> <<e_Events_EVENT12>> : Events.EVENT12
|
States.STATE12 -[#1E90FF,bold]-> States.STATE13 <<external>> : Events.EVENT12
|
||||||
States.STATE13 -[#1E90FF,bold]-> States.STATE14 <<external>> <<e_Events_EVENT13>> : Events.EVENT13
|
States.STATE13 -[#1E90FF,bold]-> States.STATE14 <<external>> : Events.EVENT13
|
||||||
States.STATE14 -[#1E90FF,bold]-> States.STATE15 <<external>> <<e_Events_EVENT14>> : Events.EVENT14
|
States.STATE14 -[#1E90FF,bold]-> States.STATE15 <<external>> : Events.EVENT14
|
||||||
States.STATE15 -[#1E90FF,bold]-> States.STATE16 <<external>> <<e_Events_EVENT15>> : Events.EVENT15
|
States.STATE15 -[#1E90FF,bold]-> States.STATE16 <<external>> : Events.EVENT15
|
||||||
States.STATE1 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE1 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE2 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE3 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE4 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE5 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.STATEY <<external>> <<e_Events_EVENTY>> : Events.EVENTY
|
States.STATE4 -[#1E90FF,bold]-> States.STATEY <<external>> : Events.EVENTY
|
||||||
States.STATEY -[#FF6347,bold]-> States.STATEX <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
States.STATEY -[#FF6347,bold]-> States.STATEX <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
||||||
States.STATEY -[#FF6347,bold]-> States.STATEZ <<choice_type>> : (order=1)
|
States.STATEY -[#FF6347,bold]-> States.STATEZ <<choice_type>> : (order=1)
|
||||||
States.STATE16 -[#FF6347,bold]-> States.STATE17 <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
States.STATE16 -[#FF6347,bold]-> States.STATE17 <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
||||||
@@ -82,13 +82,13 @@ States.STATE9 -[#FF6347,bold]-> States.STATE7 <<choice_type>> : [guardVarEquals(
|
|||||||
States.STATE9 -[#FF6347,bold]-> States.STATE6 <<choice_type>> : (order=2)
|
States.STATE9 -[#FF6347,bold]-> States.STATE6 <<choice_type>> : (order=2)
|
||||||
States.STATE8 -[#FF6347,bold]-> States.STATE9 <<choice_type>> : [guardVarEquals("forward9")] (order=0)
|
States.STATE8 -[#FF6347,bold]-> States.STATE9 <<choice_type>> : [guardVarEquals("forward9")] (order=0)
|
||||||
States.STATE8 -[#FF6347,bold]-> States.STATE10 <<choice_type>> : (order=1)
|
States.STATE8 -[#FF6347,bold]-> States.STATE10 <<choice_type>> : (order=1)
|
||||||
States.STATE9 -[#1E90FF,bold]-> States.STATE_EXTRA_1_1 <<external>> <<e_Events_EVENT_1_1>> : Events.EVENT_1_1
|
States.STATE9 -[#1E90FF,bold]-> States.STATE_EXTRA_1_1 <<external>> : Events.EVENT_1_1
|
||||||
States.STATE_EXTRA_1_2 -[#FF6347,bold]-> States.STATE_EXTRA_1_1 <<choice_type>> : [guardEventHeaderEquals("header1","foo")] (order=0)
|
States.STATE_EXTRA_1_2 -[#FF6347,bold]-> States.STATE_EXTRA_1_1 <<choice_type>> : [guardEventHeaderEquals("header1","foo")] (order=0)
|
||||||
States.STATE_EXTRA_1_2 -[#FF6347,bold]-> States.STATE_EXTRA_1_3 <<choice_type>> : (order=1)
|
States.STATE_EXTRA_1_2 -[#FF6347,bold]-> States.STATE_EXTRA_1_3 <<choice_type>> : (order=1)
|
||||||
States.STATE_EXTRA_1_3 -[#1E90FF,bold]-> States.STATE_EXTRA_1 <<external>> <<e_Events_EVENT_1_2>> : Events.EVENT_1_2
|
States.STATE_EXTRA_1_3 -[#1E90FF,bold]-> States.STATE_EXTRA_1 <<external>> : Events.EVENT_1_2
|
||||||
States.STATE_EXTRA_1_1 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL_2>> : Events.EVENT_CANCEL_2
|
States.STATE_EXTRA_1_1 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL_2
|
||||||
States.STATE_EXTRA_1_2 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL_2>> : Events.EVENT_CANCEL_2
|
States.STATE_EXTRA_1_2 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL_2
|
||||||
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL_2>> : Events.EVENT_CANCEL_2
|
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL_2
|
||||||
|
|
||||||
States.STATEZ --> [*]
|
States.STATEZ --> [*]
|
||||||
@enduml
|
@enduml
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
@@ -24,14 +24,14 @@ skinparam svgLinkTarget _self
|
|||||||
[*] --> States.START
|
[*] --> States.START
|
||||||
|
|
||||||
|
|
||||||
States.START -[#1E90FF,bold]-> States.FORK <<external>> <<e_Events_TO_FORK>> : Events.TO_FORK
|
States.START -[#1E90FF,bold]-> States.FORK <<external>> : Events.TO_FORK
|
||||||
States.FORK -[#20B2AA,bold]-> States.REGION1_STATE1 <<fork>>
|
States.FORK -[#20B2AA,bold]-> States.REGION1_STATE1 <<fork>>
|
||||||
States.FORK -[#20B2AA,bold]-> States.REGION2_STATE1 <<fork>>
|
States.FORK -[#20B2AA,bold]-> States.REGION2_STATE1 <<fork>>
|
||||||
States.REGION1_STATE1 -[#1E90FF,bold]-> States.REGION1_STATE2 <<external>> <<e_Events_R1_NEXT>> : Events.R1_NEXT
|
States.REGION1_STATE1 -[#1E90FF,bold]-> States.REGION1_STATE2 <<external>> : Events.R1_NEXT
|
||||||
States.REGION2_STATE1 -[#1E90FF,bold]-> States.REGION2_STATE2 <<external>> <<e_Events_R2_NEXT>> : Events.R2_NEXT
|
States.REGION2_STATE1 -[#1E90FF,bold]-> States.REGION2_STATE2 <<external>> : Events.R2_NEXT
|
||||||
States.REGION1_STATE2 -[#8A2BE2,bold]-> States.JOIN <<join>>
|
States.REGION1_STATE2 -[#8A2BE2,bold]-> States.JOIN <<join>>
|
||||||
States.REGION2_STATE2 -[#8A2BE2,bold]-> States.JOIN <<join>>
|
States.REGION2_STATE2 -[#8A2BE2,bold]-> States.JOIN <<join>>
|
||||||
States.JOIN -[#1E90FF,bold]-> States.END <<external>> <<e_Events_TO_END>> : Events.TO_END
|
States.JOIN -[#1E90FF,bold]-> States.END <<external>> : Events.TO_END
|
||||||
|
|
||||||
States.END --> [*]
|
States.END --> [*]
|
||||||
@enduml
|
@enduml
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 99 KiB |
@@ -27,21 +27,21 @@ state States.STATEY <<choice>>
|
|||||||
state States.STATE9 <<choice>>
|
state States.STATE9 <<choice>>
|
||||||
state States.STATE8 <<choice>>
|
state States.STATE8 <<choice>>
|
||||||
|
|
||||||
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> <<e_Events_EVENT1>> : Events.EVENT1
|
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> : Events.EVENT1
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> <<e_Events_EVENT2>> : Events.EVENT2
|
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> : Events.EVENT2
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> <<e_Events_EVENT3>> : Events.EVENT3
|
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> : Events.EVENT3
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> <<e_Events_EVENT4>> : Events.EVENT4
|
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> : Events.EVENT4
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> <<e_Events_EVENT5>> : Events.EVENT5
|
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> : Events.EVENT5
|
||||||
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> <<e_Events_EVENT6>> : Events.EVENT6
|
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> : Events.EVENT6
|
||||||
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> <<e_Events_EVENT7>> : Events.EVENT7
|
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> : Events.EVENT7
|
||||||
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> <<e_Events_EVENT8>> : Events.EVENT8
|
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> : Events.EVENT8
|
||||||
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> <<e_Events_EVENT9>> : Events.EVENT9
|
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> : Events.EVENT9
|
||||||
States.STATE1 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE1 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE2 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE3 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE4 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE5 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.STATEY <<external>> <<e_Events_EVENTY>> : Events.EVENTY
|
States.STATE4 -[#1E90FF,bold]-> States.STATEY <<external>> : Events.EVENTY
|
||||||
States.STATEY -[#FF6347,bold]-> States.STATEX <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
States.STATEY -[#FF6347,bold]-> States.STATEX <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
||||||
States.STATEY -[#FF6347,bold]-> States.STATEZ <<choice_type>> : (order=1)
|
States.STATEY -[#FF6347,bold]-> States.STATEZ <<choice_type>> : (order=1)
|
||||||
States.STATE9 -[#FF6347,bold]-> States.STATE8 <<choice_type>> : [guardVarEquals("stepBack")] (order=0)
|
States.STATE9 -[#FF6347,bold]-> States.STATE8 <<choice_type>> : [guardVarEquals("stepBack")] (order=0)
|
||||||
@@ -49,9 +49,9 @@ States.STATE9 -[#FF6347,bold]-> States.STATE7 <<choice_type>> : [guardVarEquals(
|
|||||||
States.STATE9 -[#FF6347,bold]-> States.STATE6 <<choice_type>> : (order=2)
|
States.STATE9 -[#FF6347,bold]-> States.STATE6 <<choice_type>> : (order=2)
|
||||||
States.STATE8 -[#FF6347,bold]-> States.STATE9 <<choice_type>> : [guardVarEquals("forward9")] (order=0)
|
States.STATE8 -[#FF6347,bold]-> States.STATE9 <<choice_type>> : [guardVarEquals("forward9")] (order=0)
|
||||||
States.STATE8 -[#FF6347,bold]-> States.STATE10 <<choice_type>> : (order=1)
|
States.STATE8 -[#FF6347,bold]-> States.STATE10 <<choice_type>> : (order=1)
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.STATE_EXTRA_2 <<external>> <<e_Events_EVENT_1_2>> : Events.EVENT_1_2
|
States.STATE3 -[#1E90FF,bold]-> States.STATE_EXTRA_2 <<external>> : Events.EVENT_1_2
|
||||||
States.STATE_EXTRA_2 -[#1E90FF,bold]-> States.STATE_EXTRA_3 <<external>> <<e_Events_EVENT_1_2>> : Events.EVENT_1_2
|
States.STATE_EXTRA_2 -[#1E90FF,bold]-> States.STATE_EXTRA_3 <<external>> : Events.EVENT_1_2
|
||||||
States.STATE_EXTRA_3 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE_EXTRA_3 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
|
|
||||||
States.STATEZ --> [*]
|
States.STATEZ --> [*]
|
||||||
@enduml
|
@enduml
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 105 KiB |
@@ -27,21 +27,21 @@ state States.STATEY <<choice>>
|
|||||||
state States.STATE9 <<choice>>
|
state States.STATE9 <<choice>>
|
||||||
state States.STATE8 <<choice>>
|
state States.STATE8 <<choice>>
|
||||||
|
|
||||||
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> <<e_Events_EVENT1>> : Events.EVENT1
|
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> : Events.EVENT1
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> <<e_Events_EVENT2>> : Events.EVENT2
|
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> : Events.EVENT2
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> <<e_Events_EVENT3>> : Events.EVENT3
|
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> : Events.EVENT3
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> <<e_Events_EVENT4>> : Events.EVENT4
|
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> : Events.EVENT4
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> <<e_Events_EVENT5>> : Events.EVENT5
|
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> : Events.EVENT5
|
||||||
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> <<e_Events_EVENT6>> : Events.EVENT6
|
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> : Events.EVENT6
|
||||||
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> <<e_Events_EVENT7>> : Events.EVENT7
|
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> : Events.EVENT7
|
||||||
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> <<e_Events_EVENT8>> : Events.EVENT8
|
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> : Events.EVENT8
|
||||||
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> <<e_Events_EVENT9>> : Events.EVENT9
|
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> : Events.EVENT9
|
||||||
States.STATE1 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE1 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE2 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE3 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE4 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE5 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.STATEY <<external>> <<e_Events_EVENTY>> : Events.EVENTY
|
States.STATE4 -[#1E90FF,bold]-> States.STATEY <<external>> : Events.EVENTY
|
||||||
States.STATEY -[#FF6347,bold]-> States.STATEX <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
States.STATEY -[#FF6347,bold]-> States.STATEX <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
||||||
States.STATEY -[#FF6347,bold]-> States.STATEZ <<choice_type>> : (order=1)
|
States.STATEY -[#FF6347,bold]-> States.STATEZ <<choice_type>> : (order=1)
|
||||||
States.STATE9 -[#FF6347,bold]-> States.STATE8 <<choice_type>> : [guardVarEquals("stepBack")] (order=0)
|
States.STATE9 -[#FF6347,bold]-> States.STATE8 <<choice_type>> : [guardVarEquals("stepBack")] (order=0)
|
||||||
@@ -49,10 +49,10 @@ States.STATE9 -[#FF6347,bold]-> States.STATE7 <<choice_type>> : [guardVarEquals(
|
|||||||
States.STATE9 -[#FF6347,bold]-> States.STATE6 <<choice_type>> : (order=2)
|
States.STATE9 -[#FF6347,bold]-> States.STATE6 <<choice_type>> : (order=2)
|
||||||
States.STATE8 -[#FF6347,bold]-> States.STATE9 <<choice_type>> : [guardVarEquals("forward9")] (order=0)
|
States.STATE8 -[#FF6347,bold]-> States.STATE9 <<choice_type>> : [guardVarEquals("forward9")] (order=0)
|
||||||
States.STATE8 -[#FF6347,bold]-> States.STATE10 <<choice_type>> : (order=1)
|
States.STATE8 -[#FF6347,bold]-> States.STATE10 <<choice_type>> : (order=1)
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.STATE_EXTRA_1 <<external>> <<e_Events_EVENT_1_2>> : Events.EVENT_1_2
|
States.STATE3 -[#1E90FF,bold]-> States.STATE_EXTRA_1 <<external>> : Events.EVENT_1_2
|
||||||
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.STATE_EXTRA_2 <<external>> <<e_Events_EVENT_1_3>> : Events.EVENT_1_3
|
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.STATE_EXTRA_2 <<external>> : Events.EVENT_1_3
|
||||||
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE_EXTRA_2 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE_EXTRA_2 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
|
|
||||||
States.STATEZ --> [*]
|
States.STATEZ --> [*]
|
||||||
@enduml
|
@enduml
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
@@ -24,7 +24,7 @@ skinparam svgLinkTarget _self
|
|||||||
[*] --> START
|
[*] --> START
|
||||||
|
|
||||||
|
|
||||||
START -[#1E90FF,bold]-> WORKING <<external>> <<e_INHERITED_SUBMIT>> : INHERITED_SUBMIT
|
START -[#1E90FF,bold]-> WORKING <<external>> : INHERITED_SUBMIT
|
||||||
|
|
||||||
WORKING --> [*]
|
WORKING --> [*]
|
||||||
@enduml
|
@enduml
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
@@ -25,19 +25,19 @@ skinparam svgLinkTarget _self
|
|||||||
|
|
||||||
state OrderStates.PAID1 <<choice>>
|
state OrderStates.PAID1 <<choice>>
|
||||||
|
|
||||||
OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.PAID <<external>> <<e_OrderEvents_PAY>> : OrderEvents.PAY
|
OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.PAID <<external>> : OrderEvents.PAY
|
||||||
OrderStates.PAID -[#1E90FF,bold]-> OrderStates.FULFILLED <<external>> <<e_OrderEvents_FULFILL>> : OrderEvents.FULFILL
|
OrderStates.PAID -[#1E90FF,bold]-> OrderStates.FULFILLED <<external>> : OrderEvents.FULFILL
|
||||||
OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.CANCELED <<external>> <<e_OrderEvents_CANCEL>> : OrderEvents.CANCEL [λ]
|
OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.CANCELED <<external>> : OrderEvents.CANCEL [λ]
|
||||||
OrderStates.PAID -[#1E90FF,bold]-> OrderStates.CANCELED <<external>> <<e_OrderEvents_CANCEL>> : OrderEvents.CANCEL
|
OrderStates.PAID -[#1E90FF,bold]-> OrderStates.CANCELED <<external>> : OrderEvents.CANCEL
|
||||||
OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.SUBMITTED <<external>> <<e_OrderEvents_ABCD>> : OrderEvents.ABCD
|
OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.SUBMITTED <<external>> : OrderEvents.ABCD
|
||||||
OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.PAID1 <<external>> <<e_OrderEvents_ABCD>> : OrderEvents.ABCD
|
OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.PAID1 <<external>> : OrderEvents.ABCD
|
||||||
OrderStates.PAID1 -[#FF6347,bold]-> OrderStates.PAID2 <<choice_type>> : [λ] (order=0)
|
OrderStates.PAID1 -[#FF6347,bold]-> OrderStates.PAID2 <<choice_type>> : [λ] (order=0)
|
||||||
OrderStates.PAID1 -[#FF6347,bold]-> OrderStates.PAID3 <<choice_type>> : [guard1] (order=1)
|
OrderStates.PAID1 -[#FF6347,bold]-> OrderStates.PAID3 <<choice_type>> : [guard1] (order=1)
|
||||||
OrderStates.PAID1 -[#FF6347,bold]-> OrderStates.HAPPEN <<choice_type>> : [λ] (order=2)
|
OrderStates.PAID1 -[#FF6347,bold]-> OrderStates.HAPPEN <<choice_type>> : [λ] (order=2)
|
||||||
OrderStates.PAID1 -[#FF6347,bold]-> OrderStates.CANCELED <<choice_type>> : (order=3)
|
OrderStates.PAID1 -[#FF6347,bold]-> OrderStates.CANCELED <<choice_type>> : (order=3)
|
||||||
OrderStates.PAID2 -[#1E90FF,bold]-> OrderStates.CANCELED <<external>>
|
OrderStates.PAID2 -[#1E90FF,bold]-> OrderStates.CANCELED <<external>>
|
||||||
OrderStates.PAID3 -[#1E90FF,bold]-> OrderStates.CANCELED <<external>>
|
OrderStates.PAID3 -[#1E90FF,bold]-> OrderStates.CANCELED <<external>>
|
||||||
OrderStates.PAID2 -[#1E90FF,bold]-> OrderStates.PAID2 <<external>> <<e_OrderEvents_ABCD>> : OrderEvents.ABCD / λ, action2
|
OrderStates.PAID2 -[#1E90FF,bold]-> OrderStates.PAID2 <<external>> : OrderEvents.ABCD / λ, action2
|
||||||
|
|
||||||
OrderStates.CANCELED --> [*]
|
OrderStates.CANCELED --> [*]
|
||||||
OrderStates.FULFILLED --> [*]
|
OrderStates.FULFILLED --> [*]
|
||||||
|
|||||||
@@ -66,7 +66,7 @@
|
|||||||
"name" : "JMS: order.queue",
|
"name" : "JMS: order.queue",
|
||||||
"className" : "click.kamil.maven.api.JmsOrderListener",
|
"className" : "click.kamil.maven.api.JmsOrderListener",
|
||||||
"methodName" : "onMessage",
|
"methodName" : "onMessage",
|
||||||
"sourceFile" : null,
|
"sourceFile" : "api-module/src/main/java/click/kamil/maven/api/JmsOrderListener.java",
|
||||||
"metadata" : {
|
"metadata" : {
|
||||||
"protocol" : "JMS",
|
"protocol" : "JMS",
|
||||||
"destination" : "order.queue"
|
"destination" : "order.queue"
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ skinparam svgLinkTarget _self
|
|||||||
[*] --> INIT
|
[*] --> INIT
|
||||||
|
|
||||||
|
|
||||||
INIT -[#1E90FF,bold]-> BUSY <<external>> <<e_SUBMIT>> : SUBMIT / loggingAction()
|
INIT -[#1E90FF,bold]-> BUSY <<external>> : SUBMIT / loggingAction()
|
||||||
BUSY -[#1E90FF,bold]-> DONE <<external>> <<e_ORDER_EVENT>> : ORDER_EVENT
|
BUSY -[#1E90FF,bold]-> DONE <<external>> : ORDER_EVENT
|
||||||
|
|
||||||
DONE --> [*]
|
DONE --> [*]
|
||||||
@enduml
|
@enduml
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 168 KiB |
@@ -35,22 +35,22 @@ state States.STATE14 <<choice>>
|
|||||||
state States.STATE9 <<choice>>
|
state States.STATE9 <<choice>>
|
||||||
state States.STATE8 <<choice>>
|
state States.STATE8 <<choice>>
|
||||||
|
|
||||||
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> <<e_Events_EVENT1>> : Events.EVENT1
|
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> : Events.EVENT1
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> <<e_Events_EVENT2>> : Events.EVENT2
|
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> : Events.EVENT2
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> <<e_Events_EVENT3>> : Events.EVENT3
|
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> : Events.EVENT3
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> <<e_Events_EVENT4>> : Events.EVENT4
|
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> : Events.EVENT4
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> <<e_Events_EVENT5>> : Events.EVENT5
|
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> : Events.EVENT5
|
||||||
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> <<e_Events_EVENT6>> : Events.EVENT6
|
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> : Events.EVENT6
|
||||||
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> <<e_Events_EVENT7>> : Events.EVENT7
|
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> : Events.EVENT7
|
||||||
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> <<e_Events_EVENT8>> : Events.EVENT8
|
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> : Events.EVENT8
|
||||||
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> <<e_Events_EVENT9>> : Events.EVENT9
|
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> : Events.EVENT9
|
||||||
States.STATE10 -[#1E90FF,bold]-> States.STATE11 <<external>> <<e_Events_EVENT10>> : Events.EVENT10
|
States.STATE10 -[#1E90FF,bold]-> States.STATE11 <<external>> : Events.EVENT10
|
||||||
States.STATE11 -[#1E90FF,bold]-> States.STATE12 <<external>> <<e_Events_EVENT11>> : Events.EVENT11
|
States.STATE11 -[#1E90FF,bold]-> States.STATE12 <<external>> : Events.EVENT11
|
||||||
States.STATE12 -[#1E90FF,bold]-> States.STATE13 <<external>> <<e_Events_EVENT12>> : Events.EVENT12
|
States.STATE12 -[#1E90FF,bold]-> States.STATE13 <<external>> : Events.EVENT12
|
||||||
States.STATE13 -[#1E90FF,bold]-> States.STATE14 <<external>> <<e_Events_EVENT13>> : Events.EVENT13
|
States.STATE13 -[#1E90FF,bold]-> States.STATE14 <<external>> : Events.EVENT13
|
||||||
States.STATE14 -[#1E90FF,bold]-> States.STATE15 <<external>> <<e_Events_EVENT14>> : Events.EVENT14
|
States.STATE14 -[#1E90FF,bold]-> States.STATE15 <<external>> : Events.EVENT14
|
||||||
States.STATE15 -[#1E90FF,bold]-> States.STATE16 <<external>> <<e_Events_EVENT15>> : Events.EVENT15
|
States.STATE15 -[#1E90FF,bold]-> States.STATE16 <<external>> : Events.EVENT15
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.STATEY <<external>> <<e_Events_EVENTY>> : Events.EVENTY
|
States.STATE4 -[#1E90FF,bold]-> States.STATEY <<external>> : Events.EVENTY
|
||||||
States.STATEY -[#FF6347,bold]-> States.STATEX <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
States.STATEY -[#FF6347,bold]-> States.STATEX <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
||||||
States.STATEY -[#FF6347,bold]-> States.STATEZ <<choice_type>> : (order=1)
|
States.STATEY -[#FF6347,bold]-> States.STATEZ <<choice_type>> : (order=1)
|
||||||
States.STATE16 -[#FF6347,bold]-> States.STATE17 <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
States.STATE16 -[#FF6347,bold]-> States.STATE17 <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
||||||
@@ -76,7 +76,7 @@ States.STATE9 -[#FF6347,bold]-> States.STATE7 <<choice_type>> : [guardVarEquals(
|
|||||||
States.STATE9 -[#FF6347,bold]-> States.STATE6 <<choice_type>> : (order=2)
|
States.STATE9 -[#FF6347,bold]-> States.STATE6 <<choice_type>> : (order=2)
|
||||||
States.STATE8 -[#FF6347,bold]-> States.STATE9 <<choice_type>> : [guardVarEquals("forward9")] (order=0)
|
States.STATE8 -[#FF6347,bold]-> States.STATE9 <<choice_type>> : [guardVarEquals("forward9")] (order=0)
|
||||||
States.STATE8 -[#FF6347,bold]-> States.STATE10 <<choice_type>> : (order=1)
|
States.STATE8 -[#FF6347,bold]-> States.STATE10 <<choice_type>> : (order=1)
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.STATE_EXTRA_1 <<external>> <<e_Events_EVENTX>> : Events.EVENTX
|
States.STATE5 -[#1E90FF,bold]-> States.STATE_EXTRA_1 <<external>> : Events.EVENTX
|
||||||
|
|
||||||
States.STATEZ --> [*]
|
States.STATEZ --> [*]
|
||||||
@enduml
|
@enduml
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ skinparam svgLinkTarget _self
|
|||||||
[*] --> NEW
|
[*] --> NEW
|
||||||
|
|
||||||
|
|
||||||
NEW -[#1E90FF,bold]-> PROCESSING <<external>> <<e_SUBMIT>> : SUBMIT / processAction()
|
NEW -[#1E90FF,bold]-> PROCESSING <<external>> : SUBMIT / processAction()
|
||||||
PROCESSING -[#1E90FF,bold]-> COMPLETED <<external>> <<e_FINISH>> : FINISH
|
PROCESSING -[#1E90FF,bold]-> COMPLETED <<external>> : FINISH
|
||||||
|
|
||||||
COMPLETED --> [*]
|
COMPLETED --> [*]
|
||||||
@enduml
|
@enduml
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 55 KiB |
@@ -26,11 +26,11 @@ skinparam svgLinkTarget _self
|
|||||||
state OrderStates.SUBMITTED <<choice>>
|
state OrderStates.SUBMITTED <<choice>>
|
||||||
state OrderStates.PAID <<choice>>
|
state OrderStates.PAID <<choice>>
|
||||||
|
|
||||||
OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.PAID <<external>> <<e_OrderEvents_PAY>> : OrderEvents.PAY
|
OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.PAID <<external>> : OrderEvents.PAY
|
||||||
OrderStates.PAID -[#1E90FF,bold]-> OrderStates.FULFILLED <<external>> <<e_OrderEvents_FULFILL>> : OrderEvents.FULFILL
|
OrderStates.PAID -[#1E90FF,bold]-> OrderStates.FULFILLED <<external>> : OrderEvents.FULFILL
|
||||||
OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.CANCELED <<external>> <<e_OrderEvents_CANCEL>> : OrderEvents.CANCEL [λ]
|
OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.CANCELED <<external>> : OrderEvents.CANCEL [λ]
|
||||||
OrderStates.PAID -[#1E90FF,bold]-> OrderStates.CANCELED <<external>> <<e_OrderEvents_CANCEL>> : OrderEvents.CANCEL
|
OrderStates.PAID -[#1E90FF,bold]-> OrderStates.CANCELED <<external>> : OrderEvents.CANCEL
|
||||||
OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.SUBMITTED <<external>> <<e_OrderEvents_ABCD>> : OrderEvents.ABCD
|
OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.SUBMITTED <<external>> : OrderEvents.ABCD
|
||||||
OrderStates.SUBMITTED -[#FF6347,bold]-> OrderStates.PAID2 <<choice_type>> : [λ] (order=0)
|
OrderStates.SUBMITTED -[#FF6347,bold]-> OrderStates.PAID2 <<choice_type>> : [λ] (order=0)
|
||||||
OrderStates.SUBMITTED -[#FF6347,bold]-> OrderStates.PAID3 <<choice_type>> : (order=1)
|
OrderStates.SUBMITTED -[#FF6347,bold]-> OrderStates.PAID3 <<choice_type>> : (order=1)
|
||||||
OrderStates.PAID -[#FF6347,bold]-> OrderStates.PAID1 <<choice_type>> : [λ] (order=0)
|
OrderStates.PAID -[#FF6347,bold]-> OrderStates.PAID1 <<choice_type>> : [λ] (order=0)
|
||||||
@@ -39,7 +39,7 @@ OrderStates.PAID -[#FF6347,bold]-> OrderStates.HAPPEN <<choice_type>> : [λ] (or
|
|||||||
OrderStates.PAID -[#FF6347,bold]-> OrderStates.PAID3 <<choice_type>> : (order=3)
|
OrderStates.PAID -[#FF6347,bold]-> OrderStates.PAID3 <<choice_type>> : (order=3)
|
||||||
OrderStates.PAID2 -[#1E90FF,bold]-> OrderStates.CANCELED <<external>>
|
OrderStates.PAID2 -[#1E90FF,bold]-> OrderStates.CANCELED <<external>>
|
||||||
OrderStates.PAID3 -[#1E90FF,bold]-> OrderStates.CANCELED <<external>>
|
OrderStates.PAID3 -[#1E90FF,bold]-> OrderStates.CANCELED <<external>>
|
||||||
OrderStates.PAID1 -[#1E90FF,bold]-> OrderStates.PAID1 <<external>> <<e_OrderEvents_ABCD>> : OrderEvents.ABCD / λ, action2
|
OrderStates.PAID1 -[#1E90FF,bold]-> OrderStates.PAID1 <<external>> : OrderEvents.ABCD / λ, action2
|
||||||
|
|
||||||
OrderStates.CANCELED --> [*]
|
OrderStates.CANCELED --> [*]
|
||||||
OrderStates.FULFILLED --> [*]
|
OrderStates.FULFILLED --> [*]
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
digraph statemachine {
|
||||||
|
rankdir=LR;
|
||||||
|
node [shape=rounded, style=filled, fillcolor=white, fontname="Arial"];
|
||||||
|
edge [fontname="Arial", fontsize=10];
|
||||||
|
|
||||||
|
_start [shape=circle, label="", fillcolor=black, width=0.1];
|
||||||
|
_start -> NEW;
|
||||||
|
COMPLETED [fillcolor=lightgray];
|
||||||
|
CANCELLED [fillcolor=lightgray];
|
||||||
|
NEW -> PROCESSING [label="OrderEvent.PROCESS", style="solid", color="black"];
|
||||||
|
PROCESSING -> COMPLETED [label="OrderEvent.COMPLETE", style="solid", color="black"];
|
||||||
|
NEW -> CANCELLED [label="OrderEvent.CANCEL", style="solid", color="black"];
|
||||||
|
PROCESSING -> CANCELLED [label="OrderEvent.CANCEL", style="solid", color="black"];
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,429 @@
|
|||||||
|
{
|
||||||
|
"metadata" : {
|
||||||
|
"triggers" : [ {
|
||||||
|
"event" : "event",
|
||||||
|
"className" : "click.kamil.service.StateMachineServiceImpl",
|
||||||
|
"methodName" : "sendMessage",
|
||||||
|
"sourceFile" : "service/src/main/java/click/kamil/service/StateMachineServiceImpl.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 25
|
||||||
|
}, {
|
||||||
|
"event" : "eventProvider",
|
||||||
|
"className" : "click.kamil.service.StateMachineServiceImpl",
|
||||||
|
"methodName" : "sendMessageWithProvider",
|
||||||
|
"sourceFile" : "service/src/main/java/click/kamil/service/StateMachineServiceImpl.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 50
|
||||||
|
}, {
|
||||||
|
"event" : "customMessage",
|
||||||
|
"className" : "click.kamil.service.StateMachineServiceImpl",
|
||||||
|
"methodName" : "sendCustomMessage",
|
||||||
|
"sourceFile" : "service/src/main/java/click/kamil/service/StateMachineServiceImpl.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 78
|
||||||
|
} ],
|
||||||
|
"entryPoints" : [ {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/orders/process",
|
||||||
|
"className" : "click.kamil.web.OrderController",
|
||||||
|
"methodName" : "processOrder",
|
||||||
|
"sourceFile" : "web/src/main/java/click/kamil/web/OrderController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/orders/process",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/orders/complete",
|
||||||
|
"className" : "click.kamil.web.OrderController",
|
||||||
|
"methodName" : "completeOrder",
|
||||||
|
"sourceFile" : "web/src/main/java/click/kamil/web/OrderController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/orders/complete",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/orders/cancel",
|
||||||
|
"className" : "click.kamil.web.OrderController",
|
||||||
|
"methodName" : "cancelOrder",
|
||||||
|
"sourceFile" : "web/src/main/java/click/kamil/web/OrderController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/orders/cancel",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ ]
|
||||||
|
}, {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/orders/functional-complete",
|
||||||
|
"className" : "click.kamil.web.OrderController",
|
||||||
|
"methodName" : "functionalCompleteOrder",
|
||||||
|
"sourceFile" : "web/src/main/java/click/kamil/web/OrderController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/orders/functional-complete",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ ]
|
||||||
|
}, {
|
||||||
|
"type" : "RABBIT",
|
||||||
|
"name" : "RABBIT: order.custom.transition.queue",
|
||||||
|
"className" : "click.kamil.web.RabbitOrderListener",
|
||||||
|
"methodName" : "handleCustomTransition",
|
||||||
|
"sourceFile" : "web/src/main/java/click/kamil/web/RabbitOrderListener.java",
|
||||||
|
"metadata" : {
|
||||||
|
"protocol" : "RABBIT",
|
||||||
|
"destination" : "order.custom.transition.queue"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "payload",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "JMS",
|
||||||
|
"name" : "JMS: order.process.queue",
|
||||||
|
"className" : "click.kamil.web.JmsOrderListener",
|
||||||
|
"methodName" : "receiveProcessCommand",
|
||||||
|
"sourceFile" : "web/src/main/java/click/kamil/web/JmsOrderListener.java",
|
||||||
|
"metadata" : {
|
||||||
|
"protocol" : "JMS",
|
||||||
|
"destination" : "order.process.queue"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "message",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"type" : "JMS",
|
||||||
|
"name" : "JMS: order.cancel.queue",
|
||||||
|
"className" : "click.kamil.web.JmsOrderListener",
|
||||||
|
"methodName" : "receiveCancelCommand",
|
||||||
|
"sourceFile" : "web/src/main/java/click/kamil/web/JmsOrderListener.java",
|
||||||
|
"metadata" : {
|
||||||
|
"protocol" : "JMS",
|
||||||
|
"destination" : "order.cancel.queue"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "message",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ ]
|
||||||
|
} ]
|
||||||
|
} ],
|
||||||
|
"callChains" : [ {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/orders/process",
|
||||||
|
"className" : "click.kamil.web.OrderController",
|
||||||
|
"methodName" : "processOrder",
|
||||||
|
"sourceFile" : "web/src/main/java/click/kamil/web/OrderController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/orders/process",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.web.OrderController.processOrder", "click.kamil.service.StateMachineServiceImpl.sendMessageWithOutbox", "click.kamil.service.StateMachineServiceImpl.sendMessage" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "OrderEvent.PROCESS",
|
||||||
|
"className" : "click.kamil.service.StateMachineServiceImpl",
|
||||||
|
"methodName" : "sendMessage",
|
||||||
|
"sourceFile" : "service/src/main/java/click/kamil/service/StateMachineServiceImpl.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 25
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : [ {
|
||||||
|
"sourceState" : "OrderState.NEW",
|
||||||
|
"targetState" : "OrderState.PROCESSING",
|
||||||
|
"event" : "OrderEvent.PROCESS"
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/orders/complete",
|
||||||
|
"className" : "click.kamil.web.OrderController",
|
||||||
|
"methodName" : "completeOrder",
|
||||||
|
"sourceFile" : "web/src/main/java/click/kamil/web/OrderController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/orders/complete",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.web.OrderController.completeOrder", "click.kamil.service.StateMachineServiceImpl.sendMessage" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "OrderEvent.COMPLETE",
|
||||||
|
"className" : "click.kamil.service.StateMachineServiceImpl",
|
||||||
|
"methodName" : "sendMessage",
|
||||||
|
"sourceFile" : "service/src/main/java/click/kamil/service/StateMachineServiceImpl.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 25
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : [ {
|
||||||
|
"sourceState" : "OrderState.PROCESSING",
|
||||||
|
"targetState" : "OrderState.COMPLETED",
|
||||||
|
"event" : "OrderEvent.COMPLETE"
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/orders/cancel",
|
||||||
|
"className" : "click.kamil.web.OrderController",
|
||||||
|
"methodName" : "cancelOrder",
|
||||||
|
"sourceFile" : "web/src/main/java/click/kamil/web/OrderController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/orders/cancel",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.web.OrderController.cancelOrder", "click.kamil.service.StateMachineServiceImpl.sendMessage" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "OrderEvent.CANCEL",
|
||||||
|
"className" : "click.kamil.service.StateMachineServiceImpl",
|
||||||
|
"methodName" : "sendMessage",
|
||||||
|
"sourceFile" : "service/src/main/java/click/kamil/service/StateMachineServiceImpl.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 25
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : [ {
|
||||||
|
"sourceState" : "OrderState.NEW",
|
||||||
|
"targetState" : "OrderState.CANCELLED",
|
||||||
|
"event" : "OrderEvent.CANCEL"
|
||||||
|
}, {
|
||||||
|
"sourceState" : "OrderState.PROCESSING",
|
||||||
|
"targetState" : "OrderState.CANCELLED",
|
||||||
|
"event" : "OrderEvent.CANCEL"
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "REST",
|
||||||
|
"name" : "POST /api/orders/functional-complete",
|
||||||
|
"className" : "click.kamil.web.OrderController",
|
||||||
|
"methodName" : "functionalCompleteOrder",
|
||||||
|
"sourceFile" : "web/src/main/java/click/kamil/web/OrderController.java",
|
||||||
|
"metadata" : {
|
||||||
|
"path" : "/api/orders/functional-complete",
|
||||||
|
"verb" : "POST"
|
||||||
|
},
|
||||||
|
"parameters" : [ ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.web.OrderController.functionalCompleteOrder", "click.kamil.web.OrderController.triggerTransitionFunction", "click.kamil.service.StateMachineServiceImpl.sendMessage" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "OrderEvent.COMPLETE",
|
||||||
|
"className" : "click.kamil.service.StateMachineServiceImpl",
|
||||||
|
"methodName" : "sendMessage",
|
||||||
|
"sourceFile" : "service/src/main/java/click/kamil/service/StateMachineServiceImpl.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 25
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : [ {
|
||||||
|
"sourceState" : "OrderState.PROCESSING",
|
||||||
|
"targetState" : "OrderState.COMPLETED",
|
||||||
|
"event" : "OrderEvent.COMPLETE"
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "RABBIT",
|
||||||
|
"name" : "RABBIT: order.custom.transition.queue",
|
||||||
|
"className" : "click.kamil.web.RabbitOrderListener",
|
||||||
|
"methodName" : "handleCustomTransition",
|
||||||
|
"sourceFile" : "web/src/main/java/click/kamil/web/RabbitOrderListener.java",
|
||||||
|
"metadata" : {
|
||||||
|
"protocol" : "RABBIT",
|
||||||
|
"destination" : "order.custom.transition.queue"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "payload",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.web.RabbitOrderListener.handleCustomTransition", "click.kamil.service.StateMachineServiceImpl.sendCustomMessage" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "OrderEvent.PROCESS",
|
||||||
|
"className" : "click.kamil.service.StateMachineServiceImpl",
|
||||||
|
"methodName" : "sendCustomMessage",
|
||||||
|
"sourceFile" : "service/src/main/java/click/kamil/service/StateMachineServiceImpl.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 78
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : [ {
|
||||||
|
"sourceState" : "OrderState.NEW",
|
||||||
|
"targetState" : "OrderState.PROCESSING",
|
||||||
|
"event" : "OrderEvent.PROCESS"
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "JMS",
|
||||||
|
"name" : "JMS: order.process.queue",
|
||||||
|
"className" : "click.kamil.web.JmsOrderListener",
|
||||||
|
"methodName" : "receiveProcessCommand",
|
||||||
|
"sourceFile" : "web/src/main/java/click/kamil/web/JmsOrderListener.java",
|
||||||
|
"metadata" : {
|
||||||
|
"protocol" : "JMS",
|
||||||
|
"destination" : "order.process.queue"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "message",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.web.JmsOrderListener.receiveProcessCommand", "click.kamil.service.StateMachineServiceImpl.sendMessageWithOutbox", "click.kamil.service.StateMachineServiceImpl.sendMessage" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "OrderEvent.PROCESS",
|
||||||
|
"className" : "click.kamil.service.StateMachineServiceImpl",
|
||||||
|
"methodName" : "sendMessage",
|
||||||
|
"sourceFile" : "service/src/main/java/click/kamil/service/StateMachineServiceImpl.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 25
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : [ {
|
||||||
|
"sourceState" : "OrderState.NEW",
|
||||||
|
"targetState" : "OrderState.PROCESSING",
|
||||||
|
"event" : "OrderEvent.PROCESS"
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"entryPoint" : {
|
||||||
|
"type" : "JMS",
|
||||||
|
"name" : "JMS: order.cancel.queue",
|
||||||
|
"className" : "click.kamil.web.JmsOrderListener",
|
||||||
|
"methodName" : "receiveCancelCommand",
|
||||||
|
"sourceFile" : "web/src/main/java/click/kamil/web/JmsOrderListener.java",
|
||||||
|
"metadata" : {
|
||||||
|
"protocol" : "JMS",
|
||||||
|
"destination" : "order.cancel.queue"
|
||||||
|
},
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "message",
|
||||||
|
"type" : "String",
|
||||||
|
"annotations" : [ ]
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"methodChain" : [ "click.kamil.web.JmsOrderListener.receiveCancelCommand", "click.kamil.service.StateMachineServiceImpl.sendMessageWithProvider" ],
|
||||||
|
"triggerPoint" : {
|
||||||
|
"event" : "OrderEvent.CANCEL",
|
||||||
|
"className" : "click.kamil.service.StateMachineServiceImpl",
|
||||||
|
"methodName" : "sendMessageWithProvider",
|
||||||
|
"sourceFile" : "service/src/main/java/click/kamil/service/StateMachineServiceImpl.java",
|
||||||
|
"sourceModule" : null,
|
||||||
|
"stateMachineId" : null,
|
||||||
|
"sourceState" : null,
|
||||||
|
"lineNumber" : 50
|
||||||
|
},
|
||||||
|
"contextMachineId" : null,
|
||||||
|
"matchedTransitions" : [ {
|
||||||
|
"sourceState" : "OrderState.NEW",
|
||||||
|
"targetState" : "OrderState.CANCELLED",
|
||||||
|
"event" : "OrderEvent.CANCEL"
|
||||||
|
}, {
|
||||||
|
"sourceState" : "OrderState.PROCESSING",
|
||||||
|
"targetState" : "OrderState.CANCELLED",
|
||||||
|
"event" : "OrderEvent.CANCEL"
|
||||||
|
} ]
|
||||||
|
} ],
|
||||||
|
"properties" : {
|
||||||
|
"default" : { }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name" : "click.kamil.domain.StateMachineConfig",
|
||||||
|
"renderChoicesAsDiamonds" : true,
|
||||||
|
"startStates" : [ "OrderState.NEW" ],
|
||||||
|
"transitions" : [ {
|
||||||
|
"type" : "EXTERNAL",
|
||||||
|
"sourceStates" : [ {
|
||||||
|
"rawName" : "OrderState.NEW",
|
||||||
|
"fullIdentifier" : "OrderState.NEW"
|
||||||
|
} ],
|
||||||
|
"targetStates" : [ {
|
||||||
|
"rawName" : "OrderState.PROCESSING",
|
||||||
|
"fullIdentifier" : "OrderState.PROCESSING"
|
||||||
|
} ],
|
||||||
|
"event" : {
|
||||||
|
"rawName" : "OrderEvent.PROCESS",
|
||||||
|
"fullIdentifier" : "OrderEvent.PROCESS"
|
||||||
|
},
|
||||||
|
"guard" : null,
|
||||||
|
"actions" : [ ],
|
||||||
|
"order" : null
|
||||||
|
}, {
|
||||||
|
"type" : "EXTERNAL",
|
||||||
|
"sourceStates" : [ {
|
||||||
|
"rawName" : "OrderState.PROCESSING",
|
||||||
|
"fullIdentifier" : "OrderState.PROCESSING"
|
||||||
|
} ],
|
||||||
|
"targetStates" : [ {
|
||||||
|
"rawName" : "OrderState.COMPLETED",
|
||||||
|
"fullIdentifier" : "OrderState.COMPLETED"
|
||||||
|
} ],
|
||||||
|
"event" : {
|
||||||
|
"rawName" : "OrderEvent.COMPLETE",
|
||||||
|
"fullIdentifier" : "OrderEvent.COMPLETE"
|
||||||
|
},
|
||||||
|
"guard" : null,
|
||||||
|
"actions" : [ ],
|
||||||
|
"order" : null
|
||||||
|
}, {
|
||||||
|
"type" : "EXTERNAL",
|
||||||
|
"sourceStates" : [ {
|
||||||
|
"rawName" : "OrderState.NEW",
|
||||||
|
"fullIdentifier" : "OrderState.NEW"
|
||||||
|
} ],
|
||||||
|
"targetStates" : [ {
|
||||||
|
"rawName" : "OrderState.CANCELLED",
|
||||||
|
"fullIdentifier" : "OrderState.CANCELLED"
|
||||||
|
} ],
|
||||||
|
"event" : {
|
||||||
|
"rawName" : "OrderEvent.CANCEL",
|
||||||
|
"fullIdentifier" : "OrderEvent.CANCEL"
|
||||||
|
},
|
||||||
|
"guard" : null,
|
||||||
|
"actions" : [ ],
|
||||||
|
"order" : null
|
||||||
|
}, {
|
||||||
|
"type" : "EXTERNAL",
|
||||||
|
"sourceStates" : [ {
|
||||||
|
"rawName" : "OrderState.PROCESSING",
|
||||||
|
"fullIdentifier" : "OrderState.PROCESSING"
|
||||||
|
} ],
|
||||||
|
"targetStates" : [ {
|
||||||
|
"rawName" : "OrderState.CANCELLED",
|
||||||
|
"fullIdentifier" : "OrderState.CANCELLED"
|
||||||
|
} ],
|
||||||
|
"event" : {
|
||||||
|
"rawName" : "OrderEvent.CANCEL",
|
||||||
|
"fullIdentifier" : "OrderEvent.CANCEL"
|
||||||
|
},
|
||||||
|
"guard" : null,
|
||||||
|
"actions" : [ ],
|
||||||
|
"order" : null
|
||||||
|
} ],
|
||||||
|
"endStates" : [ "OrderState.COMPLETED", "OrderState.CANCELLED" ]
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
@startuml
|
||||||
|
!pragma layout smetana
|
||||||
|
set separator none
|
||||||
|
hide empty description
|
||||||
|
hide stereotype
|
||||||
|
skinparam state {
|
||||||
|
BackgroundColor white
|
||||||
|
BorderColor #94a3b8
|
||||||
|
BorderThickness 1
|
||||||
|
FontName Inter
|
||||||
|
FontSize 9
|
||||||
|
FontStyle bold
|
||||||
|
RoundCorner 20
|
||||||
|
Padding 1
|
||||||
|
}
|
||||||
|
skinparam shadowing false
|
||||||
|
skinparam ArrowFontName JetBrains Mono
|
||||||
|
skinparam ArrowFontSize 8
|
||||||
|
skinparam ArrowColor #cbd5e1
|
||||||
|
skinparam ArrowThickness 1
|
||||||
|
skinparam dpi 110
|
||||||
|
skinparam svgLinkTarget _self
|
||||||
|
|
||||||
|
[*] --> OrderState.NEW
|
||||||
|
|
||||||
|
|
||||||
|
OrderState.NEW -[#1E90FF,bold]-> OrderState.PROCESSING <<external>> : OrderEvent.PROCESS
|
||||||
|
OrderState.PROCESSING -[#1E90FF,bold]-> OrderState.COMPLETED <<external>> : OrderEvent.COMPLETE
|
||||||
|
OrderState.NEW -[#1E90FF,bold]-> OrderState.CANCELLED <<external>> : OrderEvent.CANCEL
|
||||||
|
OrderState.PROCESSING -[#1E90FF,bold]-> OrderState.CANCELLED <<external>> : OrderEvent.CANCEL
|
||||||
|
|
||||||
|
OrderState.COMPLETED --> [*]
|
||||||
|
OrderState.CANCELLED --> [*]
|
||||||
|
@enduml
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="NEW">
|
||||||
|
<state id="NEW">
|
||||||
|
<transition target="PROCESSING" event="OrderEvent.PROCESS"/>
|
||||||
|
<transition target="CANCELLED" event="OrderEvent.CANCEL"/>
|
||||||
|
</state>
|
||||||
|
<state id="PROCESSING">
|
||||||
|
<transition target="COMPLETED" event="OrderEvent.COMPLETE"/>
|
||||||
|
<transition target="CANCELLED" event="OrderEvent.CANCEL"/>
|
||||||
|
</state>
|
||||||
|
<state id="COMPLETED">
|
||||||
|
</state>
|
||||||
|
<state id="CANCELLED">
|
||||||
|
</state>
|
||||||
|
</scxml>
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 223 KiB |
@@ -36,27 +36,27 @@ state States.STATE9 <<choice>>
|
|||||||
state States.STATE8 <<choice>>
|
state States.STATE8 <<choice>>
|
||||||
state States.STATE2 <<choice>>
|
state States.STATE2 <<choice>>
|
||||||
|
|
||||||
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> <<e_Events_EVENT1>> : Events.EVENT1
|
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> : Events.EVENT1
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> <<e_Events_EVENT2>> : Events.EVENT2
|
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> : Events.EVENT2
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> <<e_Events_EVENT3>> : Events.EVENT3
|
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> : Events.EVENT3
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> <<e_Events_EVENT4>> : Events.EVENT4
|
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> : Events.EVENT4
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> <<e_Events_EVENT5>> : Events.EVENT5
|
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> : Events.EVENT5
|
||||||
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> <<e_Events_EVENT6>> : Events.EVENT6
|
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> : Events.EVENT6
|
||||||
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> <<e_Events_EVENT7>> : Events.EVENT7
|
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> : Events.EVENT7
|
||||||
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> <<e_Events_EVENT8>> : Events.EVENT8
|
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> : Events.EVENT8
|
||||||
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> <<e_Events_EVENT9>> : Events.EVENT9
|
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> : Events.EVENT9
|
||||||
States.STATE10 -[#1E90FF,bold]-> States.STATE11 <<external>> <<e_Events_EVENT10>> : Events.EVENT10
|
States.STATE10 -[#1E90FF,bold]-> States.STATE11 <<external>> : Events.EVENT10
|
||||||
States.STATE11 -[#1E90FF,bold]-> States.STATE12 <<external>> <<e_Events_EVENT11>> : Events.EVENT11
|
States.STATE11 -[#1E90FF,bold]-> States.STATE12 <<external>> : Events.EVENT11
|
||||||
States.STATE12 -[#1E90FF,bold]-> States.STATE13 <<external>> <<e_Events_EVENT12>> : Events.EVENT12
|
States.STATE12 -[#1E90FF,bold]-> States.STATE13 <<external>> : Events.EVENT12
|
||||||
States.STATE13 -[#1E90FF,bold]-> States.STATE14 <<external>> <<e_Events_EVENT13>> : Events.EVENT13
|
States.STATE13 -[#1E90FF,bold]-> States.STATE14 <<external>> : Events.EVENT13
|
||||||
States.STATE14 -[#1E90FF,bold]-> States.STATE15 <<external>> <<e_Events_EVENT14>> : Events.EVENT14
|
States.STATE14 -[#1E90FF,bold]-> States.STATE15 <<external>> : Events.EVENT14
|
||||||
States.STATE15 -[#1E90FF,bold]-> States.STATE16 <<external>> <<e_Events_EVENT15>> : Events.EVENT15
|
States.STATE15 -[#1E90FF,bold]-> States.STATE16 <<external>> : Events.EVENT15
|
||||||
States.STATE1 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE1 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE2 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE3 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE4 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE5 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.STATEY <<external>> <<e_Events_EVENTY>> : Events.EVENTY
|
States.STATE4 -[#1E90FF,bold]-> States.STATEY <<external>> : Events.EVENTY
|
||||||
States.STATEY -[#FF6347,bold]-> States.STATEX <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
States.STATEY -[#FF6347,bold]-> States.STATEX <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
||||||
States.STATEY -[#FF6347,bold]-> States.STATEZ <<choice_type>> : (order=1)
|
States.STATEY -[#FF6347,bold]-> States.STATEZ <<choice_type>> : (order=1)
|
||||||
States.STATE16 -[#FF6347,bold]-> States.STATE17 <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
States.STATE16 -[#FF6347,bold]-> States.STATE17 <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
||||||
@@ -82,12 +82,12 @@ States.STATE9 -[#FF6347,bold]-> States.STATE7 <<choice_type>> : [guardVarEquals(
|
|||||||
States.STATE9 -[#FF6347,bold]-> States.STATE6 <<choice_type>> : (order=2)
|
States.STATE9 -[#FF6347,bold]-> States.STATE6 <<choice_type>> : (order=2)
|
||||||
States.STATE8 -[#FF6347,bold]-> States.STATE9 <<choice_type>> : [guardVarEquals("forward9")] (order=0)
|
States.STATE8 -[#FF6347,bold]-> States.STATE9 <<choice_type>> : [guardVarEquals("forward9")] (order=0)
|
||||||
States.STATE8 -[#FF6347,bold]-> States.STATE10 <<choice_type>> : (order=1)
|
States.STATE8 -[#FF6347,bold]-> States.STATE10 <<choice_type>> : (order=1)
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.STATE_EXTRA_1 <<external>> <<e_Events_EVENTX>> : Events.EVENTX
|
States.STATE2 -[#1E90FF,bold]-> States.STATE_EXTRA_1 <<external>> : Events.EVENTX
|
||||||
States.STATE2 -[#FF6347,bold]-> States.STATE1 <<choice_type>> : [guardEventHeaderEquals("header1","foo")] (order=0)
|
States.STATE2 -[#FF6347,bold]-> States.STATE1 <<choice_type>> : [guardEventHeaderEquals("header1","foo")] (order=0)
|
||||||
States.STATE2 -[#FF6347,bold]-> States.STATE_EXTRA_1 <<choice_type>> : (order=1)
|
States.STATE2 -[#FF6347,bold]-> States.STATE_EXTRA_1 <<choice_type>> : (order=1)
|
||||||
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.STATE_EXTRA_3 <<external>> <<e_Events_EVENTY>> : Events.EVENTY
|
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.STATE_EXTRA_3 <<external>> : Events.EVENTY
|
||||||
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL_2>> : Events.EVENT_CANCEL_2
|
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL_2
|
||||||
States.STATE_EXTRA_2 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL_2>> : Events.EVENT_CANCEL_2
|
States.STATE_EXTRA_2 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL_2
|
||||||
|
|
||||||
States.STATEZ --> [*]
|
States.STATEZ --> [*]
|
||||||
@enduml
|
@enduml
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 211 KiB After Width: | Height: | Size: 211 KiB |
@@ -35,27 +35,27 @@ state States.STATE14 <<choice>>
|
|||||||
state States.STATE9 <<choice>>
|
state States.STATE9 <<choice>>
|
||||||
state States.STATE8 <<choice>>
|
state States.STATE8 <<choice>>
|
||||||
|
|
||||||
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> <<e_Events_EVENT1>> : Events.EVENT1
|
States.STATE1 -[#1E90FF,bold]-> States.STATE2 <<external>> : Events.EVENT1
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> <<e_Events_EVENT2>> : Events.EVENT2
|
States.STATE2 -[#1E90FF,bold]-> States.STATE3 <<external>> : Events.EVENT2
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> <<e_Events_EVENT3>> : Events.EVENT3
|
States.STATE3 -[#1E90FF,bold]-> States.STATE4 <<external>> : Events.EVENT3
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> <<e_Events_EVENT4>> : Events.EVENT4
|
States.STATE4 -[#1E90FF,bold]-> States.STATE5 <<external>> : Events.EVENT4
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> <<e_Events_EVENT5>> : Events.EVENT5
|
States.STATE5 -[#1E90FF,bold]-> States.STATE6 <<external>> : Events.EVENT5
|
||||||
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> <<e_Events_EVENT6>> : Events.EVENT6
|
States.STATE6 -[#1E90FF,bold]-> States.STATE7 <<external>> : Events.EVENT6
|
||||||
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> <<e_Events_EVENT7>> : Events.EVENT7
|
States.STATE7 -[#1E90FF,bold]-> States.STATE8 <<external>> : Events.EVENT7
|
||||||
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> <<e_Events_EVENT8>> : Events.EVENT8
|
States.STATE8 -[#1E90FF,bold]-> States.STATE9 <<external>> : Events.EVENT8
|
||||||
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> <<e_Events_EVENT9>> : Events.EVENT9
|
States.STATE9 -[#1E90FF,bold]-> States.STATE10 <<external>> : Events.EVENT9
|
||||||
States.STATE10 -[#1E90FF,bold]-> States.STATE11 <<external>> <<e_Events_EVENT10>> : Events.EVENT10
|
States.STATE10 -[#1E90FF,bold]-> States.STATE11 <<external>> : Events.EVENT10
|
||||||
States.STATE11 -[#1E90FF,bold]-> States.STATE12 <<external>> <<e_Events_EVENT11>> : Events.EVENT11
|
States.STATE11 -[#1E90FF,bold]-> States.STATE12 <<external>> : Events.EVENT11
|
||||||
States.STATE12 -[#1E90FF,bold]-> States.STATE13 <<external>> <<e_Events_EVENT12>> : Events.EVENT12
|
States.STATE12 -[#1E90FF,bold]-> States.STATE13 <<external>> : Events.EVENT12
|
||||||
States.STATE13 -[#1E90FF,bold]-> States.STATE14 <<external>> <<e_Events_EVENT13>> : Events.EVENT13
|
States.STATE13 -[#1E90FF,bold]-> States.STATE14 <<external>> : Events.EVENT13
|
||||||
States.STATE14 -[#1E90FF,bold]-> States.STATE15 <<external>> <<e_Events_EVENT14>> : Events.EVENT14
|
States.STATE14 -[#1E90FF,bold]-> States.STATE15 <<external>> : Events.EVENT14
|
||||||
States.STATE15 -[#1E90FF,bold]-> States.STATE16 <<external>> <<e_Events_EVENT15>> : Events.EVENT15
|
States.STATE15 -[#1E90FF,bold]-> States.STATE16 <<external>> : Events.EVENT15
|
||||||
States.STATE1 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE1 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE2 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE2 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE3 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE3 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE4 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE5 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE4 -[#1E90FF,bold]-> States.STATEY <<external>> <<e_Events_EVENTY>> : Events.EVENTY
|
States.STATE4 -[#1E90FF,bold]-> States.STATEY <<external>> : Events.EVENTY
|
||||||
States.STATEY -[#FF6347,bold]-> States.STATEX <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
States.STATEY -[#FF6347,bold]-> States.STATEX <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
||||||
States.STATEY -[#FF6347,bold]-> States.STATEZ <<choice_type>> : (order=1)
|
States.STATEY -[#FF6347,bold]-> States.STATEZ <<choice_type>> : (order=1)
|
||||||
States.STATE16 -[#FF6347,bold]-> States.STATE17 <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
States.STATE16 -[#FF6347,bold]-> States.STATE17 <<choice_type>> : [guardVarEquals("value1")] (order=0)
|
||||||
@@ -81,9 +81,9 @@ States.STATE9 -[#FF6347,bold]-> States.STATE7 <<choice_type>> : [guardVarEquals(
|
|||||||
States.STATE9 -[#FF6347,bold]-> States.STATE6 <<choice_type>> : (order=2)
|
States.STATE9 -[#FF6347,bold]-> States.STATE6 <<choice_type>> : (order=2)
|
||||||
States.STATE8 -[#FF6347,bold]-> States.STATE9 <<choice_type>> : [guardVarEquals("forward9")] (order=0)
|
States.STATE8 -[#FF6347,bold]-> States.STATE9 <<choice_type>> : [guardVarEquals("forward9")] (order=0)
|
||||||
States.STATE8 -[#FF6347,bold]-> States.STATE10 <<choice_type>> : (order=1)
|
States.STATE8 -[#FF6347,bold]-> States.STATE10 <<choice_type>> : (order=1)
|
||||||
States.STATE5 -[#1E90FF,bold]-> States.STATE_EXTRA_1 <<external>> <<e_Events_EVENTX>> : Events.EVENTX
|
States.STATE5 -[#1E90FF,bold]-> States.STATE_EXTRA_1 <<external>> : Events.EVENTX
|
||||||
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL>> : Events.EVENT_CANCEL
|
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL
|
||||||
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <<external>> <<e_Events_EVENT_CANCEL_2>> : Events.EVENT_CANCEL_2
|
States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <<external>> : Events.EVENT_CANCEL_2
|
||||||
|
|
||||||
States.STATEZ --> [*]
|
States.STATEZ --> [*]
|
||||||
@enduml
|
@enduml
|
||||||
|
|||||||
@@ -576,7 +576,7 @@
|
|||||||
if (!c.matchedTransitions || c.matchedTransitions.length === 0) return false;
|
if (!c.matchedTransitions || c.matchedTransitions.length === 0) return false;
|
||||||
return c.matchedTransitions.some(t => {
|
return c.matchedTransitions.some(t => {
|
||||||
const cEventStr = typeof t.event === 'object' ? (t.event.fullIdentifier || t.event.rawName || t.event) : t.event;
|
const cEventStr = typeof t.event === 'object' ? (t.event.fullIdentifier || t.event.rawName || t.event) : t.event;
|
||||||
return normalize(cEventStr) === name;
|
return normalize(cEventStr) === normalize(name);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -631,7 +631,7 @@
|
|||||||
let html = `<div style="font-size:0.65rem; font-weight:700; color:#94a3b8; margin-top:8px; margin-bottom:4px; text-transform:uppercase;">Input Data</div>`;
|
let html = `<div style="font-size:0.65rem; font-weight:700; color:#94a3b8; margin-top:8px; margin-bottom:4px; text-transform:uppercase;">Input Data</div>`;
|
||||||
html += `<div class="payload-box">`;
|
html += `<div class="payload-box">`;
|
||||||
params.forEach(p => {
|
params.forEach(p => {
|
||||||
const annotation = (p.annotations || []).find(a => a.endsWith("RequestBody") || a.endsWith("PathVariable") || a.endsWith("RequestParam"));
|
const annotation = (p.annotations || []).find(a => a.endsWith("RequestBody") || a.endsWith("PathVariable") || a.endsWith("RequestParam") || a.endsWith("Payload") || a.endsWith("Header") || a.endsWith("Headers"));
|
||||||
const cleanAnn = annotation ? "@" + annotation.substring(annotation.lastIndexOf('.') + 1) : "";
|
const cleanAnn = annotation ? "@" + annotation.substring(annotation.lastIndexOf('.') + 1) : "";
|
||||||
html += `<div class="payload-param">
|
html += `<div class="payload-param">
|
||||||
<span style="color:#f43f5e; font-size:0.65rem; font-weight:bold;">${cleanAnn}</span>
|
<span style="color:#f43f5e; font-size:0.65rem; font-weight:bold;">${cleanAnn}</span>
|
||||||
|
|||||||
@@ -81,6 +81,14 @@ public class HtmlExporterTest {
|
|||||||
|
|
||||||
// 7. Assertions - Surgical SVG Identification
|
// 7. Assertions - Surgical SVG Identification
|
||||||
// Every event should be wrapped in an identifying hyperlink for robust JS selection
|
// Every event should be wrapped in an identifying hyperlink for robust JS selection
|
||||||
|
java.nio.file.Files.writeString(java.nio.file.Paths.get("debug_html.html"), html);
|
||||||
|
|
||||||
|
click.kamil.springstatemachineexporter.exporter.ExportOptions plantUmlOptions = click.kamil.springstatemachineexporter.exporter.ExportOptions.builder()
|
||||||
|
.embedIdentifiers(true)
|
||||||
|
.build();
|
||||||
|
click.kamil.springstatemachineexporter.exporter.PlantUml pumlExporter = new click.kamil.springstatemachineexporter.exporter.PlantUml();
|
||||||
|
java.nio.file.Files.writeString(java.nio.file.Paths.get("debug_puml.puml"), pumlExporter.export(result, plantUmlOptions));
|
||||||
|
|
||||||
assertThat(html).contains("__CREATE");
|
assertThat(html).contains("__CREATE");
|
||||||
assertThat(html).contains("__ASSIGN");
|
assertThat(html).contains("__ASSIGN");
|
||||||
assertThat(html).contains("__CLOSE_TICKET");
|
assertThat(html).contains("__CLOSE_TICKET");
|
||||||
|
|||||||
33
state_machines/complex_multi_module_sm/.gitignore
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
HELP.md
|
||||||
|
target/
|
||||||
|
.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
33
state_machines/complex_multi_module_sm/domain/.gitignore
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
HELP.md
|
||||||
|
target/
|
||||||
|
.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
24
state_machines/complex_multi_module_sm/domain/pom.xml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>click.kamil.complex</groupId>
|
||||||
|
<artifactId>complex-multi-module-sm</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>domain</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.statemachine</groupId>
|
||||||
|
<artifactId>spring-statemachine-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package click.kamil.domain;
|
||||||
|
|
||||||
|
import org.springframework.messaging.support.GenericMessage;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class CustomStateMachineMessage<T, P> extends GenericMessage<T> {
|
||||||
|
|
||||||
|
private final P customPayload;
|
||||||
|
|
||||||
|
public CustomStateMachineMessage(T payload, P customPayload) {
|
||||||
|
super(payload);
|
||||||
|
this.customPayload = customPayload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomStateMachineMessage(T payload, Map<String, Object> headers, P customPayload) {
|
||||||
|
super(payload, headers);
|
||||||
|
this.customPayload = customPayload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public P getCustomPayload() {
|
||||||
|
return customPayload;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package click.kamil.domain;
|
||||||
|
|
||||||
|
public interface IEvent {
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package click.kamil.domain;
|
||||||
|
|
||||||
|
public interface IState {
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package click.kamil.domain;
|
||||||
|
|
||||||
|
public enum OrderEvent implements IEvent {
|
||||||
|
PROCESS, COMPLETE, CANCEL
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package click.kamil.domain;
|
||||||
|
|
||||||
|
public enum OrderState implements IState {
|
||||||
|
NEW, PROCESSING, COMPLETED, CANCELLED
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package click.kamil.domain;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.statemachine.config.EnableStateMachine;
|
||||||
|
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
|
||||||
|
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
|
||||||
|
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableStateMachine
|
||||||
|
public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<OrderState, OrderEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(StateMachineStateConfigurer<OrderState, OrderEvent> states) throws Exception {
|
||||||
|
states
|
||||||
|
.withStates()
|
||||||
|
.initial(OrderState.NEW)
|
||||||
|
.states(EnumSet.allOf(OrderState.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(StateMachineTransitionConfigurer<OrderState, OrderEvent> transitions) throws Exception {
|
||||||
|
transitions
|
||||||
|
.withExternal()
|
||||||
|
.source(OrderState.NEW).target(OrderState.PROCESSING).event(OrderEvent.PROCESS)
|
||||||
|
.and()
|
||||||
|
.withExternal()
|
||||||
|
.source(OrderState.PROCESSING).target(OrderState.COMPLETED).event(OrderEvent.COMPLETE)
|
||||||
|
.and()
|
||||||
|
.withExternal()
|
||||||
|
.source(OrderState.NEW).target(OrderState.CANCELLED).event(OrderEvent.CANCEL)
|
||||||
|
.and()
|
||||||
|
.withExternal()
|
||||||
|
.source(OrderState.PROCESSING).target(OrderState.CANCELLED).event(OrderEvent.CANCEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
51
state_machines/complex_multi_module_sm/pom.xml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>click.kamil.complex</groupId>
|
||||||
|
<artifactId>complex-multi-module-sm</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>domain</module>
|
||||||
|
<module>service</module>
|
||||||
|
<module>web</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<spring-boot.version>3.2.0</spring-boot.version>
|
||||||
|
<spring-statemachine.version>3.2.0</spring-statemachine.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.statemachine</groupId>
|
||||||
|
<artifactId>spring-statemachine-core</artifactId>
|
||||||
|
<version>${spring-statemachine.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>click.kamil.complex</groupId>
|
||||||
|
<artifactId>domain</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>click.kamil.complex</groupId>
|
||||||
|
<artifactId>service</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
</project>
|
||||||
33
state_machines/complex_multi_module_sm/service/.gitignore
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
HELP.md
|
||||||
|
target/
|
||||||
|
.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
32
state_machines/complex_multi_module_sm/service/pom.xml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>click.kamil.complex</groupId>
|
||||||
|
<artifactId>complex-multi-module-sm</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>service</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>click.kamil.complex</groupId>
|
||||||
|
<artifactId>domain</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.statemachine</groupId>
|
||||||
|
<artifactId>spring-statemachine-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-tx</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package click.kamil.service;
|
||||||
|
|
||||||
|
import click.kamil.domain.IEvent;
|
||||||
|
|
||||||
|
public interface OutboxAction<T extends IEvent> {
|
||||||
|
void onCommit(T event);
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package click.kamil.service;
|
||||||
|
|
||||||
|
import click.kamil.domain.IEvent;
|
||||||
|
import click.kamil.domain.IState;
|
||||||
|
|
||||||
|
public interface StateMachineService {
|
||||||
|
<S extends IState, T extends IEvent> void sendMessage(T event);
|
||||||
|
|
||||||
|
<S extends IState, T extends IEvent, A extends OutboxAction<T>> void sendMessageWithOutbox(T event, A action);
|
||||||
|
|
||||||
|
// Quirky pattern: Bounded generic supplier instead of reflection
|
||||||
|
<T extends click.kamil.domain.OrderEvent> void sendMessageWithProvider(java.util.function.Supplier<T> eventProvider);
|
||||||
|
|
||||||
|
// Quirky pattern 2: Generic Varargs
|
||||||
|
<T extends IEvent> void sendEventsVarargs(T... events);
|
||||||
|
|
||||||
|
// Functional quirks: passing functions and method references
|
||||||
|
<T extends IEvent> void executeFunctionalTransition(java.util.function.Supplier<T> eventSupplier,
|
||||||
|
java.util.function.Function<T, Void> transitionAction);
|
||||||
|
|
||||||
|
// Child class of Spring's GenericMessage with a generic payload
|
||||||
|
<T extends click.kamil.domain.OrderEvent, P> void sendCustomMessage(click.kamil.domain.CustomStateMachineMessage<T, P> customMessage);
|
||||||
|
|
||||||
|
// Quirky pattern 3: Multiple generic bounds (Intersection Types)
|
||||||
|
<T extends IEvent & java.io.Serializable & Cloneable> T processQuirkyEvent(T event);
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package click.kamil.service;
|
||||||
|
|
||||||
|
import click.kamil.domain.IEvent;
|
||||||
|
import click.kamil.domain.IState;
|
||||||
|
import click.kamil.domain.OrderEvent;
|
||||||
|
import click.kamil.domain.OrderState;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.messaging.support.MessageBuilder;
|
||||||
|
import org.springframework.statemachine.StateMachine;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.transaction.support.TransactionSynchronization;
|
||||||
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class StateMachineServiceImpl implements StateMachineService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private StateMachine<OrderState, OrderEvent> stateMachine;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <S extends IState, T extends IEvent> void sendMessage(T event) {
|
||||||
|
if (event instanceof OrderEvent) {
|
||||||
|
stateMachine.sendEvent(Mono.just(MessageBuilder.withPayload((OrderEvent) event).build())).subscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public <S extends IState, T extends IEvent, A extends OutboxAction<T>> void sendMessageWithOutbox(T event, A action) {
|
||||||
|
sendMessage(event);
|
||||||
|
|
||||||
|
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||||
|
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
||||||
|
@Override
|
||||||
|
public void afterCommit() {
|
||||||
|
action.onCommit(event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
action.onCommit(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends OrderEvent> void sendMessageWithProvider(java.util.function.Supplier<T> eventProvider) {
|
||||||
|
T event = eventProvider.get();
|
||||||
|
if (event != null) {
|
||||||
|
stateMachine.sendEvent(Mono.just(MessageBuilder.withPayload((OrderEvent) event).build())).subscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SafeVarargs
|
||||||
|
public final <T extends IEvent> void sendEventsVarargs(T... events) {
|
||||||
|
for (T event : events) {
|
||||||
|
sendMessage(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends IEvent> void executeFunctionalTransition(java.util.function.Supplier<T> eventSupplier,
|
||||||
|
java.util.function.Function<T, Void> transitionAction) {
|
||||||
|
// Resolve the event from the getter / supplier function
|
||||||
|
T event = eventSupplier.get();
|
||||||
|
// Apply the transition via the provided function / method reference
|
||||||
|
transitionAction.apply(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends OrderEvent, P> void sendCustomMessage(click.kamil.domain.CustomStateMachineMessage<T, P> customMessage) {
|
||||||
|
// Because CustomStateMachineMessage extends GenericMessage<T> and implements Message<T>,
|
||||||
|
// we can pass it directly to the state machine as long as T resolves to OrderEvent!
|
||||||
|
|
||||||
|
// We cast it to Message<OrderEvent> to satisfy Mono's strict type requirements
|
||||||
|
org.springframework.messaging.Message<OrderEvent> msg = (org.springframework.messaging.Message<OrderEvent>) customMessage;
|
||||||
|
stateMachine.sendEvent(Mono.just(msg)).subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends IEvent & java.io.Serializable & Cloneable> T processQuirkyEvent(T event) {
|
||||||
|
// Quirky pattern 3: Multiple bounds, returning the same generic type
|
||||||
|
sendMessage(event);
|
||||||
|
return event; // returns something that is guaranteed to be IEvent, Serializable, AND Cloneable
|
||||||
|
}
|
||||||
|
}
|
||||||
33
state_machines/complex_multi_module_sm/web/.gitignore
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
HELP.md
|
||||||
|
target/
|
||||||
|
.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
32
state_machines/complex_multi_module_sm/web/pom.xml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>click.kamil.complex</groupId>
|
||||||
|
<artifactId>complex-multi-module-sm</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>web</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>click.kamil.complex</groupId>
|
||||||
|
<artifactId>service</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-activemq</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package click.kamil.web;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.jms.annotation.EnableJms;
|
||||||
|
|
||||||
|
@SpringBootApplication(scanBasePackages = "click.kamil")
|
||||||
|
@EnableJms
|
||||||
|
public class Application {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(Application.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package click.kamil.web;
|
||||||
|
|
||||||
|
import click.kamil.domain.OrderEvent;
|
||||||
|
import click.kamil.service.StateMachineService;
|
||||||
|
import org.springframework.jms.annotation.JmsListener;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class JmsOrderListener {
|
||||||
|
|
||||||
|
private final StateMachineService stateMachineService;
|
||||||
|
|
||||||
|
// Constructor injection
|
||||||
|
public JmsOrderListener(StateMachineService stateMachineService) {
|
||||||
|
this.stateMachineService = stateMachineService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JmsListener(destination = "order.process.queue")
|
||||||
|
public void receiveProcessCommand(String message) {
|
||||||
|
System.out.println("Received JMS message: " + message);
|
||||||
|
stateMachineService.sendMessageWithOutbox(OrderEvent.PROCESS, event -> {
|
||||||
|
System.out.println("JMS Triggered Faulty Outbox Action executed post-commit for event: " + event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@JmsListener(destination = "order.cancel.queue")
|
||||||
|
public void receiveCancelCommand(String message) {
|
||||||
|
System.out.println("Received JMS message: " + message);
|
||||||
|
stateMachineService.sendMessageWithProvider(() -> OrderEvent.CANCEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package click.kamil.web;
|
||||||
|
|
||||||
|
import click.kamil.domain.OrderEvent;
|
||||||
|
import click.kamil.service.StateMachineService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/orders")
|
||||||
|
public class OrderController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private StateMachineService stateMachineService;
|
||||||
|
|
||||||
|
@PostMapping("/process")
|
||||||
|
public String processOrder() {
|
||||||
|
stateMachineService.sendMessageWithOutbox(OrderEvent.PROCESS, event -> {
|
||||||
|
System.out.println("Faulty Outbox Action executed post-commit for event: " + event);
|
||||||
|
});
|
||||||
|
return "Order process event sent within transaction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/complete")
|
||||||
|
public String completeOrder() {
|
||||||
|
stateMachineService.sendMessage(OrderEvent.COMPLETE);
|
||||||
|
return "Order complete event sent";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/cancel")
|
||||||
|
public String cancelOrder() {
|
||||||
|
stateMachineService.sendMessage(OrderEvent.CANCEL);
|
||||||
|
return "Order cancel event sent";
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Functional Quirks for Static Analysis ---
|
||||||
|
|
||||||
|
// A getter returning a specific ENUM constant
|
||||||
|
public OrderEvent getCompleteEvent() {
|
||||||
|
return OrderEvent.COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A specific function that performs the transition
|
||||||
|
public Void triggerTransitionFunction(click.kamil.domain.IEvent event) {
|
||||||
|
stateMachineService.sendMessage(event);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/functional-complete")
|
||||||
|
public String functionalCompleteOrder() {
|
||||||
|
// Pass the getter and the transition applier as method references
|
||||||
|
stateMachineService.executeFunctionalTransition(
|
||||||
|
this::getCompleteEvent,
|
||||||
|
this::triggerTransitionFunction
|
||||||
|
);
|
||||||
|
return "Functional complete event triggered via method references";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package click.kamil.web;
|
||||||
|
|
||||||
|
import click.kamil.domain.CustomStateMachineMessage;
|
||||||
|
import click.kamil.domain.OrderEvent;
|
||||||
|
import click.kamil.service.StateMachineService;
|
||||||
|
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class RabbitOrderListener {
|
||||||
|
|
||||||
|
private final StateMachineService stateMachineService;
|
||||||
|
|
||||||
|
// Constructor Injection
|
||||||
|
public RabbitOrderListener(StateMachineService stateMachineService) {
|
||||||
|
this.stateMachineService = stateMachineService;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listens to RabbitMQ, constructs the custom class, triggers a state transition
|
||||||
|
@RabbitListener(queues = "order.custom.transition.queue")
|
||||||
|
public void handleCustomTransition(String payload) {
|
||||||
|
System.out.println("Received RabbitMQ message: " + payload);
|
||||||
|
|
||||||
|
// Construct our custom event containing the generic payload and the enum state
|
||||||
|
CustomStateMachineMessage<OrderEvent, String> customMessage =
|
||||||
|
new CustomStateMachineMessage<>(OrderEvent.PROCESS, "My Rabbit Custom Payload: " + payload);
|
||||||
|
|
||||||
|
// Push the custom event into the state machine to perform the transition
|
||||||
|
stateMachineService.sendCustomMessage(customMessage);
|
||||||
|
System.out.println("Triggered PROCESS transition via custom message over RabbitMQ");
|
||||||
|
}
|
||||||
|
}
|
||||||