mirror of https://github.com/apache/lucene.git
LUCENE-5207: load available javascript functions from resource file (properties)
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/branches/lucene5207@1523114 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b23b6276cc
commit
ada121d6b0
|
@ -236,7 +236,7 @@ public class JavascriptCompiler {
|
|||
recursiveCompile(current.getChild(argument), ComputedType.DOUBLE);
|
||||
}
|
||||
|
||||
methodVisitor.visitMethodInsn(INVOKESTATIC, method.klass, method.method, method.signature);
|
||||
methodVisitor.visitMethodInsn(INVOKESTATIC, method.klass, method.method, method.descriptor);
|
||||
|
||||
typeCompile(expected, ComputedType.DOUBLE);
|
||||
break;
|
||||
|
|
|
@ -16,11 +16,16 @@ package org.apache.lucene.expressions.js;
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import org.apache.lucene.util.IOUtils;
|
||||
import org.apache.lucene.util.MathUtil;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
|
@ -32,59 +37,48 @@ class JavascriptFunction {
|
|||
private static final Map<String, JavascriptFunction> methods = new HashMap<String, JavascriptFunction>();
|
||||
static {
|
||||
try {
|
||||
addFunction("abs", Math.class.getMethod("abs", double.class));
|
||||
addFunction("acos", Math.class.getMethod("acos", double.class));
|
||||
addFunction("acosh", MathUtil.class.getMethod("acosh", double.class));
|
||||
addFunction("asin", Math.class.getMethod("asin", double.class));
|
||||
addFunction("asinh", MathUtil.class.getMethod("asinh", double.class));
|
||||
addFunction("atan", Math.class.getMethod("atan", double.class));
|
||||
addFunction("atan2", Math.class.getMethod("atan2", double.class, double.class));
|
||||
addFunction("atanh", MathUtil.class.getMethod("atanh", double.class));
|
||||
addFunction("ceil", Math.class.getMethod("ceil", double.class));
|
||||
addFunction("cos", Math.class.getMethod("cos", double.class));
|
||||
addFunction("cosh", Math.class.getMethod("cosh", double.class));
|
||||
addFunction("exp", Math.class.getMethod("exp", double.class));
|
||||
addFunction("floor", Math.class.getMethod("floor", double.class));
|
||||
addFunction("ln", Math.class.getMethod("log", double.class));
|
||||
addFunction("log10", Math.class.getMethod("log10", double.class));
|
||||
addFunction("logn", MathUtil.class.getMethod("log", double.class, double.class));
|
||||
addFunction("max", Math.class.getMethod("max", double.class, double.class));
|
||||
addFunction("min", Math.class.getMethod("min", double.class, double.class));
|
||||
addFunction("pow", Math.class.getMethod("pow", double.class, double.class));
|
||||
addFunction("sin", Math.class.getMethod("sin", double.class));
|
||||
addFunction("sinh", Math.class.getMethod("sinh", double.class));
|
||||
addFunction("sqrt", Math.class.getMethod("sqrt", double.class));
|
||||
addFunction("tan", Math.class.getMethod("tan", double.class));
|
||||
addFunction("tanh", Math.class.getMethod("tanh", double.class));
|
||||
} catch (NoSuchMethodException e) {
|
||||
final Properties props = new Properties();
|
||||
try (Reader in = IOUtils.getDecodingReader(JavascriptFunction.class,
|
||||
JavascriptFunction.class.getSimpleName() + ".properties", IOUtils.CHARSET_UTF_8)) {
|
||||
props.load(in);
|
||||
}
|
||||
for (final String call : props.stringPropertyNames()) {
|
||||
final String[] vals = props.getProperty(call).split(",");
|
||||
if (vals.length != 3) {
|
||||
throw new Error("Syntax error while reading Javascript functions from resource");
|
||||
}
|
||||
final Class<?> clazz = Class.forName(vals[0].trim());
|
||||
final String methodName = vals[1].trim();
|
||||
final int arity = Integer.parseInt(vals[2].trim());
|
||||
@SuppressWarnings({"rawtypes", "unchecked"}) Class[] args = new Class[arity];
|
||||
Arrays.fill(args, double.class);
|
||||
methods.put(call, new JavascriptFunction(call, clazz.getMethod(methodName, args)));
|
||||
}
|
||||
} catch (NoSuchMethodException | ClassNotFoundException | IOException e) {
|
||||
throw new Error("Cannot resolve function", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addFunction(String call, Method method) {
|
||||
methods.put(call, new JavascriptFunction(call, method));
|
||||
}
|
||||
|
||||
public static JavascriptFunction getMethod(String call, int arguments) {
|
||||
public static JavascriptFunction getMethod(String call, int arity) {
|
||||
JavascriptFunction method = methods.get(call);
|
||||
|
||||
if (method == null) {
|
||||
throw new IllegalArgumentException("Unrecognized method call (" + call + ").");
|
||||
}
|
||||
|
||||
if (arguments != method.arguments && method.arguments != -1) {
|
||||
throw new IllegalArgumentException("Expected (" + method.arguments + ") arguments for method call (" +
|
||||
call + "), but found (" + arguments + ").");
|
||||
if (arity != method.arity && method.arity != -1) {
|
||||
throw new IllegalArgumentException("Expected (" + method.arity + ") arguments for method call (" +
|
||||
call + "), but found (" + arity + ").");
|
||||
}
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
public final String call;
|
||||
public final int arguments;
|
||||
public final int arity;
|
||||
public final String klass;
|
||||
public final String method;
|
||||
public final String signature;
|
||||
public final String descriptor;
|
||||
|
||||
private JavascriptFunction(String call, Method method) {
|
||||
// do some checks if the signature is "compatible":
|
||||
|
@ -95,17 +89,10 @@ class JavascriptFunction {
|
|||
throw new Error(method + " does not return a double.");
|
||||
}
|
||||
|
||||
final Class<?>[] paramTypes = method.getParameterTypes();
|
||||
for (final Class<?> paramType : paramTypes) {
|
||||
if (paramType != double.class) {
|
||||
throw new Error(method + " may only take parameters of type 'double'.");
|
||||
}
|
||||
}
|
||||
|
||||
this.call = call;
|
||||
this.arguments = paramTypes.length;
|
||||
this.arity = method.getParameterTypes().length;
|
||||
this.klass = Type.getInternalName(method.getDeclaringClass());
|
||||
this.method = method.getName();
|
||||
this.signature = Type.getMethodDescriptor(method);
|
||||
this.descriptor = Type.getMethodDescriptor(method);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
# 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
|
||||
#
|
||||
# http://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.
|
||||
|
||||
|
||||
# This properties file contains all Javascript functions as keys.
|
||||
# The values are the implementing class, the static method name, and
|
||||
# the number of double parameters.
|
||||
|
||||
abs = java.lang.Math, abs, 1
|
||||
acos = java.lang.Math, acos, 1
|
||||
acosh = org.apache.lucene.util.MathUtil, acosh, 1
|
||||
asin = java.lang.Math, asin, 1
|
||||
asinh = org.apache.lucene.util.MathUtil, asinh, 1
|
||||
atan = java.lang.Math, atan, 1
|
||||
atan2 = java.lang.Math, atan2, 2
|
||||
atanh = org.apache.lucene.util.MathUtil, atanh, 1
|
||||
ceil = java.lang.Math, ceil, 1
|
||||
cos = java.lang.Math, cos, 1
|
||||
cosh = java.lang.Math, cosh, 1
|
||||
exp = java.lang.Math, exp, 1
|
||||
floor = java.lang.Math, floor, 1
|
||||
ln = java.lang.Math, log, 1
|
||||
log10 = java.lang.Math, log10, 1
|
||||
logn = org.apache.lucene.util.MathUtil, log, 2
|
||||
max = java.lang.Math, max, 2
|
||||
min = java.lang.Math, min, 2
|
||||
pow = java.lang.Math, pow, 2
|
||||
sin = java.lang.Math, sin, 1
|
||||
sinh = java.lang.Math, sinh, 1
|
||||
sqrt = java.lang.Math, sqrt, 1
|
||||
tan = java.lang.Math, tan, 1
|
||||
tanh = java.lang.Math, tanh, 1
|
Loading…
Reference in New Issue