/** * Unmarshalls the string into a FEEL value by executing it. * * @param feelType this parameter is ignored by this marshaller and can be set to null * @param value the FEEL code to execute for unmarshalling * * @return the value resulting from executing the code */ @Override public Object unmarshall(Type feelType, String value) { return feel.evaluate( value ); } }
FEEL feel = FEEL.newInstance(runtime.getRootClassLoader(), profiles); Object value = feel.evaluate(expr, variables);
protected void assertResult(final String expression, final Map<String, Type> inputTypes, final Map<String, Object> inputValues, final Object result) { final CompilerContext ctx = feel.newCompilerContext(); inputTypes.forEach(ctx::addInputVariableType); final CompiledExpression compiledExpression = feel.compile(expression, ctx ); if( result == null ) { assertThat( "Evaluating: '" + expression + "'", feel.evaluate( compiledExpression, inputValues ), is( nullValue() ) ); } else if( result instanceof Class<?> ) { assertThat( "Evaluating: '" + expression + "'", feel.evaluate( compiledExpression, inputValues ), is( instanceOf( (Class<?>) result ) ) ); } else { assertThat( "Evaluating: '"+expression+"'", feel.evaluate( compiledExpression, inputValues ), is( result ) ); } }
@Test public void unknownVariable() { final FEEL feel = FEEL.newInstance(); final FEELEventListener fel = Mockito.mock(FEELEventListener.class ); feel.addListener( fel ); final CompilerContext ctx = feel.newCompilerContext(); feel.compile( "a variable name", ctx ); final ArgumentCaptor<FEELEvent> captor = ArgumentCaptor.forClass(FEELEvent.class ); verify( fel, times(2) ).onEvent( captor.capture() ); Assert.assertThat( captor.getAllValues().size(), is( 2 ) ); Assert.assertThat( captor.getAllValues().get(1), is( instanceOf( UnknownVariableErrorEvent.class ) ) ); Assert.assertThat( ((UnknownVariableErrorEvent)captor.getAllValues().get(1)).getOffendingSymbol(), is( "a variable name" ) ); }
/** * Convert row to DTDecisionRule * @param mainCtx the main context is used to identify the hosted FEELEventManager * @param embeddedFEEL a possibly cached embedded FEEL to compile the output expression, error will be reported up to the mainCtx * @param index * @param rule * @param inputSize * @return */ private static DTDecisionRule toDecisionRule(EvaluationContext mainCtx, FEEL embeddedFEEL, int index, List<?> rule, int inputSize) { // TODO should be check indeed block of inputSize n inputs, followed by block of outputs. DTDecisionRule dr = new DTDecisionRule( index ); for ( int i = 0; i < rule.size(); i++ ) { Object o = rule.get( i ); if ( i < inputSize ) { dr.getInputEntry().add( toUnaryTest( mainCtx, o ) ); } else { FEELEventListener ruleListener = event -> mainCtx.notifyEvt( () -> new FEELEventBase(event.getSeverity(), Msg.createMessage(Msg.ERROR_COMPILE_EXPR_DT_FUNCTION_RULE_IDX, index+1, event.getMessage()), event.getSourceException())); embeddedFEEL.addListener(ruleListener); CompiledExpression compiledExpression = embeddedFEEL.compile((String) o, embeddedFEEL.newCompilerContext()); dr.getOutputEntry().add( compiledExpression ); embeddedFEEL.removeListener(ruleListener); } } return dr; }
@Before public void setup() { testVariable = null; feel = FEEL.newInstance(); feel.addListener(event -> testVariable = LISTENER_OUTPUT); feel.addListener(System.out::println); feel.addListener( (evt) -> { if (evt.getSeverity() == Severity.ERROR) System.err.println(evt); } ); }
@Test public void testAllowedValuesForASimpleTypeCollection() { // DROOLS-2357 final String testNS = "testDROOLS2357"; final FEEL feel = FEEL.newInstance(); final DMNType tDecision1 = typeRegistry.registerType(new SimpleTypeImpl(testNS, "tListOfVowels", null, true, feel.evaluateUnaryTests("\"a\",\"e\",\"i\",\"o\",\"u\""), FEEL_STRING, BuiltInType.STRING)); assertTrue(tDecision1.isAssignableValue("a")); assertTrue(tDecision1.isAssignableValue(Collections.singletonList("a"))); assertFalse(tDecision1.isAssignableValue("z")); assertTrue(tDecision1.isAssignableValue(Arrays.asList("a", "e"))); assertFalse(tDecision1.isAssignableValue(Arrays.asList("a", "e", "zzz"))); }
@Test public void testExpression() { feel = (testFEELTarget == FEEL_TARGET.JAVA_TRANSLATED) ? FEEL.newInstance(Collections.singletonList(new DoCompileFEELProfile())) : FEEL.newInstance(); assertResult( expression, inputTypes, inputValues, result ); }
@Override public boolean evaluate(Object rawExpression, Object resultValue, Class<?> resultClass) { if (rawExpression != null && !(rawExpression instanceof String)) { throw new IllegalArgumentException("Raw expression should be a string"); } EvaluationContext evaluationContext = newEvaluationContext(); List<UnaryTest> unaryTests = feel.evaluateUnaryTests((String) rawExpression); if(unaryTests.size() < 1) { throw new IllegalArgumentException("Impossible to parse the expression '" + rawExpression + "'"); } return unaryTests.stream().allMatch(unaryTest -> unaryTest.apply(evaluationContext, resultValue)); }
@After public void after() { feel.removeListener( errorsCountingListener ); }
@Before public void before() { errors = new ArrayList<>(); errorsCountingListener = evt -> { if ( evt.getSeverity() == Severity.ERROR ) { errors.add(evt); } }; feel.addListener( errorsCountingListener ); }
@Test public void test2() { CompilerContext ctx = feel.newCompilerContext(); ctx.addInputVariableType( "MyPerson", new MapBackedType().addField( "FullName", BuiltInType.STRING ) ); CompiledExpression compiledExpression = feel.compile( "MyPerson.fullName", ctx ); assertThat(errors.toString(), errors.size(), is(1) ); Map<String, Object> inputs = new HashMap<>(); inputs.put( "MyPerson", prototype(entry("FullName", "John Doe")) ); Object result = feel.evaluate(compiledExpression, inputs); assertThat(result, nullValue()); }
@Test public void testExpression() { final List<FEELProfile> profiles = getFEELProfilesForTests(); feel = FEEL.newInstance(profiles); final FEELEventListener listener = mock(FEELEventListener.class ); feel.addListener( listener ); feel.addListener(System.out::println); assertResult( expression, result ); if( severity != null ) { final ArgumentCaptor<FEELEvent> captor = ArgumentCaptor.forClass(FEELEvent.class ); verify( listener , atLeastOnce()).onEvent( captor.capture() ); assertThat( captor.getValue().getSeverity(), is( severity ) ); } else { verify( listener, never() ).onEvent( any(FEELEvent.class) ); } }
FEEL feel = FEEL.newInstance(); List<DTDecisionRule> decisionRules = IntStream.range( 0, ruleList.size() ) .mapToObj( index -> toDecisionRule( ctx, feel, index, ruleList.get( index ), inputExpressions.size() ) ) DecisionTableImpl dti = new DecisionTableImpl(UUID.randomUUID().toString(), inputExpressions, inputs, outputClauses, decisionRules, HitPolicy.fromString(hitPolicy), FEEL.newInstance()); return new DTInvokerFunction( dti );
@Override public Object getValueForGiven(String className, Object raw) { if (!(raw instanceof String)) { return raw; } EvaluationContext evaluationContext = newEvaluationContext(); return feel.evaluate((String) raw, evaluationContext); }
@Test public void test2OK() { CompilerContext ctx = feel.newCompilerContext(); ctx.addInputVariableType( "MyPerson", new MapBackedType().addField( "FullName", BuiltInType.STRING ) ); CompiledExpression compiledExpression = feel.compile( "MyPerson.FullName", ctx ); Map<String, Object> inputs = new HashMap<>(); inputs.put( "MyPerson", prototype(entry("FullName", "John Doe")) ); Object result = feel.evaluate(compiledExpression, inputs); assertThat(result, is("John Doe")); } }
@BeforeClass public static void setupTest() { String expression = loadExpression( "example_10_6_1.feel" ); feel = FEEL.newInstance(); context = (Map) feel.evaluate( expression ); }
private Object[] resolveActualInputs(EvaluationContext ctx, FEEL feel) { Map<String, Object> variables = ctx.getAllValues(); Object[] actualInputs = new Object[ inputs.size() ]; for( int i = 0; i < inputs.size(); i++ ) { CompiledExpression compiledInput = inputs.get( i ).getCompiledInput(); if( compiledInput != null ) { actualInputs[i] = feel.evaluate( compiledInput, variables ); } else { actualInputs[i] = feel.evaluate( inputs.get( i ).getInputExpression(), variables ); } } return actualInputs; }
@Test public void test_isDynamicResolution() { CompilerContext ctx = feel.newCompilerContext(); ctx.addInputVariableType( "Person List", BuiltInType.LIST); CompiledExpression compiledExpression = feel.compile( "Person List[My Variable 1 = \"A\"]", ctx ); assertThat(errors.toString(), errors.size(), is(0) ); Map<String, Object> inputs = new HashMap<>(); List<Map<String, ?>> pList = new ArrayList<>(); inputs.put("Person List", pList); pList.add(prototype(entry("Full Name", "Edson Tirelli"), entry("My Variable 1","A")) ); pList.add(prototype(entry("Full Name", "Matteo Mortari"), entry("My Variable 1","B")) ); Object result = feel.evaluate(compiledExpression, inputs); assertThat( result, instanceOf( List.class ) ); assertThat( (List<?>) result, hasSize(1) ); assertThat( ((Map<?, ?>) ((List<?>) result).get(0)).get("Full Name"), is("Edson Tirelli") ); }
FEEL feel = FEEL.newInstance(runtime.getRootClassLoader(), profiles); Object value = feel.evaluate(expr, variables);