Search in sources :

Example 1 with CompositeTypeImpl

use of org.kie.dmn.core.impl.CompositeTypeImpl in project drools by kiegroup.

the class DMNCompilerImpl method buildTypeDef.

private DMNType buildTypeDef(DMNCompilerContext ctx, DMNFEELHelper feel, DMNModelImpl dmnModel, DMNNode node, ItemDefinition itemDef, boolean topLevel) {
    BaseDMNTypeImpl type = null;
    if (itemDef.getTypeRef() != null) {
        // this is a reference to an existing type, so resolve the reference
        type = (BaseDMNTypeImpl) resolveTypeRef(dmnModel, node, itemDef, itemDef, itemDef.getTypeRef());
        if (type != null) {
            UnaryTests allowedValuesStr = itemDef.getAllowedValues();
            // or if it changes the metadata for the base type
            if (topLevel || allowedValuesStr != null || itemDef.isIsCollection() != type.isCollection()) {
                // we have to clone this type definition into a new one
                BaseDMNTypeImpl baseType = type;
                type = type.clone();
                type.setBaseType(baseType);
                type.setNamespace(dmnModel.getNamespace());
                type.setName(itemDef.getName());
                type.setAllowedValues(null);
                if (allowedValuesStr != null) {
                    List<UnaryTest> av = feel.evaluateUnaryTests(ctx, allowedValuesStr.getText(), dmnModel, itemDef, Msg.ERR_COMPILING_ALLOWED_VALUES_LIST_ON_ITEM_DEF, allowedValuesStr.getText(), node.getName());
                    type.setAllowedValues(av);
                }
                if (itemDef.isIsCollection()) {
                    type.setCollection(itemDef.isIsCollection());
                }
            }
            if (topLevel) {
                DMNType registered = dmnModel.getTypeRegistry().registerType(type);
                if (registered != type) {
                    MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, itemDef, dmnModel, null, null, Msg.DUPLICATED_ITEM_DEFINITION, itemDef.getName());
                }
            }
        }
    } else {
        // this is a composite type
        DMNCompilerHelper.checkVariableName(dmnModel, itemDef, itemDef.getName());
        CompositeTypeImpl compType = new CompositeTypeImpl(dmnModel.getNamespace(), itemDef.getName(), itemDef.getId(), itemDef.isIsCollection());
        for (ItemDefinition fieldDef : itemDef.getItemComponent()) {
            DMNCompilerHelper.checkVariableName(dmnModel, fieldDef, fieldDef.getName());
            DMNType fieldType = buildTypeDef(ctx, feel, dmnModel, node, fieldDef, false);
            fieldType = fieldType != null ? fieldType : DMNTypeRegistry.UNKNOWN;
            compType.addField(fieldDef.getName(), fieldType);
        }
        type = compType;
        if (topLevel) {
            DMNType registered = dmnModel.getTypeRegistry().registerType(type);
            if (registered != type) {
                MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, itemDef, dmnModel, null, null, Msg.DUPLICATED_ITEM_DEFINITION, itemDef.getName());
            }
        }
    }
    return type;
}
Also used : ItemDefinition(org.kie.dmn.model.v1_1.ItemDefinition) BaseDMNTypeImpl(org.kie.dmn.core.impl.BaseDMNTypeImpl) UnaryTests(org.kie.dmn.model.v1_1.UnaryTests) UnaryTest(org.kie.dmn.feel.runtime.UnaryTest) CompositeTypeImpl(org.kie.dmn.core.impl.CompositeTypeImpl) DMNType(org.kie.dmn.api.core.DMNType)

Example 2 with CompositeTypeImpl

use of org.kie.dmn.core.impl.CompositeTypeImpl in project drools by kiegroup.

the class DecisionCompiler method compileEvaluator.

