Search in sources :

Example 1 with ConstructorAccessor

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

the class ReflectiveAccessorOptimizer method compileConstructor.

@SuppressWarnings({ "WeakerAccess" })
private AccessorNode compileConstructor(char[] expression, Object ctx, VariableResolverFactory vars) throws InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, NoSuchMethodException {
    String[] cnsRes = captureContructorAndResidual(expression, start, length);
    List<char[]> constructorParms = parseMethodOrConstructor(cnsRes[0].toCharArray());
    if (constructorParms != null) {
        String s = new String(subset(expression, 0, ArrayTools.findFirst('(', start, length, expression)));
        Class cls = ParseTools.findClass(vars, s, pCtx);
        ExecutableStatement[] cStmts = new ExecutableStatement[constructorParms.size()];
        for (int i = 0; i < constructorParms.size(); i++) {
            cStmts[i] = (ExecutableStatement) subCompileExpression(constructorParms.get(i), pCtx);
        }
        Object[] parms = new Object[constructorParms.size()];
        for (int i = 0; i < constructorParms.size(); i++) {
            parms[i] = cStmts[i].getValue(ctx, vars);
        }
        Constructor cns = getBestConstructorCandidate(parms, cls, pCtx.isStrongTyping());
        if (cns == null) {
            StringBuilder error = new StringBuilder();
            for (int i = 0; i < parms.length; i++) {
                error.append(parms[i].getClass().getName());
                if (i + 1 < parms.length)
                    error.append(", ");
            }
            throw new CompileException("unable to find constructor: " + cls.getName() + "(" + error.toString() + ")", this.expr, this.start);
        }
        for (int i = 0; i < parms.length; i++) {
            // noinspection unchecked
            parms[i] = convert(parms[i], paramTypeVarArgsSafe(cns.getParameterTypes(), i, cns.isVarArgs()));
        }
        parms = normalizeArgsForVarArgs(cns.getParameterTypes(), parms, cns.isVarArgs());
        AccessorNode ca = new ConstructorAccessor(cns, cStmts);
        if (cnsRes.length > 1) {
            ReflectiveAccessorOptimizer compiledOptimizer = new ReflectiveAccessorOptimizer(pCtx, cnsRes[1].toCharArray(), 0, cnsRes[1].length(), cns.newInstance(parms), ctx, vars);
            compiledOptimizer.ingressType = cns.getDeclaringClass();
            compiledOptimizer.setRootNode(ca);
            compiledOptimizer.compileGetChain();
            ca = compiledOptimizer.getRootNode();
            this.val = compiledOptimizer.getResultOptPass();
        }
        return ca;
    } else {
        ClassLoader classLoader = pCtx != null ? pCtx.getClassLoader() : currentThread().getContextClassLoader();
        Constructor<?> cns = Class.forName(new String(expression), true, classLoader).getConstructor(EMPTYCLS);
        AccessorNode ca = new ConstructorAccessor(cns, null);
        if (cnsRes.length > 1) {
            // noinspection NullArgumentToVariableArgMethod
            ReflectiveAccessorOptimizer compiledOptimizer = new ReflectiveAccessorOptimizer(pCtx, cnsRes[1].toCharArray(), 0, cnsRes[1].length(), cns.newInstance(null), ctx, vars);
            compiledOptimizer.setRootNode(ca);
            compiledOptimizer.compileGetChain();
            ca = compiledOptimizer.getRootNode();
            this.val = compiledOptimizer.getResultOptPass();
        }
        return ca;
    }
}
Also used : ExecutableStatement(org.mvel2.compiler.ExecutableStatement) Constructor(java.lang.reflect.Constructor) AccessorNode(org.mvel2.compiler.AccessorNode) CompileException(org.mvel2.CompileException) ConstructorAccessor(org.mvel2.optimizers.impl.refl.nodes.ConstructorAccessor)

Example 2 with ConstructorAccessor

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

the class ReflectiveAccessorOptimizer method compileConstructor.

