Interface DMNType

All Superinterfaces:
Cloneable

public interface DMNType extends Cloneable
Represent a DMN type; in the vast majority of cases, this representation exists as a result of a DMN model specifying an ItemDefinition.

Design document

A DMN type has a namespace; when a DMN type is a representation of an ItemDefinition defined in a DMN model, the namespace correspond to the model's namespace as per DMNModel.getNamespace(). When the namespace is a FEEL reserved namespace such as https://www.omg.org/spec/DMN/20191111/FEEL/ then the DMN type stands for an equivalent representation of a built-in FEEL type.

To be noted FEEL built-in org.kie.dmn.feel.lang.Type(s) find an equivalent representation as a DMN type when the DMNModel is compiled. This is by design, since the DMN layer of the Drools DMN open source engine is based on top of the FEEL layer.

A DMN type has a name; this usually corresponds to the ItemDefinition's name (see: NamedElement.getName()).

Simple and Composite types

As per the DMN specification, a DMN type representing an ItemDefinition in a model, can be specified based on either:
  • a reference to a FEEL built-in or another ItemDefinition specified in the model; possibly restricted with getAllowedValues()
  • a composition of ItemDefinition(s)
  • as a FunctionItem

The difference between Simple and Composite types have large implication on a number of attributes.

When specified by reference:
  • the isComposite() will be false
  • it is expected this will be an instance of org.kie.dmn.core.impl.SimpleTypeImpl
  • call to getBaseType() will be different than null
  • call to getFields() will be an empty collection

For example the following is a DMN Simple type, defining a type which is like a FEEL string but its values can only be a vowel:

<dmn:itemDefinition name="tVowel">
  <dmn:typeRef>string</dmn:typeRef>
  <dmn:allowedValues>
    <dmn:text>"a", "e", "i", "o", "u"</dmn:text>
  </dmn:allowedValues>
</dmn:itemDefinition>
Another example of DMN Simple type, modeling a FEEL list<number>:

<dmn:itemDefinition name="tNumbers" isCollection="true">
  <dmn:typeRef>number</dmn:typeRef>
</dmn:itemDefinition>
Another example of DMN Simple type, making reference to another ItemDefinition specified in the model, modeling a list of just vowels:

<dmn:itemDefinition name="tListOfVowels" isCollection="true">
  <dmn:typeRef>tVowel</dmn:typeRef>
</dmn:itemDefinition>
When instead specified by composition:
  • the isComposite() will be true
  • it is expected this will be an instance of org.kie.dmn.core.impl.CompositeTypeImpl
  • calling getBaseType() always return null.
  • call to getFields() will return the collection of fields representing this composition

For example the following is a DMN Composite type, consisting of two fields for full name and age respectively, equivalently representing FEEL type for context<full name: string, age: number>:

<dmn:itemDefinition name="tPerson">
  <dmn:itemComponent name="full name">
    <dmn:typeRef>string</dmn:typeRef>
  </dmn:itemComponent>
  <dmn:itemComponent name="age">
    <dmn:typeRef>number</dmn:typeRef>
  </dmn:itemComponent>
</dmn:itemDefinition>

isCollection

As per the DMN specification, setting ItemDefinition.isIsCollection() to true, indicates that the actual values defined by the type are collections of (allowed) values.
This is reflected in this DMN type isCollection().

It is important to note that this attribute is orthogonal to the fact of being a Simple or Composite type; most of the time however for Methodology best-practices DMN collection types are simple types, that is, specified by reference.

allowedValues

As per the DMN specification, the ItemDefinition.getAllowedValues() attribute lists the possible values or ranges of values in the base type that are allowed in this ItemDefinition. This is reflected in this DMN type getAllowedValues().

It is important to note that attribute can only be present when the type is specified by reference.

typeConstraints

As per the DMN specification, the ItemDefinition.getTypeConstraint() ()} attribute lists the possible values or ranges of values in the base type that are allowed in this ItemDefinition. This is reflected in this DMN type getTypeConstraint().

It is important to note that attribute can only be present when the type is specified by reference.

getFields

Only when a type is specified by composition, getFields() will return the collection of the fields which constitutes the composite type.

For example in the following DMN Composite type, consisting of two fields for full name and age respectively:

