Search in sources :

Example 6 with PropertyHandler

use of org.mvel2.integration.PropertyHandler in project mvel by mikebrock.

the class PropertyHandlerTests method _testListener.

public void _testListener() {
    MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
    class MyListener implements Listener {

        public int count;

        public void onEvent(Object context, String contextName, VariableResolverFactory variableFactory, Object value) {
            count++;
        }
    }
    MyListener listener = new MyListener();
    GlobalListenerFactory.registerGetListener(listener);
    PropertyHandlerFactory.setNullPropertyHandler(new PropertyHandler() {

        public Object getProperty(String name, Object contextObj, VariableResolverFactory variableFactory) {
            List someList = new ArrayList();
            someList.add(new Foo());
            return someList;
        }

        public Object setProperty(String name, Object contextObj, VariableResolverFactory variableFactory, Object value) {
            return null;
        }
    });
    PropertyHandlerFactory.registerPropertyHandler(List.class, new PropertyHandler() {

        public Object getProperty(String name, Object contextObj, VariableResolverFactory variableFactory) {
            List list = (List) contextObj;
            int index = Integer.valueOf(name);
            while (index >= list.size()) {
                list.add(new Foo());
            }
            return list.get(index);
        }

        public Object setProperty(String name, Object contextObj, VariableResolverFactory variableFactory, Object value) {
            return null;
        }
    });
    Foo foo = new Foo();
    final Serializable fooExpr0 = MVEL.compileSetExpression("collectionTest[0].name");
    final Serializable fooExpr1 = MVEL.compileSetExpression("collectionTest[1].name");
    MVEL.executeSetExpression(fooExpr0, foo, "John Galt");
    MVEL.executeSetExpression(fooExpr1, foo, "The Joker");
    assertEquals(2, listener.count);
    MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = false;
}
Also used : Serializable(java.io.Serializable) Foo(org.mvel2.tests.core.res.Foo) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List)

Example 7 with PropertyHandler

use of org.mvel2.integration.PropertyHandler in project mvel by mikebrock.

the class PropertyHandlerTests method testNullPropertyHandler.

public void testNullPropertyHandler() {
    MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
    OptimizerFactory.setDefaultOptimizer("ASM");
    PropertyHandlerFactory.setNullPropertyHandler(new PropertyHandler() {

        public Object getProperty(String name, Object contextObj, VariableResolverFactory variableFactory) {
            return "NULL";
        }

        public Object setProperty(String name, Object contextObj, VariableResolverFactory variableFactory, Object value) {
            return "NULL";
        }
    });
    Foo foo = new Foo();
    Bar bar = foo.getBar();
    foo.setBar(null);
    Map map = new HashMap();
    map.put("foo", foo);
    Serializable s = MVEL.compileExpression("foo.bar");
    assertEquals("NULL", MVEL.executeExpression(s, map));
    assertEquals("NULL", MVEL.executeExpression(s, map));
    foo.setBar(bar);
    assertEquals(bar, MVEL.executeExpression(s, map));
}
Also used : Bar(org.mvel2.tests.core.res.Bar) Serializable(java.io.Serializable) HashMap(java.util.HashMap) Foo(org.mvel2.tests.core.res.Foo) HashMap(java.util.HashMap) Map(java.util.Map)

Example 8 with PropertyHandler

use of org.mvel2.integration.PropertyHandler in project mvel by mikebrock.

the class ASMAccessorOptimizer method getBeanProperty.

