Search in sources :

Example 1 with StringAppender

use of org.mvel2.util.StringAppender in project mvel by mvel.

the class PropertyAccessor method getMethod.

/**
 * Find an appropriate method, execute it, and return it's response.
 *
 * @param ctx  -
 * @param name -
 * @return -
 */
@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 FunctionInstance) {
            ((FunctionInstance) ptr).getFunction().checkArgumentCount(args.length);
            return ((FunctionInstance) 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 = currType != null ? currType : ((ctx instanceof Class ? (Class) ctx : ctx.getClass()));
    currType = null;
    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.getDeclaredMethods(), false)) != null) {
                addMethodCache(cls, createSignature(name, tk), m);
                parameterTypes = m.getParameterTypes();
            }
        }
    }
    // If we didn't find anything and the declared class is different from the actual one try also with the actual one
    if (m == null && cls != ctx.getClass() && !(ctx instanceof Class)) {
        cls = ctx.getClass();
        if ((m = getBestCandidate(args, name, cls, cls.getDeclaredMethods(), false)) != null) {
            addMethodCache(cls, createSignature(name, tk), m);
            parameterTypes = m.getParameterTypes();
        }
    }
    if (ctx instanceof PrototypalFunctionInstance) {
        final VariableResolverFactory funcCtx = ((PrototypalFunctionInstance) ctx).getResolverFactory();
        Object prop = funcCtx.getVariableResolver(name).getValue();
        if (prop instanceof PrototypalFunctionInstance) {
            return ((PrototypalFunctionInstance) prop).call(ctx, thisReference, new InvokationContextFactory(variableFactory, funcCtx), args);
        }
    }
    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);
        }
        throw new PropertyAccessException("unable to resolve method: " + cls.getName() + "." + name + "(" + errorBuild.toString() + ") [arglength=" + args.length + "]", property, st, pCtx);
    } else {
        for (int i = 0; i < args.length; i++) {
            args[i] = convert(args[i], paramTypeVarArgsSafe(parameterTypes, i, m.isVarArgs()));
        }
        /**
         * Invoke the target method and return the response.
         */
        currType = toNonPrimitiveType(m.getReturnType());
        try {
            return m.invoke(ctx, normalizeArgsForVarArgs(parameterTypes, args, m.isVarArgs()));
        } 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, pCtx);
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new PropertyAccessException("unable to invoke method: " + name, property, cursor, e, pCtx);
        }
    }
}
Also used : VariableResolverFactory(org.mvel2.integration.VariableResolverFactory) MethodStub(org.mvel2.util.MethodStub) StringAppender(org.mvel2.util.StringAppender)

Example 2 with StringAppender

use of org.mvel2.util.StringAppender in project mvel by mvel.

the class PropertyVerifier method getMethod.

/**
 * Process method
 *
 * @param ctx  - the ingress type
 * @param name - the property component
 * @return known egress type.
 */
