Search in sources :

Example 21 with PropertyAccessException

use of org.mvel2.PropertyAccessException in project mvel by mikebrock.

the class PropertyAccessor method getMethod.

/**
 * Find an appropriate method, execute it, and return it's response.
 *
 * @param ctx  -
 * @param name -
 * @return -
 * @throws Exception -
 */
@SuppressWarnings({ "unchecked" })
private Object getMethod(Object ctx, String name) {
    int _start = cursor;
    String tk = cursor != end && property[cursor] == '(' && ((cursor = balancedCapture(property, cursor, '(')) - _start) > 1 ? new String(property, _start + 1, cursor - _start - 1) : "";
    cursor++;
    Object[] args;
    if (tk.length() == 0) {
        args = ParseTools.EMPTY_OBJ_ARR;
    } else {
        List<char[]> subtokens = parseParameterList(tk.toCharArray(), 0, -1);
        args = new Object[subtokens.size()];
        for (int i = 0; i < subtokens.size(); i++) {
            args[i] = eval(subtokens.get(i), thisReference, variableFactory);
        }
    }
    if (first && variableFactory != null && variableFactory.isResolveable(name)) {
        Object ptr = variableFactory.getVariableResolver(name).getValue();
        if (ptr instanceof Method) {
            ctx = ((Method) ptr).getDeclaringClass();
            name = ((Method) ptr).getName();
        } else if (ptr instanceof MethodStub) {
            ctx = ((MethodStub) ptr).getClassReference();
            name = ((MethodStub) ptr).getMethodName();
        } else if (ptr instanceof Function) {
            ((Function) ptr).checkArgumentCount(args.length);
            return ((Function) ptr).call(null, thisReference, variableFactory, args);
        } else {
            throw new OptimizationFailure("attempt to optimize a method call for a reference that does not point to a method: " + name + " (reference is type: " + (ctx != null ? ctx.getClass().getName() : null) + ")");
        }
        first = false;
    }
    if (ctx == null)
        throw new CompileException("no such method or function: " + name, property, cursor);
    /**
     * If the target object is an instance of java.lang.Class itself then do not
     * adjust the Class scope target.
     */
    Class cls = (ctx instanceof Class ? (Class) ctx : ctx.getClass());
    if (cls == Proto.ProtoInstance.class) {
        return ((Proto.ProtoInstance) ctx).get(name).call(null, thisReference, variableFactory, args);
    }
    /**
     * Check to see if we have already cached this method;
     */
    Object[] cache = checkMethodCache(cls, createSignature(name, tk));
    Method m;
    Class[] parameterTypes;
    if (cache != null) {
        m = (Method) cache[0];
        parameterTypes = (Class[]) cache[1];
    } else {
        m = null;
        parameterTypes = null;
    }
    /**
     * If we have not cached the method then we need to go ahead and try to resolve it.
     */
    if (m == null) {
        /**
         * Try to find an instance method from the class target.
         */
        if ((m = getBestCandidate(args, name, cls, cls.getMethods(), false)) != null) {
            addMethodCache(cls, createSignature(name, tk), m);
            parameterTypes = m.getParameterTypes();
        }
        if (m == null) {
            /**
             * If we didn't find anything, maybe we're looking for the actual java.lang.Class methods.
             */
            if ((m = getBestCandidate(args, name, cls, cls.getClass().getDeclaredMethods(), false)) != null) {
                addMethodCache(cls, createSignature(name, tk), m);
                parameterTypes = m.getParameterTypes();
            }
        }
    }
    if (m == null) {
        StringAppender errorBuild = new StringAppender();
        for (int i = 0; i < args.length; i++) {
            errorBuild.append(args[i] != null ? args[i].getClass().getName() : null);
            if (i < args.length - 1)
                errorBuild.append(", ");
        }
        if ("size".equals(name) && args.length == 0 && cls.isArray()) {
            return getLength(ctx);
        }
        System.out.println("{ " + new String(property) + " }");
        throw new PropertyAccessException("unable to resolve method: " + cls.getName() + "." + name + "(" + errorBuild.toString() + ") [arglength=" + args.length + "]", property, st);
    } else {
        for (int i = 0; i < args.length; i++) {
            args[i] = convert(args[i], parameterTypes[i]);
        }
        /**
         * Invoke the target method and return the response.
         */
        try {
            return m.invoke(ctx, args);
        } catch (IllegalAccessException e) {
            try {
                addMethodCache(cls, createSignature(name, tk), (m = getWidenedTarget(m)));
                return m.invoke(ctx, args);
            } catch (Exception e2) {
                throw new PropertyAccessException("unable to invoke method: " + name, property, cursor, e2);
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new PropertyAccessException("unable to invoke method: " + name, property, cursor, e);
        }
    }
}
Also used : Function(org.mvel2.ast.Function) Proto(org.mvel2.ast.Proto) MethodStub(org.mvel2.util.MethodStub) StringAppender(org.mvel2.util.StringAppender)

Example 22 with PropertyAccessException

use of org.mvel2.PropertyAccessException in project mvel by mikebrock.

the class PropertyAccessor 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);
    }
    if (ctx == null)
        return null;
    int _start = ++cursor;
    whiteSpaceSkip();
    if (cursor == end || scanTo(']'))
        throw new PropertyAccessException("unterminated '['", property, cursor);
    prop = new String(property, _start, cursor++ - _start);
    if (ctx instanceof Map) {
        return ((Map) ctx).get(eval(prop, ctx, variableFactory));
    } else if (ctx instanceof List) {
        return ((List) ctx).get((Integer) eval(prop, ctx, variableFactory));
    } else if (ctx instanceof Collection) {
        int count = (Integer) eval(prop, ctx, variableFactory);
        if (count > ((Collection) ctx).size())
            throw new PropertyAccessException("index [" + count + "] out of bounds on collections", property, cursor);
        Iterator iter = ((Collection) ctx).iterator();
        for (int i = 0; i < count; i++) iter.next();
        return iter.next();
    } else if (ctx.getClass().isArray()) {
        return Array.get(ctx, (Integer) eval(prop, ctx, variableFactory));
    } else if (ctx instanceof CharSequence) {
        return ((CharSequence) ctx).charAt((Integer) eval(prop, ctx, variableFactory));
    } else {
        // TypeDescriptor td = new TypeDescriptor(property, 0);
        try {
            return getClassReference(getCurrentThreadParserContext(), (Class) ctx, new TypeDescriptor(property, start, length, 0));
        } catch (Exception e) {
            throw new PropertyAccessException("illegal use of []: unknown type: " + (ctx == null ? null : ctx.getClass().getName()), property, st, e);
        }
    }
}
Also used : TypeDescriptor(org.mvel2.ast.TypeDescriptor)

