use of org.kie.kogito.codegen.core.BodyDeclarationComparator in project kogito-runtimes by kiegroup.
the class CloudEventsResourceGenerator method generate.
/**
* Generates the source code for a CloudEventListenerResource
*
* @return
*/
public String generate() {
final CompilationUnit clazz = generator.compilationUnitOrThrow("Cannot generate CloudEvents REST Resource");
final ClassOrInterfaceDeclaration template = clazz.findFirst(ClassOrInterfaceDeclaration.class).orElseThrow(() -> new NoSuchElementException("Compilation unit doesn't contain a class or interface declaration!"));
template.getMembers().sort(new BodyDeclarationComparator());
return clazz.toString();
}
use of org.kie.kogito.codegen.core.BodyDeclarationComparator in project kogito-runtimes by kiegroup.
the class MessageConsumerGenerator method generate.
public String generate() {
ClassOrInterfaceDeclaration template = clazz.findFirst(ClassOrInterfaceDeclaration.class).orElseThrow(() -> new InvalidTemplateException(generator, "Cannot find class declaration"));
generateModelMethods(template);
template.setName(resourceClazzName);
template.findAll(ConstructorDeclaration.class).forEach(cd -> cd.setName(resourceClazzName));
template.findAll(ClassOrInterfaceType.class).forEach(cls -> interpolateTypes(cls, dataClazzName));
template.findAll(StringLiteralExpr.class).forEach(str -> str.setString(str.asString().replace("$ProcessName$", processName)));
template.findAll(StringLiteralExpr.class).forEach(str -> str.setString(str.asString().replace("$Trigger$", trigger.getName())));
template.findAll(ClassOrInterfaceType.class).forEach(t -> t.setName(t.getNameAsString().replace("$DataType$", trigger.getDataType())));
template.findAll(MethodCallExpr.class).forEach(this::interpolateStrings);
// legacy: force initialize fields
if (!context.hasDI()) {
template.findAll(FieldDeclaration.class, fd -> isProcessField(fd)).forEach(fd -> initializeProcessField(fd));
template.findAll(FieldDeclaration.class, fd -> isApplicationField(fd)).forEach(fd -> initializeApplicationField(fd));
template.findAll(FieldDeclaration.class, fd -> isObjectMapperField(fd)).forEach(fd -> initializeObjectMapperField(fd));
}
template.getMembers().sort(new BodyDeclarationComparator());
return clazz.toString();
}
use of org.kie.kogito.codegen.core.BodyDeclarationComparator in project kogito-runtimes by kiegroup.
the class MessageProducerGenerator method generate.
public String generate() {
ClassOrInterfaceDeclaration template = clazz.findFirst(ClassOrInterfaceDeclaration.class).orElseThrow(() -> new InvalidTemplateException(generator, "Cannot find class declaration"));
template.setName(resourceClazzName);
template.findAll(ConstructorDeclaration.class).forEach(cd -> cd.setName(resourceClazzName));
template.findAll(ClassOrInterfaceType.class).forEach(cls -> CodegenUtils.interpolateTypes(cls, trigger.getDataType()));
template.findAll(StringLiteralExpr.class).forEach(str -> str.setString(str.asString().replace("$Trigger$", trigger.getName())));
template.findAll(StringLiteralExpr.class).forEach(str -> str.setString(str.asString().replace("$ClassName$", resourceClazzName)));
template.findAll(ClassOrInterfaceType.class).forEach(t -> t.setName(t.getNameAsString().replace("$DataType$", trigger.getDataType())));
template.findAll(StringLiteralExpr.class).forEach(s -> s.setString(s.getValue().replace("$channel$", trigger.getName())));
template.getMembers().sort(new BodyDeclarationComparator());
return clazz.toString();
}
use of org.kie.kogito.codegen.core.BodyDeclarationComparator in project kogito-runtimes by kiegroup.
the class ProcessGenerator method classDeclaration.
public ClassOrInterfaceDeclaration classDeclaration() {
ClassOrInterfaceDeclaration cls = new ClassOrInterfaceDeclaration().setName(targetTypeName).setModifiers(Modifier.Keyword.PUBLIC);
ProcessMetaData processMetaData = processExecutable.generate();
ConstructorDeclaration constructor = getConstructorDeclaration().addParameter(appCanonicalName, APPLICATION);
MethodCallExpr handlersCollection = new MethodCallExpr(new NameExpr("java.util.Arrays"), "asList");
MethodCallExpr superMethod = new MethodCallExpr(null, "super").addArgument(new NameExpr(APPLICATION)).addArgument(handlersCollection);
if (context.getAddonsConfig().usePersistence()) {
constructor.addParameter(ProcessInstancesFactory.class.getCanonicalName(), FACTORY);
superMethod.addArgument(new NameExpr(FACTORY));
}
constructor.setBody(new BlockStmt().addStatement(superMethod).addStatement(new MethodCallExpr("activate")));
if (context.hasDI()) {
context.getDependencyInjectionAnnotator().withNamedApplicationComponent(cls, process.getId());
context.getDependencyInjectionAnnotator().withEagerStartup(cls);
context.getDependencyInjectionAnnotator().withInjection(constructor);
}
Map<String, CompilationUnit> handlers = processMetaData.getGeneratedHandlers();
if (!handlers.isEmpty()) {
MethodCallExpr initMethodCall = new MethodCallExpr(null, "this").addArgument(new NameExpr(APPLICATION));
ConstructorDeclaration decl = getConstructorDeclaration().addParameter(appCanonicalName, APPLICATION).setBody(new BlockStmt().addStatement(initMethodCall));
if (context.getAddonsConfig().usePersistence()) {
initMethodCall.addArgument(new NameExpr(FACTORY));
decl.addParameter(ProcessInstancesFactory.class.getCanonicalName(), FACTORY);
}
cls.addMember(decl);
for (Entry<String, CompilationUnit> handler : handlers.entrySet()) {
String varName = handler.getKey().substring(handler.getKey().lastIndexOf('.') + 1);
varName = Character.toLowerCase(varName.charAt(0)) + varName.substring(1);
ClassOrInterfaceDeclaration handlerClazz = handler.getValue().findFirst(ClassOrInterfaceDeclaration.class).orElseThrow(() -> new NoSuchElementException("Compilation unit doesn't contain a method declaration!"));
String clazzName = handler.getValue().getPackageDeclaration().map(pd -> pd.getName().toString() + '.' + handlerClazz.getName()).orElse(handlerClazz.getName().asString());
ClassOrInterfaceType clazzNameType = parseClassOrInterfaceType(clazzName);
Parameter parameter = new Parameter(clazzNameType, varName);
if (context.hasDI()) {
context.getDependencyInjectionAnnotator().withApplicationComponent(handlerClazz);
context.getDependencyInjectionAnnotator().withOptionalInjection(handlerClazz.getConstructors().stream().filter(c -> !c.getParameters().isEmpty()).findFirst().orElseThrow(() -> new IllegalStateException("Cannot find a non empty constructor to annotate in handler class " + handlerClazz)));
}
initMethodCall.addArgument(new ObjectCreationExpr(null, clazzNameType, NodeList.nodeList()));
constructor.addParameter(parameter);
handlersCollection.addArgument(new NameExpr(varName));
additionalClasses.add(handler.getValue());
}
}
String processInstanceFQCN = ProcessInstanceGenerator.qualifiedName(packageName, typeName);
cls.addExtendedType(abstractProcessType(modelTypeName)).addMember(constructor).addMember(getConstructorDeclaration()).addMember(createInstanceMethod(processInstanceFQCN)).addMember(createInstanceWithBusinessKeyMethod(processInstanceFQCN)).addMember(new MethodDeclaration().addModifier(Keyword.PUBLIC).setName(CREATE_MODEL).setType(modelTypeName).addAnnotation(Override.class).setBody(new BlockStmt().addStatement(new ReturnStmt(new ObjectCreationExpr(null, new ClassOrInterfaceType(null, modelTypeName), NodeList.nodeList()))))).addMember(createInstanceGenericMethod(processInstanceFQCN)).addMember(createInstanceGenericWithBusinessKeyMethod(processInstanceFQCN)).addMember(createInstanceGenericWithWorkflowInstanceMethod(processInstanceFQCN)).addMember(createReadOnlyInstanceGenericWithWorkflowInstanceMethod(processInstanceFQCN)).addMember(process(processMetaData));
internalConfigure(processMetaData).ifPresent(cls::addMember);
internalRegisterListeners(processMetaData).ifPresent(cls::addMember);
if (!processMetaData.getSubProcesses().isEmpty()) {
for (Entry<String, String> subProcess : processMetaData.getSubProcesses().entrySet()) {
FieldDeclaration subprocessFieldDeclaration = new FieldDeclaration();
String fieldName = "process" + subProcess.getKey();
ClassOrInterfaceType modelType = new ClassOrInterfaceType(null, new SimpleName(org.kie.kogito.process.Process.class.getCanonicalName()), NodeList.nodeList(new ClassOrInterfaceType(null, StringUtils.ucFirst(subProcess.getKey() + "Model"))));
if (context.hasDI()) {
subprocessFieldDeclaration.addVariable(new VariableDeclarator(modelType, fieldName));
context.getDependencyInjectionAnnotator().withInjection(subprocessFieldDeclaration);
} else {
// app.get(org.kie.kogito.process.Processes.class).processById()
MethodCallExpr initSubProcessField = new MethodCallExpr(new MethodCallExpr(new NameExpr(APPLICATION), "get").addArgument(new ClassExpr().setType(Processes.class.getCanonicalName())), "processById").addArgument(new StringLiteralExpr(subProcess.getKey()));
subprocessFieldDeclaration.addVariable(new VariableDeclarator(modelType, fieldName));
constructor.getBody().addStatement(new AssignExpr(new FieldAccessExpr(new ThisExpr(), fieldName), new CastExpr(modelType, initSubProcessField), Operator.ASSIGN));
}
cls.addMember(subprocessFieldDeclaration);
}
}
if (!processMetaData.getTriggers().isEmpty()) {
for (TriggerMetaData trigger : processMetaData.getTriggers()) {
// add message produces as field
if (trigger.getType().equals(TriggerMetaData.TriggerType.ProduceMessage)) {
String producerFieldType = packageName + "." + typeName + "MessageProducer_" + trigger.getOwnerId();
String producerFieldName = "producer_" + trigger.getOwnerId();
FieldDeclaration producerFieldDeclaration = new FieldDeclaration().addVariable(new VariableDeclarator(new ClassOrInterfaceType(null, producerFieldType), producerFieldName));
cls.addMember(producerFieldDeclaration);
if (context.hasDI()) {
context.getDependencyInjectionAnnotator().withInjection(producerFieldDeclaration);
} else {
AssignExpr assignExpr = new AssignExpr(new FieldAccessExpr(new ThisExpr(), producerFieldName), new ObjectCreationExpr().setType(producerFieldType), AssignExpr.Operator.ASSIGN);
cls.getConstructors().forEach(c -> c.getBody().addStatement(assignExpr));
}
}
}
}
cls.getMembers().sort(new BodyDeclarationComparator());
return cls;
}
use of org.kie.kogito.codegen.core.BodyDeclarationComparator 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));
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();
}
Aggregations