private Class getMethod(Class ctx, String name) {
    int st = cursor;
    /**
     * Check to see if this is the first element in the statement.
     */
    if (first) {
        first = false;
        methodCall = true;
        /**
         * It's the first element in the statement, therefore we check to see if there is a static import of a
         * native Java method or an MVEL function.
         */
        if (pCtx.hasImport(name)) {
            Method m = pCtx.getStaticImport(name).getMethod();
            /**
             * Replace the method parameters.
             */
            ctx = m.getDeclaringClass();
            name = m.getName();
        } else {
            Function f = pCtx.getFunction(name);
            if (f != null && f.getEgressType() != null) {
                resolvedExternally = false;
                f.checkArgumentCount(parseParameterList((((cursor = balancedCapture(expr, cursor, end, '(')) - st) > 1 ? ParseTools.subset(expr, st + 1, cursor - st - 1) : new char[0]), 0, -1).size());
                return f.getEgressType();
            } else if (pCtx.hasVarOrInput("this")) {
                if (pCtx.isStrictTypeEnforcement()) {
                    recordTypeParmsForProperty("this");
                }
                ctx = pCtx.getVarOrInputType("this");
                resolvedExternally = false;
            }
        }
    }
    /**
     * Get the arguments for the method.
     */
    String tk;
    if (cursor < end && expr[cursor] == '(' && ((cursor = balancedCapture(expr, cursor, end, '(')) - st) > 1) {
        tk = new String(expr, st + 1, cursor - st - 1);
    } else {
        tk = "";
    }
    cursor++;
    /**
     * Parse out the arguments list.
     */
    Class[] args;
    List<char[]> subtokens = parseParameterList(tk.toCharArray(), 0, -1);
    if (subtokens.size() == 0) {
        args = new Class[0];
        subtokens = Collections.emptyList();
    } else {
        // ParserContext subCtx = pCtx.createSubcontext();
        args = new Class[subtokens.size()];
        /**
         *  Subcompile all the arguments to determine their known types.
         */
        // ExpressionCompiler compiler;
        List<ErrorDetail> errors = pCtx.getErrorList().isEmpty() ? pCtx.getErrorList() : new ArrayList<ErrorDetail>(pCtx.getErrorList());
        CompileException rethrow = null;
        for (int i = 0; i < subtokens.size(); i++) {
            try {
                args[i] = MVEL.analyze(subtokens.get(i), pCtx);
                if ("null".equals(String.valueOf(subtokens.get(i)))) {
                    args[i] = NullType.class;
                }
            } catch (CompileException e) {
                rethrow = ErrorUtil.rewriteIfNeeded(e, expr, this.st);
            }
            if (errors.size() < pCtx.getErrorList().size()) {
                for (ErrorDetail detail : pCtx.getErrorList()) {
                    if (!errors.contains(detail)) {
                        detail.setExpr(expr);
                        detail.setCursor(new String(expr).substring(this.st).indexOf(new String(subtokens.get(i))) + this.st);
                        detail.setColumn(0);
                        detail.setLineNumber(0);
                        detail.calcRowAndColumn();
                    }
                }
            }
            if (rethrow != null) {
                throw rethrow;
            }
        }
    }
    /**
     * If the target object is an instance of java.lang.Class itself then do not
     * adjust the Class scope target.
     */
    Method m;
    if ((m = getBestCandidate(args, name, ctx, ctx.getMethods(), pCtx.isStrongTyping())) == null) {
        if ((m = getBestCandidate(args, name, ctx, ctx.getDeclaredMethods(), pCtx.isStrongTyping())) == null) {
            StringAppender errorBuild = new StringAppender();
            for (int i = 0; i < args.length; i++) {
                errorBuild.append(args[i] != null ? args[i].getName() : null);
                if (i < args.length - 1)
                    errorBuild.append(", ");
            }
            if (("size".equals(name) || "length".equals(name)) && args.length == 0 && ctx.isArray()) {
                return Integer.class;
            }
            if (pCtx.isStrictTypeEnforcement()) {
                throw new CompileException("unable to resolve method using strict-mode: " + ctx.getName() + "." + name + "(" + errorBuild.toString() + ")", expr, tkStart);
            }
            return Object.class;
        }
    }
    /**
     * If we're in strict mode, we look for generic type information.
     */
    if (pCtx.isStrictTypeEnforcement() && m.getGenericReturnType() != null) {
        Map<String, Class> typeArgs = new HashMap<String, Class>();
        Type[] gpt = m.getGenericParameterTypes();
        Class z;
        ParameterizedType pt;
        for (int i = 0; i < gpt.length; i++) {
            if (gpt[i] instanceof ParameterizedType) {
                pt = (ParameterizedType) gpt[i];
                if ((z = pCtx.getImport(new String(subtokens.get(i)))) != null) {
                    /**
                     * We record the value of the type parameter to our typeArgs Map.
                     */
                    if (pt.getRawType().equals(Class.class)) {
                        /**
                         * If this is an instance of Class, we deal with the special parameterization case.
                         */
                        typeArgs.put(pt.getActualTypeArguments()[0].toString(), z);
                    } else {
                        typeArgs.put(gpt[i].toString(), z);
                    }
                }
            }
        }
        if (pCtx.isStrictTypeEnforcement() && ctx.getTypeParameters().length != 0 && pCtx.getLastTypeParameters() != null && pCtx.getLastTypeParameters().length == ctx.getTypeParameters().length) {
            TypeVariable[] typeVariables = ctx.getTypeParameters();
            for (int i = 0; i < typeVariables.length; i++) {
                Type typeArg = pCtx.getLastTypeParameters()[i];
                typeArgs.put(typeVariables[i].getName(), typeArg instanceof Class ? type2Class(pCtx.getLastTypeParameters()[i]) : Object.class);
            }
        }
        /**
         * Get the return type argument
         */
        Type parametricReturnType = m.getGenericReturnType();
        String returnTypeArg = parametricReturnType.toString();
        // push return type parameters onto parser context, only if this is a parametric type
        if (parametricReturnType instanceof ParameterizedType) {
            pCtx.setLastTypeParameters(((ParameterizedType) parametricReturnType).getActualTypeArguments());
        }
        if (paramTypes != null && paramTypes.containsKey(returnTypeArg)) {
            /**
             * If the paramTypes Map contains the known type, return that type.
             */
            return type2Class(paramTypes.get(returnTypeArg));
        } else if (typeArgs.containsKey(returnTypeArg)) {
            /**
             * If the generic type was declared as part of the method, it will be in this
             * Map.
             */
            return typeArgs.get(returnTypeArg);
        }
    }
    if (!Modifier.isPublic(m.getModifiers()) && pCtx.isStrictTypeEnforcement()) {
        StringAppender errorBuild = new StringAppender();
        for (int i = 0; i < args.length; i++) {
            errorBuild.append(args[i] != null ? args[i].getName() : null);
            if (i < args.length - 1)
                errorBuild.append(", ");
        }
        String scope = Modifier.toString(m.getModifiers());
        if (scope.trim().equals(""))
            scope = "<package local>";
        addFatalError("the referenced method is not accessible: " + ctx.getName() + "." + name + "(" + errorBuild.toString() + ")" + " (scope: " + scope + "; required: public", this.tkStart);
    }
    return getReturnType(ctx, m);
}
Also used : HashMap(java.util.HashMap) Method(java.lang.reflect.Method) ErrorDetail(org.mvel2.ErrorDetail) ParameterizedType(java.lang.reflect.ParameterizedType) Function(org.mvel2.ast.Function) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) NullType(org.mvel2.util.NullType) TypeVariable(java.lang.reflect.TypeVariable) StringAppender(org.mvel2.util.StringAppender) CompileException(org.mvel2.CompileException)

