in kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java [265:362]
protected void generateSignalsEndpoints(TemplatedGenerator.Builder templateBuilder,
ClassOrInterfaceDeclaration template, AtomicInteger index) {
Optional.ofNullable(signals)
.ifPresent(signalsMap -> {
//using template class to the endpoints generation
CompilationUnit signalClazz = templateBuilder.build(context, REST_SIGNAL_TEMPLATE_NAME)
.compilationUnitOrThrow();
ClassOrInterfaceDeclaration signalTemplate = signalClazz
.findFirst(ClassOrInterfaceDeclaration.class)
.orElseThrow(() -> new NoSuchElementException("SignalResourceTemplate class not found!"));
MethodDeclaration signalProcessDeclaration = signalTemplate
.findFirst(MethodDeclaration.class, md -> md.getNameAsString().equals("signalProcess"))
.orElseThrow(() -> new NoSuchElementException("signalProcess method not found in SignalResourceTemplate"));
MethodDeclaration signalInstanceDeclaration = signalTemplate
.findFirst(MethodDeclaration.class, md -> md.getNameAsString().equals("signalInstance"))
.orElseThrow(() -> new NoSuchElementException("signalInstance method not found in SignalResourceTemplate"));
Collection<TriggerMetaData> startSignalTriggers = getStartSignalTriggers();
signalsMap.entrySet()
.stream()
.filter(e -> Objects.nonNull(e.getKey()))
.forEach(entry -> {
String signalName = entry.getKey();
String signalType = entry.getValue();
// Looking if the Process starts with the current signal
Optional<TriggerMetaData> startTrigger = startSignalTriggers.stream()
.filter(trigger -> trigger.getName().equals(signalName))
.findAny();
startTrigger.ifPresent(trigger -> {
// Create endpoint to signal the process container to start new instances
MethodDeclaration signalProcessDeclarationClone = signalProcessDeclaration.clone();
BlockStmt signalProcessBody = signalProcessDeclarationClone.getBody()
.orElseThrow(() -> new RuntimeException("signalProcessDeclaration doesn't have body"));
MethodCallExpr setterMethod = signalProcessBody.findAll(MethodCallExpr.class, m -> m.getName().getIdentifier().contains("$SetModelMethodName$"))
.stream()
.findFirst()
.orElseThrow(() -> new RuntimeException("signalProcessDeclaration doesn't have model setter"));
if (signalType == null) {
// if there's no type we should remove the payload references form the method declaration and body
signalProcessDeclarationClone.getParameters()
.stream()
.filter(parameter -> parameter.getNameAsString().equals("data"))
.findFirst()
.ifPresent(Parameter::removeForced);
setterMethod.removeForced();
} else {
String name = Optional.ofNullable((String) trigger.getNode().getMetaData().get(Metadata.MAPPING_VARIABLE)).orElseGet(trigger::getModelRef);
setterMethod.setName(setterMethod.getNameAsString().replace("$SetModelMethodName$", StringUtils.ucFirst(name)));
}
template.addMethod(SIGNAL_METHOD_PREFFIX + signalName, Keyword.PUBLIC)
.setType(signalProcessDeclarationClone.getType())
.setParameters(signalProcessDeclarationClone.getParameters())
.setBody(signalProcessBody)
.setAnnotations(signalProcessDeclarationClone.getAnnotations());
});
// Create endpoint to signal process instances
MethodDeclaration signalInstanceDeclarationClone = signalInstanceDeclaration.clone();
BlockStmt signalInstanceBody = signalInstanceDeclarationClone.getBody()
.orElseThrow(() -> new RuntimeException("signalInstanceDeclaration doesn't have body"));
if (signalType == null) {
signalInstanceBody.findAll(NameExpr.class, nameExpr -> "data".equals(nameExpr.getNameAsString())).forEach(name -> name.replace(new NullLiteralExpr()));
}
template.addMethod(SIGNAL_METHOD_PREFFIX + index.getAndIncrement(), Keyword.PUBLIC)
.setType(signalInstanceDeclarationClone.getType())
// Remove data parameter ( payload ) if signalType is null
.setParameters(signalType == null ? NodeList.nodeList(signalInstanceDeclarationClone.getParameter(0)) : signalInstanceDeclaration.getParameters())
.setBody(signalInstanceBody)
.setAnnotations(signalInstanceDeclarationClone.getAnnotations());
if (signalType != null) {
template.findAll(ClassOrInterfaceType.class).forEach(name -> {
String identifier = name.getNameAsString();
name.setName(identifier.replace("$signalType$", signalType));
});
}
template.findAll(StringLiteralExpr.class).forEach(vv -> {
String s = vv.getValue();
String interpolated = s.replace("$signalName$", signalName);
interpolated = interpolated.replace("$signalPath$", sanitizeName(signalName));
vv.setString(interpolated);
});
});
});
}