killme2008 / aviatorscript Goto Github PK
View Code? Open in Web Editor NEWA high performance scripting language hosted on the JVM.
Home Page: http://fnil.net/aviator/
A high performance scripting language hosted on the JVM.
Home Page: http://fnil.net/aviator/
I want to use aviator in a multi-threading environment. Each thread uses aviator to evaluate expressions. But the AviatorEvaluator.addFunction()
is a static method. So it is global and will influence all threads. But I only want each thread to specify its own functions. Can you make addFunction()
a local method, like an instance method?
AviatorEvaluator.compile("SUM(5, 6)");
如上面的表达式,编译后可以判断是否存在某个自定义函数吗?
com.googlecode.aviator.exception.ExpressionSyntaxErrorException: Syntax error:illegal expression at 12, current token: [type='Number',lexeme='.',index=11]
测试了下,调用clearExpressionCache,清理后,应该用了加载器,这些丢弃的类都无法卸载呢。
类加载器是不是应该不要用一个,直接在生在字节码的时候NEW一个临时加载器,这样就可以卸载了。
需要返回:"你好',
这是我的表达式:AviatorEvaluator.execute("'"你好''"),运行是报错的,请问如果需要返回多个特殊的字符应该怎么写
"8161 == PCV3-8" ,运行时,发现8161是数据,会走数字类型,但是比较值是字符串时报错。
问题点:
if (otherValue instanceof Number) {
return this.innerCompare(AviatorNumber.valueOf(otherValue));
} else {
throw new ExpressionRuntimeException("Could not compare " + this + " with " + other);
}
功能的确很强大,只是效率上低了一丢丢,10000次计算a+b*c平均每次在200ms左右,生产环境下还是慢了些。。。simpleEL快太多了
Double的精度不是很低吗?
例:“2 * 2.33 * 2.44”,看了下源码,通过'.'这个,自动转double,没有设置按统一的Bigdecimal来计算的吗?我知道可以设置成这样"2 * 2.33M * 2.44M", 但数字在字符串中常常是未知的,但是我想要的结果都是通过BigDecimal计算的结果,Double计算的不精确。
现在我的解决方案是把把有的数字都提取出来,再加上“M”,再拼接回去,再计算
我看了下你的源码?没有发现可以统一设置的入口,这真得很让人郁闷,JEP提供这些功能,可以统一设置。
或许我说得是不对的,希望作者回复,看有没有更好的解决方案
本项目与 BeanShell的区别在于? 轻量吗?
你好,aviator如何对list进行过滤?如:
class Foo{
private int i;
private String m;
getter、setter……
}
List<Foo> list = new ArrayList<>();
list.add(new Foo(1,"m"));
list.add(new Foo(2,"n"));
list.add(new Foo(3,"n"));
//需要筛选出list中,i>2 && m=="n" 的list集合?
谢谢!
我想问函数的 overtime 变量在表达式中怎么写呢?
public class TestAviator {
public static void main(String[] args) {
AviatorEvaluator.addFunction(new OrderOvertime());
Map<String, Object> env = new HashMap<>(16);
env.put("overtime", 10);
boolean result = (boolean) AviatorEvaluator.exec("ORDER_OVERTIME(overtime) || false", env);
System.out.println(result);
}
}
public class OrderOvertime extends AbstractFunction {
@Override
public String getName() {
return "ORDER_OVERTIME";
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1) {
Number overtime = FunctionUtils.getNumberValue(arg1, env);
return AviatorBoolean.valueOf(overtime.intValue() > 5);
}
}
1.执行速度快和编译速度优先有什么区别。
2.如果在执行不传入true的第二个参数,每次都进行编译一次会不会造成内存的持续增长。
例如IKExpression写到xml,Fel的"$"直接获取
public void testMap() {
Map mmap = new HashMap<>();
mmap.put("a", "1");
mmap.put("b", "2");
mmap.put("c", "3");
mmap.put("100", "1001");
Map<String, Object> env = new HashMap<String, Object>();
env.put("map", mmap);
// collect
logger.info("☆☆☆ result = {}", AviatorEvaluator.execute("map.a", env));
// error
logger.info("☆☆☆ result = {}", AviatorEvaluator.execute("map.100", env));
}
String s = "timeHourRange(e1_startTime,0,13)";
Map< String, Object > context = new HashMap<>();
AviatorEvaluator.compile( expression, true ).execute( context );// expected false,actuall exception
这样执行就会抛异常,是因为没有e1_startTime参数 Caused by: java.lang.NullPointerException: There is no string namede1_startTime
,这样的情况我想返回false,应该怎么做到呢?急急急啊
1)AviatorEvaluator.execute("4E8_1.0/3E9_1.0");
0.13333333333333333
2)AviatorEvaluator.execute("1E9_1.0/2E10_1.0");
5.0E7--- 这个有问题
3)AviatorEvaluator.execute("1000000000_1.0/20000000000_1.0");
0.05
科学计数法达到一定级别的就报错了(2,3其实表达的数字是一样的)!不知道是不是bug
因为项目中用到了大量的jdk8语法,请问aviator能否支持jdk8的lamba表达式?
非常感谢
Map<String, Object> env = new HashMap<String, Object>();
env.put("users", users);
Object execute3 = AviatorEvaluator.execute("users[0].name",env);其中 users 是list对象。
如果底层用的是commons-beanutils实现的是支持的,我测试过,代码如下:Object indexedProperty = PropertyUtils.getNestedProperty(users, "[0].age");System.out.println(indexedProperty);结果成功输出 第一个元素中年龄age的属性值。所以,大神这个bug是可以修复的,赶紧修复一下吧。哈哈
类似 aa && bb && cc 这样的逻辑表达式,当返回 false 的时候,可能想知道哪个步骤终止了
能否增加一个禁用语法糖的配置选项。比如说在编译表达式替换变量时,变量字符串如果本来就包括'.', '*'这样的关键字时,又不合适去掉的时候,就按照语法糖解析了。
~ /.(iPhone|Mate|华为|三星|vivo|MIUI|小米|魅族|sam sung|samsung)./
String str = "a==3+3";
这个编译为什么能通过呢?感觉不是正常的逻辑啊!计算的时候才报错,我觉得是不是编译的时候就不能通过吧
举个例子:
public class Order{
private List subOrders;
}
public class SubOrder{
private String subOrderId;
}
如果表达式是:order. subOrders可以拿到一个List对象
但是我如果要想获取subOrderId时,表达式如:order.subOrders.subOrderId
这个Aviator无法解析,因为Aviator认为subOrderId是List的属性,
请问,如果想实现上述的问题,Aviator是否支持,表达式该如何描述?
谢谢
how to force the decimal result when integer division result zero, example : 2+(3/5+1)=3.6 not 3.
如果有愿意协助的请联系。
`package com.zork.streaming
import java.util
import com.googlecode.aviator.{AviatorEvaluator, Expression}
/**
Created by sinmes on 16/9/21.
*/
object Test {
var expressList:scala.collection.mutable.MutableList[util.HashMap[String, AnyRef]] = _
def getresult(env: util.HashMap[String, AnyRef]): scala.collection.mutable.MutableList[util.HashMap[String, AnyRef]] = {
val list = new scala.collection.mutable.MutableList[util.HashMap[String, AnyRef]]
for (temp <- expressList){
if ("true".equals(temp.get("expression").asInstanceOf[Expression].execute(env).toString)) {
val maptmp = new util.HashMapString, AnyRef
maptmp.put("event", env.toString)
maptmp.put("info", temp.toString)
list += maptmp
}
}
list
}
def compileExpression (expressionsstr : String) {
expressList = new scala.collection.mutable.MutableList[util.HashMap[String, AnyRef]]
val exstrArray = expressionsstr.split(":")
for (str <- exstrArray) {
var map = new util.HashMapString, AnyRef
map.put("expression", AviatorEvaluator.compile(str))
map.put("alarminfo", str)
expressList += map
}
}
def main(args: Array[String]): Unit = {
val a = Test
a.compileExpression("idea_exe_CpuUsage<1110")
val c = new util.HashMapString, AnyRef
c.put("idea_exe_CpuUsage111", "17.00000".toDouble.asInstanceOf[AnyRef])
c.put("timestamp","1474423160")
c.put("IP", "10.176.3.6")
c.put("hostname", "hl")
c.put("SystemType", "WindowsComputer")
val d = a.getresult(c)
d.foreach(e => {
val itr = e.entrySet().iterator()
while (itr.hasNext){
val tmp = itr.next()
println(tmp.getKey+":"+tmp.getValue)
}
})
}
}
`
输出结果是:
event:{timestamp=1474423160, idea_exe_CpuUsage111=17.0, IP=10.176.3.6, hostname=hl, SystemType=WindowsComputer}
info:{expression=Script_1474599424448_0@606145c5, alarminfo=idea_exe_CpuUsage<1110}
例如以下java代码:
List<User> userList = users.stream()
.filter(user -> user.age > 3 && "张三".equals(user.name))
.collect(Collectors.toList());
升级3.2后莫名的出现这个问题,web服务重启也没做任何改动又恢复了,不知道这种异常是在什么场景下会抛出来。
com.googlecode.aviator.exception.ExpressionRuntimeException: Execute expression error
Caused by: java.lang.NoClassDefFoundError: Script_1514466240951_0
at Script_1514466240951_0/136757698.execute0(Unknown Source) ~[na:na]
at com.googlecode.aviator.ClassExpression.execute(ClassExpression.java:49) ~[aviator-3.2.0.jar:na]
... 17 common frames omitted
Caused by: java.lang.ClassNotFoundException: Script_1514466240951_0
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1333) ~[catalina.jar:8.0.44]
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1167) ~[catalina.jar:8.0.44]
... 19 common frames omitted
为什么“4( * ssss”, 这样的字符串是可以编译通过的,不管4 * (后面跟任何字符串,计算的结果都是4?
在使用时,发现有个语法上的小纠结。
比如我想用mybatis的map文件那样的语法。一堆字符串混合着#{变量名},这种语法比较易用。
而且一看就知道哪个是变量。
但是aviator的语法是类似java那样的语法。需要写很多单引号拼接字符串。
aviator可否支持设置变量前后缀,支持mybatis那样的语法?
假如不支持的话,我想到的办法是,自己做一层转换。
按mybatis语法配置。把函数和变量名都写到#{}里。然后执行表达式前,把#{替换成'+,把}替换成+'。去掉头尾孤立的多余符号。
是否有计划支持复杂的表达式如 if-else 语句?
因为多层级的三元表达式用起来复杂且并不直观
目前在用这个表达式引擎来实现一些excel函数,"&"这个运算符在excel里面是表示内容拼接,我是通过改源码的方式来实现的,如果可以提供运算符重载就很方便了
例如
seq.and(seq.gt(3), seq.lt(10))
用于过滤器等。
我的需求是 类似这样
Matrix a = new Matrix()
Matrix b = new Matrix()
能否重载+ 来计算 a + b
Map<String, Object> map = new HashMap<String, Object>();
List<Map<String, Object>> sublist = new ArrayList<Map<String, Object>>();
HashMap<String,Object> sublistmap=new HashMap<String, Object>();
sublistmap.put("data", "2");
sublist.add(sublistmap);
map.put("sublist", sublist);
HashMap<String, Object> env = new HashMap<String, Object>();
env.put("mmap", map);
System.out.println(AviatorEvaluator.execute("mmap.sublist[0].data", env));
Exception in thread "main" com.googlecode.aviator.exception.ExpressionSyntaxErrorException: Syntax error:illegal expression at 16, current token: [type='Number',lexeme='.',index=15]
at com.googlecode.aviator.parser.ExpressionParser.reportSyntaxError(ExpressionParser.java:622)
AviatorString类的compare方法未考虑this.lexeme为null以及otherString.lexeme为null的情况。这导致以下两种不符合预期的case
return this.lexeme.compareTo(otherString.lexeme);
return this.lexeme.compareTo(String.valueOf(otherJavaValue));
该代码在this.lexeme为null,或者otherString.lexeme为null时,均会抛出空指针异常。
下面是我用到的测试case
public class StringGetFromJsonMapFunction extends AbstractFunction {
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
//blablala
//始终返回null
return new AviatorString(null);
}
@Override
public String getName() {
return "string.getFromJsonMap";
}
}
进行如下测试
@Test
public void testNullPointerException() {
String exp = "string.getFromJsonMap(mapJson, key) == 'abc'";
Map<String, Object> env = Maps.newHashMap();
env.put("mapJson", "{\"key1\":\"value1\", \"key2\":\"value2\"}");
env.put("key", "key3");
//预期返回false,实际上却抛出了空指针异常。
assertEquals(false, (Boolean)AviatorEvaluator.execute(exp, env));
}
@Test
public void testNil() {
String exp = "string.getFromJsonMap(mapJson, key) == nil";
Map<String, Object> env = Maps.newHashMap();
env.put("mapJson", "{\"key1\":\"value1\", \"key2\":\"value2\"}");
env.put("key", "key3");
//预期返回true,实际上却返回false。
assertEquals(true, (Boolean)AviatorEvaluator.execute(exp, env));
}
附AviatorString的compare方法源码 (Aviator 3.0.0版本)
public int compare(AviatorObject other, Map<String, Object> env) {
if (this == other) {
return 0;
}
switch (other.getAviatorType()) {
case String:
AviatorString otherString = (AviatorString) other;
return this.lexeme.compareTo(otherString.lexeme); //可能抛出空指针
case JavaType:
AviatorJavaType javaType = (AviatorJavaType) other;
final Object otherJavaValue = javaType.getValue(env);
if (otherJavaValue == null) {
return 1;
}
if(TypeUtils.isString(otherJavaValue)) {
return this.lexeme.compareTo(String.valueOf(otherJavaValue)); //可能抛出空指针
}
else if (otherJavaValue instanceof Date) {
return this.tryCompareDate((Date) otherJavaValue);
}
else {
throw new ExpressionRuntimeException("Could not compare " + this + " with " + other);
}
case Nil:
return 1; //该分支未考虑this.lexeme为null的情况
default:
throw new ExpressionRuntimeException("Could not compare " + this + " with " + other);
}
}
不知道我的理解是否正确,麻烦看一下这个问题,谢谢。
try {
AviatorEvaluator.setTraceOutputStream(new FileOutputStream(new File("aviator.log")));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
AviatorEvaluator.setOption(Options.TRACE_EVAL, true);
AviatorEvaluator.execute
然后我发现文件中没有相应的数据,我看了下代码
OperationRuntime.java
public static void printTrace(String msg) {
System.out.println("[Aviator TRACE] " + msg);
}
是否应该替换outputString 而不是System.out.println("[Aviator TRACE] " + msg);
我发现,变量的命名,可以包含数字,下划线,中英文等,甚至少量的物殊符号,比如包含$这个变量名称是支持的,但是包含#的变量名称是不支持的,但是我知道我列举的肯定是不全的,所以我很需要一份文档来参考,希望作者考虑下,能不能加下这个文档说明,谢谢。
JRockit 6中不支持Long.compare (AviatorLong.java)
Exception in thread "Main Thread" com.googlecode.aviator.exception.ExpressionRuntimeException: Execute expression error
at com.googlecode.aviator.ClassExpression.execute(ClassExpression.java:59)
at com.etone.project.ebars.engine.MonitortRunner.main(MonitortRunner.java:105)
Caused by: java.lang.NoSuchMethodError: java/lang/Long.compare(JJ)I
at com.googlecode.aviator.runtime.type.AviatorLong.innerCompare(AviatorLong.java:83)
at com.googlecode.aviator.runtime.type.AviatorNumber.compare(AviatorNumber.java:219)
at Script_1377485712923_0.execute0(Unknown Source)
at com.googlecode.aviator.ClassExpression.execute(ClassExpression.java:53)
我自定义的函数GetFirstNonNullFunction类如下:
package com.meituan.rc.zeus.aviator.function;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.type.AviatorObject;
import com.googlecode.aviator.runtime.type.AviatorString;
import java.util.Map;
public class GetFirstNonNullFunction extends AbstractFunction {
private AviatorObject firstNonNull(Map<String, Object> env, AviatorObject... args) {
if (args != null) {
for (AviatorObject arg : args) {
if (arg.getValue(env) != null) {
return arg;
}
}
}
return new AviatorString(null);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
return firstNonNull(env, arg1, arg2);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3) {
return firstNonNull(env, arg1, arg2, arg3);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4) {
return firstNonNull(env, arg1, arg2, arg3, arg4);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6, AviatorObject arg7) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6, AviatorObject arg7, AviatorObject arg8) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6, AviatorObject arg7, AviatorObject arg8, AviatorObject arg9) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6, AviatorObject arg7, AviatorObject arg8, AviatorObject arg9, AviatorObject arg10) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6, AviatorObject arg7, AviatorObject arg8, AviatorObject arg9, AviatorObject arg10, AviatorObject arg11) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6, AviatorObject arg7, AviatorObject arg8, AviatorObject arg9, AviatorObject arg10, AviatorObject arg11, AviatorObject arg12) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6, AviatorObject arg7, AviatorObject arg8, AviatorObject arg9, AviatorObject arg10, AviatorObject arg11, AviatorObject arg12, AviatorObject arg13) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6, AviatorObject arg7, AviatorObject arg8, AviatorObject arg9, AviatorObject arg10, AviatorObject arg11, AviatorObject arg12, AviatorObject arg13, AviatorObject arg14) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6, AviatorObject arg7, AviatorObject arg8, AviatorObject arg9, AviatorObject arg10, AviatorObject arg11, AviatorObject arg12, AviatorObject arg13, AviatorObject arg14, AviatorObject arg15) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6, AviatorObject arg7, AviatorObject arg8, AviatorObject arg9, AviatorObject arg10, AviatorObject arg11, AviatorObject arg12, AviatorObject arg13, AviatorObject arg14, AviatorObject arg15, AviatorObject arg16) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6, AviatorObject arg7, AviatorObject arg8, AviatorObject arg9, AviatorObject arg10, AviatorObject arg11, AviatorObject arg12, AviatorObject arg13, AviatorObject arg14, AviatorObject arg15, AviatorObject arg16, AviatorObject arg17) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6, AviatorObject arg7, AviatorObject arg8, AviatorObject arg9, AviatorObject arg10, AviatorObject arg11, AviatorObject arg12, AviatorObject arg13, AviatorObject arg14, AviatorObject arg15, AviatorObject arg16, AviatorObject arg17, AviatorObject arg18) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6, AviatorObject arg7, AviatorObject arg8, AviatorObject arg9, AviatorObject arg10, AviatorObject arg11, AviatorObject arg12, AviatorObject arg13, AviatorObject arg14, AviatorObject arg15, AviatorObject arg16, AviatorObject arg17, AviatorObject arg18, AviatorObject arg19) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6, AviatorObject arg7, AviatorObject arg8, AviatorObject arg9, AviatorObject arg10, AviatorObject arg11, AviatorObject arg12, AviatorObject arg13, AviatorObject arg14, AviatorObject arg15, AviatorObject arg16, AviatorObject arg17, AviatorObject arg18, AviatorObject arg19, AviatorObject arg20) {
return firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20);
}
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4, AviatorObject arg5, AviatorObject arg6, AviatorObject arg7, AviatorObject arg8, AviatorObject arg9, AviatorObject arg10, AviatorObject arg11, AviatorObject arg12, AviatorObject arg13, AviatorObject arg14, AviatorObject arg15, AviatorObject arg16, AviatorObject arg17, AviatorObject arg18, AviatorObject arg19, AviatorObject arg20, AviatorObject... args) {
AviatorObject result = firstNonNull(env, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20);
if (result.getValue(env) != null) {
return result;
} else {
return firstNonNull(env, args);
}
}
@Override
public String getName() {
return "getFirstNonNull";
}
}
@Override
private String getInvokeMethodDesc(int paramCount) {
StringBuilder sb = new StringBuilder("(Ljava/util/Map;");
for (int i = 0; i < paramCount; i++) {
sb.append("Lcom/googlecode/aviator/runtime/type/AviatorObject;");
}
sb.append(")Lcom/googlecode/aviator/runtime/type/AviatorObject;");
return sb.toString();
}
@Override
public void onMethodInvoke(Token lookhead) {
final MethodMetaData methodMetaData = this.methodMetaDataStack.pop();
final int parameterCount = methodMetaData.parameterCount;
this.mv.visitMethodInsn(INVOKEINTERFACE, "com/googlecode/aviator/runtime/type/AviatorFunction", "call",
this.getInvokeMethodDesc(parameterCount));
this.popOperand(); // method object
this.popOperand(); // env map
// pop operands
for (int i = 0; i < parameterCount; i++) {
this.popOperand();
}
// push result
this.pushOperand(0);
}
发现在getInvokeMethodDesc方法中并未有对参数超过20个时做额外处理转化为数组的代码,因此猜测(当然只是猜测)您是否忽略了参数超过了20个参数时对于反射调用可变参数时的处理,如果是这样,请问能不能支持一下这个特性?(长篇大论了些,请见谅!!!)
我有如下map 对象
{
"E": {
"F": [
{
"H": 1,
"J": {
"A": 12
}
}
}
想取值 E.F[0].H 语法错误,
请问不支持数组map的嵌套取值吗?
结果是一个数组,无法获得第二个元素。我的用法有错误吗?还是不支持
调用 Expression.getVariableNames(), 返回的的是变量的第一层。
如下:
// BaseExpression.java private List varNames; public BaseExpression(List varNames) { super(); LinkedHashSet tmp = new LinkedHashSet(varNames.size()); // process nested names for (String name : varNames) { if (name.contains(".")) { name = name.substring(0, name.indexOf(".")); } tmp.add(name); } this.varNames = new ArrayList(tmp); }
能否增加一个类似 List varFullNames; 的成员,返回变量的全路径?
主要是这样一种场景(业务员编辑业务规则公式),
1、前端业务员进行公示编辑时候,可以通过 AviatorEvaluator.compile(String expression) 来告诉他公式编写是否正确,公式中用到了哪些变量。
2、然后前端业务员可以对变量进行赋值,通过 AviatorEvaluator.execute(String expression, Map<String, Object> env) 来测试公式。
目前提供了基本的逻辑运算符, 但在实际使用中经常有这种场景:
判断某个变量是否在某个常量集合中, 如果能提供类似python的 in 算符就很好了。否则还需要把常量作为变量,再通过include才能实现 。
或者还有其他简便的方法我没看到?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.