2009-03-08 15:55:05 -04:00
|
|
|
|
2009-04-04 15:36:12 -04:00
|
|
|
package net.sourceforge.filebot.format;
|
2009-03-08 15:55:05 -04:00
|
|
|
|
|
|
|
|
|
|
|
import java.io.InputStreamReader;
|
|
|
|
import java.text.FieldPosition;
|
|
|
|
import java.text.Format;
|
|
|
|
import java.text.ParsePosition;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.regex.Matcher;
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
import javax.script.Bindings;
|
|
|
|
import javax.script.Compilable;
|
|
|
|
import javax.script.CompiledScript;
|
2009-04-04 15:36:12 -04:00
|
|
|
import javax.script.ScriptContext;
|
2009-03-08 15:55:05 -04:00
|
|
|
import javax.script.ScriptEngine;
|
|
|
|
import javax.script.ScriptException;
|
2009-04-04 15:36:12 -04:00
|
|
|
import javax.script.SimpleScriptContext;
|
2009-03-08 15:55:05 -04:00
|
|
|
|
2009-04-11 19:27:10 -04:00
|
|
|
import com.sun.phobos.script.javascript.RhinoScriptEngine;
|
|
|
|
|
2009-03-08 15:55:05 -04:00
|
|
|
|
2009-04-04 15:36:12 -04:00
|
|
|
public class ExpressionFormat extends Format {
|
2009-03-08 15:55:05 -04:00
|
|
|
|
2009-04-26 09:34:22 -04:00
|
|
|
private final String expression;
|
2009-03-08 15:55:05 -04:00
|
|
|
|
2009-04-26 09:34:22 -04:00
|
|
|
private final Object[] compilation;
|
2009-03-08 15:55:05 -04:00
|
|
|
|
2009-04-04 15:36:12 -04:00
|
|
|
private ScriptException lastException;
|
|
|
|
|
2009-03-08 15:55:05 -04:00
|
|
|
|
2009-04-26 09:34:22 -04:00
|
|
|
public ExpressionFormat(String expression) throws ScriptException {
|
|
|
|
this.expression = expression;
|
|
|
|
this.compilation = compile(expression, (Compilable) initScriptEngine());
|
2009-03-08 15:55:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected ScriptEngine initScriptEngine() throws ScriptException {
|
2009-04-11 19:27:10 -04:00
|
|
|
// don't use jdk rhino so we can use rhino specific features and classes (e.g. Scriptable)
|
|
|
|
ScriptEngine engine = new RhinoScriptEngine();
|
2009-03-08 15:55:05 -04:00
|
|
|
|
2009-04-04 15:36:12 -04:00
|
|
|
engine.eval(new InputStreamReader(ExpressionFormat.class.getResourceAsStream("ExpressionFormat.global.js")));
|
2009-03-08 15:55:05 -04:00
|
|
|
|
|
|
|
return engine;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-26 09:34:22 -04:00
|
|
|
public String getExpression() {
|
|
|
|
return expression;
|
2009-03-08 15:55:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-26 09:34:22 -04:00
|
|
|
protected Object[] compile(String expression, Compilable engine) throws ScriptException {
|
|
|
|
List<Object> compilation = new ArrayList<Object>();
|
2009-03-08 15:55:05 -04:00
|
|
|
|
2009-04-26 09:34:22 -04:00
|
|
|
Matcher matcher = Pattern.compile("\\{([^\\{]*?)\\}").matcher(expression);
|
2009-03-08 15:55:05 -04:00
|
|
|
|
|
|
|
int position = 0;
|
|
|
|
|
|
|
|
while (matcher.find()) {
|
|
|
|
if (position < matcher.start()) {
|
|
|
|
// literal before
|
2009-04-26 09:34:22 -04:00
|
|
|
compilation.add(expression.substring(position, matcher.start()));
|
2009-03-08 15:55:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
String script = matcher.group(1);
|
|
|
|
|
|
|
|
if (script.length() > 0) {
|
|
|
|
// compiled script, or literal
|
2009-04-26 09:34:22 -04:00
|
|
|
compilation.add(engine.compile(script));
|
2009-03-08 15:55:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
position = matcher.end();
|
|
|
|
}
|
|
|
|
|
2009-04-26 09:34:22 -04:00
|
|
|
if (position < expression.length()) {
|
2009-03-08 15:55:05 -04:00
|
|
|
// tail
|
2009-04-26 09:34:22 -04:00
|
|
|
compilation.add(expression.substring(position, expression.length()));
|
2009-03-08 15:55:05 -04:00
|
|
|
}
|
|
|
|
|
2009-04-26 09:34:22 -04:00
|
|
|
return compilation.toArray();
|
2009-03-08 15:55:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-25 03:59:08 -04:00
|
|
|
public Bindings getBindings(Object value) {
|
|
|
|
return new ExpressionBindings(value);
|
2009-04-04 15:36:12 -04:00
|
|
|
}
|
2009-03-08 15:55:05 -04:00
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public StringBuffer format(Object object, StringBuffer sb, FieldPosition pos) {
|
2009-04-25 03:59:08 -04:00
|
|
|
return format(getBindings(object), sb);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public StringBuffer format(Bindings bindings, StringBuffer sb) {
|
2009-04-04 15:36:12 -04:00
|
|
|
ScriptContext context = new SimpleScriptContext();
|
|
|
|
context.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
|
|
|
|
|
2009-04-26 09:34:22 -04:00
|
|
|
for (Object snipped : compilation) {
|
2009-04-25 03:59:08 -04:00
|
|
|
if (snipped instanceof CompiledScript) {
|
|
|
|
try {
|
|
|
|
Object value = ((CompiledScript) snipped).eval(context);
|
|
|
|
|
|
|
|
if (value != null) {
|
|
|
|
sb.append(value);
|
2009-03-08 15:55:05 -04:00
|
|
|
}
|
2009-04-25 03:59:08 -04:00
|
|
|
} catch (ScriptException e) {
|
|
|
|
lastException = e;
|
|
|
|
} catch (Exception e) {
|
|
|
|
lastException = new ScriptException(e);
|
2009-03-08 15:55:05 -04:00
|
|
|
}
|
2009-04-25 03:59:08 -04:00
|
|
|
} else {
|
|
|
|
sb.append(snipped);
|
2009-03-08 15:55:05 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return sb;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-04 15:36:12 -04:00
|
|
|
public ScriptException scriptException() {
|
|
|
|
return lastException;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-03-08 15:55:05 -04:00
|
|
|
@Override
|
|
|
|
public Object parseObject(String source, ParsePosition pos) {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|