Search in sources :

Example 1 with Notify

use of org.mvel2.optimizers.impl.refl.nodes.Notify in project mvel by mvel.

the class ReflectiveAccessorOptimizer method getBeanPropertyAO.

private Object getBeanPropertyAO(Object ctx, String property) throws Exception {
    if (GlobalListenerFactory.hasGetListeners()) {
        notifyGetListeners(ctx, property, variableFactory);
        addAccessorNode(new Notify(property));
    }
    if (ctx != null && hasPropertyHandler(ctx.getClass()))
        return propHandler(property, ctx, ctx.getClass());
    return getBeanProperty(ctx, property);
}
Also used : Notify(org.mvel2.optimizers.impl.refl.nodes.Notify)

Example 2 with Notify

use of org.mvel2.optimizers.impl.refl.nodes.Notify 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;
}
Also used : PropertyVerifier(org.mvel2.compiler.PropertyVerifier) List(java.util.List) Map(java.util.Map) WeakHashMap(java.util.WeakHashMap)

Example 3 with Notify

use of org.mvel2.optimizers.impl.refl.nodes.Notify 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;
}
Also used : PropertyVerifier(org.mvel2.compiler.PropertyVerifier) Notify(org.mvel2.optimizers.impl.refl.nodes.Notify) ArrayAccessorNest(org.mvel2.optimizers.impl.refl.nodes.ArrayAccessorNest) PropertyAccessException(org.mvel2.PropertyAccessException) Method(java.lang.reflect.Method) MapAccessorNest(org.mvel2.optimizers.impl.refl.nodes.MapAccessorNest) FieldAccessor(org.mvel2.optimizers.impl.refl.nodes.FieldAccessor) DynamicFieldAccessor(org.mvel2.optimizers.impl.refl.nodes.DynamicFieldAccessor) InvocationTargetException(java.lang.reflect.InvocationTargetException) Array(java.lang.reflect.Array) Field(java.lang.reflect.Field) SetterAccessor(org.mvel2.optimizers.impl.refl.nodes.SetterAccessor) ListAccessorNest(org.mvel2.optimizers.impl.refl.nodes.ListAccessorNest) CompileException(org.mvel2.CompileException) List(java.util.List) MapAccessor(org.mvel2.optimizers.impl.refl.nodes.MapAccessor) Map(java.util.Map) Member(java.lang.reflect.Member) DynamicFieldAccessor(org.mvel2.optimizers.impl.refl.nodes.DynamicFieldAccessor)

Example 4 with Notify

use of org.mvel2.optimizers.impl.refl.nodes.Notify in project BroadleafCommerce by BroadleafCommerce.

the class MvelHelper method evaluateRule.

/**
 * @param rule
 * @param ruleParameters
 * @param expressionCache
 * @param additionalContextImports additional imports to give to the {@link ParserContext} besides "MVEL" ({@link MVEL} and
 * "MvelHelper" ({@link MvelHelper}) since they are automatically added
 * @return
 */
public static boolean evaluateRule(String rule, Map<String, Object> ruleParameters, Map<String, Serializable> expressionCache, Map<String, Class<?>> additionalContextImports) {
    // Null or empty is a match
    if (rule == null || "".equals(rule)) {
        return true;
    } else {
        // MVEL expression compiling can be expensive so let's cache the expression
        Serializable exp = null;
        if (expressionCache != null) {
            exp = expressionCache.get(rule);
        }
        if (exp == null) {
            ParserContext context = new ParserContext();
            context.addImport("MVEL", MVEL.class);
            context.addImport("MvelHelper", MvelHelper.class);
            context.addImport("CollectionUtils", SelectizeCollectionUtils.class);
            if (MapUtils.isNotEmpty(additionalContextImports)) {
                for (Entry<String, Class<?>> entry : additionalContextImports.entrySet()) {
                    context.addImport(entry.getKey(), entry.getValue());
                }
            }
            String modifiedRule = modifyExpression(rule, ruleParameters, context);
            synchronized (expressionCache) {
                exp = MVEL.compileExpression(modifiedRule, context);
                expressionCache.put(rule, exp);
            }
        }
        Map<String, Object> mvelParameters = new HashMap<String, Object>();
        if (ruleParameters != null) {
            for (String parameter : ruleParameters.keySet()) {
                mvelParameters.put(parameter, ruleParameters.get(parameter));
            }
        }
        try {
            Object test = MVEL.executeExpression(exp, mvelParameters);
            if (test == null) {
                // This can occur if there is no actual rule
                return true;
            }
            return (Boolean) test;
        } catch (Exception e) {
            // Return false, but notify about the bad expression through logs
            if (!TEST_MODE && LOG.isInfoEnabled()) {
                LOG.info("Unable to parse and/or execute the mvel expression (" + StringUtil.sanitize(rule) + "). Reporting to the logs and returning false for the match expression", e);
            }
            return false;
        }
    }
}
Also used : Serializable(java.io.Serializable) HashMap(java.util.HashMap) ParserContext(org.mvel2.ParserContext) ParseException(java.text.ParseException)

Aggregations

List (java.util.List)2 Map (java.util.Map)2 PropertyVerifier (org.mvel2.compiler.PropertyVerifier)2 Notify (org.mvel2.optimizers.impl.refl.nodes.Notify)2 Serializable (java.io.Serializable)1 Array (java.lang.reflect.Array)1 Field (java.lang.reflect.Field)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Member (java.lang.reflect.Member)1 Method (java.lang.reflect.Method)1 ParseException (java.text.ParseException)1 HashMap (java.util.HashMap)1 WeakHashMap (java.util.WeakHashMap)1 CompileException (org.mvel2.CompileException)1 ParserContext (org.mvel2.ParserContext)1 PropertyAccessException (org.mvel2.PropertyAccessException)1 ArrayAccessorNest (org.mvel2.optimizers.impl.refl.nodes.ArrayAccessorNest)1 DynamicFieldAccessor (org.mvel2.optimizers.impl.refl.nodes.DynamicFieldAccessor)1 FieldAccessor (org.mvel2.optimizers.impl.refl.nodes.FieldAccessor)1 ListAccessorNest (org.mvel2.optimizers.impl.refl.nodes.ListAccessorNest)1