use of org.kie.dmn.api.feel.runtime.events.FEELEvent in project drools by kiegroup.
the class DMNDTExpressionEvaluator method processEvents.
private EventResults processEvents(List<FEELEvent> events, DMNRuntimeEventManager eventManager, DMNResultImpl result) {
EventResults r = new EventResults();
for (FEELEvent e : events) {
if (e instanceof DecisionTableRulesMatchedEvent) {
r.matchedRules = ((DecisionTableRulesMatchedEvent) e).getMatches();
} else if (e instanceof DecisionTableRulesSelectedEvent) {
r.fired = ((DecisionTableRulesSelectedEvent) e).getFired();
} else if (e.getSeverity() == FEELEvent.Severity.ERROR) {
MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, ((DMNBaseNode) node).getSource(), result, null, e, Msg.FEEL_ERROR, e.getMessage());
r.hasErrors = true;
} else if (e.getSeverity() == FEELEvent.Severity.WARN) {
MsgUtil.reportMessage(logger, DMNMessage.Severity.WARN, ((DMNBaseNode) node).getSource(), result, null, e, Msg.FEEL_WARN, e.getMessage());
}
}
events.clear();
return r;
}
use of org.kie.dmn.api.feel.runtime.events.FEELEvent in project drools by kiegroup.
the class DMNInvocationEvaluator method hasErrors.
private boolean hasErrors(List<FEELEvent> events, DMNRuntimeEventManager eventManager, DMNResultImpl result) {
boolean hasErrors = false;
for (FEELEvent e : events) {
if (e.getSeverity() == FEELEvent.Severity.ERROR) {
MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, invocation, result, null, e, Msg.FEEL_ERROR, e.getMessage());
hasErrors = true;
}
}
events.clear();
return hasErrors;
}
use of org.kie.dmn.api.feel.runtime.events.FEELEvent in project drools by kiegroup.
the class DMNFEELHelper method valueMatchesInUnaryTests.
public static boolean valueMatchesInUnaryTests(List<UnaryTest> unaryTests, Object value, DMNContext dmnContext) {
FEELEventListenersManager manager = new FEELEventListenersManager();
FEELEventsListenerImpl listener = new FEELEventsListenerImpl();
manager.addListener(listener);
EvaluationContextImpl ctx = new EvaluationContextImpl(manager);
try {
ctx.enterFrame();
if (dmnContext != null) {
// need to set the values for in context variables...
for (Map.Entry<String, Object> entry : dmnContext.getAll().entrySet()) {
ctx.setValue(entry.getKey(), entry.getValue());
}
}
for (UnaryTest t : unaryTests) {
try {
Boolean applyT = t.apply(ctx, value);
// the unary test above can actually return null, so we have to handle it here
if (applyT == null) {
return false;
} else if (applyT) {
return true;
}
} catch (Throwable e) {
StringBuilder message = new StringBuilder();
for (FEELEvent feelEvent : listener.getFeelEvents()) {
message.append(feelEvent.getMessage());
message.append("\n");
}
throw new RuntimeException(message.toString(), e);
}
}
} finally {
ctx.exitFrame();
}
return false;
}
use of org.kie.dmn.api.feel.runtime.events.FEELEvent in project drools by kiegroup.
the class DecisionTableImpl method evaluate.
/**
* Evaluates this decision table returning the result
* @param ctx
* @param params these are the required information items, not to confuse with the columns of the
* decision table that are expressions derived from these parameters
* @return
*/
public FEELFnResult<Object> evaluate(EvaluationContext ctx, Object[] params) {
if (decisionRules.isEmpty()) {
return FEELFnResult.ofError(new FEELEventBase(Severity.WARN, "Decision table is empty", null));
}
Object[] actualInputs = resolveActualInputs(ctx, feel);
Either<FEELEvent, Object> actualInputMatch = actualInputsMatchInputValues(ctx, actualInputs);
if (actualInputMatch.isLeft()) {
return actualInputMatch.cata(e -> FEELFnResult.ofError(e), e -> FEELFnResult.ofError(null));
}
List<DTDecisionRule> matches = findMatches(ctx, actualInputs);
if (!matches.isEmpty()) {
List<Object> results = evaluateResults(ctx, feel, actualInputs, matches);
Map<Integer, String> msgs = checkResults(ctx, matches, results);
if (msgs.isEmpty()) {
Object result = hitPolicy.getDti().dti(ctx, this, actualInputs, matches, results);
return FEELFnResult.ofResult(result);
} else {
List<Integer> offending = msgs.keySet().stream().collect(Collectors.toList());
return FEELFnResult.ofError(new HitPolicyViolationEvent(Severity.ERROR, "Errors found evaluating decision table '" + getName() + "': \n" + (msgs.values().stream().collect(Collectors.joining("\n"))), name, offending));
}
} else {
// check if there is a default value set for the outputs
if (hasDefaultValues) {
Object result = defaultToOutput(ctx, feel);
return FEELFnResult.ofResult(result);
} else {
if (hitPolicy.getDefaultValue() != null) {
return FEELFnResult.ofResult(hitPolicy.getDefaultValue());
}
return FEELFnResult.ofError(new HitPolicyViolationEvent(Severity.WARN, "No rule matched for decision table '" + name + "' and no default values were defined. Setting result to null.", name, Collections.EMPTY_LIST));
}
}
}
use of org.kie.dmn.api.feel.runtime.events.FEELEvent in project drools by kiegroup.
the class BaseFEELFunction method invokeReflectively.
@Override
public Object invokeReflectively(EvaluationContext ctx, Object[] params) {
// use reflection to call the appropriate invoke method
try {
boolean isNamedParams = params.length > 0 && params[0] instanceof NamedParameter;
if (!isCustomFunction()) {
List<String> available = null;
if (isNamedParams) {
available = Stream.of(params).map(p -> ((NamedParameter) p).getName()).collect(Collectors.toList());
}
CandidateMethod cm = getCandidateMethod(ctx, params, isNamedParams, available);
if (cm != null) {
Object result = cm.apply.invoke(this, cm.actualParams);
if (result instanceof Either) {
@SuppressWarnings("unchecked") Either<FEELEvent, Object> either = (Either<FEELEvent, Object>) result;
Object eitherResult = either.cata((left) -> {
ctx.notifyEvt(() -> {
if (left instanceof InvalidParametersEvent) {
InvalidParametersEvent invalidParametersEvent = (InvalidParametersEvent) left;
invalidParametersEvent.setNodeName(getName());
invalidParametersEvent.setActualParameters(Stream.of(cm.apply.getParameters()).map(p -> p.getAnnotation(ParameterName.class).value()).collect(Collectors.toList()), Arrays.asList(cm.actualParams));
}
return left;
});
return null;
}, Function.identity());
return eitherResult;
}
return result;
} else {
String ps = getClass().toString();
logger.error("Unable to find function '" + getName() + "( " + ps.substring(1, ps.length() - 1) + " )'");
ctx.notifyEvt(() -> {
return new FEELEventBase(Severity.ERROR, "Unable to find function '" + getName() + "( " + ps.substring(1, ps.length() - 1) + " )'", null);
});
}
} else {
if (isNamedParams) {
params = rearrangeParameters(params, this.getParameterNames().get(0));
}
Object result = invoke(ctx, params);
if (result instanceof Either) {
@SuppressWarnings("unchecked") Either<FEELEvent, Object> either = (Either<FEELEvent, Object>) result;
final Object[] usedParams = params;
Object eitherResult = either.cata((left) -> {
ctx.notifyEvt(() -> {
if (left instanceof InvalidParametersEvent) {
InvalidParametersEvent invalidParametersEvent = (InvalidParametersEvent) left;
invalidParametersEvent.setNodeName(getName());
invalidParametersEvent.setActualParameters(IntStream.of(0, usedParams.length).mapToObj(i -> "arg" + i).collect(Collectors.toList()), Arrays.asList(usedParams));
}
return left;
});
return null;
}, Function.identity());
return normalizeResult(eitherResult);
}
return normalizeResult(result);
}
} catch (Exception e) {
logger.error("Error trying to call function " + getName() + ".", e);
ctx.notifyEvt(() -> {
return new FEELEventBase(Severity.ERROR, "Error trying to call function " + getName() + ".", e);
});
}
return null;
}
Aggregations