You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kie.apache.org by pe...@apache.org on 2025/02/27 20:41:55 UTC

(incubator-kie-kogito-runtimes) branch main updated: [Incubator-kie-issues-1790] Enhancing business calendar flexibility (#3850)

This is an automated email from the ASF dual-hosted git repository.

pefernan pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-kogito-runtimes.git


The following commit(s) were added to refs/heads/main by this push:
     new 3bce97e3d2 [Incubator-kie-issues-1790] Enhancing business calendar flexibility (#3850)
3bce97e3d2 is described below

commit 3bce97e3d2af9ee45681bbfdd3412bfa01cc5e81
Author: Abhiram Gundala <16...@users.noreply.github.com>
AuthorDate: Thu Feb 27 15:41:51 2025 -0500

    [Incubator-kie-issues-1790] Enhancing business calendar flexibility (#3850)
    
    * Custom_Calendar
    
    * Custom_Calendar
    
    * Custom_Calendar
    
    * Custom_Calendar
    
    * Custom_Calendar
    
    * Custom_Calendar
    
    * Custom_Calendar
    
    * Custom_Calendar
    
    * Custom_Calendar
    
    * - Adding Unit Test
    - Small adjustments
    
    * - Cleanup
    
    * - Cleanup 2
    
    * - Extra check in ProcessCodegen.java to avoid ambiguities when we have calendar.properties and kogito.processes.businessCalendar at same time
    - Small cleanup
    
    * - Fix test according to previous change, if the build fails compilation unit should stay untouched.
    
    ---------
    
    Co-authored-by: Pere Fernández <pe...@users.noreply.github.com>
---
 .../kie/kogito/codegen/process/ProcessCodegen.java |  61 ++++++---
 .../codegen/process/util/BusinessCalendarUtil.java | 106 +++++++++++++++
 .../BusinessCalendarProducerQuarkusTemplate.java   |   7 +-
 .../BusinessCalendarProducerSpringTemplate.java    |  10 +-
 .../process/util/BusinessCalendarUtilTest.java     | 149 +++++++++++++++++++++
 .../DefaultAccessorCustomBusinessCalendar.java}    |  24 ++--
 .../calendars/AbstractCustomBusinessCalendar.java} |  19 +--
 .../util/calendars/CustomBusinessCalendar.java}    |  24 ++--
 .../CustomBusinessCalendarInterface.java}          |  19 +--
 9 files changed, 339 insertions(+), 80 deletions(-)

diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java
index 20c7189198..fdbb2541c3 100644
--- a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java
+++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java
@@ -21,16 +21,7 @@ package org.kie.kogito.codegen.process;
 import java.io.File;
 import java.io.IOException;
 import java.io.Reader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Stream;
 
 import org.drools.codegen.common.GeneratedFile;
@@ -39,11 +30,7 @@ import org.drools.io.InternalResource;
 import org.jbpm.bpmn2.xml.BPMNDISemanticModule;
 import org.jbpm.bpmn2.xml.BPMNExtensionsSemanticModule;
 import org.jbpm.bpmn2.xml.BPMNSemanticModule;
-import org.jbpm.compiler.canonical.ModelMetaData;
-import org.jbpm.compiler.canonical.ProcessMetaData;
-import org.jbpm.compiler.canonical.ProcessToExecModelGenerator;
-import org.jbpm.compiler.canonical.TriggerMetaData;
-import org.jbpm.compiler.canonical.WorkItemModelMetaData;
+import org.jbpm.compiler.canonical.*;
 import org.jbpm.compiler.xml.XmlProcessReader;
 import org.jbpm.compiler.xml.core.SemanticModules;
 import org.jbpm.process.core.impl.ProcessImpl;
@@ -84,6 +71,8 @@ import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
 import static java.lang.String.format;
 import static java.util.stream.Collectors.toList;
 import static org.jbpm.process.core.constants.CalendarConstants.BUSINESS_CALENDAR_PATH;