Example 3 with StringAppender

use of org.mvel2.util.StringAppender in project mvel by mvel.

the class MVELIncludeTest method testEvalFile1.

/**
 * evalFile with sub template in utf-8 encoding
 *
 * @throws IOException
 */
public void testEvalFile1() throws IOException {
    final CompiledTemplate template = TemplateCompiler.compileTemplate(file);
    final String tr = (String) new TemplateRuntime(template.getTemplate(), null, template.getRoot(), "./samples/scripts/").execute(new StringAppender(), new HashMap<String, String>(), new ImmutableDefaultFactory());
    assertEquals("Hello mister Gaël Périé", tr);
}
Also used : ImmutableDefaultFactory(org.mvel2.integration.impl.ImmutableDefaultFactory) HashMap(java.util.HashMap) StringAppender(org.mvel2.util.StringAppender) TemplateRuntime(org.mvel2.templates.TemplateRuntime) CompiledTemplate(org.mvel2.templates.CompiledTemplate)

Example 4 with StringAppender

use of org.mvel2.util.StringAppender in project mvel by mvel.

the class ObjectInspector method renderMethods.

private static void renderMethods(Class cls) {
    Method[] methods = cls.getMethods();
    Method m;
    StringAppender appender = new StringAppender();
    int mf;
    for (int i = 0; i < methods.length; i++) {
        appender.append(TextUtil.paint(' ', PADDING + 2));
        if (((mf = (m = methods[i]).getModifiers()) & Modifier.PUBLIC) != 0)
            appender.append("public");
        else if ((mf & Modifier.PRIVATE) != 0)
            appender.append("private");
        else if ((mf & Modifier.PROTECTED) != 0)
            appender.append("protected");
        appender.append(' ').append(m.getReturnType().getName()).append(' ').append(m.getName()).append("(");
        Class[] parmTypes = m.getParameterTypes();
        for (int y = 0; y < parmTypes.length; y++) {
            if (parmTypes[y].isArray()) {
                appender.append(parmTypes[y].getComponentType().getName() + "[]");
            } else {
                appender.append(parmTypes[y].getName());
            }
            if ((y + 1) < parmTypes.length)
                appender.append(", ");
        }
        appender.append(")");
        if (m.getDeclaringClass() != cls) {
            appender.append("    [inherited from: ").append(m.getDeclaringClass().getName()).append("]");
        }
        if ((i + 1) < methods.length)
            appender.append('\n');
    }
    System.out.println(appender.toString());
}
Also used : StringAppender(org.mvel2.util.StringAppender) Method(java.lang.reflect.Method)

