package org.n3r.eql.util;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import ognl.NoSuchPropertyException;
import ognl.Ognl;
import ognl.OgnlException;
import java.util.Map;
@Slf4j
public class Og {
public static Object eval(String expr, Map<String, Object> mergeProperties,
Map<Object, Map<String, Object>> cachedProperties) {
Exception ex = null;
try {
val nestedExpr = new NestedExpr(expr);
if (nestedExpr.isNested()) {
Object map = evalNested(nestedExpr, mergeProperties, cachedProperties);
if (map != null) return map;
}
return Ognl.getValue(expr, new OgRoot(mergeProperties));
} catch (NoSuchPropertyException e) { // ignore
} catch (OgnlException e) {
if (!e.getMessage().contains("source is null for getProperty"))
ex = e;
} catch (Exception e) {
ex = e;
}
if (ex != null) log.warn("error while eval " + expr, ex);
return null;
}
private static Object evalNested(NestedExpr nestedExpr,
Map<String, Object> mergeProperties,
Map<Object, Map<String, Object>> cachedProperties) {
Object parent = eval(nestedExpr.getParentExpr(), mergeProperties, cachedProperties);
if (!isNormalBean(parent)) return null;
val map = parseBeanProperties(cachedProperties, parent);
return eval(nestedExpr.getSubExpr(), map, cachedProperties);
}
public static boolean isNormalBean(Object parent) {
return parent != null && !(parent instanceof Map);
}
private static Map<String, Object> parseBeanProperties(
Map<Object, Map<String, Object>> cachedProperties, Object parent) {
val map = cachedProperties.get(parent);
if (map != null) return map;
val proxy = MapInvocationHandler.proxy(null, parent);
cachedProperties.put(parent, proxy);
return proxy;
}
}