Search in sources :

Example 1 with MethodAccessor

use of org.mvel2.optimizers.impl.refl.nodes.MethodAccessor in project drools by kiegroup.

the class MVELConditionEvaluator method isEvaluated.

private static boolean isEvaluated(ASTNode node) {
    node = unwrapSubstatement(node);
    if (node == null) {
        return true;
    }
    if (node instanceof Contains) {
        return ((Contains) node).getFirstStatement().getAccessor() != null;
    }
    if (node instanceof BooleanNode) {
        return isEvaluated(((BooleanNode) node).getLeft()) && isEvaluated(((BooleanNode) node).getRight());
    }
    Accessor accessor = node.getAccessor();
    if (accessor == null) {
        return node instanceof LiteralNode;
    }
    if (accessor instanceof AccessorNode) {
        AccessorNode nextNode = ((AccessorNode) accessor).getNextNode();
        if (nextNode instanceof MethodAccessor && ((MethodAccessor) nextNode).getParms() != null) {
            for (ExecutableStatement param : ((MethodAccessor) nextNode).getParms()) {
                if (!isFullyEvaluated(param)) {
                    return false;
                }
            }
        }
    }
    return true;
}
Also used : LiteralNode(org.mvel2.ast.LiteralNode) AccessorNode(org.mvel2.compiler.AccessorNode) ExecutableStatement(org.mvel2.compiler.ExecutableStatement) MethodAccessor(org.mvel2.optimizers.impl.refl.nodes.MethodAccessor) Contains(org.mvel2.ast.Contains) BooleanNode(org.mvel2.ast.BooleanNode) MethodAccessor(org.mvel2.optimizers.impl.refl.nodes.MethodAccessor) ExecutableAccessor(org.mvel2.compiler.ExecutableAccessor) Accessor(org.mvel2.compiler.Accessor)

Example 2 with MethodAccessor

use of org.mvel2.optimizers.impl.refl.nodes.MethodAccessor in project drools by kiegroup.

the class ConditionAnalyzer method analyzeAccessorInvocation.