Example 5 with StringAppender

use of org.mvel2.util.StringAppender in project mvel by mvel.

the class Fuzzer method main.

public static void main(String[] args) throws IOException {
    DecimalFormat df = new DecimalFormat("###,###.##");
    StringAppender append = new StringAppender();
    int len;
    long start = currentTimeMillis();
    long time;
    double rate;
    int seed;
    boolean flip = false;
    Random rand = new Random(System.currentTimeMillis());
    Random rand1 = new Random(System.currentTimeMillis() + 1);
    Random rand2 = new Random(rand1.nextInt());
    Random rand3 = new Random(rand.nextInt(SALTS.length - 1));
    Random rand4 = new Random(rand3.nextInt());
    for (int run = 0; run < MAX; run++) {
        len = (int) (random() * 500) + 10;
        append.reset();
        for (int i = 0; i < len; i++) {
            append.append(CHAR_TABLE[((SALTS[((rand.nextInt(1000)) + 1) % SALTS.length]) * ((flip = !flip) ? rand1.nextInt(1000) : rand2.nextInt(1000)) + 1) % CHAR_TABLE.length]);
            SALTS[rand3.nextInt(SALTS.length - 1)] ^= rand4.nextInt(1000) + 1;
        }
        try {
            MVEL.eval(append.toString());
        } catch (UnresolveablePropertyException e) {
        // ignore
        } catch (CompileException e) {
        // ignore
        } catch (ArithmeticException e) {
        // ignore
        } catch (ScriptRuntimeException e) {
        // ignore
        } catch (Exception e) {
            System.out.println("untrapped error!\n---\n" + append.toString() + "\n---\n");
            System.out.flush();
            e.printStackTrace();
            System.err.flush();
        }
        if (run % 25000 == 0 && run != 0) {
            long l = time = (currentTimeMillis() - start) / 1000;
            if (l == 0) {
                l = 1;
            }
            rate = run / l;
            System.out.println("Run: " + df.format(run) + " times; " + df.format(time) + "secs; " + df.format(rate) + " avg. per second.");
        }
    }
}
Also used : Random(java.util.Random) ScriptRuntimeException(org.mvel2.ScriptRuntimeException) DecimalFormat(java.text.DecimalFormat) StringAppender(org.mvel2.util.StringAppender) CompileException(org.mvel2.CompileException) UnresolveablePropertyException(org.mvel2.UnresolveablePropertyException) UnresolveablePropertyException(org.mvel2.UnresolveablePropertyException) ScriptRuntimeException(org.mvel2.ScriptRuntimeException) IOException(java.io.IOException) CompileException(org.mvel2.CompileException)

Aggregations

StringAppender (org.mvel2.util.StringAppender)24 MethodVisitor (org.mvel2.asm.MethodVisitor)6 Method (java.lang.reflect.Method)5 CompileException (org.mvel2.CompileException)5 ClassWriter (org.mvel2.asm.ClassWriter)4 Function (org.mvel2.ast.Function)4 MethodStub (org.mvel2.util.MethodStub)4 HashMap (java.util.HashMap)3 ExecutableStatement (org.mvel2.compiler.ExecutableStatement)3 IOException (java.io.IOException)2 DecimalFormat (java.text.DecimalFormat)2 LinkedList (java.util.LinkedList)2 Random (java.util.Random)2 ErrorDetail (org.mvel2.ErrorDetail)2 OptimizationFailure (org.mvel2.OptimizationFailure)2 ParserContext (org.mvel2.ParserContext)2 ScriptRuntimeException (org.mvel2.ScriptRuntimeException)2 UnresolveablePropertyException (org.mvel2.UnresolveablePropertyException)2 FunctionInstance (org.mvel2.ast.FunctionInstance)2 CompiledExpression (org.mvel2.compiler.CompiledExpression)2