private Object getBeanProperty(Object ctx, String property) throws IllegalAccessException, InvocationTargetException {
    assert debug("\n  **  ENTER -> {bean: " + property + "; ctx=" + ctx + "}");
    if ((pCtx == null ? currType : pCtx.getVarOrInputTypeOrNull(property)) == Object.class && !pCtx.isStrongTyping()) {
        currType = null;
    }
    if (returnType != null && returnType.isPrimitive()) {
        //noinspection unchecked
        wrapPrimitive(returnType);
    }
    boolean classRef = false;
    Class<?> cls;
    if (ctx instanceof Class) {
        if (MVEL.COMPILER_OPT_SUPPORT_JAVA_STYLE_CLASS_LITERALS && "class".equals(property)) {
            ldcClassConstant((Class<?>) ctx);
            return ctx;
        }
        cls = (Class<?>) ctx;
        classRef = true;
    } else if (ctx != null) {
        cls = ctx.getClass();
    } else {
        cls = null;
    }
    if (hasPropertyHandler(cls)) {
        PropertyHandler prop = getPropertyHandler(cls);
        if (prop instanceof ProducesBytecode) {
            ((ProducesBytecode) prop).produceBytecodeGet(mv, property, variableFactory);
            return prop.getProperty(property, ctx, variableFactory);
        } else {
            throw new RuntimeException("unable to compileShared: custom accessor does not support producing bytecode: " + prop.getClass().getName());
        }
    }
    Member member = cls != null ? getFieldOrAccessor(cls, property) : null;
    if (member != null && classRef && (member.getModifiers() & Modifier.STATIC) == 0) {
        member = null;
    }
    if (member != null && hasGetListeners()) {
        mv.visitVarInsn(ALOAD, 1);
        mv.visitLdcInsn(member.getName());
        mv.visitVarInsn(ALOAD, 3);
        mv.visitMethodInsn(INVOKESTATIC, NAMESPACE + "integration/GlobalListenerFactory", "notifyGetListeners", "(Ljava/lang/Object;Ljava/lang/String;L" + NAMESPACE + "integration/VariableResolverFactory;)V");
        notifyGetListeners(ctx, member.getName(), variableFactory);
    }
    if (first) {
        if ("this".equals(property)) {
            assert debug("ALOAD 2");
            mv.visitVarInsn(ALOAD, 2);
            return thisRef;
        } else if (variableFactory != null && variableFactory.isResolveable(property)) {
            if (variableFactory.isIndexedFactory() && variableFactory.isTarget(property)) {
                int idx;
                try {
                    loadVariableByIndex(idx = variableFactory.variableIndexOf(property));
                } catch (Exception e) {
                    throw new OptimizationFailure(property);
                }
                return variableFactory.getIndexedVariableResolver(idx).getValue();
            } else {
                try {
                    loadVariableByName(property);
                } catch (Exception e) {
                    throw new OptimizationFailure("critical error in JIT", e);
                }
                return variableFactory.getVariableResolver(property).getValue();
            }
        } else {
            assert debug("ALOAD 1");
            mv.visitVarInsn(ALOAD, 1);
        }
    }
    if (member instanceof Field) {
        Object o = ((Field) member).get(ctx);
        if (((member.getModifiers() & STATIC) != 0)) {
            // Check if the static field reference is a constant and a primitive.
            if ((member.getModifiers() & FINAL) != 0 && (o instanceof String || ((Field) member).getType().isPrimitive())) {
                o = ((Field) member).get(null);
                assert debug("LDC " + valueOf(o));
                mv.visitLdcInsn(o);
                wrapPrimitive(o.getClass());
                if (hasNullPropertyHandler()) {
                    if (o == null) {
                        o = getNullPropertyHandler().getProperty(member.getName(), ctx, variableFactory);
                    }
                    writeOutNullHandler(member, 0);
                }
                return o;
            } else {
                assert debug("GETSTATIC " + getDescriptor(member.getDeclaringClass()) + "." + member.getName() + "::" + getDescriptor(((Field) member).getType()));
                mv.visitFieldInsn(GETSTATIC, getInternalName(member.getDeclaringClass()), member.getName(), getDescriptor(returnType = ((Field) member).getType()));
            }
        } else {
            assert debug("CHECKCAST " + getInternalName(cls));
            mv.visitTypeInsn(CHECKCAST, getInternalName(cls));
            assert debug("GETFIELD " + property + ":" + getDescriptor(((Field) member).getType()));
            mv.visitFieldInsn(GETFIELD, getInternalName(cls), property, getDescriptor(returnType = ((Field) member).getType()));
        }
        returnType = ((Field) member).getType();
        if (hasNullPropertyHandler()) {
            if (o == null) {
                o = getNullPropertyHandler().getProperty(member.getName(), ctx, variableFactory);
            }
            writeOutNullHandler(member, 0);
        }
        return o;
    } else if (member != null) {
        Object o;
        if (first) {
            assert debug("ALOAD 1 (B)");
            mv.visitVarInsn(ALOAD, 1);
        }
        try {
            o = ((Method) member).invoke(ctx, EMPTYARG);
            if (returnType != member.getDeclaringClass()) {
                assert debug("CHECKCAST " + getInternalName(member.getDeclaringClass()));
                mv.visitTypeInsn(CHECKCAST, getInternalName(member.getDeclaringClass()));
            }
            returnType = ((Method) member).getReturnType();
            assert debug("INVOKEVIRTUAL " + member.getName() + ":" + returnType);
            mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(member.getDeclaringClass()), member.getName(), getMethodDescriptor((Method) member));
        } catch (IllegalAccessException e) {
            Method iFaceMeth = determineActualTargetMethod((Method) member);
            if (iFaceMeth == null)
                throw new PropertyAccessException("could not access field: " + cls.getName() + "." + property, expr, st, e);
            assert debug("CHECKCAST " + getInternalName(iFaceMeth.getDeclaringClass()));
            mv.visitTypeInsn(CHECKCAST, getInternalName(iFaceMeth.getDeclaringClass()));
            returnType = iFaceMeth.getReturnType();
            assert debug("INVOKEINTERFACE " + member.getName() + ":" + returnType);
            mv.visitMethodInsn(INVOKEINTERFACE, getInternalName(iFaceMeth.getDeclaringClass()), member.getName(), getMethodDescriptor((Method) member));
            o = iFaceMeth.invoke(ctx, EMPTYARG);
        } catch (IllegalArgumentException e) {
            if (member.getDeclaringClass().equals(ctx)) {
                try {
                    Class c = Class.forName(member.getDeclaringClass().getName() + "$" + property);
                    throw new CompileException("name collision between innerclass: " + c.getCanonicalName() + "; and bean accessor: " + property + " (" + member.toString() + ")", expr, tkStart);
                } catch (ClassNotFoundException e2) {
                //fallthru
                }
            }
            throw e;
        }
        if (hasNullPropertyHandler()) {
            if (o == null)
                o = getNullPropertyHandler().getProperty(member.getName(), ctx, variableFactory);
            writeOutNullHandler(member, 0);
        }
        return o;
    } else if (ctx instanceof Map && (((Map) ctx).containsKey(property) || nullSafe)) {
        assert debug("CHECKCAST java/util/Map");
        mv.visitTypeInsn(CHECKCAST, "java/util/Map");
        assert debug("LDC: \"" + property + "\"");
        mv.visitLdcInsn(property);
        assert debug("INVOKEINTERFACE: get");
        mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
        return ((Map) ctx).get(property);
    } else if (first && "this".equals(property)) {
        assert debug("ALOAD 2");
        // load the thisRef value.
        mv.visitVarInsn(ALOAD, 2);
        return this.thisRef;
    } else if ("length".equals(property) && ctx.getClass().isArray()) {
        anyArrayCheck(ctx.getClass());
        assert debug("ARRAYLENGTH");
        mv.visitInsn(ARRAYLENGTH);
        wrapPrimitive(int.class);
        return getLength(ctx);
    } else if (LITERALS.containsKey(property)) {
        Object lit = LITERALS.get(property);
        if (lit instanceof Class) {
            ldcClassConstant((Class) lit);
        }
        return lit;
    } else {
        Object ts = tryStaticAccess();
        if (ts != null) {
            if (ts instanceof Class) {
                ldcClassConstant((Class) ts);
                return ts;
            } else if (ts instanceof Method) {
                writeFunctionPointerStub(((Method) ts).getDeclaringClass(), (Method) ts);
                return ts;
            } else {
                Field f = (Field) ts;
                if ((f.getModifiers() & FINAL) != 0) {
                    Object finalVal = f.get(null);
                    assert debug("LDC " + valueOf(finalVal));
                    mv.visitLdcInsn(finalVal);
                    wrapPrimitive(finalVal.getClass());
                    return finalVal;
                } else {
                    assert debug("GETSTATIC " + getInternalName(f.getDeclaringClass()) + "." + ((Field) ts).getName() + "::" + getDescriptor(f.getType()));
                    mv.visitFieldInsn(GETSTATIC, getInternalName(f.getDeclaringClass()), f.getName(), getDescriptor(returnType = f.getType()));
                    return f.get(null);
                }
            }
        } else if (ctx instanceof Class) {
            /**
         * This is our ugly support for function pointers.  This works but needs to be re-thought out at some
         * point.
         */
            Class c = (Class) ctx;
            for (Method m : c.getMethods()) {
                if (property.equals(m.getName())) {
                    if (MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL) {
                        assert debug("POP");
                        mv.visitInsn(POP);
                        assert debug("INVOKESTATIC " + m.getName());
                        mv.visitMethodInsn(INVOKESTATIC, getInternalName(m.getDeclaringClass()), m.getName(), getMethodDescriptor(m));
                        returnType = m.getReturnType();
                        return m.invoke(null, EMPTY_OBJ_ARR);
                    } else {
                        writeFunctionPointerStub(c, m);
                        return m;
                    }
                }
            }
            try {
                Class subClass = findClass(variableFactory, c.getName() + "$" + property, pCtx);
                ldcClassConstant(subClass);
                return subClass;
            } catch (ClassNotFoundException cnfe) {
            // fall through.
            }
        } else if (MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL) {
            return getMethod(ctx, property);
        }
        if (ctx == null) {
            throw new PropertyAccessException("unresolvable property or identifier: " + property, expr, st);
        } else {
            throw new PropertyAccessException("could not access: " + property + "; in class: " + ctx.getClass().getName(), expr, st);
        }
    }
}
Also used : IOException(java.io.IOException) PropertyHandler(org.mvel2.integration.PropertyHandler) Map(java.util.Map)

Example 9 with PropertyHandler

use of org.mvel2.integration.PropertyHandler 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)

Aggregations

PropertyHandler (org.mvel2.integration.PropertyHandler)4 Serializable (java.io.Serializable)3 Map (java.util.Map)3 Foo (org.mvel2.tests.core.res.Foo)3 HashMap (java.util.HashMap)2 Label (org.mvel2.asm.Label)2 Bar (org.mvel2.tests.core.res.Bar)2 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1