private Invocation analyzeAccessorInvocation(AccessorNode accessorNode, ASTNode containingNode, Invocation formerInvocation, Class<?> variableType) {
    if (accessorNode instanceof GetterAccessor) {
        return new MethodInvocation(((GetterAccessor) accessorNode).getMethod(), variableType == null ? conditionClass : variableType.getName());
    }
    if (accessorNode instanceof MethodAccessor) {
        MethodAccessor methodAccessor = (MethodAccessor) accessorNode;
        Method method = methodAccessor.getMethod();
        MethodInvocation invocation = new MethodInvocation(method);
        boolean isVarArgs = method.isVarArgs();
        readInvocationParams(invocation, methodAccessor.getParms(), methodAccessor.getParameterTypes(), isVarArgs);
        return invocation;
    }
    if (accessorNode instanceof ConstructorAccessor) {
        ConstructorAccessor constructorAccessor = (ConstructorAccessor) accessorNode;
        Constructor constructor = constructorAccessor.getConstructor();
        ConstructorInvocation invocation = new ConstructorInvocation(constructor);
        readInvocationParams(invocation, constructorAccessor.getParameters(), constructorAccessor.getParameterTypes(), constructor.isVarArgs());
        return invocation;
    }
    if (accessorNode instanceof ArrayAccessor) {
        ArrayAccessor arrayAccessor = (ArrayAccessor) accessorNode;
        return new ArrayAccessInvocation(formerInvocation != null ? formerInvocation.getReturnType() : Object[].class, new FixedExpression(int.class, arrayAccessor.getIndex()));
    }
    if (accessorNode instanceof ArrayAccessorNest) {
        ArrayAccessorNest arrayAccessorNest = (ArrayAccessorNest) accessorNode;
        ExecutableAccessor index = (ExecutableAccessor) arrayAccessorNest.getIndex();
        return new ArrayAccessInvocation(formerInvocation != null ? formerInvocation.getReturnType() : Object[].class, analyzeNode(index.getNode()));
    }
    if (accessorNode instanceof ArrayLength) {
        return new ArrayLengthInvocation();
    }
    if (accessorNode instanceof ListAccessor) {
        Class<?> listType = getListType(formerInvocation);
        ListAccessor listAccessor = (ListAccessor) accessorNode;
        return new ListAccessInvocation(listType, new FixedExpression(int.class, listAccessor.getIndex()));
    }
    if (accessorNode instanceof ListAccessorNest) {
        Class<?> listType = getListType(formerInvocation);
        ListAccessorNest listAccessorNest = (ListAccessorNest) accessorNode;
        ExecutableAccessor index = (ExecutableAccessor) listAccessorNest.getIndex();
        return new ListAccessInvocation(listType, analyzeNode(index.getNode()));
    }
    if (accessorNode instanceof MapAccessor) {
        MapAccessor mapAccessor = (MapAccessor) accessorNode;
        return new MapAccessInvocation(Object.class, Object.class, new FixedExpression(Object.class, mapAccessor.getProperty()));
    }
    if (accessorNode instanceof MapAccessorNest) {
        Class<?> keyType = Object.class;
        Class<?> valueType = Object.class;
        Type[] generics = getGenerics(formerInvocation);
        if (generics != null && generics.length == 2 && generics[0] instanceof Class) {
            keyType = (Class<?>) generics[0];
            if (generics[1] instanceof Class)
                valueType = (Class<?>) generics[1];
        }
        MapAccessorNest mapAccessor = (MapAccessorNest) accessorNode;
        ExecutableStatement statement = mapAccessor.getProperty();
        if (statement instanceof ExecutableLiteral) {
            return new MapAccessInvocation(keyType, valueType, new FixedExpression(keyType, ((ExecutableLiteral) statement).getLiteral()));
        } else {
            return new MapAccessInvocation(keyType, valueType, analyzeNode(((ExecutableAccessor) statement).getNode()));
        }
    }
    if (accessorNode instanceof FieldAccessor) {
        return new FieldAccessInvocation(((FieldAccessor) accessorNode).getField());
    }
    if (accessorNode instanceof StaticVarAccessor) {
        Field field = ((StaticVarAccessor) accessorNode).getField();
        return new FieldAccessInvocation(field);
    }
    if (accessorNode instanceof ThisValueAccessor) {
        return new ThisInvocation(accessorNode.getNextNode() == null ? containingNode.getEgressType() : Object.class);
    }
    throw new RuntimeException("Unknown AccessorNode type: " + accessorNode.getClass().getName());
}
Also used : ArrayAccessorNest(org.mvel2.optimizers.impl.refl.nodes.ArrayAccessorNest) ExecutableAccessor(org.mvel2.compiler.ExecutableAccessor) FieldAccessor(org.mvel2.optimizers.impl.refl.nodes.FieldAccessor) ListAccessor(org.mvel2.optimizers.impl.refl.nodes.ListAccessor) Field(java.lang.reflect.Field) ThisValueAccessor(org.mvel2.optimizers.impl.refl.nodes.ThisValueAccessor) ExecutableLiteral(org.mvel2.compiler.ExecutableLiteral) MapAccessor(org.mvel2.optimizers.impl.refl.nodes.MapAccessor) ExecutableStatement(org.mvel2.compiler.ExecutableStatement) GetterAccessor(org.mvel2.optimizers.impl.refl.nodes.GetterAccessor) MethodAccessor(org.mvel2.optimizers.impl.refl.nodes.MethodAccessor) Constructor(java.lang.reflect.Constructor) ArrayLength(org.mvel2.optimizers.impl.refl.nodes.ArrayLength) StaticVarAccessor(org.mvel2.optimizers.impl.refl.nodes.StaticVarAccessor) Method(java.lang.reflect.Method) MapAccessorNest(org.mvel2.optimizers.impl.refl.nodes.MapAccessorNest) ArrayAccessor(org.mvel2.optimizers.impl.refl.nodes.ArrayAccessor) ClassUtils.convertToPrimitiveType(org.drools.core.util.ClassUtils.convertToPrimitiveType) Type(java.lang.reflect.Type) ParameterizedType(java.lang.reflect.ParameterizedType) ListAccessorNest(org.mvel2.optimizers.impl.refl.nodes.ListAccessorNest) ConstructorAccessor(org.mvel2.optimizers.impl.refl.nodes.ConstructorAccessor)

Example 3 with MethodAccessor

use of org.mvel2.optimizers.impl.refl.nodes.MethodAccessor in project drools by kiegroup.

the class ModifyInterceptor method extractMethod.