Example 23 with PropertyAccessException

use of org.mvel2.PropertyAccessException in project mvel by mvel.

the class ASMAccessorOptimizer method compileAccessor.

private Accessor compileAccessor() {
    assert debug("<<INITIATE COMPILE>>");
    Object curr = ctx;
    try {
        if (!MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING) {
            while (cursor < end) {
                switch(nextSubToken()) {
                    case BEAN:
                        curr = getBeanProperty(curr, capture());
                        break;
                    case METH:
                        curr = getMethod(curr, capture());
                        break;
                    case COL:
                        curr = getCollectionProperty(curr, capture());
                        break;
                    case WITH:
                        curr = getWithProperty(curr);
                        break;
                }
                // check to see if a null safety is enabled on this property.
                if (fields == -1) {
                    if (curr == null) {
                        if (nullSafe) {
                            throw new OptimizationNotSupported();
                        }
                        break;
                    } else {
                        fields = 0;
                    }
                }
                first = false;
                if (nullSafe && cursor < end) {
                    assert debug("DUP");
                    mv.visitInsn(DUP);
                    Label j = new Label();
                    assert debug("IFNONNULL : jump");
                    mv.visitJumpInsn(IFNONNULL, j);
                    assert debug("ARETURN");
                    mv.visitInsn(ARETURN);
                    assert debug("LABEL:jump");
                    mv.visitLabel(j);
                }
            }
        } else {
            while (cursor < end) {
                switch(nextSubToken()) {
                    case BEAN:
                        curr = getBeanPropertyAO(curr, capture());
                        break;
                    case METH:
                        curr = getMethod(curr, capture());
                        break;
                    case COL:
                        curr = getCollectionPropertyAO(curr, capture());
                        break;
                    case WITH:
                        curr = getWithProperty(curr);
                        break;
                }
                // check to see if a null safety is enabled on this property.
                if (fields == -1) {
                    if (curr == null) {
                        if (nullSafe) {
                            throw new OptimizationNotSupported();
                        }
                        break;
                    } else {
                        fields = 0;
                    }
                }
                first = false;
                if (nullSafe && cursor < end) {
                    assert debug("DUP");
                    mv.visitInsn(DUP);
                    Label j = new Label();
                    assert debug("IFNONNULL : jump");
                    mv.visitJumpInsn(IFNONNULL, j);
                    assert debug("ARETURN");
                    mv.visitInsn(ARETURN);
                    assert debug("LABEL:jump");
                    mv.visitLabel(j);
                }
            }
        }
        val = curr;
        _finishJIT();
        return _initializeAccessor();
    } catch (InvocationTargetException e) {
        throw new PropertyAccessException(new String(expr), expr, st, e, pCtx);
    } catch (IllegalAccessException e) {
        throw new PropertyAccessException(new String(expr), expr, st, e, pCtx);
    } catch (IndexOutOfBoundsException e) {
        throw new PropertyAccessException(new String(expr), expr, st, e, pCtx);
    } catch (PropertyAccessException e) {
        throw new CompileException(e.getMessage(), expr, st, e);
    } catch (CompileException e) {
        throw e;
    } catch (NullPointerException e) {
        throw new PropertyAccessException(new String(expr), expr, st, e, pCtx);
    } catch (OptimizationNotSupported e) {
        throw e;
    } catch (Exception e) {
        throw new CompileException(e.getMessage(), expr, st, e);
    }
}
Also used : Label(org.mvel2.asm.Label) PropertyAccessException(org.mvel2.PropertyAccessException) CompileException(org.mvel2.CompileException) OptimizationNotSupported(org.mvel2.optimizers.OptimizationNotSupported) InvocationTargetException(java.lang.reflect.InvocationTargetException) InvocationTargetException(java.lang.reflect.InvocationTargetException) PropertyAccessException(org.mvel2.PropertyAccessException) IOException(java.io.IOException) CompileException(org.mvel2.CompileException)