@SuppressWarnings({ "WeakerAccess" })
public AccessorNode compileConstructor(char[] expression, Object ctx, VariableResolverFactory vars) throws InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, NoSuchMethodException {
    String[] cnsRes = captureContructorAndResidual(expression, start, length);
    List<char[]> constructorParms = parseMethodOrConstructor(cnsRes[0].toCharArray());
    if (constructorParms != null) {
        String s = new String(subset(expression, 0, ArrayTools.findFirst('(', start, length, expression)));
        Class cls = ParseTools.findClass(vars, s, pCtx);
        ExecutableStatement[] cStmts = new ExecutableStatement[constructorParms.size()];
        for (int i = 0; i < constructorParms.size(); i++) {
            cStmts[i] = (ExecutableStatement) subCompileExpression(constructorParms.get(i), pCtx);
        }
        Object[] parms = new Object[constructorParms.size()];
        for (int i = 0; i < constructorParms.size(); i++) {
            parms[i] = cStmts[i].getValue(ctx, vars);
        }
        Constructor cns = getBestConstructorCandidate(parms, cls, pCtx.isStrongTyping());
        if (cns == null) {
            StringBuilder error = new StringBuilder();
            for (int i = 0; i < parms.length; i++) {
                error.append(parms[i].getClass().getName());
                if (i + 1 < parms.length)
                    error.append(", ");
            }
            throw new CompileException("unable to find constructor: " + cls.getName() + "(" + error.toString() + ")", this.expr, this.start);
        }
        for (int i = 0; i < parms.length; i++) {
            // noinspection unchecked
            parms[i] = convert(parms[i], cns.getParameterTypes()[i]);
        }
        AccessorNode ca = new ConstructorAccessor(cns, cStmts);
        if (cnsRes.length > 1) {
            ReflectiveAccessorOptimizer compiledOptimizer = new ReflectiveAccessorOptimizer(pCtx, cnsRes[1].toCharArray(), 0, cnsRes[1].length(), cns.newInstance(parms), ctx, vars);
            compiledOptimizer.ingressType = cns.getDeclaringClass();
            compiledOptimizer.setRootNode(ca);
            compiledOptimizer.compileGetChain();
            ca = compiledOptimizer.getRootNode();
            this.val = compiledOptimizer.getResultOptPass();
        }
        return ca;
    } else {
        Constructor<?> cns = Class.forName(new String(expression), true, Thread.currentThread().getContextClassLoader()).getConstructor(EMPTYCLS);
        AccessorNode ca = new ConstructorAccessor(cns, null);
        if (cnsRes.length > 1) {
            // noinspection NullArgumentToVariableArgMethod
            ReflectiveAccessorOptimizer compiledOptimizer = new ReflectiveAccessorOptimizer(getCurrentThreadParserContext(), cnsRes[1].toCharArray(), 0, cnsRes[1].length(), cns.newInstance(null), ctx, vars);
            compiledOptimizer.setRootNode(ca);
            compiledOptimizer.compileGetChain();
            ca = compiledOptimizer.getRootNode();
            this.val = compiledOptimizer.getResultOptPass();
        }
        return ca;
    }
}
Also used : ExecutableStatement(org.mvel2.compiler.ExecutableStatement) AccessorNode(org.mvel2.compiler.AccessorNode)

Example 3 with ConstructorAccessor

use of org.mvel2.optimizers.impl.refl.nodes.ConstructorAccessor 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

ExecutableStatement (org.mvel2.compiler.ExecutableStatement)3 Constructor (java.lang.reflect.Constructor)2 AccessorNode (org.mvel2.compiler.AccessorNode)2 ConstructorAccessor (org.mvel2.optimizers.impl.refl.nodes.ConstructorAccessor)2 Field (java.lang.reflect.Field)1 Method (java.lang.reflect.Method)1 ParameterizedType (java.lang.reflect.ParameterizedType)1 Type (java.lang.reflect.Type)1 ClassUtils.convertToPrimitiveType (org.drools.core.util.ClassUtils.convertToPrimitiveType)1 CompileException (org.mvel2.CompileException)1 ExecutableAccessor (org.mvel2.compiler.ExecutableAccessor)1 ExecutableLiteral (org.mvel2.compiler.ExecutableLiteral)1 ArrayAccessor (org.mvel2.optimizers.impl.refl.nodes.ArrayAccessor)1 ArrayAccessorNest (org.mvel2.optimizers.impl.refl.nodes.ArrayAccessorNest)1 ArrayLength (org.mvel2.optimizers.impl.refl.nodes.ArrayLength)1 FieldAccessor (org.mvel2.optimizers.impl.refl.nodes.FieldAccessor)1 GetterAccessor (org.mvel2.optimizers.impl.refl.nodes.GetterAccessor)1 ListAccessor (org.mvel2.optimizers.impl.refl.nodes.ListAccessor)1 ListAccessorNest (org.mvel2.optimizers.impl.refl.nodes.ListAccessorNest)1 MapAccessor (org.mvel2.optimizers.impl.refl.nodes.MapAccessor)1