use of org.kie.kogito.codegen.core.CodegenUtils in project kogito-runtimes by kiegroup.
the class ProcessResourceGenerator method generate.
public String generate() {
TemplatedGenerator.Builder templateBuilder = TemplatedGenerator.builder().withFallbackContext(QuarkusKogitoBuildContext.CONTEXT_NAME);
CompilationUnit clazz = templateBuilder.build(context, getRestTemplateName()).compilationUnitOrThrow();
clazz.setPackageDeclaration(process.getPackageName());
clazz.addImport(modelfqcn);
ClassOrInterfaceDeclaration template = clazz.findFirst(ClassOrInterfaceDeclaration.class).orElseThrow(() -> new NoSuchElementException("Compilation unit doesn't contain a class or interface declaration!"));
template.setName(resourceClazzName);
AtomicInteger index = new AtomicInteger(0);
// Generate signals endpoints
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!"));
signalsMap.entrySet().stream().filter(e -> Objects.nonNull(e.getKey())).forEach(entry -> {
String methodName = "signal_" + index.getAndIncrement();
String outputType = modelfqcn;
String signalName = entry.getKey();
String signalType = entry.getValue();
signalTemplate.findAll(MethodDeclaration.class).forEach(md -> {
MethodDeclaration cloned = md.clone();
BlockStmt body = cloned.getBody().get();
if (signalType == null) {
body.findAll(NameExpr.class, nameExpr -> "data".equals(nameExpr.getNameAsString())).forEach(name -> name.replace(new NullLiteralExpr()));
}
template.addMethod(methodName, Keyword.PUBLIC).setType(outputType).setParameters(signalType == null ? NodeList.nodeList(cloned.getParameter(0)) : cloned.getParameters()).setBody(body).setAnnotations(cloned.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);
});
});
});
// security must be applied before user tasks are added to make sure that user task
// endpoints are not security annotated as they should restrict access based on user assignments
securityAnnotated(template);
Map<String, String> typeInterpolations = new HashMap<>();
taskModelFactoryUnit = parse(this.getClass().getResourceAsStream("/class-templates/TaskModelFactoryTemplate.java"));
String taskModelFactorySimpleClassName = ucFirst(ProcessToExecModelGenerator.extractProcessId(processId) + "_" + "TaskModelFactory");
taskModelFactoryUnit.setPackageDeclaration(process.getPackageName());
taskModelFactoryClassName = process.getPackageName() + "." + taskModelFactorySimpleClassName;
ClassOrInterfaceDeclaration taskModelFactoryClass = taskModelFactoryUnit.findFirst(ClassOrInterfaceDeclaration.class).orElseThrow(IllegalStateException::new);
taskModelFactoryClass.setName(taskModelFactorySimpleClassName);
typeInterpolations.put("$TaskModelFactory$", taskModelFactoryClassName);
if (userTasks != null && !userTasks.isEmpty()) {
CompilationUnit userTaskClazz = templateBuilder.build(context, REST_USER_TASK_TEMPLATE_NAME).compilationUnitOrThrow();
ClassOrInterfaceDeclaration userTaskTemplate = userTaskClazz.findFirst(ClassOrInterfaceDeclaration.class).orElseThrow(() -> new NoSuchElementException("Compilation unit doesn't contain a class or interface declaration!"));
MethodDeclaration taskModelFactoryMethod = taskModelFactoryClass.findFirst(MethodDeclaration.class, m -> m.getNameAsString().equals("from")).orElseThrow(IllegalStateException::new);
SwitchStmt switchExpr = taskModelFactoryMethod.getBody().map(b -> b.findFirst(SwitchStmt.class).orElseThrow(IllegalStateException::new)).orElseThrow(IllegalStateException::new);
for (UserTaskModelMetaData userTask : userTasks) {
String methodSuffix = sanitizeName(userTask.getName()) + "_" + index.getAndIncrement();
userTaskTemplate.findAll(MethodDeclaration.class).forEach(md -> {
MethodDeclaration cloned = md.clone();
template.addMethod(cloned.getName() + "_" + methodSuffix, Keyword.PUBLIC).setType(cloned.getType()).setParameters(cloned.getParameters()).setBody(cloned.getBody().get()).setAnnotations(cloned.getAnnotations());
});
template.findAll(StringLiteralExpr.class).forEach(s -> interpolateUserTaskStrings(s, userTask));
template.findAll(ClassOrInterfaceType.class).forEach(c -> interpolateUserTaskTypes(c, userTask));
template.findAll(NameExpr.class).forEach(c -> interpolateUserTaskNameExp(c, userTask));
if (!userTask.isAdHoc()) {
template.findAll(MethodDeclaration.class).stream().filter(md -> md.getNameAsString().equals("signal_" + methodSuffix)).collect(Collectors.toList()).forEach(template::remove);
}
switchExpr.getEntries().add(0, userTask.getModelSwitchEntry());
}
}
typeInterpolations.put("$Clazz$", resourceClazzName);
typeInterpolations.put("$Type$", dataClazzName);
template.findAll(StringLiteralExpr.class).forEach(this::interpolateStrings);
template.findAll(ClassOrInterfaceType.class).forEach(cls -> interpolateTypes(cls, typeInterpolations));
TagResourceGenerator.addTags(clazz, process);
template.findAll(MethodDeclaration.class).forEach(this::interpolateMethods);
if (context.hasDI()) {
template.findAll(FieldDeclaration.class, CodegenUtils::isProcessField).forEach(fd -> context.getDependencyInjectionAnnotator().withNamedInjection(fd, processId));
} else {
template.findAll(FieldDeclaration.class, CodegenUtils::isProcessField).forEach(this::initializeProcessField);
}
// if triggers are not empty remove createResource method as there is another trigger to start process instances
if ((!startable && !dynamic) || !isPublic()) {
Optional<MethodDeclaration> createResourceMethod = template.findFirst(MethodDeclaration.class).filter(md -> md.getNameAsString().equals("createResource_" + processName));
createResourceMethod.ifPresent(template::remove);
}
if (context.hasDI()) {
context.getDependencyInjectionAnnotator().withApplicationComponent(template);
}
enableValidation(template);
template.getMembers().sort(new BodyDeclarationComparator());
return clazz.toString();
}
use of org.kie.kogito.codegen.core.CodegenUtils in project kogito-runtimes by kiegroup.
the class DecisionRestResourceGenerator method generate.
public String generate() {
CompilationUnit clazz = generator.compilationUnitOrThrow("Cannot generate Decision REST Resource");
ClassOrInterfaceDeclaration template = clazz.findFirst(ClassOrInterfaceDeclaration.class).orElseThrow(() -> new NoSuchElementException("Compilation unit doesn't contain a class or interface declaration!"));
template.setName(resourceClazzName);
template.findAll(StringLiteralExpr.class).forEach(this::interpolateStrings);
template.findAll(MethodDeclaration.class).forEach(this::interpolateMethods);
interpolateInputType(template);
interpolateInputData(template);
interpolateExtractContextMethod(template);
modifyDmnMethodForStronglyTyped(template);
chooseMethodForStronglyTyped(template);
if (context.hasDI()) {
template.findAll(FieldDeclaration.class, CodegenUtils::isApplicationField).forEach(fd -> context.getDependencyInjectionAnnotator().withInjection(fd));
} else {
template.findAll(FieldDeclaration.class, CodegenUtils::isApplicationField).forEach(this::initializeApplicationField);
}
MethodDeclaration dmnMethod = template.findAll(MethodDeclaration.class, x -> x.getName().toString().equals("dmn")).get(0);
processOASAnn(dmnMethod, null);
final String dmnMethodUrlPlaceholder = "$dmnMethodUrl$";
template.addMember(cloneForDMNResult(dmnMethod, "dmn_dmnresult", "dmnresult", dmnMethodUrlPlaceholder));
for (DecisionService ds : dmnModel.getDefinitions().getDecisionService()) {
if (ds.getAdditionalAttributes().keySet().stream().anyMatch(qn -> qn.getLocalPart().equals("dynamicDecisionService"))) {
continue;
}
MethodDeclaration clonedMethod = dmnMethod.clone();
processOASAnn(clonedMethod, ds);
String name = CodegenStringUtil.escapeIdentifier("decisionService_" + ds.getName());
clonedMethod.setName(name);
MethodCallExpr evaluateCall = clonedMethod.findFirst(MethodCallExpr.class, x -> x.getNameAsString().equals("evaluateAll")).orElseThrow(TEMPLATE_WAS_MODIFIED);
evaluateCall.setName(new SimpleName("evaluateDecisionService"));
evaluateCall.addArgument(new StringLiteralExpr(ds.getName()));
MethodCallExpr ctxCall = clonedMethod.findFirst(MethodCallExpr.class, x -> x.getNameAsString().equals("ctx")).orElseThrow(TEMPLATE_WAS_MODIFIED);
ctxCall.addArgument(new StringLiteralExpr(ds.getName()));
// insert request path
final String path = ds.getName();
interpolateRequestPath(path, dmnMethodUrlPlaceholder, clonedMethod);
ReturnStmt returnStmt = clonedMethod.findFirst(ReturnStmt.class).orElseThrow(TEMPLATE_WAS_MODIFIED);
if (ds.getOutputDecision().size() == 1) {
MethodCallExpr rewrittenReturnExpr = returnStmt.findFirst(MethodCallExpr.class, mce -> mce.getNameAsString().equals("extractContextIfSucceded") || mce.getNameAsString().equals("extractStronglyTypedContextIfSucceded")).orElseThrow(TEMPLATE_WAS_MODIFIED);
rewrittenReturnExpr.setName("extractSingletonDSIfSucceded");
}
if (context.getAddonsConfig().useMonitoring()) {
addMonitoringToMethod(clonedMethod, ds.getName());
}
template.addMember(clonedMethod);
template.addMember(cloneForDMNResult(clonedMethod, name + "_dmnresult", ds.getName() + "/dmnresult", path));
}
// set the root path for the dmnMethod itself
interpolateRequestPath("", dmnMethodUrlPlaceholder, dmnMethod);
if (context.getAddonsConfig().useMonitoring()) {
addMonitoringImports(clazz);
addMonitoringFields(template);
addExceptionMetricsLogging(clazz, nameURL);
addMonitoringToMethod(dmnMethod, nameURL);
}
template.getMembers().sort(new BodyDeclarationComparator());
return clazz.toString();
}
use of org.kie.kogito.codegen.core.CodegenUtils in project kogito-runtimes by kiegroup.
the class DecisionCloudEventMetaFactoryGenerator method generate.
public String generate() {
CompilationUnit compilationUnit = generator.compilationUnitOrThrow("Cannot generate CloudEventMetaFactory");
ClassOrInterfaceDeclaration classDefinition = compilationUnit.findFirst(ClassOrInterfaceDeclaration.class).orElseThrow(() -> new InvalidTemplateException(generator, "Compilation unit doesn't contain a class or interface declaration!"));
MethodDeclaration templatedBuildMethod = classDefinition.findFirst(MethodDeclaration.class, x -> x.getName().toString().startsWith("buildCloudEventMeta_$methodName$")).orElseThrow(() -> new InvalidTemplateException(generator, "Impossible to find expected buildCloudEventMeta_ method"));
Set<DecisionCloudEventMeta> methodDataList = this.getCloudEventMetaBuilder().build(models);
methodDataList.forEach(methodData -> {
MethodDeclaration builderMethod = templatedBuildMethod.clone();
String methodNameValue = String.format("%s_%s", methodData.getKind().name(), methodData.methodNameChunk);
String builderMethodName = getBuilderMethodName(classDefinition, templatedBuildMethod.getNameAsString(), methodNameValue);
builderMethod.setName(builderMethodName);
Map<String, Expression> expressions = new HashMap<>();
expressions.put("$type$", new StringLiteralExpr(methodData.getType()));
expressions.put("$source$", new StringLiteralExpr(methodData.getSource()));
expressions.put("$kind$", new FieldAccessExpr(new NameExpr(new SimpleName(EventKind.class.getName())), methodData.getKind().name()));
builderMethod.findFirst(MethodCallExpr.class).ifPresent(callExpr -> CodegenUtils.interpolateArguments(callExpr, expressions));
classDefinition.addMember(builderMethod);
});
templatedBuildMethod.remove();
if (context.hasDI()) {
context.getDependencyInjectionAnnotator().withFactoryClass(classDefinition);
classDefinition.findAll(FieldDeclaration.class, CodegenUtils::isConfigBeanField).forEach(fd -> context.getDependencyInjectionAnnotator().withInjection(fd));
classDefinition.findAll(MethodDeclaration.class, x -> x.getName().toString().startsWith("buildCloudEventMeta_")).forEach(md -> context.getDependencyInjectionAnnotator().withFactoryMethod(md));
}
return compilationUnit.toString();
}
Aggregations