Example 24 with PropertyAccessException

use of org.mvel2.PropertyAccessException 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 25 with PropertyAccessException

use of org.mvel2.PropertyAccessException in project mvel by mvel.

the class ASMAccessorOptimizer 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.expr = property;
    this.start = this.cursor = start;
    this.end = start + offset;
    this.length = start + offset;
    this.first = true;
    this.ingressType = ingressType;
    compiledInputs = new ArrayList<ExecutableStatement>();
    this.pCtx = pCtx;
    this.ctx = ctx;
    this.thisRef = thisRef;
    this.variableFactory = factory;
    char[] root = null;
    PropertyVerifier verifier = new PropertyVerifier(property, this.pCtx = pCtx);
    int split = findLastUnion();
    if (split != -1) {
        root = subset(property, 0, split);
    }
    AccessorNode rootAccessor = null;
    _initJIT2();
    if (root != null) {
        int _length = this.length;
        int _end = this.end;
        char[] _expr = this.expr;
        this.length = end = (this.expr = root).length;
        // run the compiler but don't finish building.
        deferFinish = true;
        noinit = true;
        compileAccessor();
        ctx = this.val;
        this.expr = _expr;
        this.cursor = start + root.length + 1;
        this.length = _length - root.length - 1;
        this.end = this.cursor + this.length;
    } else {
        assert debug("ALOAD 1");
        mv.visitVarInsn(ALOAD, 1);
    }
    try {
        skipWhitespace();
        if (collection) {
            int st = cursor;
            whiteSpaceSkip();
            if (st == end)
                throw new PropertyAccessException("unterminated '['", expr, start, pCtx);
            if (scanTo(']'))
                throw new PropertyAccessException("unterminated '['", expr, start, pCtx);
            String ex = new String(expr, st, cursor - st).trim();
            assert debug("CHECKCAST " + ctx.getClass().getName());
            mv.visitTypeInsn(CHECKCAST, getInternalName(ctx.getClass()));
            if (ctx instanceof Map) {
                if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(Map.class)) {
                    propHandlerByteCodePut(ex, ctx, Map.class, value);
                } else {
                    // noinspection unchecked
                    ((Map) ctx).put(eval(ex, ctx, variableFactory), convert(value, returnType = verifier.analyze()));
                    writeLiteralOrSubexpression(subCompileExpression(ex.toCharArray(), pCtx));
                    assert debug("ALOAD 4");
                    mv.visitVarInsn(ALOAD, 4);
                    if (value != null && returnType != value.getClass()) {
                        dataConversion(returnType);
                        checkcast(returnType);
                    }
                    assert debug("INVOKEINTERFACE Map.put");
                    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
                    assert debug("POP");
                    mv.visitInsn(POP);
                    assert debug("ALOAD 4");
                    mv.visitVarInsn(ALOAD, 4);
                }
            } else if (ctx instanceof List) {
                if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(List.class)) {
                    propHandlerByteCodePut(ex, ctx, List.class, value);
                } else {
                    // noinspection unchecked
                    ((List) ctx).set(eval(ex, ctx, variableFactory, Integer.class), convert(value, returnType = verifier.analyze()));
                    writeLiteralOrSubexpression(subCompileExpression(ex.toCharArray(), pCtx));
                    unwrapPrimitive(int.class);
                    assert debug("ALOAD 4");
                    mv.visitVarInsn(ALOAD, 4);
                    if (value != null && !value.getClass().isAssignableFrom(returnType)) {
                        dataConversion(returnType);
                        checkcast(returnType);
                    }
                    assert debug("INVOKEINTERFACE List.set");
                    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "set", "(ILjava/lang/Object;)Ljava/lang/Object;");
                    assert debug("ALOAD 4");
                    mv.visitVarInsn(ALOAD, 4);
                }
            } else if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(ctx.getClass())) {
                propHandlerByteCodePut(ex, ctx, ctx.getClass(), value);
            } else if (ctx.getClass().isArray()) {
                if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(Array.class)) {
                    propHandlerByteCodePut(ex, ctx, Array.class, value);
                } else {
                    Class type = getBaseComponentType(ctx.getClass());
                    Object idx = eval(ex, ctx, variableFactory);
                    writeLiteralOrSubexpression(subCompileExpression(ex.toCharArray(), pCtx), int.class);
                    if (!(idx instanceof Integer)) {
                        dataConversion(Integer.class);
                        idx = DataConversion.convert(idx, Integer.class);
                        unwrapPrimitive(int.class);
                    }
                    assert debug("ALOAD 4");
                    mv.visitVarInsn(ALOAD, 4);
                    if (type.isPrimitive())
                        unwrapPrimitive(type);
                    else if (!type.equals(value.getClass())) {
                        dataConversion(type);
                    }
                    arrayStore(type);
                    // noinspection unchecked
                    Array.set(ctx, (Integer) idx, convert(value, type));
                    assert debug("ALOAD 4");
                    mv.visitVarInsn(ALOAD, 4);
                }
            } else {
                throw new PropertyAccessException("cannot bind to collection property: " + new String(expr) + ": not a recognized collection type: " + ctx.getClass(), expr, start, pCtx);
            }
            deferFinish = false;
            noinit = false;
            _finishJIT();
            try {
                deferFinish = false;
                return _initializeAccessor();
            } catch (Exception e) {
                throw new CompileException("could not generate accessor", expr, start, e);
            }
        }
        String tk = new String(expr, this.cursor, end - cursor);
        Member member = getFieldOrWriteAccessor(ctx.getClass(), tk, value == null ? null : ingressType);
        if (GlobalListenerFactory.hasSetListeners()) {
            mv.visitVarInsn(ALOAD, 1);
            mv.visitLdcInsn(tk);
            mv.visitVarInsn(ALOAD, 3);
            mv.visitVarInsn(ALOAD, 4);
            mv.visitMethodInsn(INVOKESTATIC, NAMESPACE + "integration/GlobalListenerFactory", "notifySetListeners", "(Ljava/lang/Object;Ljava/lang/String;L" + NAMESPACE + "integration/VariableResolverFactory;Ljava/lang/Object;)V");
            GlobalListenerFactory.notifySetListeners(ctx, tk, variableFactory, value);
        }
        if (member instanceof Field) {
            checkcast(ctx.getClass());
            Field fld = (Field) member;
            Label jmp = null;
            Label jmp2 = new Label();
            if (fld.getType().isPrimitive()) {
                assert debug("ASTORE 5");
                mv.visitVarInsn(ASTORE, 5);
                assert debug("ALOAD 4");
                mv.visitVarInsn(ALOAD, 4);
                if (value == null)
                    value = PropertyTools.getPrimitiveInitialValue(fld.getType());
                jmp = new Label();
                assert debug("IFNOTNULL jmp");
                mv.visitJumpInsn(IFNONNULL, jmp);
                assert debug("ALOAD 5");
                mv.visitVarInsn(ALOAD, 5);
                assert debug("ICONST_0");
                mv.visitInsn(ICONST_0);
                assert debug("PUTFIELD " + getInternalName(fld.getDeclaringClass()) + "." + tk);
                mv.visitFieldInsn(PUTFIELD, getInternalName(fld.getDeclaringClass()), tk, getDescriptor(fld.getType()));
                assert debug("GOTO jmp2");
                mv.visitJumpInsn(GOTO, jmp2);
                assert debug("jmp:");
                mv.visitLabel(jmp);
                assert debug("ALOAD 5");
                mv.visitVarInsn(ALOAD, 5);
                assert debug("ALOAD 4");
                mv.visitVarInsn(ALOAD, 4);
                unwrapPrimitive(fld.getType());
            } else {
                assert debug("ALOAD 4");
                mv.visitVarInsn(ALOAD, 4);
                checkcast(fld.getType());
            }
            if (jmp == null && value != null && !fld.getType().isAssignableFrom(value.getClass())) {
                if (!canConvert(fld.getType(), value.getClass())) {
                    throw new CompileException("cannot convert type: " + value.getClass() + ": to " + fld.getType(), expr, start);
                }
                dataConversion(fld.getType());
                fld.set(ctx, convert(value, fld.getType()));
            } else {
                fld.set(ctx, value);
            }
            assert debug("PUTFIELD " + getInternalName(fld.getDeclaringClass()) + "." + tk);
            mv.visitFieldInsn(PUTFIELD, getInternalName(fld.getDeclaringClass()), tk, getDescriptor(fld.getType()));
            assert debug("jmp2:");
            mv.visitLabel(jmp2);
            assert debug("ALOAD 4");
            mv.visitVarInsn(ALOAD, 4);
        } else if (member != null) {
            assert debug("CHECKCAST " + getInternalName(ctx.getClass()));
            mv.visitTypeInsn(CHECKCAST, getInternalName(ctx.getClass()));
            Method meth = (Method) member;
            assert debug("ALOAD 4");
            mv.visitVarInsn(ALOAD, 4);
            Class targetType = meth.getParameterTypes()[0];
            Label jmp;
            Label jmp2 = new Label();
            if (value != null && !targetType.isAssignableFrom(value.getClass())) {
                if (!canConvert(targetType, value.getClass())) {
                    throw new CompileException("cannot convert type: " + value.getClass() + ": to " + meth.getParameterTypes()[0], expr, start);
                }
                dataConversion(getWrapperClass(targetType));
                if (targetType.isPrimitive()) {
                    unwrapPrimitive(targetType);
                } else
                    checkcast(targetType);
                meth.invoke(ctx, convert(value, meth.getParameterTypes()[0]));
            } else {
                if (targetType.isPrimitive()) {
                    if (value == null)
                        value = PropertyTools.getPrimitiveInitialValue(targetType);
                    jmp = new Label();
                    assert debug("IFNOTNULL jmp");
                    mv.visitJumpInsn(IFNONNULL, jmp);
                    assert debug("ICONST_0");
                    mv.visitInsn(ICONST_0);
                    assert debug("INVOKEVIRTUAL " + getInternalName(meth.getDeclaringClass()) + "." + meth.getName());
                    mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(meth.getDeclaringClass()), meth.getName(), getMethodDescriptor(meth));
                    assert debug("GOTO jmp2");
                    mv.visitJumpInsn(GOTO, jmp2);
                    assert debug("jmp:");
                    mv.visitLabel(jmp);
                    assert debug("ALOAD 4");
                    mv.visitVarInsn(ALOAD, 4);
                    unwrapPrimitive(targetType);
                } else {
                    checkcast(targetType);
                }
                meth.invoke(ctx, value);
            }
            assert debug("INVOKEVIRTUAL " + getInternalName(meth.getDeclaringClass()) + "." + meth.getName());
            mv.visitMethodInsn(INVOKEVIRTUAL, getInternalName(meth.getDeclaringClass()), meth.getName(), getMethodDescriptor(meth));
            assert debug("jmp2:");
            mv.visitLabel(jmp2);
            assert debug("ALOAD 4");
            mv.visitVarInsn(ALOAD, 4);
        } else if (ctx instanceof Map) {
            assert debug("CHECKCAST " + getInternalName(ctx.getClass()));
            mv.visitTypeInsn(CHECKCAST, getInternalName(ctx.getClass()));
            assert debug("LDC '" + tk + "'");
            mv.visitLdcInsn(tk);
            assert debug("ALOAD 4");
            mv.visitVarInsn(ALOAD, 4);
            assert debug("INVOKEINTERFACE java/util/Map.put");
            mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
            assert debug("ALOAD 4");
            mv.visitVarInsn(ALOAD, 4);
            // noinspection unchecked
            ((Map) ctx).put(tk, value);
        } else {
            throw new PropertyAccessException("could not access property (" + tk + ") in: " + ingressType.getName(), expr, start, pCtx);
        }
    } catch (InvocationTargetException e) {
        throw new PropertyAccessException("could not access property", expr, start, e, pCtx);
    } catch (IllegalAccessException e) {
        throw new PropertyAccessException("could not access property", expr, start, e, pCtx);
    }
    try {
        deferFinish = false;
        noinit = false;
        _finishJIT();
        return _initializeAccessor();
    } catch (Exception e) {
        throw new CompileException("could not generate accessor", expr, start, e);
    }
}
Also used : ExecutableStatement(org.mvel2.compiler.ExecutableStatement) PropertyVerifier(org.mvel2.compiler.PropertyVerifier) Label(org.mvel2.asm.Label) PropertyAccessException(org.mvel2.PropertyAccessException) ParseTools.determineActualTargetMethod(org.mvel2.util.ParseTools.determineActualTargetMethod) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) PropertyAccessException(org.mvel2.PropertyAccessException) IOException(java.io.IOException) CompileException(org.mvel2.CompileException) InvocationTargetException(java.lang.reflect.InvocationTargetException) Array(java.lang.reflect.Array) ReflectionUtil.toNonPrimitiveArray(org.mvel2.util.ReflectionUtil.toNonPrimitiveArray) Field(java.lang.reflect.Field) AccessorNode(org.mvel2.compiler.AccessorNode) CompileException(org.mvel2.CompileException) ArrayList(java.util.ArrayList) ParseTools.parseParameterList(org.mvel2.util.ParseTools.parseParameterList) List(java.util.List) ParseTools.findClass(org.mvel2.util.ParseTools.findClass) Map(java.util.Map) Member(java.lang.reflect.Member)

Aggregations

PropertyAccessException (org.mvel2.PropertyAccessException)19 Test (org.junit.Test)10 KieSession (org.kie.api.runtime.KieSession)10 Map (java.util.Map)7 IOException (java.io.IOException)6 ConsequenceException (org.kie.api.runtime.rule.ConsequenceException)6 CompileException (org.mvel2.CompileException)6 InvocationTargetException (java.lang.reflect.InvocationTargetException)5 Method (java.lang.reflect.Method)5 KieBase (org.kie.api.KieBase)5 KieServices (org.kie.api.KieServices)5 KieFileSystem (org.kie.api.builder.KieFileSystem)5 ReleaseId (org.kie.api.builder.ReleaseId)5 KieContainer (org.kie.api.runtime.KieContainer)5 Field (java.lang.reflect.Field)4 Member (java.lang.reflect.Member)4 List (java.util.List)4 Label (org.mvel2.asm.Label)4 ExecutableStatement (org.mvel2.compiler.ExecutableStatement)4 PropertyVerifier (org.mvel2.compiler.PropertyVerifier)3