* use proper Groovy DefaultTypeTransformation instead of hacky "value as boolean" script

This commit is contained in:
Reinhard Pointner 2014-04-17 06:14:38 +00:00
parent ed9413afe7
commit 03ce43e6f9
1 changed files with 20 additions and 35 deletions

View File

@ -1,7 +1,5 @@
package net.sourceforge.filebot.format; package net.sourceforge.filebot.format;
import java.security.AccessController; import java.security.AccessController;
import javax.script.Bindings; import javax.script.Bindings;
@ -9,71 +7,58 @@ import javax.script.Compilable;
import javax.script.CompiledScript; import javax.script.CompiledScript;
import javax.script.ScriptContext; import javax.script.ScriptContext;
import javax.script.ScriptException; import javax.script.ScriptException;
import javax.script.SimpleBindings;
import javax.script.SimpleScriptContext; import javax.script.SimpleScriptContext;
import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
public class ExpressionFilter { public class ExpressionFilter {
private final String expression; private final String expression;
private final CompiledScript compiledExpression;
private final CompiledScript userScript;
private final CompiledScript asBooleanScript;
private Throwable lastException; private Throwable lastException;
public ExpressionFilter(String expression) throws ScriptException { public ExpressionFilter(String expression) throws ScriptException {
this.expression = expression; this.expression = expression;
Compilable engine = (Compilable) ExpressionFormat.getGroovyScriptEngine(); Compilable engine = (Compilable) ExpressionFormat.getGroovyScriptEngine();
this.userScript = new SecureCompiledScript(engine.compile(expression)); // sandboxed script this.compiledExpression = new SecureCompiledScript(engine.compile(expression)); // sandboxed script
this.asBooleanScript = engine.compile("value as Boolean");
} }
public String getExpression() { public String getExpression() {
return expression; return expression;
} }
public Throwable getLastException() { public Throwable getLastException() {
return lastException; return lastException;
} }
public boolean matches(Object value) throws ScriptException { public boolean matches(Object value) throws ScriptException {
return matches(new ExpressionBindings(value)); return matches(new ExpressionBindings(value));
} }
public boolean matches(Bindings bindings) throws ScriptException { public boolean matches(Bindings bindings) throws ScriptException {
this.lastException = null; this.lastException = null;
// use privileged bindings so we are not restricted by the script sandbox // use privileged bindings so we are not restricted by the script sandbox
Bindings priviledgedBindings = PrivilegedInvocation.newProxy(Bindings.class, bindings, AccessController.getContext()); Bindings priviledgedBindings = PrivilegedInvocation.newProxy(Bindings.class, bindings, AccessController.getContext());
// initialize script context with the privileged bindings // initialize script context with the privileged bindings
ScriptContext context = new SimpleScriptContext(); ScriptContext context = new SimpleScriptContext();
context.setBindings(priviledgedBindings, ScriptContext.GLOBAL_SCOPE); context.setBindings(priviledgedBindings, ScriptContext.GLOBAL_SCOPE);
try { try {
// evaluate user script // evaluate user script
Object value = userScript.eval(context); Object value = compiledExpression.eval(context);
// convert value to boolean // value as boolean
Bindings valueBinding = new SimpleBindings(); return DefaultTypeTransformation.castToBoolean(value);
valueBinding.put("value", value);
Object result = asBooleanScript.eval(valueBinding);
if (result instanceof Boolean) {
return (Boolean) result;
}
} catch (Throwable e) { } catch (Throwable e) {
// ignore any and all scripting exceptions // ignore any and all scripting exceptions
this.lastException = e; this.lastException = e;
} }
return false; return false;
} }
} }