@Override
public void compileEvaluator(DMNNode node, DMNCompilerImpl compiler, DMNCompilerContext ctx, DMNModelImpl model) {
    DecisionNodeImpl di = (DecisionNodeImpl) node;
    compiler.linkRequirements(model, di);
    ctx.enterFrame();
    try {
        Map<String, DMNType> importedTypes = new HashMap<>();
        for (DMNNode dep : di.getDependencies().values()) {
            if (dep instanceof DecisionNode) {
                ctx.setVariable(dep.getName(), ((DecisionNode) dep).getResultType());
            } else if (dep instanceof InputDataNode) {
                ctx.setVariable(dep.getName(), ((InputDataNode) dep).getType());
            } else if (dep instanceof BusinessKnowledgeModelNode) {
                if (dep.getModelNamespace().equals(model.getNamespace())) {
                    // might need to create a DMNType for "functions" and replace the type here by that
                    ctx.setVariable(dep.getName(), ((BusinessKnowledgeModelNode) dep).getResultType());
                } else {
                    // then the BKM dependency is an imported BKM.
                    Optional<String> alias = model.getImportAliasFor(dep.getModelNamespace(), dep.getModelName());
                    if (alias.isPresent()) {
                        CompositeTypeImpl importedComposite = (CompositeTypeImpl) importedTypes.computeIfAbsent(alias.get(), a -> new CompositeTypeImpl());
                        importedComposite.addField(dep.getName(), ((BusinessKnowledgeModelNode) dep).getResultType());
                    }
                }
            }
        }
        for (Entry<String, DMNType> importedType : importedTypes.entrySet()) {
            ctx.setVariable(importedType.getKey(), importedType.getValue());
        }
        DMNExpressionEvaluator evaluator = compiler.getEvaluatorCompiler().compileExpression(ctx, model, di, di.getName(), di.getDecision().getExpression());
        di.setEvaluator(evaluator);
    } finally {
        ctx.exitFrame();
    }
}
Also used : DMNType(org.kie.dmn.api.core.DMNType) DMNNode(org.kie.dmn.api.core.ast.DMNNode) DMNModelImpl(org.kie.dmn.core.impl.DMNModelImpl) HashMap(java.util.HashMap) BusinessKnowledgeModelNode(org.kie.dmn.api.core.ast.BusinessKnowledgeModelNode) Decision(org.kie.dmn.model.v1_1.Decision) DecisionNode(org.kie.dmn.api.core.ast.DecisionNode) DMNExpressionEvaluator(org.kie.dmn.core.api.DMNExpressionEvaluator) Map(java.util.Map) DRGElement(org.kie.dmn.model.v1_1.DRGElement) Entry(java.util.Map.Entry) Optional(java.util.Optional) InputDataNode(org.kie.dmn.api.core.ast.InputDataNode) CompositeTypeImpl(org.kie.dmn.core.impl.CompositeTypeImpl) Msg(org.kie.dmn.core.util.Msg) DecisionNodeImpl(org.kie.dmn.core.ast.DecisionNodeImpl) DMNExpressionEvaluator(org.kie.dmn.core.api.DMNExpressionEvaluator) HashMap(java.util.HashMap) DecisionNode(org.kie.dmn.api.core.ast.DecisionNode) BusinessKnowledgeModelNode(org.kie.dmn.api.core.ast.BusinessKnowledgeModelNode) DecisionNodeImpl(org.kie.dmn.core.ast.DecisionNodeImpl) DMNNode(org.kie.dmn.api.core.ast.DMNNode) InputDataNode(org.kie.dmn.api.core.ast.InputDataNode) CompositeTypeImpl(org.kie.dmn.core.impl.CompositeTypeImpl) DMNType(org.kie.dmn.api.core.DMNType)

Example 3 with CompositeTypeImpl

use of org.kie.dmn.core.impl.CompositeTypeImpl in project drools by kiegroup.

the class DMNTypeTest method testDROOLS2147.

