136 lines
2.9 KiB
Java
136 lines
2.9 KiB
Java
package net.filebot.format;
|
|
|
|
import static net.filebot.util.ExceptionUtilities.*;
|
|
|
|
import java.lang.reflect.Method;
|
|
import java.util.AbstractMap;
|
|
import java.util.HashSet;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.TreeMap;
|
|
|
|
import javax.script.Bindings;
|
|
|
|
public class ExpressionBindings extends AbstractMap<String, Object> implements Bindings {
|
|
|
|
protected final Object bindingBean;
|
|
|
|
protected final Map<String, Method> bindings = new TreeMap<String, Method>(String.CASE_INSENSITIVE_ORDER);
|
|
|
|
protected final Method undefined;
|
|
|
|
public ExpressionBindings(Object bindingBean) {
|
|
this.bindingBean = bindingBean;
|
|
|
|
// get method bindings
|
|
for (Method method : bindingBean.getClass().getMethods()) {
|
|
Define define = method.getAnnotation(Define.class);
|
|
|
|
if (define != null) {
|
|
for (String name : define.value()) {
|
|
Method existingBinding = bindings.put(name, method);
|
|
|
|
if (existingBinding != null)
|
|
throw new IllegalArgumentException(String.format("Illegal binding {%s} on %s", name, method.getName()));
|
|
}
|
|
}
|
|
}
|
|
|
|
// extract mapping that handles undefined bindings
|
|
undefined = bindings.remove(Define.undefined);
|
|
}
|
|
|
|
protected boolean isUndefined(Object value) {
|
|
if (value instanceof CharSequence) {
|
|
return ((CharSequence) value).length() <= 0;
|
|
}
|
|
return value == null;
|
|
}
|
|
|
|
public Object getBindingBean() {
|
|
return bindingBean;
|
|
}
|
|
|
|
@Override
|
|
public Object get(Object key) {
|
|
Method method = bindings.get(key);
|
|
|
|
if (method != null) {
|
|
try {
|
|
Object value = method.invoke(bindingBean);
|
|
if (!isUndefined(value)) {
|
|
return value;
|
|
}
|
|
if (undefined != null) {
|
|
return undefined.invoke(bindingBean, key); // invoke fallback method
|
|
}
|
|
} catch (Exception e) {
|
|
// check InvocationTargetException cause
|
|
if (e.getCause() instanceof NullPointerException) {
|
|
return null;
|
|
}
|
|
if (e.getCause() instanceof BindingException) {
|
|
throw (BindingException) e.getCause();
|
|
}
|
|
throw new BindingException(key.toString(), getRootCauseMessage(e), e);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public Object put(String key, Object value) {
|
|
// bindings are immutable
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public Object remove(Object key) {
|
|
// bindings are immutable
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public boolean containsKey(Object key) {
|
|
return bindings.containsKey(key);
|
|
}
|
|
|
|
@Override
|
|
public Set<String> keySet() {
|
|
return bindings.keySet();
|
|
}
|
|
|
|
@Override
|
|
public boolean isEmpty() {
|
|
return bindings.isEmpty();
|
|
}
|
|
|
|
@Override
|
|
public Set<Entry<String, Object>> entrySet() {
|
|
Set<Entry<String, Object>> entrySet = new HashSet<Entry<String, Object>>();
|
|
|
|
for (final String key : keySet()) {
|
|
entrySet.add(new Entry<String, Object>() {
|
|
|
|
@Override
|
|
public String getKey() {
|
|
return key;
|
|
}
|
|
|
|
@Override
|
|
public Object getValue() {
|
|
return get(key);
|
|
}
|
|
|
|
@Override
|
|
public Object setValue(Object value) {
|
|
return put(key, value);
|
|
}
|
|
});
|
|
}
|
|
|
|
return entrySet;
|
|
}
|
|
|
|
}
|