use of org.kie.dmn.core.ast.DecisionServiceNodeImpl in project drools by kiegroup.
the class DMNRuntimeImpl method evaluateDecisionService.
@Override
public DMNResult evaluateDecisionService(DMNModel model, DMNContext context, String decisionServiceName) {
Objects.requireNonNull(model, () -> MsgUtil.createMessage(Msg.PARAM_CANNOT_BE_NULL, "model"));
Objects.requireNonNull(context, () -> MsgUtil.createMessage(Msg.PARAM_CANNOT_BE_NULL, "context"));
Objects.requireNonNull(decisionServiceName, () -> MsgUtil.createMessage(Msg.PARAM_CANNOT_BE_NULL, "decisionServiceName"));
boolean typeCheck = performRuntimeTypeCheck(model);
DMNResultImpl result = createResultImpl(model, context);
// the engine should evaluate all belonging to the "local" model namespace, not imported nodes explicitly.
Optional<DecisionServiceNode> lookupDS = ((DMNModelImpl) model).getDecisionServices().stream().filter(d -> d.getModelNamespace().equals(model.getNamespace())).filter(ds -> ds.getName().equals(decisionServiceName)).findFirst();
if (lookupDS.isPresent()) {
DecisionServiceNodeImpl decisionService = (DecisionServiceNodeImpl) lookupDS.get();
for (DMNNode dep : decisionService.getInputParameters().values()) {
if (!isNodeValueDefined(result, decisionService, dep)) {
DMNMessage message = MsgUtil.reportMessage(logger, DMNMessage.Severity.WARN, decisionService.getSource(), result, null, null, Msg.REQ_INPUT_NOT_FOUND_FOR_DS, getDependencyIdentifier(decisionService, dep), getIdentifier(decisionService));
final boolean walkingIntoScope = walkIntoImportScope(result, decisionService, dep);
result.getContext().set(dep.getName(), null);
if (walkingIntoScope) {
result.getContext().popScope();
}
} else {
final boolean walkingIntoScope = walkIntoImportScope(result, decisionService, dep);
final Object originalValue = result.getContext().get(dep.getName());
DMNType depType = ((DMNModelImpl) model).getTypeRegistry().unknown();
if (dep instanceof InputDataNode) {
depType = ((InputDataNode) dep).getType();
} else if (dep instanceof DecisionNode) {
depType = ((DecisionNode) dep).getResultType();
}
Object c = coerceUsingType(originalValue, depType, typeCheck, (r, t) -> MsgUtil.reportMessage(logger, DMNMessage.Severity.WARN, decisionService.getDecisionService(), result, null, null, Msg.PARAMETER_TYPE_MISMATCH_DS, dep.getName(), t, MsgUtil.clipString(r.toString(), 50)));
if (c != originalValue) {
// intentional by-reference
result.getContext().set(dep.getName(), c);
}
if (walkingIntoScope) {
result.getContext().popScope();
}
}
}
// please note singleton output coercion does not influence anyway when invoked DS on a model.
EvaluatorResult evaluate = new DMNDecisionServiceEvaluator(decisionService, true, false).evaluate(this, result);
} else {
MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, null, result, null, null, Msg.DECISION_SERVICE_NOT_FOUND_FOR_NAME, decisionServiceName);
}
return result;
}
use of org.kie.dmn.core.ast.DecisionServiceNodeImpl in project drools by kiegroup.
the class DynamicDMNContextBuilder method populateContextForDecisionServiceWith.
public DMNContext populateContextForDecisionServiceWith(String decisionServiceName, Map<String, Object> json) {
DecisionServiceNode dsNode = model.getDecisionServices().stream().filter(ds -> ds.getName().equals(decisionServiceName)).findFirst().orElseThrow(IllegalArgumentException::new);
for (Entry<String, Object> kv : json.entrySet()) {
DecisionServiceNodeImpl dsNodeImpl = (DecisionServiceNodeImpl) dsNode;
DMNNode node = dsNodeImpl.getInputParameters().get(kv.getKey());
if (node instanceof InputDataNode) {
processInputDataNode(kv, (InputDataNode) node);
} else if (node instanceof DecisionNode) {
processDecisionNode(kv, (DecisionNode) node);
} else {
LOG.debug("The key {} was not a RequiredInput nor a RequiredDecision for the DecisionService, setting it as-is.", kv.getKey());
context.set(kv.getKey(), kv.getValue());
}
}
return context;
}
use of org.kie.dmn.core.ast.DecisionServiceNodeImpl in project drools by kiegroup.
the class DecisionServiceCompiler method compileEvaluator.
@Override
public void compileEvaluator(DMNNode node, DMNCompilerImpl compiler, DMNCompilerContext ctx, DMNModelImpl model) {
DecisionServiceNodeImpl ni = (DecisionServiceNodeImpl) node;
List<DSFormalParameter> parameters = new ArrayList<>();
for (DMNElementReference er : ni.getDecisionService().getInputData()) {
String id = DMNCompilerImpl.getId(er);
InputDataNode input = model.getInputById(id);
String inputNamePrefix = inputQualifiedNamePrefix(input, model);
if (input != null) {
ni.addInputParameter(inputNamePrefix != null ? inputNamePrefix + "." + input.getName() : input.getName(), input);
parameters.add(new DSFormalParameter(inputNamePrefix, input.getName(), input.getType()));
} else {
MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.REFERENCE_NOT_FOUND_FOR_DS, id, node.getName());
}
}
for (DMNElementReference er : ni.getDecisionService().getInputDecision()) {
String id = DMNCompilerImpl.getId(er);
DecisionNode input = model.getDecisionById(id);
String inputNamePrefix = inputQualifiedNamePrefix(input, model);
if (input != null) {
ni.addInputParameter(inputNamePrefix != null ? inputNamePrefix + "." + input.getName() : input.getName(), input);
parameters.add(new DSFormalParameter(inputNamePrefix, input.getName(), input.getResultType()));
} else {
MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.REFERENCE_NOT_FOUND_FOR_DS, id, node.getName());
}
}
for (DMNElementReference er : ni.getDecisionService().getEncapsulatedDecision()) {
String id = DMNCompilerImpl.getId(er);
DecisionNode input = model.getDecisionById(id);
if (input != null) {
// nothing to do.
} else {
MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.REFERENCE_NOT_FOUND_FOR_DS, id, node.getName());
}
}
List<DecisionNode> outputDecisions = new ArrayList<>();
for (DMNElementReference er : ni.getDecisionService().getOutputDecision()) {
String id = DMNCompilerImpl.getId(er);
DecisionNode outDecision = model.getDecisionById(id);
if (outDecision != null) {
outputDecisions.add(outDecision);
} else {
MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.REFERENCE_NOT_FOUND_FOR_DS, id, node.getName());
}
}
boolean coerceSingleton = ((DMNCompilerConfigurationImpl) compiler.getDmnCompilerConfig()).getOption(CoerceDecisionServiceSingletonOutputOption.class).isCoerceSingleton();
DMNDecisionServiceFunctionDefinitionEvaluator exprEvaluator = new DMNDecisionServiceFunctionDefinitionEvaluator(ni, parameters, coerceSingleton);
ni.setEvaluator(exprEvaluator);
if (ni.getType() != null) {
checkFnConsistency(model, ni, ni.getType(), outputDecisions);
}
}
use of org.kie.dmn.core.ast.DecisionServiceNodeImpl in project drools by kiegroup.
the class DecisionServiceCompiler method checkFnConsistency.
private void checkFnConsistency(DMNModelImpl model, DecisionServiceNodeImpl ni, DMNType type, List<DecisionNode> outputDecisions) {
SimpleFnTypeImpl fnType = ((SimpleFnTypeImpl) type);
FunctionItem fi = fnType.getFunctionItem();
if (fi.getParameters().size() != ni.getInputParameters().size()) {
MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.PARAMETER_COUNT_MISMATCH_COMPILING, ni.getName(), fi.getParameters().size(), ni.getInputParameters().size());
return;
}
for (int i = 0; i < fi.getParameters().size(); i++) {
InformationItem fiII = fi.getParameters().get(i);
String fpName = ni.getInputParameters().keySet().stream().skip(i).findFirst().orElse(null);
if (!fiII.getName().equals(fpName)) {
List<String> fiParamNames = fi.getParameters().stream().map(InformationItem::getName).collect(Collectors.toList());
List<String> funcDefParamNames = ni.getInputParameters().keySet().stream().collect(Collectors.toList());
MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.PARAMETER_NAMES_MISMATCH_COMPILING, ni.getName(), fiParamNames, funcDefParamNames);
return;
}
QName fiQname = fiII.getTypeRef();
QName fdQname = null;
DMNNode fpDMNNode = ni.getInputParameters().get(fpName);
if (fpDMNNode instanceof InputDataNodeImpl) {
fdQname = ((InputDataNodeImpl) fpDMNNode).getInputData().getVariable().getTypeRef();
} else if (fpDMNNode instanceof DecisionNodeImpl) {
fdQname = ((DecisionNodeImpl) fpDMNNode).getDecision().getVariable().getTypeRef();
}
if (fiQname != null && fdQname != null && !fiQname.equals(fdQname)) {
MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.PARAMETER_TYPEREF_MISMATCH_COMPILING, ni.getName(), fiII.getName(), fiQname, fdQname);
}
}
QName fiReturnType = fi.getOutputTypeRef();
if (ni.getDecisionService().getOutputDecision().size() == 1) {
QName fdReturnType = outputDecisions.get(0).getDecision().getVariable().getTypeRef();
if (fiReturnType != null && fdReturnType != null && !fiReturnType.equals(fdReturnType)) {
MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.RETURNTYPE_TYPEREF_MISMATCH_COMPILING, ni.getName(), fiReturnType, fdReturnType);
}
} else if (ni.getDecisionService().getOutputDecision().size() > 1) {
final Function<QName, QName> lookupFn = (in) -> DMNCompilerImpl.getNamespaceAndName(ni.getDecisionService(), model.getImportAliasesForNS(), in, model.getNamespace());
LinkedHashMap<String, QName> fdComposite = new LinkedHashMap<>();
for (DecisionNode dn : outputDecisions) {
fdComposite.put(dn.getName(), lookupFn.apply(dn.getDecision().getVariable().getTypeRef()));
}
final QName lookup = lookupFn.apply(fiReturnType);
Optional<ItemDefNodeImpl> composite = model.getItemDefinitions().stream().filter(id -> id.getModelNamespace().equals(lookup.getNamespaceURI()) && id.getName().equals(lookup.getLocalPart())).map(ItemDefNodeImpl.class::cast).findFirst();
if (!composite.isPresent()) {
MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.RETURNTYPE_TYPEREF_MISMATCH_COMPILING, ni.getName(), lookup, fdComposite);
return;
}
LinkedHashMap<String, QName> fiComposite = new LinkedHashMap<>();
for (ItemDefinition ic : composite.get().getItemDef().getItemComponent()) {
fiComposite.put(ic.getName(), lookupFn.apply(ic.getTypeRef()));
}
if (!fiComposite.equals(fdComposite)) {
MsgUtil.reportMessage(LOG, DMNMessage.Severity.ERROR, ni.getDecisionService(), model, null, null, Msg.RETURNTYPE_TYPEREF_MISMATCH_COMPILING, ni.getName(), fiComposite, fdComposite);
}
}
}
use of org.kie.dmn.core.ast.DecisionServiceNodeImpl in project drools by kiegroup.
the class DecisionServiceCompiler method compileNode.
/**
* backport of DMN v1.1
*/
public void compileNode(DecisionService ds, DMNCompilerImpl compiler, DMNModelImpl model) {
DMNType type = null;
DMNType fnType = null;
if (ds.getVariable() == null) {
// even for the v1.1 backport, variable creation is taken care in DMNCompiler.
DMNCompilerHelper.reportMissingVariable(model, ds, ds, Msg.MISSING_VARIABLE_FOR_DS);
return;
}
DMNCompilerHelper.checkVariableName(model, ds, ds.getName());
if (ds.getVariable() != null && ds.getVariable().getTypeRef() != null) {
type = compiler.resolveTypeRef(model, ds, ds.getVariable(), ds.getVariable().getTypeRef());
if (type instanceof SimpleFnTypeImpl) {
fnType = type;
type = ((SimpleFnTypeImpl) type).getReturnType();
}
} else {
// for now the call bellow will return type UNKNOWN
type = compiler.resolveTypeRef(model, ds, ds, null);
}
DecisionServiceNodeImpl bkmn = new DecisionServiceNodeImpl(ds, fnType, type);
model.addDecisionService(bkmn);
}
Aggregations