blob: 37a6fb03db5845a6b636dd8972d6bda2d9e76c5a [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.example;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.jexl3.JexlBuilder;
import org.apache.commons.jexl3.JexlContext;
import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlExpression;
import org.apache.commons.jexl3.JexlScript;
import org.apache.commons.jexl3.MapContext;
import org.apache.commons.jexl3.internal.Engine;
import org.apache.commons.jexl3.internal.TemplateInterpreter;
import org.apache.commons.jexl3.introspection.JexlPermissions;
import org.apache.commons.jexl3.parser.JexlNode;
import org.junit.jupiter.api.Test;
class SomeTest {
/**
* Engine creating dedicated template interpreter.
*/
public static class Engine406 extends Engine {
public Engine406(final JexlBuilder conf) {
super(conf);
}
@Override public TemplateInterpreter createTemplateInterpreter(final TemplateInterpreter.Arguments args) {
return new TemplateInterpreter406(args);
}
}
public static class MyMath {
public double cos(final double x) {
return Math.cos(x);
}
}
public static class TemplateInterpreter406 extends TemplateInterpreter {
protected TemplateInterpreter406(final Arguments args) {
super(args);
}
@Override
public Object interpret(final JexlNode node) {
CALL406.incrementAndGet();
return super.interpret(node);
}
}
/** Counting the number of node interpretation calls. */
static AtomicInteger CALL406 = new AtomicInteger();
@Test
void test406b() {
final JexlEngine jexl = new JexlBuilder() {
@Override
public JexlEngine create() {
return new Engine406(this);
}
}.cache(64).strict(true).safe(false).create();
final String src = "`Call ${x}`";
final JexlScript script = jexl.createScript(src, "x");
Object result = script.execute(null, 406);
assertEquals("Call 406", result);
assertEquals(1, CALL406.get());
result = script.execute(null, 42);
assertEquals("Call 42", result);
assertEquals(2, CALL406.get());
}
/**
* User namespace needs to be allowed through permissions.
*/
@Test
void testCustomFunctionPermissions() {
final Map<String, Object> funcs = new HashMap<>();
funcs.put("math", new MyMath());
final JexlPermissions permissions = JexlPermissions.parse("org.example.*");
final JexlEngine jexl = new JexlBuilder().permissions(permissions).namespaces(funcs).create();
final JexlContext jc = new MapContext();
jc.set("pi", Math.PI);
final JexlExpression e = jexl.createExpression("math:cos(pi)");
final Number result = (Number) e.evaluate(jc);
assertEquals(-1, result.intValue());
}
}