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

mariofusco 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 e04f4bed64 This enables validation that all fact types used in rules 
have proper (#6524)
e04f4bed64 is described below

commit e04f4bed645721129a330e2bbd43ed0a21ac681f
Author: Toni Rikkola <[email protected]>
AuthorDate: Thu Nov 27 16:14:26 2025 +0200

    This enables validation that all fact types used in rules have proper 
(#6524)
    
    declare statements and that field references match declared fields.
    
    Co-authored-by: Claude <[email protected]>
---
 .../verifier/builder/ScopesAgendaFilter.java       |   2 +
 .../org/drools/verifier/components/Definition.java | 123 +++++++++++++++
 .../verifier/components/LiteralRestriction.java    |  12 +-
 .../verifier/components/VerifierComponentType.java |   1 +
 .../visitor/ExprConstraintDescrVisitor.java        |   1 +
 .../visitor/FieldConstraintDescrVisitor.java       |   1 +
 .../verifier/visitor/PackageDescrVisitor.java      |   2 +-
 .../visitor/TypeDeclarationDescrVisitor.java       |  10 +-
 .../definition/DefinitionValidationTest.java       | 166 +++++++++++++++++++++
 .../definition/DefinitionValidationTest.drl        |  59 ++++++++
 .../definition/DefinitionVerificationRules.drl     | 152 +++++++++++++++++++
 .../verifier/definition/MissingDefinitionTest.drl  |  46 ++++++
 .../definition/UndefinedFieldUsageTest.drl         |  51 +++++++
 13 files changed, 623 insertions(+), 3 deletions(-)

diff --git 
a/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/builder/ScopesAgendaFilter.java
 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/builder/ScopesAgendaFilter.java
index f3e28c31dd..96aa2672e7 100644
--- 
a/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/builder/ScopesAgendaFilter.java
+++ 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/builder/ScopesAgendaFilter.java
@@ -32,6 +32,7 @@ public class ScopesAgendaFilter
     public final static String             VERIFYING_SCOPE_SINGLE_RULE       = 
"single-rule";
     public final static String             VERIFYING_SCOPE_DECISION_TABLE    = 
"decision-table";
     public final static String             VERIFYING_SCOPE_KNOWLEDGE_PACKAGE = 
"knowledge-package";
+    public final static String             VERIFYING_SCOPE_DEFINITION_CHECK  = 
"definition-check";
 
     public final static Collection<String> ALL_SCOPES                        = 
new ArrayList<String>() {
 
@@ -41,6 +42,7 @@ public class ScopesAgendaFilter
                                                                                
      add( VERIFYING_SCOPE_DECISION_TABLE );
                                                                                
      add( VERIFYING_SCOPE_SINGLE_RULE );
                                                                                
      add( VERIFYING_SCOPE_KNOWLEDGE_PACKAGE );
+                                                                               
      add( VERIFYING_SCOPE_DEFINITION_CHECK );
                                                                                
  }
                                                                              };
 
diff --git 
a/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/components/Definition.java
 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/components/Definition.java
new file mode 100644
index 0000000000..3335b957ad
--- /dev/null
+++ 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/components/Definition.java
@@ -0,0 +1,123 @@
+/*
+ * 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.drools.verifier.components;
+
+import org.drools.drl.ast.descr.TypeDeclarationDescr;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class Definition extends PackageComponent<TypeDeclarationDescr> {
+
+    private String typeName;
+    private String superTypeName;
+    private Map<String, Object> metadata = new HashMap<>();
+    private Map<String, String> declaredFields = new HashMap<>();
+
+    public Definition(TypeDeclarationDescr descr, RulePackage rulePackage) {
+        super(descr, rulePackage);
+        this.typeName = descr.getTypeName();
+        this.superTypeName = descr.getSuperTypeName();
+        initializeDeclaredFields(descr);
+    }
+
+    protected Definition(TypeDeclarationDescr descr, String packageName) {
+        super(descr, packageName);
+        this.typeName = descr.getTypeName();
+        this.superTypeName = descr.getSuperTypeName();
+        initializeDeclaredFields(descr);
+    }
+
+    private void initializeDeclaredFields(TypeDeclarationDescr descr) {
+        if (descr.getFields() != null) {
+            for (String fieldName : descr.getFields().keySet()) {
+                String fieldType = 
descr.getFields().get(fieldName).getPattern().getObjectType();
+                this.declaredFields.put(fieldName, fieldType);
+            }
+        }
+    }
+
+    @Override
+    public String getPath() {
+        return String.format("%s/definition[@name='%s']", 
+                           getPackagePath(), 
+                           getTypeName());
+    }
+
+    @Override
+    public VerifierComponentType getVerifierComponentType() {
+        return VerifierComponentType.DEFINITION;
+    }
+
+    public String getTypeName() {
+        return typeName;
+    }
+
+    public void setTypeName(String typeName) {
+        this.typeName = typeName;
+    }
+
+    public String getSuperTypeName() {
+        return superTypeName;
+    }
+
+    public void setSuperTypeName(String superTypeName) {
+        this.superTypeName = superTypeName;
+    }
+
+    public Map<String, Object> getMetadata() {
+        return metadata;
+    }
+
+    public void setMetadata(Map<String, Object> metadata) {
+        this.metadata = metadata;
+    }
+
+    public Map<String, String> getDeclaredFields() {
+        return declaredFields;
+    }
+
+    public void setDeclaredFields(Map<String, String> declaredFields) {
+        this.declaredFields = declaredFields;
+    }
+
+    public boolean hasField(String fieldName) {
+        return declaredFields.containsKey(fieldName);
+    }
+
+    public String getFieldType(String fieldName) {
+        return declaredFields.get(fieldName);
+    }
+
+    public Set<String> getFieldNames() {
+        return declaredFields.keySet();
+    }
+
+    @Override
+    public String toString() {
+        return "Definition{" +
+                "typeName='" + typeName + '\'' +
+                ", packageName='" + getPackageName() + '\'' +
+                ", superTypeName='" + superTypeName + '\'' +
+                ", declaredFields=" + declaredFields +
+                '}';
+    }
+}
\ No newline at end of file
diff --git 
a/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/components/LiteralRestriction.java
 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/components/LiteralRestriction.java
index 0eb0c49db8..1ecfe96fb8 100644
--- 
a/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/components/LiteralRestriction.java
+++ 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/components/LiteralRestriction.java
@@ -29,12 +29,14 @@ public abstract class LiteralRestriction extends Restriction
     implements
     Cause {
 
+    private String fieldName;
+
     public LiteralRestriction(Pattern pattern) {
         super( pattern );
     }
 
     public RestrictionType getRestrictionType() {
-        return Restriction.RestrictionType.LITERAL;
+        return RestrictionType.LITERAL;
     }
 
     public abstract String getValueAsString();
@@ -96,4 +98,12 @@ public abstract class LiteralRestriction extends Restriction
     public String toString() {
         return "LiteralRestriction from rule [" + getRuleName() + "] value '" 
+ operator.getOperatorString() + " " + getValueAsString() + "'";
     }
+
+    public void setFieldName(String fieldName) {
+        this.fieldName = fieldName;
+    }
+
+    public String getFieldName() {
+        return fieldName;
+    }
 }
diff --git 
a/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/components/VerifierComponentType.java
 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/components/VerifierComponentType.java
index 7949fb3dfb..ea0740bcf6 100644
--- 
a/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/components/VerifierComponentType.java
+++ 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/components/VerifierComponentType.java
@@ -49,6 +49,7 @@ public class VerifierComponentType
     public static final VerifierComponentType ENTRY_POINT_DESCR = new 
VerifierComponentType("entryPointDescr");
     public static final VerifierComponentType WORKING_MEMORY = new 
VerifierComponentType("workingMemory");
     public static final VerifierComponentType IMPORT = new 
VerifierComponentType("import");
+    public static final VerifierComponentType DEFINITION = new 
VerifierComponentType("definition");
     public static final VerifierComponentType FIELD_LEVEL_VARIABLE = new 
VerifierComponentType("fieldLevelVariable");
 
     private final String type;
diff --git 
a/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/ExprConstraintDescrVisitor.java
 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/ExprConstraintDescrVisitor.java
index 4c2b1d1d07..afbb01407e 100644
--- 
a/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/ExprConstraintDescrVisitor.java
+++ 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/ExprConstraintDescrVisitor.java
@@ -88,6 +88,7 @@ public class ExprConstraintDescrVisitor {
     private void createRestriction(int currentOrderNumber, String value, 
Operator operator) {
         LiteralRestriction restriction = 
LiteralRestriction.createRestriction(pattern, value);
         restriction.setFieldPath(field.getPath());
+        restriction.setFieldName(field.getName());
         restriction.setPatternIsNot(pattern.isPatternNot());
         restriction.setParentPath(pattern.getPath());
         restriction.setParentType(pattern.getVerifierComponentType());
diff --git 
a/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/FieldConstraintDescrVisitor.java
 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/FieldConstraintDescrVisitor.java
index 7f24d185be..4950e78f77 100644
--- 
a/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/FieldConstraintDescrVisitor.java
+++ 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/FieldConstraintDescrVisitor.java
@@ -138,6 +138,7 @@ public class FieldConstraintDescrVisitor {
 
         restriction.setPatternIsNot(pattern.isPatternNot());
         restriction.setFieldPath(field.getPath());
+        restriction.setFieldName(field.getName());
         
restriction.setOperator(Operator.determineOperator(descr.getEvaluator(),
                 descr.isNegated()));
         restriction.setOrderNumber(orderNumber);
diff --git 
a/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/PackageDescrVisitor.java
 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/PackageDescrVisitor.java
index eb45173a22..e5b2d6aa12 100644
--- 
a/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/PackageDescrVisitor.java
+++ 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/PackageDescrVisitor.java
@@ -59,7 +59,7 @@ public class PackageDescrVisitor {
 
         visitImports(descr.getImports());
 
-        TypeDeclarationDescrVisitor typeDeclarationDescrVisitor = new 
TypeDeclarationDescrVisitor(data);
+        TypeDeclarationDescrVisitor typeDeclarationDescrVisitor = new 
TypeDeclarationDescrVisitor(data, rulePackage);
         typeDeclarationDescrVisitor.visit(descr.getTypeDeclarations());
 
         visitRules(descr.getRules());
diff --git 
a/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/TypeDeclarationDescrVisitor.java
 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/TypeDeclarationDescrVisitor.java
index 03b25cadc2..7b1eed453a 100644
--- 
a/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/TypeDeclarationDescrVisitor.java
+++ 
b/drools-verifier/drools-verifier-drl/src/main/java/org/drools/verifier/visitor/TypeDeclarationDescrVisitor.java
@@ -20,9 +20,11 @@ package org.drools.verifier.visitor;
 
 import org.drools.drl.ast.descr.AnnotationDescr;
 import org.drools.drl.ast.descr.TypeDeclarationDescr;
+import org.drools.verifier.components.Definition;
 import org.drools.verifier.components.Field;
 import org.drools.verifier.components.Import;
 import org.drools.verifier.components.ObjectType;
+import org.drools.verifier.components.RulePackage;
 import org.drools.verifier.data.VerifierData;
 
 import java.util.List;
@@ -31,13 +33,18 @@ import java.util.Map;
 public class TypeDeclarationDescrVisitor {
 
     private final VerifierData data;
+    private final RulePackage rulePackage;
 
-    public TypeDeclarationDescrVisitor(VerifierData data) {
+    public TypeDeclarationDescrVisitor(VerifierData data, RulePackage 
rulePackage) {
         this.data = data;
+        this.rulePackage = rulePackage;
     }
 
     public void visit(List<TypeDeclarationDescr> typeDeclarationDescrs) {
         for (TypeDeclarationDescr typeDeclaration : typeDeclarationDescrs) {
+            // Create Definition component for DRL type definitions
+            Definition definition = new Definition(typeDeclaration, 
rulePackage);
+            data.add(definition);
             Import objectImport = 
data.getImportByName(typeDeclaration.getTypeName());
             String objectTypeName;
             if (objectImport == null) {
@@ -71,6 +78,7 @@ public class TypeDeclarationDescrVisitor {
                 Map<String, Object> values = 
typeDeclaration.getAnnotation(annDescr.getName()).getValueMap();
                 for (String value : values.keySet()) {
                     objectType.getMetadata().put(annDescr.getName(), value);
+                    definition.getMetadata().put(annDescr.getName(), 
values.get(value));
                 }
             }
         }
diff --git 
a/drools-verifier/drools-verifier-drl/src/test/java/org/drools/verifier/definition/DefinitionValidationTest.java
 
b/drools-verifier/drools-verifier-drl/src/test/java/org/drools/verifier/definition/DefinitionValidationTest.java
new file mode 100644
index 0000000000..777a0af3b4
--- /dev/null
+++ 
b/drools-verifier/drools-verifier-drl/src/test/java/org/drools/verifier/definition/DefinitionValidationTest.java
@@ -0,0 +1,166 @@
+/*
+ * 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.drools.verifier.definition;
+
+import org.drools.io.ClassPathResource;
+import org.drools.verifier.TestBase;
+import org.drools.verifier.Verifier;
+import org.drools.verifier.VerifierConfiguration;
+import org.drools.verifier.VerifierError;
+import org.drools.verifier.builder.VerifierBuilder;
+import org.drools.verifier.builder.VerifierBuilderFactory;
+import org.drools.verifier.data.VerifierReport;
+import org.drools.verifier.report.components.Severity;
+import org.junit.jupiter.api.Test;
+import org.kie.api.io.ResourceType;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Fail.fail;
+
+public class DefinitionValidationTest extends TestBase {
+
+    @Test
+    void testMissingDefinitionsAndFields() {
+
+        VerifierBuilder vBuilder = VerifierBuilderFactory.newVerifierBuilder();
+
+        VerifierConfiguration vConfiguration = 
vBuilder.newVerifierConfiguration();
+
+        // Check that the builder works.
+        assertThat(vBuilder.hasErrors()).isFalse();
+        assertThat(vBuilder.getErrors().size()).isEqualTo(0);
+
+        vConfiguration.getVerifyingResources().put(new 
ClassPathResource("DefinitionVerificationRules.drl", 
DefinitionValidationTest.class), ResourceType.DRL);
+
+        Verifier verifier = vBuilder.newVerifier(vConfiguration);
+
+        verifier.addResourcesToVerify(new 
ClassPathResource("MissingDefinitionTest.drl", DefinitionValidationTest.class), 
ResourceType.DRL);
+
+        assertThat(verifier.hasErrors()).isFalse();
+        assertThat(verifier.getErrors().size()).isEqualTo(0);
+
+        boolean works = verifier.fireAnalysis();
+
+        if (!works) {
+            for (VerifierError error : verifier.getErrors()) {
+                System.out.println(error.getMessage());
+            }
+            fail("Could not run verifier");
+        }
+        assertThat(works).isTrue();
+
+        VerifierReport result = verifier.getResult();
+
+
+        
result.getBySeverity(Severity.ERROR).stream().forEach(System.out::println);
+
+        assertThat(result).isNotNull();
+        assertThat(result.getBySeverity(Severity.ERROR).size()).isEqualTo(3);
+        assertThat(result.getBySeverity(Severity.WARNING).size()).isEqualTo(0);
+        assertThat(result.getBySeverity(Severity.NOTE).size()).isEqualTo(0);
+
+        assertThat(result.getBySeverity(Severity.ERROR).stream().anyMatch(m -> 
m.getMessage().contains("Missing type definition for fact type: 
Employee"))).isTrue();
+        assertThat(result.getBySeverity(Severity.ERROR).stream().anyMatch(m -> 
m.getMessage().contains("Field 'department' used in rule but not declared in 
definition of type 'Employee'"))).isTrue();
+        assertThat(result.getBySeverity(Severity.ERROR).stream().anyMatch(m -> 
m.getMessage().contains("Missing type definition for fact type: 
Vehicle"))).isTrue();
+
+    }
+
+    @Test
+    void testMissingFields() {
+
+        VerifierBuilder vBuilder = VerifierBuilderFactory.newVerifierBuilder();
+
+        VerifierConfiguration vConfiguration = 
vBuilder.newVerifierConfiguration();
+
+        // Check that the builder works.
+        assertThat(vBuilder.hasErrors()).isFalse();
+        assertThat(vBuilder.getErrors().size()).isEqualTo(0);
+
+        vConfiguration.getVerifyingResources().put(new 
ClassPathResource("DefinitionVerificationRules.drl", 
DefinitionValidationTest.class), ResourceType.DRL);
+
+        Verifier verifier = vBuilder.newVerifier(vConfiguration);
+
+        verifier.addResourcesToVerify(new 
ClassPathResource("UndefinedFieldUsageTest.drl", 
DefinitionValidationTest.class), ResourceType.DRL);
+
+        assertThat(verifier.hasErrors()).isFalse();
+        assertThat(verifier.getErrors().size()).isEqualTo(0);
+
+        boolean works = verifier.fireAnalysis();
+
+        if (!works) {
+            for (VerifierError error : verifier.getErrors()) {
+                System.out.println(error.getMessage());
+            }
+            fail("Could not run verifier");
+        }
+        assertThat(works).isTrue();
+
+        VerifierReport result = verifier.getResult();
+
+        assertThat(result).isNotNull();
+        assertThat(result.getBySeverity(Severity.ERROR).size()).isEqualTo(5);
+        assertThat(result.getBySeverity(Severity.WARNING).size()).isEqualTo(0);
+        assertThat(result.getBySeverity(Severity.NOTE).size()).isEqualTo(0);
+
+        assertThat(result.getBySeverity(Severity.ERROR).stream().anyMatch(m -> 
m.getMessage().contains("Field 'department' used in rule but not declared in 
definition of type 'Person'"))).isTrue();
+        assertThat(result.getBySeverity(Severity.ERROR).stream().anyMatch(m -> 
m.getMessage().contains("Field 'experience' used in rule but not declared in 
definition of type 'Person'"))).isTrue();
+        assertThat(result.getBySeverity(Severity.ERROR).stream().anyMatch(m -> 
m.getMessage().contains("Field 'salary' used in rule but not declared in 
definition of type 'Person'"))).isTrue();
+        assertThat(result.getBySeverity(Severity.ERROR).stream().anyMatch(m -> 
m.getMessage().contains("Field 'year' used in rule but not declared in 
definition of type 'Vehicle'"))).isTrue();
+        assertThat(result.getBySeverity(Severity.ERROR).stream().anyMatch(m -> 
m.getMessage().contains("Field 'owner' used in rule but not declared in 
definition of type 'Vehicle'"))).isTrue();
+
+    }
+
+    @Test
+    void testValidFileWithNestedFacts() {
+
+        VerifierBuilder vBuilder = VerifierBuilderFactory.newVerifierBuilder();
+
+        VerifierConfiguration vConfiguration = 
vBuilder.newVerifierConfiguration();
+
+        // Check that the builder works.
+        assertThat(vBuilder.hasErrors()).isFalse();
+        assertThat(vBuilder.getErrors().size()).isEqualTo(0);
+
+        vConfiguration.getVerifyingResources().put(new 
ClassPathResource("DefinitionVerificationRules.drl", 
DefinitionValidationTest.class), ResourceType.DRL);
+
+        Verifier verifier = vBuilder.newVerifier(vConfiguration);
+
+        verifier.addResourcesToVerify(new 
ClassPathResource("DefinitionValidationTest.drl", 
DefinitionValidationTest.class), ResourceType.DRL);
+
+        assertThat(verifier.hasErrors()).isFalse();
+        assertThat(verifier.getErrors().size()).isEqualTo(0);
+
+        boolean works = verifier.fireAnalysis();
+
+        if (!works) {
+            for (VerifierError error : verifier.getErrors()) {
+                System.out.println(error.getMessage());
+            }
+            fail("Could not run verifier");
+        }
+        assertThat(works).isTrue();
+
+        VerifierReport result = verifier.getResult();
+
+        assertThat(result).isNotNull();
+        assertThat(result.getBySeverity(Severity.ERROR).size()).isEqualTo(0);
+        assertThat(result.getBySeverity(Severity.WARNING).size()).isEqualTo(0);
+        assertThat(result.getBySeverity(Severity.NOTE).size()).isEqualTo(0);
+    }
+}
diff --git 
a/drools-verifier/drools-verifier-drl/src/test/resources/org/drools/verifier/definition/DefinitionValidationTest.drl
 
b/drools-verifier/drools-verifier-drl/src/test/resources/org/drools/verifier/definition/DefinitionValidationTest.drl
new file mode 100644
index 0000000000..d0a805b505
--- /dev/null
+++ 
b/drools-verifier/drools-verifier-drl/src/test/resources/org/drools/verifier/definition/DefinitionValidationTest.drl
@@ -0,0 +1,59 @@
+/**
+ * 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.drools.verifier.definition
+
+declare Person
+    name : String
+    age : Integer
+    address : Address
+end
+
+declare Address
+    street : String
+    city : String
+    zipCode : String
+end
+
+declare Vehicle
+    make : String
+    model : String
+    owner : Person
+end
+
+rule "Adult persons"
+when
+    $p : Person( age >= 18 )
+then
+    System.out.println("Adult: " + $p.getName());
+end
+
+rule "City residents"
+when
+    $p : Person( address.city == "New York" )
+then
+    System.out.println("NYC resident: " + $p.getName());
+end
+
+rule "Vehicle owners"
+when
+    $v : Vehicle( owner.age > 21 )
+then
+    System.out.println("Vehicle owned by adult: " + $v.getOwner().getName());
+end
\ No newline at end of file
diff --git 
a/drools-verifier/drools-verifier-drl/src/test/resources/org/drools/verifier/definition/DefinitionVerificationRules.drl
 
b/drools-verifier/drools-verifier-drl/src/test/resources/org/drools/verifier/definition/DefinitionVerificationRules.drl
new file mode 100644
index 0000000000..76c531f790
--- /dev/null
+++ 
b/drools-verifier/drools-verifier-drl/src/test/resources/org/drools/verifier/definition/DefinitionVerificationRules.drl
@@ -0,0 +1,152 @@
+/**
+ * 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.
+ */
+
+//Verification rules for checking DRL type definitions
+package org.drools.verifier.definition
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.drools.verifier.components.Definition;
+import org.drools.verifier.components.ObjectType;
+import org.drools.verifier.components.LiteralRestriction;
+import org.drools.verifier.components.Pattern;
+import org.drools.verifier.report.components.Severity;
+import org.drools.verifier.report.components.VerifierMessage;
+import org.drools.verifier.report.components.MessageType;
+
+import org.drools.verifier.data.VerifierReport
+import org.drools.verifier.components.Field;
+
+global VerifierReport result;
+
+rule "Missing Definition for ObjectType"
+    when
+        $objectType : ObjectType( $typeName : name )
+        not Definition( typeName == $typeName )
+    then
+        result.add(new VerifierMessage(
+                        new HashMap(),
+                        Severity.ERROR,
+                        MessageType.MISSING_COMPONENT,
+                        $objectType,
+                        "Missing type definition for fact type: " + $typeName
+                        ,
+                        new ArrayList() ) );
+end
+
+
+declare FinalField
+    patternName: String
+    fieldName: String
+end
+
+declare Split
+    patternName: String
+    fieldName: String
+    leftOver: String[]
+end
+
+rule "Split"
+    when
+        LiteralRestriction( fieldPath != null, $fieldName : fieldName, 
$patternName : patternName )
+    then
+        if($fieldName.contains(".")) {
+            Split split = new Split();
+
+            String[] array = $fieldName.split("\\.");
+            split.setFieldName(array[0]);
+            split.setPatternName( $patternName );
+            split.setLeftOver( java.util.Arrays.copyOfRange(array, 1, 
array.length) );
+            insert( split );
+        } else {
+            FinalField ff = new FinalField();
+            ff.setPatternName( $patternName );
+            ff.setFieldName( $fieldName );
+            insert( ff );
+        }
+end
+
+rule "Trim split"
+    when
+        $split :Split( $fieldName :fieldName, eval( leftOver.length > 0) )
+        $definition : Definition( typeName == $split.patternName, fieldNames 
contains $fieldName)
+    then
+        String fieldType = $definition.getDeclaredFields().get($fieldName);
+        String[] oldArray = $split.getLeftOver();
+        String[] newArray = java.util.Arrays.copyOfRange(oldArray, 1, 
oldArray.length);
+        $split.setFieldName(oldArray[0]);
+        $split.setPatternName( fieldType );
+        $split.setLeftOver( newArray );
+        update( $split );
+
+end
+
+rule "Add final field"
+    when
+        Split( $patternName : patternName, $fieldName : fieldName, eval( 
leftOver.length == 0))
+    then
+        FinalField ff = new FinalField();
+        ff.setPatternName( $patternName );
+        ff.setFieldName( $fieldName );
+        insert( ff );
+end
+
+rule "Missing Field in Definition"
+    when
+        $restriction : FinalField( $fieldName : fieldName )
+        $definition : Definition( typeName == $restriction.patternName, 
fieldNames not contains $fieldName )
+    then
+        result.add(new VerifierMessage(
+                          new HashMap(),
+                          Severity.ERROR,
+                          MessageType.MISSING_COMPONENT,
+                          $definition,
+                          "Field '" + $fieldName  + "' used in rule but not 
declared in definition of type '" + $restriction.getPatternName() + "'",
+                          new ArrayList() ) );
+end
+
+rule "Missing Field in a missing Definition"
+    when
+        $restriction : FinalField( $fieldName : fieldName )
+        not Definition( typeName == $restriction.patternName )
+    then
+        result.add(new VerifierMessage(
+                          new HashMap(),
+                          Severity.ERROR,
+                          MessageType.MISSING_COMPONENT,
+                          null,
+                          "Field '" + $fieldName  + "' used in rule but not 
declared in definition of type '" + $restriction.getPatternName() + "'",
+                          new ArrayList() ) );
+end
+
+rule "Error when Definition exists, but it is lacking a field"
+    when
+        $split :Split( $fieldName :fieldName, $patternName :patternName)
+        $definition : Definition( typeName == $split.patternName, fieldNames 
not contains $split.fieldName)
+    then
+          result.add(new VerifierMessage(
+                              new HashMap(),
+                              Severity.ERROR,
+                              MessageType.MISSING_COMPONENT,
+                              null,
+                              "Field '" + $fieldName  + "' used in rule but 
not declared in definition of type '" + $patternName + "'",
+                              new ArrayList() ) );
+end
+
diff --git 
a/drools-verifier/drools-verifier-drl/src/test/resources/org/drools/verifier/definition/MissingDefinitionTest.drl
 
b/drools-verifier/drools-verifier-drl/src/test/resources/org/drools/verifier/definition/MissingDefinitionTest.drl
new file mode 100644
index 0000000000..f8c87bdfad
--- /dev/null
+++ 
b/drools-verifier/drools-verifier-drl/src/test/resources/org/drools/verifier/definition/MissingDefinitionTest.drl
@@ -0,0 +1,46 @@
+/**
+ * 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.drools.verifier.definition
+
+declare Person
+    name : String
+    age : Integer
+end
+
+rule "Adult persons"
+when
+    $p : Person( age >= 18 )
+then
+    System.out.println("Adult: " + $p.getName());
+end
+
+rule "Company employees"
+when
+    $e : Employee( department == "Engineering" )
+then
+    System.out.println("Engineer: " + $e.getName());
+end
+
+rule "Vehicle owners"
+when
+    $v : Vehicle( owner.age > 21 )
+then
+    System.out.println("Vehicle owned by adult: " + $v.getOwner().getName());
+end
\ No newline at end of file
diff --git 
a/drools-verifier/drools-verifier-drl/src/test/resources/org/drools/verifier/definition/UndefinedFieldUsageTest.drl
 
b/drools-verifier/drools-verifier-drl/src/test/resources/org/drools/verifier/definition/UndefinedFieldUsageTest.drl
new file mode 100644
index 0000000000..35b24494fc
--- /dev/null
+++ 
b/drools-verifier/drools-verifier-drl/src/test/resources/org/drools/verifier/definition/UndefinedFieldUsageTest.drl
@@ -0,0 +1,51 @@
+/**
+ * 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.drools.verifier.definition
+
+declare Person
+    name : String
+    age : Integer
+end
+
+declare Vehicle
+    make : String
+    model : String
+end
+
+rule "Person with undefined field"
+when
+    $p : Person( name != null, age > 18, salary > 50000 )  // salary not 
defined
+then
+    System.out.println("Person: " + $p.getName());
+end
+
+rule "Vehicle with undefined fields"
+when
+    $v : Vehicle( make == "Toyota", year > 2020, owner.age > 25 )  // year and 
owner not defined
+then
+    System.out.println("Vehicle: " + $v.getMake());
+end
+
+rule "Multiple undefined fields"
+when
+    $p : Person( department == "IT", experience > 5 )  // department and 
experience not defined
+then
+    System.out.println("Employee: " + $p.getName());
+end
\ No newline at end of file


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


Reply via email to