use of org.mvel2.optimizers.impl.refl.nodes.MapAccessorNest in project mvel by mikebrock.
the class ReflectiveAccessorOptimizer method optimizeSetAccessor.
public Accessor optimizeSetAccessor(ParserContext pCtx, char[] property, int start, int offset, Object ctx, Object thisRef, VariableResolverFactory factory, boolean rootThisRef, Object value, Class ingressType) {
this.rootNode = this.currNode = null;
this.expr = property;
this.start = start;
this.first = true;
this.length = start + offset;
this.ctx = ctx;
this.thisRef = thisRef;
this.variableFactory = factory;
this.ingressType = ingressType;
char[] root = null;
int split = findLastUnion();
PropertyVerifier verifier = new PropertyVerifier(property, this.pCtx = pCtx);
if (split != -1) {
root = subset(property, 0, split++);
// todo: must use the property verifier.
property = subset(property, split, property.length - split);
}
if (root != null) {
this.length = end = (this.expr = root).length;
compileGetChain();
ctx = this.val;
}
if (ctx == null) {
throw new PropertyAccessException("could not access property: " + new String(property, this.start, length) + "; parent is null: " + new String(expr), expr, this.start);
}
try {
this.length = end = (this.expr = property).length;
int st;
this.cursor = st = 0;
skipWhitespace();
if (collection) {
st = cursor;
if (cursor == end)
throw new PropertyAccessException("unterminated '['", expr, this.start);
if (scanTo(']'))
throw new PropertyAccessException("unterminated '['", expr, this.start);
String ex = new String(property, st, cursor - st);
if (ctx instanceof Map) {
if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(Map.class)) {
propHandlerSet(ex, ctx, Map.class, value);
} else {
// noinspection unchecked
((Map) ctx).put(eval(ex, ctx, variableFactory), convert(value, returnType = verifier.analyze()));
addAccessorNode(new MapAccessorNest(ex, returnType));
}
return rootNode;
} else if (ctx instanceof List) {
if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(List.class)) {
propHandlerSet(ex, ctx, List.class, value);
} else {
// noinspection unchecked
((List) ctx).set(eval(ex, ctx, variableFactory, Integer.class), convert(value, returnType = verifier.analyze()));
addAccessorNode(new ListAccessorNest(ex, returnType));
}
return rootNode;
} else if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(ctx.getClass())) {
propHandlerSet(ex, ctx, ctx.getClass(), value);
return rootNode;
} else if (ctx.getClass().isArray()) {
if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(Array.class)) {
propHandlerSet(ex, ctx, Array.class, value);
} else {
// noinspection unchecked
Array.set(ctx, eval(ex, ctx, variableFactory, Integer.class), convert(value, getBaseComponentType(ctx.getClass())));
addAccessorNode(new ArrayAccessorNest(ex));
}
return rootNode;
} else {
throw new PropertyAccessException("cannot bind to collection property: " + new String(property) + ": not a recognized collection type: " + ctx.getClass(), expr, this.st);
}
} else if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(ctx.getClass())) {
propHandlerSet(new String(property), ctx, ctx.getClass(), value);
return rootNode;
}
String tk = new String(property, 0, length);
if (hasSetListeners()) {
notifySetListeners(ctx, tk, variableFactory, value);
addAccessorNode(new Notify(tk));
}
Member member = getFieldOrWriteAccessor(ctx.getClass(), tk, value == null ? null : ingressType);
if (member instanceof Field) {
Field fld = (Field) member;
if (value != null && !fld.getType().isAssignableFrom(value.getClass())) {
if (!canConvert(fld.getType(), value.getClass())) {
throw new CompileException("cannot convert type: " + value.getClass() + ": to " + fld.getType(), this.expr, this.start);
}
fld.set(ctx, convert(value, fld.getType()));
addAccessorNode(new DynamicFieldAccessor(fld));
} else if (value == null && fld.getType().isPrimitive()) {
fld.set(ctx, PropertyTools.getPrimitiveInitialValue(fld.getType()));
addAccessorNode(new FieldAccessor(fld));
} else {
fld.set(ctx, value);
addAccessorNode(new FieldAccessor(fld));
}
} else if (member != null) {
Method meth = (Method) member;
if (value != null && !meth.getParameterTypes()[0].isAssignableFrom(value.getClass())) {
if (!canConvert(meth.getParameterTypes()[0], value.getClass())) {
throw new CompileException("cannot convert type: " + value.getClass() + ": to " + meth.getParameterTypes()[0], this.expr, this.start);
}
meth.invoke(ctx, convert(value, meth.getParameterTypes()[0]));
} else if (value == null && meth.getParameterTypes()[0].isPrimitive()) {
meth.invoke(ctx, PropertyTools.getPrimitiveInitialValue(meth.getParameterTypes()[0]));
} else {
meth.invoke(ctx, value);
}
addAccessorNode(new SetterAccessor(meth));
} else if (ctx instanceof Map) {
// noinspection unchecked
((Map) ctx).put(tk, value);
addAccessorNode(new MapAccessor(tk));
} else {
throw new PropertyAccessException("could not access property (" + tk + ") in: " + ingressType.getName(), this.expr, this.start);
}
} catch (InvocationTargetException e) {
throw new PropertyAccessException("could not access property: " + new String(property), this.expr, st, e);
} catch (IllegalAccessException e) {
throw new PropertyAccessException("could not access property: " + new String(property), this.expr, st, e);
} catch (IllegalArgumentException e) {
throw new PropertyAccessException("error binding property: " + new String(property) + " (value <<" + value + ">>::" + (value == null ? "null" : value.getClass().getCanonicalName()) + ")", this.expr, st, e);
}
return rootNode;
}
use of org.mvel2.optimizers.impl.refl.nodes.MapAccessorNest in project mvel by mvel.
the class ReflectiveAccessorOptimizer method optimizeSetAccessor.
public Accessor optimizeSetAccessor(ParserContext pCtx, char[] property, int start, int offset, Object ctx, Object thisRef, VariableResolverFactory factory, boolean rootThisRef, Object value, Class ingressType) {
this.rootNode = this.currNode = null;
this.expr = property;
this.start = start;
this.first = true;
this.length = start + offset;
this.ctx = ctx;
this.thisRef = thisRef;
this.variableFactory = factory;
this.ingressType = ingressType;
char[] root = null;
int split = findLastUnion();
PropertyVerifier verifier = new PropertyVerifier(property, this.pCtx = pCtx);
if (split != -1) {
root = subset(property, 0, split++);
// todo: must use the property verifier.
property = subset(property, split, property.length - split);
}
if (root != null) {
this.length = end = (this.expr = root).length;
compileGetChain();
ctx = this.val;
}
if (ctx == null) {
throw new PropertyAccessException("could not access property: " + new String(property, this.start, Math.min(length, property.length)) + "; parent is null: " + new String(expr), expr, this.start, pCtx);
}
try {
this.length = end = (this.expr = property).length;
int st;
this.cursor = st = 0;
skipWhitespace();
if (collection) {
st = cursor;
if (cursor == end)
throw new PropertyAccessException("unterminated '['", expr, this.start, pCtx);
if (scanTo(']'))
throw new PropertyAccessException("unterminated '['", expr, this.start, pCtx);
String ex = new String(property, st, cursor - st);
if (ctx instanceof Map) {
if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(Map.class)) {
propHandlerSet(ex, ctx, Map.class, value);
} else {
// noinspection unchecked
((Map) ctx).put(eval(ex, ctx, variableFactory), convert(value, returnType = verifier.analyze()));
addAccessorNode(new MapAccessorNest(ex, returnType));
}
return rootNode;
} else if (ctx instanceof List) {
if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(List.class)) {
propHandlerSet(ex, ctx, List.class, value);
} else {
// noinspection unchecked
((List) ctx).set(eval(ex, ctx, variableFactory, Integer.class), convert(value, returnType = verifier.analyze()));
addAccessorNode(new ListAccessorNest(ex, returnType));
}
return rootNode;
} else if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(ctx.getClass())) {
propHandlerSet(ex, ctx, ctx.getClass(), value);
return rootNode;
} else if (ctx.getClass().isArray()) {
if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(Array.class)) {
propHandlerSet(ex, ctx, Array.class, value);
} else {
// noinspection unchecked
Array.set(ctx, eval(ex, ctx, variableFactory, Integer.class), convert(value, getBaseComponentType(ctx.getClass())));
addAccessorNode(new ArrayAccessorNest(ex));
}
return rootNode;
} else {
throw new PropertyAccessException("cannot bind to collection property: " + new String(property) + ": not a recognized collection type: " + ctx.getClass(), expr, this.st, pCtx);
}
} else if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(ctx.getClass())) {
propHandlerSet(new String(property), ctx, ctx.getClass(), value);
return rootNode;
}
String tk = new String(property, 0, length).trim();
if (hasSetListeners()) {
notifySetListeners(ctx, tk, variableFactory, value);
addAccessorNode(new Notify(tk));
}
Member member = getFieldOrWriteAccessor(ctx.getClass(), tk, value == null ? null : ingressType);
if (member instanceof Field) {
Field fld = (Field) member;
if (value != null && !fld.getType().isAssignableFrom(value.getClass())) {
if (!canConvert(fld.getType(), value.getClass())) {
throw new CompileException("cannot convert type: " + value.getClass() + ": to " + fld.getType(), this.expr, this.start);
}
fld.set(ctx, convert(value, fld.getType()));
addAccessorNode(new DynamicFieldAccessor(fld));
} else if (value == null && fld.getType().isPrimitive()) {
fld.set(ctx, PropertyTools.getPrimitiveInitialValue(fld.getType()));
addAccessorNode(new FieldAccessor(fld));
} else {
fld.set(ctx, value);
addAccessorNode(new FieldAccessor(fld));
}
} else if (member != null) {
Method meth = (Method) member;
if (value != null && !meth.getParameterTypes()[0].isAssignableFrom(value.getClass())) {
if (!canConvert(meth.getParameterTypes()[0], value.getClass())) {
throw new CompileException("cannot convert type: " + value.getClass() + ": to " + meth.getParameterTypes()[0], this.expr, this.start);
}
meth.invoke(ctx, convert(value, meth.getParameterTypes()[0]));
} else if (value == null && meth.getParameterTypes()[0].isPrimitive()) {
meth.invoke(ctx, PropertyTools.getPrimitiveInitialValue(meth.getParameterTypes()[0]));
} else {
meth.invoke(ctx, value);
}
addAccessorNode(new SetterAccessor(meth));
} else if (ctx instanceof Map) {
// noinspection unchecked
((Map) ctx).put(tk, value);
addAccessorNode(new MapAccessor(tk));
} else {
throw new PropertyAccessException("could not access property (" + tk + ") in: " + ingressType.getName(), this.expr, this.start, pCtx);
}
} catch (InvocationTargetException e) {
throw new PropertyAccessException("could not access property: " + new String(property), this.expr, st, e, pCtx);
} catch (IllegalAccessException e) {
throw new PropertyAccessException("could not access property: " + new String(property), this.expr, st, e, pCtx);
} catch (IllegalArgumentException e) {
throw new PropertyAccessException("error binding property: " + new String(property) + " (value <<" + value + ">>::" + (value == null ? "null" : value.getClass().getCanonicalName()) + ")", this.expr, st, e, pCtx);
}
return rootNode;
}
use of org.mvel2.optimizers.impl.refl.nodes.MapAccessorNest in project mvel by mvel.
the class ReflectiveAccessorOptimizer method getCollectionProperty.
/**
* Handle accessing a property embedded in a collections, map, or array
*
* @param ctx -
* @param prop -
* @return -
* @throws Exception -
*/
private Object getCollectionProperty(Object ctx, String prop) throws Exception {
if (prop.length() > 0) {
ctx = getBeanProperty(ctx, prop);
}
currType = null;
if (ctx == null)
return null;
int start = ++cursor;
skipWhitespace();
if (cursor == end)
throw new CompileException("unterminated '['", this.expr, this.start);
String item;
if (scanTo(']'))
throw new CompileException("unterminated '['", this.expr, this.start);
item = new String(expr, start, cursor - start);
boolean itemSubExpr = true;
Object idx = null;
try {
idx = parseInt(item);
itemSubExpr = false;
} catch (Exception e) {
// not a number;
}
ExecutableStatement itemStmt = null;
if (itemSubExpr) {
try {
idx = (itemStmt = (ExecutableStatement) subCompileExpression(item.toCharArray(), pCtx)).getValue(thisRef, thisRef, variableFactory);
} catch (CompileException e) {
e.setExpr(this.expr);
e.setCursor(start);
throw e;
}
}
++cursor;
if (ctx instanceof Map) {
if (itemSubExpr) {
addAccessorNode(new MapAccessorNest(itemStmt, null));
} else {
addAccessorNode(new MapAccessor(parseInt(item)));
}
return ((Map) ctx).get(idx);
} else if (ctx instanceof List) {
if (itemSubExpr) {
addAccessorNode(new ListAccessorNest(itemStmt, null));
} else {
addAccessorNode(new ListAccessor(parseInt(item)));
}
return ((List) ctx).get((Integer) idx);
} else if (ctx.getClass().isArray()) {
if (itemSubExpr) {
addAccessorNode(new ArrayAccessorNest(itemStmt));
} else {
addAccessorNode(new ArrayAccessor(parseInt(item)));
}
return Array.get(ctx, (Integer) idx);
} else if (ctx instanceof CharSequence) {
if (itemSubExpr) {
addAccessorNode(new IndexedCharSeqAccessorNest(itemStmt));
} else {
addAccessorNode(new IndexedCharSeqAccessor(parseInt(item)));
}
return ((CharSequence) ctx).charAt((Integer) idx);
} else if (ctx instanceof Class) {
TypeDescriptor tDescr = new TypeDescriptor(expr, this.start, length, 0);
if (tDescr.isArray()) {
Class cls = getClassReference((Class) ctx, tDescr, variableFactory, pCtx);
rootNode = new StaticReferenceAccessor(cls);
return cls;
}
}
throw new CompileException("illegal use of []: unknown type: " + ctx.getClass().getName(), this.expr, this.start);
}
use of org.mvel2.optimizers.impl.refl.nodes.MapAccessorNest in project mvel by mvel.
the class ReflectiveAccessorOptimizer method getCollectionPropertyAO.
private Object getCollectionPropertyAO(Object ctx, String prop) throws Exception {
if (prop.length() > 0) {
ctx = getBeanPropertyAO(ctx, prop);
}
currType = null;
if (ctx == null)
return null;
int _start = ++cursor;
skipWhitespace();
if (cursor == end)
throw new CompileException("unterminated '['", this.expr, this.start);
String item;
if (scanTo(']'))
throw new CompileException("unterminated '['", this.expr, this.start);
item = new String(expr, _start, cursor - _start);
boolean itemSubExpr = true;
Object idx = null;
try {
idx = parseInt(item);
itemSubExpr = false;
} catch (Exception e) {
// not a number;
}
ExecutableStatement itemStmt = null;
if (itemSubExpr) {
idx = (itemStmt = (ExecutableStatement) subCompileExpression(item.toCharArray(), pCtx)).getValue(thisRef, thisRef, variableFactory);
}
++cursor;
if (ctx instanceof Map) {
if (hasPropertyHandler(Map.class)) {
return propHandler(item, ctx, Map.class);
} else {
if (itemSubExpr) {
addAccessorNode(new MapAccessorNest(itemStmt, null));
} else {
addAccessorNode(new MapAccessor(parseInt(item)));
}
return ((Map) ctx).get(idx);
}
} else if (ctx instanceof List) {
if (hasPropertyHandler(List.class)) {
return propHandler(item, ctx, List.class);
} else {
if (itemSubExpr) {
addAccessorNode(new ListAccessorNest(itemStmt, null));
} else {
addAccessorNode(new ListAccessor(parseInt(item)));
}
return ((List) ctx).get((Integer) idx);
}
} else if (ctx.getClass().isArray()) {
if (hasPropertyHandler(Array.class)) {
return propHandler(item, ctx, Array.class);
} else {
if (itemSubExpr) {
addAccessorNode(new ArrayAccessorNest(itemStmt));
} else {
addAccessorNode(new ArrayAccessor(parseInt(item)));
}
return Array.get(ctx, (Integer) idx);
}
} else if (ctx instanceof CharSequence) {
if (hasPropertyHandler(CharSequence.class)) {
return propHandler(item, ctx, CharSequence.class);
} else {
if (itemSubExpr) {
addAccessorNode(new IndexedCharSeqAccessorNest(itemStmt));
} else {
addAccessorNode(new IndexedCharSeqAccessor(parseInt(item)));
}
return ((CharSequence) ctx).charAt((Integer) idx);
}
} else {
TypeDescriptor tDescr = new TypeDescriptor(expr, this.start, end - this.start, 0);
if (tDescr.isArray()) {
Class cls = getClassReference((Class) ctx, tDescr, variableFactory, pCtx);
rootNode = new StaticReferenceAccessor(cls);
return cls;
}
throw new CompileException("illegal use of []: unknown type: " + ctx.getClass().getName(), this.expr, this.st);
}
}
use of org.mvel2.optimizers.impl.refl.nodes.MapAccessorNest in project mule by mulesoft.
the class AbstractVariableExpressionDataTypeResolver method getDataType.
@Override
protected DataType getDataType(PrivilegedEvent event, ASTNode node) {
final Accessor accessor = node.getAccessor();
if (accessor instanceof VariableAccessor) {
VariableAccessor variableAccessor = (VariableAccessor) accessor;
if (variableAccessor.getProperty().equals(propertyName)) {
final AccessorNode nextNode = variableAccessor.getNextNode();
String propertyName = null;
if (nextNode instanceof MapAccessorNest) {
final MapAccessorNest mapAccesorNest = (MapAccessorNest) nextNode;
if (mapAccesorNest.getProperty().isLiteralOnly()) {
propertyName = (String) ((ExecutableLiteral) mapAccesorNest.getProperty()).getLiteral();
}
} else if (nextNode instanceof MapAccessor) {
propertyName = (String) ((MapAccessor) nextNode).getProperty();
}
if (propertyName != null) {
return getVariableDataType(event, propertyName);
}
}
}
return null;
}
Aggregations