public static VelMethod getMethod()

in velocity-engine-core/src/main/java/org/apache/velocity/util/ClassUtils.java [172:269]


    public static VelMethod getMethod(String methodName, Object[] params,
                                    Class<?>[] paramClasses, Object o, InternalContextAdapter context,
                                    SimpleNode node, boolean strictRef)
    {
        VelMethod method = null;
        try
        {
            /*
            * check the cache
            */
            boolean classObject = (o instanceof Class);
            MethodCacheKey mck = new MethodCacheKey(methodName, paramClasses, classObject);
            IntrospectionCacheData icd = context.icacheGet(mck);
            Class<?> clazz = classObject ? (Class<?>)o : o.getClass();

            /*
            * like ASTIdentifier, if we have cache information, and the Class of
            * Object o is the same as that in the cache, we are safe.
            */
            if (icd != null && icd.contextData == clazz)
            {
                /*
                * get the method from the cache
                */
                method = (VelMethod) icd.thingy;
            }
            else
            {
                /*
                * otherwise, do the introspection, and then cache it
                */
                method = node.getRuntimeServices().getUberspect().getMethod(o, methodName, params,
                    new Info(node.getTemplateName(), node.getLine(), node.getColumn()));

                if (method != null)
                {
                    icd = new IntrospectionCacheData();
                    icd.contextData = clazz;
                    icd.thingy = method;
                    context.icachePut(mck, icd);
                }
            }

            /*
            * if we still haven't gotten the method, either we are calling a method
            * that doesn't exist (which is fine...) or I screwed it up.
            */
            if (method == null)
            {
                if (strictRef)
                {
                    // Create a parameter list for the exception error message
                    StringBuilder plist = new StringBuilder();
                    for (int i = 0; i < params.length; i++)
                    {
                        Class<?> param = paramClasses[i];
                        plist.append(param == null ? "null" : param.getName());
                        if (i < params.length - 1)
                            plist.append(", ");
                    }
                    throw new MethodInvocationException("Object '"
                        + o.getClass().getName() + "' does not contain method "
                        + methodName + "(" + plist + ")", null, methodName, node
                        .getTemplateName(), node.getLine(), node.getColumn());
                }
                else
                {
                    return null;
                }
            }
        }
        catch (MethodInvocationException mie)
        {
            /*
            * this can come from the doIntrospection(), as the arg values are
            * evaluated to find the right method signature. We just want to propagate
            * it here, not do anything fancy
            */
            throw mie;
        }
        catch (RuntimeException e)
        {
            /**
            * pass through application level runtime exceptions
            */
            throw e;
        }
        catch (Exception e)
        {
            /*
            * can come from the doIntropection() also, from Introspector
            */
            String msg = "ASTMethod.execute() : exception from introspection";
            throw new VelocityException(msg, e);
        }

        return method;
    }