+import static org.kie.kogito.codegen.process.util.BusinessCalendarUtil.conditionallyAddCustomBusinessCalendar;
+import static org.kie.kogito.codegen.process.util.CodegenUtil.generatorProperty;
 import static org.kie.kogito.codegen.process.util.CodegenUtil.isTransactionEnabled;
 import static org.kie.kogito.grafana.GrafanaConfigurationWriter.buildDashboardName;
 import static org.kie.kogito.grafana.GrafanaConfigurationWriter.generateOperationalDashboard;
@@ -105,11 +94,13 @@ public class ProcessCodegen extends AbstractGenerator {
     private static final GeneratedFileType PRODUCER_TYPE = GeneratedFileType.of("PRODUCER", GeneratedFileType.Category.SOURCE);
     private static final SemanticModules BPMN_SEMANTIC_MODULES = new SemanticModules();
     public static final String SVG_EXPORT_NAME_EXPRESION = "%s-svg.svg";
+    public static final String CUSTOM_BUSINESS_CALENDAR_PROPERTY = "businessCalendar";
 
     private static final String GLOBAL_OPERATIONAL_DASHBOARD_TEMPLATE = "/grafana-dashboard-template/processes/global-operational-dashboard-template.json";
     private static final String PROCESS_OPERATIONAL_DASHBOARD_TEMPLATE = "/grafana-dashboard-template/processes/process-operational-dashboard-template.json";
     public static final String BUSINESS_CALENDAR_PRODUCER_TEMPLATE = "BusinessCalendarProducer";
     private static final String IS_BUSINESS_CALENDAR_PRESENT = "isBusinessCalendarPresent";
+
     static {
         ProcessValidatorRegistry.getInstance().registerAdditonalValidator(JavaRuleFlowProcessValidator.getInstance());
         BPMN_SEMANTIC_MODULES.addSemanticModule(new BPMNSemanticModule());
@@ -459,11 +450,8 @@ public class ProcessCodegen extends AbstractGenerator {
         staticDependencyInjectionProducerGenerator.generate()
                 .entrySet()
                 .forEach(entry -> storeFile(PRODUCER_TYPE, entry.getKey(), entry.getValue()));
-        Boolean isBusinessCalendarPresent = context().getContextAttribute(IS_BUSINESS_CALENDAR_PRESENT, Boolean.class);
-        if (Objects.nonNull(isBusinessCalendarPresent) && isBusinessCalendarPresent) {
-            staticDependencyInjectionProducerGenerator.generate(List.of(BUSINESS_CALENDAR_PRODUCER_TEMPLATE))
-                    .forEach((key, value) -> storeFile(PRODUCER_TYPE, key, value));
-        }
+
+        generateBusinessCalendarProducer();
 
         if (CodegenUtil.isTransactionEnabled(this, context()) && !isServerless) {
             String template = "ExceptionHandlerTransaction";
@@ -548,7 +536,7 @@ public class ProcessCodegen extends AbstractGenerator {
 
     private void storeFile(GeneratedFileType type, String path, String source) {
         if (generatedFiles.stream().anyMatch(f -> path.equals(f.relativePath()))) {
-            LOGGER.warn("There's already a generated file named {} to be compiled. Ignoring.", path);
+            LOGGER.warn("There is already a generated file named {} to be compiled. Ignoring.", path);
         } else {
             generatedFiles.add(new GeneratedFile(type, path, source));
         }
@@ -556,7 +544,7 @@ public class ProcessCodegen extends AbstractGenerator {
 
     private void storeFile(GeneratedFileType type, String path, byte[] source) {
         if (generatedFiles.stream().anyMatch(f -> path.equals(f.relativePath()))) {
-            LOGGER.warn("There's already a generated file named {} to be compiled. Ignoring.", path);
+            LOGGER.warn("There is already a generated file named {} to be compiled. Ignoring.", path);
         } else {
             generatedFiles.add(new GeneratedFile(type, path, source));
         }
@@ -582,4 +570,33 @@ public class ProcessCodegen extends AbstractGenerator {
     public int priority() {
         return 10;
     }
+
+    private void generateBusinessCalendarProducer() {
+
+        boolean isBusinessCalendarPresent = Optional.ofNullable(context().getContextAttribute(IS_BUSINESS_CALENDAR_PRESENT, Boolean.class)).orElse(false);
+        String businessCalendarClassName = CodegenUtil.getProperty(this, context(), CUSTOM_BUSINESS_CALENDAR_PROPERTY, String::valueOf, null);
+
+        if (isBusinessCalendarPresent && businessCalendarClassName != null) {
+            String message = String.format("Project could not provide both '%s' file and '%s' property.", BUSINESS_CALENDAR_PATH, generatorProperty(this, CUSTOM_BUSINESS_CALENDAR_PROPERTY));
+            throw new ProcessCodegenException(message);
+        }
+
+        if (!isBusinessCalendarPresent && businessCalendarClassName == null) {
+            return;
+        }
+
+        TemplatedGenerator generator = TemplatedGenerator.builder()
+                .withTemplateBasePath("/class-templates/producer/")
+                .withFallbackContext(JavaKogitoBuildContext.CONTEXT_NAME)
+                .withTargetTypeName(BUSINESS_CALENDAR_PRODUCER_TEMPLATE)
+                .build(context(), BUSINESS_CALENDAR_PRODUCER_TEMPLATE);
+
+        CompilationUnit compilationUnit = generator.compilationUnitOrThrow();
+
+        if (businessCalendarClassName != null) {
+            conditionallyAddCustomBusinessCalendar(compilationUnit, context(), businessCalendarClassName);
+        }
+
+        storeFile(PRODUCER_TYPE, generator.generatedFilePath(), compilationUnit.toString());
+    }
 }
diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/util/BusinessCalendarUtil.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/util/BusinessCalendarUtil.java
new file mode 100644
index 0000000000..e93b6eb5f3
--- /dev/null
+++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/util/BusinessCalendarUtil.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.kie.kogito.codegen.process.util;
+
+import java.lang.reflect.Modifier;
+
+import org.kie.kogito.calendar.BusinessCalendar;
+import org.kie.kogito.codegen.api.context.KogitoBuildContext;
+import org.kie.kogito.codegen.process.ProcessCodegenException;
+
+import com.github.javaparser.StaticJavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.Statement;
+
+public class BusinessCalendarUtil {
+
+    public static final String BUSINESS_CALENDAR_FIELD_NAME = "businessCalendar";
+
+    private BusinessCalendarUtil() {
+        // This is a utility class and shouldn't be instantiated.
+    }
+
+    public static void conditionallyAddCustomBusinessCalendar(CompilationUnit compilationUnit, KogitoBuildContext context, String businessCalendarClassName) {
+        validateBusinessCalendarClass(businessCalendarClassName, context);
+
+        Expression expression = getBusinessCalendarCreationExpression(businessCalendarClassName);
+
+        BlockStmt constructorBody = compilationUnit.findFirst(ClassOrInterfaceDeclaration.class)
+                .orElseThrow(() -> new ProcessCodegenException("BusinessCalendarProducer template does not contain a class declaration"))
+                .getDefaultConstructor()
+                .orElseThrow(() -> new ProcessCodegenException("BusinessCalendarProducer template does not contain a default constructor"))
+                .getBody();
+
+        AssignExpr calendarAssignment = getAssignExpression(constructorBody);
+
+        calendarAssignment.setValue(expression);
+    }
+
+    static void validateBusinessCalendarClass(String className, KogitoBuildContext context) {
+        try {
+            if (className == null) {
+                throw new ProcessCodegenException("Custom Business Calendar class cannot be null");
+            }
+
+            Class<? extends BusinessCalendar> businessCalendarClass = context.getClassLoader().loadClass(className).asSubclass(BusinessCalendar.class);
+
+            int mod = businessCalendarClass.getModifiers();
+
+            if (Modifier.isAbstract(mod) || Modifier.isInterface(mod)) {
+                throw new ProcessCodegenException(String.format("Custom Business Calendar class '%s' must be a concrete class", className));
+            }
+
+            if (!Modifier.isPublic(mod)) {
+                throw new ProcessCodegenException(String.format("Custom Business Calendar class '%s' must be a public class", className));
+            }
+        } catch (ClassNotFoundException e) {
+            String message = String.format("Custom Business Calendar class '%s' not found or it is not an instance of '%s'", className, BusinessCalendar.class.getCanonicalName());
+            throw new ProcessCodegenException(message);
+        }
+    }
+
+    static ObjectCreationExpr getBusinessCalendarCreationExpression(String businessCalendarClassName) {
+        return new ObjectCreationExpr(null, StaticJavaParser.parseClassOrInterfaceType(businessCalendarClassName), NodeList.nodeList());
+    }
+
+    static AssignExpr getAssignExpression(BlockStmt constructorBody) {
+        Statement calendarFieldInitStatement = constructorBody.getStatements()
+                .getFirst()
+                .orElseThrow(() -> new ProcessCodegenException("BusinessCalendarProducer constructor does not contain any statements"));
+
+        Node firstNode = calendarFieldInitStatement.getChildNodes().get(0);
+
+        if (!(firstNode instanceof AssignExpr toReturn)) {
+            throw new ProcessCodegenException("BusinessCalendarProducer template does not contain an assign expression");
+        }
+        if (!(toReturn.getTarget().isFieldAccessExpr() && BUSINESS_CALENDAR_FIELD_NAME.equals(toReturn.getTarget().asFieldAccessExpr().getNameAsString()))) {
+            throw new ProcessCodegenException("BusinessCalendarProducer template does not contain a assign expression for businessCalendar field");
+        }
+
+        return toReturn;
+    }
+}
diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java
index ff375187a2..5fcaae8e25 100644
--- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java
+++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java
@@ -28,9 +28,14 @@ import jakarta.enterprise.inject.Produces;
 public class BusinessCalendarProducer {
 
     private static final Logger logger = LoggerFactory.getLogger(BusinessCalendarProducer.class);
+    private BusinessCalendar businessCalendar;
+
+    public BusinessCalendarProducer() {
+        this.businessCalendar = BusinessCalendarImpl.builder().build();
+    }
 
     @Produces
     public BusinessCalendar createBusinessCalendar() {
-        return BusinessCalendarImpl.builder().build();
+        return this.businessCalendar;
     }
 }
\ No newline at end of file
diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerSpringTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerSpringTemplate.java
index 2f0ca351f8..c945771617 100644
--- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerSpringTemplate.java
+++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerSpringTemplate.java
@@ -18,8 +18,8 @@
  */
 package $Package$;
 
-import org.kie.kogito.calendar.BusinessCalendar;
 import org.jbpm.process.core.timer.BusinessCalendarImpl;
+import org.kie.kogito.calendar.BusinessCalendar;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.context.annotation.Bean;
@@ -29,10 +29,14 @@ import org.springframework.context.annotation.Configuration;
 public class BusinessCalendarProducer {
 
     private static final Logger logger = LoggerFactory.getLogger(BusinessCalendarProducer.class);
+    private BusinessCalendar businessCalendar;
+
+    public BusinessCalendarProducer() {
+        this.businessCalendar = BusinessCalendarImpl.builder().build();
+    }
 
     @Bean
     public BusinessCalendar createBusinessCalendar() {
-
-        return BusinessCalendarImpl.builder().build();
+        return this.businessCalendar;
     }
 }
\ No newline at end of file
diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/BusinessCalendarUtilTest.java b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/BusinessCalendarUtilTest.java
new file mode 100644
index 0000000000..59d2f88991
--- /dev/null
+++ b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/BusinessCalendarUtilTest.java
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.kie.kogito.codegen.process.util;
+
+import java.util.List;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.kie.kogito.codegen.api.context.KogitoBuildContext;
+import org.kie.kogito.codegen.api.context.impl.JavaKogitoBuildContext;
+import org.kie.kogito.codegen.api.context.impl.QuarkusKogitoBuildContext;
+import org.kie.kogito.codegen.api.template.TemplatedGenerator;
+import org.kie.kogito.codegen.process.ProcessCodegenException;
+import org.kie.kogito.codegen.process.util.calendars.AbstractCustomBusinessCalendar;
+import org.kie.kogito.codegen.process.util.calendars.CustomBusinessCalendar;
+import org.kie.kogito.codegen.process.util.calendars.CustomBusinessCalendarInterface;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.BlockStmt;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.kie.kogito.codegen.process.ProcessCodegen.BUSINESS_CALENDAR_PRODUCER_TEMPLATE;
+import static org.kie.kogito.codegen.process.util.BusinessCalendarUtil.*;
+
+public class BusinessCalendarUtilTest {
+
+    private KogitoBuildContext context;
+
+    @BeforeEach
+    public void setup() {
+        this.context = QuarkusKogitoBuildContext.builder().build();
+    }
+
+    @Test
+    public void testValidateBusinessCalendarClass() {
+        assertThatThrownBy(() -> validateBusinessCalendarClass(CustomBusinessCalendarInterface.class.getCanonicalName(), context))
+                .isExactlyInstanceOf(ProcessCodegenException.class)
+                .hasMessage("Custom Business Calendar class 'org.kie.kogito.codegen.process.util.calendars.CustomBusinessCalendarInterface' must be a concrete class");
+
+        assertThatThrownBy(() -> validateBusinessCalendarClass(AbstractCustomBusinessCalendar.class.getCanonicalName(), context))
+                .isExactlyInstanceOf(ProcessCodegenException.class)
+                .hasMessage("Custom Business Calendar class 'org.kie.kogito.codegen.process.util.calendars.AbstractCustomBusinessCalendar' must be a concrete class");
+
+        assertThatThrownBy(() -> validateBusinessCalendarClass("this is a totally wrong value", context))
+                .isExactlyInstanceOf(ProcessCodegenException.class)
+                .hasMessage("Custom Business Calendar class 'this is a totally wrong value' not found or it is not an instance of 'org.kie.kogito.calendar.BusinessCalendar'");
+
+        assertThatThrownBy(() -> validateBusinessCalendarClass(null, context))
+                .isExactlyInstanceOf(ProcessCodegenException.class)
+                .hasMessage("Custom Business Calendar class cannot be null");
+
+        assertThatThrownBy(() -> validateBusinessCalendarClass(DefaultAccessorCustomBusinessCalendar.class.getCanonicalName(), context))
+                .isExactlyInstanceOf(ProcessCodegenException.class)
+                .hasMessage("Custom Business Calendar class 'org.kie.kogito.codegen.process.util.DefaultAccessorCustomBusinessCalendar' must be a public class");
+
+        assertThatNoException()
+                .isThrownBy(() -> validateBusinessCalendarClass(CustomBusinessCalendar.class.getCanonicalName(), context));
+    }
+
+    @Test
+    public void testGetBusinessCalendarCreationExpression() {
+        ObjectCreationExpr expression = getBusinessCalendarCreationExpression(CustomBusinessCalendar.class.getCanonicalName()).asObjectCreationExpr();
+
+        assertThat(expression)
+                .isNotNull()
+                .hasFieldOrPropertyWithValue("typeAsString", CustomBusinessCalendar.class.getCanonicalName());
+    }
+
+    @Test
+    public void testConditionallyAddCustomBusinessCalendarWithoutCustomCalendarClassName() {
+        CompilationUnit compilationUnit = getCompilationUnit();
+
+        assertThatThrownBy(() -> conditionallyAddCustomBusinessCalendar(compilationUnit, context, null))
+                .isExactlyInstanceOf(ProcessCodegenException.class)
+                .hasMessage("Custom Business Calendar class cannot be null");
+
+        // This is just to verify that the Compilation unit has not been modified by BusinessCalendarUtil
+        MethodCallExpr expression = new MethodCallExpr(new MethodCallExpr(new NameExpr("BusinessCalendarImpl"), "builder"), "build");
+        assertBusinessCalendarProducerConstructor(compilationUnit, expression);
+    }
+
+    @Test
+    public void testConditionallyAddCustomBusinessCalendar() {
+        CompilationUnit compilationUnit = getCompilationUnit();
+
+        conditionallyAddCustomBusinessCalendar(compilationUnit, context, CustomBusinessCalendar.class.getCanonicalName());
+
+        ObjectCreationExpr expression = getBusinessCalendarCreationExpression(CustomBusinessCalendar.class.getCanonicalName());
+
+        assertBusinessCalendarProducerConstructor(compilationUnit, expression);
+    }
+
+    void assertBusinessCalendarProducerConstructor(CompilationUnit compilationUnit, Expression expectedInitExpression) {
+
+        ClassOrInterfaceDeclaration producerClass = compilationUnit.findFirst(ClassOrInterfaceDeclaration.class).orElseThrow();
+
+        BlockStmt constructorBody = producerClass.getDefaultConstructor()
+                .orElseThrow()
+                .getBody();
+
+        List<Node> nodes = constructorBody.getStatements()
+                .getFirst()
+                .orElseThrow()
+                .getChildNodes();
+
+        assertThat(nodes)
+                .isNotNull()
+                .hasSize(1);
+
+        Node firstNode = nodes.get(0);
+
+        FieldAccessExpr expectedTargetExpression = new FieldAccessExpr(new ThisExpr(), BUSINESS_CALENDAR_FIELD_NAME);
+
+        assertThat(firstNode)
+                .isNotNull()
+                .isInstanceOf(AssignExpr.class)
+                .hasFieldOrPropertyWithValue("target", expectedTargetExpression)
+                .hasFieldOrPropertyWithValue("value", expectedInitExpression);
+    }
+
+    public CompilationUnit getCompilationUnit() {
+        TemplatedGenerator generator = TemplatedGenerator.builder()
+                .withTemplateBasePath("/class-templates/producer/")
+                .withFallbackContext(JavaKogitoBuildContext.CONTEXT_NAME)
+                .withTargetTypeName(BUSINESS_CALENDAR_PRODUCER_TEMPLATE)
+                .build(context, BUSINESS_CALENDAR_PRODUCER_TEMPLATE);
+
+        return generator.compilationUnitOrThrow();
+    }
+}
diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/DefaultAccessorCustomBusinessCalendar.java
similarity index 66%
copy from kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java
copy to kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/DefaultAccessorCustomBusinessCalendar.java
index ff375187a2..710fdde5c1 100644
--- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java
+++ b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/DefaultAccessorCustomBusinessCalendar.java
@@ -16,21 +16,21 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package $Package$;
 
-import org.jbpm.process.core.timer.BusinessCalendarImpl;
-import org.kie.kogito.calendar.BusinessCalendar;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+package org.kie.kogito.codegen.process.util;
 
-import jakarta.enterprise.inject.Produces;
+import java.util.Date;
 
-public class BusinessCalendarProducer {
+import org.kie.kogito.calendar.BusinessCalendar;
 
-    private static final Logger logger = LoggerFactory.getLogger(BusinessCalendarProducer.class);
+class DefaultAccessorCustomBusinessCalendar implements BusinessCalendar {
+    @Override
+    public long calculateBusinessTimeAsDuration(String timeExpression) {
+        return 0;
+    }
 
-    @Produces
-    public BusinessCalendar createBusinessCalendar() {
-        return BusinessCalendarImpl.builder().build();
+    @Override
+    public Date calculateBusinessTimeAsDate(String timeExpression) {
+        return null;
     }
-}
\ No newline at end of file
+}
diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/calendars/AbstractCustomBusinessCalendar.java
similarity index 65%
copy from kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java
copy to kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/calendars/AbstractCustomBusinessCalendar.java
index ff375187a2..e4cfd34bf1 100644
--- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java
+++ b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/calendars/AbstractCustomBusinessCalendar.java
@@ -16,21 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package $Package$;
 
-import org.jbpm.process.core.timer.BusinessCalendarImpl;
-import org.kie.kogito.calendar.BusinessCalendar;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import jakarta.enterprise.inject.Produces;
+package org.kie.kogito.codegen.process.util.calendars;
 
-public class BusinessCalendarProducer {
-
-    private static final Logger logger = LoggerFactory.getLogger(BusinessCalendarProducer.class);
+import org.kie.kogito.calendar.BusinessCalendar;
 
-    @Produces
-    public BusinessCalendar createBusinessCalendar() {
-        return BusinessCalendarImpl.builder().build();
-    }
-}
\ No newline at end of file
+public abstract class AbstractCustomBusinessCalendar implements BusinessCalendar {
+}
diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/calendars/CustomBusinessCalendar.java
similarity index 66%
copy from kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java
copy to kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/calendars/CustomBusinessCalendar.java
index ff375187a2..bb53ef8445 100644
--- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java
+++ b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/calendars/CustomBusinessCalendar.java
@@ -16,21 +16,21 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package $Package$;
 
-import org.jbpm.process.core.timer.BusinessCalendarImpl;
-import org.kie.kogito.calendar.BusinessCalendar;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+package org.kie.kogito.codegen.process.util.calendars;
 
-import jakarta.enterprise.inject.Produces;
+import java.util.Date;
 
-public class BusinessCalendarProducer {
+import org.kie.kogito.calendar.BusinessCalendar;
 
-    private static final Logger logger = LoggerFactory.getLogger(BusinessCalendarProducer.class);
+public class CustomBusinessCalendar implements BusinessCalendar {
+    @Override
+    public long calculateBusinessTimeAsDuration(String timeExpression) {
+        return 0;
+    }
 
-    @Produces
-    public BusinessCalendar createBusinessCalendar() {
-        return BusinessCalendarImpl.builder().build();
+    @Override
+    public Date calculateBusinessTimeAsDate(String timeExpression) {
+        return null;
     }
-}
\ No newline at end of file
+}
diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/calendars/CustomBusinessCalendarInterface.java
similarity index 65%
copy from kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java
copy to kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/calendars/CustomBusinessCalendarInterface.java
index ff375187a2..0a34a360cd 100644
--- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/BusinessCalendarProducerQuarkusTemplate.java
+++ b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/calendars/CustomBusinessCalendarInterface.java
@@ -16,21 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package $Package$;
 
-import org.jbpm.process.core.timer.BusinessCalendarImpl;
-import org.kie.kogito.calendar.BusinessCalendar;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import jakarta.enterprise.inject.Produces;
+package org.kie.kogito.codegen.process.util.calendars;
 
-public class BusinessCalendarProducer {
-
-    private static final Logger logger = LoggerFactory.getLogger(BusinessCalendarProducer.class);
+import org.kie.kogito.calendar.BusinessCalendar;
 
-    @Produces
-    public BusinessCalendar createBusinessCalendar() {
-        return BusinessCalendarImpl.builder().build();
-    }
-}
\ No newline at end of file
+public interface CustomBusinessCalendarInterface extends BusinessCalendar {
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@kie.apache.org
For additional commands, e-mail: commits-help@kie.apache.org