org.kie.dmn.validation.DMNv1x.dmn-validation-rules.drl Maven / Gradle / Ivy
The newest version!
/**
* 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.dmn.validation.DMNv1x;
import org.kie.dmn.model.api.*;
import org.kie.dmn.api.core.DMNMessage;
import org.kie.dmn.core.impl.DMNMessageImpl;
import org.kie.dmn.core.util.MsgUtil;
import org.kie.dmn.feel.lang.types.BuiltInType;
import org.kie.dmn.feel.parser.feel11.FEELParser;
import org.kie.dmn.feel.runtime.events.SyntaxErrorEvent;
import org.kie.dmn.api.feel.runtime.events.FEELEvent;
import org.kie.dmn.core.util.Msg;
import org.kie.dmn.core.compiler.ImportDMNResolverUtil;
import org.kie.dmn.validation.ValidatorUtil;
import function org.kie.dmn.validation.ValidatorUtil.rightOfHash;
import function org.kie.dmn.validation.ValidatorUtil.getRootItemDef;
global org.kie.dmn.validation.MessageReporter reporter;
declare entry-point "DMNImports" end
rule MISSING_IMPORT_p1
when
$elemRef : Import( ImportDMNResolverUtil.whichImportType(this) == ImportDMNResolverUtil.ImportType.DMN,
$importedNS : namespace,
getAdditionalAttributes().get(ValidatorUtil.KIE_MODEL_NAME_QNAME) == null )
not( Definitions( namespace == $importedNS ) from entry-point "DMNImports" )
then
reporter.report(DMNMessage.Severity.ERROR, $elemRef, Msg.IMPORT_NOT_FOUND_FOR_NODE, $importedNS, $elemRef.getIdentifierString());
end
rule MISSING_IMPORT_p2
when
$elemRef : Import( ImportDMNResolverUtil.whichImportType(this) == ImportDMNResolverUtil.ImportType.DMN,
$importedNS : namespace,
getAdditionalAttributes().get(ValidatorUtil.KIE_MODEL_NAME_QNAME) != null,
$importedName : getAdditionalAttributes().get(ValidatorUtil.KIE_MODEL_NAME_QNAME) )
not( Definitions( namespace == $importedNS, name == $importedName ) from entry-point "DMNImports" )
then
reporter.report(DMNMessage.Severity.ERROR, $elemRef, Msg.IMPORT_NOT_FOUND_FOR_NODE, $importedNS + $importedName, $elemRef.getIdentifierString());
end
rule INVOCATION_MISSING_EXPR
when
$b : Binding( expression == null )
then
reporter.report( DMNMessage.Severity.WARN, $b, Msg.MISSING_EXPRESSION_FOR_PARAM_OF_INVOCATION,
$b.getParameter() != null ? $b.getParameter().getIdentifierString() : "[unnamed]",
$b.getParentDRDElement().getIdentifierString() );
end
rule NAME_EMPTY
when
$ne : NamedElement( !(this instanceof Import),
!FEELParser.isVariableNameEmpty( name ) )
then
java.util.List errors = FEELParser.checkVariableNameEmpty( $ne.getName() );
if ( ! errors.isEmpty() ) {
reporter.report( DMNMessage.Severity.ERROR, $ne , Msg.INVALID_NAME, $ne.getName(), errors.get( 0 ).getMessage() );
}
end
rule NAME_INVALID
when
$ne : NamedElement( parent != null,
// the following constraint prevents duplicate reporting due to variables having the same name as their enclosing nodes
!( parent instanceof NamedElement ) || (((NamedElement)parent).name != name ),
!FEELParser.isVariableNameValid( name ) )
then
java.util.List errors = FEELParser.checkVariableName( $ne.getName() );
if ( ! errors.isEmpty() ) {
reporter.report( DMNMessage.Severity.ERROR, $ne , Msg.INVALID_NAME, $ne.getName(), errors.get( 0 ).getMessage() );
}
end
rule NAME_NOT_TRIMMED
when
$ne : NamedElement( name != null, name str[startsWith] " " || name str[endsWith] " " )
then
reporter.report( DMNMessage.Severity.WARN, $ne , Msg.NAME_NOT_TRIMMED, $ne.getName(), $ne.getClass().getSimpleName(), $ne.getId() );
end
rule NAME_NOT_NORMALIZED
when
$ne : NamedElement( name != null, name contains " " )
then
reporter.report( DMNMessage.Severity.WARN, $ne , Msg.NAME_NOT_NORMALIZED, $ne.getName(), $ne.getClass().getSimpleName(), $ne.getId() );
end
rule VARIABLE_LEADING_TRAILING_SPACES
when
$ce1 : InformationItem( name != null,
name str[startsWith] " " || name str[endsWith] " ",
!(parent instanceof Binding || parent instanceof FunctionDefinition || parent instanceof Relation ) )
then
reporter.report( DMNMessage.Severity.WARN, $ce1 , Msg.VARIABLE_LEADING_TRAILING_SPACES, $ce1.getName(), $ce1.getParentDRDElement().getIdentifierString() );
end
rule DRGELEM_NOT_UNIQUE
when
$x : DRGElement( parent instanceof Definitions )
$y : DRGElement( name == $x.name, parent instanceof Definitions,
parent == $x.parent,
this != $x )
then
reporter.report( DMNMessage.Severity.ERROR, $x , Msg.DUPLICATE_DRG_ELEMENT, $x.getName() );
end
// From DMN Spec: 6.3.3 Import metamodel
rule IMPORT_NAME_NOT_UNIQUE
when
$x : Import( parent instanceof Definitions )
$y : Import( name == $x.name, parent instanceof Definitions, parent == $x.parent, this != $x )
then
reporter.report( DMNMessage.Severity.ERROR, $x , Msg.IMPORT_NAME_NOT_UNIQUE, $x.getName() );
end
// From DMN Spec: 6.3.3 Import metamodel
rule IMPORT_NAME_NOT_UNIQUE_WITH_DRG
when
$x : Import( parent instanceof Definitions )
$y : DRGElement( name == $x.name, parent instanceof Definitions, parent == $x.parent )
then
reporter.report( DMNMessage.Severity.ERROR, $x , Msg.IMPORT_NAME_NOT_UNIQUE, $x.getName() );
end
// From DMN Spec: 6.3.3 Import metamodel
rule IMPORT_NAME_NOT_UNIQUE_WITH_ITEMDEF
when
$x : Import( parent instanceof Definitions )
$y : ItemDefinition( name == $x.name, parent instanceof Definitions, parent == $x.parent )
then
reporter.report( DMNMessage.Severity.ERROR, $x , Msg.IMPORT_NAME_NOT_UNIQUE, $x.getName() );
end
rule FORMAL_PARAM_DUPLICATED
when
$fp1 : InformationItem( parent instanceof FunctionDefinition )
$fp2 : InformationItem( name == $fp1.name, parent == $fp1.parent, this != $fp1 )
then
reporter.report( DMNMessage.Severity.ERROR, $fp1 , Msg.DUPLICATE_FORMAL_PARAM, $fp1.getName(), $fp1.getParentDRDElement().getIdentifierString() );
end
rule RELATION_DUP_COLUMN
when
$c1 : InformationItem( parent instanceof Relation )
$c2 : InformationItem( name == $c1.name, parent == $c1.parent, this != $c1 )
then
reporter.report( DMNMessage.Severity.ERROR, $c1 , Msg.DUPLICATED_RELATION_COLUMN, $c1.getName(), $c1.getParentDRDElement().getIdentifierString() );
end
rule INVOCATION_MISSING_EXPRESSION
when
$inv : Invocation( expression == null || expression#LiteralExpression.text == "" )
then
reporter.report( DMNMessage.Severity.ERROR, $inv , Msg.MISSING_EXPRESSION_FOR_INVOCATION, $inv.getParentDRDElement().getIdentifierString() );
end
// The parameter names in the Binding elements SHALL be a subset of the formalParameters of the calledFunction.
rule INVOCATION_INCONSISTENT_PARAM_NAMES
when
$inv : Invocation( $targetName : expression#LiteralExpression.text )
$target : BusinessKnowledgeModel( name == $targetName )
$b : Binding($s : parameter.name) from $inv.binding
not( InformationItem( name == $s ) from $target.encapsulatedLogic.formalParameter )
then
reporter.report( DMNMessage.Severity.ERROR, $b.getParameter() , Msg.UNKNOWN_PARAMETER, $s, $targetName, $inv.getParentDRDElement().getIdentifierString() );
end
// the following rule needs to be improved as an invocation element can be used to invoke
// functions not defined in DRGelements
//rule INVOCATION_MISSING_TARGET
//when
// $inv : Invocation( $targetName : expression#LiteralExpression.text )
// not( DRGElement( name == $targetName ) )
//then
// reporter.report( DMNMessage.Severity.ERROR, $inv , Msg.INVOCATION_MISSING_TARGET );
//end
rule INVOCATION_WRONG_PARAM_COUNT
when
$inv : Invocation( $targetName : expression#LiteralExpression.text )
BusinessKnowledgeModel( name == $targetName, encapsulatedLogic!.formalParameter.size != $inv.binding.size )
then
reporter.report( DMNMessage.Severity.ERROR, $inv , Msg.PARAMETER_COUNT_MISMATCH, $targetName, $inv.getParentDRDElement().getIdentifierString() );
end
// This is a lower level complement of ITEMDEF_NOT_UNIQUE below, for detecting duplicate attribute names inside the same ItemDefinition
rule ITEMCOMP_DUPLICATED
when
$ic1 : ItemDefinition( parent instanceof ItemDefinition )
$ic2 : ItemDefinition( name == $ic1.name, parent == $ic1.parent, this != $ic1 )
then
reporter.report( DMNMessage.Severity.ERROR, $ic1 , Msg.DUPLICATED_ITEM_COMPONENT, $ic1.getName(), getRootItemDef( $ic1 ).getName() );
end
rule ITEMDEF_NOT_UNIQUE
when
$x : ItemDefinition( parent instanceof Definitions )
$y : ItemDefinition( parent instanceof Definitions, parent == $x.parent, name == $x.name, this != $x )
then
reporter.report( DMNMessage.Severity.ERROR, $x , Msg.DUPLICATED_ITEM_DEFINITION, $x.getName() );
end
rule RELATION_ROW_CELL_NOT_LITERAL
when
$e : Expression( parent instanceof org.kie.dmn.model.api.List, parent.parent instanceof Relation, ! (this instanceof LiteralExpression) )
then
org.kie.dmn.model.api.List row = (org.kie.dmn.model.api.List) $e.getParent();
Relation relation = (Relation) row.getParent();
reporter.report( DMNMessage.Severity.ERROR, $e , Msg.RELATION_CELL_NOT_LITERAL,
relation.getRow().indexOf(row)+1,
relation.getParentDRDElement().getIdentifierString() );
end
rule RELATION_ROW_CELLCOUNTMISMATCH
when
$rel : Relation()
$row : org.kie.dmn.model.api.List( expression.size != $rel.column.size ) from $rel.row
then
reporter.report( DMNMessage.Severity.ERROR, $row , Msg.RELATION_CELL_COUNT_MISMATCH,
$rel.getRow().indexOf($row)+1,
$rel.getParentDRDElement().getIdentifierString() );
end
© 2015 - 2025 Weber Informatics LLC | Privacy Policy