@Test
public void testDROOLS2147() {
    // DROOLS-2147
    final String testNS = "testDROOLS2147";
    Map<String, DMNType> personPrototype = prototype(entry("name", FEEL_STRING), entry("age", FEEL_NUMBER));
    DMNType dmnPerson = typeRegistry.registerType(new CompositeTypeImpl(testNS, "person", null, false, personPrototype, null, null));
    DMNType dmnPersonList = typeRegistry.registerType(new CompositeTypeImpl(testNS, "personList", null, true, null, dmnPerson, null));
    DMNType dmnListOfPersonsGrouped = typeRegistry.registerType(new CompositeTypeImpl(testNS, "groups", null, true, null, dmnPersonList, null));
    Map<String, Object> instanceBob = prototype(entry("name", "Bob"), entry("age", 42));
    Map<String, Object> instanceJohn = prototype(entry("name", "John"), entry("age", 47));
    Map<String, Object> instanceNOTaPerson = prototype(entry("name", "NOTAPERSON"));
    assertTrue(dmnPerson.isAssignableValue(instanceBob));
    assertTrue(dmnPerson.isAssignableValue(instanceJohn));
    assertFalse(dmnPerson.isAssignableValue(instanceNOTaPerson));
    List<Map<String, Object>> onlyBob = Arrays.asList(instanceBob);
    List<Map<String, Object>> bobANDjohn = Arrays.asList(instanceBob, instanceJohn);
    List<Map<String, Object>> johnANDnotAPerson = Arrays.asList(instanceJohn, instanceNOTaPerson);
    assertTrue(dmnPersonList.isAssignableValue(onlyBob));
    assertTrue(dmnPersonList.isAssignableValue(bobANDjohn));
    assertFalse(dmnPersonList.isAssignableValue(johnANDnotAPerson));
    // because accordingly to FEEL spec, bob=[bob]
    assertTrue(dmnPersonList.isAssignableValue(instanceBob));
    List<List<Map<String, Object>>> the2ListsThatContainBob = Arrays.asList(onlyBob, bobANDjohn);
    assertTrue(dmnListOfPersonsGrouped.isAssignableValue(the2ListsThatContainBob));
    List<List<Map<String, Object>>> the3Lists = Arrays.asList(onlyBob, bobANDjohn, johnANDnotAPerson);
    assertFalse(dmnListOfPersonsGrouped.isAssignableValue(the3Lists));
    List<Object> groupsOfBobAndBobHimself = Arrays.asList(instanceBob, onlyBob, bobANDjohn);
    // [bob, [bob], [bob, john]] because for the property of FEEL spec a=[a] is equivalent to [[bob], [bob], [bob, john]]
    assertTrue(dmnListOfPersonsGrouped.isAssignableValue(groupsOfBobAndBobHimself));
    DMNType listOfGroups = typeRegistry.registerType(new CompositeTypeImpl(testNS, "listOfGroups", null, true, null, dmnListOfPersonsGrouped, null));
    List<Object> groupsContainingBobPartitionedBySize = Arrays.asList(the2ListsThatContainBob, Arrays.asList(bobANDjohn));
    // [ [[B], [B, J]], [[B, J]] ]
    assertTrue(listOfGroups.isAssignableValue(groupsContainingBobPartitionedBySize));
}
Also used : List(java.util.List) Map(java.util.Map) CompositeTypeImpl(org.kie.dmn.core.impl.CompositeTypeImpl) DMNType(org.kie.dmn.api.core.DMNType) Test(org.junit.Test)

Example 4 with CompositeTypeImpl

use of org.kie.dmn.core.impl.CompositeTypeImpl in project drools by kiegroup.

the class DMNCompilerImpl method resolveTypeRef.

public DMNType resolveTypeRef(DMNModelImpl dmnModel, DMNNode node, NamedElement model, DMNModelInstrumentedBase localElement, QName typeRef) {
    if (typeRef != null) {
        QName nsAndName = getNamespaceAndName(localElement, dmnModel.getImportAliasesForNS(), typeRef);
        DMNType type = dmnModel.getTypeRegistry().resolveType(nsAndName.getNamespaceURI(), nsAndName.getLocalPart());
        if (type == null && DMNModelInstrumentedBase.URI_FEEL.equals(nsAndName.getNamespaceURI())) {
            if (model instanceof Decision && ((Decision) model).getExpression() instanceof DecisionTable) {
                DecisionTable dt = (DecisionTable) ((Decision) model).getExpression();
                if (dt.getOutput().size() > 1) {
                    // implicitly define a type for the decision table result
                    CompositeTypeImpl compType = new CompositeTypeImpl(dmnModel.getNamespace(), model.getName() + "_Type", model.getId(), dt.getHitPolicy().isMultiHit());
                    for (OutputClause oc : dt.getOutput()) {
                        DMNType fieldType = resolveTypeRef(dmnModel, node, model, oc, oc.getTypeRef());
                        compType.addField(oc.getName(), fieldType);
                    }
                    dmnModel.getTypeRegistry().registerType(compType);
                    return compType;
                } else if (dt.getOutput().size() == 1) {
                    return resolveTypeRef(dmnModel, node, model, dt.getOutput().get(0), dt.getOutput().get(0).getTypeRef());
                }
            }
        } else if (type == null) {
            MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, localElement, dmnModel, null, null, Msg.UNKNOWN_TYPE_REF_ON_NODE, typeRef.toString(), localElement.getParentDRDElement().getIdentifierString());
        }
        return type;
    }
    return dmnModel.getTypeRegistry().resolveType(DMNModelInstrumentedBase.URI_FEEL, BuiltInType.UNKNOWN.getName());
}
Also used : OutputClause(org.kie.dmn.model.v1_1.OutputClause) DecisionTable(org.kie.dmn.model.v1_1.DecisionTable) QName(javax.xml.namespace.QName) Decision(org.kie.dmn.model.v1_1.Decision) CompositeTypeImpl(org.kie.dmn.core.impl.CompositeTypeImpl) DMNType(org.kie.dmn.api.core.DMNType)

