private void registerExpressionFunctions(Stream<FunctionModel> functions, ExpressionModule.Builder module) { final FunctionParameterDefaultValueResolverFactory valueResolverFactory = (defaultValue, type) -> context -> { ExtendedExpressionManager em = muleContext.getExpressionManager(); String value = String.valueOf(defaultValue); return em.isExpression(value) ? em.evaluate(value, type, context) : new TypedValue<>(defaultValue, type); }; functions.forEach(function -> function.getModelProperty(FunctionExecutorModelProperty.class).ifPresent(mp -> { FunctionExecutor executor = mp.getExecutorFactory().createExecutor(function, valueResolverFactory); lifecycleAwareElements.add(executor); module.addBinding(function.getName(), new TypedValue<>(executor, fromFunction(executor))); })); }
@Test public void buildFunction() { FunctionDataType dataType = (FunctionDataType) DataType.fromFunction(new SomeFunction()); // Return type assertThat(dataType.getReturnType().isPresent(), is(true)); assertThat(dataType.getReturnType().get(), equalTo(STRING)); // Parameters assertThat(dataType.getParameters(), hasSize(2)); FunctionParameter first = dataType.getParameters().get(0); assertThat(first.getName(), is("fst")); assertThat(first.getType(), equalTo(NUMBER)); assertThat(first.getDefaultValueResolver(), nullValue()); FunctionParameter second = dataType.getParameters().get(1); assertThat(second.getName(), is("snd")); assertThat(second.getType(), equalTo(OBJECT)); // Default assertThat(second.getDefaultValueResolver().getDefaultValue(builder().build()), is("wow")); }
@Override public BindingContext getBindingContext() { TestExpressionFunction function = new TestExpressionFunction(); return builder() .addBinding("number", new TypedValue(1, NUMBER)) .addBinding("repeat", new TypedValue(function, fromFunction(function))) .build(); } }
BindingContext context = BindingContext.builder() .addBinding(global, new TypedValue(value, STRING)) .addBinding("upper", new TypedValue(expressionFunction, fromFunction(expressionFunction))) .build(); expressionLanguageAdapter.addGlobalBindings(context);
@Test @Description("Verifies that global bindings can be added.") public void globals() { DataType integerType = fromType(Integer.class); ExpressionFunction multiply = new ExpressionFunction() { @Override public Object call(Object[] objects, BindingContext bindingContext) { return ((Integer) objects[0]) * ((Integer) objects[1]); } @Override public Optional<DataType> returnType() { return of(integerType); } @Override public List<FunctionParameter> parameters() { return asList(new FunctionParameter("x", integerType), new FunctionParameter("y", integerType)); } }; BindingContext globalContext = builder() .addBinding("aNum", new TypedValue<>(4, fromType(Integer.class))) .addBinding("times", new TypedValue<>(multiply, fromFunction(multiply))) .build(); expressionManager.addGlobalBindings(globalContext); TypedValue result = expressionManager.evaluate("aNum times 5"); assertThat(result.getValue(), is(20)); expressionManager.addGlobalBindings(builder().addBinding("otherNum", new TypedValue(3, integerType)).build()); result = expressionManager.evaluate("(times(7, 3) + otherNum) / aNum"); assertThat(result.getValue(), is(6)); }
@Override public BindingContext getBindingContext() { BindingContext.Builder builder = BindingContext.builder(); PropertyAccessFunction propertyFunction = new PropertyAccessFunction(configurationProperties); builder.addBinding("p", new TypedValue(propertyFunction, fromFunction(propertyFunction))); ExpressionFunction lookupFunction = new LookupFunction(componentLocator); builder.addBinding("lookup", new TypedValue(lookupFunction, fromFunction(lookupFunction))); ExpressionFunction causedByFunction = new CausedByFunction(errorTypeRepository); builder.addBinding("causedBy", new TypedValue(causedByFunction, fromFunction(causedByFunction))); return builder.build(); }
private void registerExpressionFunctions(Stream<FunctionModel> functions, ExpressionModule.Builder module) { final FunctionParameterDefaultValueResolverFactory valueResolverFactory = (defaultValue, type) -> context -> { ExtendedExpressionManager em = muleContext.getExpressionManager(); String value = String.valueOf(defaultValue); return em.isExpression(value) ? em.evaluate(value, type, context) : new TypedValue<>(defaultValue, type); }; functions.forEach(function -> function.getModelProperty(FunctionExecutorModelProperty.class).ifPresent(mp -> { FunctionExecutor executor = mp.getExecutorFactory().createExecutor(function, valueResolverFactory); lifecycleAwareElements.add(executor); module.addBinding(function.getName(), new TypedValue<>(executor, fromFunction(executor))); })); }
@Test public void buildFunction() { FunctionDataType dataType = (FunctionDataType) DataType.fromFunction(new SomeFunction()); // Return type assertThat(dataType.getReturnType().isPresent(), is(true)); assertThat(dataType.getReturnType().get(), equalTo(STRING)); // Parameters assertThat(dataType.getParameters(), hasSize(2)); FunctionParameter first = dataType.getParameters().get(0); assertThat(first.getName(), is("fst")); assertThat(first.getType(), equalTo(NUMBER)); assertThat(first.getDefaultValueResolver(), nullValue()); FunctionParameter second = dataType.getParameters().get(1); assertThat(second.getName(), is("snd")); assertThat(second.getType(), equalTo(OBJECT)); // Default assertThat(second.getDefaultValueResolver().getDefaultValue(builder().build()), is("wow")); }
@Override public BindingContext getBindingContext() { TestExpressionFunction function = new TestExpressionFunction(); return builder() .addBinding("number", new TypedValue(1, NUMBER)) .addBinding("repeat", new TypedValue(function, fromFunction(function))) .build(); } }
@Test @Description("Verifies that global bindings can be added.") public void globals() { DataType integerType = fromType(Integer.class); ExpressionFunction multiply = new ExpressionFunction() { @Override public Object call(Object[] objects, BindingContext bindingContext) { return ((Integer) objects[0]) * ((Integer) objects[1]); } @Override public Optional<DataType> returnType() { return of(integerType); } @Override public List<FunctionParameter> parameters() { return asList(new FunctionParameter("x", integerType), new FunctionParameter("y", integerType)); } }; BindingContext globalContext = builder() .addBinding("aNum", new TypedValue<>(4, fromType(Integer.class))) .addBinding("times", new TypedValue<>(multiply, fromFunction(multiply))) .build(); expressionManager.addGlobalBindings(globalContext); TypedValue result = expressionManager.evaluate("aNum times 5"); assertThat(result.getValue(), is(20)); expressionManager.addGlobalBindings(builder().addBinding("otherNum", new TypedValue(3, integerType)).build()); result = expressionManager.evaluate("(times(7, 3) + otherNum) / aNum"); assertThat(result.getValue(), is(6)); }
BindingContext context = BindingContext.builder() .addBinding(global, new TypedValue(value, STRING)) .addBinding("upper", new TypedValue(expressionFunction, fromFunction(expressionFunction))) .build(); expressionLanguageAdapter.addGlobalBindings(context);