public ClassOrInterfaceDeclaration classDeclaration()

in kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessGenerator.java [369:548]


    public ClassOrInterfaceDeclaration classDeclaration() {
        ClassOrInterfaceDeclaration cls = new ClassOrInterfaceDeclaration()
                .setName(targetTypeName)
                .setModifiers(Modifier.Keyword.PUBLIC);
        ProcessMetaData processMetaData = processExecutable.generate();

        ConstructorDeclaration constructor = getConstructorDeclaration()
                .addParameter(appCanonicalName, APPLICATION)
                .addParameter(CorrelationService.class.getCanonicalName(), CORRELATIONS);

        MethodCallExpr handlersCollection = new MethodCallExpr(new NameExpr("java.util.Arrays"), "asList");
        MethodCallExpr superMethod = new MethodCallExpr(null, "super")
                .addArgument(new NameExpr(APPLICATION))
                .addArgument(handlersCollection)
                .addArgument(new NameExpr(CORRELATIONS));

        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))
                    .addArgument(new NameExpr(CORRELATIONS));

            ConstructorDeclaration decl = getConstructorDeclaration()
                    .addParameter(appCanonicalName, APPLICATION)
                    .addParameter(CorrelationService.class.getCanonicalName(), CORRELATIONS)
                    .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()
                            .withInjection(
                                    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(createInstanceWithCorrelationMethod(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, processMetaData.getModelPackageName() != null ? processMetaData.getModelPackageName() + "." + processMetaData.getModelClassName()
                                        : sanitizeClassName(subProcess.getKey() + "Model"))));
                if (context.hasDI()) {
                    subprocessFieldDeclaration
                            .addVariable(new VariableDeclarator(modelType, fieldName));
                    context.getDependencyInjectionAnnotator().withNamedInjection(subprocessFieldDeclaration, subProcess.getValue());
                } 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;
    }