Example 5 with CompositeTypeImpl

use of org.kie.dmn.core.impl.CompositeTypeImpl in project drools by kiegroup.

the class DMNCompilerTest method testCompositeItemDefinition.

@Test
public void testCompositeItemDefinition() {
    DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0008-LX-arithmetic.dmn", this.getClass());
    DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "0008-LX-arithmetic");
    assertThat(dmnModel, notNullValue());
    ItemDefNode itemDef = dmnModel.getItemDefinitionByName("tLoan");
    assertThat(itemDef.getName(), is("tLoan"));
    assertThat(itemDef.getId(), is("tLoan"));
    DMNType type = itemDef.getType();
    assertThat(type, is(notNullValue()));
    assertThat(type.getName(), is("tLoan"));
    assertThat(type.getId(), is("tLoan"));
    assertThat(type, is(instanceOf(CompositeTypeImpl.class)));
    CompositeTypeImpl compType = (CompositeTypeImpl) type;
    assertThat(compType.getFields().size(), is(3));
    DMNType principal = compType.getFields().get("principal");
    assertThat(principal, is(notNullValue()));
    assertThat(principal.getName(), is("number"));
    assertThat(((SimpleTypeImpl) principal).getFeelType(), is(BuiltInType.NUMBER));
    DMNType rate = compType.getFields().get("rate");
    assertThat(rate, is(notNullValue()));
    assertThat(rate.getName(), is("number"));
    assertThat(((SimpleTypeImpl) rate).getFeelType(), is(BuiltInType.NUMBER));
    DMNType termMonths = compType.getFields().get("termMonths");
    assertThat(termMonths, is(notNullValue()));
    assertThat(termMonths.getName(), is("number"));
    assertThat(((SimpleTypeImpl) termMonths).getFeelType(), is(BuiltInType.NUMBER));
}
Also used : ItemDefNode(org.kie.dmn.api.core.ast.ItemDefNode) DMNRuntime(org.kie.dmn.api.core.DMNRuntime) DMNModel(org.kie.dmn.api.core.DMNModel) CompositeTypeImpl(org.kie.dmn.core.impl.CompositeTypeImpl) DMNType(org.kie.dmn.api.core.DMNType) Test(org.junit.Test)

Aggregations

DMNType (org.kie.dmn.api.core.DMNType)5 CompositeTypeImpl (org.kie.dmn.core.impl.CompositeTypeImpl)5 Map (java.util.Map)2 Test (org.junit.Test)2 Decision (org.kie.dmn.model.v1_1.Decision)2 HashMap (java.util.HashMap)1 List (java.util.List)1 Entry (java.util.Map.Entry)1 Optional (java.util.Optional)1 QName (javax.xml.namespace.QName)1 DMNModel (org.kie.dmn.api.core.DMNModel)1 DMNRuntime (org.kie.dmn.api.core.DMNRuntime)1 BusinessKnowledgeModelNode (org.kie.dmn.api.core.ast.BusinessKnowledgeModelNode)1 DMNNode (org.kie.dmn.api.core.ast.DMNNode)1 DecisionNode (org.kie.dmn.api.core.ast.DecisionNode)1 InputDataNode (org.kie.dmn.api.core.ast.InputDataNode)1 ItemDefNode (org.kie.dmn.api.core.ast.ItemDefNode)1 DMNExpressionEvaluator (org.kie.dmn.core.api.DMNExpressionEvaluator)1 DecisionNodeImpl (org.kie.dmn.core.ast.DecisionNodeImpl)1 BaseDMNTypeImpl (org.kie.dmn.core.impl.BaseDMNTypeImpl)1