private Method extractMethod(WithNode.ParmValuePair parmValuePair) {
    Serializable setExpression = parmValuePair.getSetExpression();
    if (setExpression != null) {
        SetterAccessor setterAccessor = (SetterAccessor) ((CompiledAccExpression) setExpression).getAccessor();
        return setterAccessor.getMethod();
    } else {
        ExecutableAccessor accessor = (ExecutableAccessor) parmValuePair.getStatement();
        AccessorNode accessorNode = (AccessorNode) accessor.getNode().getAccessor();
        MethodAccessor methodAccessor = (MethodAccessor) accessorNode.getNextNode();
        return methodAccessor.getMethod();
    }
}
Also used : SetterAccessor(org.mvel2.optimizers.impl.refl.nodes.SetterAccessor) Serializable(java.io.Serializable) AccessorNode(org.mvel2.compiler.AccessorNode) MethodAccessor(org.mvel2.optimizers.impl.refl.nodes.MethodAccessor) ExecutableAccessor(org.mvel2.compiler.ExecutableAccessor)

Example 4 with MethodAccessor

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

the class ReflectiveAccessorOptimizer 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) throws Exception {
    int st = cursor;
    String tk = cursor != end && expr[cursor] == '(' && ((cursor = balancedCapture(expr, cursor, '(')) - st) > 1 ? new String(expr, st + 1, cursor - st - 1) : "";
    cursor++;
    Object[] args;
    Class[] argTypes;
    ExecutableStatement[] es;
    if (tk.length() == 0) {
        args = ParseTools.EMPTY_OBJ_ARR;
        argTypes = ParseTools.EMPTY_CLS_ARR;
        es = null;
    } else {
        List<char[]> subtokens = parseParameterList(tk.toCharArray(), 0, -1);
        es = new ExecutableStatement[subtokens.size()];
        args = new Object[subtokens.size()];
        argTypes = new Class[subtokens.size()];
        for (int i = 0; i < subtokens.size(); i++) {
            try {
                args[i] = (es[i] = (ExecutableStatement) subCompileExpression(subtokens.get(i), pCtx)).getValue(this.thisRef, thisRef, variableFactory);
            } catch (CompileException e) {
                throw ErrorUtil.rewriteIfNeeded(e, this.expr, this.start);
            }
            if (es[i].isExplicitCast())
                argTypes[i] = es[i].getKnownEgressType();
        }
        if (pCtx.isStrictTypeEnforcement()) {
            for (int i = 0; i < args.length; i++) {
                argTypes[i] = es[i].getKnownEgressType();
            }
        } else {
            for (int i = 0; i < args.length; i++) {
                if (argTypes[i] != null)
                    continue;
                if (es[i].getKnownEgressType() == Object.class) {
                    argTypes[i] = args[i] == null ? null : args[i].getClass();
                } else {
                    argTypes[i] = es[i].getKnownEgressType();
                }
            }
        }
    }
    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 func = (Function) ptr;
            if (!name.equals(func.getName())) {
                getBeanProperty(ctx, name);
                addAccessorNode(new DynamicFunctionAccessor(es));
            } else {
                addAccessorNode(new FunctionAccessor((Function) ptr, es));
            }
            return ((Function) ptr).call(ctx, thisRef, 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 PropertyAccessException("null pointer or function not found: " + name, this.expr, this.start);
    }
    boolean classTarget = false;
    Class<?> cls = currType != null ? currType : ((classTarget = ctx instanceof Class) ? (Class<?>) ctx : ctx.getClass());
    currType = null;
    Method m;
    Class[] parameterTypes = null;
    if ((m = getBestCandidate(argTypes, name, cls, cls.getMethods(), false, classTarget)) != null) {
        parameterTypes = m.getParameterTypes();
    }
    if (m == null && classTarget) {
        /**
         * If we didn't find anything, maybe we're looking for the actual java.lang.Class methods.
         */
        if ((m = getBestCandidate(argTypes, name, cls, Class.class.getMethods(), false)) != null) {
            parameterTypes = m.getParameterTypes();
        }
    }
    if (m == null) {
        StringAppender errorBuild = new StringAppender();
        if ("size".equals(name) && args.length == 0 && cls.isArray()) {
            addAccessorNode(new ArrayLength());
            return getLength(ctx);
        }
        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(", ");
        }
        throw new PropertyAccessException("unable to resolve method: " + cls.getName() + "." + name + "(" + errorBuild.toString() + ") [arglength=" + args.length + "]", this.expr, this.st);
    } else {
        if (es != null) {
            ExecutableStatement cExpr;
            for (int i = 0; i < es.length; i++) {
                cExpr = (ExecutableStatement) es[i];
                if (cExpr.getKnownIngressType() == null) {
                    cExpr.setKnownIngressType(parameterTypes[i]);
                    cExpr.computeTypeConversionRule();
                }
                if (!cExpr.isConvertableIngressEgress()) {
                    args[i] = convert(args[i], parameterTypes[i]);
                }
            }
        } else {
            /**
             * Coerce any types if required.
             */
            for (int i = 0; i < args.length; i++) args[i] = convert(args[i], parameterTypes[i]);
        }
        Object o = getWidenedTarget(m).invoke(ctx, args);
        if (hasNullMethodHandler()) {
            addAccessorNode(new MethodAccessorNH(getWidenedTarget(m), (ExecutableStatement[]) es, getNullMethodHandler()));
            if (o == null)
                o = getNullMethodHandler().getProperty(m.getName(), ctx, variableFactory);
        } else {
            addAccessorNode(new MethodAccessor(getWidenedTarget(m), (ExecutableStatement[]) es));
        }
        /**
         * return the response.
         */
        return o;
    }
}
Also used : ExecutableStatement(org.mvel2.compiler.ExecutableStatement) Function(org.mvel2.ast.Function)