<dmn:itemDefinition name="tPerson">
  <dmn:itemComponent name="full name">
    <dmn:typeRef>string</dmn:typeRef>
  </dmn:itemComponent>
  <dmn:itemComponent name="age">
    <dmn:typeRef>number</dmn:typeRef>
  </dmn:itemComponent>
</dmn:itemDefinition>
a call to getFields() returns a collection of two entries:
  • field key full name, value the FEEL built-in type string
  • field key age, value the FEEL built-in type number

Anonymous inner types and TypeRegistry

When the DMN model specifies an ItemDefinition this gets compiled as a DMN type and it is registered in the model's org.kie.dmn.core.impl.DMNModelImpl#getTypeRegistry().

There is a special case where ItemDefinition defines an anonymous inner type, which naturally cannot be registered in the type registry since it does not have a globally valid and unique name.
This use-case be thought, in some respects, of being similar to Java's inner classes.

For example in the following DMN Composite type:

<dmn:itemDefinition name="tPerson">
  <dmn:itemComponent name="full name">
    <dmn:typeRef>string</dmn:typeRef>
  </dmn:itemComponent>
  <dmn:itemComponent name="address">
    <dmn:itemComponent name="country">
      <dmn:typeRef>string</dmn:typeRef>
    </dmn:itemComponent>
    <dmn:itemComponent name="zip">
      <dmn:typeRef>string</dmn:typeRef>
    </dmn:itemComponent>
  </dmn:itemComponent>
</dmn:itemDefinition>
a call to getFields() returns a collection of two entries:
  • field key full name, value the FEEL built-in type string
  • field key address, value an anonymous inner Composite type.

This latter inner Composite type is not registered in the model's type registry, as explained.
By convention, it is given the name of the corresponding field: therefore, a call to getName() returns address.
In itself, it is a Composite type; therefore everything said about Composite type is applicable, for example a call to getFields() in turn would return a collection of two entries:
  • field key country, value the FEEL built-in type string
  • field key zip, value the FEEL built-in type string

Another example of a DMN Composite type defining an anonymous inner type:

<dmn:itemDefinition name="tPart">
  <dmn:itemComponent name="name">
    <dmn:typeRef>string</dmn:typeRef>
  </dmn:itemComponent>
  <dmn:itemComponent name="grade">
    <dmn:typeRef>string</dmn:typeRef>
    <dmn:allowedValues>
      <dmn:text>"A", "B", "C"</dmn:text>
    </dmn:allowedValues>
  </dmn:itemComponent>
</dmn:itemDefinition>
a call to getFields() returns a collection of two entries:
  • field key name, value the FEEL built-in type string
  • field key grade, value an anonymous inner Simple type.

This latter inner Simple type is not registered in the model's type registry, as explained.
By convention, it is given the name of the corresponding field: therefore, a call to getName() returns grade.
In itself, it is a Simple type; therefore everything said about Simple type is applicable.

Implementation notes

To be noted that the convention of representing FEEL built-in types also as DMNType, is merely for internal mechanisms adopted by the engine and does not correspond to any requirement from the DMN specification; the current valorization of the attributes of this DMNType follows internal implementation choices and can change any time the convention might need update. It is strongly advised to discern these representations from normal ItemDefinition defined in the DMN model, by making use of the namespace attribute as described above.
  • Method Details

    • getNamespace

      String getNamespace()
    • getName

      String getName()
    • getId

      String getId()
    • isCollection

      boolean isCollection()
    • isComposite

      boolean isComposite()
    • getFields

      Map<String,DMNType> getFields()
    • getBaseType

      DMNType getBaseType()
    • clone

      DMNType clone()
    • isInstanceOf

      boolean isInstanceOf(Object o)
      Definition of `instance of` accordingly to FEEL specifications Table 61.
      Parameters:
      o -
      Returns:
      if o is instance of the type represented by this type. If the parameter is null, returns false.
    • isAssignableValue

      boolean isAssignableValue(Object value)
      Check if the value passed as parameter can be assigned to this type. It checks 1. type itself 2. allowedValues 3. typeConstraint
      Parameters:
      value -
      Returns:
      if value can be assigned to the type represented by this type. If the parameter is null, returns true.
    • getAllowedValues

      List<DMNUnaryTest> getAllowedValues()
    • getTypeConstraint

      List<DMNUnaryTest> getTypeConstraint()