Search in sources :

Example 11 with Accessor

use of org.mvel2.compiler.Accessor in project mvel by mikebrock.

the class ASMAccessorOptimizer method propHandlerByteCodePut.

private void propHandlerByteCodePut(String property, Object ctx, Class handler, Object value) {
    PropertyHandler ph = getPropertyHandler(handler);
    if (ph instanceof ProducesBytecode) {
        assert debug("<<3rd-Party Code Generation>>");
        ((ProducesBytecode) ph).produceBytecodePut(mv, property, variableFactory);
        ph.setProperty(property, ctx, variableFactory, value);
    } else {
        throw new RuntimeException("unable to compileShared: custom accessor does not support producing bytecode: " + ph.getClass().getName());
    }
}
Also used : PropertyHandler(org.mvel2.integration.PropertyHandler)

Example 12 with Accessor

use of org.mvel2.compiler.Accessor 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 13 with Accessor

use of org.mvel2.compiler.Accessor in project mvel by mikebrock.

the class AbstractOptimizer method tryStaticAccess.

/**
   * Try static access of the property, and return an instance of the Field, Method of Class if successful.
   *
   * @return - Field, Method or Class instance.
   */
protected Object tryStaticAccess() {
    int begin = cursor;
    try {
        /**
       * Try to resolve this *smartly* as a static class reference.
       *
       * This starts at the end of the token and starts to step backwards to figure out whether
       * or not this may be a static class reference.  We search for method calls simply by
       * inspecting for ()'s.  The first union area we come to where no brackets are present is our
       * test-point for a class reference.  If we find a class, we pass the reference to the
       * property accessor along  with trailing methods (if any).
       *
       */
        boolean meth = false;
        // int end = start + length;
        int last = end;
        for (int i = end - 1; i > start; i--) {
            switch(expr[i]) {
                case '.':
                    if (!meth) {
                        try {
                            String test = new String(expr, start, (cursor = last) - start);
                            return Class.forName(test, true, pCtx != null ? pCtx.getParserConfiguration().getClassLoader() : currentThread().getContextClassLoader());
                        } catch (ClassNotFoundException e) {
                            Class cls = Class.forName(new String(expr, start, i - start), true, pCtx != null ? pCtx.getParserConfiguration().getClassLoader() : currentThread().getContextClassLoader());
                            String name = new String(expr, i + 1, end - i - 1);
                            try {
                                return cls.getField(name);
                            } catch (NoSuchFieldException nfe) {
                                for (Method m : cls.getMethods()) {
                                    if (name.equals(m.getName()))
                                        return m;
                                }
                                return null;
                            }
                        }
                    }
                    meth = false;
                    last = i;
                    break;
                case '}':
                    i--;
                    for (int d = 1; i > start && d != 0; i--) {
                        switch(expr[i]) {
                            case '}':
                                d++;
                                break;
                            case '{':
                                d--;
                                break;
                            case '"':
                            case '\'':
                                char s = expr[i];
                                while (i > start && (expr[i] != s && expr[i - 1] != '\\')) i--;
                        }
                    }
                    break;
                case ')':
                    i--;
                    for (int d = 1; i > start && d != 0; i--) {
                        switch(expr[i]) {
                            case ')':
                                d++;
                                break;
                            case '(':
                                d--;
                                break;
                            case '"':
                            case '\'':
                                char s = expr[i];
                                while (i > start && (expr[i] != s && expr[i - 1] != '\\')) i--;
                        }
                    }
                    meth = true;
                    last = i++;
                    break;
                case '\'':
                    while (--i > start) {
                        if (expr[i] == '\'' && expr[i - 1] != '\\') {
                            break;
                        }
                    }
                    break;
                case '"':
                    while (--i > start) {
                        if (expr[i] == '"' && expr[i - 1] != '\\') {
                            break;
                        }
                    }
                    break;
            }
        }
    } catch (Exception cnfe) {
        cursor = begin;
    }
    return null;
}
Also used : Method(java.lang.reflect.Method) CompileException(org.mvel2.CompileException)