Example 5 with MethodAccessor

use of org.mvel2.optimizers.impl.refl.nodes.MethodAccessor in project drools by kiegroup.

the class ConditionAnalyzer method analyzeAccessorInvocation.

private Invocation analyzeAccessorInvocation(AccessorNode accessorNode, ASTNode containingNode, Invocation formerInvocation, Class<?> variableType) {
    if (accessorNode instanceof GetterAccessor) {
        return new MethodInvocation(((GetterAccessor) accessorNode).getMethod(), variableType == null ? conditionClass : variableType.getName());
    }
    if (accessorNode instanceof MethodAccessor) {
        MethodAccessor methodAccessor = (MethodAccessor) accessorNode;
        Method method = methodAccessor.getMethod();
        MethodInvocation invocation = new MethodInvocation(method);
        boolean isVarArgs = method.isVarArgs();
        readInvocationParams(invocation, methodAccessor.getParms(), methodAccessor.getParameterTypes(), isVarArgs);
        return invocation;
    }
    if (accessorNode instanceof ConstructorAccessor) {
        ConstructorAccessor constructorAccessor = (ConstructorAccessor) accessorNode;
        Constructor constructor = constructorAccessor.getConstructor();
        ConstructorInvocation invocation = new ConstructorInvocation(constructor);
        readInvocationParams(invocation, constructorAccessor.getParameters(), constructorAccessor.getParameterTypes(), constructor.isVarArgs());
        return invocation;
    }
    if (accessorNode instanceof ArrayAccessor) {
        ArrayAccessor arrayAccessor = (ArrayAccessor) accessorNode;
        return new ArrayAccessInvocation(formerInvocation != null ? formerInvocation.getReturnType() : Object[].class, new FixedExpression(int.class, arrayAccessor.getIndex()));
    }
    if (accessorNode instanceof ArrayAccessorNest) {
        ArrayAccessorNest arrayAccessorNest = (ArrayAccessorNest) accessorNode;
        ExecutableAccessor index = (ExecutableAccessor) arrayAccessorNest.getIndex();
        return new ArrayAccessInvocation(formerInvocation != null ? formerInvocation.getReturnType() : Object[].class, analyzeNode(index.getNode()));
    }
    if (accessorNode instanceof ArrayLength) {
        return new ArrayLengthInvocation();
    }
    if (accessorNode instanceof ListAccessor) {
        Class<?> listType = getListType(formerInvocation);
        ListAccessor listAccessor = (ListAccessor) accessorNode;
        return new ListAccessInvocation(listType, new FixedExpression(int.class, listAccessor.getIndex()));
    }
    if (accessorNode instanceof ListAccessorNest) {
        Class<?> listType = getListType(formerInvocation);
        ListAccessorNest listAccessorNest = (ListAccessorNest) accessorNode;
        ExecutableAccessor index = (ExecutableAccessor) listAccessorNest.getIndex();
        return new ListAccessInvocation(listType, analyzeNode(index.getNode()));
    }
    if (accessorNode instanceof MapAccessor) {
        MapAccessor mapAccessor = (MapAccessor) accessorNode;
        return new MapAccessInvocation(Object.class, Object.class, new FixedExpression(Object.class, mapAccessor.getProperty()));
    }
    if (accessorNode instanceof MapAccessorNest) {
        Class<?> keyType = Object.class;
        Class<?> valueType = Object.class;
        Type[] generics = getGenerics(formerInvocation);
        if (generics != null && generics.length == 2 && generics[0] instanceof Class) {
            keyType = (Class<?>) generics[0];
            if (generics[1] instanceof Class)
                valueType = (Class<?>) generics[1];
        }
        MapAccessorNest mapAccessor = (MapAccessorNest) accessorNode;
        ExecutableStatement statement = mapAccessor.getProperty();
        if (statement instanceof ExecutableLiteral) {
            return new MapAccessInvocation(keyType, valueType, new FixedExpression(keyType, ((ExecutableLiteral) statement).getLiteral()));
        } else {
            return new MapAccessInvocation(keyType, valueType, analyzeNode(((ExecutableAccessor) statement).getNode()));
        }
    }
    if (accessorNode instanceof FieldAccessor) {
        return new FieldAccessInvocation(((FieldAccessor) accessorNode).getField());
    }
    if (accessorNode instanceof StaticVarAccessor) {
        Field field = ((StaticVarAccessor) accessorNode).getField();
        return new FieldAccessInvocation(field);
    }
    if (accessorNode instanceof ThisValueAccessor) {
        return new ThisInvocation(accessorNode.getNextNode() == null ? containingNode.getEgressType() : Object.class);
    }
    throw new RuntimeException("Unknown AccessorNode type: " + accessorNode.getClass().getName());
}
Also used : ArrayAccessorNest(org.mvel2.optimizers.impl.refl.nodes.ArrayAccessorNest) ExecutableAccessor(org.mvel2.compiler.ExecutableAccessor) FieldAccessor(org.mvel2.optimizers.impl.refl.nodes.FieldAccessor) ListAccessor(org.mvel2.optimizers.impl.refl.nodes.ListAccessor) Field(java.lang.reflect.Field) ThisValueAccessor(org.mvel2.optimizers.impl.refl.nodes.ThisValueAccessor) ExecutableLiteral(org.mvel2.compiler.ExecutableLiteral) MapAccessor(org.mvel2.optimizers.impl.refl.nodes.MapAccessor) ExecutableStatement(org.mvel2.compiler.ExecutableStatement) GetterAccessor(org.mvel2.optimizers.impl.refl.nodes.GetterAccessor) MethodAccessor(org.mvel2.optimizers.impl.refl.nodes.MethodAccessor) Constructor(java.lang.reflect.Constructor) ArrayLength(org.mvel2.optimizers.impl.refl.nodes.ArrayLength) StaticVarAccessor(org.mvel2.optimizers.impl.refl.nodes.StaticVarAccessor) Method(java.lang.reflect.Method) MapAccessorNest(org.mvel2.optimizers.impl.refl.nodes.MapAccessorNest) ArrayAccessor(org.mvel2.optimizers.impl.refl.nodes.ArrayAccessor) ClassUtils.convertToPrimitiveType(org.drools.core.util.ClassUtils.convertToPrimitiveType) Type(java.lang.reflect.Type) ParameterizedType(java.lang.reflect.ParameterizedType) ListAccessorNest(org.mvel2.optimizers.impl.refl.nodes.ListAccessorNest) ConstructorAccessor(org.mvel2.optimizers.impl.refl.nodes.ConstructorAccessor)

