コード例 #1
0
        private ITypedValue GetValueInternal(IEvaluationContext evaluationContext, object value, Type targetType, object[] arguments)
        {
            var argumentTypes = GetArgumentTypes(arguments);

            if (value == null)
            {
                ThrowIfNotNullSafe(argumentTypes);
                return(TypedValue.NULL);
            }

            var executorToUse = GetCachedExecutor(evaluationContext, value, targetType, argumentTypes);

            if (executorToUse != null)
            {
                try
                {
                    return(executorToUse.Execute(evaluationContext, value, arguments));
                }
                catch (AccessException ex)
                {
                    // Two reasons this can occur:
                    // 1. the method invoked actually threw a real exception
                    // 2. the method invoked was not passed the arguments it expected and
                    //    has become 'stale'

                    // In the first case we should not retry, in the second case we should see
                    // if there is a better suited method.

                    // To determine the situation, the AccessException will contain a cause.
                    // If the cause is an InvocationTargetException, a user exception was
                    // thrown inside the method. Otherwise the method could not be invoked.
                    ThrowSimpleExceptionIfPossible(value, ex);

                    // At this point we know it wasn't a user problem so worth a retry if a
                    // better candidate can be found.
                    _cachedExecutor = null;
                }
            }

            // either there was no accessor or it no longer existed
            executorToUse   = FindAccessorForMethod(argumentTypes, value, evaluationContext);
            _cachedExecutor = new CachedMethodExecutor(executorToUse, value is Type type ? type : null, targetType, argumentTypes);
            try
            {
                return(executorToUse.Execute(evaluationContext, value, arguments));
            }
            catch (AccessException ex)
            {
                // Same unwrapping exception handling as above in above catch block
                ThrowSimpleExceptionIfPossible(value, ex);
                throw new SpelEvaluationException(StartPosition, ex, SpelMessage.EXCEPTION_DURING_METHOD_INVOCATION, _name, value.GetType().FullName, ex.Message);
            }
        }
コード例 #2
0
        private IMethodExecutor GetCachedExecutor(IEvaluationContext evaluationContext, object value, Type target, IList <Type> argumentTypes)
        {
            var methodResolvers = evaluationContext.MethodResolvers;

            if (methodResolvers.Count != 1 || methodResolvers[0] is not ReflectiveMethodResolver)
            {
                // Not a default ReflectiveMethodResolver - don't know whether caching is valid
                return(null);
            }

            var executorToCheck = _cachedExecutor;

            if (executorToCheck != null && executorToCheck.IsSuitable(value, target, argumentTypes))
            {
                return(executorToCheck.Get());
            }

            _cachedExecutor = null;
            return(null);
        }