Example 14 with Accessor

use of org.mvel2.compiler.Accessor in project mvel by mikebrock.

the class OptimizerFactory method setDefaultOptimizer.

public static void setDefaultOptimizer(String name) {
    try {
        //noinspection unchecked
        AccessorOptimizer ao = accessorCompilers.get(defaultOptimizer = name);
        ao.init();
        setThreadAccessorOptimizer(ao.getClass());
    } catch (Exception e) {
        throw new RuntimeException("unable to instantiate accessor compiler", e);
    }
}
Also used : ASMAccessorOptimizer(org.mvel2.optimizers.impl.asm.ASMAccessorOptimizer) ReflectiveAccessorOptimizer(org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer)

Example 15 with Accessor

use of org.mvel2.compiler.Accessor in project mvel by mikebrock.

the class ASTNode method optimize.

private Object optimize(Object ctx, Object thisValue, VariableResolverFactory factory) {
    if ((fields & DEOP) != 0) {
        fields ^= DEOP;
    }
    AccessorOptimizer optimizer;
    Object retVal = null;
    if ((fields & NOJIT) != 0 || factory != null && factory.isResolveable(nameCache)) {
        optimizer = getAccessorCompiler(SAFE_REFLECTIVE);
    } else {
        optimizer = getDefaultAccessorCompiler();
    }
    ParserContext pCtx;
    if ((fields & PCTX_STORED) != 0) {
        pCtx = (ParserContext) literal;
    } else {
        pCtx = new ParserContext(new ParserConfiguration(getInjectedImports(factory), null));
    }
    try {
        pCtx.optimizationNotify();
        setAccessor(optimizer.optimizeAccessor(pCtx, expr, start, offset, ctx, thisValue, factory, true, egressType));
    } catch (OptimizationNotSupported ne) {
        setAccessor((optimizer = getAccessorCompiler(SAFE_REFLECTIVE)).optimizeAccessor(pCtx, expr, start, offset, ctx, thisValue, factory, true, null));
    }
    if (accessor == null) {
        return get(expr, start, offset, ctx, factory, thisValue);
    }
    if (retVal == null) {
        retVal = optimizer.getResultOptPass();
    }
    if (egressType == null) {
        egressType = optimizer.getEgressType();
    }
    return retVal;
}
Also used : AccessorOptimizer(org.mvel2.optimizers.AccessorOptimizer) ParserContext(org.mvel2.ParserContext) OptimizationNotSupported(org.mvel2.optimizers.OptimizationNotSupported) ParserConfiguration(org.mvel2.ParserConfiguration)

Aggregations

IOException (java.io.IOException)5 PropertyTools.getFieldOrAccessor (org.mvel2.util.PropertyTools.getFieldOrAccessor)5 PropertyTools.getFieldOrWriteAccessor (org.mvel2.util.PropertyTools.getFieldOrWriteAccessor)5 Map (java.util.Map)4 Accessor (org.mvel2.compiler.Accessor)4 AccessorOptimizer (org.mvel2.optimizers.AccessorOptimizer)4 List (java.util.List)3 ExprValueAccessor (org.mvel2.optimizers.impl.refl.collection.ExprValueAccessor)3 WeakHashMap (java.util.WeakHashMap)2 ClassWriter (org.mvel2.asm.ClassWriter)2 Label (org.mvel2.asm.Label)2 MethodVisitor (org.mvel2.asm.MethodVisitor)2 PropertyHandler (org.mvel2.integration.PropertyHandler)2 OptimizationNotSupported (org.mvel2.optimizers.OptimizationNotSupported)2 Union (org.mvel2.optimizers.impl.refl.nodes.Union)2 Method (java.lang.reflect.Method)1 ArrayList (java.util.ArrayList)1 CompileException (org.mvel2.CompileException)1 ParserConfiguration (org.mvel2.ParserConfiguration)1 ParserContext (org.mvel2.ParserContext)1