Aggregations

MethodAccessor (org.mvel2.optimizers.impl.refl.nodes.MethodAccessor)6 ExecutableStatement (org.mvel2.compiler.ExecutableStatement)5 Method (java.lang.reflect.Method)4 ExecutableAccessor (org.mvel2.compiler.ExecutableAccessor)4 ArrayLength (org.mvel2.optimizers.impl.refl.nodes.ArrayLength)4 Field (java.lang.reflect.Field)3 FieldAccessor (org.mvel2.optimizers.impl.refl.nodes.FieldAccessor)3 GetterAccessor (org.mvel2.optimizers.impl.refl.nodes.GetterAccessor)3 MapAccessor (org.mvel2.optimizers.impl.refl.nodes.MapAccessor)3 StaticVarAccessor (org.mvel2.optimizers.impl.refl.nodes.StaticVarAccessor)3 ThisValueAccessor (org.mvel2.optimizers.impl.refl.nodes.ThisValueAccessor)3 Constructor (java.lang.reflect.Constructor)2 ParameterizedType (java.lang.reflect.ParameterizedType)2 Type (java.lang.reflect.Type)2 ClassUtils.convertToPrimitiveType (org.drools.core.util.ClassUtils.convertToPrimitiveType)2 PropertyAccessException (org.mvel2.PropertyAccessException)2 AccessorNode (org.mvel2.compiler.AccessorNode)2 ExecutableLiteral (org.mvel2.compiler.ExecutableLiteral)2 ArrayAccessor (org.mvel2.optimizers.impl.refl.nodes.ArrayAccessor)2 ArrayAccessorNest (org.mvel2.optimizers.impl.refl.nodes.ArrayAccessorNest)2