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

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


The following commit(s) were added to refs/heads/main by this push:
     new 06d9380f74 [incubator-kie-issues#2048] DMN Model Validation failed - 
Getting Index 0 out of bounds for length 0 (#6413)
06d9380f74 is described below

commit 06d9380f74ce10d0204c8219c72252e2faab73a1
Author: ChinchuAjith <[email protected]>
AuthorDate: Fri Aug 8 14:36:53 2025 +0530

    [incubator-kie-issues#2048] DMN Model Validation failed - Getting Index 0 
out of bounds for length 0 (#6413)
    
    * Fixing index out of bound and Required input not foubd issues
    
    * Fixing review comments
    
    * Fixing review comments
    
    * Adding license header to test dmn files
    
    * unit tests
    
    * Fixing review comments. adding check to verify source and target classes
    
    * removing unused dmn files
---
 .../kie/dmn/core/compiler/UnnamedImportUtils.java  | 48 ++++++++---
 .../dmn/core/compiler/UnnamedImportUtilsTest.java  | 92 ++++++++++++++++++----
 .../DMNv1_3/dmn-validation-rules-dmndi.drl         |  2 +-
 3 files changed, 112 insertions(+), 30 deletions(-)

diff --git 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/UnnamedImportUtils.java
 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/UnnamedImportUtils.java
index e47a6e10a3..5e460cab2e 100644
--- 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/UnnamedImportUtils.java
+++ 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/UnnamedImportUtils.java
@@ -20,12 +20,11 @@ package org.kie.dmn.core.compiler;
 
 import java.util.Collection;
 import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.kie.dmn.api.core.ast.DMNNode;
 import org.kie.dmn.core.impl.DMNModelImpl;
-import org.kie.dmn.model.api.Definitions;
-import org.kie.dmn.model.api.Import;
-import org.kie.dmn.model.api.NamedElement;
+import org.kie.dmn.model.api.*;
 
 /**
  * Class meant to provide helper methods to deal with unnamed model imports
@@ -65,22 +64,45 @@ public class UnnamedImportUtils {
         // incubator-kie-issues#852: The idea is to not treat the anonymous 
models as import, but to "merge" them with original one,
         // Here we try to put all the definitions from the "imported" model 
inside the parent one
         
parentDefinitions.getArtifact().addAll(mergedDefinitions.getArtifact());
-
-        addIfNotPresent(parentDefinitions.getDecisionService(), 
mergedDefinitions.getDecisionService());
-        addIfNotPresent(parentDefinitions.getBusinessContextElement(), 
mergedDefinitions.getBusinessContextElement());
-        addIfNotPresent(parentDefinitions.getDrgElement(), 
mergedDefinitions.getDrgElement());
-        addIfNotPresent(parentDefinitions.getImport(), 
mergedDefinitions.getImport());
-        addIfNotPresent(parentDefinitions.getItemDefinition(), 
mergedDefinitions.getItemDefinition());
+        addIfNotPresent(parentDefinitions.getDecisionService(), 
mergedDefinitions.getDecisionService(), DecisionService.class);
+        addIfNotPresent(parentDefinitions.getBusinessContextElement(), 
mergedDefinitions.getBusinessContextElement(), BusinessContextElement.class);
+        addIfNotPresent(parentDefinitions.getDrgElement(), 
mergedDefinitions.getDrgElement(), DRGElement.class);
+        addIfNotPresent(parentDefinitions.getImport(), 
mergedDefinitions.getImport(), Import.class);
+        addIfNotPresent(parentDefinitions.getItemDefinition(), 
mergedDefinitions.getItemDefinition(), ItemDefinition.class);
         
mergedDefinitions.getChildren().forEach(parentDefinitions::addChildren);
     }
 
-    static <T extends NamedElement> void addIfNotPresent(Collection<T> target, 
Collection<T> source) {
-        source.forEach(sourceElement -> addIfNotPresent(target, 
sourceElement));
+    static <T extends NamedElement> void addIfNotPresent(Collection<T> target, 
Collection<T> source, Class expectedClass) {
+        source.forEach(sourceElement -> {
+            if(!expectedClass.isAssignableFrom(sourceElement.getClass())) {
+                throw new IllegalStateException("type mismatch : " + "Expected 
" + expectedClass.getName() + ", but found " + 
sourceElement.getClass().getName());
+            }
+            addIfNotPresent(target, sourceElement, expectedClass);
+        });
+
     }
 
-    static <T extends NamedElement> void addIfNotPresent(Collection<T> target, 
T source) {
-        if (target.stream().noneMatch(namedElement -> 
Objects.equals(namedElement.getName(), source.getName()))) {
+    static <T extends NamedElement> void addIfNotPresent(Collection<T> target, 
T source, Class expectedClass) {
+        if (checkIfNotPresent(target, source, expectedClass)) {
             target.add(source);
         }
     }
+
+    static <T extends NamedElement> boolean checkIfNotPresent(Collection<T> 
target, T source, Class expectedClass) {
+        for (T namedElement : target) {
+            if(!expectedClass.isAssignableFrom(namedElement.getClass()) ) {
+                throw new IllegalStateException("type mismatch : " + "Expected 
" + expectedClass.getName() + ", but found " + 
namedElement.getClass().getName());
+            }
+            if (Objects.equals(namedElement.getName(), source.getName())) {
+                if (!(namedElement instanceof Import &&
+                        namedElement.getName() != null &&
+                        namedElement.getName().isEmpty())) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+
 }
\ No newline at end of file
diff --git 
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/compiler/UnnamedImportUtilsTest.java
 
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/compiler/UnnamedImportUtilsTest.java
index 34898662b2..043e64a725 100644
--- 
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/compiler/UnnamedImportUtilsTest.java
+++ 
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/compiler/UnnamedImportUtilsTest.java
@@ -25,6 +25,7 @@ import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 
 import org.junit.jupiter.api.Test;
 import org.kie.dmn.api.core.DMNModel;
@@ -32,12 +33,15 @@ import org.kie.dmn.api.core.DMNRuntime;
 import org.kie.dmn.backend.marshalling.v1x.DMNMarshallerFactory;
 import org.kie.dmn.core.impl.DMNModelImpl;
 import org.kie.dmn.core.util.DMNRuntimeUtil;
-import org.kie.dmn.model.api.Definitions;
-import org.kie.dmn.model.api.NamedElement;
+import org.kie.dmn.model.api.*;
+import org.kie.dmn.model.v1_5.TImport;
+import org.kie.dmn.model.v1_5.TInputData;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.kie.dmn.core.compiler.UnnamedImportUtils.addIfNotPresent;
 import static org.kie.dmn.core.compiler.UnnamedImportUtils.isInUnnamedImport;
+import static org.kie.dmn.core.compiler.UnnamedImportUtils.checkIfNotPresent;
 
 class UnnamedImportUtilsTest {
 
@@ -80,11 +84,11 @@ class UnnamedImportUtilsTest {
         try (InputStream is = importedModelFileResource.openStream()) {
             String xml = new String(is.readAllBytes(), StandardCharsets.UTF_8);
             Definitions definitions = 
DMNMarshallerFactory.newDefaultMarshaller().unmarshal(xml);
-            assertThat(definitions.getDecisionService()).allMatch(this::added);
-            
assertThat(definitions.getBusinessContextElement()).allMatch(this::added);
-            assertThat(definitions.getDrgElement()).allMatch(this::added);
-            assertThat(definitions.getImport()).allMatch(this::added);
-            assertThat(definitions.getItemDefinition()).allMatch(this::added);
+            assertThat(definitions.getDecisionService()).allMatch(source -> 
added(source, DecisionService.class));
+            
assertThat(definitions.getBusinessContextElement()).allMatch(source -> 
added(source, BusinessContextElement.class));
+            assertThat(definitions.getDrgElement()).allMatch(source -> 
added(source, DRGElement.class));
+            assertThat(definitions.getImport()).allMatch(source -> 
added(source, Import.class));
+            assertThat(definitions.getItemDefinition()).allMatch(source -> 
added(source, ItemDefinition.class));
         }
     }
 
@@ -100,6 +104,58 @@ class UnnamedImportUtilsTest {
                                     
"valid_models/DMNv1_5/Imported_Model_Unamed.dmn");
     }
 
+    @Test
+    void checkIfNotPresentWithMatchingName() {
+        TInputData targetElement = new TInputData();
+        targetElement.setName("modelName");
+        TInputData sourceElement = new TInputData();
+        sourceElement.setName("modelName");
+        boolean result = 
UnnamedImportUtils.checkIfNotPresent(List.of(targetElement), sourceElement, 
TInputData.class);
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    void checkIfNotPresentWithNonMatchingName() {
+        TInputData targetElement = new TInputData();
+        targetElement.setName("targetName");
+        TInputData sourceElement = new TInputData();
+        sourceElement.setName("sourceName");
+        boolean result = 
UnnamedImportUtils.checkIfNotPresent(List.of(targetElement), sourceElement, 
TInputData.class);
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    void checkIfNotPresentWithNamedImport() {
+        TImport unnamedImport = new TImport();
+        unnamedImport.setName("targetName");
+        TImport source = new TImport();
+        source.setName("sourceName");
+        boolean result = 
UnnamedImportUtils.checkIfNotPresent(List.of(unnamedImport), source, 
TImport.class);
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    void checkIfNotPresentWithEmptyNamedImport() {
+        TImport unnamedImport = new TImport();
+        unnamedImport.setName("");
+        TImport source = new TImport();
+        source.setName("");
+        boolean result = 
UnnamedImportUtils.checkIfNotPresent(List.of(unnamedImport), source, 
TImport.class);
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    void checkIfNotPresentWithDifferentTargetClass() {
+        TInputData targetElement = new TInputData();
+        targetElement.setName("modelName");
+        TImport source = new TImport();
+        source.setName("modelName");
+        assertThatThrownBy(() -> 
UnnamedImportUtils.checkIfNotPresent(List.of(targetElement), source, 
DecisionService.class))
+                .isInstanceOf(IllegalStateException.class)
+                .hasMessageContaining("type mismatch");
+    }
+
+
     private void commonIsInUnnamedImportTrue(String importingModelRef, String 
importedModelRef) {
         final DMNRuntime runtime = 
DMNRuntimeUtil.createRuntimeWithAdditionalResources(importingModelRef,
                                                                                
        this.getClass(),
@@ -136,21 +192,25 @@ class UnnamedImportUtilsTest {
         try (InputStream is = importedModelFileResource.openStream()) {
             String importedXml = new String(is.readAllBytes(), 
StandardCharsets.UTF_8);
             Definitions importedDefinitions = 
DMNMarshallerFactory.newDefaultMarshaller().unmarshal(importedXml);
-            
assertThat(importedDefinitions.getDecisionService()).noneMatch(definition -> 
added(importingDefinitions.getDecisionService(), definition));
-            
assertThat(importedDefinitions.getBusinessContextElement()).noneMatch(definition
 -> added(importingDefinitions.getBusinessContextElement(), definition));
-            
assertThat(importedDefinitions.getDrgElement()).noneMatch(definition -> 
added(importingDefinitions.getDrgElement(), definition));
-            assertThat(importedDefinitions.getImport()).noneMatch(definition 
-> added(importingDefinitions.getImport(), definition));
-            
assertThat(importedDefinitions.getItemDefinition()).noneMatch(definition -> 
added(importingDefinitions.getItemDefinition(), definition));
+            
assertThat(importedDefinitions.getDecisionService()).noneMatch(definition -> 
added(importingDefinitions.getDecisionService(), definition, 
DecisionService.class));
+            
assertThat(importedDefinitions.getBusinessContextElement()).noneMatch(definition
 -> added(importingDefinitions.getBusinessContextElement(), definition, 
BusinessContextElement.class));
+            
assertThat(importedDefinitions.getDrgElement()).noneMatch(definition -> 
added(importingDefinitions.getDrgElement(), definition, DRGElement.class));
+            assertThat(importedDefinitions.getImport()).noneMatch(definition 
-> added(importingDefinitions.getImport(), definition, Import.class));
+            
assertThat(importedDefinitions.getItemDefinition()).noneMatch(definition -> 
added(importingDefinitions.getItemDefinition(), definition, 
ItemDefinition.class));
         }
     }
 
-    private  <T extends NamedElement> boolean added(T source) {
-        return added(new ArrayList<>(), source);
+    private  <T extends NamedElement> boolean added(T source, Class 
expectedClass) {
+        return added(new ArrayList<>(), source, expectedClass);
     }
 
-    private  <T extends NamedElement> boolean added(Collection<T> target, T 
source) {
-        addIfNotPresent(target, source);
+    private  <T extends NamedElement> boolean added(Collection<T> target, T 
source, Class expectedClass) {
+        addIfNotPresent(target, source, expectedClass);
         return target.contains(source);
     }
 
+    private  <T extends NamedElement> boolean checkIfNotPresent(Collection<T> 
target, T source, Class expectedClass) {
+        return UnnamedImportUtils.checkIfNotPresent(target, source, 
expectedClass);
+    }
+
 }
\ No newline at end of file
diff --git 
a/kie-dmn/kie-dmn-validation/src/main/resources/org/kie/dmn/validation/DMNv1_3/dmn-validation-rules-dmndi.drl
 
b/kie-dmn/kie-dmn-validation/src/main/resources/org/kie/dmn/validation/DMNv1_3/dmn-validation-rules-dmndi.drl
index 9f535472de..ffafacec06 100644
--- 
a/kie-dmn/kie-dmn-validation/src/main/resources/org/kie/dmn/validation/DMNv1_3/dmn-validation-rules-dmndi.drl
+++ 
b/kie-dmn/kie-dmn-validation/src/main/resources/org/kie/dmn/validation/DMNv1_3/dmn-validation-rules-dmndi.drl
@@ -102,7 +102,7 @@ when
     $definitions : Definitions($nsContext : nsContext)
     $import : Import(DMNImportsUtil.whichImportType(this) == 
DMNImportsUtil.ImportType.DMN, namespace == $nsContext[$prefix])
     $importDef : Definitions(namespace == $import.namespace) from entry-point 
"DMNImports"
-    $importRelatedDefinitions :  Definitions(drgElement[0].id == $localPart) 
from entry-point "RelatedImports"
+    $importRelatedDefinitions :  Definitions(drgElement.empty == false, 
drgElement[0].id == $localPart) from entry-point "RelatedImports"
     not DRGElement(id == $localPart) from $importDef.drgElement
     not DRGElement(id == $localPart) from $importRelatedDefinitions.drgElement
     not DRGElement(id == $localPart)


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to