Compare commits
14 Commits
89736a4aa1
...
ai-branch-
| Author | SHA1 | Date | |
|---|---|---|---|
| bb97285906 | |||
| 9a5f122bd2 | |||
| a7bf07e8b2 | |||
| 4f8c35adef | |||
| 31adae0a4b | |||
| 2caaec5419 | |||
| 56588a835d | |||
| 0a8f9720c9 | |||
| 6472f01026 | |||
| e041cb9a80 | |||
| 9bea5c4687 | |||
| 475084aed4 | |||
| 28df9fc99f | |||
| e3dd26c0d4 |
@@ -20,3 +20,5 @@ include ':state_machines:enterprise_order_system'
|
||||
include ':state_machines:multi_module_sample:api-module'
|
||||
include ':state_machines:multi_module_sample:core-module'
|
||||
include ':state_machines:state_machine_enterprise'
|
||||
include 'state_machine_exporter_kotlin'
|
||||
include ':state_machines:kotlin_simple_state_machine'
|
||||
|
||||
@@ -32,6 +32,9 @@ dependencies {
|
||||
// deps for parsing java AST
|
||||
implementation 'org.eclipse.jdt:org.eclipse.jdt.core:3.36.0'
|
||||
|
||||
// Kotlin plugin integration via ServiceLoader
|
||||
runtimeOnly project(':state_machine_exporter_kotlin')
|
||||
|
||||
// Jackson for JSON support
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.1'
|
||||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.17.1'
|
||||
@@ -60,9 +63,3 @@ task runGolden(type: JavaExec) {
|
||||
classpath = sourceSets.test.runtimeClasspath
|
||||
workingDir = rootProject.projectDir
|
||||
}
|
||||
|
||||
task runGoldenFixed(type: JavaExec) {
|
||||
mainClass = "click.kamil.springstatemachineexporter.GoldenUpdater"
|
||||
classpath = sourceSets.test.runtimeClasspath
|
||||
workingDir = rootProject.projectDir
|
||||
}
|
||||
|
||||
@@ -6,11 +6,22 @@ import java.util.List;
|
||||
|
||||
public class HeuristicEventMatchingEngine implements EventMatchingEngine {
|
||||
|
||||
private final java.util.Map<java.util.Map.Entry<Event, TriggerPoint>, Boolean> matchesCache = new java.util.HashMap<>();
|
||||
|
||||
@Override
|
||||
public boolean matches(Event stateMachineEvent, TriggerPoint triggerPoint) {
|
||||
if (stateMachineEvent == null || triggerPoint == null || triggerPoint.getEvent() == null) {
|
||||
return false;
|
||||
}
|
||||
java.util.Map.Entry<Event, TriggerPoint> cacheKey = new java.util.AbstractMap.SimpleImmutableEntry<>(stateMachineEvent, triggerPoint);
|
||||
if (matchesCache.containsKey(cacheKey)) return matchesCache.get(cacheKey);
|
||||
|
||||
boolean result = calculateMatches(stateMachineEvent, triggerPoint);
|
||||
matchesCache.put(cacheKey, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean calculateMatches(Event stateMachineEvent, TriggerPoint triggerPoint) {
|
||||
|
||||
String rawTriggerEvent = triggerPoint.getEvent();
|
||||
String smEventRaw = stateMachineEvent.fullIdentifier() != null ? stateMachineEvent.fullIdentifier() : stateMachineEvent.rawName();
|
||||
@@ -58,7 +69,22 @@ public class HeuristicEventMatchingEngine implements EventMatchingEngine {
|
||||
}
|
||||
|
||||
if (hasPolyMatch) return true;
|
||||
if (polyEvents.isEmpty() && isWildcard) return true;
|
||||
if (polyEvents.isEmpty() && isWildcard) {
|
||||
String eventTypeFqn = triggerPoint.getEventTypeFqn();
|
||||
if (eventTypeFqn != null && smEventRaw.contains(".")) {
|
||||
String smEventClass = smEventRaw.substring(0, smEventRaw.lastIndexOf('.'));
|
||||
if (smEventClass.equals(eventTypeFqn)) {
|
||||
return true;
|
||||
}
|
||||
String simpleEventType = eventTypeFqn.contains(".") ? eventTypeFqn.substring(eventTypeFqn.lastIndexOf('.') + 1) : eventTypeFqn;
|
||||
String simpleSmClass = smEventClass.contains(".") ? smEventClass.substring(smEventClass.lastIndexOf('.') + 1) : smEventClass;
|
||||
if (simpleEventType.equalsIgnoreCase(simpleSmClass)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rawTriggerEvent.contains(".") && smEventRaw.contains(".")) {
|
||||
if (smEventRaw.equals(rawTriggerEvent) || smEventRaw.endsWith("." + rawTriggerEvent) || rawTriggerEvent.endsWith("." + smEventRaw)) {
|
||||
|
||||
@@ -43,10 +43,12 @@ public class SymbolicPathValueEstimator implements PathValueEstimator {
|
||||
|
||||
click.kamil.springstatemachineexporter.analysis.resolver.ConstantResolver resolver = new click.kamil.springstatemachineexporter.analysis.resolver.ConstantResolver();
|
||||
|
||||
if (caller != null) {
|
||||
String callerVal = resolver.resolve(caller, context);
|
||||
if (callerVal != null && !callerVal.isEmpty()) {
|
||||
addValue(collectedConstants, callerVal);
|
||||
}
|
||||
}
|
||||
|
||||
String argVal = resolver.resolve(arg, context);
|
||||
if (argVal != null && !argVal.isEmpty()) {
|
||||
|
||||
@@ -27,6 +27,7 @@ public class TriggerPoint {
|
||||
private final java.util.List<String> polymorphicEvents; // NEW: stores concrete events resolved via deep polymorphism
|
||||
private final boolean external;
|
||||
private final String constraint;
|
||||
private final boolean ambiguous;
|
||||
|
||||
public TriggerPoint(
|
||||
String event,
|
||||
@@ -41,7 +42,8 @@ public class TriggerPoint {
|
||||
String eventTypeFqn,
|
||||
java.util.List<String> polymorphicEvents,
|
||||
boolean external,
|
||||
String constraint) {
|
||||
String constraint,
|
||||
boolean ambiguous) {
|
||||
this.className = className;
|
||||
this.methodName = methodName;
|
||||
this.sourceFile = sourceFile;
|
||||
@@ -53,9 +55,6 @@ public class TriggerPoint {
|
||||
this.eventTypeFqn = eventTypeFqn;
|
||||
this.event = qualifyEvent(event, eventTypeFqn);
|
||||
if (polymorphicEvents != null) {
|
||||
if (polymorphicEvents.contains("CustomEvents.ALPHA")) {
|
||||
new Exception("DEBUG TriggerPoint constructed with CustomEvents.ALPHA!").printStackTrace(System.out);
|
||||
}
|
||||
this.polymorphicEvents = polymorphicEvents.stream()
|
||||
.map(pe -> qualifyEvent(pe, eventTypeFqn))
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
@@ -64,10 +63,10 @@ public class TriggerPoint {
|
||||
}
|
||||
this.external = external;
|
||||
this.constraint = constraint;
|
||||
this.ambiguous = ambiguous;
|
||||
}
|
||||
|
||||
private static String qualifyEvent(String e, String eventTypeFqn) {
|
||||
System.out.println("qualifyEvent e=" + e + " eventTypeFqn=" + eventTypeFqn);
|
||||
if (e == null || eventTypeFqn == null || e.isEmpty()) {
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -96,9 +96,9 @@ public class ConstantResolver {
|
||||
|
||||
// Fallback for unresolved AST nodes
|
||||
if (mi.getExpression() instanceof QualifiedName qn) {
|
||||
System.out.println("RETURNING qn name: " + qn.getName().getIdentifier()); return qn.getName().getIdentifier();
|
||||
return qn.getName().getIdentifier();
|
||||
} else if (mi.getExpression() instanceof SimpleName sn) {
|
||||
System.out.println("RETURNING sn name: " + sn.getIdentifier()); return sn.getIdentifier();
|
||||
return sn.getIdentifier();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,9 +239,8 @@ public class ConstantResolver {
|
||||
}
|
||||
|
||||
try {
|
||||
java.util.Map<String, String> localVars = new java.util.HashMap<>(prebuiltLocals);
|
||||
java.util.Set<String> declaredLocals = new java.util.HashSet<>(prebuiltLocals.keySet());
|
||||
return evaluateBody(md.getBody(), localVars, declaredLocals, context, visited);
|
||||
return evaluateBody(md.getBody(), prebuiltLocals, declaredLocals, context, visited);
|
||||
} finally {
|
||||
visited.remove(methodFqn);
|
||||
}
|
||||
@@ -267,15 +266,61 @@ public class ConstantResolver {
|
||||
String varName = fragment.getName().getIdentifier();
|
||||
declaredLocals.add(varName);
|
||||
if (fragment.getInitializer() != null) {
|
||||
String rhsVal = resolveExpressionWithParams(fragment.getInitializer(), localVars);
|
||||
String rhsVal = resolveExpressionWithParams(fragment.getInitializer(), localVars, context);
|
||||
if (rhsVal == null) rhsVal = resolveInternal(fragment.getInitializer(), context, visited);
|
||||
if (rhsVal != null) localVars.put(varName, rhsVal);
|
||||
if (rhsVal != null) {
|
||||
localVars.put(varName, rhsVal);
|
||||
} else {
|
||||
java.util.Map<String, String> bFields = extractBuilderFields(fragment.getInitializer(), localVars, context, visited);
|
||||
if (bFields != null) {
|
||||
for (java.util.Map.Entry<String, String> e : bFields.entrySet()) {
|
||||
localVars.put(varName + "." + e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.visit(vds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(org.eclipse.jdt.core.dom.MethodInvocation node) {
|
||||
MethodDeclaration sideEffectMd = findInvokedMethod(node, context);
|
||||
if (sideEffectMd != null && sideEffectMd.getBody() != null) {
|
||||
TypeDeclaration currentTd = findEnclosingType(sideEffectMd);
|
||||
if (sideEffectMd != null && sideEffectMd.getBody() != null) {
|
||||
java.util.Map<String, String> inlineLocals = new java.util.HashMap<>();
|
||||
for (java.util.Map.Entry<String, String> entry : localVars.entrySet()) {
|
||||
if (entry.getKey().startsWith("this.")) {
|
||||
inlineLocals.put(entry.getKey(), entry.getValue());
|
||||
} else if (context.hasField(currentTd, entry.getKey())) {
|
||||
inlineLocals.put(entry.getKey(), entry.getValue());
|
||||
inlineLocals.put("this." + entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < node.arguments().size() && i < sideEffectMd.parameters().size(); i++) {
|
||||
Expression arg = (Expression) node.arguments().get(i);
|
||||
String val = resolveExpressionWithParams(arg, localVars, context);
|
||||
if (val == null) val = resolveInternal(arg, context, visited);
|
||||
if (val != null) {
|
||||
org.eclipse.jdt.core.dom.SingleVariableDeclaration param = (org.eclipse.jdt.core.dom.SingleVariableDeclaration) sideEffectMd.parameters().get(i);
|
||||
inlineLocals.put(param.getName().getIdentifier(), val);
|
||||
}
|
||||
}
|
||||
evaluateMethodBodyWithLocals(sideEffectMd, inlineLocals, context, visited);
|
||||
for (java.util.Map.Entry<String, String> entry : inlineLocals.entrySet()) {
|
||||
if (entry.getKey().startsWith("this.")) {
|
||||
localVars.put(entry.getKey(), entry.getValue());
|
||||
String bareName = entry.getKey().substring(5);
|
||||
if (!declaredLocals.contains(bareName)) localVars.put(bareName, entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.visit(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(Assignment assignment) {
|
||||
Expression lhs = assignment.getLeftHandSide();
|
||||
@@ -285,9 +330,19 @@ public class ConstantResolver {
|
||||
} else if (lhs instanceof FieldAccess fa) {
|
||||
varName = "this." + fa.getName().getIdentifier();
|
||||
}
|
||||
String rhsVal = resolveExpressionWithParams(assignment.getRightHandSide(), localVars);
|
||||
if (varName != null) {
|
||||
String rhsVal = resolveExpressionWithParams(assignment.getRightHandSide(), localVars, context);
|
||||
if (rhsVal == null) rhsVal = resolveInternal(assignment.getRightHandSide(), context, visited);
|
||||
if (varName != null && rhsVal != null) {
|
||||
if (rhsVal != null) {
|
||||
localVars.put(varName, rhsVal);
|
||||
} else {
|
||||
java.util.Map<String, String> bFields = extractBuilderFields(assignment.getRightHandSide(), localVars, context, visited);
|
||||
if (bFields != null) {
|
||||
for (java.util.Map.Entry<String, String> e : bFields.entrySet()) {
|
||||
localVars.put(varName + "." + e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (varName.startsWith("this.")) {
|
||||
localVars.put(varName, rhsVal);
|
||||
String bareName = varName.substring(5);
|
||||
@@ -316,7 +371,7 @@ public class ConstantResolver {
|
||||
String result = evaluateSwitchExpression(se, localVars, context, visited);
|
||||
if (result != null) finalResult[0] = result;
|
||||
} else if (rs.getExpression() != null) {
|
||||
String result = resolveExpressionWithParams(rs.getExpression(), localVars);
|
||||
String result = resolveExpressionWithParams(rs.getExpression(), localVars, context);
|
||||
if (result == null) result = resolveInternal(rs.getExpression(), context, visited);
|
||||
if (result != null) finalResult[0] = result;
|
||||
}
|
||||
@@ -329,7 +384,7 @@ public class ConstantResolver {
|
||||
}
|
||||
|
||||
private String evaluateSwitchStatement(org.eclipse.jdt.core.dom.SwitchStatement ss, java.util.Map<String, String> paramValues, CodebaseContext context, Set<String> visited) {
|
||||
String switchVar = resolveExpressionWithParams(ss.getExpression(), paramValues);
|
||||
String switchVar = resolveExpressionWithParams(ss.getExpression(), paramValues, context);
|
||||
if (switchVar == null) {
|
||||
Set<String> values = new LinkedHashSet<>();
|
||||
for (Object stmtObj : ss.statements()) {
|
||||
@@ -381,7 +436,7 @@ public class ConstantResolver {
|
||||
matchingCase = true;
|
||||
} else {
|
||||
for (Object exprObj : sc.expressions()) {
|
||||
String caseVal = resolveExpressionWithParams((Expression) exprObj, paramValues);
|
||||
String caseVal = resolveExpressionWithParams((Expression) exprObj, paramValues, context);
|
||||
// Bare SimpleName case label (e.g. "case PAY"): use identifier as fallback
|
||||
if (caseVal == null && exprObj instanceof org.eclipse.jdt.core.dom.SimpleName caseSn) {
|
||||
caseVal = caseSn.getIdentifier();
|
||||
@@ -416,7 +471,7 @@ public class ConstantResolver {
|
||||
}
|
||||
|
||||
private String evaluateSwitchExpression(org.eclipse.jdt.core.dom.SwitchExpression se, java.util.Map<String, String> paramValues, CodebaseContext context, Set<String> visited) {
|
||||
String switchVar = resolveExpressionWithParams(se.getExpression(), paramValues);
|
||||
String switchVar = resolveExpressionWithParams(se.getExpression(), paramValues, context);
|
||||
if (switchVar == null) {
|
||||
Set<String> values = new LinkedHashSet<>();
|
||||
for (Object stmtObj : se.statements()) {
|
||||
@@ -468,7 +523,7 @@ public class ConstantResolver {
|
||||
matchingCase = true;
|
||||
} else {
|
||||
for (Object exprObj : sc.expressions()) {
|
||||
String caseVal = resolveExpressionWithParams((Expression) exprObj, paramValues);
|
||||
String caseVal = resolveExpressionWithParams((Expression) exprObj, paramValues, context);
|
||||
// Bare SimpleName case label (e.g. "case PAY"): use identifier as fallback
|
||||
if (caseVal == null && exprObj instanceof org.eclipse.jdt.core.dom.SimpleName caseSn) {
|
||||
caseVal = caseSn.getIdentifier();
|
||||
@@ -502,7 +557,7 @@ public class ConstantResolver {
|
||||
return null;
|
||||
}
|
||||
|
||||
private String resolveExpressionWithParams(Expression expr, java.util.Map<String, String> paramValues) {
|
||||
private String resolveExpressionWithParams(Expression expr, java.util.Map<String, String> paramValues, CodebaseContext context) {
|
||||
if (expr instanceof SimpleName sn) {
|
||||
String name = sn.getIdentifier();
|
||||
if (paramValues.containsKey(name)) return paramValues.get(name);
|
||||
@@ -515,10 +570,107 @@ public class ConstantResolver {
|
||||
return null;
|
||||
} else if (expr instanceof org.eclipse.jdt.core.dom.StringLiteral sl) {
|
||||
return sl.getLiteralValue();
|
||||
} else if (expr instanceof MethodInvocation mi) {
|
||||
if ("valueOf".equals(mi.getName().getIdentifier())) {
|
||||
Expression arg = null;
|
||||
if (mi.arguments().size() == 1) {
|
||||
arg = (Expression) mi.arguments().get(0);
|
||||
} else if (mi.arguments().size() == 2) {
|
||||
arg = (Expression) mi.arguments().get(1);
|
||||
}
|
||||
if (arg != null) {
|
||||
String resolvedArg = resolveExpressionWithParams(arg, paramValues, context);
|
||||
if (resolvedArg != null && resolvedArg.matches("^[a-zA-Z_][a-zA-Z0-9_]*$")) {
|
||||
String enumFqn = null;
|
||||
if (mi.arguments().size() == 2) {
|
||||
enumFqn = resolveEnumFqn((Expression) mi.arguments().get(0), context);
|
||||
} else if (mi.arguments().size() == 1 && mi.getExpression() != null) {
|
||||
enumFqn = resolveEnumFqn(mi.getExpression(), context);
|
||||
}
|
||||
if (enumFqn != null) {
|
||||
return enumFqn + "." + resolvedArg;
|
||||
} else {
|
||||
// If we can't resolve the exact enum type here, we can just return the bare constant
|
||||
return resolvedArg;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mi.arguments().isEmpty() && mi.getExpression() instanceof SimpleName sn) {
|
||||
String objName = sn.getIdentifier();
|
||||
String methodName = mi.getName().getIdentifier();
|
||||
String propName = null;
|
||||
if (methodName.startsWith("get") && methodName.length() > 3) {
|
||||
propName = methodName.substring(3, 4).toLowerCase() + methodName.substring(4);
|
||||
} else {
|
||||
propName = methodName;
|
||||
}
|
||||
String val = paramValues.get(objName + "." + propName);
|
||||
if (val == null && !propName.equals(methodName)) {
|
||||
val = paramValues.get(objName + "." + methodName);
|
||||
}
|
||||
if (val != null) return val;
|
||||
}
|
||||
|
||||
MethodDeclaration sideEffectMd = findInvokedMethod(mi, context);
|
||||
if (sideEffectMd != null && sideEffectMd.getBody() != null) {
|
||||
TypeDeclaration currentTd = findEnclosingType(sideEffectMd);
|
||||
java.util.Map<String, String> inlineLocals = new java.util.HashMap<>();
|
||||
for (java.util.Map.Entry<String, String> entry : paramValues.entrySet()) {
|
||||
if (entry.getKey().startsWith("this.")) {
|
||||
inlineLocals.put(entry.getKey(), entry.getValue());
|
||||
} else if (context.hasField(currentTd, entry.getKey())) {
|
||||
inlineLocals.put(entry.getKey(), entry.getValue());
|
||||
inlineLocals.put("this." + entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < mi.arguments().size() && i < sideEffectMd.parameters().size(); i++) {
|
||||
Expression arg = (Expression) mi.arguments().get(i);
|
||||
String val = resolveExpressionWithParams(arg, paramValues, context);
|
||||
if (val == null) val = resolveInternal(arg, context, new java.util.HashSet<>());
|
||||
if (val != null) {
|
||||
org.eclipse.jdt.core.dom.SingleVariableDeclaration param = (org.eclipse.jdt.core.dom.SingleVariableDeclaration) sideEffectMd.parameters().get(i);
|
||||
inlineLocals.put(param.getName().getIdentifier(), val);
|
||||
}
|
||||
}
|
||||
String ret = evaluateMethodBodyWithLocals(sideEffectMd, inlineLocals, context, new java.util.HashSet<>());
|
||||
for (java.util.Map.Entry<String, String> entry : inlineLocals.entrySet()) {
|
||||
if (entry.getKey().startsWith("this.")) {
|
||||
paramValues.put(entry.getKey(), entry.getValue());
|
||||
String bareName = entry.getKey().substring(5);
|
||||
paramValues.put(bareName, entry.getValue());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private java.util.Map<String, String> extractBuilderFields(Expression expr, java.util.Map<String, String> localVars, CodebaseContext context, Set<String> visited) {
|
||||
if (!(expr instanceof MethodInvocation mi)) return null;
|
||||
java.util.Map<String, String> fields = new java.util.HashMap<>();
|
||||
MethodInvocation current = mi;
|
||||
while (current != null) {
|
||||
String methodName = current.getName().getIdentifier();
|
||||
if (!"build".equals(methodName) && !"builder".equals(methodName) && !"toBuilder".equals(methodName)) {
|
||||
if (current.arguments().size() == 1) {
|
||||
Expression arg = (Expression) current.arguments().get(0);
|
||||
String val = resolveExpressionWithParams(arg, localVars, context);
|
||||
if (val == null) val = resolveInternal(arg, context, visited);
|
||||
if (val != null) fields.put(methodName, val);
|
||||
}
|
||||
}
|
||||
if (current.getExpression() instanceof MethodInvocation next) {
|
||||
current = next;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return fields.isEmpty() ? null : fields;
|
||||
}
|
||||
|
||||
private String resolveInfix(InfixExpression expr, CodebaseContext context, Set<String> visited) {
|
||||
if (expr.getOperator() != InfixExpression.Operator.PLUS) return null;
|
||||
|
||||
@@ -646,12 +798,51 @@ public class ConstantResolver {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check superclass
|
||||
if (td.getSuperclassType() != null) {
|
||||
String superclassName = click.kamil.springstatemachineexporter.ast.common.AstUtils.extractSimpleTypeName(td.getSuperclassType());
|
||||
String resolvedSuperclass = resolveTypeFqn(superclassName, context, td);
|
||||
if (resolvedSuperclass != null) {
|
||||
TypeDeclaration superTd = context.getTypeDeclaration(resolvedSuperclass);
|
||||
if (superTd != null) {
|
||||
String result = resolveFieldInType(superTd, fieldName, resolvedSuperclass, context, visited);
|
||||
if (result != null) return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check superinterfaces
|
||||
for (Object intfObj : td.superInterfaceTypes()) {
|
||||
Type intfType = (Type) intfObj;
|
||||
String intfName = click.kamil.springstatemachineexporter.ast.common.AstUtils.extractSimpleTypeName(intfType);
|
||||
String resolvedIntf = resolveTypeFqn(intfName, context, td);
|
||||
if (resolvedIntf != null) {
|
||||
TypeDeclaration intfTd = context.getTypeDeclaration(resolvedIntf);
|
||||
if (intfTd != null) {
|
||||
String result = resolveFieldInType(intfTd, fieldName, resolvedIntf, context, visited);
|
||||
if (result != null) return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
visited.remove(fieldId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String resolveTypeFqn(String simpleName, CodebaseContext context, TypeDeclaration td) {
|
||||
CompilationUnit cu = (CompilationUnit) td.getRoot();
|
||||
for (Object impObj : cu.imports()) {
|
||||
ImportDeclaration imp = (ImportDeclaration) impObj;
|
||||
String name = imp.getName().getFullyQualifiedName();
|
||||
if (name.endsWith("." + simpleName)) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return cu.getPackage().getName().getFullyQualifiedName() + "." + simpleName;
|
||||
}
|
||||
|
||||
private String findValueFromAnnotation(FieldDeclaration fd) {
|
||||
for (Object mod : fd.modifiers()) {
|
||||
if (mod instanceof Annotation ann) {
|
||||
@@ -685,11 +876,29 @@ public class ConstantResolver {
|
||||
}
|
||||
|
||||
private TypeDeclaration findEnclosingType(ASTNode node) {
|
||||
ASTNode parent = node.getParent();
|
||||
while (parent != null && !(parent instanceof TypeDeclaration)) {
|
||||
parent = parent.getParent();
|
||||
ASTNode current = node;
|
||||
while (current != null && !(current instanceof TypeDeclaration)) {
|
||||
current = current.getParent();
|
||||
}
|
||||
return (TypeDeclaration) parent;
|
||||
return (TypeDeclaration) current;
|
||||
}
|
||||
|
||||
private MethodDeclaration findInvokedMethod(org.eclipse.jdt.core.dom.MethodInvocation mi, CodebaseContext context) {
|
||||
org.eclipse.jdt.core.dom.IMethodBinding methodBinding = mi.resolveMethodBinding();
|
||||
if (methodBinding != null) {
|
||||
org.eclipse.jdt.core.dom.ITypeBinding declaringClass = methodBinding.getDeclaringClass();
|
||||
if (declaringClass != null) {
|
||||
TypeDeclaration targetTd = context.getTypeDeclaration(declaringClass.getErasure().getQualifiedName());
|
||||
if (targetTd != null) {
|
||||
return context.findMethodDeclaration(targetTd, mi.getName().getIdentifier(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
TypeDeclaration currentTd = findEnclosingType(mi);
|
||||
if (currentTd != null && (mi.getExpression() == null || mi.getExpression() instanceof org.eclipse.jdt.core.dom.ThisExpression)) {
|
||||
return context.findMethodDeclaration(currentTd, mi.getName().getIdentifier(), true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private MethodDeclaration findEnclosingMethod(ASTNode node) {
|
||||
|
||||
@@ -66,6 +66,23 @@ public class SiblingDependencyResolver {
|
||||
for (String gradlePath : gradlePaths) {
|
||||
String relativePath = gradlePath.replace(':', '/');
|
||||
Path resolvedSibling = rootDir.resolve(relativePath).normalize();
|
||||
|
||||
// Check for explicit projectDir mapping in settings.gradle or settings.gradle.kts
|
||||
Path settingsFile = rootDir.resolve("settings.gradle");
|
||||
if (!Files.exists(settingsFile)) {
|
||||
settingsFile = rootDir.resolve("settings.gradle.kts");
|
||||
}
|
||||
if (Files.exists(settingsFile)) {
|
||||
String settingsContent = Files.readString(settingsFile);
|
||||
String regex = "project\\(['\"]:" + gradlePath + "['\"]\\)\\.projectDir\\s*=\\s*(?:file\\(['\"](.*?)['\"]\\)|new File\\(.*?,\\s*['\"](.*?)['\"]\\))";
|
||||
Matcher settingsMatcher = Pattern.compile(regex).matcher(settingsContent);
|
||||
if (settingsMatcher.find()) {
|
||||
String customPath = settingsMatcher.group(1) != null ? settingsMatcher.group(1) : settingsMatcher.group(2);
|
||||
resolvedSibling = rootDir.resolve(customPath).normalize();
|
||||
log.info("Found custom projectDir in settings for {}: {}", gradlePath, resolvedSibling);
|
||||
}
|
||||
}
|
||||
|
||||
if (Files.exists(resolvedSibling)) {
|
||||
log.info("Discovered local Gradle sibling dependency: {}", resolvedSibling);
|
||||
siblings.add(resolvedSibling);
|
||||
@@ -156,6 +173,19 @@ public class SiblingDependencyResolver {
|
||||
|
||||
// Also add parent dir if it has a pom.xml
|
||||
Path parentDir = projectDir.getParent();
|
||||
|
||||
// Check for explicit <relativePath> in parent block
|
||||
Matcher parentRelativePathMatcher = Pattern.compile("<parent>.*?<relativePath>(.*?)</relativePath>.*?</parent>", Pattern.DOTALL).matcher(content);
|
||||
if (parentRelativePathMatcher.find()) {
|
||||
String relPathStr = parentRelativePathMatcher.group(1).trim();
|
||||
Path relPath = projectDir.resolve(relPathStr).normalize();
|
||||
if (Files.isRegularFile(relPath) && relPath.getFileName().toString().equals("pom.xml")) {
|
||||
parentDir = relPath.getParent();
|
||||
} else if (Files.isDirectory(relPath)) {
|
||||
parentDir = relPath;
|
||||
}
|
||||
}
|
||||
|
||||
if (parentDir != null && Files.exists(parentDir.resolve("pom.xml")) && !parentDir.equals(projectDir)) {
|
||||
log.info("Discovered local Maven parent sibling: {}", parentDir);
|
||||
siblings.add(parentDir);
|
||||
|
||||
@@ -21,6 +21,40 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
protected final VariableTracer variableTracer;
|
||||
protected final ConstantExtractor constantExtractor;
|
||||
protected final ConstructorAnalyzer constructorAnalyzer;
|
||||
private final Map<String, ASTNode> parsedNodeCache = new HashMap<>();
|
||||
|
||||
private ASTNode parseExpressionString(String expr) {
|
||||
if (expr == null) return null;
|
||||
return parsedNodeCache.computeIfAbsent(expr, e -> {
|
||||
ASTParser parser = ASTParser.newParser(AST.JLS17);
|
||||
Map<String, String> options = org.eclipse.jdt.core.JavaCore.getOptions();
|
||||
org.eclipse.jdt.core.JavaCore.setComplianceOptions(org.eclipse.jdt.core.JavaCore.VERSION_17, options);
|
||||
parser.setCompilerOptions(options);
|
||||
parser.setKind(ASTParser.K_EXPRESSION);
|
||||
parser.setSource(e.toCharArray());
|
||||
try {
|
||||
ASTNode node = parser.createAST(null);
|
||||
if (node instanceof org.eclipse.jdt.core.dom.CompilationUnit) {
|
||||
ASTParser fallbackParser = ASTParser.newParser(AST.JLS17);
|
||||
fallbackParser.setCompilerOptions(options);
|
||||
fallbackParser.setKind(ASTParser.K_COMPILATION_UNIT);
|
||||
fallbackParser.setSource(("class A { Object o = " + e + "; }").toCharArray());
|
||||
org.eclipse.jdt.core.dom.CompilationUnit cu = (org.eclipse.jdt.core.dom.CompilationUnit) fallbackParser.createAST(null);
|
||||
if (!cu.types().isEmpty()) {
|
||||
org.eclipse.jdt.core.dom.TypeDeclaration td = (org.eclipse.jdt.core.dom.TypeDeclaration) cu.types().get(0);
|
||||
if (!td.bodyDeclarations().isEmpty() && td.bodyDeclarations().get(0) instanceof org.eclipse.jdt.core.dom.FieldDeclaration fd) {
|
||||
if (!fd.fragments().isEmpty() && fd.fragments().get(0) instanceof org.eclipse.jdt.core.dom.VariableDeclarationFragment vdf) {
|
||||
return vdf.getInitializer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
protected interface RhsResolver {
|
||||
@@ -122,10 +156,10 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
String currentParamName = event;
|
||||
String resolvedValue = event;
|
||||
String methodSuffix = "";
|
||||
|
||||
String[] extractedEntry = extractMethodSuffix(currentParamName, methodSuffix);
|
||||
currentParamName = extractedEntry[0];
|
||||
methodSuffix = extractedEntry[1];
|
||||
boolean isAmbiguous = false;
|
||||
if (finalParamNameRef != null) finalParamNameRef[0] = currentParamName;
|
||||
|
||||
for (int i = path.size() - 1; i > 0; i--) {
|
||||
@@ -268,7 +302,7 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
constantExtractor.extractConstantsFromExpression(tracedSetter, setterEvents);
|
||||
}
|
||||
if (!setterEvents.isEmpty()) {
|
||||
System.out.println("DEBUG Early return 1: setterEvents = " + setterEvents);
|
||||
log.debug("Early return 1: setterEvents = {}", setterEvents);
|
||||
return TriggerPoint.builder()
|
||||
.event(tp.getEvent())
|
||||
.className(tp.getClassName())
|
||||
@@ -293,7 +327,7 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
if (hasGetterOnReceiver) {
|
||||
List<String> getterEvents = evaluateGetterOnReceiver(resolvedValue, methodSuffix, entryMethod, path, callGraph);
|
||||
if (getterEvents != null && !getterEvents.isEmpty()) {
|
||||
System.out.println("DEBUG Early return 2: getterEvents = " + getterEvents);
|
||||
log.debug("Early return 2: getterEvents = {}", getterEvents);
|
||||
return TriggerPoint.builder()
|
||||
.event(tp.getEvent())
|
||||
.className(tp.getClassName())
|
||||
@@ -323,7 +357,7 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("DEBUG resolvedValue before ENUM_SET check: " + resolvedValue + " for path: " + path);
|
||||
log.debug("resolvedValue before ENUM_SET check: {} for path: {}", resolvedValue, path);
|
||||
List<String> polymorphicEvents = new ArrayList<>();
|
||||
|
||||
if (resolvedValue.startsWith("ENUM_SET:")) {
|
||||
@@ -348,10 +382,10 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
.build();
|
||||
}
|
||||
|
||||
ASTParser exprParser = ASTParser.newParser(AST.JLS17);
|
||||
exprParser.setKind(ASTParser.K_EXPRESSION);
|
||||
exprParser.setSource(resolvedValue.toCharArray());
|
||||
ASTNode exprNode = exprParser.createAST(null);
|
||||
ASTNode exprNode = parseExpressionString(resolvedValue);
|
||||
while (exprNode instanceof ParenthesizedExpression pe) {
|
||||
exprNode = pe.getExpression();
|
||||
}
|
||||
|
||||
String varName = null;
|
||||
String methodName = null;
|
||||
@@ -360,6 +394,31 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
|
||||
if (exprNode instanceof MethodInvocation mi) {
|
||||
methodName = mi.getName().getIdentifier();
|
||||
boolean handledStaticEnum = false;
|
||||
if (methodName.equals("valueOf") && mi.arguments().size() == 1) {
|
||||
Object arg = mi.arguments().get(0);
|
||||
if (arg instanceof StringLiteral sl) {
|
||||
polymorphicEvents.add(sl.getLiteralValue());
|
||||
methodName = null;
|
||||
handledStaticEnum = true;
|
||||
} else if (arg instanceof QualifiedName qn) {
|
||||
polymorphicEvents.add(qn.getName().getIdentifier());
|
||||
methodName = null;
|
||||
handledStaticEnum = true;
|
||||
}
|
||||
} else if (methodName.equals("name") && mi.arguments().isEmpty()) {
|
||||
if (mi.getExpression() instanceof QualifiedName qn) {
|
||||
polymorphicEvents.add(qn.getName().getIdentifier());
|
||||
methodName = null;
|
||||
handledStaticEnum = true;
|
||||
} else if (mi.getExpression() instanceof SimpleName sn) {
|
||||
polymorphicEvents.add(sn.getIdentifier());
|
||||
methodName = null;
|
||||
handledStaticEnum = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!handledStaticEnum) {
|
||||
if (mi.getExpression() instanceof SimpleName sn) {
|
||||
varName = sn.getIdentifier();
|
||||
} else if (mi.getExpression() instanceof ParenthesizedExpression pe &&
|
||||
@@ -398,6 +457,7 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
.stateTypeFqn(tp.getStateTypeFqn())
|
||||
.eventTypeFqn(tp.getEventTypeFqn())
|
||||
.external(tp.isExternal())
|
||||
.ambiguous(isAmbiguous)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -436,6 +496,7 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
varName = exprStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (exprNode instanceof ClassInstanceCreation cic) {
|
||||
declaredType = click.kamil.springstatemachineexporter.ast.common.AstUtils.extractSimpleTypeName(cic.getType());
|
||||
sourceMethod = "inline-instantiation";
|
||||
@@ -456,14 +517,53 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
}
|
||||
sourceMethod = "inline-ternary";
|
||||
declaredType = polymorphicEvents.isEmpty() ? null : polymorphicEvents.get(0);
|
||||
} else if (exprNode instanceof SwitchExpression swExpr) {
|
||||
List<String> polyEventsRef = polymorphicEvents;
|
||||
swExpr.accept(new ASTVisitor() {
|
||||
@Override
|
||||
public boolean visit(YieldStatement ys) {
|
||||
List<Expression> tracedBranch = variableTracer.traceVariableAll(ys.getExpression());
|
||||
for (Expression tb : tracedBranch) {
|
||||
if (tb instanceof ClassInstanceCreation cic) {
|
||||
polyEventsRef.add(click.kamil.springstatemachineexporter.ast.common.AstUtils.extractSimpleTypeName(cic.getType()));
|
||||
} else {
|
||||
constantExtractor.extractConstantsFromExpression(tb, polyEventsRef);
|
||||
}
|
||||
}
|
||||
return super.visit(ys);
|
||||
}
|
||||
@Override
|
||||
public boolean visit(ExpressionStatement es) {
|
||||
List<Expression> tracedBranch = variableTracer.traceVariableAll(es.getExpression());
|
||||
for (Expression tb : tracedBranch) {
|
||||
if (tb instanceof ClassInstanceCreation cic) {
|
||||
polyEventsRef.add(click.kamil.springstatemachineexporter.ast.common.AstUtils.extractSimpleTypeName(cic.getType()));
|
||||
} else {
|
||||
constantExtractor.extractConstantsFromExpression(tb, polyEventsRef);
|
||||
}
|
||||
}
|
||||
return super.visit(es);
|
||||
}
|
||||
});
|
||||
sourceMethod = "inline-switch";
|
||||
declaredType = polymorphicEvents.isEmpty() ? null : polymorphicEvents.get(0);
|
||||
} else if (exprNode instanceof SimpleName sn) {
|
||||
varName = sn.getIdentifier();
|
||||
if (varName.equals(varName.toUpperCase()) && varName.contains("_")) {
|
||||
if (varName.equals(varName.toUpperCase())) {
|
||||
polymorphicEvents.add(varName);
|
||||
methodName = null;
|
||||
} else {
|
||||
methodName = "VariableReference";
|
||||
}
|
||||
} else if (exprNode instanceof QualifiedName qn) {
|
||||
polymorphicEvents.add(qn.getFullyQualifiedName());
|
||||
methodName = null;
|
||||
} else if (exprNode instanceof FieldAccess fa) {
|
||||
polymorphicEvents.add(fa.toString());
|
||||
methodName = null;
|
||||
} else if (exprNode instanceof StringLiteral sl) {
|
||||
polymorphicEvents.add(sl.getLiteralValue());
|
||||
methodName = null;
|
||||
} else if (exprNode instanceof ParenthesizedExpression pe &&
|
||||
pe.getExpression() instanceof CastExpression ce &&
|
||||
ce.getExpression() instanceof ClassInstanceCreation cic) {
|
||||
@@ -503,6 +603,7 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
.stateTypeFqn(tp.getStateTypeFqn())
|
||||
.eventTypeFqn(tp.getEventTypeFqn())
|
||||
.external(tp.isExternal())
|
||||
.ambiguous(isAmbiguous)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -552,10 +653,7 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
if (extractedFinalTraced[0] != null) {
|
||||
resolvedValue = extractedFinalTraced[0] + extractedFinalTraced[1];
|
||||
if (extractedFinalTraced[0].contains("new ") && extractedFinalTraced[0].contains("{")) {
|
||||
ASTParser p = ASTParser.newParser(AST.JLS17);
|
||||
p.setKind(ASTParser.K_EXPRESSION);
|
||||
p.setSource(resolvedValue.toCharArray());
|
||||
ASTNode newNode = p.createAST(null);
|
||||
ASTNode newNode = parseExpressionString(resolvedValue);
|
||||
if (newNode instanceof Expression) {
|
||||
List<Expression> traced = variableTracer.traceVariableAll((Expression) newNode);
|
||||
for (Expression ex : traced) {
|
||||
@@ -581,10 +679,7 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
if (polymorphicEvents.isEmpty() && variableTracer != null) {
|
||||
String initializer = variableTracer.traceLocalVariable(methodFqn, varName);
|
||||
if (initializer != null && !initializer.equals(varName)) {
|
||||
ASTParser mapParser = ASTParser.newParser(AST.JLS17);
|
||||
mapParser.setKind(ASTParser.K_EXPRESSION);
|
||||
mapParser.setSource(initializer.toCharArray());
|
||||
ASTNode mapNode = mapParser.createAST(null);
|
||||
ASTNode mapNode = parseExpressionString(initializer);
|
||||
if (mapNode instanceof Expression) {
|
||||
List<Expression> mapTraced = variableTracer.traceVariableAll((Expression) mapNode);
|
||||
for (Expression t : mapTraced) {
|
||||
@@ -625,13 +720,14 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("DEBUG declaredType before getEnumValues: " + declaredType + " for exprNode: " + exprNode + " in " + entryMethod);
|
||||
log.debug("declaredType before getEnumValues: {} for exprNode: {} in {}", declaredType, exprNode, entryMethod);
|
||||
if (declaredType != null) {
|
||||
List<String> enumValues = context.getEnumValues(declaredType);
|
||||
if (enumValues != null && !enumValues.isEmpty()) {
|
||||
for (String ev : enumValues) {
|
||||
polymorphicEvents.add(constantExtractor.parseEnumSetElement(ev));
|
||||
}
|
||||
isAmbiguous = true;
|
||||
} else {
|
||||
List<String> typesToInspect = new ArrayList<>();
|
||||
if ("inline-instantiation".equals(sourceMethod)) {
|
||||
@@ -935,10 +1031,10 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
}
|
||||
|
||||
protected List<String> evaluateGetterOnReceiver(String resolvedValue, String methodSuffix, String entryMethod, List<String> path, Map<String, List<CallEdge>> callGraph) {
|
||||
ASTParser exprParser = ASTParser.newParser(AST.JLS17);
|
||||
exprParser.setKind(ASTParser.K_EXPRESSION);
|
||||
exprParser.setSource(resolvedValue.toCharArray());
|
||||
ASTNode exprNode = exprParser.createAST(null);
|
||||
ASTNode exprNode = parseExpressionString(resolvedValue);
|
||||
while (exprNode instanceof ParenthesizedExpression pe) {
|
||||
exprNode = pe.getExpression();
|
||||
}
|
||||
|
||||
if (exprNode instanceof SuperMethodInvocation smi) {
|
||||
String getterName = smi.getName().getIdentifier();
|
||||
@@ -1499,10 +1595,7 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
if (arg == null) return null;
|
||||
String current = arg;
|
||||
while (current.contains("(") && !current.startsWith("new ")) {
|
||||
org.eclipse.jdt.core.dom.ASTParser argParser = org.eclipse.jdt.core.dom.ASTParser.newParser(org.eclipse.jdt.core.dom.AST.JLS17);
|
||||
argParser.setKind(org.eclipse.jdt.core.dom.ASTParser.K_EXPRESSION);
|
||||
argParser.setSource(current.toCharArray());
|
||||
org.eclipse.jdt.core.dom.ASTNode argNode = argParser.createAST(null);
|
||||
org.eclipse.jdt.core.dom.ASTNode argNode = parseExpressionString(current);
|
||||
if (argNode instanceof org.eclipse.jdt.core.dom.MethodInvocation miArg && !miArg.arguments().isEmpty()) {
|
||||
boolean shouldUnpack = false;
|
||||
org.eclipse.jdt.core.dom.Expression recv = miArg.getExpression();
|
||||
|
||||
@@ -8,4 +8,8 @@ import java.util.List;
|
||||
|
||||
public interface CallGraphEngine {
|
||||
List<CallChain> findChains(List<EntryPoint> entryPoints, List<TriggerPoint> triggers);
|
||||
|
||||
default java.util.Map<String, java.util.List<click.kamil.springstatemachineexporter.analysis.model.CallEdge>> getCallGraph() {
|
||||
return java.util.Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,10 @@ import java.util.*;
|
||||
@Slf4j
|
||||
public class CallGraphPathFinder {
|
||||
private final CodebaseContext context;
|
||||
private final Map<String, Boolean> heuristicCache = new HashMap<>();
|
||||
private final Map<java.util.Map.Entry<String, String>, Boolean> heuristicCache = new HashMap<>();
|
||||
|
||||
private final Map<java.util.Map.Entry<String, String>, List<List<String>>> memoCache = new HashMap<>();
|
||||
private final Map<java.util.Map.Entry<String, String>, Boolean> unreachableCache = new HashMap<>();
|
||||
|
||||
public CallGraphPathFinder(CodebaseContext context) {
|
||||
this.context = context;
|
||||
@@ -50,12 +53,30 @@ public class CallGraphPathFinder {
|
||||
}
|
||||
|
||||
public List<List<String>> findAllPaths(String start, String target, Map<String, List<CallEdge>> graph, Set<String> visited) {
|
||||
return findAllPaths(start, target, graph, visited, new HashSet<>(), new boolean[]{false});
|
||||
return findAllPaths(start, target, graph, visited, new boolean[]{false});
|
||||
}
|
||||
|
||||
public List<List<String>> findAllPaths(String start, String target, Map<String, List<CallEdge>> graph, Set<String> visited, Set<String> unreachable, boolean[] parentHitCycle) {
|
||||
public List<List<String>> findAllPaths(String start, String target, Map<String, List<CallEdge>> graph, Set<String> visited, boolean[] parentHitCycle) {
|
||||
List<List<String>> result = new ArrayList<>();
|
||||
if (unreachable.contains(start)) {
|
||||
java.util.Map.Entry<String, String> cacheKey = new java.util.AbstractMap.SimpleImmutableEntry<>(start, target);
|
||||
if (unreachableCache.containsKey(cacheKey)) {
|
||||
return result;
|
||||
}
|
||||
if (memoCache.containsKey(cacheKey)) {
|
||||
List<List<String>> cached = memoCache.get(cacheKey);
|
||||
for (List<String> path : cached) {
|
||||
boolean hasCycle = false;
|
||||
for (String node : path) {
|
||||
if (visited.contains(node)) {
|
||||
hasCycle = true;
|
||||
parentHitCycle[0] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasCycle) {
|
||||
result.add(new ArrayList<>(path));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (start.equals(target)) {
|
||||
@@ -78,7 +99,7 @@ public class CallGraphPathFinder {
|
||||
List<String> path = new ArrayList<>(List.of(start, target));
|
||||
result.add(path);
|
||||
} else {
|
||||
List<List<String>> subPaths = findAllPaths(neighbor, target, graph, visited, unreachable, localHitCycle);
|
||||
List<List<String>> subPaths = findAllPaths(neighbor, target, graph, visited, localHitCycle);
|
||||
for (List<String> subPath : subPaths) {
|
||||
List<String> path = new ArrayList<>();
|
||||
path.add(start);
|
||||
@@ -102,7 +123,7 @@ public class CallGraphPathFinder {
|
||||
if (superclass != null) {
|
||||
String superMethod = superclass + "." + methodName;
|
||||
if (graph.containsKey(superMethod)) {
|
||||
List<List<String>> superPaths = findAllPaths(superMethod, target, graph, visited, unreachable, localHitCycle);
|
||||
List<List<String>> superPaths = findAllPaths(superMethod, target, graph, visited, localHitCycle);
|
||||
for (List<String> superPath : superPaths) {
|
||||
List<String> path = new ArrayList<>();
|
||||
path.add(start);
|
||||
@@ -126,7 +147,7 @@ public class CallGraphPathFinder {
|
||||
for (String impl : impls) {
|
||||
String implMethod = impl + "." + methodName;
|
||||
if (graph.containsKey(implMethod)) {
|
||||
List<List<String>> implPaths = findAllPaths(implMethod, target, graph, visited, unreachable, localHitCycle);
|
||||
List<List<String>> implPaths = findAllPaths(implMethod, target, graph, visited, localHitCycle);
|
||||
for (List<String> implPath : implPaths) {
|
||||
List<String> path = new ArrayList<>();
|
||||
path.add(start);
|
||||
@@ -142,7 +163,13 @@ public class CallGraphPathFinder {
|
||||
if (localHitCycle[0]) {
|
||||
parentHitCycle[0] = true;
|
||||
} else if (result.isEmpty()) {
|
||||
unreachable.add(start);
|
||||
unreachableCache.put(cacheKey, true);
|
||||
} else {
|
||||
List<List<String>> toCache = new ArrayList<>();
|
||||
for (List<String> path : result) {
|
||||
toCache.add(new ArrayList<>(path));
|
||||
}
|
||||
memoCache.put(cacheKey, toCache);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -169,7 +196,7 @@ public class CallGraphPathFinder {
|
||||
if (neighbor == null || target == null) return false;
|
||||
if (neighbor.equals(target)) return true;
|
||||
|
||||
String cacheKey = neighbor + "|" + target;
|
||||
java.util.Map.Entry<String, String> cacheKey = new java.util.AbstractMap.SimpleImmutableEntry<>(neighbor, target);
|
||||
Boolean cached = heuristicCache.get(cacheKey);
|
||||
if (cached != null) return cached;
|
||||
|
||||
@@ -179,7 +206,6 @@ public class CallGraphPathFinder {
|
||||
}
|
||||
|
||||
private boolean calculateHeuristicMatch(String neighbor, String target) {
|
||||
System.out.println("calculateHeuristicMatch: neighbor=" + neighbor + ", target=" + target);
|
||||
if (neighbor.equals(target)) return true;
|
||||
|
||||
if (isFullyQualifiedMethod(neighbor) && isFullyQualifiedMethod(target)) {
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
package click.kamil.springstatemachineexporter.analysis.service;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.model.CallChain;
|
||||
import click.kamil.springstatemachineexporter.analysis.model.CallEdge;
|
||||
import click.kamil.springstatemachineexporter.analysis.model.EntryPoint;
|
||||
import click.kamil.springstatemachineexporter.analysis.model.TriggerPoint;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CompositeCallGraphEngine implements CallGraphEngine {
|
||||
private final List<CallGraphEngine> engines;
|
||||
private final Map<String, List<CallEdge>> mergedGraph = new HashMap<>();
|
||||
|
||||
public CompositeCallGraphEngine(List<CallGraphEngine> engines) {
|
||||
this.engines = engines;
|
||||
mergeGraphs();
|
||||
}
|
||||
|
||||
private void mergeGraphs() {
|
||||
for (CallGraphEngine engine : engines) {
|
||||
Map<String, List<CallEdge>> graph = engine.getCallGraph();
|
||||
if (graph != null) {
|
||||
for (Map.Entry<String, List<CallEdge>> entry : graph.entrySet()) {
|
||||
String caller = normalizeCompanionFqn(entry.getKey());
|
||||
List<CallEdge> edges = mergedGraph.computeIfAbsent(caller, k -> new ArrayList<>());
|
||||
for (CallEdge edge : entry.getValue()) {
|
||||
String target = normalizeCompanionFqn(edge.getTargetMethod());
|
||||
edges.add(new CallEdge(target, edge.getArguments(), edge.getReceiver()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String normalizeCompanionFqn(String fqn) {
|
||||
if (fqn == null) return null;
|
||||
return fqn.replace(".Companion.", ".");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<CallEdge>> getCallGraph() {
|
||||
return mergedGraph;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CallChain> findChains(List<EntryPoint> entryPoints, List<TriggerPoint> triggers) {
|
||||
List<CallChain> chains = new ArrayList<>();
|
||||
for (EntryPoint ep : entryPoints) {
|
||||
String startMethod = normalizeCompanionFqn(ep.getClassName() + "." + ep.getMethodName());
|
||||
for (TriggerPoint tp : triggers) {
|
||||
String targetMethod = normalizeCompanionFqn(tp.getClassName() + "." + tp.getMethodName());
|
||||
List<List<String>> paths = findAllPaths(startMethod, targetMethod, new LinkedHashSet<>());
|
||||
for (List<String> path : paths) {
|
||||
chains.add(CallChain.builder()
|
||||
.entryPoint(ep)
|
||||
.methodChain(path)
|
||||
.triggerPoint(tp)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
return chains;
|
||||
}
|
||||
|
||||
private List<List<String>> findAllPaths(String start, String target, Set<String> visited) {
|
||||
List<List<String>> result = new ArrayList<>();
|
||||
if (start.equals(target)) {
|
||||
result.add(new ArrayList<>(List.of(start)));
|
||||
return result;
|
||||
}
|
||||
if (!visited.add(start)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
List<CallEdge> neighbors = mergedGraph.get(start);
|
||||
if (neighbors != null) {
|
||||
for (CallEdge edge : neighbors) {
|
||||
String neighbor = edge.getTargetMethod();
|
||||
if (neighbor.startsWith("java.") || neighbor.startsWith("javax.") ||
|
||||
neighbor.startsWith("jakarta.") || neighbor.startsWith("org.springframework.")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (neighbor.equals(target) || isHeuristicMatch(neighbor, target)) {
|
||||
List<String> path = new ArrayList<>(List.of(start, target));
|
||||
result.add(path);
|
||||
} else {
|
||||
List<List<String>> subPaths = findAllPaths(neighbor, target, visited);
|
||||
for (List<String> subPath : subPaths) {
|
||||
List<String> path = new ArrayList<>();
|
||||
path.add(start);
|
||||
path.addAll(subPath);
|
||||
result.add(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
visited.remove(start);
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isHeuristicMatch(String neighbor, String target) {
|
||||
if (neighbor == null || target == null) return false;
|
||||
if (neighbor.equals(target)) return true;
|
||||
if (neighbor.contains(".") && target.contains(".")) {
|
||||
String methodNeighbor = neighbor.substring(neighbor.lastIndexOf('.') + 1);
|
||||
String methodTarget = target.substring(target.lastIndexOf('.') + 1);
|
||||
if (methodNeighbor.equals(methodTarget)) {
|
||||
String classNeighbor = neighbor.substring(0, neighbor.lastIndexOf('.'));
|
||||
String classTarget = target.substring(0, target.lastIndexOf('.'));
|
||||
String simpleClassNeighbor = classNeighbor.contains(".") ? classNeighbor.substring(classNeighbor.lastIndexOf('.') + 1) : classNeighbor;
|
||||
String simpleClassTarget = classTarget.contains(".") ? classTarget.substring(classTarget.lastIndexOf('.') + 1) : classTarget;
|
||||
return simpleClassNeighbor.equalsIgnoreCase(simpleClassTarget);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package click.kamil.springstatemachineexporter.analysis.service;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.model.CallChain;
|
||||
import click.kamil.springstatemachineexporter.analysis.model.EntryPoint;
|
||||
import click.kamil.springstatemachineexporter.analysis.model.TriggerPoint;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CompositeIntelligenceProvider implements CodebaseIntelligenceProvider {
|
||||
private final List<CodebaseIntelligenceProvider> providers;
|
||||
private final List<CallGraphEngine> engines;
|
||||
|
||||
public CompositeIntelligenceProvider(List<CodebaseIntelligenceProvider> providers, List<CallGraphEngine> engines) {
|
||||
this.providers = providers;
|
||||
this.engines = engines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TriggerPoint> findTriggerPoints() {
|
||||
List<TriggerPoint> result = new ArrayList<>();
|
||||
for (CodebaseIntelligenceProvider provider : providers) {
|
||||
result.addAll(provider.findTriggerPoints());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EntryPoint> findEntryPoints() {
|
||||
List<EntryPoint> result = new ArrayList<>();
|
||||
for (CodebaseIntelligenceProvider provider : providers) {
|
||||
result.addAll(provider.findEntryPoints());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CallChain> findCallChains(List<EntryPoint> entryPoints, List<TriggerPoint> triggers) {
|
||||
CompositeCallGraphEngine compositeEngine = new CompositeCallGraphEngine(engines);
|
||||
return compositeEngine.findChains(entryPoints, triggers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, String>> resolveProperties() {
|
||||
Map<String, Map<String, String>> result = new HashMap<>();
|
||||
for (CodebaseIntelligenceProvider provider : providers) {
|
||||
Map<String, Map<String, String>> props = provider.resolveProperties();
|
||||
if (props != null) {
|
||||
result.putAll(props);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,8 @@ public class ConstantExtractor {
|
||||
} else if (expr instanceof MethodInvocation mi) {
|
||||
String methodName = mi.getName().getIdentifier();
|
||||
|
||||
System.out.println("Processing mi: " + mi); if (methodName.equals("get") || methodName.equals("getOrDefault")) {
|
||||
log.trace("Processing mi: {}", mi);
|
||||
if (methodName.equals("get") || methodName.equals("getOrDefault")) {
|
||||
if (mi.getExpression() != null) {
|
||||
if (variableTracer != null) {
|
||||
List<Expression> traced = variableTracer.traceVariableAll(mi.getExpression());
|
||||
@@ -281,7 +282,7 @@ public class ConstantExtractor {
|
||||
}
|
||||
|
||||
public List<String> resolveMethodReturnConstant(String className, String methodName, int depth, Set<String> visited, CompilationUnit contextCu) {
|
||||
System.out.println("DEBUG ConstantExtractor.resolveMethodReturnConstant CALLED: className=" + className + ", methodName=" + methodName);
|
||||
log.debug("ConstantExtractor.resolveMethodReturnConstant CALLED: className={}, methodName={}", className, methodName);
|
||||
log.debug("Entering resolveMethodReturnConstant with className={}, methodName={}, depth={}", className, methodName, depth);
|
||||
if (depth > 20) {
|
||||
log.debug("Exiting resolveMethodReturnConstant early (depth limit) for {}.{}", className, methodName);
|
||||
@@ -392,7 +393,7 @@ public class ConstantExtractor {
|
||||
}
|
||||
}
|
||||
visited.remove(fqn);
|
||||
System.out.println("DEBUG resolveMethodReturnConstant className=" + className + " methodName=" + methodName + " returns: " + constants);
|
||||
log.debug("resolveMethodReturnConstant className={} methodName={} returns: {}", className, methodName, constants);
|
||||
log.debug("resolveMethodReturnConstant for class={}, method={} resolved constants: {}", className, methodName, constants);
|
||||
return constants;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
|
||||
import org.eclipse.jdt.core.dom.*;
|
||||
import java.util.*;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class ConstructorAnalyzer {
|
||||
private final CodebaseContext context;
|
||||
private final ConstantResolver constantResolver;
|
||||
@@ -274,37 +277,17 @@ public class ConstructorAnalyzer {
|
||||
}
|
||||
// Evaluate constructor body regardless of whether parameters could be resolved as constants
|
||||
|
||||
ctor.getBody().accept(new ASTVisitor() {
|
||||
@Override
|
||||
public boolean visit(Assignment node) {
|
||||
Expression lhs = node.getLeftHandSide();
|
||||
Expression rhs = node.getRightHandSide();
|
||||
|
||||
String fieldName = null;
|
||||
if (lhs instanceof FieldAccess fa
|
||||
&& fa.getExpression() instanceof ThisExpression) {
|
||||
fieldName = fa.getName().getIdentifier();
|
||||
} else if (lhs instanceof SimpleName sn
|
||||
&& !paramValues.containsKey(sn.getIdentifier())) {
|
||||
fieldName = sn.getIdentifier();
|
||||
}
|
||||
|
||||
if (fieldName != null) {
|
||||
String paramVal = null;
|
||||
if (rhs instanceof SimpleName snRhs) {
|
||||
paramVal = paramValues.get(snRhs.getIdentifier());
|
||||
} else if (rhsResolver != null) {
|
||||
paramVal = rhsResolver.resolve(rhs, paramValues, td);
|
||||
}
|
||||
|
||||
if (paramVal != null) {
|
||||
fieldValues.put(fieldName, paramVal);
|
||||
fieldValues.put("this." + fieldName, paramVal);
|
||||
java.util.Map<String, String> localVars = new java.util.HashMap<>(paramValues);
|
||||
constantResolver.evaluateMethodBodyWithLocals(ctor, localVars, context, new java.util.HashSet<>());
|
||||
for (java.util.Map.Entry<String, String> entry : localVars.entrySet()) {
|
||||
if (entry.getKey().startsWith("this.")) {
|
||||
fieldValues.put(entry.getKey(), entry.getValue());
|
||||
fieldValues.put(entry.getKey().substring(5), entry.getValue());
|
||||
} else if (context.hasField(td, entry.getKey())) {
|
||||
fieldValues.put(entry.getKey(), entry.getValue());
|
||||
fieldValues.put("this." + entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
return super.visit(node);
|
||||
}
|
||||
});
|
||||
|
||||
ctor.getBody().accept(new ASTVisitor() {
|
||||
@Override
|
||||
@@ -396,37 +379,17 @@ public class ConstructorAnalyzer {
|
||||
}
|
||||
if (superParamValues.isEmpty()) continue;
|
||||
|
||||
superCtor.getBody().accept(new ASTVisitor() {
|
||||
@Override
|
||||
public boolean visit(Assignment node) {
|
||||
Expression lhs = node.getLeftHandSide();
|
||||
Expression rhs = node.getRightHandSide();
|
||||
|
||||
String fieldName = null;
|
||||
if (lhs instanceof FieldAccess fa
|
||||
&& fa.getExpression() instanceof ThisExpression) {
|
||||
fieldName = fa.getName().getIdentifier();
|
||||
} else if (lhs instanceof SimpleName sn
|
||||
&& !superParamValues.containsKey(sn.getIdentifier())) {
|
||||
fieldName = sn.getIdentifier();
|
||||
}
|
||||
|
||||
if (fieldName != null) {
|
||||
String paramVal = null;
|
||||
if (rhs instanceof SimpleName snRhs) {
|
||||
paramVal = superParamValues.get(snRhs.getIdentifier());
|
||||
} else if (rhsResolver != null) {
|
||||
paramVal = rhsResolver.resolve(rhs, superParamValues, superTd);
|
||||
}
|
||||
|
||||
if (paramVal != null) {
|
||||
fieldValues.put(fieldName, paramVal);
|
||||
fieldValues.put("this." + fieldName, paramVal);
|
||||
java.util.Map<String, String> localVars = new java.util.HashMap<>(superParamValues);
|
||||
constantResolver.evaluateMethodBodyWithLocals(superCtor, localVars, context, new java.util.HashSet<>());
|
||||
for (java.util.Map.Entry<String, String> entry : localVars.entrySet()) {
|
||||
if (entry.getKey().startsWith("this.")) {
|
||||
fieldValues.put(entry.getKey(), entry.getValue());
|
||||
fieldValues.put(entry.getKey().substring(5), entry.getValue());
|
||||
} else if (context.hasField(superTd, entry.getKey())) {
|
||||
fieldValues.put(entry.getKey(), entry.getValue());
|
||||
fieldValues.put("this." + entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
return super.visit(node);
|
||||
}
|
||||
});
|
||||
|
||||
superCtor.getBody().accept(new ASTVisitor() {
|
||||
@Override
|
||||
@@ -591,11 +554,11 @@ public class ConstructorAnalyzer {
|
||||
|
||||
try {
|
||||
Map<String, String> fieldValues = buildFieldValuesFromCIC(td, cic, context, this::evaluateMethodCallInConstructor);
|
||||
System.out.println("RESOLVE_GETTER: td=" + context.getFqn(td) + ", fieldValues=" + fieldValues);
|
||||
log.debug("RESOLVE_GETTER: td={}, fieldValues={}", context.getFqn(td), fieldValues);
|
||||
if (fieldValues.isEmpty()) return Collections.emptyList();
|
||||
|
||||
String result = constantResolver.evaluateMethodBodyWithLocals(getter, fieldValues, context, visited);
|
||||
System.out.println("RESOLVE_GETTER: result=" + result);
|
||||
log.debug("RESOLVE_GETTER: result={}", result);
|
||||
return result != null ? List.of(result) : Collections.emptyList();
|
||||
} finally {
|
||||
visited.remove(getterKey);
|
||||
|
||||
@@ -34,9 +34,7 @@ public class DynamicClasspathResolver {
|
||||
|
||||
protected List<String> resolveMaven(Path projectRoot) {
|
||||
log.info("Maven project detected. Resolving dependencies...");
|
||||
Path cpFile = null;
|
||||
try {
|
||||
cpFile = Files.createTempFile("state_machine_exporter_cp", ".txt");
|
||||
String mvnCmd = getCommand(projectRoot, "mvnw", "mvn");
|
||||
if (mvnCmd == null) {
|
||||
log.warn("Maven executable not found.");
|
||||
@@ -48,26 +46,32 @@ public class DynamicClasspathResolver {
|
||||
"-q",
|
||||
"dependency:build-classpath",
|
||||
"-DincludeScope=compile",
|
||||
"-Dmdep.outputFile=" + cpFile.toAbsolutePath().toString()
|
||||
"-Dmdep.outputFile=sme_cp.txt"
|
||||
);
|
||||
pb.directory(projectRoot.toFile());
|
||||
|
||||
runProcess(pb);
|
||||
|
||||
if (Files.exists(cpFile)) {
|
||||
java.util.Set<String> allPaths = new java.util.LinkedHashSet<>();
|
||||
try (java.util.stream.Stream<Path> stream = Files.walk(projectRoot)) {
|
||||
stream.filter(p -> p.getFileName().toString().equals("sme_cp.txt"))
|
||||
.forEach(cpFile -> {
|
||||
try {
|
||||
String cpString = Files.readString(cpFile).trim();
|
||||
if (!cpString.isEmpty()) {
|
||||
return Arrays.asList(cpString.split(File.pathSeparator));
|
||||
allPaths.addAll(Arrays.asList(cpString.split(File.pathSeparator)));
|
||||
}
|
||||
Files.deleteIfExists(cpFile);
|
||||
} catch (IOException e) {
|
||||
log.warn("Failed to read or delete sme_cp.txt at {}", cpFile, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!allPaths.isEmpty()) {
|
||||
return new ArrayList<>(allPaths);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to dynamically resolve Maven classpath", e);
|
||||
} finally {
|
||||
if (cpFile != null) {
|
||||
try {
|
||||
Files.deleteIfExists(cpFile);
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -107,14 +111,18 @@ public class DynamicClasspathResolver {
|
||||
pb.directory(projectRoot.toFile());
|
||||
|
||||
String output = runProcessAndGetOutput(pb);
|
||||
java.util.Set<String> allPaths = new java.util.LinkedHashSet<>();
|
||||
for (String line : output.split("\\r?\\n")) {
|
||||
if (line.startsWith("SME_CLASSPATH_MARKER:")) {
|
||||
String cpString = line.substring("SME_CLASSPATH_MARKER:".length()).trim();
|
||||
if (!cpString.isEmpty()) {
|
||||
return Arrays.asList(cpString.split(File.pathSeparator));
|
||||
allPaths.addAll(Arrays.asList(cpString.split(File.pathSeparator)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!allPaths.isEmpty()) {
|
||||
return new ArrayList<>(allPaths);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to dynamically resolve Gradle classpath", e);
|
||||
} finally {
|
||||
@@ -143,11 +151,14 @@ public class DynamicClasspathResolver {
|
||||
}
|
||||
|
||||
protected void runProcess(ProcessBuilder pb) throws IOException, InterruptedException {
|
||||
pb.redirectErrorStream(true);
|
||||
pb.redirectOutput(ProcessBuilder.Redirect.DISCARD);
|
||||
Process p = pb.start();
|
||||
p.waitFor();
|
||||
}
|
||||
|
||||
protected String runProcessAndGetOutput(ProcessBuilder pb) throws IOException, InterruptedException {
|
||||
pb.redirectErrorStream(true);
|
||||
Process p = pb.start();
|
||||
StringBuilder out = new StringBuilder();
|
||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
|
||||
|
||||
@@ -20,7 +20,13 @@ public class HeuristicCallGraphEngine extends AbstractCallGraphEngine {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Map<String, List<CallEdge>> buildCallGraph() {
|
||||
Map<String, List<CallEdge>> cached = (Map<String, List<CallEdge>>) context.getCache().get("heuristicCallGraph");
|
||||
if (cached != null) {
|
||||
this.graph = cached;
|
||||
return cached;
|
||||
}
|
||||
graph = new HashMap<>();
|
||||
for (CompilationUnit cu : context.getCompilationUnits()) {
|
||||
cu.accept(new ASTVisitor() {
|
||||
@@ -131,6 +137,7 @@ public class HeuristicCallGraphEngine extends AbstractCallGraphEngine {
|
||||
}
|
||||
});
|
||||
}
|
||||
context.getCache().put("heuristicCallGraph", graph);
|
||||
return graph;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,18 @@ public class JdtCallGraphEngine extends AbstractCallGraphEngine {
|
||||
this.injectionAnalyzer = injectionAnalyzer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<CallEdge>> getCallGraph() {
|
||||
return buildCallGraph();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Map<String, List<CallEdge>> buildCallGraph() {
|
||||
Map<String, List<CallEdge>> cached = (Map<String, List<CallEdge>>) context.getCache().get("jdtCallGraph");
|
||||
if (cached != null) {
|
||||
this.graph = cached;
|
||||
return cached;
|
||||
}
|
||||
graph = new HashMap<>();
|
||||
for (CompilationUnit cu : context.getCompilationUnits()) {
|
||||
cu.accept(new ASTVisitor() {
|
||||
@@ -131,6 +142,7 @@ public class JdtCallGraphEngine extends AbstractCallGraphEngine {
|
||||
}
|
||||
});
|
||||
}
|
||||
context.getCache().put("jdtCallGraph", graph);
|
||||
return graph;
|
||||
}
|
||||
|
||||
@@ -155,7 +167,11 @@ public class JdtCallGraphEngine extends AbstractCallGraphEngine {
|
||||
}
|
||||
|
||||
// Delegate to base class for lambda, method reference, and constructor unwrapping
|
||||
return super.resolveArgument(expr);
|
||||
String result = super.resolveArgument(expr);
|
||||
if (result != null) {
|
||||
result = result.replaceAll("->\\s*yield\\s+", "-> ");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected String resolveCalledMethod(MethodInvocation node) {
|
||||
@@ -185,16 +201,16 @@ public class JdtCallGraphEngine extends AbstractCallGraphEngine {
|
||||
nameBinding = fa.resolveFieldBinding();
|
||||
}
|
||||
if (nameBinding instanceof IVariableBinding varBinding) {
|
||||
System.out.println("CALLGRAPH RESOLVING BEAN FOR BINDING: " + varBinding.getName() + " calling " + methodName);
|
||||
log.debug("CALLGRAPH RESOLVING BEAN FOR BINDING: {} calling {}", varBinding.getName(), methodName);
|
||||
String concreteFqn = injectionAnalyzer.resolveInjectedBeanFqn(varBinding);
|
||||
if (concreteFqn != null) {
|
||||
System.out.println(" -> RESOLVED CONCRETE FQN: " + concreteFqn);
|
||||
log.debug(" -> RESOLVED CONCRETE FQN: {}", concreteFqn);
|
||||
return concreteFqn + "." + methodName;
|
||||
} else {
|
||||
System.out.println(" -> RESOLVE FAILED, RETURNED NULL");
|
||||
log.debug(" -> RESOLVE FAILED, RETURNED NULL");
|
||||
}
|
||||
} else {
|
||||
System.out.println("CALLGRAPH NAME BINDING IS NOT VARIABLE: " + nameBinding + " calling " + methodName);
|
||||
log.debug("CALLGRAPH NAME BINDING IS NOT VARIABLE: {} calling {}", nameBinding, methodName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ public class JdtIntelligenceProvider implements CodebaseIntelligenceProvider {
|
||||
private final LifecycleDetector lifecycleDetector;
|
||||
private final InterceptorDetector interceptorDetector;
|
||||
private final SpringComponentDetector componentDetector;
|
||||
private List<TriggerPoint> cachedTriggers;
|
||||
private List<EntryPoint> cachedEntryPoints;
|
||||
|
||||
public JdtIntelligenceProvider(CodebaseContext context, Path rootDir) {
|
||||
this.context = context;
|
||||
@@ -54,6 +56,9 @@ public class JdtIntelligenceProvider implements CodebaseIntelligenceProvider {
|
||||
|
||||
@Override
|
||||
public List<TriggerPoint> findTriggerPoints() {
|
||||
if (cachedTriggers != null) {
|
||||
return cachedTriggers;
|
||||
}
|
||||
List<TriggerPoint> allTriggers = new ArrayList<>();
|
||||
var cus = context.getCompilationUnits();
|
||||
log.info("JdtIntelligenceProvider scanning {} compilation units for triggers", cus.size());
|
||||
@@ -62,11 +67,15 @@ public class JdtIntelligenceProvider implements CodebaseIntelligenceProvider {
|
||||
allTriggers.addAll(lifecycleDetector.detect(cu));
|
||||
}
|
||||
log.info("Found {} triggers (including lifecycle) in total", allTriggers.size());
|
||||
cachedTriggers = allTriggers;
|
||||
return allTriggers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EntryPoint> findEntryPoints() {
|
||||
if (cachedEntryPoints != null) {
|
||||
return cachedEntryPoints;
|
||||
}
|
||||
List<EntryPoint> allEntryPoints = new ArrayList<>();
|
||||
var cus = context.getCompilationUnits();
|
||||
log.info("JdtIntelligenceProvider scanning {} compilation units for entry points", cus.size());
|
||||
@@ -77,6 +86,7 @@ public class JdtIntelligenceProvider implements CodebaseIntelligenceProvider {
|
||||
allEntryPoints.addAll(componentDetector.detect(cu));
|
||||
}
|
||||
log.info("Found {} entry points (including interceptors and listeners) in total", allEntryPoints.size());
|
||||
cachedEntryPoints = allEntryPoints;
|
||||
return allEntryPoints;
|
||||
}
|
||||
|
||||
|
||||
@@ -110,12 +110,44 @@ public class VariableTracer {
|
||||
if (superFqn != null) {
|
||||
TypeDeclaration superTd = context.getTypeDeclaration(superFqn);
|
||||
if (superTd != null) {
|
||||
return getFieldType(superTd, fieldName, context, visited);
|
||||
String result = getFieldType(superTd, fieldName, context, visited);
|
||||
if (result != null) return result;
|
||||
}
|
||||
}
|
||||
|
||||
for (Object intfObj : td.superInterfaceTypes()) {
|
||||
Type intfType = (Type) intfObj;
|
||||
String intfName = click.kamil.springstatemachineexporter.ast.common.AstUtils.extractSimpleTypeName(intfType);
|
||||
String resolvedIntf = resolveTypeFqn(intfName, context, td);
|
||||
if (resolvedIntf != null) {
|
||||
TypeDeclaration intfTd = context.getTypeDeclaration(resolvedIntf);
|
||||
if (intfTd != null) {
|
||||
String result = getFieldType(intfTd, fieldName, context, visited);
|
||||
if (result != null) return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String resolveTypeFqn(String simpleName, CodebaseContext context, TypeDeclaration td) {
|
||||
CompilationUnit cu = td.getRoot() instanceof CompilationUnit ? (CompilationUnit) td.getRoot() : null;
|
||||
if (cu != null) {
|
||||
for (Object impObj : cu.imports()) {
|
||||
ImportDeclaration imp = (ImportDeclaration) impObj;
|
||||
String name = imp.getName().getFullyQualifiedName();
|
||||
if (name.endsWith("." + simpleName)) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
if (cu.getPackage() != null) {
|
||||
return cu.getPackage().getName().getFullyQualifiedName() + "." + simpleName;
|
||||
}
|
||||
}
|
||||
return simpleName;
|
||||
}
|
||||
|
||||
public String getVariableDeclaredType(String methodFqn, String cleanFieldName) {
|
||||
if (methodFqn == null) return null;
|
||||
int lastDot = methodFqn.lastIndexOf('.');
|
||||
@@ -294,14 +326,16 @@ public class VariableTracer {
|
||||
stringified.add(traced.toString());
|
||||
}
|
||||
}
|
||||
if (stringified.size() == 1) return stringified.get(0);
|
||||
if (stringified.size() == 1) {
|
||||
return stringified.get(0).replaceAll("->\\s*yield\\s+", "-> ");
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < stringified.size() - 1; i++) {
|
||||
sb.append("true ? ").append(stringified.get(i)).append(" : ");
|
||||
}
|
||||
sb.append(stringified.get(stringified.size() - 1));
|
||||
return sb.toString();
|
||||
return sb.toString().replaceAll("->\\s*yield\\s+", "-> ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ public class SpringContextScanner extends ASTVisitor {
|
||||
.isPrimary(hasPrimaryMethod(methodBinding, node))
|
||||
.qualifiers(extractQualifiers(methodBinding))
|
||||
.order(extractOrder(methodBinding))
|
||||
.declaringClassFqn(methodBinding.getDeclaringClass().getQualifiedName())
|
||||
.declaringClassFqn(methodBinding.getDeclaringClass() != null ? methodBinding.getDeclaringClass().getQualifiedName() : null)
|
||||
.factoryMethodName(node.getName().getIdentifier())
|
||||
.build();
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class SpringDependencyResolver {
|
||||
private final SpringBeanRegistry registry;
|
||||
|
||||
@@ -21,16 +24,16 @@ public class SpringDependencyResolver {
|
||||
*/
|
||||
public List<SpringBean> resolve(String requiredTypeFqn, String qualifier, String injectionName) {
|
||||
if (requiredTypeFqn == null) return new ArrayList<>();
|
||||
log.debug("RESOLVING {} qual={} injectionName={}", requiredTypeFqn, qualifier, injectionName);
|
||||
|
||||
// 1. Filter by Type (Exact FQN or Assignable Type)
|
||||
System.out.println("RESOLVING " + requiredTypeFqn + " qual=" + qualifier + " injectionName=" + injectionName);
|
||||
List<SpringBean> candidates = registry.getBeans().stream()
|
||||
.filter(bean -> requiredTypeFqn.equals(bean.getTypeFqn()) || bean.getAssignableTypes().contains(requiredTypeFqn))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
System.out.println("CANDIDATES AFTER TYPE: " + candidates.stream().map(c -> c.getTypeFqn() + " (primary=" + c.isPrimary() + " names=" + c.getBeanNames() + " qual=" + c.getQualifiers() + ")").collect(Collectors.toList()));
|
||||
log.debug("CANDIDATES AFTER TYPE: {}", candidates.stream().map(c -> c.getTypeFqn() + " (primary=" + c.isPrimary() + " names=" + c.getBeanNames() + " qual=" + c.getQualifiers() + ")").collect(Collectors.toList()));
|
||||
if (candidates.isEmpty() || candidates.size() == 1) {
|
||||
System.out.println("RETURNING: " + candidates.size());
|
||||
log.debug("RETURNING: {}", candidates.size());
|
||||
return candidates;
|
||||
}
|
||||
|
||||
@@ -81,7 +84,7 @@ public class SpringDependencyResolver {
|
||||
}
|
||||
|
||||
// Return whatever candidates remain (could be ambiguous)
|
||||
System.out.println("RETURNING: " + candidates.size());
|
||||
log.debug("RETURNING: {}", candidates.size());
|
||||
return candidates;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,15 +239,31 @@ public class AstTransitionParser {
|
||||
} else {
|
||||
t.setEvent(Event.of(QuotedExpression.of(resolved).toStringWithoutQuotes()));
|
||||
}
|
||||
if (args.size() > 1) {
|
||||
Expression actionArg = resolveArg((Expression) args.get(1), argsMap);
|
||||
parseAction(actionArg, t, cu, context);
|
||||
}
|
||||
}
|
||||
case "guard", "guardExpression" -> {
|
||||
Expression resolved = resolveArg((Expression) args.get(0), argsMap);
|
||||
parseGuard(resolved, t, cu, context);
|
||||
}
|
||||
case "guards" -> {
|
||||
args.forEach(arg -> {
|
||||
Expression resolved = resolveArg((Expression) arg, argsMap);
|
||||
parseGuard(resolved, t, cu, context);
|
||||
});
|
||||
}
|
||||
case "action" -> {
|
||||
Expression resolved = resolveArg((Expression) args.get(0), argsMap);
|
||||
parseAction(resolved, t, cu, context);
|
||||
}
|
||||
case "actions" -> {
|
||||
args.forEach(arg -> {
|
||||
Expression resolved = resolveArg((Expression) arg, argsMap);
|
||||
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() + ")"));
|
||||
@@ -521,7 +537,7 @@ public class AstTransitionParser {
|
||||
TypeDeclaration td = findEnclosingType(quotedExpr.getExpression());
|
||||
String fqn = td != null ? context.getFqn(td) : null;
|
||||
String sourceFile = fqn != null ? context.getRelativePath(fqn) : null;
|
||||
t.setGuard(Guard.of(quotedExpr.toStringWithoutQuotes(), isLambdaOrAnonymous(quotedExpr.getExpression()), internalLogic, lineNumber, fqn, sourceFile));
|
||||
t.getGuards().add(Guard.of(quotedExpr.toStringWithoutQuotes(), isLambdaOrAnonymous(quotedExpr.getExpression()), internalLogic, lineNumber, fqn, sourceFile));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,9 +22,10 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import click.kamil.springstatemachineexporter.spi.SourceContext;
|
||||
|
||||
@Slf4j
|
||||
public class CodebaseContext {
|
||||
public class CodebaseContext implements SourceContext {
|
||||
private final Map<String, CompilationUnit> classes = new HashMap<>();
|
||||
private final Map<String, Path> classPaths = new HashMap<>();
|
||||
private final Map<String, String> simpleNameToFqn = new HashMap<>();
|
||||
@@ -41,11 +42,21 @@ public class CodebaseContext {
|
||||
private List<LibraryHint> libraryHints = new ArrayList<>();
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private Path projectRoot;
|
||||
private final Map<String, Object> cache = new HashMap<>();
|
||||
|
||||
public Map<String, Object> getCache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
public void setProjectRoot(Path root) {
|
||||
this.projectRoot = root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getProjectRoot() {
|
||||
return projectRoot;
|
||||
}
|
||||
|
||||
public String getRelativePath(Path fullPath) {
|
||||
if (projectRoot != null && fullPath.isAbsolute() && fullPath.startsWith(projectRoot)) {
|
||||
return projectRoot.relativize(fullPath).toString();
|
||||
@@ -83,6 +94,10 @@ public class CodebaseContext {
|
||||
this.classpath = classpath.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public List<String> getClasspath() {
|
||||
return java.util.Arrays.asList(classpath);
|
||||
}
|
||||
|
||||
public void setSourcepath(List<String> sourcepath) {
|
||||
this.sourcepath = sourcepath.toArray(new String[0]);
|
||||
}
|
||||
@@ -378,7 +393,7 @@ public class CodebaseContext {
|
||||
String fqn = simpleNameToFqn.get(cleanName);
|
||||
if (fqn != null) values = enumValues.get(fqn);
|
||||
}
|
||||
System.out.println("DEBUG getEnumValues called for: " + fqnOrSimpleName + " resolved to " + cleanName + ". Returns: " + values);
|
||||
log.debug("getEnumValues called for: {} resolved to {}. Returns: {}", fqnOrSimpleName, cleanName, values);
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,9 @@ package click.kamil.springstatemachineexporter.ast.common;
|
||||
import org.eclipse.jdt.core.dom.*;
|
||||
import java.util.*;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class JdtDataFlowModel implements DataFlowModel {
|
||||
private final CodebaseContext context;
|
||||
private final Map<MethodDeclaration, ControlFlowGraph> cfgCache = new HashMap<>();
|
||||
@@ -436,7 +439,8 @@ public class JdtDataFlowModel implements DataFlowModel {
|
||||
currentParamValues.put(paramVb, resolvedArg);
|
||||
}
|
||||
}
|
||||
System.out.println("EVAL_CTOR: cd=" + cd.getName() + ", currentParamValues=" + currentParamValues);
|
||||
|
||||
log.debug("EVAL_CTOR: cd={}, currentParamValues={}", cd.getName(), currentParamValues);
|
||||
|
||||
List<?> statements = cd.getBody().statements();
|
||||
if (!statements.isEmpty()) {
|
||||
|
||||
@@ -107,13 +107,19 @@ public class Dot implements StateMachineExporter {
|
||||
}
|
||||
}
|
||||
|
||||
// Guard
|
||||
if (t.getGuard() != null && !t.getGuard().expression().isBlank()) {
|
||||
// Guards
|
||||
if (t.getGuards() != null && !t.getGuards().isEmpty()) {
|
||||
if (!label.isEmpty())
|
||||
label.append(" ");
|
||||
String guardText = options.isUseLambdaGuards() && t.getGuard().isLambda() ? "λ"
|
||||
: escapeDotString(t.getGuard().expression().replaceAll("[\\n\\r]+", " ").replaceAll("\\s{2,}", " ").trim());
|
||||
label.append("[").append(guardText).append("]");
|
||||
label.append("[");
|
||||
for (int i = 0; i < t.getGuards().size(); i++) {
|
||||
if (i > 0) label.append(" && ");
|
||||
var guard = t.getGuards().get(i);
|
||||
String guardText = options.isUseLambdaGuards() && guard.isLambda() ? "λ"
|
||||
: escapeDotString(guard.expression().replaceAll("[\\n\\r]+", " ").replaceAll("\\s{2,}", " ").trim());
|
||||
label.append(guardText);
|
||||
}
|
||||
label.append("]");
|
||||
}
|
||||
|
||||
// Actions
|
||||
|
||||
@@ -203,14 +203,21 @@ public class PlantUml implements StateMachineExporter {
|
||||
parts.add(eventStr);
|
||||
}
|
||||
}
|
||||
if (t.getGuard() != null) {
|
||||
String g = t.getGuard().expression();
|
||||
if (options.isUseLambdaGuards() && t.getGuard().isLambda()) {
|
||||
parts.add("[" + LAMBDA + "]");
|
||||
if (t.getGuards() != null && !t.getGuards().isEmpty()) {
|
||||
StringBuilder guardsBuilder = new StringBuilder();
|
||||
guardsBuilder.append("[");
|
||||
for (int i = 0; i < t.getGuards().size(); i++) {
|
||||
if (i > 0) guardsBuilder.append(" && ");
|
||||
var guard = t.getGuards().get(i);
|
||||
if (options.isUseLambdaGuards() && guard.isLambda()) {
|
||||
guardsBuilder.append(LAMBDA);
|
||||
} else {
|
||||
parts.add("[" + g.replaceAll("[\\n\\r]+", " ").replaceAll("\\s{2,}", " ").trim() + "]");
|
||||
guardsBuilder.append(guard.expression().replaceAll("[\\n\\r]+", " ").replaceAll("\\s{2,}", " ").trim());
|
||||
}
|
||||
}
|
||||
guardsBuilder.append("]");
|
||||
parts.add(guardsBuilder.toString());
|
||||
}
|
||||
if (t.getActions() != null && !t.getActions().isEmpty()) {
|
||||
parts.add("/ " + t.getActions().stream()
|
||||
.map(a -> (options.isUseLambdaGuards() && a.isLambda()) ? LAMBDA : a.expression().replaceAll("[\\n\\r]+", " ").replaceAll("\\s{2,}", " ").trim())
|
||||
|
||||
@@ -102,12 +102,20 @@ public class Scxml implements StateMachineExporter {
|
||||
}
|
||||
|
||||
private static String getGuardText(Transition t, boolean useLambdaGuards) {
|
||||
if (t.getGuard() == null || t.getGuard().expression().isBlank())
|
||||
if (t.getGuards() == null || t.getGuards().isEmpty())
|
||||
return "";
|
||||
if (useLambdaGuards && t.getGuard().isLambda()) {
|
||||
return LAMBDA;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < t.getGuards().size(); i++) {
|
||||
if (i > 0) sb.append(" && ");
|
||||
var guard = t.getGuards().get(i);
|
||||
if (useLambdaGuards && guard.isLambda()) {
|
||||
sb.append(LAMBDA);
|
||||
} else {
|
||||
sb.append(guard.expression().replaceAll("[\\n\\r]+", " ").replaceAll("\\s{2,}", " ").trim());
|
||||
}
|
||||
return t.getGuard().expression().replaceAll("[\\n\\r]+", " ").replaceAll("\\s{2,}", " ").trim();
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String escapeXml(String s) {
|
||||
|
||||
@@ -16,7 +16,7 @@ public class Transition {
|
||||
private List<State> targetStates = new ArrayList<>();
|
||||
private Event event;
|
||||
|
||||
private Guard guard;
|
||||
private List<Guard> guards = new ArrayList<>();
|
||||
private List<Action> actions = new ArrayList<>();
|
||||
|
||||
private Integer order = null; // optional order for withChoice or withJunction
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
package click.kamil.springstatemachineexporter.plugin.java;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.model.AnalysisResult;
|
||||
import click.kamil.springstatemachineexporter.analysis.service.CallGraphEngine;
|
||||
import click.kamil.springstatemachineexporter.analysis.service.CodebaseIntelligenceProvider;
|
||||
import click.kamil.springstatemachineexporter.analysis.service.JdtCallGraphEngine;
|
||||
import click.kamil.springstatemachineexporter.analysis.service.JdtIntelligenceProvider;
|
||||
import click.kamil.springstatemachineexporter.ast.app.AstTransitionParser;
|
||||
import click.kamil.springstatemachineexporter.ast.app.StateMachineAggregator;
|
||||
import click.kamil.springstatemachineexporter.ast.app.TransitionStateUtils;
|
||||
import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
|
||||
import click.kamil.springstatemachineexporter.model.Transition;
|
||||
import click.kamil.springstatemachineexporter.spi.LanguageAnalyzerPlugin;
|
||||
import click.kamil.springstatemachineexporter.spi.SourceContext;
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
public class JavaLanguageAnalyzerPlugin implements LanguageAnalyzerPlugin {
|
||||
|
||||
@Override
|
||||
public boolean supports(Path projectRoot) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceContext parseProject(Path projectRoot, List<String> classpath, Set<Path> sourcePaths) {
|
||||
CodebaseContext context = new CodebaseContext();
|
||||
context.setProjectRoot(projectRoot);
|
||||
if (classpath != null && !classpath.isEmpty()) {
|
||||
context.setClasspath(classpath);
|
||||
}
|
||||
|
||||
Path hintsFile = projectRoot.resolve("hints.json");
|
||||
if (!java.nio.file.Files.exists(hintsFile)) {
|
||||
hintsFile = projectRoot.resolve("src/main/resources/hints.json");
|
||||
}
|
||||
if (java.nio.file.Files.exists(hintsFile)) {
|
||||
try {
|
||||
context.loadLibraryHints(hintsFile);
|
||||
} catch (java.io.IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> sp = sourcePaths.stream()
|
||||
.map(p -> p.resolve("src/main/java"))
|
||||
.filter(p -> java.nio.file.Files.exists(p))
|
||||
.map(Path::toString)
|
||||
.toList();
|
||||
if (sp.isEmpty()) {
|
||||
sp = sourcePaths.stream().map(Path::toString).toList();
|
||||
}
|
||||
context.setSourcepath(sp);
|
||||
|
||||
context.setResolveBindings(true);
|
||||
try {
|
||||
context.scan(sourcePaths, Collections.emptySet());
|
||||
} catch (java.io.IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallGraphEngine createCallGraphEngine(SourceContext context) {
|
||||
if (context instanceof CodebaseContext jdtContext) {
|
||||
return new JdtCallGraphEngine(jdtContext, null);
|
||||
}
|
||||
throw new IllegalArgumentException("Expected CodebaseContext");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodebaseIntelligenceProvider createIntelligenceProvider(SourceContext context) {
|
||||
if (context instanceof CodebaseContext jdtContext) {
|
||||
return new JdtIntelligenceProvider(jdtContext, jdtContext.getProjectRoot());
|
||||
}
|
||||
throw new IllegalArgumentException("Expected CodebaseContext");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AnalysisResult> extractStateMachines(SourceContext context, boolean renderChoicesAsDiamonds) {
|
||||
if (context instanceof CodebaseContext jdtContext) {
|
||||
List<AnalysisResult> results = new ArrayList<>();
|
||||
|
||||
// 1. Find entry point classes (annotated or extending adapter)
|
||||
List<TypeDeclaration> entryPoints = jdtContext.findEntryPointClasses(List.of("EnableStateMachineFactory", "EnableStateMachine"));
|
||||
for (TypeDeclaration td : entryPoints) {
|
||||
String className = jdtContext.getFqn(td);
|
||||
StateMachineAggregator aggregator = new StateMachineAggregator(jdtContext);
|
||||
List<Transition> transitions = aggregator.aggregateTransitions(td);
|
||||
aggregator.aggregateStates(td);
|
||||
Set<String> initialStatesAst = aggregator.getInitialStates();
|
||||
Set<String> endStatesAst = aggregator.getEndStates();
|
||||
|
||||
Set<String> startStates = TransitionStateUtils.findStartStates(transitions, initialStatesAst);
|
||||
Set<String> endStates = TransitionStateUtils.findEndStates(transitions, endStatesAst);
|
||||
Set<click.kamil.springstatemachineexporter.model.State> allStates = TransitionStateUtils.findAllStates(transitions, initialStatesAst, endStatesAst);
|
||||
|
||||
if (allStates.isEmpty() && transitions.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
results.add(AnalysisResult.builder()
|
||||
.name(className)
|
||||
.states(allStates)
|
||||
.transitions(transitions)
|
||||
.startStates(startStates)
|
||||
.endStates(endStates)
|
||||
.renderChoicesAsDiamonds(renderChoicesAsDiamonds)
|
||||
.build());
|
||||
}
|
||||
|
||||
// 2. Find methods returning StateMachine beans
|
||||
List<MethodDeclaration> beanMethods = jdtContext.findBeanMethodsReturning(Set.of("StateMachine", "StateMachineFactory", "StateMachineModelFactory"));
|
||||
for (MethodDeclaration m : beanMethods) {
|
||||
TypeDeclaration parentClass = (TypeDeclaration) m.getParent();
|
||||
String parentFqn = jdtContext.getFqn(parentClass);
|
||||
String methodName = m.getName().getIdentifier();
|
||||
String uniqueName = parentFqn + "#" + methodName;
|
||||
|
||||
List<Transition> transitions = AstTransitionParser.parseTransitions(m, jdtContext);
|
||||
|
||||
Set<String> startStates = TransitionStateUtils.findStartStates(transitions, null);
|
||||
Set<String> endStates = TransitionStateUtils.findEndStates(transitions, null);
|
||||
Set<click.kamil.springstatemachineexporter.model.State> allStates = TransitionStateUtils.findAllStates(transitions, null, null);
|
||||
|
||||
if (allStates.isEmpty() && transitions.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
results.add(AnalysisResult.builder()
|
||||
.name(uniqueName)
|
||||
.states(allStates)
|
||||
.transitions(transitions)
|
||||
.startStates(startStates)
|
||||
.endStates(endStates)
|
||||
.renderChoicesAsDiamonds(renderChoicesAsDiamonds)
|
||||
.build());
|
||||
}
|
||||
return results;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,11 @@ import click.kamil.springstatemachineexporter.exporter.StateMachineExporter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import click.kamil.springstatemachineexporter.spi.LanguageAnalyzerPlugin;
|
||||
import click.kamil.springstatemachineexporter.spi.SourceContext;
|
||||
import click.kamil.springstatemachineexporter.analysis.service.CompositeIntelligenceProvider;
|
||||
import click.kamil.springstatemachineexporter.analysis.service.CallGraphEngine;
|
||||
import click.kamil.springstatemachineexporter.analysis.service.JdtCallGraphEngine;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
@@ -137,8 +142,57 @@ public class ExportService {
|
||||
|
||||
context.scan(allPaths, Collections.emptySet());
|
||||
|
||||
CodebaseIntelligenceProvider intelligence = new JdtIntelligenceProvider(context, inputDir);
|
||||
exportAll(context, intelligence, outputDir, selectedFormats, renderChoicesAsDiamonds, flows, machineFilter, activeProfiles != null ? activeProfiles : Collections.emptyList(), eventFormat, stateFormat);
|
||||
// Load SPI plugins dynamically
|
||||
ServiceLoader<LanguageAnalyzerPlugin> loader = ServiceLoader.load(LanguageAnalyzerPlugin.class);
|
||||
List<LanguageAnalyzerPlugin> plugins = new ArrayList<>();
|
||||
for (LanguageAnalyzerPlugin plugin : loader) {
|
||||
if (plugin.supports(inputDir)) {
|
||||
plugins.add(plugin);
|
||||
}
|
||||
}
|
||||
if (plugins.isEmpty()) {
|
||||
plugins.add(new click.kamil.springstatemachineexporter.plugin.java.JavaLanguageAnalyzerPlugin());
|
||||
}
|
||||
|
||||
List<SourceContext> sourceContexts = new ArrayList<>();
|
||||
List<CodebaseIntelligenceProvider> providers = new ArrayList<>();
|
||||
List<CallGraphEngine> engines = new ArrayList<>();
|
||||
List<AnalysisResult> extractedResults = new ArrayList<>();
|
||||
|
||||
for (LanguageAnalyzerPlugin plugin : plugins) {
|
||||
SourceContext sc = plugin.parseProject(projectRoot, context.getClasspath(), allPaths);
|
||||
sourceContexts.add(sc);
|
||||
providers.add(plugin.createIntelligenceProvider(sc));
|
||||
engines.add(plugin.createCallGraphEngine(sc));
|
||||
extractedResults.addAll(plugin.extractStateMachines(sc, renderChoicesAsDiamonds));
|
||||
}
|
||||
|
||||
CodebaseContext codebaseContext = context;
|
||||
CodebaseIntelligenceProvider unifiedIntelligence;
|
||||
if (plugins.size() == 1) {
|
||||
unifiedIntelligence = providers.get(0);
|
||||
if (sourceContexts.get(0) instanceof CodebaseContext jdtCtx) {
|
||||
codebaseContext = jdtCtx;
|
||||
}
|
||||
} else {
|
||||
unifiedIntelligence = new CompositeIntelligenceProvider(providers, engines);
|
||||
}
|
||||
|
||||
// Process all extracted state machines
|
||||
for (AnalysisResult result : extractedResults) {
|
||||
String name = result.getName();
|
||||
if (machineFilter != null && !name.contains(machineFilter)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (result.getFlows() == null || result.getFlows().isEmpty()) {
|
||||
result.setFlows(flows);
|
||||
}
|
||||
|
||||
enrichmentService.enrich(result, codebaseContext, unifiedIntelligence);
|
||||
resolveProperties(result, activeProfiles);
|
||||
generateOutputs(outputDir, result, selectedFormats, eventFormat, stateFormat);
|
||||
}
|
||||
}
|
||||
|
||||
public void runJsonExporter(Path jsonFile, Path outputDir, List<String> selectedFormats) throws IOException {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package click.kamil.springstatemachineexporter.spi;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.service.CallGraphEngine;
|
||||
import click.kamil.springstatemachineexporter.analysis.service.CodebaseIntelligenceProvider;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Service Provider Interface (SPI) for introducing support for different languages (Java, Kotlin, etc.).
|
||||
*/
|
||||
public interface LanguageAnalyzerPlugin {
|
||||
|
||||
/**
|
||||
* Determines if this plugin is capable of handling the provided project root.
|
||||
* Often checks for file extensions (.kt, .java) within the root.
|
||||
*/
|
||||
boolean supports(Path projectRoot);
|
||||
|
||||
/**
|
||||
* Parses the codebase and sets up a SourceContext loaded with the language's AST structures.
|
||||
*/
|
||||
SourceContext parseProject(Path projectRoot, List<String> classpath, Set<Path> sourcePaths);
|
||||
|
||||
/**
|
||||
* Creates a CallGraphEngine specialized for this language's syntax and paradigms.
|
||||
*/
|
||||
CallGraphEngine createCallGraphEngine(SourceContext context);
|
||||
|
||||
/**
|
||||
* Creates a CodebaseIntelligenceProvider specialized for this language to discover
|
||||
* Spring State Machine configurations, entry points, and transitions.
|
||||
*/
|
||||
CodebaseIntelligenceProvider createIntelligenceProvider(SourceContext context);
|
||||
|
||||
/**
|
||||
* Finds and extracts all Spring State Machine models (configurations and beans) from the project.
|
||||
*/
|
||||
default List<click.kamil.springstatemachineexporter.analysis.model.AnalysisResult> extractStateMachines(SourceContext context, boolean renderChoicesAsDiamonds) {
|
||||
return java.util.Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package click.kamil.springstatemachineexporter.spi;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.model.LibraryHint;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An abstraction over a parsed source codebase (Java, Kotlin, etc.).
|
||||
* Provides access to common metadata required by analysis engines.
|
||||
*/
|
||||
public interface SourceContext {
|
||||
/**
|
||||
* Gets the root directory of the scanned project.
|
||||
*/
|
||||
Path getProjectRoot();
|
||||
|
||||
/**
|
||||
* Relativizes an absolute path against the project root.
|
||||
*/
|
||||
String getRelativePath(Path fullPath);
|
||||
|
||||
/**
|
||||
* Returns a relative file path for a given fully qualified class/type name.
|
||||
*/
|
||||
String getRelativePath(String fqn);
|
||||
|
||||
/**
|
||||
* Retrieves any loaded library hints (e.g. from hints.json).
|
||||
*/
|
||||
List<LibraryHint> getLibraryHints();
|
||||
|
||||
/**
|
||||
* Retrieves application properties (e.g. from application.yml).
|
||||
*/
|
||||
Map<String, Map<String, String>> getProperties();
|
||||
|
||||
/**
|
||||
* Gets an unstructured cache map that plugins can use to share data across processing phases.
|
||||
*/
|
||||
Map<String, Object> getCache();
|
||||
}
|
||||
@@ -125,4 +125,26 @@ class HeuristicEventMatchingEngineTest {
|
||||
|
||||
assertThat(engine.matches(smEvent, triggerPoint)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldMatchWildcardIfTypeMatches() {
|
||||
Event smEvent = Event.of("PAY", "com.example.OrderEvents.PAY");
|
||||
TriggerPoint triggerPoint = TriggerPoint.builder()
|
||||
.event("event")
|
||||
.eventTypeFqn("com.example.OrderEvents")
|
||||
.build();
|
||||
|
||||
assertThat(engine.matches(smEvent, triggerPoint)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotMatchWildcardIfTypeMismatches() {
|
||||
Event smEvent = Event.of("PAY", "com.example.InvoiceEvents.PAY");
|
||||
TriggerPoint triggerPoint = TriggerPoint.builder()
|
||||
.event("event")
|
||||
.eventTypeFqn("com.example.OrderEvents")
|
||||
.build();
|
||||
|
||||
assertThat(engine.matches(smEvent, triggerPoint)).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package click.kamil.springstatemachineexporter.analysis.resolver;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Set;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class RelativePathTest {
|
||||
@Test
|
||||
public void testRelativePathDirectory(@TempDir Path tempDir) throws Exception {
|
||||
Path rootDir = tempDir.resolve("root");
|
||||
Path childDir = tempDir.resolve("child");
|
||||
Files.createDirectories(rootDir);
|
||||
Files.createDirectories(childDir);
|
||||
|
||||
Files.writeString(rootDir.resolve("pom.xml"), "<project><groupId>com.acme</groupId><artifactId>root</artifactId></project>");
|
||||
Files.writeString(childDir.resolve("pom.xml"), "<project><parent><relativePath>../root</relativePath></parent></project>");
|
||||
|
||||
SiblingDependencyResolver resolver = new SiblingDependencyResolver();
|
||||
Set<Path> siblings = resolver.resolveSiblings(childDir);
|
||||
assertTrue(siblings.contains(rootDir), "Should resolve parent directory from <relativePath>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelativePathFile(@TempDir Path tempDir) throws Exception {
|
||||
Path rootDir = tempDir.resolve("root");
|
||||
Path childDir = tempDir.resolve("child");
|
||||
Files.createDirectories(rootDir);
|
||||
Files.createDirectories(childDir);
|
||||
|
||||
Files.writeString(rootDir.resolve("pom.xml"), "<project><groupId>com.acme</groupId><artifactId>root</artifactId></project>");
|
||||
Files.writeString(childDir.resolve("pom.xml"), "<project><parent><relativePath>../root/pom.xml</relativePath></parent></project>");
|
||||
|
||||
SiblingDependencyResolver resolver = new SiblingDependencyResolver();
|
||||
Set<Path> siblings = resolver.resolveSiblings(childDir);
|
||||
assertTrue(siblings.contains(rootDir), "Should resolve parent directory from <relativePath> file");
|
||||
}
|
||||
}
|
||||
@@ -66,4 +66,59 @@ class BuilderLocalVariableTest {
|
||||
assertThat(chain.getTriggerPoint().getPolymorphicEvents())
|
||||
.containsExactlyInAnyOrder("OrderEvents.PAY");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldTraceFluentBuilder(@TempDir Path tempDir) throws IOException {
|
||||
String source = """
|
||||
package com.example;
|
||||
public class MyController {
|
||||
private MyService service;
|
||||
public void processEvent() {
|
||||
MyEvent event = MyEvent.builder().type(MyEnum.STATE_2).build();
|
||||
service.process(event.getType());
|
||||
}
|
||||
}
|
||||
|
||||
class MyService {
|
||||
public void process(MyEnum event) {}
|
||||
}
|
||||
|
||||
class MyEvent {
|
||||
private MyEnum type;
|
||||
public static Builder builder() { return new Builder(); }
|
||||
public MyEnum getType() { return type; }
|
||||
public static class Builder {
|
||||
private MyEnum type;
|
||||
public Builder type(MyEnum type) { this.type = type; return this; }
|
||||
public MyEvent build() { return new MyEvent(); }
|
||||
}
|
||||
}
|
||||
|
||||
enum MyEnum { STATE_1, STATE_2 }
|
||||
""";
|
||||
Files.writeString(tempDir.resolve("MyConfig.java"), source);
|
||||
|
||||
CodebaseContext context = new CodebaseContext();
|
||||
context.scan(tempDir);
|
||||
|
||||
HeuristicCallGraphEngine builder = new HeuristicCallGraphEngine(context);
|
||||
|
||||
EntryPoint entryPoint = EntryPoint.builder()
|
||||
.className("com.example.MyController")
|
||||
.methodName("processEvent")
|
||||
.build();
|
||||
|
||||
TriggerPoint trigger = TriggerPoint.builder()
|
||||
.className("com.example.MyService")
|
||||
.methodName("process")
|
||||
.event("event")
|
||||
.build();
|
||||
|
||||
List<CallChain> chains = builder.findChains(List.of(entryPoint), List.of(trigger));
|
||||
|
||||
assertThat(chains).hasSize(1);
|
||||
CallChain chain = chains.get(0);
|
||||
assertThat(chain.getTriggerPoint().getPolymorphicEvents())
|
||||
.containsExactlyInAnyOrder("MyEnum.STATE_2");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class DynamicClasspathResolverTest {
|
||||
.filter(arg -> arg.startsWith("-Dmdep.outputFile="))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
Path outputFile = Path.of(outputFileArg.substring("-Dmdep.outputFile=".length()));
|
||||
Path outputFile = pb.directory().toPath().resolve(outputFileArg.substring("-Dmdep.outputFile=".length()));
|
||||
|
||||
Files.writeString(outputFile, cp);
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ class EnterpriseBugsTest {
|
||||
|
||||
Files.writeString(tempDir.resolve("OrderConfig.java"), source);
|
||||
CodebaseContext context = new CodebaseContext();
|
||||
context.setResolveBindings(true);
|
||||
context.scan(tempDir);
|
||||
|
||||
HeuristicCallGraphEngine engine = new HeuristicCallGraphEngine(context);
|
||||
|
||||
@@ -1036,4 +1036,47 @@ class HeuristicCallGraphEngineCoreTest {
|
||||
org.assertj.core.api.Assertions.assertThat(chains).hasSize(1);
|
||||
org.assertj.core.api.Assertions.assertThat(chains.get(0).getTriggerPoint().getPolymorphicEvents()).containsExactlyInAnyOrder("REACTIVE_EVENT");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExtractEventFromSwitchExpressionAndParentheses(@TempDir Path tempDir) throws IOException {
|
||||
String source = """
|
||||
package com.example;
|
||||
public class SwitchOrderService {
|
||||
public void processOrder(int type) {
|
||||
String e = (((switch(type) {
|
||||
case 1 -> "PAY";
|
||||
default -> { yield "CANCEL"; }
|
||||
})));
|
||||
sendEvent(e);
|
||||
}
|
||||
|
||||
public void sendEvent(String event) {
|
||||
}
|
||||
}
|
||||
""";
|
||||
Files.writeString(tempDir.resolve("SwitchOrderService.java"), source);
|
||||
|
||||
CodebaseContext context = new CodebaseContext();
|
||||
context.scan(tempDir);
|
||||
|
||||
HeuristicCallGraphEngine builder = new HeuristicCallGraphEngine(context);
|
||||
|
||||
EntryPoint entryPoint = EntryPoint.builder()
|
||||
.className("com.example.SwitchOrderService")
|
||||
.methodName("processOrder")
|
||||
.build();
|
||||
|
||||
TriggerPoint trigger = TriggerPoint.builder()
|
||||
.className("com.example.SwitchOrderService")
|
||||
.methodName("sendEvent")
|
||||
.event("event")
|
||||
.build();
|
||||
|
||||
List<CallChain> chains = builder.findChains(List.of(entryPoint), List.of(trigger));
|
||||
|
||||
assertThat(chains).hasSize(1);
|
||||
System.out.println("POLY EVENTS: " + chains.get(0).getTriggerPoint().getPolymorphicEvents());
|
||||
assertThat(chains.get(0).getTriggerPoint().getPolymorphicEvents())
|
||||
.containsExactlyInAnyOrder("PAY", "CANCEL");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ class AstTransitionParserTest {
|
||||
|
||||
assertThat(transitions).hasSize(1);
|
||||
Transition transition = transitions.getFirst();
|
||||
assertThat(transition.getGuard())
|
||||
assertThat(transition.getGuards().getFirst())
|
||||
.extracting(Guard::expression)
|
||||
.isEqualTo("amount > 0");
|
||||
}
|
||||
@@ -129,7 +129,7 @@ class AstTransitionParserTest {
|
||||
|
||||
assertThat(transitions).hasSize(1);
|
||||
Transition transition = transitions.getFirst();
|
||||
assertThat(transition.getGuard().isLambda()).isTrue();
|
||||
assertThat(transition.getGuards().getFirst().isLambda()).isTrue();
|
||||
assertThat(transition.getActions())
|
||||
.extracting(Action::isLambda)
|
||||
.containsExactly(true);
|
||||
@@ -230,7 +230,7 @@ class AstTransitionParserTest {
|
||||
List<Transition> transitions = AstTransitionParser.parseTransitions(method, context);
|
||||
|
||||
assertThat(transitions).hasSize(1);
|
||||
assertThat(transitions.getFirst().getGuard().internalLogic())
|
||||
assertThat(transitions.getFirst().getGuards().getFirst().internalLogic())
|
||||
.contains("context.getMessage() != null");
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@ class AstTransitionParserTest {
|
||||
List<Transition> transitions = AstTransitionParser.parseTransitions(method, context);
|
||||
|
||||
assertThat(transitions).hasSize(1);
|
||||
assertThat(transitions.getFirst().getGuard().internalLogic())
|
||||
assertThat(transitions.getFirst().getGuards().getFirst().internalLogic())
|
||||
.contains("return expected.equals(context.getMessage());")
|
||||
.doesNotContain("protected Guard<String, String> guardVarEquals");
|
||||
}
|
||||
@@ -364,7 +364,7 @@ class AstTransitionParserTest {
|
||||
List<Transition> transitions = AstTransitionParser.parseTransitions(method, context);
|
||||
|
||||
assertThat(transitions).hasSize(1);
|
||||
assertThat(transitions.getFirst().getGuard().internalLogic())
|
||||
assertThat(transitions.getFirst().getGuards().getFirst().internalLogic())
|
||||
.contains("return \"OK\".equals(context.getMessage().getPayload());")
|
||||
.contains("public boolean evaluate");
|
||||
}
|
||||
@@ -390,7 +390,7 @@ class AstTransitionParserTest {
|
||||
List<Transition> transitions = AstTransitionParser.parseTransitions(method, context);
|
||||
|
||||
assertThat(transitions).hasSize(1);
|
||||
assertThat(transitions.getFirst().getGuard().internalLogic())
|
||||
assertThat(transitions.getFirst().getGuards().getFirst().internalLogic())
|
||||
.contains("context -> \"LOCAL_OK\".equals(context.getMessage())");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class PlantUmlTest {
|
||||
t.setTargetStates(List.of(state2));
|
||||
|
||||
// Add a guard and action containing problematic characters
|
||||
t.setGuard(Guard.of("list.size() < 5", false, null, null, null, null));
|
||||
t.getGuards().add(Guard.of("list.size() < 5", false, null, null, null, null));
|
||||
t.setActions(List.of(Action.of("doSomething(new int[]{1, 2})", false, null, null, null, null)));
|
||||
|
||||
String result = plantUml.export(
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"rawName" : "Events.EVENT1",
|
||||
"fullIdentifier" : "Events.EVENT1"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -43,7 +43,7 @@
|
||||
"rawName" : "Events.EVENT2",
|
||||
"fullIdentifier" : "Events.EVENT2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -60,7 +60,7 @@
|
||||
"rawName" : "Events.EVENT3",
|
||||
"fullIdentifier" : "Events.EVENT3"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -77,7 +77,7 @@
|
||||
"rawName" : "Events.EVENT4",
|
||||
"fullIdentifier" : "Events.EVENT4"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -94,7 +94,7 @@
|
||||
"rawName" : "Events.EVENT5",
|
||||
"fullIdentifier" : "Events.EVENT5"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -111,7 +111,7 @@
|
||||
"rawName" : "Events.EVENT6",
|
||||
"fullIdentifier" : "Events.EVENT6"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -128,7 +128,7 @@
|
||||
"rawName" : "Events.EVENT7",
|
||||
"fullIdentifier" : "Events.EVENT7"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -145,7 +145,7 @@
|
||||
"rawName" : "Events.EVENT8",
|
||||
"fullIdentifier" : "Events.EVENT8"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -162,7 +162,7 @@
|
||||
"rawName" : "Events.EVENT9",
|
||||
"fullIdentifier" : "Events.EVENT9"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -179,7 +179,7 @@
|
||||
"rawName" : "Events.EVENT10",
|
||||
"fullIdentifier" : "Events.EVENT10"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -196,7 +196,7 @@
|
||||
"rawName" : "Events.EVENT11",
|
||||
"fullIdentifier" : "Events.EVENT11"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -213,7 +213,7 @@
|
||||
"rawName" : "Events.EVENT12",
|
||||
"fullIdentifier" : "Events.EVENT12"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -230,7 +230,7 @@
|
||||
"rawName" : "Events.EVENT13",
|
||||
"fullIdentifier" : "Events.EVENT13"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -247,7 +247,7 @@
|
||||
"rawName" : "Events.EVENT14",
|
||||
"fullIdentifier" : "Events.EVENT14"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -264,7 +264,7 @@
|
||||
"rawName" : "Events.EVENT15",
|
||||
"fullIdentifier" : "Events.EVENT15"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -278,14 +278,14 @@
|
||||
"fullIdentifier" : "States.STATE17"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value1\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 86,
|
||||
"className" : "click.kamil.examples.statemachine.complex.ComplexStateMachineConfig",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/complex/ComplexStateMachineConfig.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -299,14 +299,14 @@
|
||||
"fullIdentifier" : "States.STATE18"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value2\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 87,
|
||||
"className" : "click.kamil.examples.statemachine.complex.ComplexStateMachineConfig",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/complex/ComplexStateMachineConfig.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -320,7 +320,7 @@
|
||||
"fullIdentifier" : "States.STATE19"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -334,14 +334,14 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardEventHeaderEquals(\"header1\",\"foo\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object header=context.getMessageHeader(headerName);\n return expected.equals(header);\n}\n",
|
||||
"lineNumber" : 92,
|
||||
"className" : "click.kamil.examples.statemachine.complex.ComplexStateMachineConfig",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/complex/ComplexStateMachineConfig.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -355,7 +355,7 @@
|
||||
"fullIdentifier" : "States.STATE16"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -369,14 +369,14 @@
|
||||
"fullIdentifier" : "States.STATE19"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value3\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 97,
|
||||
"className" : "click.kamil.examples.statemachine.complex.ComplexStateMachineConfig",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/complex/ComplexStateMachineConfig.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -390,7 +390,7 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -404,14 +404,14 @@
|
||||
"fullIdentifier" : "States.STATE1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"reset\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 102,
|
||||
"className" : "click.kamil.examples.statemachine.complex.ComplexStateMachineConfig",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/complex/ComplexStateMachineConfig.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -425,7 +425,7 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -439,14 +439,14 @@
|
||||
"fullIdentifier" : "States.STATE5"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardEventHeaderEquals(\"header2\",\"bar\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object header=context.getMessageHeader(headerName);\n return expected.equals(header);\n}\n",
|
||||
"lineNumber" : 107,
|
||||
"className" : "click.kamil.examples.statemachine.complex.ComplexStateMachineConfig",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/complex/ComplexStateMachineConfig.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -460,7 +460,7 @@
|
||||
"fullIdentifier" : "States.STATE1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -474,14 +474,14 @@
|
||||
"fullIdentifier" : "States.STATE13"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goTo13\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 112,
|
||||
"className" : "click.kamil.examples.statemachine.complex.ComplexStateMachineConfig",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/complex/ComplexStateMachineConfig.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -495,14 +495,14 @@
|
||||
"fullIdentifier" : "States.STATE14"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goTo14\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 113,
|
||||
"className" : "click.kamil.examples.statemachine.complex.ComplexStateMachineConfig",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/complex/ComplexStateMachineConfig.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -516,7 +516,7 @@
|
||||
"fullIdentifier" : "States.STATE15"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -530,14 +530,14 @@
|
||||
"fullIdentifier" : "States.STATE10"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goBack10\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 118,
|
||||
"className" : "click.kamil.examples.statemachine.complex.ComplexStateMachineConfig",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/complex/ComplexStateMachineConfig.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -551,7 +551,7 @@
|
||||
"fullIdentifier" : "States.STATE11"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -565,14 +565,14 @@
|
||||
"fullIdentifier" : "States.STATE12"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"loop12\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 123,
|
||||
"className" : "click.kamil.examples.statemachine.complex.ComplexStateMachineConfig",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/complex/ComplexStateMachineConfig.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -586,7 +586,7 @@
|
||||
"fullIdentifier" : "States.STATE16"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -600,14 +600,14 @@
|
||||
"fullIdentifier" : "States.STATE8"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBack\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 128,
|
||||
"className" : "click.kamil.examples.statemachine.complex.ComplexStateMachineConfig",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/complex/ComplexStateMachineConfig.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -621,14 +621,14 @@
|
||||
"fullIdentifier" : "States.STATE7"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBackMore\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 129,
|
||||
"className" : "click.kamil.examples.statemachine.complex.ComplexStateMachineConfig",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/complex/ComplexStateMachineConfig.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -642,7 +642,7 @@
|
||||
"fullIdentifier" : "States.STATE6"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -656,14 +656,14 @@
|
||||
"fullIdentifier" : "States.STATE9"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"forward9\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 134,
|
||||
"className" : "click.kamil.examples.statemachine.complex.ComplexStateMachineConfig",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/complex/ComplexStateMachineConfig.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -677,7 +677,7 @@
|
||||
"fullIdentifier" : "States.STATE10"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
} ],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"metadata" : {
|
||||
"triggers" : [ {
|
||||
"event" : "click.kamil.enterprise.machines.order.OrderEvent.PAY",
|
||||
"event" : "OrderEvent.PAY",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "payOrder",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -11,9 +11,10 @@
|
||||
"lineNumber" : 30,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.order.OrderEvent.SHIP",
|
||||
"event" : "OrderEvent.SHIP",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "shipOrder",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -23,9 +24,10 @@
|
||||
"lineNumber" : 37,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.SUBMIT",
|
||||
"event" : "DocumentEvent.SUBMIT",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "submitDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -35,9 +37,10 @@
|
||||
"lineNumber" : 44,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.APPROVE",
|
||||
"event" : "DocumentEvent.APPROVE",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "approveDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -47,9 +50,10 @@
|
||||
"lineNumber" : 51,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.REJECT",
|
||||
"event" : "DocumentEvent.REJECT",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "rejectDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -59,9 +63,10 @@
|
||||
"lineNumber" : 58,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.user.UserEvent.VERIFY",
|
||||
"event" : "UserEvent.VERIFY",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "verifyUser",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -71,9 +76,10 @@
|
||||
"lineNumber" : 65,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.user.UserEvent.SUSPEND",
|
||||
"event" : "UserEvent.SUSPEND",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "suspendUser",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -83,7 +89,8 @@
|
||||
"lineNumber" : 72,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "event",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
@@ -95,7 +102,8 @@
|
||||
"lineNumber" : 81,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "event",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
@@ -107,7 +115,8 @@
|
||||
"lineNumber" : 87,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "event",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
@@ -119,7 +128,8 @@
|
||||
"lineNumber" : 93,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
} ],
|
||||
"entryPoints" : [ {
|
||||
"type" : "REST",
|
||||
@@ -269,7 +279,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.payOrder", "click.kamil.enterprise.web.StateMachineDispatcher.payOrder" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.order.OrderEvent.PAY",
|
||||
"event" : "OrderEvent.PAY",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "payOrder",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -279,7 +289,8 @@
|
||||
"lineNumber" : 30,
|
||||
"polymorphicEvents" : [ "OrderEvent.PAY" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -302,7 +313,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.shipOrder", "click.kamil.enterprise.web.StateMachineDispatcher.shipOrder" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.order.OrderEvent.SHIP",
|
||||
"event" : "OrderEvent.SHIP",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "shipOrder",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -312,7 +323,8 @@
|
||||
"lineNumber" : 37,
|
||||
"polymorphicEvents" : [ "OrderEvent.SHIP" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -335,7 +347,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.submitDocument", "click.kamil.enterprise.web.StateMachineDispatcher.submitDocument" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.SUBMIT",
|
||||
"event" : "DocumentEvent.SUBMIT",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "submitDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -345,7 +357,8 @@
|
||||
"lineNumber" : 44,
|
||||
"polymorphicEvents" : [ "DocumentEvent.SUBMIT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -372,7 +385,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.approveDocument", "click.kamil.enterprise.web.StateMachineDispatcher.approveDocument" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.APPROVE",
|
||||
"event" : "DocumentEvent.APPROVE",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "approveDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -382,7 +395,8 @@
|
||||
"lineNumber" : 51,
|
||||
"polymorphicEvents" : [ "DocumentEvent.APPROVE" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -409,7 +423,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.rejectDocument", "click.kamil.enterprise.web.StateMachineDispatcher.rejectDocument" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.REJECT",
|
||||
"event" : "DocumentEvent.REJECT",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "rejectDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -419,7 +433,8 @@
|
||||
"lineNumber" : 58,
|
||||
"polymorphicEvents" : [ "DocumentEvent.REJECT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -446,7 +461,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.verifyUser", "click.kamil.enterprise.web.StateMachineDispatcher.verifyUser" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.user.UserEvent.VERIFY",
|
||||
"event" : "UserEvent.VERIFY",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "verifyUser",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -456,7 +471,8 @@
|
||||
"lineNumber" : 65,
|
||||
"polymorphicEvents" : [ "UserEvent.VERIFY" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -479,7 +495,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.suspendUser", "click.kamil.enterprise.web.StateMachineDispatcher.suspendUser" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.user.UserEvent.SUSPEND",
|
||||
"event" : "UserEvent.SUSPEND",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "suspendUser",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -489,7 +505,8 @@
|
||||
"lineNumber" : 72,
|
||||
"polymorphicEvents" : [ "UserEvent.SUSPEND" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -526,11 +543,12 @@
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
"sourceModule" : null,
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"sourceState" : "ORDER",
|
||||
"lineNumber" : 81,
|
||||
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
|
||||
"external" : true,
|
||||
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -567,26 +585,15 @@
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
"sourceModule" : null,
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"sourceState" : "DOCUMENT",
|
||||
"lineNumber" : 87,
|
||||
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
|
||||
"external" : true,
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
"sourceState" : "DocumentState.DRAFT",
|
||||
"targetState" : "DocumentState.IN_REVIEW",
|
||||
"event" : "DocumentEvent.SUBMIT"
|
||||
}, {
|
||||
"sourceState" : "DocumentState.IN_REVIEW",
|
||||
"targetState" : "DocumentState.APPROVED",
|
||||
"event" : "DocumentEvent.APPROVE"
|
||||
}, {
|
||||
"sourceState" : "DocumentState.IN_REVIEW",
|
||||
"targetState" : "DocumentState.DRAFT",
|
||||
"event" : "DocumentEvent.REJECT"
|
||||
} ]
|
||||
"matchedTransitions" : null
|
||||
}, {
|
||||
"entryPoint" : {
|
||||
"type" : "REST",
|
||||
@@ -620,11 +627,12 @@
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
"sourceModule" : null,
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"sourceState" : "USER",
|
||||
"lineNumber" : 93,
|
||||
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
|
||||
"external" : true,
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -650,7 +658,7 @@
|
||||
"rawName" : "DocumentEvent.SUBMIT",
|
||||
"fullIdentifier" : "DocumentEvent.SUBMIT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -667,7 +675,7 @@
|
||||
"rawName" : "DocumentEvent.APPROVE",
|
||||
"fullIdentifier" : "DocumentEvent.APPROVE"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -684,7 +692,7 @@
|
||||
"rawName" : "DocumentEvent.REJECT",
|
||||
"fullIdentifier" : "DocumentEvent.REJECT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "PLACE_ORDER",
|
||||
"className" : "click.kamil.examples.enterprise.service.OrderServiceImpl",
|
||||
@@ -23,7 +24,8 @@
|
||||
"lineNumber" : 16,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "CANCEL_ORDER",
|
||||
"className" : "click.kamil.examples.enterprise.service.OrderServiceImpl",
|
||||
@@ -35,7 +37,8 @@
|
||||
"lineNumber" : 21,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "PAY_ORDER",
|
||||
"className" : "click.kamil.examples.enterprise.service.ReactivePaymentService",
|
||||
@@ -47,7 +50,8 @@
|
||||
"lineNumber" : 18,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "SHIP_ORDER",
|
||||
"className" : "click.kamil.examples.enterprise.messaging.ShippingJmsListener",
|
||||
@@ -59,7 +63,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "RETURN_ORDER",
|
||||
"className" : "click.kamil.examples.enterprise.messaging.ReturnsRabbitListener",
|
||||
@@ -71,7 +76,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
} ],
|
||||
"entryPoints" : [ {
|
||||
"type" : "REST",
|
||||
@@ -206,7 +212,8 @@
|
||||
"lineNumber" : 16,
|
||||
"polymorphicEvents" : [ "PLACE_ORDER" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -243,7 +250,8 @@
|
||||
"lineNumber" : 21,
|
||||
"polymorphicEvents" : [ "CANCEL_ORDER" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -276,7 +284,8 @@
|
||||
"lineNumber" : 16,
|
||||
"polymorphicEvents" : [ "PLACE_ORDER" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -313,7 +322,8 @@
|
||||
"lineNumber" : 21,
|
||||
"polymorphicEvents" : [ "CANCEL_ORDER" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -345,7 +355,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -378,7 +389,8 @@
|
||||
"lineNumber" : 18,
|
||||
"polymorphicEvents" : [ "PAY_ORDER" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -415,7 +427,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -452,7 +465,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -482,7 +496,7 @@
|
||||
"rawName" : "OrderEvents.PLACE",
|
||||
"fullIdentifier" : "PLACE_ORDER"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -496,14 +510,14 @@
|
||||
"fullIdentifier" : "PENDING_PAYMENT"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "(c) -> true",
|
||||
"isLambda" : true,
|
||||
"internalLogic" : "(c) -> true",
|
||||
"lineNumber" : 41,
|
||||
"className" : "click.kamil.examples.enterprise.config.EnterpriseStateMachineConfig",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/enterprise/config/EnterpriseStateMachineConfig.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -517,7 +531,7 @@
|
||||
"fullIdentifier" : "CANCELLED"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -534,7 +548,7 @@
|
||||
"rawName" : "OrderEvents.PAY",
|
||||
"fullIdentifier" : "PAY_ORDER"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -551,7 +565,7 @@
|
||||
"rawName" : "OrderEvents.SHIP",
|
||||
"fullIdentifier" : "SHIP_ORDER"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -568,7 +582,7 @@
|
||||
"rawName" : "\"FINALIZE\"",
|
||||
"fullIdentifier" : "FINALIZE"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -585,7 +599,7 @@
|
||||
"rawName" : "OrderEvents.CANCEL",
|
||||
"fullIdentifier" : "CANCEL_ORDER"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -602,7 +616,7 @@
|
||||
"rawName" : "OrderEvents.RETURN",
|
||||
"fullIdentifier" : "RETURN_ORDER"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
"lineNumber" : 34,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "AUDIT_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.web.AuditInterceptor",
|
||||
@@ -23,7 +24,8 @@
|
||||
"lineNumber" : 16,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "FALLBACK_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.FallbackQuirkService",
|
||||
@@ -35,7 +37,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "PROFILED_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.ProfiledQuirkService",
|
||||
@@ -47,7 +50,8 @@
|
||||
"lineNumber" : 19,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "PRIMARY_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.PrimaryQuirkService",
|
||||
@@ -59,7 +63,8 @@
|
||||
"lineNumber" : 19,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "SUBMIT_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
|
||||
@@ -71,7 +76,8 @@
|
||||
"lineNumber" : 20,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "CANCEL_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
|
||||
@@ -83,7 +89,8 @@
|
||||
"lineNumber" : 25,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "[LIFECYCLE:RESTORE]",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
|
||||
@@ -95,7 +102,8 @@
|
||||
"lineNumber" : 29,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "QUALIFIER_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.QualifierQuirkService",
|
||||
@@ -107,7 +115,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "NAMED_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.NamedQuirkService",
|
||||
@@ -119,7 +128,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "AUTHORIZE",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.PaymentServiceImpl",
|
||||
@@ -131,7 +141,8 @@
|
||||
"lineNumber" : 22,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "CAPTURE",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.PaymentServiceImpl",
|
||||
@@ -143,7 +154,8 @@
|
||||
"lineNumber" : 35,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "[LIFECYCLE:RESTORE]",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.PaymentServiceImpl",
|
||||
@@ -155,7 +167,8 @@
|
||||
"lineNumber" : 28,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "REACTIVE_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.ReactiveOrderService",
|
||||
@@ -167,7 +180,8 @@
|
||||
"lineNumber" : 18,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
} ],
|
||||
"entryPoints" : [ {
|
||||
"type" : "REST",
|
||||
@@ -397,7 +411,8 @@
|
||||
"lineNumber" : 20,
|
||||
"polymorphicEvents" : [ "SUBMIT_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -430,7 +445,8 @@
|
||||
"lineNumber" : 25,
|
||||
"polymorphicEvents" : [ "CANCEL_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -463,7 +479,8 @@
|
||||
"lineNumber" : 34,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -500,7 +517,8 @@
|
||||
"lineNumber" : 29,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : "orderId",
|
||||
"matchedTransitions" : null
|
||||
@@ -533,7 +551,8 @@
|
||||
"lineNumber" : 18,
|
||||
"polymorphicEvents" : [ "REACTIVE_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -565,7 +584,8 @@
|
||||
"lineNumber" : 16,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -598,7 +618,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : [ "NAMED_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -627,7 +648,8 @@
|
||||
"lineNumber" : 19,
|
||||
"polymorphicEvents" : [ "PRIMARY_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -656,7 +678,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : [ "NAMED_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -685,7 +708,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : [ "QUALIFIER_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -714,7 +738,8 @@
|
||||
"lineNumber" : 19,
|
||||
"polymorphicEvents" : [ "PRIMARY_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -743,7 +768,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : [ "QUALIFIER_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -772,7 +798,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : [ "NAMED_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -803,9 +830,10 @@
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"lineNumber" : 22,
|
||||
"polymorphicEvents" : null,
|
||||
"polymorphicEvents" : [ "AUTHORIZE" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -836,9 +864,10 @@
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"lineNumber" : 35,
|
||||
"polymorphicEvents" : null,
|
||||
"polymorphicEvents" : [ "CAPTURE" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : "paymentId",
|
||||
"matchedTransitions" : null
|
||||
@@ -871,7 +900,8 @@
|
||||
"lineNumber" : 28,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : "paymentId",
|
||||
"matchedTransitions" : null
|
||||
@@ -902,7 +932,7 @@
|
||||
"rawName" : "MyEvents.SUBMIT",
|
||||
"fullIdentifier" : "SUBMIT_EVENT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -919,7 +949,7 @@
|
||||
"rawName" : "\"FINISH\"",
|
||||
"fullIdentifier" : "FINISH"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -936,7 +966,7 @@
|
||||
"rawName" : "MyEvents.CANCEL",
|
||||
"fullIdentifier" : "CANCEL_EVENT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -953,7 +983,7 @@
|
||||
"rawName" : "\"REACTIVE_EVENT\"",
|
||||
"fullIdentifier" : "REACTIVE_EVENT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -970,7 +1000,7 @@
|
||||
"rawName" : "\"AUDIT_EVENT\"",
|
||||
"fullIdentifier" : "AUDIT_EVENT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -987,7 +1017,7 @@
|
||||
"rawName" : "\"EXTERNAL_TRIGGER\"",
|
||||
"fullIdentifier" : "EXTERNAL_TRIGGER"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
"lineNumber" : 34,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "AUDIT_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.web.AuditInterceptor",
|
||||
@@ -23,7 +24,8 @@
|
||||
"lineNumber" : 16,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "FALLBACK_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.FallbackQuirkService",
|
||||
@@ -35,7 +37,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "PROFILED_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.ProfiledQuirkService",
|
||||
@@ -47,7 +50,8 @@
|
||||
"lineNumber" : 19,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "PRIMARY_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.PrimaryQuirkService",
|
||||
@@ -59,7 +63,8 @@
|
||||
"lineNumber" : 19,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "SUBMIT_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
|
||||
@@ -71,7 +76,8 @@
|
||||
"lineNumber" : 20,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "CANCEL_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
|
||||
@@ -83,7 +89,8 @@
|
||||
"lineNumber" : 25,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "[LIFECYCLE:RESTORE]",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.OrderService",
|
||||
@@ -95,7 +102,8 @@
|
||||
"lineNumber" : 29,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "QUALIFIER_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.QualifierQuirkService",
|
||||
@@ -107,7 +115,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "NAMED_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.NamedQuirkService",
|
||||
@@ -119,7 +128,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "AUTHORIZE",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.PaymentServiceImpl",
|
||||
@@ -131,7 +141,8 @@
|
||||
"lineNumber" : 22,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "CAPTURE",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.PaymentServiceImpl",
|
||||
@@ -143,7 +154,8 @@
|
||||
"lineNumber" : 35,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "[LIFECYCLE:RESTORE]",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.PaymentServiceImpl",
|
||||
@@ -155,7 +167,8 @@
|
||||
"lineNumber" : 28,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "REACTIVE_EVENT",
|
||||
"className" : "click.kamil.examples.statemachine.extended.service.ReactiveOrderService",
|
||||
@@ -167,7 +180,8 @@
|
||||
"lineNumber" : 18,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
} ],
|
||||
"entryPoints" : [ {
|
||||
"type" : "REST",
|
||||
@@ -397,7 +411,8 @@
|
||||
"lineNumber" : 20,
|
||||
"polymorphicEvents" : [ "SUBMIT_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -430,7 +445,8 @@
|
||||
"lineNumber" : 25,
|
||||
"polymorphicEvents" : [ "CANCEL_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -463,7 +479,8 @@
|
||||
"lineNumber" : 34,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -500,7 +517,8 @@
|
||||
"lineNumber" : 29,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : "orderId",
|
||||
"matchedTransitions" : null
|
||||
@@ -533,7 +551,8 @@
|
||||
"lineNumber" : 18,
|
||||
"polymorphicEvents" : [ "REACTIVE_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -565,7 +584,8 @@
|
||||
"lineNumber" : 16,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -598,7 +618,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : [ "NAMED_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -627,7 +648,8 @@
|
||||
"lineNumber" : 19,
|
||||
"polymorphicEvents" : [ "PRIMARY_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -656,7 +678,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : [ "NAMED_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -685,7 +708,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : [ "QUALIFIER_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -714,7 +738,8 @@
|
||||
"lineNumber" : 19,
|
||||
"polymorphicEvents" : [ "PRIMARY_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -743,7 +768,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : [ "QUALIFIER_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -772,7 +798,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : [ "NAMED_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -803,9 +830,10 @@
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"lineNumber" : 22,
|
||||
"polymorphicEvents" : null,
|
||||
"polymorphicEvents" : [ "AUTHORIZE" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -836,9 +864,10 @@
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"lineNumber" : 35,
|
||||
"polymorphicEvents" : null,
|
||||
"polymorphicEvents" : [ "CAPTURE" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : "paymentId",
|
||||
"matchedTransitions" : null
|
||||
@@ -871,7 +900,8 @@
|
||||
"lineNumber" : 28,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : "paymentId",
|
||||
"matchedTransitions" : null
|
||||
@@ -902,7 +932,7 @@
|
||||
"rawName" : "MyEvents.SUBMIT",
|
||||
"fullIdentifier" : "SUBMIT_EVENT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -919,7 +949,7 @@
|
||||
"rawName" : "\"FINISH\"",
|
||||
"fullIdentifier" : "FINISH"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -936,7 +966,7 @@
|
||||
"rawName" : "MyEvents.CANCEL",
|
||||
"fullIdentifier" : "CANCEL_EVENT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -953,7 +983,7 @@
|
||||
"rawName" : "\"REACTIVE_EVENT\"",
|
||||
"fullIdentifier" : "REACTIVE_EVENT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -970,7 +1000,7 @@
|
||||
"rawName" : "\"AUDIT_EVENT\"",
|
||||
"fullIdentifier" : "AUDIT_EVENT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -987,7 +1017,7 @@
|
||||
"rawName" : "\"EXTERNAL_TRIGGER\"",
|
||||
"fullIdentifier" : "EXTERNAL_TRIGGER"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"rawName" : "Events.EVENT1",
|
||||
"fullIdentifier" : "Events.EVENT1"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -43,7 +43,7 @@
|
||||
"rawName" : "Events.EVENT2",
|
||||
"fullIdentifier" : "Events.EVENT2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -60,7 +60,7 @@
|
||||
"rawName" : "Events.EVENT3",
|
||||
"fullIdentifier" : "Events.EVENT3"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -77,7 +77,7 @@
|
||||
"rawName" : "Events.EVENT4",
|
||||
"fullIdentifier" : "Events.EVENT4"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -94,7 +94,7 @@
|
||||
"rawName" : "Events.EVENT5",
|
||||
"fullIdentifier" : "Events.EVENT5"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -111,7 +111,7 @@
|
||||
"rawName" : "Events.EVENT6",
|
||||
"fullIdentifier" : "Events.EVENT6"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -128,7 +128,7 @@
|
||||
"rawName" : "Events.EVENT7",
|
||||
"fullIdentifier" : "Events.EVENT7"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -145,7 +145,7 @@
|
||||
"rawName" : "Events.EVENT8",
|
||||
"fullIdentifier" : "Events.EVENT8"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -162,7 +162,7 @@
|
||||
"rawName" : "Events.EVENT9",
|
||||
"fullIdentifier" : "Events.EVENT9"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -179,7 +179,7 @@
|
||||
"rawName" : "Events.EVENT10",
|
||||
"fullIdentifier" : "Events.EVENT10"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -196,7 +196,7 @@
|
||||
"rawName" : "Events.EVENT11",
|
||||
"fullIdentifier" : "Events.EVENT11"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -213,7 +213,7 @@
|
||||
"rawName" : "Events.EVENT12",
|
||||
"fullIdentifier" : "Events.EVENT12"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -230,7 +230,7 @@
|
||||
"rawName" : "Events.EVENT13",
|
||||
"fullIdentifier" : "Events.EVENT13"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -247,7 +247,7 @@
|
||||
"rawName" : "Events.EVENT14",
|
||||
"fullIdentifier" : "Events.EVENT14"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -264,7 +264,7 @@
|
||||
"rawName" : "Events.EVENT15",
|
||||
"fullIdentifier" : "Events.EVENT15"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -281,7 +281,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -298,7 +298,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -315,7 +315,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -332,7 +332,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -349,7 +349,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -366,7 +366,7 @@
|
||||
"rawName" : "Events.EVENTY",
|
||||
"fullIdentifier" : "Events.EVENTY"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -380,14 +380,14 @@
|
||||
"fullIdentifier" : "States.STATEX"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value1\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 120,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -401,7 +401,7 @@
|
||||
"fullIdentifier" : "States.STATEZ"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -415,14 +415,14 @@
|
||||
"fullIdentifier" : "States.STATE17"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value1\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 126,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -436,14 +436,14 @@
|
||||
"fullIdentifier" : "States.STATE18"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value2\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 127,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -457,7 +457,7 @@
|
||||
"fullIdentifier" : "States.STATE19"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -471,14 +471,14 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardEventHeaderEquals(\"header1\",\"foo\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object header=context.getMessageHeader(headerName);\n return expected.equals(header);\n}\n",
|
||||
"lineNumber" : 132,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -492,7 +492,7 @@
|
||||
"fullIdentifier" : "States.STATE16"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -506,14 +506,14 @@
|
||||
"fullIdentifier" : "States.STATE19"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value3\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 137,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -527,7 +527,7 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -541,14 +541,14 @@
|
||||
"fullIdentifier" : "States.STATE1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"reset\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 142,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -562,7 +562,7 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -576,14 +576,14 @@
|
||||
"fullIdentifier" : "States.STATE5"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardEventHeaderEquals(\"header2\",\"bar\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object header=context.getMessageHeader(headerName);\n return expected.equals(header);\n}\n",
|
||||
"lineNumber" : 147,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -597,7 +597,7 @@
|
||||
"fullIdentifier" : "States.STATE1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -611,14 +611,14 @@
|
||||
"fullIdentifier" : "States.STATE13"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goTo13\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 152,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -632,14 +632,14 @@
|
||||
"fullIdentifier" : "States.STATE14"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goTo14\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 153,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -653,7 +653,7 @@
|
||||
"fullIdentifier" : "States.STATE15"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -667,14 +667,14 @@
|
||||
"fullIdentifier" : "States.STATE10"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goBack10\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 158,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -688,7 +688,7 @@
|
||||
"fullIdentifier" : "States.STATE11"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -702,14 +702,14 @@
|
||||
"fullIdentifier" : "States.STATE12"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"loop12\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 163,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -723,7 +723,7 @@
|
||||
"fullIdentifier" : "States.STATE16"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -737,14 +737,14 @@
|
||||
"fullIdentifier" : "States.STATE8"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBack\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 168,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -758,14 +758,14 @@
|
||||
"fullIdentifier" : "States.STATE7"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBackMore\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 169,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -779,7 +779,7 @@
|
||||
"fullIdentifier" : "States.STATE6"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -793,14 +793,14 @@
|
||||
"fullIdentifier" : "States.STATE9"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"forward9\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 174,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -814,7 +814,7 @@
|
||||
"fullIdentifier" : "States.STATE10"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -831,7 +831,7 @@
|
||||
"rawName" : "Events.EVENTX",
|
||||
"fullIdentifier" : "Events.EVENTX"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -845,14 +845,14 @@
|
||||
"fullIdentifier" : "States.STATE1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardEventHeaderEquals(\"header1\",\"foo\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object header=context.getMessageHeader(headerName);\n return expected.equals(header);\n}\n",
|
||||
"lineNumber" : 31,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.F1StateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/F1StateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -866,7 +866,7 @@
|
||||
"fullIdentifier" : "States.STATE_EXTRA_1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -883,7 +883,7 @@
|
||||
"rawName" : "Events.EVENTY",
|
||||
"fullIdentifier" : "Events.EVENTY"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -900,7 +900,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL_2",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL_2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -917,7 +917,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL_2",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL_2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"rawName" : "Events.EVENT1",
|
||||
"fullIdentifier" : "Events.EVENT1"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -43,7 +43,7 @@
|
||||
"rawName" : "Events.EVENT2",
|
||||
"fullIdentifier" : "Events.EVENT2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -60,7 +60,7 @@
|
||||
"rawName" : "Events.EVENT3",
|
||||
"fullIdentifier" : "Events.EVENT3"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -77,7 +77,7 @@
|
||||
"rawName" : "Events.EVENT4",
|
||||
"fullIdentifier" : "Events.EVENT4"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -94,7 +94,7 @@
|
||||
"rawName" : "Events.EVENT5",
|
||||
"fullIdentifier" : "Events.EVENT5"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -111,7 +111,7 @@
|
||||
"rawName" : "Events.EVENT6",
|
||||
"fullIdentifier" : "Events.EVENT6"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -128,7 +128,7 @@
|
||||
"rawName" : "Events.EVENT7",
|
||||
"fullIdentifier" : "Events.EVENT7"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -145,7 +145,7 @@
|
||||
"rawName" : "Events.EVENT8",
|
||||
"fullIdentifier" : "Events.EVENT8"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -162,7 +162,7 @@
|
||||
"rawName" : "Events.EVENT9",
|
||||
"fullIdentifier" : "Events.EVENT9"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -179,7 +179,7 @@
|
||||
"rawName" : "Events.EVENT10",
|
||||
"fullIdentifier" : "Events.EVENT10"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -196,7 +196,7 @@
|
||||
"rawName" : "Events.EVENT11",
|
||||
"fullIdentifier" : "Events.EVENT11"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -213,7 +213,7 @@
|
||||
"rawName" : "Events.EVENT12",
|
||||
"fullIdentifier" : "Events.EVENT12"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -230,7 +230,7 @@
|
||||
"rawName" : "Events.EVENT13",
|
||||
"fullIdentifier" : "Events.EVENT13"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -247,7 +247,7 @@
|
||||
"rawName" : "Events.EVENT14",
|
||||
"fullIdentifier" : "Events.EVENT14"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -264,7 +264,7 @@
|
||||
"rawName" : "Events.EVENT15",
|
||||
"fullIdentifier" : "Events.EVENT15"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -281,7 +281,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -298,7 +298,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -315,7 +315,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -332,7 +332,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -349,7 +349,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -366,7 +366,7 @@
|
||||
"rawName" : "Events.EVENTY",
|
||||
"fullIdentifier" : "Events.EVENTY"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -380,14 +380,14 @@
|
||||
"fullIdentifier" : "States.STATEX"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value1\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 120,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -401,7 +401,7 @@
|
||||
"fullIdentifier" : "States.STATEZ"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -415,14 +415,14 @@
|
||||
"fullIdentifier" : "States.STATE17"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value1\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 126,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -436,14 +436,14 @@
|
||||
"fullIdentifier" : "States.STATE18"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value2\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 127,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -457,7 +457,7 @@
|
||||
"fullIdentifier" : "States.STATE19"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -471,14 +471,14 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardEventHeaderEquals(\"header1\",\"foo\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object header=context.getMessageHeader(headerName);\n return expected.equals(header);\n}\n",
|
||||
"lineNumber" : 132,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -492,7 +492,7 @@
|
||||
"fullIdentifier" : "States.STATE16"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -506,14 +506,14 @@
|
||||
"fullIdentifier" : "States.STATE19"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value3\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 137,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -527,7 +527,7 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -541,14 +541,14 @@
|
||||
"fullIdentifier" : "States.STATE1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"reset\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 142,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -562,7 +562,7 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -576,14 +576,14 @@
|
||||
"fullIdentifier" : "States.STATE5"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardEventHeaderEquals(\"header2\",\"bar\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object header=context.getMessageHeader(headerName);\n return expected.equals(header);\n}\n",
|
||||
"lineNumber" : 147,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -597,7 +597,7 @@
|
||||
"fullIdentifier" : "States.STATE1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -611,14 +611,14 @@
|
||||
"fullIdentifier" : "States.STATE13"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goTo13\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 152,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -632,14 +632,14 @@
|
||||
"fullIdentifier" : "States.STATE14"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goTo14\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 153,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -653,7 +653,7 @@
|
||||
"fullIdentifier" : "States.STATE15"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -667,14 +667,14 @@
|
||||
"fullIdentifier" : "States.STATE10"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goBack10\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 158,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -688,7 +688,7 @@
|
||||
"fullIdentifier" : "States.STATE11"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -702,14 +702,14 @@
|
||||
"fullIdentifier" : "States.STATE12"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"loop12\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 163,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -723,7 +723,7 @@
|
||||
"fullIdentifier" : "States.STATE16"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -737,14 +737,14 @@
|
||||
"fullIdentifier" : "States.STATE8"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBack\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 168,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -758,14 +758,14 @@
|
||||
"fullIdentifier" : "States.STATE7"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBackMore\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 169,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -779,7 +779,7 @@
|
||||
"fullIdentifier" : "States.STATE6"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -793,14 +793,14 @@
|
||||
"fullIdentifier" : "States.STATE9"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"forward9\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 174,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractFStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractFStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -814,7 +814,7 @@
|
||||
"fullIdentifier" : "States.STATE10"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -831,7 +831,7 @@
|
||||
"rawName" : "Events.EVENT_1_1",
|
||||
"fullIdentifier" : "Events.EVENT_1_1"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -845,14 +845,14 @@
|
||||
"fullIdentifier" : "States.STATE_EXTRA_1_1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardEventHeaderEquals(\"header1\",\"foo\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object header=context.getMessageHeader(headerName);\n return expected.equals(header);\n}\n",
|
||||
"lineNumber" : 33,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.F2StateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/F2StateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -866,7 +866,7 @@
|
||||
"fullIdentifier" : "States.STATE_EXTRA_1_3"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -883,7 +883,7 @@
|
||||
"rawName" : "Events.EVENT_1_2",
|
||||
"fullIdentifier" : "Events.EVENT_1_2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -900,7 +900,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL_2",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL_2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -917,7 +917,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL_2",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL_2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -934,7 +934,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL_2",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL_2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"rawName" : "Events.TO_FORK",
|
||||
"fullIdentifier" : "Events.TO_FORK"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -43,7 +43,7 @@
|
||||
"fullIdentifier" : "States.REGION2_STATE1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -60,7 +60,7 @@
|
||||
"rawName" : "Events.R1_NEXT",
|
||||
"fullIdentifier" : "Events.R1_NEXT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -77,7 +77,7 @@
|
||||
"rawName" : "Events.R2_NEXT",
|
||||
"fullIdentifier" : "Events.R2_NEXT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -94,7 +94,7 @@
|
||||
"fullIdentifier" : "States.JOIN"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -111,7 +111,7 @@
|
||||
"rawName" : "Events.TO_END",
|
||||
"fullIdentifier" : "Events.TO_END"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"rawName" : "Events.EVENT1",
|
||||
"fullIdentifier" : "Events.EVENT1"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -43,7 +43,7 @@
|
||||
"rawName" : "Events.EVENT2",
|
||||
"fullIdentifier" : "Events.EVENT2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -60,7 +60,7 @@
|
||||
"rawName" : "Events.EVENT3",
|
||||
"fullIdentifier" : "Events.EVENT3"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -77,7 +77,7 @@
|
||||
"rawName" : "Events.EVENT4",
|
||||
"fullIdentifier" : "Events.EVENT4"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -94,7 +94,7 @@
|
||||
"rawName" : "Events.EVENT5",
|
||||
"fullIdentifier" : "Events.EVENT5"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -111,7 +111,7 @@
|
||||
"rawName" : "Events.EVENT6",
|
||||
"fullIdentifier" : "Events.EVENT6"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -128,7 +128,7 @@
|
||||
"rawName" : "Events.EVENT7",
|
||||
"fullIdentifier" : "Events.EVENT7"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -145,7 +145,7 @@
|
||||
"rawName" : "Events.EVENT8",
|
||||
"fullIdentifier" : "Events.EVENT8"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -162,7 +162,7 @@
|
||||
"rawName" : "Events.EVENT9",
|
||||
"fullIdentifier" : "Events.EVENT9"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -179,7 +179,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -196,7 +196,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -213,7 +213,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -230,7 +230,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -247,7 +247,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -264,7 +264,7 @@
|
||||
"rawName" : "Events.EVENTY",
|
||||
"fullIdentifier" : "Events.EVENTY"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -278,14 +278,14 @@
|
||||
"fullIdentifier" : "States.STATEX"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value1\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 98,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractGStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractGStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -299,7 +299,7 @@
|
||||
"fullIdentifier" : "States.STATEZ"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -313,14 +313,14 @@
|
||||
"fullIdentifier" : "States.STATE8"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBack\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 104,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractGStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractGStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -334,14 +334,14 @@
|
||||
"fullIdentifier" : "States.STATE7"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBackMore\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 105,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractGStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractGStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -355,7 +355,7 @@
|
||||
"fullIdentifier" : "States.STATE6"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -369,14 +369,14 @@
|
||||
"fullIdentifier" : "States.STATE9"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"forward9\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 110,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractGStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractGStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -390,7 +390,7 @@
|
||||
"fullIdentifier" : "States.STATE10"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -407,7 +407,7 @@
|
||||
"rawName" : "Events.EVENT_1_2",
|
||||
"fullIdentifier" : "Events.EVENT_1_2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -424,7 +424,7 @@
|
||||
"rawName" : "Events.EVENT_1_2",
|
||||
"fullIdentifier" : "Events.EVENT_1_2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -441,7 +441,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"rawName" : "Events.EVENT1",
|
||||
"fullIdentifier" : "Events.EVENT1"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -43,7 +43,7 @@
|
||||
"rawName" : "Events.EVENT2",
|
||||
"fullIdentifier" : "Events.EVENT2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -60,7 +60,7 @@
|
||||
"rawName" : "Events.EVENT3",
|
||||
"fullIdentifier" : "Events.EVENT3"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -77,7 +77,7 @@
|
||||
"rawName" : "Events.EVENT4",
|
||||
"fullIdentifier" : "Events.EVENT4"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -94,7 +94,7 @@
|
||||
"rawName" : "Events.EVENT5",
|
||||
"fullIdentifier" : "Events.EVENT5"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -111,7 +111,7 @@
|
||||
"rawName" : "Events.EVENT6",
|
||||
"fullIdentifier" : "Events.EVENT6"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -128,7 +128,7 @@
|
||||
"rawName" : "Events.EVENT7",
|
||||
"fullIdentifier" : "Events.EVENT7"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -145,7 +145,7 @@
|
||||
"rawName" : "Events.EVENT8",
|
||||
"fullIdentifier" : "Events.EVENT8"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -162,7 +162,7 @@
|
||||
"rawName" : "Events.EVENT9",
|
||||
"fullIdentifier" : "Events.EVENT9"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -179,7 +179,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -196,7 +196,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -213,7 +213,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -230,7 +230,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -247,7 +247,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -264,7 +264,7 @@
|
||||
"rawName" : "Events.EVENTY",
|
||||
"fullIdentifier" : "Events.EVENTY"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -278,14 +278,14 @@
|
||||
"fullIdentifier" : "States.STATEX"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value1\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 98,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractGStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractGStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -299,7 +299,7 @@
|
||||
"fullIdentifier" : "States.STATEZ"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -313,14 +313,14 @@
|
||||
"fullIdentifier" : "States.STATE8"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBack\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 104,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractGStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractGStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -334,14 +334,14 @@
|
||||
"fullIdentifier" : "States.STATE7"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBackMore\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 105,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractGStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractGStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -355,7 +355,7 @@
|
||||
"fullIdentifier" : "States.STATE6"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -369,14 +369,14 @@
|
||||
"fullIdentifier" : "States.STATE9"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"forward9\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 110,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.AbstractGStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate3/AbstractGStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -390,7 +390,7 @@
|
||||
"fullIdentifier" : "States.STATE10"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -407,7 +407,7 @@
|
||||
"rawName" : "Events.EVENT_1_2",
|
||||
"fullIdentifier" : "Events.EVENT_1_2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -424,7 +424,7 @@
|
||||
"rawName" : "Events.EVENT_1_3",
|
||||
"fullIdentifier" : "Events.EVENT_1_3"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -441,7 +441,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -458,7 +458,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
"lineNumber" : 15,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
} ],
|
||||
"entryPoints" : [ {
|
||||
"type" : "REST",
|
||||
@@ -61,7 +62,8 @@
|
||||
"lineNumber" : 15,
|
||||
"polymorphicEvents" : [ "INHERITED_SUBMIT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -94,7 +96,8 @@
|
||||
"lineNumber" : 15,
|
||||
"polymorphicEvents" : [ "INHERITED_SUBMIT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -124,7 +127,7 @@
|
||||
"rawName" : "\"INHERITED_SUBMIT\"",
|
||||
"fullIdentifier" : "INHERITED_SUBMIT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"rawName" : "OrderEvents.PAY",
|
||||
"fullIdentifier" : "OrderEvents.PAY"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -43,7 +43,7 @@
|
||||
"rawName" : "OrderEvents.FULFILL",
|
||||
"fullIdentifier" : "OrderEvents.FULFILL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -60,14 +60,14 @@
|
||||
"rawName" : "OrderEvents.CANCEL",
|
||||
"fullIdentifier" : "OrderEvents.CANCEL"
|
||||
},
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "new Guard<OrderStates,OrderEvents>(){\n @Override public boolean evaluate( StateContext<OrderStates,OrderEvents> context){\n return false;\n }\n}\n",
|
||||
"isLambda" : true,
|
||||
"internalLogic" : "new Guard<OrderStates,OrderEvents>(){\n @Override public boolean evaluate( StateContext<OrderStates,OrderEvents> context){\n return false;\n }\n}\n",
|
||||
"lineNumber" : 29,
|
||||
"className" : "click.kamil.examples.statemachine.enumstate.KamilEnumStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/enumstate/KamilEnumStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -84,7 +84,7 @@
|
||||
"rawName" : "OrderEvents.CANCEL",
|
||||
"fullIdentifier" : "OrderEvents.CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -98,7 +98,7 @@
|
||||
"rawName" : "OrderEvents.ABCD",
|
||||
"fullIdentifier" : "OrderEvents.ABCD"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -115,7 +115,7 @@
|
||||
"rawName" : "OrderEvents.ABCD",
|
||||
"fullIdentifier" : "OrderEvents.ABCD"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -129,14 +129,14 @@
|
||||
"fullIdentifier" : "OrderStates.PAID2"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "new Guard<OrderStates,OrderEvents>(){\n @Override public boolean evaluate( StateContext<OrderStates,OrderEvents> context){\n return true;\n }\n}\n",
|
||||
"isLambda" : true,
|
||||
"internalLogic" : "new Guard<OrderStates,OrderEvents>(){\n @Override public boolean evaluate( StateContext<OrderStates,OrderEvents> context){\n return true;\n }\n}\n",
|
||||
"lineNumber" : 46,
|
||||
"className" : "click.kamil.examples.statemachine.enumstate.KamilEnumStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/enumstate/KamilEnumStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -150,14 +150,14 @@
|
||||
"fullIdentifier" : "OrderStates.PAID3"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guard1",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : null,
|
||||
"lineNumber" : 52,
|
||||
"className" : "click.kamil.examples.statemachine.enumstate.KamilEnumStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/enumstate/KamilEnumStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -171,14 +171,14 @@
|
||||
"fullIdentifier" : "OrderStates.HAPPEN"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "new Guard<OrderStates,OrderEvents>(){\n @Override public boolean evaluate( StateContext<OrderStates,OrderEvents> context){\n return false;\n }\n}\n",
|
||||
"isLambda" : true,
|
||||
"internalLogic" : "new Guard<OrderStates,OrderEvents>(){\n @Override public boolean evaluate( StateContext<OrderStates,OrderEvents> context){\n return false;\n }\n}\n",
|
||||
"lineNumber" : 53,
|
||||
"className" : "click.kamil.examples.statemachine.enumstate.KamilEnumStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/enumstate/KamilEnumStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -192,7 +192,7 @@
|
||||
"fullIdentifier" : "OrderStates.CANCELED"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 3
|
||||
}, {
|
||||
@@ -206,7 +206,7 @@
|
||||
"fullIdentifier" : "OrderStates.CANCELED"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -220,7 +220,7 @@
|
||||
"fullIdentifier" : "OrderStates.CANCELED"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -234,7 +234,7 @@
|
||||
"rawName" : "OrderEvents.ABCD",
|
||||
"fullIdentifier" : "OrderEvents.ABCD"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ {
|
||||
"expression" : "new Action<OrderStates,OrderEvents>(){\n @Override public void execute( StateContext<OrderStates,OrderEvents> context){\n }\n}\n",
|
||||
"isLambda" : true,
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
"lineNumber" : 40,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "ORDER_EVENT",
|
||||
"className" : "click.kamil.maven.core.MavenOrderStateMachine.OrderService",
|
||||
@@ -23,7 +24,8 @@
|
||||
"lineNumber" : 52,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
} ],
|
||||
"entryPoints" : [ {
|
||||
"type" : "REST",
|
||||
@@ -112,7 +114,8 @@
|
||||
"lineNumber" : 40,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -147,9 +150,10 @@
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"lineNumber" : 40,
|
||||
"polymorphicEvents" : null,
|
||||
"polymorphicEvents" : [ "SUBMIT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -186,7 +190,8 @@
|
||||
"lineNumber" : 52,
|
||||
"polymorphicEvents" : [ "ORDER_EVENT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -216,7 +221,7 @@
|
||||
"rawName" : "\"SUBMIT\"",
|
||||
"fullIdentifier" : "SUBMIT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ {
|
||||
"expression" : "loggingAction()",
|
||||
"isLambda" : false,
|
||||
@@ -240,7 +245,7 @@
|
||||
"rawName" : "\"ORDER_EVENT\"",
|
||||
"fullIdentifier" : "ORDER_EVENT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"rawName" : "Events.EVENT1",
|
||||
"fullIdentifier" : "Events.EVENT1"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -43,7 +43,7 @@
|
||||
"rawName" : "Events.EVENT2",
|
||||
"fullIdentifier" : "Events.EVENT2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -60,7 +60,7 @@
|
||||
"rawName" : "Events.EVENT3",
|
||||
"fullIdentifier" : "Events.EVENT3"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -77,7 +77,7 @@
|
||||
"rawName" : "Events.EVENT4",
|
||||
"fullIdentifier" : "Events.EVENT4"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -94,7 +94,7 @@
|
||||
"rawName" : "Events.EVENT5",
|
||||
"fullIdentifier" : "Events.EVENT5"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -111,7 +111,7 @@
|
||||
"rawName" : "Events.EVENT6",
|
||||
"fullIdentifier" : "Events.EVENT6"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -128,7 +128,7 @@
|
||||
"rawName" : "Events.EVENT7",
|
||||
"fullIdentifier" : "Events.EVENT7"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -145,7 +145,7 @@
|
||||
"rawName" : "Events.EVENT8",
|
||||
"fullIdentifier" : "Events.EVENT8"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -162,7 +162,7 @@
|
||||
"rawName" : "Events.EVENT9",
|
||||
"fullIdentifier" : "Events.EVENT9"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -179,7 +179,7 @@
|
||||
"rawName" : "Events.EVENT10",
|
||||
"fullIdentifier" : "Events.EVENT10"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -196,7 +196,7 @@
|
||||
"rawName" : "Events.EVENT11",
|
||||
"fullIdentifier" : "Events.EVENT11"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -213,7 +213,7 @@
|
||||
"rawName" : "Events.EVENT12",
|
||||
"fullIdentifier" : "Events.EVENT12"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -230,7 +230,7 @@
|
||||
"rawName" : "Events.EVENT13",
|
||||
"fullIdentifier" : "Events.EVENT13"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -247,7 +247,7 @@
|
||||
"rawName" : "Events.EVENT14",
|
||||
"fullIdentifier" : "Events.EVENT14"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -264,7 +264,7 @@
|
||||
"rawName" : "Events.EVENT15",
|
||||
"fullIdentifier" : "Events.EVENT15"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -281,7 +281,7 @@
|
||||
"rawName" : "Events.EVENTY",
|
||||
"fullIdentifier" : "Events.EVENTY"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -295,14 +295,14 @@
|
||||
"fullIdentifier" : "States.STATEX"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value1\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 91,
|
||||
"className" : "click.kamil.examples.statemachine.inheritancestate.AbstractOneStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritancestate/AbstractOneStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -316,7 +316,7 @@
|
||||
"fullIdentifier" : "States.STATEZ"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -330,14 +330,14 @@
|
||||
"fullIdentifier" : "States.STATE17"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value1\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 97,
|
||||
"className" : "click.kamil.examples.statemachine.inheritancestate.AbstractOneStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritancestate/AbstractOneStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -351,14 +351,14 @@
|
||||
"fullIdentifier" : "States.STATE18"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value2\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 98,
|
||||
"className" : "click.kamil.examples.statemachine.inheritancestate.AbstractOneStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritancestate/AbstractOneStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -372,7 +372,7 @@
|
||||
"fullIdentifier" : "States.STATE19"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -386,14 +386,14 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardEventHeaderEquals(\"header1\",\"foo\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object header=context.getMessageHeader(headerName);\n return expected.equals(header);\n}\n",
|
||||
"lineNumber" : 103,
|
||||
"className" : "click.kamil.examples.statemachine.inheritancestate.AbstractOneStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritancestate/AbstractOneStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -407,7 +407,7 @@
|
||||
"fullIdentifier" : "States.STATE16"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -421,14 +421,14 @@
|
||||
"fullIdentifier" : "States.STATE19"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value3\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 108,
|
||||
"className" : "click.kamil.examples.statemachine.inheritancestate.AbstractOneStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritancestate/AbstractOneStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -442,7 +442,7 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -456,14 +456,14 @@
|
||||
"fullIdentifier" : "States.STATE1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"reset\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 113,
|
||||
"className" : "click.kamil.examples.statemachine.inheritancestate.AbstractOneStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritancestate/AbstractOneStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -477,7 +477,7 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -491,14 +491,14 @@
|
||||
"fullIdentifier" : "States.STATE5"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardEventHeaderEquals(\"header2\",\"bar\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object header=context.getMessageHeader(headerName);\n return expected.equals(header);\n}\n",
|
||||
"lineNumber" : 118,
|
||||
"className" : "click.kamil.examples.statemachine.inheritancestate.AbstractOneStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritancestate/AbstractOneStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -512,7 +512,7 @@
|
||||
"fullIdentifier" : "States.STATE1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -526,14 +526,14 @@
|
||||
"fullIdentifier" : "States.STATE13"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goTo13\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 123,
|
||||
"className" : "click.kamil.examples.statemachine.inheritancestate.AbstractOneStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritancestate/AbstractOneStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -547,14 +547,14 @@
|
||||
"fullIdentifier" : "States.STATE14"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goTo14\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 124,
|
||||
"className" : "click.kamil.examples.statemachine.inheritancestate.AbstractOneStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritancestate/AbstractOneStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -568,7 +568,7 @@
|
||||
"fullIdentifier" : "States.STATE15"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -582,14 +582,14 @@
|
||||
"fullIdentifier" : "States.STATE10"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goBack10\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 129,
|
||||
"className" : "click.kamil.examples.statemachine.inheritancestate.AbstractOneStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritancestate/AbstractOneStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -603,7 +603,7 @@
|
||||
"fullIdentifier" : "States.STATE11"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -617,14 +617,14 @@
|
||||
"fullIdentifier" : "States.STATE12"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"loop12\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 134,
|
||||
"className" : "click.kamil.examples.statemachine.inheritancestate.AbstractOneStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritancestate/AbstractOneStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -638,7 +638,7 @@
|
||||
"fullIdentifier" : "States.STATE16"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -652,14 +652,14 @@
|
||||
"fullIdentifier" : "States.STATE8"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBack\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 139,
|
||||
"className" : "click.kamil.examples.statemachine.inheritancestate.AbstractOneStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritancestate/AbstractOneStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -673,14 +673,14 @@
|
||||
"fullIdentifier" : "States.STATE7"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBackMore\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 140,
|
||||
"className" : "click.kamil.examples.statemachine.inheritancestate.AbstractOneStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritancestate/AbstractOneStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -694,7 +694,7 @@
|
||||
"fullIdentifier" : "States.STATE6"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -708,14 +708,14 @@
|
||||
"fullIdentifier" : "States.STATE9"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"forward9\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 145,
|
||||
"className" : "click.kamil.examples.statemachine.inheritancestate.AbstractOneStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritancestate/AbstractOneStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -729,7 +729,7 @@
|
||||
"fullIdentifier" : "States.STATE10"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -746,7 +746,7 @@
|
||||
"rawName" : "Events.EVENTX",
|
||||
"fullIdentifier" : "Events.EVENTX"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
"lineNumber" : 18,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
} ],
|
||||
"entryPoints" : [ {
|
||||
"type" : "REST",
|
||||
@@ -73,7 +74,8 @@
|
||||
"lineNumber" : 18,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -108,9 +110,10 @@
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"lineNumber" : 18,
|
||||
"polymorphicEvents" : null,
|
||||
"polymorphicEvents" : [ "SUBMIT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -140,7 +143,7 @@
|
||||
"rawName" : "\"SUBMIT\"",
|
||||
"fullIdentifier" : "SUBMIT"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ {
|
||||
"expression" : "processAction()",
|
||||
"isLambda" : false,
|
||||
@@ -164,7 +167,7 @@
|
||||
"rawName" : "\"FINISH\"",
|
||||
"fullIdentifier" : "FINISH"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"metadata" : {
|
||||
"triggers" : [ {
|
||||
"event" : "click.kamil.enterprise.machines.order.OrderEvent.PAY",
|
||||
"event" : "OrderEvent.PAY",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "payOrder",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -11,9 +11,10 @@
|
||||
"lineNumber" : 30,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.order.OrderEvent.SHIP",
|
||||
"event" : "OrderEvent.SHIP",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "shipOrder",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -23,9 +24,10 @@
|
||||
"lineNumber" : 37,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.SUBMIT",
|
||||
"event" : "DocumentEvent.SUBMIT",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "submitDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -35,9 +37,10 @@
|
||||
"lineNumber" : 44,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.APPROVE",
|
||||
"event" : "DocumentEvent.APPROVE",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "approveDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -47,9 +50,10 @@
|
||||
"lineNumber" : 51,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.REJECT",
|
||||
"event" : "DocumentEvent.REJECT",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "rejectDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -59,9 +63,10 @@
|
||||
"lineNumber" : 58,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.user.UserEvent.VERIFY",
|
||||
"event" : "UserEvent.VERIFY",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "verifyUser",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -71,9 +76,10 @@
|
||||
"lineNumber" : 65,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.user.UserEvent.SUSPEND",
|
||||
"event" : "UserEvent.SUSPEND",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "suspendUser",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -83,7 +89,8 @@
|
||||
"lineNumber" : 72,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "event",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
@@ -95,7 +102,8 @@
|
||||
"lineNumber" : 81,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "event",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
@@ -107,7 +115,8 @@
|
||||
"lineNumber" : 87,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "event",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
@@ -119,7 +128,8 @@
|
||||
"lineNumber" : 93,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
} ],
|
||||
"entryPoints" : [ {
|
||||
"type" : "REST",
|
||||
@@ -269,7 +279,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.payOrder", "click.kamil.enterprise.web.StateMachineDispatcher.payOrder" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.order.OrderEvent.PAY",
|
||||
"event" : "OrderEvent.PAY",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "payOrder",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -279,7 +289,8 @@
|
||||
"lineNumber" : 30,
|
||||
"polymorphicEvents" : [ "OrderEvent.PAY" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -306,7 +317,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.shipOrder", "click.kamil.enterprise.web.StateMachineDispatcher.shipOrder" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.order.OrderEvent.SHIP",
|
||||
"event" : "OrderEvent.SHIP",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "shipOrder",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -316,7 +327,8 @@
|
||||
"lineNumber" : 37,
|
||||
"polymorphicEvents" : [ "OrderEvent.SHIP" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -343,7 +355,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.submitDocument", "click.kamil.enterprise.web.StateMachineDispatcher.submitDocument" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.SUBMIT",
|
||||
"event" : "DocumentEvent.SUBMIT",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "submitDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -353,7 +365,8 @@
|
||||
"lineNumber" : 44,
|
||||
"polymorphicEvents" : [ "DocumentEvent.SUBMIT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -376,7 +389,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.approveDocument", "click.kamil.enterprise.web.StateMachineDispatcher.approveDocument" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.APPROVE",
|
||||
"event" : "DocumentEvent.APPROVE",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "approveDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -386,7 +399,8 @@
|
||||
"lineNumber" : 51,
|
||||
"polymorphicEvents" : [ "DocumentEvent.APPROVE" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -409,7 +423,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.rejectDocument", "click.kamil.enterprise.web.StateMachineDispatcher.rejectDocument" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.REJECT",
|
||||
"event" : "DocumentEvent.REJECT",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "rejectDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -419,7 +433,8 @@
|
||||
"lineNumber" : 58,
|
||||
"polymorphicEvents" : [ "DocumentEvent.REJECT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -442,7 +457,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.verifyUser", "click.kamil.enterprise.web.StateMachineDispatcher.verifyUser" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.user.UserEvent.VERIFY",
|
||||
"event" : "UserEvent.VERIFY",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "verifyUser",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -452,7 +467,8 @@
|
||||
"lineNumber" : 65,
|
||||
"polymorphicEvents" : [ "UserEvent.VERIFY" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -475,7 +491,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.suspendUser", "click.kamil.enterprise.web.StateMachineDispatcher.suspendUser" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.user.UserEvent.SUSPEND",
|
||||
"event" : "UserEvent.SUSPEND",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "suspendUser",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -485,7 +501,8 @@
|
||||
"lineNumber" : 72,
|
||||
"polymorphicEvents" : [ "UserEvent.SUSPEND" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -522,60 +539,12 @@
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
"sourceModule" : null,
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"sourceState" : "ORDER",
|
||||
"lineNumber" : 81,
|
||||
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
|
||||
"external" : true,
|
||||
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)"
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
"sourceState" : "OrderState.NEW",
|
||||
"targetState" : "OrderState.PENDING",
|
||||
"event" : "OrderEvent.PAY"
|
||||
}, {
|
||||
"sourceState" : "OrderState.PENDING",
|
||||
"targetState" : "OrderState.SHIPPED",
|
||||
"event" : "OrderEvent.SHIP"
|
||||
} ]
|
||||
}, {
|
||||
"entryPoint" : {
|
||||
"type" : "REST",
|
||||
"name" : "POST /api/machine/{machineType}/transition/{event}",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||
"methodName" : "transition",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||
"metadata" : {
|
||||
"path" : "/api/machine/{machineType}/transition/{event}",
|
||||
"verb" : "POST"
|
||||
},
|
||||
"parameters" : [ {
|
||||
"name" : "machineType",
|
||||
"type" : "String",
|
||||
"annotations" : [ "PathVariable" ]
|
||||
}, {
|
||||
"name" : "event",
|
||||
"type" : "String",
|
||||
"annotations" : [ "PathVariable" ]
|
||||
}, {
|
||||
"name" : "userId",
|
||||
"type" : "String",
|
||||
"annotations" : [ "RequestParam" ]
|
||||
} ]
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "true ? OrderEvent.valueOf(eventString.toUpperCase()) : true ? DocumentEvent.valueOf(eventString.toUpperCase()) : UserEvent.valueOf(eventString.toUpperCase())",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "dispatch",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
"sourceModule" : null,
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"lineNumber" : 87,
|
||||
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
|
||||
"external" : true,
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -612,11 +581,54 @@
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
"sourceModule" : null,
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"sourceState" : "DOCUMENT",
|
||||
"lineNumber" : 87,
|
||||
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
|
||||
"external" : true,
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
}, {
|
||||
"entryPoint" : {
|
||||
"type" : "REST",
|
||||
"name" : "POST /api/machine/{machineType}/transition/{event}",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineController",
|
||||
"methodName" : "transition",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineController.java",
|
||||
"metadata" : {
|
||||
"path" : "/api/machine/{machineType}/transition/{event}",
|
||||
"verb" : "POST"
|
||||
},
|
||||
"parameters" : [ {
|
||||
"name" : "machineType",
|
||||
"type" : "String",
|
||||
"annotations" : [ "PathVariable" ]
|
||||
}, {
|
||||
"name" : "event",
|
||||
"type" : "String",
|
||||
"annotations" : [ "PathVariable" ]
|
||||
}, {
|
||||
"name" : "userId",
|
||||
"type" : "String",
|
||||
"annotations" : [ "RequestParam" ]
|
||||
} ]
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.transition", "click.kamil.enterprise.web.StateMachineDispatcher.dispatch" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "true ? OrderEvent.valueOf(eventString.toUpperCase()) : true ? DocumentEvent.valueOf(eventString.toUpperCase()) : UserEvent.valueOf(eventString.toUpperCase())",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "dispatch",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
"sourceModule" : null,
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : "USER",
|
||||
"lineNumber" : 93,
|
||||
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
|
||||
"external" : true,
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -642,7 +654,7 @@
|
||||
"rawName" : "OrderEvent.PAY",
|
||||
"fullIdentifier" : "OrderEvent.PAY"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ {
|
||||
"expression" : "context -> System.out.println(\"Payment processed.\")",
|
||||
"isLambda" : true,
|
||||
@@ -666,7 +678,7 @@
|
||||
"rawName" : "OrderEvent.SHIP",
|
||||
"fullIdentifier" : "OrderEvent.SHIP"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
"lineNumber" : 13,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "payload",
|
||||
"className" : "click.kamil.examples.statemachine.polymorphic.OrderService",
|
||||
@@ -23,7 +24,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "event",
|
||||
"className" : "click.kamil.examples.statemachine.polymorphic.OrderService",
|
||||
@@ -35,7 +37,8 @@
|
||||
"lineNumber" : 21,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
} ],
|
||||
"entryPoints" : [ {
|
||||
"type" : "REST",
|
||||
@@ -199,7 +202,8 @@
|
||||
"lineNumber" : 13,
|
||||
"polymorphicEvents" : [ "OrderEvents.PAY" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -232,7 +236,8 @@
|
||||
"lineNumber" : 13,
|
||||
"polymorphicEvents" : [ "OrderEvents.FULFILL" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -265,7 +270,8 @@
|
||||
"lineNumber" : 13,
|
||||
"polymorphicEvents" : [ "OrderEvents.CANCEL" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -298,7 +304,8 @@
|
||||
"lineNumber" : 17,
|
||||
"polymorphicEvents" : [ "OrderEvents.PAY" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -331,7 +338,8 @@
|
||||
"lineNumber" : 13,
|
||||
"polymorphicEvents" : [ "OrderEvents.PAY" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -364,7 +372,8 @@
|
||||
"lineNumber" : 13,
|
||||
"polymorphicEvents" : [ "OrderEvents.PAY" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -401,7 +410,8 @@
|
||||
"lineNumber" : 13,
|
||||
"polymorphicEvents" : [ "OrderEvents.PAY", "OrderEvents.CANCEL" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -438,7 +448,8 @@
|
||||
"lineNumber" : 13,
|
||||
"polymorphicEvents" : [ "OrderEvents.PAY" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -471,7 +482,8 @@
|
||||
"lineNumber" : 13,
|
||||
"polymorphicEvents" : [ "OrderEvents.FULFILL" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -504,7 +516,8 @@
|
||||
"lineNumber" : 13,
|
||||
"polymorphicEvents" : [ "OrderEvents.CANCEL" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -537,7 +550,8 @@
|
||||
"lineNumber" : 21,
|
||||
"polymorphicEvents" : [ "OrderEvents.ABCD" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -570,7 +584,8 @@
|
||||
"lineNumber" : 21,
|
||||
"polymorphicEvents" : [ "OrderEvents.ABCD", "OrderEvents.PAY" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -606,7 +621,7 @@
|
||||
"rawName" : "OrderEvents.PAY",
|
||||
"fullIdentifier" : "OrderEvents.PAY"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -623,7 +638,7 @@
|
||||
"rawName" : "OrderEvents.FULFILL",
|
||||
"fullIdentifier" : "OrderEvents.FULFILL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -640,7 +655,7 @@
|
||||
"rawName" : "OrderEvents.CANCEL",
|
||||
"fullIdentifier" : "OrderEvents.CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -657,7 +672,7 @@
|
||||
"rawName" : "OrderEvents.ABCD",
|
||||
"fullIdentifier" : "OrderEvents.ABCD"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"rawName" : "OrderEvents.PAY",
|
||||
"fullIdentifier" : "OrderEvents.PAY"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -43,7 +43,7 @@
|
||||
"rawName" : "OrderEvents.FULFILL",
|
||||
"fullIdentifier" : "OrderEvents.FULFILL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -60,14 +60,14 @@
|
||||
"rawName" : "OrderEvents.CANCEL",
|
||||
"fullIdentifier" : "OrderEvents.CANCEL"
|
||||
},
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "new Guard<OrderStates,OrderEvents>(){\n @Override public boolean evaluate( StateContext<OrderStates,OrderEvents> context){\n return false;\n }\n}\n",
|
||||
"isLambda" : true,
|
||||
"internalLogic" : "new Guard<OrderStates,OrderEvents>(){\n @Override public boolean evaluate( StateContext<OrderStates,OrderEvents> context){\n return false;\n }\n}\n",
|
||||
"lineNumber" : 29,
|
||||
"className" : "click.kamil.examples.statemachine.simple.SimpleEnumStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/simple/SimpleEnumStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -84,7 +84,7 @@
|
||||
"rawName" : "OrderEvents.CANCEL",
|
||||
"fullIdentifier" : "OrderEvents.CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -98,7 +98,7 @@
|
||||
"rawName" : "OrderEvents.ABCD",
|
||||
"fullIdentifier" : "OrderEvents.ABCD"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -112,14 +112,14 @@
|
||||
"fullIdentifier" : "OrderStates.PAID2"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "new Guard<OrderStates,OrderEvents>(){\n @Override public boolean evaluate( StateContext<OrderStates,OrderEvents> context){\n return false;\n }\n}\n",
|
||||
"isLambda" : true,
|
||||
"internalLogic" : "new Guard<OrderStates,OrderEvents>(){\n @Override public boolean evaluate( StateContext<OrderStates,OrderEvents> context){\n return false;\n }\n}\n",
|
||||
"lineNumber" : 46,
|
||||
"className" : "click.kamil.examples.statemachine.simple.SimpleEnumStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/simple/SimpleEnumStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -133,7 +133,7 @@
|
||||
"fullIdentifier" : "OrderStates.PAID3"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -147,14 +147,14 @@
|
||||
"fullIdentifier" : "OrderStates.PAID1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "new Guard<OrderStates,OrderEvents>(){\n @Override public boolean evaluate( StateContext<OrderStates,OrderEvents> context){\n return true;\n }\n}\n",
|
||||
"isLambda" : true,
|
||||
"internalLogic" : "new Guard<OrderStates,OrderEvents>(){\n @Override public boolean evaluate( StateContext<OrderStates,OrderEvents> context){\n return true;\n }\n}\n",
|
||||
"lineNumber" : 55,
|
||||
"className" : "click.kamil.examples.statemachine.simple.SimpleEnumStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/simple/SimpleEnumStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -168,14 +168,14 @@
|
||||
"fullIdentifier" : "OrderStates.PAID2"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guard1",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : null,
|
||||
"lineNumber" : 61,
|
||||
"className" : "click.kamil.examples.statemachine.simple.SimpleEnumStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/simple/SimpleEnumStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -189,14 +189,14 @@
|
||||
"fullIdentifier" : "OrderStates.HAPPEN"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "new Guard<OrderStates,OrderEvents>(){\n @Override public boolean evaluate( StateContext<OrderStates,OrderEvents> context){\n return false;\n }\n}\n",
|
||||
"isLambda" : true,
|
||||
"internalLogic" : "new Guard<OrderStates,OrderEvents>(){\n @Override public boolean evaluate( StateContext<OrderStates,OrderEvents> context){\n return false;\n }\n}\n",
|
||||
"lineNumber" : 62,
|
||||
"className" : "click.kamil.examples.statemachine.simple.SimpleEnumStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/simple/SimpleEnumStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -210,7 +210,7 @@
|
||||
"fullIdentifier" : "OrderStates.PAID3"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 3
|
||||
}, {
|
||||
@@ -224,7 +224,7 @@
|
||||
"fullIdentifier" : "OrderStates.CANCELED"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -238,7 +238,7 @@
|
||||
"fullIdentifier" : "OrderStates.CANCELED"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -252,7 +252,7 @@
|
||||
"rawName" : "OrderEvents.ABCD",
|
||||
"fullIdentifier" : "OrderEvents.ABCD"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ {
|
||||
"expression" : "new Action<OrderStates,OrderEvents>(){\n @Override public void execute( StateContext<OrderStates,OrderEvents> context){\n ;\n }\n}\n",
|
||||
"isLambda" : true,
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
"lineNumber" : 25,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : "event instanceof OrderEvent"
|
||||
"constraint" : "event instanceof OrderEvent",
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "eventProvider",
|
||||
"className" : "click.kamil.service.StateMachineServiceImpl",
|
||||
@@ -23,7 +24,8 @@
|
||||
"lineNumber" : 50,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : "event != null"
|
||||
"constraint" : "event != null",
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "customMessage",
|
||||
"className" : "click.kamil.service.StateMachineServiceImpl",
|
||||
@@ -35,7 +37,8 @@
|
||||
"lineNumber" : 78,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
} ],
|
||||
"entryPoints" : [ {
|
||||
"type" : "REST",
|
||||
@@ -152,7 +155,8 @@
|
||||
"lineNumber" : 25,
|
||||
"polymorphicEvents" : [ "OrderEvent.PROCESS" ],
|
||||
"external" : false,
|
||||
"constraint" : "event instanceof OrderEvent"
|
||||
"constraint" : "event instanceof OrderEvent",
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -185,7 +189,8 @@
|
||||
"lineNumber" : 25,
|
||||
"polymorphicEvents" : [ "OrderEvent.COMPLETE" ],
|
||||
"external" : false,
|
||||
"constraint" : "event instanceof OrderEvent"
|
||||
"constraint" : "event instanceof OrderEvent",
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -218,7 +223,8 @@
|
||||
"lineNumber" : 25,
|
||||
"polymorphicEvents" : [ "OrderEvent.CANCEL" ],
|
||||
"external" : false,
|
||||
"constraint" : "event instanceof OrderEvent"
|
||||
"constraint" : "event instanceof OrderEvent",
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -255,7 +261,8 @@
|
||||
"lineNumber" : 25,
|
||||
"polymorphicEvents" : [ "OrderEvent.COMPLETE" ],
|
||||
"external" : false,
|
||||
"constraint" : "event instanceof OrderEvent"
|
||||
"constraint" : "event instanceof OrderEvent",
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -292,7 +299,8 @@
|
||||
"lineNumber" : 78,
|
||||
"polymorphicEvents" : [ ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -325,7 +333,8 @@
|
||||
"lineNumber" : 25,
|
||||
"polymorphicEvents" : [ "OrderEvent.PROCESS" ],
|
||||
"external" : false,
|
||||
"constraint" : "event instanceof OrderEvent"
|
||||
"constraint" : "event instanceof OrderEvent",
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -362,7 +371,8 @@
|
||||
"lineNumber" : 50,
|
||||
"polymorphicEvents" : [ "OrderEvent.CANCEL" ],
|
||||
"external" : false,
|
||||
"constraint" : "event != null"
|
||||
"constraint" : "event != null",
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -396,7 +406,7 @@
|
||||
"rawName" : "OrderEvent.PROCESS",
|
||||
"fullIdentifier" : "OrderEvent.PROCESS"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -413,7 +423,7 @@
|
||||
"rawName" : "OrderEvent.COMPLETE",
|
||||
"fullIdentifier" : "OrderEvent.COMPLETE"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -430,7 +440,7 @@
|
||||
"rawName" : "OrderEvent.CANCEL",
|
||||
"fullIdentifier" : "OrderEvent.CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -447,7 +457,7 @@
|
||||
"rawName" : "OrderEvent.CANCEL",
|
||||
"fullIdentifier" : "OrderEvent.CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"rawName" : "Events.EVENT1",
|
||||
"fullIdentifier" : "Events.EVENT1"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -43,7 +43,7 @@
|
||||
"rawName" : "Events.EVENT2",
|
||||
"fullIdentifier" : "Events.EVENT2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -60,7 +60,7 @@
|
||||
"rawName" : "Events.EVENT3",
|
||||
"fullIdentifier" : "Events.EVENT3"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -77,7 +77,7 @@
|
||||
"rawName" : "Events.EVENT4",
|
||||
"fullIdentifier" : "Events.EVENT4"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -94,7 +94,7 @@
|
||||
"rawName" : "Events.EVENT5",
|
||||
"fullIdentifier" : "Events.EVENT5"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -111,7 +111,7 @@
|
||||
"rawName" : "Events.EVENT6",
|
||||
"fullIdentifier" : "Events.EVENT6"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -128,7 +128,7 @@
|
||||
"rawName" : "Events.EVENT7",
|
||||
"fullIdentifier" : "Events.EVENT7"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -145,7 +145,7 @@
|
||||
"rawName" : "Events.EVENT8",
|
||||
"fullIdentifier" : "Events.EVENT8"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -162,7 +162,7 @@
|
||||
"rawName" : "Events.EVENT9",
|
||||
"fullIdentifier" : "Events.EVENT9"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -179,7 +179,7 @@
|
||||
"rawName" : "Events.EVENT10",
|
||||
"fullIdentifier" : "Events.EVENT10"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -196,7 +196,7 @@
|
||||
"rawName" : "Events.EVENT11",
|
||||
"fullIdentifier" : "Events.EVENT11"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -213,7 +213,7 @@
|
||||
"rawName" : "Events.EVENT12",
|
||||
"fullIdentifier" : "Events.EVENT12"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -230,7 +230,7 @@
|
||||
"rawName" : "Events.EVENT13",
|
||||
"fullIdentifier" : "Events.EVENT13"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -247,7 +247,7 @@
|
||||
"rawName" : "Events.EVENT14",
|
||||
"fullIdentifier" : "Events.EVENT14"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -264,7 +264,7 @@
|
||||
"rawName" : "Events.EVENT15",
|
||||
"fullIdentifier" : "Events.EVENT15"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -281,7 +281,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -298,7 +298,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -315,7 +315,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -332,7 +332,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -349,7 +349,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -366,7 +366,7 @@
|
||||
"rawName" : "Events.EVENTY",
|
||||
"fullIdentifier" : "Events.EVENTY"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -380,14 +380,14 @@
|
||||
"fullIdentifier" : "States.STATEX"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value1\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 120,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.AbstractThreeStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate2/AbstractThreeStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -401,7 +401,7 @@
|
||||
"fullIdentifier" : "States.STATEZ"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -415,14 +415,14 @@
|
||||
"fullIdentifier" : "States.STATE17"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value1\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 126,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.AbstractThreeStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate2/AbstractThreeStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -436,14 +436,14 @@
|
||||
"fullIdentifier" : "States.STATE18"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value2\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 127,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.AbstractThreeStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate2/AbstractThreeStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -457,7 +457,7 @@
|
||||
"fullIdentifier" : "States.STATE19"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -471,14 +471,14 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardEventHeaderEquals(\"header1\",\"foo\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object header=context.getMessageHeader(headerName);\n return expected.equals(header);\n}\n",
|
||||
"lineNumber" : 132,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.AbstractThreeStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate2/AbstractThreeStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -492,7 +492,7 @@
|
||||
"fullIdentifier" : "States.STATE16"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -506,14 +506,14 @@
|
||||
"fullIdentifier" : "States.STATE19"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value3\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 137,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.AbstractThreeStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate2/AbstractThreeStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -527,7 +527,7 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -541,14 +541,14 @@
|
||||
"fullIdentifier" : "States.STATE1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"reset\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 142,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.AbstractThreeStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate2/AbstractThreeStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -562,7 +562,7 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -576,14 +576,14 @@
|
||||
"fullIdentifier" : "States.STATE5"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardEventHeaderEquals(\"header2\",\"bar\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object header=context.getMessageHeader(headerName);\n return expected.equals(header);\n}\n",
|
||||
"lineNumber" : 147,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.AbstractThreeStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate2/AbstractThreeStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -597,7 +597,7 @@
|
||||
"fullIdentifier" : "States.STATE1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -611,14 +611,14 @@
|
||||
"fullIdentifier" : "States.STATE13"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goTo13\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 152,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.AbstractThreeStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate2/AbstractThreeStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -632,14 +632,14 @@
|
||||
"fullIdentifier" : "States.STATE14"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goTo14\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 153,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.AbstractThreeStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate2/AbstractThreeStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -653,7 +653,7 @@
|
||||
"fullIdentifier" : "States.STATE15"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -667,14 +667,14 @@
|
||||
"fullIdentifier" : "States.STATE10"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goBack10\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 158,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.AbstractThreeStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate2/AbstractThreeStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -688,7 +688,7 @@
|
||||
"fullIdentifier" : "States.STATE11"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -702,14 +702,14 @@
|
||||
"fullIdentifier" : "States.STATE12"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"loop12\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 163,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.AbstractThreeStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate2/AbstractThreeStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -723,7 +723,7 @@
|
||||
"fullIdentifier" : "States.STATE16"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -737,14 +737,14 @@
|
||||
"fullIdentifier" : "States.STATE8"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBack\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 168,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.AbstractThreeStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate2/AbstractThreeStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -758,14 +758,14 @@
|
||||
"fullIdentifier" : "States.STATE7"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBackMore\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 169,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.AbstractThreeStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate2/AbstractThreeStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -779,7 +779,7 @@
|
||||
"fullIdentifier" : "States.STATE6"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -793,14 +793,14 @@
|
||||
"fullIdentifier" : "States.STATE9"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"forward9\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 174,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.AbstractThreeStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate2/AbstractThreeStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -814,7 +814,7 @@
|
||||
"fullIdentifier" : "States.STATE10"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -831,7 +831,7 @@
|
||||
"rawName" : "Events.EVENTX",
|
||||
"fullIdentifier" : "Events.EVENTX"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -845,14 +845,14 @@
|
||||
"fullIdentifier" : "States.STATE1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardEventHeaderEquals(\"header1\",\"foo\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object header=context.getMessageHeader(headerName);\n return expected.equals(header);\n}\n",
|
||||
"lineNumber" : 31,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.ThreeStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate2/ThreeStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -866,7 +866,7 @@
|
||||
"fullIdentifier" : "States.STATE_EXTRA_1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -883,7 +883,7 @@
|
||||
"rawName" : "Events.EVENTY",
|
||||
"fullIdentifier" : "Events.EVENTY"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -900,7 +900,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL_2",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL_2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -917,7 +917,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL_2",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL_2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"rawName" : "Events.EVENT1",
|
||||
"fullIdentifier" : "Events.EVENT1"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -43,7 +43,7 @@
|
||||
"rawName" : "Events.EVENT2",
|
||||
"fullIdentifier" : "Events.EVENT2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -60,7 +60,7 @@
|
||||
"rawName" : "Events.EVENT3",
|
||||
"fullIdentifier" : "Events.EVENT3"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -77,7 +77,7 @@
|
||||
"rawName" : "Events.EVENT4",
|
||||
"fullIdentifier" : "Events.EVENT4"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -94,7 +94,7 @@
|
||||
"rawName" : "Events.EVENT5",
|
||||
"fullIdentifier" : "Events.EVENT5"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -111,7 +111,7 @@
|
||||
"rawName" : "Events.EVENT6",
|
||||
"fullIdentifier" : "Events.EVENT6"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -128,7 +128,7 @@
|
||||
"rawName" : "Events.EVENT7",
|
||||
"fullIdentifier" : "Events.EVENT7"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -145,7 +145,7 @@
|
||||
"rawName" : "Events.EVENT8",
|
||||
"fullIdentifier" : "Events.EVENT8"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -162,7 +162,7 @@
|
||||
"rawName" : "Events.EVENT9",
|
||||
"fullIdentifier" : "Events.EVENT9"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -179,7 +179,7 @@
|
||||
"rawName" : "Events.EVENT10",
|
||||
"fullIdentifier" : "Events.EVENT10"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -196,7 +196,7 @@
|
||||
"rawName" : "Events.EVENT11",
|
||||
"fullIdentifier" : "Events.EVENT11"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -213,7 +213,7 @@
|
||||
"rawName" : "Events.EVENT12",
|
||||
"fullIdentifier" : "Events.EVENT12"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -230,7 +230,7 @@
|
||||
"rawName" : "Events.EVENT13",
|
||||
"fullIdentifier" : "Events.EVENT13"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -247,7 +247,7 @@
|
||||
"rawName" : "Events.EVENT14",
|
||||
"fullIdentifier" : "Events.EVENT14"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -264,7 +264,7 @@
|
||||
"rawName" : "Events.EVENT15",
|
||||
"fullIdentifier" : "Events.EVENT15"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -281,7 +281,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -298,7 +298,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -315,7 +315,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -332,7 +332,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -349,7 +349,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -366,7 +366,7 @@
|
||||
"rawName" : "Events.EVENTY",
|
||||
"fullIdentifier" : "Events.EVENTY"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -380,14 +380,14 @@
|
||||
"fullIdentifier" : "States.STATEX"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value1\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 120,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate.AbstractTwoStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate/AbstractTwoStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -401,7 +401,7 @@
|
||||
"fullIdentifier" : "States.STATEZ"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -415,14 +415,14 @@
|
||||
"fullIdentifier" : "States.STATE17"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value1\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 126,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate.AbstractTwoStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate/AbstractTwoStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -436,14 +436,14 @@
|
||||
"fullIdentifier" : "States.STATE18"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value2\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 127,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate.AbstractTwoStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate/AbstractTwoStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -457,7 +457,7 @@
|
||||
"fullIdentifier" : "States.STATE19"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -471,14 +471,14 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardEventHeaderEquals(\"header1\",\"foo\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object header=context.getMessageHeader(headerName);\n return expected.equals(header);\n}\n",
|
||||
"lineNumber" : 132,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate.AbstractTwoStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate/AbstractTwoStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -492,7 +492,7 @@
|
||||
"fullIdentifier" : "States.STATE16"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -506,14 +506,14 @@
|
||||
"fullIdentifier" : "States.STATE19"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"value3\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 137,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate.AbstractTwoStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate/AbstractTwoStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -527,7 +527,7 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -541,14 +541,14 @@
|
||||
"fullIdentifier" : "States.STATE1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"reset\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 142,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate.AbstractTwoStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate/AbstractTwoStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -562,7 +562,7 @@
|
||||
"fullIdentifier" : "States.STATE20"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -576,14 +576,14 @@
|
||||
"fullIdentifier" : "States.STATE5"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardEventHeaderEquals(\"header2\",\"bar\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object header=context.getMessageHeader(headerName);\n return expected.equals(header);\n}\n",
|
||||
"lineNumber" : 147,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate.AbstractTwoStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate/AbstractTwoStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -597,7 +597,7 @@
|
||||
"fullIdentifier" : "States.STATE1"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -611,14 +611,14 @@
|
||||
"fullIdentifier" : "States.STATE13"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goTo13\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 152,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate.AbstractTwoStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate/AbstractTwoStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -632,14 +632,14 @@
|
||||
"fullIdentifier" : "States.STATE14"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goTo14\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 153,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate.AbstractTwoStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate/AbstractTwoStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -653,7 +653,7 @@
|
||||
"fullIdentifier" : "States.STATE15"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -667,14 +667,14 @@
|
||||
"fullIdentifier" : "States.STATE10"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"goBack10\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 158,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate.AbstractTwoStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate/AbstractTwoStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -688,7 +688,7 @@
|
||||
"fullIdentifier" : "States.STATE11"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -702,14 +702,14 @@
|
||||
"fullIdentifier" : "States.STATE12"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"loop12\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 163,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate.AbstractTwoStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate/AbstractTwoStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -723,7 +723,7 @@
|
||||
"fullIdentifier" : "States.STATE16"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -737,14 +737,14 @@
|
||||
"fullIdentifier" : "States.STATE8"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBack\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 168,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate.AbstractTwoStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate/AbstractTwoStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -758,14 +758,14 @@
|
||||
"fullIdentifier" : "States.STATE7"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"stepBackMore\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 169,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate.AbstractTwoStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate/AbstractTwoStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -779,7 +779,7 @@
|
||||
"fullIdentifier" : "States.STATE6"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 2
|
||||
}, {
|
||||
@@ -793,14 +793,14 @@
|
||||
"fullIdentifier" : "States.STATE9"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : {
|
||||
"guards" : [ {
|
||||
"expression" : "guardVarEquals(\"forward9\")",
|
||||
"isLambda" : false,
|
||||
"internalLogic" : "context -> {\n Object var=context.getExtendedState().getVariables().get(\"var\");\n return expected.equals(var);\n}\n",
|
||||
"lineNumber" : 174,
|
||||
"className" : "click.kamil.examples.statemachine.inheritanceextrafunctionsstate.AbstractTwoStateMachineConfiguration",
|
||||
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritanceextrafunctionsstate/AbstractTwoStateMachineConfiguration.java"
|
||||
},
|
||||
} ],
|
||||
"actions" : [ ],
|
||||
"order" : 0
|
||||
}, {
|
||||
@@ -814,7 +814,7 @@
|
||||
"fullIdentifier" : "States.STATE10"
|
||||
} ],
|
||||
"event" : null,
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : 1
|
||||
}, {
|
||||
@@ -831,7 +831,7 @@
|
||||
"rawName" : "Events.EVENTX",
|
||||
"fullIdentifier" : "Events.EVENTX"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -848,7 +848,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -865,7 +865,7 @@
|
||||
"rawName" : "Events.EVENT_CANCEL_2",
|
||||
"fullIdentifier" : "Events.EVENT_CANCEL_2"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"metadata" : {
|
||||
"triggers" : [ {
|
||||
"event" : "click.kamil.enterprise.machines.order.OrderEvent.PAY",
|
||||
"event" : "OrderEvent.PAY",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "payOrder",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -11,9 +11,10 @@
|
||||
"lineNumber" : 30,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.order.OrderEvent.SHIP",
|
||||
"event" : "OrderEvent.SHIP",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "shipOrder",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -23,9 +24,10 @@
|
||||
"lineNumber" : 37,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.SUBMIT",
|
||||
"event" : "DocumentEvent.SUBMIT",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "submitDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -35,9 +37,10 @@
|
||||
"lineNumber" : 44,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.APPROVE",
|
||||
"event" : "DocumentEvent.APPROVE",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "approveDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -47,9 +50,10 @@
|
||||
"lineNumber" : 51,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.REJECT",
|
||||
"event" : "DocumentEvent.REJECT",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "rejectDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -59,9 +63,10 @@
|
||||
"lineNumber" : 58,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.user.UserEvent.VERIFY",
|
||||
"event" : "UserEvent.VERIFY",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "verifyUser",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -71,9 +76,10 @@
|
||||
"lineNumber" : 65,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "click.kamil.enterprise.machines.user.UserEvent.SUSPEND",
|
||||
"event" : "UserEvent.SUSPEND",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "suspendUser",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -83,7 +89,8 @@
|
||||
"lineNumber" : 72,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "event",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
@@ -95,7 +102,8 @@
|
||||
"lineNumber" : 81,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "event",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
@@ -107,7 +115,8 @@
|
||||
"lineNumber" : 87,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
}, {
|
||||
"event" : "event",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
@@ -119,7 +128,8 @@
|
||||
"lineNumber" : 93,
|
||||
"polymorphicEvents" : null,
|
||||
"external" : false,
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
} ],
|
||||
"entryPoints" : [ {
|
||||
"type" : "REST",
|
||||
@@ -269,7 +279,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.payOrder", "click.kamil.enterprise.web.StateMachineDispatcher.payOrder" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.order.OrderEvent.PAY",
|
||||
"event" : "OrderEvent.PAY",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "payOrder",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -279,7 +289,8 @@
|
||||
"lineNumber" : 30,
|
||||
"polymorphicEvents" : [ "OrderEvent.PAY" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -302,7 +313,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.shipOrder", "click.kamil.enterprise.web.StateMachineDispatcher.shipOrder" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.order.OrderEvent.SHIP",
|
||||
"event" : "OrderEvent.SHIP",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "shipOrder",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -312,7 +323,8 @@
|
||||
"lineNumber" : 37,
|
||||
"polymorphicEvents" : [ "OrderEvent.SHIP" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -335,7 +347,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.submitDocument", "click.kamil.enterprise.web.StateMachineDispatcher.submitDocument" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.SUBMIT",
|
||||
"event" : "DocumentEvent.SUBMIT",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "submitDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -345,7 +357,8 @@
|
||||
"lineNumber" : 44,
|
||||
"polymorphicEvents" : [ "DocumentEvent.SUBMIT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -368,7 +381,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.approveDocument", "click.kamil.enterprise.web.StateMachineDispatcher.approveDocument" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.APPROVE",
|
||||
"event" : "DocumentEvent.APPROVE",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "approveDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -378,7 +391,8 @@
|
||||
"lineNumber" : 51,
|
||||
"polymorphicEvents" : [ "DocumentEvent.APPROVE" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -401,7 +415,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.rejectDocument", "click.kamil.enterprise.web.StateMachineDispatcher.rejectDocument" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.document.DocumentEvent.REJECT",
|
||||
"event" : "DocumentEvent.REJECT",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "rejectDocument",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -411,7 +425,8 @@
|
||||
"lineNumber" : 58,
|
||||
"polymorphicEvents" : [ "DocumentEvent.REJECT" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -434,7 +449,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.verifyUser", "click.kamil.enterprise.web.StateMachineDispatcher.verifyUser" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.user.UserEvent.VERIFY",
|
||||
"event" : "UserEvent.VERIFY",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "verifyUser",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -444,7 +459,8 @@
|
||||
"lineNumber" : 65,
|
||||
"polymorphicEvents" : [ "UserEvent.VERIFY" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
@@ -471,7 +487,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.enterprise.web.StateMachineController.suspendUser", "click.kamil.enterprise.web.StateMachineDispatcher.suspendUser" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "click.kamil.enterprise.machines.user.UserEvent.SUSPEND",
|
||||
"event" : "UserEvent.SUSPEND",
|
||||
"className" : "click.kamil.enterprise.web.StateMachineDispatcher",
|
||||
"methodName" : "suspendUser",
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
@@ -481,7 +497,8 @@
|
||||
"lineNumber" : 72,
|
||||
"polymorphicEvents" : [ "UserEvent.SUSPEND" ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
"constraint" : null,
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -518,11 +535,12 @@
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
"sourceModule" : null,
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"sourceState" : "ORDER",
|
||||
"lineNumber" : 81,
|
||||
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
|
||||
"external" : true,
|
||||
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "\"ORDER\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -559,11 +577,12 @@
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
"sourceModule" : null,
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"sourceState" : "DOCUMENT",
|
||||
"lineNumber" : 87,
|
||||
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
|
||||
"external" : true,
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : null
|
||||
@@ -600,22 +619,15 @@
|
||||
"sourceFile" : "src/main/java/click/kamil/enterprise/web/StateMachineDispatcher.java",
|
||||
"sourceModule" : null,
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"sourceState" : "USER",
|
||||
"lineNumber" : 93,
|
||||
"polymorphicEvents" : [ "<SYMBOLIC: OrderEvent.*>", "<SYMBOLIC: DocumentEvent.*>", "<SYMBOLIC: UserEvent.*>" ],
|
||||
"external" : true,
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)"
|
||||
"constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)",
|
||||
"ambiguous" : false
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
"sourceState" : "UserState.GUEST",
|
||||
"targetState" : "UserState.REGISTERED",
|
||||
"event" : "UserEvent.REGISTER"
|
||||
}, {
|
||||
"sourceState" : "UserState.REGISTERED",
|
||||
"targetState" : "UserState.VERIFIED",
|
||||
"event" : "UserEvent.VERIFY"
|
||||
} ]
|
||||
"matchedTransitions" : null
|
||||
} ],
|
||||
"properties" : {
|
||||
"default" : { }
|
||||
@@ -638,7 +650,7 @@
|
||||
"rawName" : "UserEvent.REGISTER",
|
||||
"fullIdentifier" : "UserEvent.REGISTER"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
}, {
|
||||
@@ -655,7 +667,7 @@
|
||||
"rawName" : "UserEvent.VERIFY",
|
||||
"fullIdentifier" : "UserEvent.VERIFY"
|
||||
},
|
||||
"guard" : null,
|
||||
"guards" : [ ],
|
||||
"actions" : [ ],
|
||||
"order" : null
|
||||
} ],
|
||||
|
||||
@@ -217,6 +217,22 @@
|
||||
stroke-width: 3.5px;
|
||||
}
|
||||
|
||||
.active-path-ambiguous {
|
||||
stroke: #f97316 !important;
|
||||
stroke-width: 2.5px !important;
|
||||
stroke-dasharray: 6, 4;
|
||||
filter: drop-shadow(0 0 8px rgba(249, 115, 22, 0.4));
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.active-path-ambiguous text, a.active-path-ambiguous text {
|
||||
fill: #000 !important;
|
||||
font-weight: 900 !important;
|
||||
paint-order: stroke;
|
||||
stroke: #fff;
|
||||
stroke-width: 3.5px;
|
||||
}
|
||||
|
||||
.dimmed {
|
||||
opacity: 0.2 !important;
|
||||
filter: grayscale(1);
|
||||
@@ -418,7 +434,7 @@
|
||||
if (c.entryPoint.className === ep.className && c.entryPoint.methodName === ep.methodName) {
|
||||
if (c.matchedTransitions && c.matchedTransitions.length > 0) {
|
||||
c.matchedTransitions.forEach(t => {
|
||||
steps.push({ event: t.event, source: t.sourceState });
|
||||
steps.push({ event: t.event, source: t.sourceState, ambiguous: c.triggerPoint && c.triggerPoint.ambiguous });
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -446,10 +462,12 @@
|
||||
let targetEvent = "";
|
||||
let targetSource = "";
|
||||
let targetAnon = "";
|
||||
let isAmbiguous = false;
|
||||
|
||||
if (typeof step === 'object') {
|
||||
targetEvent = normalize(step.event);
|
||||
targetSource = normalize(step.source);
|
||||
isAmbiguous = step.ambiguous;
|
||||
} else if (step.includes("->")) {
|
||||
const parts = step.split("->");
|
||||
targetAnon = "#link_anon_" + normalize(parts[0]) + "_" + normalize(parts[1]);
|
||||
@@ -475,7 +493,7 @@
|
||||
}
|
||||
|
||||
if (matches) {
|
||||
highlightLinkGroup(link);
|
||||
highlightLinkGroup(link, isAmbiguous);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -494,8 +512,9 @@
|
||||
});
|
||||
}
|
||||
|
||||
function highlightLinkGroup(link) {
|
||||
link.classList.add('active-path');
|
||||
function highlightLinkGroup(link, isAmbiguous) {
|
||||
const activeClass = isAmbiguous ? 'active-path-ambiguous' : 'active-path';
|
||||
link.classList.add(activeClass);
|
||||
link.querySelectorAll('*').forEach(child => child.classList.remove('dimmed'));
|
||||
|
||||
// Find path and polygon immediately before the <a> tag (interleaved)
|
||||
@@ -505,11 +524,11 @@
|
||||
while (prev) {
|
||||
if (prev.tagName === 'path' && !foundPath) {
|
||||
prev.classList.remove('dimmed');
|
||||
prev.classList.add('active-path');
|
||||
prev.classList.add(activeClass);
|
||||
foundPath = true;
|
||||
} else if (prev.tagName === 'polygon' && !foundPolygon && prev.points?.numberOfItems !== 4) {
|
||||
prev.classList.remove('dimmed');
|
||||
prev.classList.add('active-path');
|
||||
prev.classList.add(activeClass);
|
||||
foundPolygon = true;
|
||||
} else if (['rect', 'circle', 'ellipse'].includes(prev.tagName) ||
|
||||
(prev.tagName === 'polygon' && prev.points?.numberOfItems === 4)) {
|
||||
@@ -522,8 +541,8 @@
|
||||
}
|
||||
|
||||
function clearHighlights() {
|
||||
document.querySelectorAll('.dimmed, .active-path').forEach(el => {
|
||||
el.classList.remove('dimmed', 'active-path');
|
||||
document.querySelectorAll('.dimmed, .active-path, .active-path-ambiguous').forEach(el => {
|
||||
el.classList.remove('dimmed', 'active-path', 'active-path-ambiguous');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -629,9 +648,11 @@
|
||||
html += `<div style="font-size:0.7rem; font-weight:800; color:#94a3b8; text-transform:uppercase; margin-bottom:10px; border-top:1px solid #eee; padding-top:10px">Triggered by</div>`;
|
||||
chains.forEach(c => {
|
||||
const triggerInfo = c.triggerPoint.sourceFile ? ` <span style="color:#94a3b8; font-weight:400; font-size:0.6rem;">(${c.triggerPoint.sourceFile}:${c.triggerPoint.lineNumber})</span>` : '';
|
||||
const ambiguousLabel = c.triggerPoint.ambiguous ? `<div style="display:inline-block; margin-top:4px; padding:2px 6px; background:#fff7ed; color:#ea580c; border:1px solid #fed7aa; border-radius:4px; font-size:0.6rem; font-weight:700;">⚠️ Ambiguous Resolution (Over-approximated)</div>` : '';
|
||||
html += `<div style="margin-bottom:20px">
|
||||
<div style="font-weight:700; font-size:0.85rem; color:var(--text);">${c.entryPoint.name}</div>
|
||||
<div style="font-size:0.65rem; color:#64748b; font-family:monospace; margin-top:2px;">Trigger: ${c.triggerPoint.methodName}${triggerInfo}</div>
|
||||
${ambiguousLabel}
|
||||
${renderParameters(c.entryPoint.parameters)}
|
||||
<div style="margin-left:10px; border-left:2px solid #e2e8f0; padding-left:12px; margin-top:10px">
|
||||
${c.methodChain.map((m, i) => `<div style="font-size:0.7rem; color:#475569; margin-top:4px; font-family:'JetBrains Mono', monospace;"><b>${i+1}</b> ${m}</div>`).join('')}
|
||||
|
||||
36
state_machine_exporter_kotlin/build.gradle
Normal file
36
state_machine_exporter_kotlin/build.gradle
Normal file
@@ -0,0 +1,36 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'click.kamil.springstatemachineexporter'
|
||||
version = '1.0.0'
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(21)
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':state_machine_exporter')
|
||||
|
||||
// Kotlin Compiler Embeddable for PSI/AST parsing
|
||||
implementation 'org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.23'
|
||||
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.9.23'
|
||||
|
||||
compileOnly 'org.projectlombok:lombok:1.18.46'
|
||||
annotationProcessor 'org.projectlombok:lombok:1.18.46'
|
||||
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:6.1.0'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:6.1.0'
|
||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher:6.1.0'
|
||||
testImplementation 'org.assertj:assertj-core:3.27.7'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
package click.kamil.springstatemachineexporter.plugin.kotlin;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.model.CallChain;
|
||||
import click.kamil.springstatemachineexporter.analysis.model.CallEdge;
|
||||
import click.kamil.springstatemachineexporter.analysis.model.EntryPoint;
|
||||
import click.kamil.springstatemachineexporter.analysis.model.TriggerPoint;
|
||||
import click.kamil.springstatemachineexporter.analysis.service.CallGraphEngine;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.CallUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class KotlinCallGraphEngine implements CallGraphEngine {
|
||||
|
||||
private final KotlinSourceContext context;
|
||||
private final Map<String, List<CallEdge>> graph = new HashMap<>();
|
||||
|
||||
public KotlinCallGraphEngine(KotlinSourceContext context) {
|
||||
this.context = context;
|
||||
buildGraph();
|
||||
}
|
||||
|
||||
private void buildGraph() {
|
||||
if (context.getBindingContext() == null) {
|
||||
return;
|
||||
}
|
||||
for (KtFile ktFile : context.getKtFiles()) {
|
||||
ktFile.accept(new KtTreeVisitorVoid() {
|
||||
private String currentClassFqn = null;
|
||||
private String currentFunctionFqn = null;
|
||||
|
||||
@Override
|
||||
public void visitClassOrObject(KtClassOrObject ktClass) {
|
||||
String oldClassFqn = currentClassFqn;
|
||||
currentClassFqn = KotlinResolutionUtils.getClassFqn(ktClass, context.getBindingContext());
|
||||
super.visitClassOrObject(ktClass);
|
||||
currentClassFqn = oldClassFqn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNamedFunction(KtNamedFunction function) {
|
||||
String oldFunctionFqn = currentFunctionFqn;
|
||||
currentFunctionFqn = KotlinResolutionUtils.getFunctionFqn(function, context.getBindingContext());
|
||||
super.visitNamedFunction(function);
|
||||
currentFunctionFqn = oldFunctionFqn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCallExpression(KtCallExpression expression) {
|
||||
if (currentFunctionFqn != null) {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall =
|
||||
CallUtilKt.getResolvedCall(expression, context.getBindingContext());
|
||||
if (resolvedCall != null) {
|
||||
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
|
||||
if (descriptor != null) {
|
||||
String targetFqn = KotlinResolutionUtils.getCallableFqn(descriptor);
|
||||
if (targetFqn != null) {
|
||||
List<String> args = new ArrayList<>();
|
||||
for (ValueArgument valArg : expression.getValueArguments()) {
|
||||
KtExpression argExpr = valArg.getArgumentExpression();
|
||||
if (argExpr != null) {
|
||||
args.add(KotlinResolutionUtils.resolveArgument(argExpr, context.getBindingContext()));
|
||||
}
|
||||
}
|
||||
CallEdge edge = new CallEdge(targetFqn, args, "unknown");
|
||||
graph.computeIfAbsent(currentFunctionFqn, k -> new ArrayList<>()).add(edge);
|
||||
|
||||
// Polymorphic/Inheritance mapping: if target class has subclasses, register implementor edges
|
||||
if (targetFqn.contains(".")) {
|
||||
String className = targetFqn.substring(0, targetFqn.lastIndexOf('.'));
|
||||
String methodName = targetFqn.substring(targetFqn.lastIndexOf('.') + 1);
|
||||
List<String> implementations = context.getImplementations().get(className);
|
||||
if (implementations != null) {
|
||||
for (String impl : implementations) {
|
||||
CallEdge implEdge = new CallEdge(impl + "." + methodName, args, "unknown");
|
||||
graph.computeIfAbsent(currentFunctionFqn, k -> new ArrayList<>()).add(implEdge);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
super.visitCallExpression(expression);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<CallEdge>> getCallGraph() {
|
||||
return graph;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CallChain> findChains(List<EntryPoint> entryPoints, List<TriggerPoint> triggers) {
|
||||
List<CallChain> chains = new ArrayList<>();
|
||||
for (EntryPoint ep : entryPoints) {
|
||||
String startMethod = ep.getClassName() + "." + ep.getMethodName();
|
||||
for (TriggerPoint tp : triggers) {
|
||||
String targetMethod = tp.getClassName() + "." + tp.getMethodName();
|
||||
List<List<String>> paths = findAllPaths(startMethod, targetMethod, new LinkedHashSet<>());
|
||||
for (List<String> path : paths) {
|
||||
chains.add(CallChain.builder()
|
||||
.entryPoint(ep)
|
||||
.methodChain(path)
|
||||
.triggerPoint(tp)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
return chains;
|
||||
}
|
||||
|
||||
private List<List<String>> findAllPaths(String start, String target, Set<String> visited) {
|
||||
List<List<String>> result = new ArrayList<>();
|
||||
if (start.equals(target)) {
|
||||
result.add(new ArrayList<>(List.of(start)));
|
||||
return result;
|
||||
}
|
||||
if (!visited.add(start)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
List<CallEdge> neighbors = graph.get(start);
|
||||
if (neighbors != null) {
|
||||
for (CallEdge edge : neighbors) {
|
||||
String neighbor = edge.getTargetMethod();
|
||||
if (neighbor.startsWith("java.") || neighbor.startsWith("javax.") ||
|
||||
neighbor.startsWith("jakarta.") || neighbor.startsWith("org.springframework.")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (neighbor.equals(target) || isHeuristicMatch(neighbor, target)) {
|
||||
List<String> path = new ArrayList<>(List.of(start, target));
|
||||
result.add(path);
|
||||
} else {
|
||||
List<List<String>> subPaths = findAllPaths(neighbor, target, visited);
|
||||
for (List<String> subPath : subPaths) {
|
||||
List<String> path = new ArrayList<>();
|
||||
path.add(start);
|
||||
path.addAll(subPath);
|
||||
result.add(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
visited.remove(start);
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isHeuristicMatch(String neighbor, String target) {
|
||||
if (neighbor == null || target == null) return false;
|
||||
if (neighbor.equals(target)) return true;
|
||||
if (neighbor.contains(".") && target.contains(".")) {
|
||||
String methodNeighbor = neighbor.substring(neighbor.lastIndexOf('.') + 1);
|
||||
String methodTarget = target.substring(target.lastIndexOf('.') + 1);
|
||||
if (methodNeighbor.equals(methodTarget)) {
|
||||
String classNeighbor = neighbor.substring(0, neighbor.lastIndexOf('.'));
|
||||
String classTarget = target.substring(0, target.lastIndexOf('.'));
|
||||
String simpleClassNeighbor = classNeighbor.contains(".") ? classNeighbor.substring(classNeighbor.lastIndexOf('.') + 1) : classNeighbor;
|
||||
String simpleClassTarget = classTarget.contains(".") ? classTarget.substring(classTarget.lastIndexOf('.') + 1) : classTarget;
|
||||
return simpleClassNeighbor.equalsIgnoreCase(simpleClassTarget);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,478 @@
|
||||
package click.kamil.springstatemachineexporter.plugin.kotlin;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.model.CallChain;
|
||||
import click.kamil.springstatemachineexporter.analysis.model.EntryPoint;
|
||||
import click.kamil.springstatemachineexporter.analysis.model.TriggerPoint;
|
||||
import click.kamil.springstatemachineexporter.analysis.service.CodebaseIntelligenceProvider;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.CallUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.kotlin.com.intellij.psi.PsiFile;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class KotlinIntelligenceProvider implements CodebaseIntelligenceProvider {
|
||||
|
||||
private final KotlinSourceContext context;
|
||||
|
||||
public KotlinIntelligenceProvider(KotlinSourceContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TriggerPoint> findTriggerPoints() {
|
||||
List<TriggerPoint> triggers = new ArrayList<>();
|
||||
BindingContext bindingContext = context.getBindingContext();
|
||||
if (bindingContext == null) {
|
||||
return triggers;
|
||||
}
|
||||
for (KtFile ktFile : context.getKtFiles()) {
|
||||
ktFile.accept(new KtTreeVisitorVoid() {
|
||||
private String currentClassFqn = null;
|
||||
private String currentFunctionFqn = null;
|
||||
|
||||
@Override
|
||||
public void visitClassOrObject(KtClassOrObject ktClass) {
|
||||
String oldClassFqn = currentClassFqn;
|
||||
currentClassFqn = KotlinResolutionUtils.getClassFqn(ktClass, bindingContext);
|
||||
super.visitClassOrObject(ktClass);
|
||||
currentClassFqn = oldClassFqn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNamedFunction(KtNamedFunction function) {
|
||||
String oldFunctionFqn = currentFunctionFqn;
|
||||
currentFunctionFqn = KotlinResolutionUtils.getFunctionFqn(function, bindingContext);
|
||||
super.visitNamedFunction(function);
|
||||
currentFunctionFqn = oldFunctionFqn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCallExpression(KtCallExpression expression) {
|
||||
KtExpression callee = expression.getCalleeExpression();
|
||||
if (callee instanceof KtNameReferenceExpression) {
|
||||
String name = ((KtNameReferenceExpression) callee).getReferencedName();
|
||||
if ("sendEvent".equals(name) || "sendEventReactively".equals(name) ||
|
||||
"sendEvents".equals(name) || "sendEventCollect".equals(name) ||
|
||||
"sendEventMono".equals(name)) {
|
||||
|
||||
String eventName = "UNKNOWN_EVENT";
|
||||
if (!expression.getValueArguments().isEmpty()) {
|
||||
KtExpression arg = expression.getValueArguments().get(0).getArgumentExpression();
|
||||
if (arg != null) {
|
||||
eventName = KotlinResolutionUtils.resolveArgument(arg, bindingContext);
|
||||
}
|
||||
}
|
||||
|
||||
KtExpression receiver = null;
|
||||
if (expression.getParent() instanceof KtDotQualifiedExpression dotExpr) {
|
||||
if (dotExpr.getSelectorExpression() == expression) {
|
||||
receiver = dotExpr.getReceiverExpression();
|
||||
}
|
||||
}
|
||||
|
||||
String stateType = null;
|
||||
String eventType = null;
|
||||
if (receiver != null) {
|
||||
org.jetbrains.kotlin.types.KotlinType receiverType = bindingContext.getType(receiver);
|
||||
if (receiverType != null && receiverType.getArguments().size() >= 2) {
|
||||
stateType = receiverType.getArguments().get(0).getType().toString();
|
||||
eventType = receiverType.getArguments().get(1).getType().toString();
|
||||
}
|
||||
}
|
||||
|
||||
if (stateType == null || eventType == null) {
|
||||
ResolvedCall<? extends org.jetbrains.kotlin.descriptors.CallableDescriptor> resolvedCall =
|
||||
CallUtilKt.getResolvedCall(expression, bindingContext);
|
||||
if (resolvedCall != null) {
|
||||
org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue dispatchReceiver = resolvedCall.getDispatchReceiver();
|
||||
if (dispatchReceiver != null) {
|
||||
org.jetbrains.kotlin.types.KotlinType receiverType = dispatchReceiver.getType();
|
||||
if (receiverType != null && receiverType.getArguments().size() >= 2) {
|
||||
stateType = receiverType.getArguments().get(0).getType().toString();
|
||||
eventType = receiverType.getArguments().get(1).getType().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean external = false;
|
||||
if (receiver instanceof KtNameReferenceExpression refExpr) {
|
||||
org.jetbrains.kotlin.descriptors.DeclarationDescriptor descriptor =
|
||||
bindingContext.get(BindingContext.REFERENCE_TARGET, refExpr);
|
||||
if (descriptor instanceof org.jetbrains.kotlin.descriptors.ValueParameterDescriptor) {
|
||||
external = true;
|
||||
}
|
||||
}
|
||||
|
||||
triggers.add(TriggerPoint.builder()
|
||||
.event(eventName)
|
||||
.sourceState(extractSourceState(expression))
|
||||
.className(currentClassFqn)
|
||||
.methodName(currentFunctionFqn != null && currentFunctionFqn.contains(".")
|
||||
? currentFunctionFqn.substring(currentFunctionFqn.lastIndexOf('.') + 1)
|
||||
: currentFunctionFqn)
|
||||
.sourceFile(getRelativePathForElement(expression, context))
|
||||
.lineNumber(getLineNumber(expression))
|
||||
.stateTypeFqn(stateType)
|
||||
.eventTypeFqn(eventType)
|
||||
.external(external)
|
||||
.constraint(findConditionConstraint(expression))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
super.visitCallExpression(expression);
|
||||
}
|
||||
});
|
||||
}
|
||||
return triggers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EntryPoint> findEntryPoints() {
|
||||
List<EntryPoint> entryPoints = new ArrayList<>();
|
||||
BindingContext bindingContext = context.getBindingContext();
|
||||
if (bindingContext == null) {
|
||||
return entryPoints;
|
||||
}
|
||||
for (KtFile ktFile : context.getKtFiles()) {
|
||||
ktFile.accept(new KtTreeVisitorVoid() {
|
||||
private String currentClassFqn = null;
|
||||
private String controllerBasePath = "";
|
||||
|
||||
@Override
|
||||
public void visitClassOrObject(KtClassOrObject ktClass) {
|
||||
String oldClassFqn = currentClassFqn;
|
||||
String oldBasePath = controllerBasePath;
|
||||
|
||||
currentClassFqn = KotlinResolutionUtils.getClassFqn(ktClass, bindingContext);
|
||||
controllerBasePath = getControllerPath(ktClass, bindingContext);
|
||||
|
||||
super.visitClassOrObject(ktClass);
|
||||
|
||||
currentClassFqn = oldClassFqn;
|
||||
controllerBasePath = oldBasePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNamedFunction(KtNamedFunction function) {
|
||||
super.visitNamedFunction(function);
|
||||
if (currentClassFqn == null || function.getName() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
RestMapping rest = getRestMapping(function, controllerBasePath, bindingContext);
|
||||
if (rest != null) {
|
||||
entryPoints.add(EntryPoint.builder()
|
||||
.type(EntryPoint.Type.REST)
|
||||
.name(rest.verb + " " + rest.path)
|
||||
.className(currentClassFqn)
|
||||
.methodName(function.getName())
|
||||
.sourceFile(getRelativePathForElement(function, context))
|
||||
.metadata(Map.of("path", rest.path, "verb", rest.verb))
|
||||
.parameters(extractParameters(function, bindingContext))
|
||||
.build());
|
||||
}
|
||||
|
||||
MessageMapping msg = getMessageMapping(function, bindingContext);
|
||||
if (msg != null) {
|
||||
entryPoints.add(EntryPoint.builder()
|
||||
.type(msg.type)
|
||||
.name(msg.protocol + ": " + msg.destination)
|
||||
.className(currentClassFqn)
|
||||
.methodName(function.getName())
|
||||
.sourceFile(getRelativePathForElement(function, context))
|
||||
.metadata(Map.of("destination", msg.destination, "protocol", msg.protocol))
|
||||
.parameters(extractParameters(function, bindingContext))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return entryPoints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CallChain> findCallChains(List<EntryPoint> entryPoints, List<TriggerPoint> triggers) {
|
||||
KotlinCallGraphEngine callGraphEngine = new KotlinCallGraphEngine(context);
|
||||
return callGraphEngine.findChains(entryPoints, triggers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, String>> resolveProperties() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
private static String getAnnotationValue(KtAnnotationEntry annotation, String name, BindingContext bindingContext) {
|
||||
for (ValueArgument arg : annotation.getValueArguments()) {
|
||||
if (arg instanceof KtValueArgument valueArg) {
|
||||
if (valueArg.getArgumentName() != null && valueArg.getArgumentName().getAsName() != null) {
|
||||
String argName = valueArg.getArgumentName().getAsName().asString();
|
||||
if (name.equals(argName)) {
|
||||
return resolveAnnotationValueExpr(valueArg.getArgumentExpression(), bindingContext);
|
||||
}
|
||||
} else if ("value".equals(name)) {
|
||||
return resolveAnnotationValueExpr(valueArg.getArgumentExpression(), bindingContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String resolveAnnotationValueExpr(KtExpression expr, BindingContext bindingContext) {
|
||||
if (expr == null) return null;
|
||||
if (expr instanceof KtCollectionLiteralExpression colExpr) {
|
||||
if (!colExpr.getInnerExpressions().isEmpty()) {
|
||||
return KotlinResolutionUtils.resolveArgument(colExpr.getInnerExpressions().get(0), bindingContext);
|
||||
}
|
||||
}
|
||||
return KotlinResolutionUtils.resolveArgument(expr, bindingContext);
|
||||
}
|
||||
|
||||
private static String getControllerPath(KtClassOrObject controller, BindingContext bindingContext) {
|
||||
for (KtAnnotationEntry ann : controller.getAnnotationEntries()) {
|
||||
String name = ann.getShortName() != null ? ann.getShortName().asString() : "";
|
||||
if (name.equals("RequestMapping") || name.equals("Path")) {
|
||||
String path = getAnnotationValue(ann, "value", bindingContext);
|
||||
if (path == null) path = getAnnotationValue(ann, "path", bindingContext);
|
||||
if (path != null) return path;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static class RestMapping {
|
||||
String verb;
|
||||
String path;
|
||||
RestMapping(String verb, String path) {
|
||||
this.verb = verb;
|
||||
this.path = path;
|
||||
}
|
||||
}
|
||||
|
||||
private static RestMapping getRestMapping(KtNamedFunction function, String basePath, BindingContext bindingContext) {
|
||||
for (KtAnnotationEntry ann : function.getAnnotationEntries()) {
|
||||
String name = ann.getShortName() != null ? ann.getShortName().asString() : "";
|
||||
String verb = null;
|
||||
if (name.equals("GetMapping") || name.equals("GET")) verb = "GET";
|
||||
else if (name.equals("PostMapping") || name.equals("POST")) verb = "POST";
|
||||
else if (name.equals("PutMapping") || name.equals("PUT")) verb = "PUT";
|
||||
else if (name.equals("DeleteMapping") || name.equals("DELETE")) verb = "DELETE";
|
||||
else if (name.equals("PatchMapping") || name.equals("PATCH")) verb = "PATCH";
|
||||
else if (name.equals("RequestMapping")) {
|
||||
verb = getAnnotationValue(ann, "method", bindingContext);
|
||||
if (verb == null) verb = "GET";
|
||||
}
|
||||
|
||||
if (verb != null) {
|
||||
String subPath = getAnnotationValue(ann, "value", bindingContext);
|
||||
if (subPath == null) subPath = getAnnotationValue(ann, "path", bindingContext);
|
||||
if (subPath == null) subPath = "";
|
||||
|
||||
String path = combinePaths(basePath, subPath);
|
||||
return new RestMapping(verb, path);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String combinePaths(String base, String sub) {
|
||||
if (base == null) base = "";
|
||||
if (sub == null) sub = "";
|
||||
if (!base.startsWith("/")) base = "/" + base;
|
||||
if (base.endsWith("/")) base = base.substring(0, base.length() - 1);
|
||||
if (!sub.startsWith("/") && !sub.isEmpty()) sub = "/" + sub;
|
||||
return base + sub;
|
||||
}
|
||||
|
||||
private static class MessageMapping {
|
||||
EntryPoint.Type type;
|
||||
String destination;
|
||||
String protocol;
|
||||
MessageMapping(EntryPoint.Type type, String destination, String protocol) {
|
||||
this.type = type;
|
||||
this.destination = destination;
|
||||
this.protocol = protocol;
|
||||
}
|
||||
}
|
||||
|
||||
private static MessageMapping getMessageMapping(KtNamedFunction function, BindingContext bindingContext) {
|
||||
for (KtAnnotationEntry ann : function.getAnnotationEntries()) {
|
||||
String name = ann.getShortName() != null ? ann.getShortName().asString() : "";
|
||||
if (name.equals("KafkaListener")) {
|
||||
String topics = getAnnotationValue(ann, "topics", bindingContext);
|
||||
if (topics == null) topics = getAnnotationValue(ann, "value", bindingContext);
|
||||
if (topics == null) topics = "unknown";
|
||||
return new MessageMapping(EntryPoint.Type.KAFKA, topics, "KAFKA");
|
||||
} else if (name.equals("RabbitListener")) {
|
||||
String queues = getAnnotationValue(ann, "queues", bindingContext);
|
||||
if (queues == null) queues = getAnnotationValue(ann, "value", bindingContext);
|
||||
if (queues == null) queues = "unknown";
|
||||
return new MessageMapping(EntryPoint.Type.RABBIT, queues, "RABBIT");
|
||||
} else if (name.equals("JmsListener")) {
|
||||
String dest = getAnnotationValue(ann, "destination", bindingContext);
|
||||
if (dest == null) dest = getAnnotationValue(ann, "value", bindingContext);
|
||||
if (dest == null) dest = "unknown";
|
||||
return new MessageMapping(EntryPoint.Type.JMS, dest, "JMS");
|
||||
} else if (name.equals("SqsListener")) {
|
||||
String dest = getAnnotationValue(ann, "value", bindingContext);
|
||||
if (dest == null) dest = getAnnotationValue(ann, "queueNames", bindingContext);
|
||||
if (dest == null) dest = "unknown";
|
||||
return new MessageMapping(EntryPoint.Type.SQS, dest, "SQS");
|
||||
} else if (name.equals("SnsListener")) {
|
||||
String dest = getAnnotationValue(ann, "value", bindingContext);
|
||||
if (dest == null) dest = getAnnotationValue(ann, "topicNames", bindingContext);
|
||||
if (dest == null) dest = "unknown";
|
||||
return new MessageMapping(EntryPoint.Type.SNS, dest, "SNS");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static List<EntryPoint.Parameter> extractParameters(KtNamedFunction function, BindingContext bindingContext) {
|
||||
List<EntryPoint.Parameter> params = new ArrayList<>();
|
||||
for (KtParameter param : function.getValueParameters()) {
|
||||
String name = param.getName();
|
||||
String typeStr = "unknown";
|
||||
org.jetbrains.kotlin.types.KotlinType type = bindingContext.get(BindingContext.TYPE, param.getTypeReference());
|
||||
if (type != null) {
|
||||
typeStr = type.toString();
|
||||
} else if (param.getTypeReference() != null) {
|
||||
typeStr = param.getTypeReference().getText();
|
||||
}
|
||||
|
||||
List<String> annotations = new ArrayList<>();
|
||||
for (KtAnnotationEntry ann : param.getAnnotationEntries()) {
|
||||
if (ann.getShortName() != null) {
|
||||
annotations.add(ann.getShortName().asString());
|
||||
}
|
||||
}
|
||||
|
||||
params.add(EntryPoint.Parameter.builder()
|
||||
.name(name)
|
||||
.type(typeStr)
|
||||
.annotations(annotations)
|
||||
.build());
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
private static String getRelativePathForElement(PsiElement element, KotlinSourceContext context) {
|
||||
if (element == null) return null;
|
||||
PsiFile file = element.getContainingFile();
|
||||
if (file instanceof KtFile ktFile) {
|
||||
if (ktFile.getVirtualFile() != null) {
|
||||
String pathStr = ktFile.getVirtualFile().getPath();
|
||||
if (pathStr != null) {
|
||||
return context.getRelativePath(java.nio.file.Path.of(pathStr));
|
||||
}
|
||||
}
|
||||
return ktFile.getName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int getLineNumber(PsiElement element) {
|
||||
if (element == null) return 0;
|
||||
String text = element.getContainingFile().getText();
|
||||
int offset = element.getTextRange().getStartOffset();
|
||||
int line = 1;
|
||||
for (int i = 0; i < offset && i < text.length(); i++) {
|
||||
if (text.charAt(i) == '\n') {
|
||||
line++;
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
private static String extractSourceState(PsiElement element) {
|
||||
PsiElement current = element;
|
||||
while (current != null && !(current instanceof KtNamedFunction)) {
|
||||
PsiElement parent = current.getParent();
|
||||
|
||||
if (parent instanceof KtIfExpression ifExpr) {
|
||||
if (ifExpr.getCondition() != current) {
|
||||
String state = extractStateFromExpression(ifExpr.getCondition());
|
||||
if (state != null) return state;
|
||||
}
|
||||
}
|
||||
|
||||
if (parent instanceof KtWhenEntry whenEntry) {
|
||||
if (whenEntry.getConditions().length > 0) {
|
||||
KtWhenCondition cond = whenEntry.getConditions()[0];
|
||||
if (cond instanceof KtWhenConditionWithExpression condExpr) {
|
||||
String state = getSimpleNameString(condExpr.getExpression());
|
||||
if (state != null) return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current = parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String extractStateFromExpression(KtExpression expr) {
|
||||
if (expr instanceof KtBinaryExpression binaryExpr) {
|
||||
String op = binaryExpr.getOperationReference().getReferencedName();
|
||||
if ("==".equals(op) || "!=".equals(op)) {
|
||||
KtExpression left = binaryExpr.getLeft();
|
||||
KtExpression right = binaryExpr.getRight();
|
||||
if (left != null && right != null) {
|
||||
if (left instanceof org.jetbrains.kotlin.psi.KtConstantExpression ||
|
||||
left instanceof KtStringTemplateExpression ||
|
||||
left instanceof KtNameReferenceExpression ||
|
||||
left instanceof KtDotQualifiedExpression) {
|
||||
return getSimpleNameString(left);
|
||||
}
|
||||
if (right instanceof org.jetbrains.kotlin.psi.KtConstantExpression ||
|
||||
right instanceof KtStringTemplateExpression ||
|
||||
right instanceof KtNameReferenceExpression ||
|
||||
right instanceof KtDotQualifiedExpression) {
|
||||
return getSimpleNameString(right);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getSimpleNameString(KtExpression expr) {
|
||||
if (expr instanceof KtNameReferenceExpression refExpr) {
|
||||
return refExpr.getReferencedName();
|
||||
}
|
||||
if (expr instanceof KtDotQualifiedExpression dotExpr) {
|
||||
KtExpression selector = dotExpr.getSelectorExpression();
|
||||
if (selector instanceof KtNameReferenceExpression selectorRef) {
|
||||
return selectorRef.getReferencedName();
|
||||
}
|
||||
return dotExpr.getText();
|
||||
}
|
||||
if (expr instanceof KtStringTemplateExpression stringTemplate) {
|
||||
return stringTemplate.getText().replace("\"", "");
|
||||
}
|
||||
return expr.getText();
|
||||
}
|
||||
|
||||
private static String findConditionConstraint(PsiElement element) {
|
||||
PsiElement current = element;
|
||||
while (current != null && !(current instanceof KtNamedFunction)) {
|
||||
PsiElement parent = current.getParent();
|
||||
if (parent instanceof KtIfExpression ifExpr) {
|
||||
if (ifExpr.getCondition() != current) {
|
||||
KtExpression cond = ifExpr.getCondition();
|
||||
if (cond != null) {
|
||||
String condText = cond.getText();
|
||||
if (!condText.contains("state") && !condText.contains("State")) {
|
||||
return condText;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
current = parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package click.kamil.springstatemachineexporter.plugin.kotlin;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.model.AnalysisResult;
|
||||
import click.kamil.springstatemachineexporter.analysis.service.CallGraphEngine;
|
||||
import click.kamil.springstatemachineexporter.analysis.service.CodebaseIntelligenceProvider;
|
||||
import click.kamil.springstatemachineexporter.spi.LanguageAnalyzerPlugin;
|
||||
import click.kamil.springstatemachineexporter.spi.SourceContext;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class KotlinLanguageAnalyzerPlugin implements LanguageAnalyzerPlugin {
|
||||
|
||||
@Override
|
||||
public boolean supports(Path projectRoot) {
|
||||
if (projectRoot == null) return false;
|
||||
try (Stream<Path> walk = Files.walk(projectRoot, 5)) { // Check top 5 levels
|
||||
return walk.anyMatch(p -> p.toString().endsWith(".kt"));
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceContext parseProject(Path projectRoot, List<String> classpath, Set<Path> sourcePaths) {
|
||||
KotlinSourceContext context = new KotlinSourceContext(projectRoot, classpath);
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallGraphEngine createCallGraphEngine(SourceContext context) {
|
||||
if (context instanceof KotlinSourceContext ktContext) {
|
||||
return new KotlinCallGraphEngine(ktContext);
|
||||
}
|
||||
throw new IllegalArgumentException("Expected KotlinSourceContext");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodebaseIntelligenceProvider createIntelligenceProvider(SourceContext context) {
|
||||
if (context instanceof KotlinSourceContext ktContext) {
|
||||
return new KotlinIntelligenceProvider(ktContext);
|
||||
}
|
||||
throw new IllegalArgumentException("Expected KotlinSourceContext");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AnalysisResult> extractStateMachines(SourceContext context, boolean renderChoicesAsDiamonds) {
|
||||
if (context instanceof KotlinSourceContext ktContext) {
|
||||
return KotlinStateMachineExtractor.extract(ktContext, renderChoicesAsDiamonds);
|
||||
}
|
||||
throw new IllegalArgumentException("Expected KotlinSourceContext");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package click.kamil.springstatemachineexporter.plugin.kotlin;
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.psi.KtStringTemplateExpression;
|
||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression;
|
||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.CallUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.psi.KtProperty;
|
||||
import org.jetbrains.kotlin.com.intellij.psi.PsiElement;
|
||||
|
||||
public class KotlinResolutionUtils {
|
||||
|
||||
public static String getClassFqn(KtClassOrObject ktClass, BindingContext bindingContext) {
|
||||
if (bindingContext != null) {
|
||||
ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, ktClass);
|
||||
if (descriptor != null) {
|
||||
return DescriptorUtils.getFqNameSafe(descriptor).asString();
|
||||
}
|
||||
}
|
||||
return ktClass.getFqName() != null ? ktClass.getFqName().asString() : ktClass.getName();
|
||||
}
|
||||
|
||||
public static String getFunctionFqn(KtNamedFunction function, BindingContext bindingContext) {
|
||||
if (bindingContext != null) {
|
||||
FunctionDescriptor descriptor = bindingContext.get(BindingContext.FUNCTION, function);
|
||||
if (descriptor != null) {
|
||||
return getCallableFqn(descriptor);
|
||||
}
|
||||
}
|
||||
return function.getName();
|
||||
}
|
||||
|
||||
public static String getCallableFqn(CallableDescriptor descriptor) {
|
||||
if (descriptor == null) return null;
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
if (containingDeclaration instanceof ClassDescriptor classDescriptor) {
|
||||
return DescriptorUtils.getFqNameSafe(classDescriptor).asString() + "." + descriptor.getName().asString();
|
||||
}
|
||||
return DescriptorUtils.getFqNameSafe(descriptor).asString();
|
||||
}
|
||||
|
||||
public static String resolveArgument(KtExpression expr, BindingContext bindingContext) {
|
||||
if (expr == null) return "null";
|
||||
|
||||
if (expr instanceof KtStringTemplateExpression stringTemplate) {
|
||||
return stringTemplate.getText().replace("\"", "");
|
||||
}
|
||||
|
||||
if (expr instanceof KtNameReferenceExpression refExpr) {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt.getResolvedCall(refExpr, bindingContext);
|
||||
if (resolvedCall != null) {
|
||||
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
|
||||
if (descriptor != null) {
|
||||
// 1. Try compile-time constant value
|
||||
if (descriptor instanceof org.jetbrains.kotlin.descriptors.VariableDescriptor varDescriptor) {
|
||||
org.jetbrains.kotlin.resolve.constants.ConstantValue<?> initializer = varDescriptor.getCompileTimeInitializer();
|
||||
if (initializer != null) {
|
||||
Object val = initializer.getValue();
|
||||
if (val != null) return val.toString();
|
||||
}
|
||||
}
|
||||
// 2. Try property initializer expression
|
||||
PsiElement decl =
|
||||
org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
|
||||
if (decl instanceof KtProperty property) {
|
||||
KtExpression initializer = property.getInitializer();
|
||||
if (initializer != null) {
|
||||
return resolveArgument(initializer, bindingContext);
|
||||
}
|
||||
}
|
||||
// Fallback to FQN
|
||||
return DescriptorUtils.getFqNameSafe(descriptor).asString();
|
||||
}
|
||||
}
|
||||
return refExpr.getReferencedName();
|
||||
}
|
||||
|
||||
if (expr instanceof KtDotQualifiedExpression dotExpr) {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt.getResolvedCall(dotExpr, bindingContext);
|
||||
if (resolvedCall != null) {
|
||||
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
|
||||
if (descriptor != null) {
|
||||
// 1. Try compile-time constant value
|
||||
if (descriptor instanceof org.jetbrains.kotlin.descriptors.VariableDescriptor varDescriptor) {
|
||||
org.jetbrains.kotlin.resolve.constants.ConstantValue<?> initializer = varDescriptor.getCompileTimeInitializer();
|
||||
if (initializer != null) {
|
||||
Object val = initializer.getValue();
|
||||
if (val != null) return val.toString();
|
||||
}
|
||||
}
|
||||
// 2. Try property initializer expression
|
||||
PsiElement decl =
|
||||
org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
|
||||
if (decl instanceof KtProperty property) {
|
||||
KtExpression initializer = property.getInitializer();
|
||||
if (initializer != null) {
|
||||
return resolveArgument(initializer, bindingContext);
|
||||
}
|
||||
}
|
||||
// Fallback to FQN
|
||||
return DescriptorUtils.getFqNameSafe(descriptor).asString();
|
||||
}
|
||||
}
|
||||
return dotExpr.getText();
|
||||
}
|
||||
|
||||
return expr.getText();
|
||||
}
|
||||
|
||||
public static java.util.List<String> resolveArgumentsList(KtExpression expr, BindingContext bindingContext) {
|
||||
if (expr instanceof org.jetbrains.kotlin.psi.KtCallExpression callExpr) {
|
||||
KtExpression callee = callExpr.getCalleeExpression();
|
||||
if (callee != null) {
|
||||
String name = callee.getText();
|
||||
if (name.equals("setOf") || name.equals("listOf") || name.equals("arrayListOf") ||
|
||||
name.equals("mutableSetOf") || name.equals("mutableListOf") || name.equals("hashSetOf") ||
|
||||
name.equals("enumSetOf")) {
|
||||
java.util.List<String> result = new java.util.ArrayList<>();
|
||||
for (org.jetbrains.kotlin.psi.ValueArgument arg : callExpr.getValueArguments()) {
|
||||
KtExpression innerExpr = arg.getArgumentExpression();
|
||||
if (innerExpr != null) {
|
||||
result.add(resolveArgument(innerExpr, bindingContext));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return java.util.Collections.singletonList(resolveArgument(expr, bindingContext));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
package click.kamil.springstatemachineexporter.plugin.kotlin;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.model.LibraryHint;
|
||||
import click.kamil.springstatemachineexporter.spi.SourceContext;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliBindingTrace;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult;
|
||||
import org.jetbrains.kotlin.com.intellij.openapi.Disposable;
|
||||
import org.jetbrains.kotlin.com.intellij.openapi.util.Disposer;
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys;
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmContentRootsKt;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory;
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
||||
import org.jetbrains.kotlin.psi.KtSuperTypeListEntry;
|
||||
import org.jetbrains.kotlin.psi.KtTypeReference;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class KotlinSourceContext implements SourceContext {
|
||||
private final Path projectRoot;
|
||||
private final Map<String, Object> cache = new HashMap<>();
|
||||
private final List<KtFile> ktFiles = new ArrayList<>();
|
||||
private KotlinCoreEnvironment environment;
|
||||
private BindingContext bindingContext;
|
||||
|
||||
private final Map<String, List<String>> implementations = new HashMap<>();
|
||||
private final Map<String, String> superclasses = new HashMap<>();
|
||||
|
||||
public KotlinSourceContext(Path projectRoot, List<String> classpath) {
|
||||
this.projectRoot = projectRoot;
|
||||
initEnvironment(classpath);
|
||||
parseFiles();
|
||||
analyze();
|
||||
}
|
||||
|
||||
private void initEnvironment(List<String> classpath) {
|
||||
Disposable disposable = Disposer.newDisposable();
|
||||
CompilerConfiguration configuration = new CompilerConfiguration();
|
||||
|
||||
configuration.put(CommonConfigurationKeys.MODULE_NAME, "spring-state-machine-exporter");
|
||||
configuration.put(org.jetbrains.kotlin.cli.common.CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY,
|
||||
org.jetbrains.kotlin.cli.common.messages.MessageCollector.Companion.getNONE());
|
||||
|
||||
if (classpath != null) {
|
||||
for (String cp : classpath) {
|
||||
JvmContentRootsKt.addJvmClasspathRoot(configuration, new File(cp));
|
||||
}
|
||||
}
|
||||
|
||||
// Include the kotlin-stdlib and kotlin-reflect dependencies explicitly
|
||||
File stdlib = getJarForClass(kotlin.Unit.class);
|
||||
if (stdlib != null && stdlib.exists()) {
|
||||
JvmContentRootsKt.addJvmClasspathRoot(configuration, stdlib);
|
||||
}
|
||||
File reflect = getJarForClass(kotlin.reflect.KClass.class);
|
||||
if (reflect != null && reflect.exists()) {
|
||||
JvmContentRootsKt.addJvmClasspathRoot(configuration, reflect);
|
||||
}
|
||||
|
||||
environment = KotlinCoreEnvironment.createForProduction(
|
||||
disposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES);
|
||||
}
|
||||
|
||||
private static File getJarForClass(Class<?> clazz) {
|
||||
try {
|
||||
String path = clazz.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
|
||||
return new File(path);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void parseFiles() {
|
||||
if (projectRoot == null || !Files.exists(projectRoot)) return;
|
||||
|
||||
KtPsiFactory psiFactory = new KtPsiFactory(environment.getProject());
|
||||
|
||||
try (Stream<Path> walk = Files.walk(projectRoot)) {
|
||||
List<Path> ktPaths = walk
|
||||
.filter(Files::isRegularFile)
|
||||
.filter(p -> p.toString().endsWith(".kt"))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (Path p : ktPaths) {
|
||||
try {
|
||||
String content = Files.readString(p);
|
||||
KtFile ktFile = psiFactory.createFile(p.getFileName().toString(), content);
|
||||
ktFiles.add(ktFile);
|
||||
} catch (IOException e) {
|
||||
System.err.println("Failed to read " + p);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.err.println("Failed to walk project root " + projectRoot);
|
||||
}
|
||||
}
|
||||
|
||||
private void analyze() {
|
||||
if (ktFiles.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
CliBindingTrace trace = new CliBindingTrace();
|
||||
AnalysisResult result = TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||
environment.getProject(),
|
||||
ktFiles,
|
||||
trace,
|
||||
environment.getConfiguration(),
|
||||
(scope) -> environment.createPackagePartProvider(scope)
|
||||
);
|
||||
this.bindingContext = result.getBindingContext();
|
||||
buildSupertypesMap();
|
||||
}
|
||||
|
||||
private void buildSupertypesMap() {
|
||||
if (bindingContext == null) return;
|
||||
for (KtFile ktFile : ktFiles) {
|
||||
ktFile.accept(new org.jetbrains.kotlin.psi.KtTreeVisitorVoid() {
|
||||
@Override
|
||||
public void visitClassOrObject(KtClassOrObject ktClass) {
|
||||
super.visitClassOrObject(ktClass);
|
||||
String classFqn = KotlinResolutionUtils.getClassFqn(ktClass, bindingContext);
|
||||
if (classFqn == null) return;
|
||||
|
||||
for (KtSuperTypeListEntry entry : ktClass.getSuperTypeListEntries()) {
|
||||
KtTypeReference typeRef = entry.getTypeReference();
|
||||
if (typeRef != null) {
|
||||
KotlinType kotlinType = bindingContext.get(BindingContext.TYPE, typeRef);
|
||||
if (kotlinType != null) {
|
||||
ClassifierDescriptor classifier = kotlinType.getConstructor().getDeclarationDescriptor();
|
||||
if (classifier != null) {
|
||||
String superFqn = DescriptorUtils.getFqNameSafe(classifier).asString();
|
||||
superclasses.put(classFqn, superFqn);
|
||||
implementations.computeIfAbsent(superFqn, k -> new ArrayList<>()).add(classFqn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public List<KtFile> getKtFiles() {
|
||||
return ktFiles;
|
||||
}
|
||||
|
||||
public KotlinCoreEnvironment getEnvironment() {
|
||||
return environment;
|
||||
}
|
||||
|
||||
public BindingContext getBindingContext() {
|
||||
return bindingContext;
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getImplementations() {
|
||||
return implementations;
|
||||
}
|
||||
|
||||
public Map<String, String> getSuperclasses() {
|
||||
return superclasses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getProjectRoot() {
|
||||
return projectRoot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRelativePath(Path fullPath) {
|
||||
if (projectRoot != null && fullPath.isAbsolute() && fullPath.startsWith(projectRoot)) {
|
||||
return projectRoot.relativize(fullPath).toString();
|
||||
}
|
||||
return fullPath.getFileName().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRelativePath(String fqn) {
|
||||
return fqn; // Simplified
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LibraryHint> getLibraryHints() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, String>> getProperties() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getCache() {
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,583 @@
|
||||
package click.kamil.springstatemachineexporter.plugin.kotlin;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.model.AnalysisResult;
|
||||
import click.kamil.springstatemachineexporter.model.Transition;
|
||||
import click.kamil.springstatemachineexporter.model.State;
|
||||
import click.kamil.springstatemachineexporter.model.Event;
|
||||
import click.kamil.springstatemachineexporter.model.TransitionType;
|
||||
import click.kamil.springstatemachineexporter.model.Action;
|
||||
import click.kamil.springstatemachineexporter.model.Guard;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.CallUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class KotlinStateMachineExtractor {
|
||||
|
||||
public static List<AnalysisResult> extract(KotlinSourceContext context, boolean renderChoicesAsDiamonds) {
|
||||
List<AnalysisResult> results = new ArrayList<>();
|
||||
BindingContext bindingContext = context.getBindingContext();
|
||||
if (bindingContext == null) return results;
|
||||
|
||||
for (KtFile ktFile : context.getKtFiles()) {
|
||||
ktFile.accept(new KtTreeVisitorVoid() {
|
||||
@Override
|
||||
public void visitClassOrObject(KtClassOrObject ktClass) {
|
||||
super.visitClassOrObject(ktClass);
|
||||
|
||||
boolean isConfig = false;
|
||||
for (KtAnnotationEntry annotation : ktClass.getAnnotationEntries()) {
|
||||
String name = annotation.getShortName() != null ? annotation.getShortName().asString() : "";
|
||||
if ("EnableStateMachine".equals(name) || "EnableStateMachineFactory".equals(name)) {
|
||||
isConfig = true;
|
||||
}
|
||||
}
|
||||
for (KtSuperTypeListEntry entry : ktClass.getSuperTypeListEntries()) {
|
||||
String text = entry.getText();
|
||||
if (text.contains("StateMachineConfigurerAdapter") || text.contains("EnumStateMachineConfigurerAdapter")) {
|
||||
isConfig = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isConfig) {
|
||||
String classFqn = KotlinResolutionUtils.getClassFqn(ktClass, bindingContext);
|
||||
|
||||
Set<State> states = new LinkedHashSet<>();
|
||||
List<Transition> transitions = new ArrayList<>();
|
||||
Set<String> startStates = new LinkedHashSet<>();
|
||||
Set<String> endStates = new LinkedHashSet<>();
|
||||
|
||||
for (KtDeclaration decl : ktClass.getDeclarations()) {
|
||||
if (decl instanceof KtNamedFunction function) {
|
||||
String funcName = function.getName();
|
||||
if ("configure".equals(funcName)) {
|
||||
parseConfigureFunction(function, context, states, transitions, startStates, endStates);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!states.isEmpty() || !transitions.isEmpty()) {
|
||||
if (startStates.isEmpty() && !states.isEmpty()) {
|
||||
for (State s : states) {
|
||||
// With the new State record, rawName is the first field
|
||||
startStates.add(s.rawName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
results.add(AnalysisResult.builder()
|
||||
.name(classFqn)
|
||||
.states(states)
|
||||
.transitions(transitions)
|
||||
.startStates(startStates)
|
||||
.endStates(endStates)
|
||||
.renderChoicesAsDiamonds(renderChoicesAsDiamonds)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static void parseConfigureFunction(KtNamedFunction function, KotlinSourceContext context,
|
||||
Set<State> states, List<Transition> transitions,
|
||||
Set<String> startStates, Set<String> endStates) {
|
||||
BindingContext bindingContext = context.getBindingContext();
|
||||
Map<String, KtExpression> varMap = new HashMap<>();
|
||||
function.accept(new KtTreeVisitorVoid() {
|
||||
@Override
|
||||
public void visitProperty(KtProperty property) {
|
||||
super.visitProperty(property);
|
||||
if (property.getName() != null && property.getInitializer() != null) {
|
||||
varMap.put(property.getName(), property.getInitializer());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function.accept(new KtTreeVisitorVoid() {
|
||||
@Override
|
||||
public void visitDotQualifiedExpression(KtDotQualifiedExpression expression) {
|
||||
super.visitDotQualifiedExpression(expression);
|
||||
if (!(expression.getParent() instanceof KtDotQualifiedExpression)) {
|
||||
checkExpression(expression);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCallExpression(KtCallExpression expression) {
|
||||
super.visitCallExpression(expression);
|
||||
if (!(expression.getParent() instanceof KtDotQualifiedExpression)) {
|
||||
checkExpression(expression);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkExpression(KtExpression expression) {
|
||||
String text = expression.getText();
|
||||
if (text.contains("initial") || text.contains("state") || text.contains("states")) {
|
||||
parseStateCalls(expression, bindingContext, states, startStates);
|
||||
}
|
||||
|
||||
if (text.contains("withExternal") || text.contains("withInternal") || text.contains("withLocal") ||
|
||||
text.contains("withChoice") || text.contains("withJunction") ||
|
||||
text.contains("withFork") || text.contains("withJoin") ||
|
||||
text.contains("source") || text.contains("sources") ||
|
||||
text.contains("target") || text.contains("targets") ||
|
||||
text.contains("event") || text.contains("timer") ||
|
||||
text.contains("first") || text.contains("then") || text.contains("last")) {
|
||||
parseTransitionChain(expression, context, transitions, varMap);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void parseStateCalls(KtExpression expression, BindingContext bindingContext,
|
||||
Set<State> states, Set<String> startStates) {
|
||||
KtExpression current = expression;
|
||||
while (current instanceof KtDotQualifiedExpression dotExpr) {
|
||||
if (dotExpr.getSelectorExpression() instanceof KtCallExpression call) {
|
||||
String name = getCallName(call);
|
||||
if ("initial".equals(name)) {
|
||||
String stateVal = getFirstArgAsString(call, bindingContext);
|
||||
if (stateVal != null) {
|
||||
states.add(new State(stateVal, stateVal));
|
||||
startStates.add(stateVal);
|
||||
}
|
||||
} else if ("state".equals(name) || "states".equals(name)) {
|
||||
for (ValueArgument arg : call.getValueArguments()) {
|
||||
KtExpression argExpr = arg.getArgumentExpression();
|
||||
if (argExpr != null) {
|
||||
List<String> stateVals = KotlinResolutionUtils.resolveArgumentsList(argExpr, bindingContext);
|
||||
for (String stateVal : stateVals) {
|
||||
states.add(new State(stateVal, stateVal));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
current = dotExpr.getReceiverExpression();
|
||||
}
|
||||
if (current instanceof KtCallExpression call) {
|
||||
String name = getCallName(call);
|
||||
if ("initial".equals(name)) {
|
||||
String stateVal = getFirstArgAsString(call, bindingContext);
|
||||
if (stateVal != null) {
|
||||
states.add(new State(stateVal, stateVal));
|
||||
startStates.add(stateVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ChoiceBranch {
|
||||
String branchType;
|
||||
String target;
|
||||
Guard guard;
|
||||
Action action;
|
||||
}
|
||||
|
||||
private static void parseTransitionChain(KtExpression expression, KotlinSourceContext context,
|
||||
List<Transition> transitions, Map<String, KtExpression> varMap) {
|
||||
BindingContext bindingContext = context.getBindingContext();
|
||||
List<String> sources = new ArrayList<>();
|
||||
List<String> targets = new ArrayList<>();
|
||||
List<Guard> guards = new ArrayList<>();
|
||||
List<Action> actions = new ArrayList<>();
|
||||
String event = null;
|
||||
TransitionType type = TransitionType.EXTERNAL;
|
||||
List<ChoiceBranch> choiceBranches = new ArrayList<>();
|
||||
|
||||
KtExpression current = expression;
|
||||
while (current != null) {
|
||||
current = resolveExpression(current, varMap);
|
||||
KtCallExpression call = null;
|
||||
if (current instanceof KtDotQualifiedExpression dotExpr) {
|
||||
if (dotExpr.getSelectorExpression() instanceof KtCallExpression selectorCall) {
|
||||
call = selectorCall;
|
||||
}
|
||||
current = dotExpr.getReceiverExpression();
|
||||
} else if (current instanceof KtCallExpression callExpr) {
|
||||
call = callExpr;
|
||||
current = null;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
if (call != null) {
|
||||
String name = getCallName(call);
|
||||
if ("source".equals(name) || "sources".equals(name)) {
|
||||
for (ValueArgument arg : call.getValueArguments()) {
|
||||
sources.addAll(KotlinResolutionUtils.resolveArgumentsList(arg.getArgumentExpression(), bindingContext));
|
||||
}
|
||||
} else if ("target".equals(name) || "targets".equals(name)) {
|
||||
for (ValueArgument arg : call.getValueArguments()) {
|
||||
targets.addAll(KotlinResolutionUtils.resolveArgumentsList(arg.getArgumentExpression(), bindingContext));
|
||||
}
|
||||
} else if ("event".equals(name)) {
|
||||
event = getFirstArgAsString(call, bindingContext);
|
||||
} else if ("timer".equals(name) || "timerOnce".equals(name)) {
|
||||
KtExpression argExpr = getArgAsExpression(call, 0, "period", "once");
|
||||
if (argExpr != null) {
|
||||
event = name + "(" + argExpr.getText() + ")";
|
||||
}
|
||||
} else if ("guard".equals(name) || "guardExpression".equals(name)) {
|
||||
KtExpression expr = getArgAsExpression(call, 0, "guard", "guardExpression");
|
||||
if (expr != null) guards.add(createGuard(expr, bindingContext, context));
|
||||
} else if ("guards".equals(name)) {
|
||||
for (int i = 0; i < call.getValueArguments().size(); i++) {
|
||||
KtExpression expr = getArgAsExpression(call, i, "guard");
|
||||
if (expr != null) guards.add(createGuard(expr, bindingContext, context));
|
||||
}
|
||||
} else if ("action".equals(name)) {
|
||||
KtExpression expr = getArgAsExpression(call, 0, "action");
|
||||
if (expr != null) actions.add(createAction(expr, bindingContext, context));
|
||||
} else if ("actions".equals(name)) {
|
||||
for (int i = 0; i < call.getValueArguments().size(); i++) {
|
||||
KtExpression expr = getArgAsExpression(call, i, "action");
|
||||
if (expr != null) actions.add(createAction(expr, bindingContext, context));
|
||||
}
|
||||
} else if ("first".equals(name) || "then".equals(name) || "last".equals(name)) {
|
||||
ChoiceBranch b = new ChoiceBranch();
|
||||
b.branchType = name;
|
||||
KtExpression targetExpr = getArgAsExpression(call, 0, "target", "state");
|
||||
b.target = targetExpr != null ? KotlinResolutionUtils.resolveArgument(targetExpr, bindingContext) : null;
|
||||
|
||||
if ("last".equals(name)) {
|
||||
KtExpression actionExpr = getArgAsExpression(call, 1, "action");
|
||||
if (actionExpr != null) {
|
||||
b.action = createAction(actionExpr, bindingContext, context);
|
||||
}
|
||||
} else {
|
||||
KtExpression guardExpr = getArgAsExpression(call, 1, "guard");
|
||||
if (guardExpr != null) {
|
||||
b.guard = createGuard(guardExpr, bindingContext, context);
|
||||
}
|
||||
KtExpression actionExpr = getArgAsExpression(call, 2, "action");
|
||||
if (actionExpr != null) {
|
||||
b.action = createAction(actionExpr, bindingContext, context);
|
||||
}
|
||||
}
|
||||
choiceBranches.add(b);
|
||||
} else if ("withChoice".equals(name) || "withJunction".equals(name)) {
|
||||
type = "withChoice".equals(name) ? TransitionType.CHOICE : TransitionType.JUNCTION;
|
||||
int order = 0;
|
||||
java.util.Collections.reverse(choiceBranches);
|
||||
List<Transition> temp = new ArrayList<>();
|
||||
for (ChoiceBranch b : choiceBranches) {
|
||||
Transition t = new Transition();
|
||||
t.setType(type);
|
||||
for (String src : sources) {
|
||||
t.getSourceStates().add(new State(src, src));
|
||||
}
|
||||
if (b.target != null) {
|
||||
t.getTargetStates().add(new State(b.target, b.target));
|
||||
}
|
||||
if (b.guard != null) t.getGuards().add(b.guard);
|
||||
if (b.action != null) t.getActions().add(b.action);
|
||||
t.setOrder(order++);
|
||||
temp.add(t);
|
||||
}
|
||||
transitions.addAll(0, temp);
|
||||
|
||||
sources.clear();
|
||||
targets.clear();
|
||||
guards.clear();
|
||||
actions.clear();
|
||||
event = null;
|
||||
choiceBranches.clear();
|
||||
type = TransitionType.EXTERNAL;
|
||||
} else if ("withExternal".equals(name) || "withInternal".equals(name) || "withLocal".equals(name) ||
|
||||
"withFork".equals(name) || "withJoin".equals(name)) {
|
||||
|
||||
if ("withInternal".equals(name)) {
|
||||
type = TransitionType.INTERNAL;
|
||||
} else if ("withLocal".equals(name)) {
|
||||
type = TransitionType.LOCAL;
|
||||
} else if ("withFork".equals(name)) {
|
||||
type = TransitionType.FORK;
|
||||
} else if ("withJoin".equals(name)) {
|
||||
type = TransitionType.JOIN;
|
||||
} else {
|
||||
type = TransitionType.EXTERNAL;
|
||||
}
|
||||
|
||||
if (!sources.isEmpty() || !targets.isEmpty()) {
|
||||
Transition t = new Transition();
|
||||
t.setType(type);
|
||||
for (String src : sources) {
|
||||
t.getSourceStates().add(new State(src, src));
|
||||
}
|
||||
for (String tgt : targets) {
|
||||
t.getTargetStates().add(new State(tgt, tgt));
|
||||
}
|
||||
if (event != null) {
|
||||
t.setEvent(new Event(event, event));
|
||||
}
|
||||
t.getGuards().addAll(guards);
|
||||
t.getActions().addAll(actions);
|
||||
transitions.add(0, t);
|
||||
}
|
||||
|
||||
sources.clear();
|
||||
targets.clear();
|
||||
guards.clear();
|
||||
actions.clear();
|
||||
event = null;
|
||||
choiceBranches.clear();
|
||||
type = TransitionType.EXTERNAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!sources.isEmpty() || !targets.isEmpty() || !choiceBranches.isEmpty()) {
|
||||
if (!choiceBranches.isEmpty()) {
|
||||
int order = 0;
|
||||
java.util.Collections.reverse(choiceBranches);
|
||||
List<Transition> temp = new ArrayList<>();
|
||||
for (ChoiceBranch b : choiceBranches) {
|
||||
Transition t = new Transition();
|
||||
t.setType(type);
|
||||
for (String src : sources) {
|
||||
t.getSourceStates().add(new State(src, src));
|
||||
}
|
||||
if (b.target != null) {
|
||||
t.getTargetStates().add(new State(b.target, b.target));
|
||||
}
|
||||
if (b.guard != null) t.getGuards().add(b.guard);
|
||||
if (b.action != null) t.getActions().add(b.action);
|
||||
t.setOrder(order++);
|
||||
temp.add(t);
|
||||
}
|
||||
transitions.addAll(0, temp);
|
||||
} else {
|
||||
Transition t = new Transition();
|
||||
t.setType(type);
|
||||
for (String src : sources) {
|
||||
t.getSourceStates().add(new State(src, src));
|
||||
}
|
||||
for (String tgt : targets) {
|
||||
t.getTargetStates().add(new State(tgt, tgt));
|
||||
}
|
||||
if (event != null) {
|
||||
t.setEvent(new Event(event, event));
|
||||
}
|
||||
t.getGuards().addAll(guards);
|
||||
t.getActions().addAll(actions);
|
||||
transitions.add(0, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getCallName(KtCallExpression call) {
|
||||
KtExpression callee = call.getCalleeExpression();
|
||||
return callee != null ? callee.getText() : "";
|
||||
}
|
||||
|
||||
private static String getFirstArgAsString(KtCallExpression call, BindingContext bindingContext) {
|
||||
KtExpression argExpr = getArgAsExpression(call, 0, "event", "state", "target", "source");
|
||||
if (argExpr != null) {
|
||||
return KotlinResolutionUtils.resolveArgument(argExpr, bindingContext);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static KtExpression getArgAsExpression(KtCallExpression call, int index, String... paramNames) {
|
||||
for (ValueArgument arg : call.getValueArguments()) {
|
||||
if (arg instanceof KtValueArgument valueArg) {
|
||||
if (valueArg.getArgumentName() != null && valueArg.getArgumentName().getAsName() != null) {
|
||||
String argName = valueArg.getArgumentName().getAsName().asString();
|
||||
for (String name : paramNames) {
|
||||
if (name.equals(argName)) {
|
||||
return valueArg.getArgumentExpression();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (call.getValueArguments().size() > index) {
|
||||
ValueArgument arg = call.getValueArguments().get(index);
|
||||
if (arg instanceof KtValueArgument valueArg) {
|
||||
if (valueArg.getArgumentName() == null) {
|
||||
return valueArg.getArgumentExpression();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!call.getLambdaArguments().isEmpty()) {
|
||||
for (String name : paramNames) {
|
||||
if ("guard".equals(name) || "action".equals(name) || "listener".equals(name)) {
|
||||
return call.getLambdaArguments().get(0).getArgumentExpression();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static KtExpression resolveExpression(KtExpression expr, Map<String, KtExpression> varMap) {
|
||||
if (expr instanceof KtNameReferenceExpression refExpr) {
|
||||
String name = refExpr.getReferencedName();
|
||||
if (varMap.containsKey(name)) {
|
||||
return resolveExpression(varMap.get(name), varMap);
|
||||
}
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
private static int getLineNumber(PsiElement element) {
|
||||
if (element == null) return 0;
|
||||
String text = element.getContainingFile().getText();
|
||||
int offset = element.getTextRange().getStartOffset();
|
||||
int line = 1;
|
||||
for (int i = 0; i < offset && i < text.length(); i++) {
|
||||
if (text.charAt(i) == '\n') {
|
||||
line++;
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
private static String getEnclosingClassFqn(PsiElement element, BindingContext bindingContext) {
|
||||
PsiElement current = element;
|
||||
while (current != null) {
|
||||
if (current instanceof KtClassOrObject ktClass) {
|
||||
return KotlinResolutionUtils.getClassFqn(ktClass, bindingContext);
|
||||
}
|
||||
current = current.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getRelativePathForElement(PsiElement element, KotlinSourceContext context) {
|
||||
if (element == null) return null;
|
||||
org.jetbrains.kotlin.com.intellij.psi.PsiFile file = element.getContainingFile();
|
||||
if (file instanceof KtFile ktFile) {
|
||||
if (ktFile.getVirtualFile() != null) {
|
||||
String pathStr = ktFile.getVirtualFile().getPath();
|
||||
if (pathStr != null) {
|
||||
return context.getRelativePath(java.nio.file.Path.of(pathStr));
|
||||
}
|
||||
}
|
||||
return ktFile.getName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String extractInternalLogic(KtExpression expr, BindingContext bindingContext) {
|
||||
if (expr == null) return null;
|
||||
|
||||
if (expr instanceof KtLambdaExpression) {
|
||||
return expr.getText();
|
||||
}
|
||||
|
||||
if (expr instanceof KtNamedFunction) {
|
||||
return expr.getText();
|
||||
}
|
||||
|
||||
if (expr instanceof KtCallableReferenceExpression callableRef) {
|
||||
org.jetbrains.kotlin.psi.KtSimpleNameExpression refName = callableRef.getCallableReference();
|
||||
if (refName != null) {
|
||||
org.jetbrains.kotlin.descriptors.DeclarationDescriptor descriptor =
|
||||
bindingContext.get(BindingContext.REFERENCE_TARGET, refName);
|
||||
if (descriptor != null) {
|
||||
org.jetbrains.kotlin.com.intellij.psi.PsiElement decl =
|
||||
org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
|
||||
if (decl instanceof KtNamedFunction helperFunc) {
|
||||
return helperFunc.getText();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (expr instanceof KtCallExpression callExpr) {
|
||||
ResolvedCall<? extends org.jetbrains.kotlin.descriptors.CallableDescriptor> resolvedCall =
|
||||
org.jetbrains.kotlin.resolve.calls.util.CallUtilKt.getResolvedCall(callExpr, bindingContext);
|
||||
if (resolvedCall != null) {
|
||||
org.jetbrains.kotlin.descriptors.CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
|
||||
if (descriptor != null) {
|
||||
org.jetbrains.kotlin.com.intellij.psi.PsiElement decl =
|
||||
org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
|
||||
if (decl instanceof KtNamedFunction helperFunc) {
|
||||
KtExpression body = helperFunc.getBodyExpression();
|
||||
if (body != null) {
|
||||
if (!helperFunc.hasBlockBody()) {
|
||||
return body.getText();
|
||||
} else if (body instanceof KtBlockExpression block) {
|
||||
List<KtExpression> statements = block.getStatements();
|
||||
if (statements.size() == 1 && statements.get(0) instanceof KtReturnExpression returnExpr) {
|
||||
KtExpression retVal = returnExpr.getReturnedExpression();
|
||||
if (retVal != null) {
|
||||
return retVal.getText();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return helperFunc.getText();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (expr instanceof KtNameReferenceExpression refExpr) {
|
||||
org.jetbrains.kotlin.descriptors.DeclarationDescriptor descriptor =
|
||||
bindingContext.get(BindingContext.REFERENCE_TARGET, refExpr);
|
||||
if (descriptor != null) {
|
||||
org.jetbrains.kotlin.com.intellij.psi.PsiElement decl =
|
||||
org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
|
||||
if (decl instanceof KtProperty property) {
|
||||
KtExpression initializer = property.getInitializer();
|
||||
if (initializer != null) {
|
||||
return extractInternalLogic(initializer, bindingContext);
|
||||
}
|
||||
}
|
||||
if (decl instanceof KtClassOrObject ktClass) {
|
||||
for (KtDeclaration childDecl : ktClass.getDeclarations()) {
|
||||
if (childDecl instanceof KtNamedFunction func) {
|
||||
String name = func.getName();
|
||||
if ("evaluate".equals(name) || "execute".equals(name)) {
|
||||
return func.getText();
|
||||
}
|
||||
}
|
||||
}
|
||||
return ktClass.getText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isLambdaOrAnonymous(KtExpression expr) {
|
||||
if (expr == null) return false;
|
||||
if (expr instanceof KtLambdaExpression) return true;
|
||||
if (expr instanceof KtNamedFunction namedFunc) {
|
||||
return namedFunc.getName() == null;
|
||||
}
|
||||
if (expr instanceof KtObjectLiteralExpression) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Guard createGuard(KtExpression expr, BindingContext bindingContext, KotlinSourceContext context) {
|
||||
boolean isLambda = isLambdaOrAnonymous(expr);
|
||||
String internalLogic = extractInternalLogic(expr, bindingContext);
|
||||
int lineNumber = getLineNumber(expr);
|
||||
String fqn = getEnclosingClassFqn(expr, bindingContext);
|
||||
String sourceFile = getRelativePathForElement(expr, context);
|
||||
return Guard.of(expr.getText(), isLambda, internalLogic, lineNumber, fqn, sourceFile);
|
||||
}
|
||||
|
||||
private static Action createAction(KtExpression expr, BindingContext bindingContext, KotlinSourceContext context) {
|
||||
boolean isLambda = isLambdaOrAnonymous(expr);
|
||||
String internalLogic = extractInternalLogic(expr, bindingContext);
|
||||
int lineNumber = getLineNumber(expr);
|
||||
String fqn = getEnclosingClassFqn(expr, bindingContext);
|
||||
String sourceFile = getRelativePathForElement(expr, context);
|
||||
return Action.of(expr.getText(), isLambda, internalLogic, lineNumber, fqn, sourceFile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
package click.kamil.springstatemachineexporter.plugin.kotlin;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.model.CallChain;
|
||||
import click.kamil.springstatemachineexporter.analysis.model.EntryPoint;
|
||||
import click.kamil.springstatemachineexporter.analysis.model.TriggerPoint;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class KotlinCallGraphEngineTest {
|
||||
|
||||
@TempDir
|
||||
Path tempDir;
|
||||
|
||||
@Test
|
||||
public void testCallChainResolution() throws IOException {
|
||||
String code = "package click.kamil.test\n" +
|
||||
"\n" +
|
||||
"annotation class GetMapping\n" +
|
||||
"\n" +
|
||||
"class Controller(val service: MyService) {\n" +
|
||||
" @GetMapping\n" +
|
||||
" fun handleRequest() {\n" +
|
||||
" service.process()\n" +
|
||||
" }\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"class MyService {\n" +
|
||||
" fun process() {\n" +
|
||||
" sendEvent(\"START\")\n" +
|
||||
" }\n" +
|
||||
" \n" +
|
||||
" fun sendEvent(event: String) {}\n" +
|
||||
"}\n";
|
||||
|
||||
Path ktFile = tempDir.resolve("App.kt");
|
||||
Files.writeString(ktFile, code);
|
||||
|
||||
KotlinSourceContext context = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
KotlinIntelligenceProvider provider = new KotlinIntelligenceProvider(context);
|
||||
|
||||
List<EntryPoint> entryPoints = provider.findEntryPoints();
|
||||
List<TriggerPoint> triggers = provider.findTriggerPoints();
|
||||
|
||||
assertThat(entryPoints).hasSize(1);
|
||||
assertThat(entryPoints.get(0).getName()).isEqualTo("click.kamil.test.Controller.handleRequest");
|
||||
assertThat(entryPoints.get(0).getClassName()).isEqualTo("click.kamil.test.Controller");
|
||||
assertThat(entryPoints.get(0).getMethodName()).isEqualTo("handleRequest");
|
||||
|
||||
assertThat(triggers).hasSize(1);
|
||||
assertThat(triggers.get(0).getEvent()).isEqualTo("START");
|
||||
assertThat(triggers.get(0).getClassName()).isEqualTo("click.kamil.test.MyService");
|
||||
assertThat(triggers.get(0).getMethodName()).isEqualTo("process");
|
||||
|
||||
List<CallChain> chains = provider.findCallChains(entryPoints, triggers);
|
||||
assertThat(chains).hasSize(1);
|
||||
|
||||
CallChain chain = chains.get(0);
|
||||
assertThat(chain.getEntryPoint()).isEqualTo(entryPoints.get(0));
|
||||
assertThat(chain.getTriggerPoint()).isEqualTo(triggers.get(0));
|
||||
assertThat(chain.getMethodChain()).containsExactly(
|
||||
"click.kamil.test.Controller.handleRequest",
|
||||
"click.kamil.test.MyService.process"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPolymorphicCallChainResolution() throws IOException {
|
||||
String code = "package click.kamil.test\n" +
|
||||
"\n" +
|
||||
"annotation class GetMapping\n" +
|
||||
"\n" +
|
||||
"interface BaseService {\n" +
|
||||
" fun process()\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"class Controller(val service: BaseService) {\n" +
|
||||
" @GetMapping\n" +
|
||||
" fun handleRequest() {\n" +
|
||||
" service.process()\n" +
|
||||
" }\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"class MyServiceImpl : BaseService {\n" +
|
||||
" override fun process() {\n" +
|
||||
" sendEvent(\"START\")\n" +
|
||||
" }\n" +
|
||||
" \n" +
|
||||
" fun sendEvent(event: String) {}\n" +
|
||||
"}\n";
|
||||
|
||||
Path ktFile = tempDir.resolve("AppPolymorphic.kt");
|
||||
Files.writeString(ktFile, code);
|
||||
|
||||
KotlinSourceContext context = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
KotlinIntelligenceProvider provider = new KotlinIntelligenceProvider(context);
|
||||
|
||||
List<EntryPoint> entryPoints = provider.findEntryPoints();
|
||||
List<TriggerPoint> triggers = provider.findTriggerPoints();
|
||||
|
||||
assertThat(entryPoints).hasSize(1);
|
||||
assertThat(triggers).hasSize(1);
|
||||
|
||||
List<CallChain> chains = provider.findCallChains(entryPoints, triggers);
|
||||
assertThat(chains).hasSize(1);
|
||||
|
||||
CallChain chain = chains.get(0);
|
||||
assertThat(chain.getMethodChain()).containsExactly(
|
||||
"click.kamil.test.Controller.handleRequest",
|
||||
"click.kamil.test.MyServiceImpl.process"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMixedLanguageCallChainResolution() throws IOException {
|
||||
String ktCode = "package click.kamil.demo\n" +
|
||||
"\n" +
|
||||
"class KotlinService {\n" +
|
||||
" fun process() {\n" +
|
||||
" sendEvent(\"MIXED_EVENT\")\n" +
|
||||
" }\n" +
|
||||
" fun sendEvent(event: String) {}\n" +
|
||||
"}\n";
|
||||
Path ktFile = tempDir.resolve("KotlinService.kt");
|
||||
Files.writeString(ktFile, ktCode);
|
||||
|
||||
String javaCode = "package click.kamil.demo;\n" +
|
||||
"\n" +
|
||||
"@org.springframework.web.bind.annotation.RestController\n" +
|
||||
"public class JavaController {\n" +
|
||||
" private final KotlinService service;\n" +
|
||||
" public JavaController(KotlinService service) {\n" +
|
||||
" this.service = service;\n" +
|
||||
" }\n" +
|
||||
" @org.springframework.web.bind.annotation.GetMapping\n" +
|
||||
" public void handleRequest() {\n" +
|
||||
" service.process();\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
String annCode = "package org.springframework.web.bind.annotation;\n" +
|
||||
"public @interface GetMapping {}\n";
|
||||
String rcAnnCode = "package org.springframework.web.bind.annotation;\n" +
|
||||
"public @interface RestController {}\n";
|
||||
|
||||
Files.createDirectories(tempDir.resolve("src/main/java/click/kamil/demo"));
|
||||
Files.createDirectories(tempDir.resolve("src/main/java/org/springframework/web/bind/annotation"));
|
||||
Files.writeString(tempDir.resolve("src/main/java/click/kamil/demo/JavaController.java"), javaCode);
|
||||
Files.writeString(tempDir.resolve("src/main/java/org/springframework/web/bind/annotation/GetMapping.java"), annCode);
|
||||
Files.writeString(tempDir.resolve("src/main/java/org/springframework/web/bind/annotation/RestController.java"), rcAnnCode);
|
||||
|
||||
KotlinSourceContext ktContext = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
KotlinIntelligenceProvider ktProvider = new KotlinIntelligenceProvider(ktContext);
|
||||
|
||||
click.kamil.springstatemachineexporter.plugin.java.JavaLanguageAnalyzerPlugin javaPlugin =
|
||||
new click.kamil.springstatemachineexporter.plugin.java.JavaLanguageAnalyzerPlugin();
|
||||
click.kamil.springstatemachineexporter.spi.SourceContext javaContext =
|
||||
javaPlugin.parseProject(tempDir, Collections.emptyList(), java.util.Set.of(tempDir));
|
||||
click.kamil.springstatemachineexporter.analysis.service.CodebaseIntelligenceProvider javaProvider =
|
||||
javaPlugin.createIntelligenceProvider(javaContext);
|
||||
|
||||
var providers = List.of(ktProvider, javaProvider);
|
||||
var engines = List.of(new KotlinCallGraphEngine(ktContext), javaPlugin.createCallGraphEngine(javaContext));
|
||||
var compositeProvider = new click.kamil.springstatemachineexporter.analysis.service.CompositeIntelligenceProvider(providers, engines);
|
||||
|
||||
List<EntryPoint> entryPoints = compositeProvider.findEntryPoints();
|
||||
List<TriggerPoint> triggers = compositeProvider.findTriggerPoints();
|
||||
|
||||
assertThat(entryPoints).isNotEmpty();
|
||||
assertThat(triggers).isNotEmpty();
|
||||
|
||||
List<CallChain> chains = compositeProvider.findCallChains(entryPoints, triggers);
|
||||
assertThat(chains).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSealedHierarchyStateExtraction() throws IOException {
|
||||
String code = "package click.kamil.test\n" +
|
||||
"\n" +
|
||||
"annotation class EnableStateMachine\n" +
|
||||
"\n" +
|
||||
"sealed class MyStates {\n" +
|
||||
" object STATE_A : MyStates()\n" +
|
||||
" object STATE_B : MyStates()\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"class StateConfigurer {\n" +
|
||||
" fun withStates(): StateConfigurer = this\n" +
|
||||
" fun initial(s: String): StateConfigurer = this\n" +
|
||||
" fun state(s: String): StateConfigurer = this\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"class TransitionConfigurer {\n" +
|
||||
" fun withExternal(): TransitionConfigurer = this\n" +
|
||||
" fun source(s: String): TransitionConfigurer = this\n" +
|
||||
" fun target(s: String): TransitionConfigurer = this\n" +
|
||||
" fun event(e: String): TransitionConfigurer = this\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"class StateMachineConfigurerAdapter<S, E>\n" +
|
||||
"\n" +
|
||||
"@EnableStateMachine\n" +
|
||||
"class MyConfig : StateMachineConfigurerAdapter<MyStates, String>() {\n" +
|
||||
" fun configure(states: StateConfigurer) {\n" +
|
||||
" states.withStates().initial(\"STATE_A\").state(\"STATE_B\")\n" +
|
||||
" }\n" +
|
||||
" fun configure(transitions: TransitionConfigurer) {\n" +
|
||||
" transitions.withExternal().source(\"STATE_A\").target(\"STATE_B\").event(\"EVENT_X\")\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
Path ktFile = tempDir.resolve("SealedStates.kt");
|
||||
Files.writeString(ktFile, code);
|
||||
|
||||
KotlinSourceContext context = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
List<click.kamil.springstatemachineexporter.analysis.model.AnalysisResult> results =
|
||||
new KotlinLanguageAnalyzerPlugin().extractStateMachines(context, true);
|
||||
|
||||
assertThat(results).isNotEmpty();
|
||||
click.kamil.springstatemachineexporter.analysis.model.AnalysisResult result = results.get(0);
|
||||
assertThat(result.getStates()).extracting("rawName").containsExactlyInAnyOrder("STATE_A", "STATE_B");
|
||||
assertThat(result.getTransitions()).hasSize(1);
|
||||
assertThat(result.getTransitions().get(0).getEvent().rawName()).isEqualTo("EVENT_X");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package click.kamil.springstatemachineexporter.plugin.kotlin;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.model.EntryPoint;
|
||||
import click.kamil.springstatemachineexporter.analysis.model.TriggerPoint;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class KotlinIntelligenceProviderTest {
|
||||
|
||||
@TempDir
|
||||
Path tempDir;
|
||||
|
||||
@Test
|
||||
public void testFindEntryPointsAndTriggerPoints() throws IOException {
|
||||
String code = "package click.kamil.test\n" +
|
||||
"\n" +
|
||||
"import org.springframework.web.bind.annotation.RestController\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestMapping\n" +
|
||||
"import org.springframework.web.bind.annotation.PostMapping\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestBody\n" +
|
||||
"import org.springframework.kafka.annotation.KafkaListener\n" +
|
||||
"import org.springframework.statemachine.StateMachine\n" +
|
||||
"\n" +
|
||||
"@RestController\n" +
|
||||
"@RequestMapping(\"/api/orders\")\n" +
|
||||
"class OrderController {\n" +
|
||||
"\n" +
|
||||
" @PostMapping(\"/create\")\n" +
|
||||
" fun createOrder(@RequestBody orderId: String, sm: StateMachine<String, String>) {\n" +
|
||||
" val userRole = \"admin\"\n" +
|
||||
" if (userRole == \"admin\") {\n" +
|
||||
" val state = \"PENDING\"\n" +
|
||||
" if (state == \"PENDING\") {\n" +
|
||||
" sm.sendEvent(\"PAY\")\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"\n" +
|
||||
" @KafkaListener(topics = [\"order-events\"])\n" +
|
||||
" fun onOrderEvent(message: String) {\n" +
|
||||
" println(message)\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
Path ktFile = tempDir.resolve("OrderController.kt");
|
||||
Files.writeString(ktFile, code);
|
||||
|
||||
KotlinSourceContext context = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
KotlinIntelligenceProvider provider = new KotlinIntelligenceProvider(context);
|
||||
|
||||
// 1. Entry Points assertions
|
||||
List<EntryPoint> entryPoints = provider.findEntryPoints();
|
||||
assertThat(entryPoints).hasSize(2);
|
||||
|
||||
// REST Entry Point
|
||||
EntryPoint restEp = entryPoints.stream()
|
||||
.filter(ep -> ep.getType() == EntryPoint.Type.REST)
|
||||
.findFirst().orElseThrow();
|
||||
assertThat(restEp.getName()).isEqualTo("POST /api/orders/create");
|
||||
assertThat(restEp.getClassName()).isEqualTo("click.kamil.test.OrderController");
|
||||
assertThat(restEp.getMethodName()).isEqualTo("createOrder");
|
||||
assertThat(restEp.getSourceFile()).isEqualTo("OrderController.kt");
|
||||
assertThat(restEp.getMetadata().get("path")).isEqualTo("/api/orders/create");
|
||||
assertThat(restEp.getMetadata().get("verb")).isEqualTo("POST");
|
||||
assertThat(restEp.getParameters()).hasSize(2);
|
||||
assertThat(restEp.getParameters().get(0).getName()).isEqualTo("orderId");
|
||||
assertThat(restEp.getParameters().get(0).getType()).contains("String");
|
||||
assertThat(restEp.getParameters().get(0).getAnnotations()).contains("RequestBody");
|
||||
|
||||
// Messaging Entry Point
|
||||
EntryPoint msgEp = entryPoints.stream()
|
||||
.filter(ep -> ep.getType() == EntryPoint.Type.KAFKA)
|
||||
.findFirst().orElseThrow();
|
||||
assertThat(msgEp.getName()).isEqualTo("KAFKA: order-events");
|
||||
assertThat(msgEp.getClassName()).isEqualTo("click.kamil.test.OrderController");
|
||||
assertThat(msgEp.getMethodName()).isEqualTo("onOrderEvent");
|
||||
assertThat(msgEp.getSourceFile()).isEqualTo("OrderController.kt");
|
||||
assertThat(msgEp.getMetadata().get("destination")).isEqualTo("order-events");
|
||||
assertThat(msgEp.getParameters()).hasSize(1);
|
||||
assertThat(msgEp.getParameters().get(0).getName()).isEqualTo("message");
|
||||
|
||||
// 2. Trigger Points assertions
|
||||
List<TriggerPoint> triggers = provider.findTriggerPoints();
|
||||
assertThat(triggers).hasSize(1);
|
||||
|
||||
TriggerPoint trigger = triggers.get(0);
|
||||
assertThat(trigger.getEvent()).isEqualTo("PAY");
|
||||
assertThat(trigger.getSourceState()).isEqualTo("PENDING");
|
||||
assertThat(trigger.getClassName()).isEqualTo("click.kamil.test.OrderController");
|
||||
assertThat(trigger.getMethodName()).isEqualTo("createOrder");
|
||||
assertThat(trigger.getSourceFile()).isEqualTo("OrderController.kt");
|
||||
assertThat(trigger.getLineNumber()).isEqualTo(20);
|
||||
assertThat(trigger.getStateTypeFqn()).contains("String");
|
||||
assertThat(trigger.getEventTypeFqn()).contains("String");
|
||||
assertThat(trigger.isExternal()).isTrue();
|
||||
assertThat(trigger.getConstraint()).isEqualTo("userRole == \"admin\"");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package click.kamil.springstatemachineexporter.plugin.kotlin;
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtClass;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction;
|
||||
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class KotlinSemanticResolutionTest {
|
||||
|
||||
@TempDir
|
||||
Path tempDir;
|
||||
|
||||
@Test
|
||||
public void testBindingContextResolution() throws IOException {
|
||||
String code = "package click.kamil.test\n" +
|
||||
"\n" +
|
||||
"class MyTestClass {\n" +
|
||||
" fun process(event: String) {\n" +
|
||||
" println(event)\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
Path ktFile = tempDir.resolve("MyTestClass.kt");
|
||||
Files.writeString(ktFile, code);
|
||||
|
||||
KotlinSourceContext context = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
assertThat(context.getKtFiles()).hasSize(1);
|
||||
|
||||
KtFile parsedFile = context.getKtFiles().get(0);
|
||||
AtomicReference<KtClass> ktClassRef = new AtomicReference<>();
|
||||
AtomicReference<KtNamedFunction> ktFunctionRef = new AtomicReference<>();
|
||||
|
||||
parsedFile.accept(new KtTreeVisitorVoid() {
|
||||
@Override
|
||||
public void visitClass(KtClass klass) {
|
||||
ktClassRef.set(klass);
|
||||
super.visitClass(klass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNamedFunction(KtNamedFunction function) {
|
||||
ktFunctionRef.set(function);
|
||||
super.visitNamedFunction(function);
|
||||
}
|
||||
});
|
||||
|
||||
assertThat(ktClassRef.get()).isNotNull();
|
||||
assertThat(ktFunctionRef.get()).isNotNull();
|
||||
|
||||
String classFqn = KotlinResolutionUtils.getClassFqn(ktClassRef.get(), context.getBindingContext());
|
||||
String functionFqn = KotlinResolutionUtils.getFunctionFqn(ktFunctionRef.get(), context.getBindingContext());
|
||||
|
||||
assertThat(classFqn).isEqualTo("click.kamil.test.MyTestClass");
|
||||
assertThat(functionFqn).isEqualTo("click.kamil.test.MyTestClass.process");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupertypeResolution() throws IOException {
|
||||
String code = "package click.kamil.test\n" +
|
||||
"\n" +
|
||||
"interface BaseService\n" +
|
||||
"class MyServiceImpl : BaseService\n";
|
||||
|
||||
Path ktFile = tempDir.resolve("Supertypes.kt");
|
||||
Files.writeString(ktFile, code);
|
||||
|
||||
KotlinSourceContext context = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
|
||||
assertThat(context.getSuperclasses()).containsEntry("click.kamil.test.MyServiceImpl", "click.kamil.test.BaseService");
|
||||
assertThat(context.getImplementations().get("click.kamil.test.BaseService"))
|
||||
.containsExactly("click.kamil.test.MyServiceImpl");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package click.kamil.springstatemachineexporter.plugin.kotlin;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.model.AnalysisResult;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class KotlinStateMachineExtractorActionGuardTest {
|
||||
|
||||
@TempDir
|
||||
Path tempDir;
|
||||
|
||||
@Test
|
||||
public void testActionsGuardsTimers() throws IOException {
|
||||
String code = "package click.kamil.test\n" +
|
||||
"\n" +
|
||||
"import org.springframework.statemachine.config.EnableStateMachine\n" +
|
||||
"import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter\n" +
|
||||
"import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer\n" +
|
||||
"\n" +
|
||||
"@EnableStateMachine\n" +
|
||||
"class MyStateMachine : EnumStateMachineConfigurerAdapter<String, String>() {\n" +
|
||||
" override fun configure(transitions: StateMachineTransitionConfigurer<String, String>) {\n" +
|
||||
" transitions\n" +
|
||||
" .withExternal()\n" +
|
||||
" .source(\"S1\").target(\"S2\")\n" +
|
||||
" .guard { true }\n" +
|
||||
" .action { println(\"S1 to S2\") }\n" +
|
||||
" .and()\n" +
|
||||
" .withExternal()\n" +
|
||||
" .source(\"S2\").target(\"S3\")\n" +
|
||||
" .timer(1000)\n" +
|
||||
" .guardExpression(\"true\")\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
Path ktFile = tempDir.resolve("MyStateMachine.kt");
|
||||
Files.writeString(ktFile, code);
|
||||
|
||||
KotlinSourceContext context = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
List<AnalysisResult> results = KotlinStateMachineExtractor.extract(context, false);
|
||||
|
||||
assertThat(results).hasSize(1);
|
||||
AnalysisResult result = results.get(0);
|
||||
|
||||
var transitions = result.getTransitions();
|
||||
assertThat(transitions).hasSize(2);
|
||||
|
||||
var t1 = transitions.stream().filter(t -> t.getSourceStates().get(0).rawName().equals("S1")).findFirst().get();
|
||||
assertThat(t1.getGuards()).hasSize(1);
|
||||
assertThat(t1.getGuards().get(0).expression()).isEqualTo("{ true }");
|
||||
assertThat(t1.getGuards().get(0).isLambda()).isTrue();
|
||||
assertThat(t1.getActions()).hasSize(1);
|
||||
assertThat(t1.getActions().get(0).expression()).isEqualTo("{ println(\"S1 to S2\") }");
|
||||
assertThat(t1.getActions().get(0).isLambda()).isTrue();
|
||||
|
||||
var t2 = transitions.stream().filter(t -> t.getSourceStates().get(0).rawName().equals("S2")).findFirst().get();
|
||||
assertThat(t2.getEvent().rawName()).isEqualTo("timer(1000)");
|
||||
assertThat(t2.getGuards()).hasSize(1);
|
||||
assertThat(t2.getGuards().get(0).expression()).isEqualTo("\"true\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRichMetadataResolution() throws IOException {
|
||||
String code = "package click.kamil.test\n" +
|
||||
"\n" +
|
||||
"import org.springframework.statemachine.config.EnableStateMachine\n" +
|
||||
"import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter\n" +
|
||||
"import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer\n" +
|
||||
"import org.springframework.statemachine.guard.Guard\n" +
|
||||
"\n" +
|
||||
"@EnableStateMachine\n" +
|
||||
"class MyStateMachine : EnumStateMachineConfigurerAdapter<String, String>() {\n" +
|
||||
" override fun configure(transitions: StateMachineTransitionConfigurer<String, String>) {\n" +
|
||||
" transitions\n" +
|
||||
" .withExternal()\n" +
|
||||
" .source(\"S1\").target(\"S2\")\n" +
|
||||
" .guard(myHelperGuard())\n" +
|
||||
" .action(::myHelperAction)\n" +
|
||||
" }\n" +
|
||||
"\n" +
|
||||
" fun myHelperGuard(): Guard<String, String> {\n" +
|
||||
" return Guard { true }\n" +
|
||||
" }\n" +
|
||||
"\n" +
|
||||
" fun myHelperAction(context: Any) {\n" +
|
||||
" println(\"action executed\")\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
Path ktFile = tempDir.resolve("MyStateMachine.kt");
|
||||
Files.writeString(ktFile, code);
|
||||
|
||||
KotlinSourceContext context = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
List<AnalysisResult> results = KotlinStateMachineExtractor.extract(context, false);
|
||||
|
||||
assertThat(results).hasSize(1);
|
||||
AnalysisResult result = results.get(0);
|
||||
|
||||
var transitions = result.getTransitions();
|
||||
assertThat(transitions).hasSize(1);
|
||||
var t1 = transitions.get(0);
|
||||
|
||||
// Guard assertions
|
||||
assertThat(t1.getGuards()).hasSize(1);
|
||||
var guard = t1.getGuards().get(0);
|
||||
assertThat(guard.expression()).isEqualTo("myHelperGuard()");
|
||||
assertThat(guard.internalLogic()).contains("Guard { true }");
|
||||
assertThat(guard.lineNumber()).isEqualTo(14);
|
||||
assertThat(guard.className()).isEqualTo("click.kamil.test.MyStateMachine");
|
||||
assertThat(guard.sourceFile()).isEqualTo("MyStateMachine.kt");
|
||||
|
||||
// Action assertions
|
||||
assertThat(t1.getActions()).hasSize(1);
|
||||
var action = t1.getActions().get(0);
|
||||
assertThat(action.expression()).isEqualTo("::myHelperAction");
|
||||
assertThat(action.internalLogic()).contains("println(\"action executed\")");
|
||||
assertThat(action.lineNumber()).isEqualTo(15);
|
||||
assertThat(action.className()).isEqualTo("click.kamil.test.MyStateMachine");
|
||||
assertThat(action.sourceFile()).isEqualTo("MyStateMachine.kt");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package click.kamil.springstatemachineexporter.plugin.kotlin;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.model.AnalysisResult;
|
||||
import click.kamil.springstatemachineexporter.model.TransitionType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class KotlinStateMachineExtractorPseudoStatesTest {
|
||||
|
||||
@TempDir
|
||||
Path tempDir;
|
||||
|
||||
@Test
|
||||
public void testPseudoStatesExtraction() throws IOException {
|
||||
String code = "package click.kamil.test\n" +
|
||||
"\n" +
|
||||
"import org.springframework.statemachine.config.EnableStateMachine\n" +
|
||||
"import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter\n" +
|
||||
"import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer\n" +
|
||||
"\n" +
|
||||
"@EnableStateMachine\n" +
|
||||
"class MyStateMachine : EnumStateMachineConfigurerAdapter<String, String>() {\n" +
|
||||
" override fun configure(transitions: StateMachineTransitionConfigurer<String, String>) {\n" +
|
||||
" transitions\n" +
|
||||
" .withChoice()\n" +
|
||||
" .source(\"S1\")\n" +
|
||||
" .first(\"S2\", { true })\n" +
|
||||
" .then(\"S3\", { false })\n" +
|
||||
" .last(\"S4\")\n" +
|
||||
" .and()\n" +
|
||||
" .withFork()\n" +
|
||||
" .source(\"S5\")\n" +
|
||||
" .targets(\"S6\", \"S7\")\n" +
|
||||
" .and()\n" +
|
||||
" .withJoin()\n" +
|
||||
" .sources(\"S8\", \"S9\")\n" +
|
||||
" .target(\"S10\")\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
Path ktFile = tempDir.resolve("MyStateMachine.kt");
|
||||
Files.writeString(ktFile, code);
|
||||
|
||||
KotlinSourceContext context = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
List<AnalysisResult> results = KotlinStateMachineExtractor.extract(context, false);
|
||||
System.out.println("RESULTS: " + results);
|
||||
|
||||
assertThat(results).hasSize(1);
|
||||
AnalysisResult result = results.get(0);
|
||||
|
||||
// Choice should create 3 transitions (first, then, last)
|
||||
long choiceCount = result.getTransitions().stream().filter(t -> t.getType() == TransitionType.CHOICE).count();
|
||||
assertThat(choiceCount).isEqualTo(3);
|
||||
|
||||
// Fork should create 1 transition with 1 source and 2 targets
|
||||
var forkTransition = result.getTransitions().stream().filter(t -> t.getType() == TransitionType.FORK).findFirst().get();
|
||||
assertThat(forkTransition.getSourceStates()).hasSize(1);
|
||||
assertThat(forkTransition.getTargetStates()).hasSize(2);
|
||||
|
||||
// Join should create 1 transition with 2 sources and 1 target
|
||||
var joinTransition = result.getTransitions().stream().filter(t -> t.getType() == TransitionType.JOIN).findFirst().get();
|
||||
assertThat(joinTransition.getSourceStates()).hasSize(2);
|
||||
assertThat(joinTransition.getTargetStates()).hasSize(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package click.kamil.springstatemachineexporter.plugin.kotlin;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.model.AnalysisResult;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class KotlinStateMachineExtractorSetOfTest {
|
||||
|
||||
@TempDir
|
||||
Path tempDir;
|
||||
|
||||
@Test
|
||||
public void testStatesWithSetOf() throws IOException {
|
||||
String code = "package click.kamil.test\n" +
|
||||
"\n" +
|
||||
"import org.springframework.statemachine.config.EnableStateMachine\n" +
|
||||
"import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter\n" +
|
||||
"import org.springframework.statemachine.config.builders.StateMachineStateConfigurer\n" +
|
||||
"\n" +
|
||||
"@EnableStateMachine\n" +
|
||||
"class MyStateMachine : EnumStateMachineConfigurerAdapter<String, String>() {\n" +
|
||||
" override fun configure(states: StateMachineStateConfigurer<String, String>) {\n" +
|
||||
" states\n" +
|
||||
" .withStates()\n" +
|
||||
" .initial(\"S1\")\n" +
|
||||
" .states(setOf(\"S2\", \"S3\"))\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
Path ktFile = tempDir.resolve("MyStateMachine.kt");
|
||||
Files.writeString(ktFile, code);
|
||||
|
||||
KotlinSourceContext context = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
List<AnalysisResult> results = KotlinStateMachineExtractor.extract(context, false);
|
||||
|
||||
assertThat(results).hasSize(1);
|
||||
AnalysisResult result = results.get(0);
|
||||
assertThat(result.getStates()).extracting("rawName").contains("S1", "S2", "S3");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
package click.kamil.springstatemachineexporter.plugin.kotlin;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.model.AnalysisResult;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class KotlinStateMachineExtractorTest {
|
||||
|
||||
@TempDir
|
||||
Path tempDir;
|
||||
|
||||
@Test
|
||||
public void testMultipleTransitionsWithAnd() throws IOException {
|
||||
String code = "package click.kamil.test\n" +
|
||||
"\n" +
|
||||
"import org.springframework.statemachine.config.EnableStateMachine\n" +
|
||||
"import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter\n" +
|
||||
"import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer\n" +
|
||||
"\n" +
|
||||
"@EnableStateMachine\n" +
|
||||
"class MyStateMachine : EnumStateMachineConfigurerAdapter<String, String>() {\n" +
|
||||
" override fun configure(transitions: StateMachineTransitionConfigurer<String, String>) {\n" +
|
||||
" transitions\n" +
|
||||
" .withExternal()\n" +
|
||||
" .source(\"S1\").target(\"S2\").event(\"E1\")\n" +
|
||||
" .and()\n" +
|
||||
" .withExternal()\n" +
|
||||
" .source(\"S2\").target(\"S3\").event(\"E2\")\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
Path ktFile = tempDir.resolve("MyStateMachine.kt");
|
||||
Files.writeString(ktFile, code);
|
||||
|
||||
KotlinSourceContext context = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
List<AnalysisResult> results = KotlinStateMachineExtractor.extract(context, false);
|
||||
|
||||
assertThat(results).hasSize(1);
|
||||
AnalysisResult result = results.get(0);
|
||||
assertThat(result.getTransitions()).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSplitVariableChains() throws IOException {
|
||||
String code = "package click.kamil.test\n" +
|
||||
"\n" +
|
||||
"import org.springframework.statemachine.config.EnableStateMachine\n" +
|
||||
"import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter\n" +
|
||||
"import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer\n" +
|
||||
"\n" +
|
||||
"@EnableStateMachine\n" +
|
||||
"class MyStateMachine : EnumStateMachineConfigurerAdapter<String, String>() {\n" +
|
||||
" override fun configure(transitions: StateMachineTransitionConfigurer<String, String>) {\n" +
|
||||
" val ext = transitions.withExternal()\n" +
|
||||
" ext.source(\"S1\").target(\"S2\").event(\"E1\")\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
Path ktFile = tempDir.resolve("MyStateMachine.kt");
|
||||
Files.writeString(ktFile, code);
|
||||
|
||||
KotlinSourceContext context = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
List<AnalysisResult> results = KotlinStateMachineExtractor.extract(context, false);
|
||||
|
||||
assertThat(results).hasSize(1);
|
||||
AnalysisResult result = results.get(0);
|
||||
assertThat(result.getTransitions()).hasSize(1);
|
||||
var transition = result.getTransitions().get(0);
|
||||
assertThat(transition.getSourceStates().get(0).rawName()).isEqualTo("S1");
|
||||
assertThat(transition.getTargetStates().get(0).rawName()).isEqualTo("S2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChoiceOrdering() throws IOException {
|
||||
String code = "package click.kamil.test\n" +
|
||||
"\n" +
|
||||
"import org.springframework.statemachine.config.EnableStateMachine\n" +
|
||||
"import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter\n" +
|
||||
"import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer\n" +
|
||||
"\n" +
|
||||
"@EnableStateMachine\n" +
|
||||
"class MyStateMachine : EnumStateMachineConfigurerAdapter<String, String>() {\n" +
|
||||
" override fun configure(transitions: StateMachineTransitionConfigurer<String, String>) {\n" +
|
||||
" transitions.withChoice()\n" +
|
||||
" .source(\"S1\")\n" +
|
||||
" .first(\"S2\", { true })\n" +
|
||||
" .then(\"S3\", { false })\n" +
|
||||
" .last(\"S4\")\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
Path ktFile = tempDir.resolve("MyStateMachine.kt");
|
||||
Files.writeString(ktFile, code);
|
||||
|
||||
KotlinSourceContext context = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
List<AnalysisResult> results = KotlinStateMachineExtractor.extract(context, false);
|
||||
|
||||
assertThat(results).hasSize(1);
|
||||
AnalysisResult result = results.get(0);
|
||||
assertThat(result.getTransitions()).hasSize(3);
|
||||
|
||||
assertThat(result.getTransitions().get(0).getTargetStates().get(0).rawName()).isEqualTo("S2");
|
||||
assertThat(result.getTransitions().get(0).getOrder()).isEqualTo(0);
|
||||
|
||||
assertThat(result.getTransitions().get(1).getTargetStates().get(0).rawName()).isEqualTo("S3");
|
||||
assertThat(result.getTransitions().get(1).getOrder()).isEqualTo(1);
|
||||
|
||||
assertThat(result.getTransitions().get(2).getTargetStates().get(0).rawName()).isEqualTo("S4");
|
||||
assertThat(result.getTransitions().get(2).getOrder()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNamedArguments() throws IOException {
|
||||
String code = "package click.kamil.test\n" +
|
||||
"\n" +
|
||||
"import org.springframework.statemachine.config.EnableStateMachine\n" +
|
||||
"import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter\n" +
|
||||
"import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer\n" +
|
||||
"\n" +
|
||||
"@EnableStateMachine\n" +
|
||||
"class MyStateMachine : EnumStateMachineConfigurerAdapter<String, String>() {\n" +
|
||||
" override fun configure(transitions: StateMachineTransitionConfigurer<String, String>) {\n" +
|
||||
" transitions.withChoice()\n" +
|
||||
" .source(\"S1\")\n" +
|
||||
" .first(guard = { true }, target = \"S2\")\n" +
|
||||
" .last(target = \"S3\")\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
Path ktFile = tempDir.resolve("MyStateMachine.kt");
|
||||
Files.writeString(ktFile, code);
|
||||
|
||||
KotlinSourceContext context = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
List<AnalysisResult> results = KotlinStateMachineExtractor.extract(context, false);
|
||||
|
||||
assertThat(results).hasSize(1);
|
||||
AnalysisResult result = results.get(0);
|
||||
assertThat(result.getTransitions()).hasSize(2);
|
||||
|
||||
assertThat(result.getTransitions().get(0).getTargetStates().get(0).rawName()).isEqualTo("S2");
|
||||
assertThat(result.getTransitions().get(1).getTargetStates().get(0).rawName()).isEqualTo("S3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstantResolution() throws IOException {
|
||||
String code = "package click.kamil.test\n" +
|
||||
"\n" +
|
||||
"import org.springframework.statemachine.config.EnableStateMachine\n" +
|
||||
"import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter\n" +
|
||||
"import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer\n" +
|
||||
"\n" +
|
||||
"const val TOP_LEVEL_STATE = \"S3\"\n" +
|
||||
"\n" +
|
||||
"@EnableStateMachine\n" +
|
||||
"class MyStateMachine : EnumStateMachineConfigurerAdapter<String, String>() {\n" +
|
||||
" companion object {\n" +
|
||||
" const val STATE_ONE = \"S1\"\n" +
|
||||
" val STATE_TWO = \"S2\"\n" +
|
||||
" }\n" +
|
||||
"\n" +
|
||||
" override fun configure(transitions: StateMachineTransitionConfigurer<String, String>) {\n" +
|
||||
" transitions.withExternal()\n" +
|
||||
" .source(STATE_ONE).target(STATE_TWO).event(\"E1\")\n" +
|
||||
" .and()\n" +
|
||||
" .withExternal()\n" +
|
||||
" .source(STATE_TWO).target(TOP_LEVEL_STATE).event(\"E2\")\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
Path ktFile = tempDir.resolve("MyStateMachine.kt");
|
||||
Files.writeString(ktFile, code);
|
||||
|
||||
KotlinSourceContext context = new KotlinSourceContext(tempDir, Collections.emptyList());
|
||||
List<AnalysisResult> results = KotlinStateMachineExtractor.extract(context, false);
|
||||
|
||||
assertThat(results).hasSize(1);
|
||||
AnalysisResult result = results.get(0);
|
||||
assertThat(result.getTransitions()).hasSize(2);
|
||||
|
||||
var t1 = result.getTransitions().get(0);
|
||||
assertThat(t1.getSourceStates().get(0).rawName()).isEqualTo("S1");
|
||||
assertThat(t1.getTargetStates().get(0).rawName()).isEqualTo("S2");
|
||||
|
||||
var t2 = result.getTransitions().get(1);
|
||||
assertThat(t2.getSourceStates().get(0).rawName()).isEqualTo("S2");
|
||||
assertThat(t2.getTargetStates().get(0).rawName()).isEqualTo("S3");
|
||||
}
|
||||
}
|
||||
17
state_machines/kotlin_simple_state_machine/build.gradle.kts
Normal file
17
state_machines/kotlin_simple_state_machine/build.gradle.kts
Normal file
@@ -0,0 +1,17 @@
|
||||
plugins {
|
||||
kotlin("jvm") version "1.9.22"
|
||||
id("org.springframework.boot") version "3.2.3"
|
||||
id("io.spring.dependency-management") version "1.1.4"
|
||||
}
|
||||
|
||||
group = "click.kamil"
|
||||
version = "1.0-SNAPSHOT"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("org.springframework.statemachine:spring-statemachine-core:3.2.1")
|
||||
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package click.kamil
|
||||
|
||||
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
|
||||
|
||||
enum class OrderState { NEW, PROCESSING, SHIPPED, COMPLETED }
|
||||
enum class OrderEvent { PAY, SHIP, DELIVER }
|
||||
|
||||
@EnableStateMachine
|
||||
class OrderStateMachine : EnumStateMachineConfigurerAdapter<OrderState, OrderEvent>() {
|
||||
|
||||
override fun configure(states: StateMachineStateConfigurer<OrderState, OrderEvent>) {
|
||||
states
|
||||
.withStates()
|
||||
.initial(OrderState.NEW)
|
||||
.states(setOf(OrderState.NEW, OrderState.PROCESSING, OrderState.SHIPPED, OrderState.COMPLETED))
|
||||
}
|
||||
|
||||
override fun configure(transitions: StateMachineTransitionConfigurer<OrderState, OrderEvent>) {
|
||||
transitions
|
||||
.withExternal()
|
||||
.source(OrderState.NEW).target(OrderState.PROCESSING)
|
||||
.event(OrderEvent.PAY)
|
||||
.action { println("Payment received") }
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(OrderState.PROCESSING).target(OrderState.SHIPPED)
|
||||
.event(OrderEvent.SHIP)
|
||||
.guard { true }
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(OrderState.SHIPPED).target(OrderState.COMPLETED)
|
||||
.event(OrderEvent.DELIVER)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user