@Override public void setRootObject(Object v) { wrapped.setRootObject(v); }
private Object invokeTheFunction(List<String> names, FEELFunction fn, EvaluationContext ctx, Object[] params) { if (names.size() == 1) { Object result = fn.invokeReflectively(ctx, params); return result; } else { try { Object newRoot = ctx.getValue(names.get(0)); ctx.enterFrame(); try { Map<String, Object> asMap = ((Map<String, Object>) newRoot); asMap.forEach(ctx::setValue); } catch (ClassCastException e) { ctx.setRootObject(newRoot); // gracefully handle the less common scenario. } return invokeTheFunction(names.subList(1, names.size()), fn, ctx, params); } finally { ctx.exitFrame(); } } }
private void evaluateExpressionInContext(EvaluationContext ctx, List results, Object v) { try { ctx.enterFrame(); // handle it as a predicate // Have the "item" variable set first, so to respect the DMN spec: The expression in square brackets can reference a list // element using the name item, unless the list element is a context that contains the key "item". ctx.setValue( "item", v ); // using Root object logic to avoid having to eagerly inspect all attributes. ctx.setRootObject(v); // a filter would always return a list with all the elements for which the filter is true. // In case any element fails in there or the filter expression returns null, it will only exclude the element, but will continue to process the list. // In case all elements fail, the result will be an empty list. Object r = this.filter.evaluate(new SilentWrappingEvaluationContextImpl(ctx)); // evaluate filter, ignoring errors if( r instanceof Boolean && ((Boolean)r) == Boolean.TRUE ) { results.add( v ); } } finally { ctx.exitFrame(); } }