org.springframework.expression.TypeConverter

Here are the examples of the java api org.springframework.expression.TypeConverter taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

55 Examples 7

19 Source : StandardComponentsTests.java
with MIT License
from Vip-Augus

@Test
public void testStandardTypeConverter() throws EvaluationException {
    TypeConverter tc = new StandardTypeConverter();
    tc.convertValue(3, TypeDescriptor.forObject(3), TypeDescriptor.valueOf(Double.clreplaced));
}

19 Source : StandardEvaluationContext.java
with MIT License
from Vip-Augus

public void setTypeConverter(TypeConverter typeConverter) {
    replacedert.notNull(typeConverter, "TypeConverter must not be null");
    this.typeConverter = typeConverter;
}

19 Source : ReflectionHelper.java
with MIT License
from Vip-Augus

/**
 * Compare argument arrays and return information about whether they match.
 * A supplied type converter and conversionAllowed flag allow for matches to
 * take into account that a type may be transformed into a different type by the
 * converter. This variant of compareArguments also allows for a varargs match.
 * @param expectedArgTypes the types the method/constructor is expecting
 * @param suppliedArgTypes the types that are being supplied at the point of invocation
 * @param typeConverter a registered type converter
 * @return a MatchInfo object indicating what kind of match it was,
 * or {@code null} if it was not a match
 */
@Nullable
static ArgumentsMatchInfo compareArgumentsVarargs(List<TypeDescriptor> expectedArgTypes, List<TypeDescriptor> suppliedArgTypes, TypeConverter typeConverter) {
    replacedert.isTrue(!CollectionUtils.isEmpty(expectedArgTypes), "Expected arguments must at least include one array (the varargs parameter)");
    replacedert.isTrue(expectedArgTypes.get(expectedArgTypes.size() - 1).isArray(), "Final expected argument should be array type (the varargs parameter)");
    ArgumentsMatchKind match = ArgumentsMatchKind.EXACT;
    // Check up until the varargs argument:
    // Deal with the arguments up to 'expected number' - 1 (that is everything but the varargs argument)
    int argCountUpToVarargs = expectedArgTypes.size() - 1;
    for (int i = 0; i < argCountUpToVarargs && match != null; i++) {
        TypeDescriptor suppliedArg = suppliedArgTypes.get(i);
        TypeDescriptor expectedArg = expectedArgTypes.get(i);
        if (suppliedArg == null) {
            if (expectedArg.isPrimitive()) {
                match = null;
            }
        } else {
            if (!expectedArg.equals(suppliedArg)) {
                if (suppliedArg.isreplacedignableTo(expectedArg)) {
                    if (match != ArgumentsMatchKind.REQUIRES_CONVERSION) {
                        match = ArgumentsMatchKind.CLOSE;
                    }
                } else if (typeConverter.canConvert(suppliedArg, expectedArg)) {
                    match = ArgumentsMatchKind.REQUIRES_CONVERSION;
                } else {
                    match = null;
                }
            }
        }
    }
    // If already confirmed it cannot be a match, then return
    if (match == null) {
        return null;
    }
    if (suppliedArgTypes.size() == expectedArgTypes.size() && expectedArgTypes.get(expectedArgTypes.size() - 1).equals(suppliedArgTypes.get(suppliedArgTypes.size() - 1))) {
    // Special case: there is one parameter left and it is an array and it matches the varargs
    // expected argument - that is a match, the caller has already built the array. Proceed with it.
    } else {
        // Now... we have the final argument in the method we are checking as a match and we have 0
        // or more other arguments left to preplaced to it.
        TypeDescriptor varargsDesc = expectedArgTypes.get(expectedArgTypes.size() - 1);
        TypeDescriptor elementDesc = varargsDesc.getElementTypeDescriptor();
        replacedert.state(elementDesc != null, "No element type");
        Clreplaced<?> varargsParamType = elementDesc.getType();
        // All remaining parameters must be of this type or convertible to this type
        for (int i = expectedArgTypes.size() - 1; i < suppliedArgTypes.size(); i++) {
            TypeDescriptor suppliedArg = suppliedArgTypes.get(i);
            if (suppliedArg == null) {
                if (varargsParamType.isPrimitive()) {
                    match = null;
                }
            } else {
                if (varargsParamType != suppliedArg.getType()) {
                    if (ClreplacedUtils.isreplacedignable(varargsParamType, suppliedArg.getType())) {
                        if (match != ArgumentsMatchKind.REQUIRES_CONVERSION) {
                            match = ArgumentsMatchKind.CLOSE;
                        }
                    } else if (typeConverter.canConvert(suppliedArg, TypeDescriptor.valueOf(varargsParamType))) {
                        match = ArgumentsMatchKind.REQUIRES_CONVERSION;
                    } else {
                        match = null;
                    }
                }
            }
        }
    }
    return (match != null ? new ArgumentsMatchInfo(match) : null);
}

19 Source : ReflectionHelper.java
with MIT License
from Vip-Augus

// TODO could do with more refactoring around argument handling and varargs
/**
 * Convert a supplied set of arguments into the requested types. If the parameterTypes are related to
 * a varargs method then the final entry in the parameterTypes array is going to be an array itself whose
 * component type should be used as the conversion target for extraneous arguments. (For example, if the
 * parameterTypes are {Integer, String[]} and the input arguments are {Integer, boolean, float} then both
 * the boolean and float must be converted to strings). This method does *not* repackage the arguments
 * into a form suitable for the varargs invocation - a subsequent call to setupArgumentsForVarargsInvocation handles that.
 * @param converter the converter to use for type conversions
 * @param arguments the arguments to convert to the requested parameter types
 * @param method the target Method
 * @return true if some kind of conversion occurred on the argument
 * @throws SpelEvaluationException if there is a problem with conversion
 */
public static boolean convertAllArguments(TypeConverter converter, Object[] arguments, Method method) throws SpelEvaluationException {
    Integer varargsPosition = (method.isVarArgs() ? method.getParameterCount() - 1 : null);
    return convertArguments(converter, arguments, method, varargsPosition);
}

19 Source : ReflectionHelper.java
with MIT License
from Vip-Augus

/**
 * Takes an input set of argument values and converts them to the types specified as the
 * required parameter types. The arguments are converted 'in-place' in the input array.
 * @param converter the type converter to use for attempting conversions
 * @param arguments the actual arguments that need conversion
 * @param executable the target Method or Constructor
 * @param varargsPosition the known position of the varargs argument, if any
 * ({@code null} if not varargs)
 * @return {@code true} if some kind of conversion occurred on an argument
 * @throws EvaluationException if a problem occurs during conversion
 */
static boolean convertArguments(TypeConverter converter, Object[] arguments, Executable executable, @Nullable Integer varargsPosition) throws EvaluationException {
    boolean conversionOccurred = false;
    if (varargsPosition == null) {
        for (int i = 0; i < arguments.length; i++) {
            TypeDescriptor targetType = new TypeDescriptor(MethodParameter.forExecutable(executable, i));
            Object argument = arguments[i];
            arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType);
            conversionOccurred |= (argument != arguments[i]);
        }
    } else {
        // Convert everything up to the varargs position
        for (int i = 0; i < varargsPosition; i++) {
            TypeDescriptor targetType = new TypeDescriptor(MethodParameter.forExecutable(executable, i));
            Object argument = arguments[i];
            arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType);
            conversionOccurred |= (argument != arguments[i]);
        }
        MethodParameter methodParam = MethodParameter.forExecutable(executable, varargsPosition);
        if (varargsPosition == arguments.length - 1) {
            // If the target is varargs and there is just one more argument
            // then convert it here
            TypeDescriptor targetType = new TypeDescriptor(methodParam);
            Object argument = arguments[varargsPosition];
            TypeDescriptor sourceType = TypeDescriptor.forObject(argument);
            arguments[varargsPosition] = converter.convertValue(argument, sourceType, targetType);
            // Three outcomes of that previous line:
            // 1) the input argument was already compatible (ie. array of valid type) and nothing was done
            // 2) the input argument was correct type but not in an array so it was made into an array
            // 3) the input argument was the wrong type and got converted and put into an array
            if (argument != arguments[varargsPosition] && !isFirstEntryInArray(argument, arguments[varargsPosition])) {
                // case 3
                conversionOccurred = true;
            }
        } else {
            // Convert remaining arguments to the varargs element type
            TypeDescriptor targetType = new TypeDescriptor(methodParam).getElementTypeDescriptor();
            replacedert.state(targetType != null, "No element type");
            for (int i = varargsPosition; i < arguments.length; i++) {
                Object argument = arguments[i];
                arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType);
                conversionOccurred |= (argument != arguments[i]);
            }
        }
    }
    return conversionOccurred;
}

19 Source : ReflectionHelper.java
with MIT License
from Vip-Augus

/**
 * Compare argument arrays and return information about whether they match.
 * A supplied type converter and conversionAllowed flag allow for matches to take
 * into account that a type may be transformed into a different type by the converter.
 * @param expectedArgTypes the types the method/constructor is expecting
 * @param suppliedArgTypes the types that are being supplied at the point of invocation
 * @param typeConverter a registered type converter
 * @return a MatchInfo object indicating what kind of match it was,
 * or {@code null} if it was not a match
 */
@Nullable
static ArgumentsMatchInfo compareArguments(List<TypeDescriptor> expectedArgTypes, List<TypeDescriptor> suppliedArgTypes, TypeConverter typeConverter) {
    replacedert.isTrue(expectedArgTypes.size() == suppliedArgTypes.size(), "Expected argument types and supplied argument types should be arrays of same length");
    ArgumentsMatchKind match = ArgumentsMatchKind.EXACT;
    for (int i = 0; i < expectedArgTypes.size() && match != null; i++) {
        TypeDescriptor suppliedArg = suppliedArgTypes.get(i);
        TypeDescriptor expectedArg = expectedArgTypes.get(i);
        // The user may supply null - and that will be ok unless a primitive is expected
        if (suppliedArg == null) {
            if (expectedArg.isPrimitive()) {
                match = null;
            }
        } else if (!expectedArg.equals(suppliedArg)) {
            if (suppliedArg.isreplacedignableTo(expectedArg)) {
                if (match != ArgumentsMatchKind.REQUIRES_CONVERSION) {
                    match = ArgumentsMatchKind.CLOSE;
                }
            } else if (typeConverter.canConvert(suppliedArg, expectedArg)) {
                match = ArgumentsMatchKind.REQUIRES_CONVERSION;
            } else {
                match = null;
            }
        }
    }
    return (match != null ? new ArgumentsMatchInfo(match) : null);
}

19 Source : ExpressionUtils.java
with MIT License
from Vip-Augus

/**
 * Attempt to convert a typed value to a float using the supplied type converter.
 */
public static float toFloat(TypeConverter typeConverter, TypedValue typedValue) {
    return convertValue(typeConverter, typedValue, Float.clreplaced);
}

19 Source : ExpressionUtils.java
with MIT License
from Vip-Augus

/**
 * Attempt to convert a typed value to a long using the supplied type converter.
 */
public static long toLong(TypeConverter typeConverter, TypedValue typedValue) {
    return convertValue(typeConverter, typedValue, Long.clreplaced);
}

19 Source : ExpressionUtils.java
with MIT License
from Vip-Augus

/**
 * Attempt to convert a typed value to a char using the supplied type converter.
 */
public static char toChar(TypeConverter typeConverter, TypedValue typedValue) {
    return convertValue(typeConverter, typedValue, Character.clreplaced);
}

19 Source : ExpressionUtils.java
with MIT License
from Vip-Augus

/**
 * Attempt to convert a typed value to a double using the supplied type converter.
 */
public static double toDouble(TypeConverter typeConverter, TypedValue typedValue) {
    return convertValue(typeConverter, typedValue, Double.clreplaced);
}

19 Source : ExpressionUtils.java
with MIT License
from Vip-Augus

/**
 * Attempt to convert a typed value to an int using the supplied type converter.
 */
public static int toInt(TypeConverter typeConverter, TypedValue typedValue) {
    return convertValue(typeConverter, typedValue, Integer.clreplaced);
}

19 Source : ExpressionUtils.java
with MIT License
from Vip-Augus

/**
 * Attempt to convert a typed value to a byte using the supplied type converter.
 */
public static byte toByte(TypeConverter typeConverter, TypedValue typedValue) {
    return convertValue(typeConverter, typedValue, Byte.clreplaced);
}

19 Source : ExpressionUtils.java
with MIT License
from Vip-Augus

/**
 * Attempt to convert a typed value to a short using the supplied type converter.
 */
public static short toShort(TypeConverter typeConverter, TypedValue typedValue) {
    return convertValue(typeConverter, typedValue, Short.clreplaced);
}

19 Source : ExpressionUtils.java
with MIT License
from Vip-Augus

/**
 * Attempt to convert a typed value to a boolean using the supplied type converter.
 */
public static boolean toBoolean(TypeConverter typeConverter, TypedValue typedValue) {
    return convertValue(typeConverter, typedValue, Boolean.clreplaced);
}

19 Source : ReflectionHelper.java
with Apache License 2.0
from langtianya

// TODO could do with more refactoring around argument handling and varargs
/**
 * Convert a supplied set of arguments into the requested types. If the parameterTypes are related to
 * a varargs method then the final entry in the parameterTypes array is going to be an array itself whose
 * component type should be used as the conversion target for extraneous arguments. (For example, if the
 * parameterTypes are {Integer, String[]} and the input arguments are {Integer, boolean, float} then both
 * the boolean and float must be converted to strings). This method does *not* repackage the arguments
 * into a form suitable for the varargs invocation - a subsequent call to setupArgumentsForVarargsInvocation handles that.
 * @param converter the converter to use for type conversions
 * @param arguments the arguments to convert to the requested parameter types
 * @param method the target Method
 * @return true if some kind of conversion occurred on the argument
 * @throws SpelEvaluationException if there is a problem with conversion
 */
public static boolean convertAllArguments(TypeConverter converter, Object[] arguments, Method method) throws SpelEvaluationException {
    Integer varargsPosition = (method.isVarArgs() ? method.getParameterTypes().length - 1 : null);
    return convertArguments(converter, arguments, method, varargsPosition);
}

19 Source : ReflectionHelper.java
with Apache License 2.0
from langtianya

/**
 * Compare argument arrays and return information about whether they match.
 * A supplied type converter and conversionAllowed flag allow for matches to
 * take into account that a type may be transformed into a different type by the
 * converter. This variant of compareArguments also allows for a varargs match.
 * @param expectedArgTypes the types the method/constructor is expecting
 * @param suppliedArgTypes the types that are being supplied at the point of invocation
 * @param typeConverter a registered type converter
 * @return a MatchInfo object indicating what kind of match it was,
 * or {@code null} if it was not a match
 */
static ArgumentsMatchInfo compareArgumentsVarargs(List<TypeDescriptor> expectedArgTypes, List<TypeDescriptor> suppliedArgTypes, TypeConverter typeConverter) {
    replacedert.isTrue(expectedArgTypes != null && expectedArgTypes.size() > 0, "Expected arguments must at least include one array (the vargargs parameter)");
    replacedert.isTrue(expectedArgTypes.get(expectedArgTypes.size() - 1).isArray(), "Final expected argument should be array type (the varargs parameter)");
    ArgumentsMatchKind match = ArgumentsMatchKind.EXACT;
    // Check up until the varargs argument:
    // Deal with the arguments up to 'expected number' - 1 (that is everything but the varargs argument)
    int argCountUpToVarargs = expectedArgTypes.size() - 1;
    for (int i = 0; i < argCountUpToVarargs && match != null; i++) {
        TypeDescriptor suppliedArg = suppliedArgTypes.get(i);
        TypeDescriptor expectedArg = expectedArgTypes.get(i);
        if (suppliedArg == null) {
            if (expectedArg.isPrimitive()) {
                match = null;
            }
        } else {
            if (!expectedArg.equals(suppliedArg)) {
                if (suppliedArg.isreplacedignableTo(expectedArg)) {
                    if (match != ArgumentsMatchKind.REQUIRES_CONVERSION) {
                        match = ArgumentsMatchKind.CLOSE;
                    }
                } else if (typeConverter.canConvert(suppliedArg, expectedArg)) {
                    match = ArgumentsMatchKind.REQUIRES_CONVERSION;
                } else {
                    match = null;
                }
            }
        }
    }
    // If already confirmed it cannot be a match, then return
    if (match == null) {
        return null;
    }
    if (suppliedArgTypes.size() == expectedArgTypes.size() && expectedArgTypes.get(expectedArgTypes.size() - 1).equals(suppliedArgTypes.get(suppliedArgTypes.size() - 1))) {
    // Special case: there is one parameter left and it is an array and it matches the varargs
    // expected argument - that is a match, the caller has already built the array. Proceed with it.
    } else {
        // Now... we have the final argument in the method we are checking as a match and we have 0
        // or more other arguments left to preplaced to it.
        TypeDescriptor varargsDesc = expectedArgTypes.get(expectedArgTypes.size() - 1);
        Clreplaced<?> varargsParamType = varargsDesc.getElementTypeDescriptor().getType();
        // All remaining parameters must be of this type or convertable to this type
        for (int i = expectedArgTypes.size() - 1; i < suppliedArgTypes.size(); i++) {
            TypeDescriptor suppliedArg = suppliedArgTypes.get(i);
            if (suppliedArg == null) {
                if (varargsParamType.isPrimitive()) {
                    match = null;
                }
            } else {
                if (varargsParamType != suppliedArg.getType()) {
                    if (ClreplacedUtils.isreplacedignable(varargsParamType, suppliedArg.getType())) {
                        if (match != ArgumentsMatchKind.REQUIRES_CONVERSION) {
                            match = ArgumentsMatchKind.CLOSE;
                        }
                    } else if (typeConverter.canConvert(suppliedArg, TypeDescriptor.valueOf(varargsParamType))) {
                        match = ArgumentsMatchKind.REQUIRES_CONVERSION;
                    } else {
                        match = null;
                    }
                }
            }
        }
    }
    return (match != null ? new ArgumentsMatchInfo(match) : null);
}

19 Source : ReflectionHelper.java
with Apache License 2.0
from langtianya

/**
 * Compare argument arrays and return information about whether they match.
 * A supplied type converter and conversionAllowed flag allow for matches to take
 * into account that a type may be transformed into a different type by the converter.
 * @param expectedArgTypes the types the method/constructor is expecting
 * @param suppliedArgTypes the types that are being supplied at the point of invocation
 * @param typeConverter a registered type converter
 * @return a MatchInfo object indicating what kind of match it was,
 * or {@code null} if it was not a match
 */
static ArgumentsMatchInfo compareArguments(List<TypeDescriptor> expectedArgTypes, List<TypeDescriptor> suppliedArgTypes, TypeConverter typeConverter) {
    replacedert.isTrue(expectedArgTypes.size() == suppliedArgTypes.size(), "Expected argument types and supplied argument types should be arrays of same length");
    ArgumentsMatchKind match = ArgumentsMatchKind.EXACT;
    for (int i = 0; i < expectedArgTypes.size() && match != null; i++) {
        TypeDescriptor suppliedArg = suppliedArgTypes.get(i);
        TypeDescriptor expectedArg = expectedArgTypes.get(i);
        if (!expectedArg.equals(suppliedArg)) {
            // The user may supply null - and that will be ok unless a primitive is expected
            if (suppliedArg == null) {
                if (expectedArg.isPrimitive()) {
                    match = null;
                }
            } else {
                if (suppliedArg.isreplacedignableTo(expectedArg)) {
                    if (match != ArgumentsMatchKind.REQUIRES_CONVERSION) {
                        match = ArgumentsMatchKind.CLOSE;
                    }
                } else if (typeConverter.canConvert(suppliedArg, expectedArg)) {
                    match = ArgumentsMatchKind.REQUIRES_CONVERSION;
                } else {
                    match = null;
                }
            }
        }
    }
    return (match != null ? new ArgumentsMatchInfo(match) : null);
}

19 Source : ExpressionUtils.java
with Apache License 2.0
from langtianya

/**
 * Attempt to convert a typed value to a float using the supplied type converter.
 */
public static float toFloat(TypeConverter typeConverter, TypedValue typedValue) {
    return (Float) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(), TypeDescriptor.valueOf(Float.clreplaced));
}

19 Source : ExpressionUtils.java
with Apache License 2.0
from langtianya

/**
 * Attempt to convert a typed value to an int using the supplied type converter.
 */
public static int toInt(TypeConverter typeConverter, TypedValue typedValue) {
    return (Integer) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(), TypeDescriptor.valueOf(Integer.clreplaced));
}

19 Source : ExpressionUtils.java
with Apache License 2.0
from langtianya

/**
 * Attempt to convert a typed value to a char using the supplied type converter.
 */
public static char toChar(TypeConverter typeConverter, TypedValue typedValue) {
    return (Character) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(), TypeDescriptor.valueOf(Character.clreplaced));
}

19 Source : ExpressionUtils.java
with Apache License 2.0
from langtianya

/**
 * Attempt to convert a typed value to a boolean using the supplied type converter.
 */
public static boolean toBoolean(TypeConverter typeConverter, TypedValue typedValue) {
    return (Boolean) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(), TypeDescriptor.valueOf(Boolean.clreplaced));
}

19 Source : ExpressionUtils.java
with Apache License 2.0
from langtianya

/**
 * Attempt to convert a typed value to a long using the supplied type converter.
 */
public static long toLong(TypeConverter typeConverter, TypedValue typedValue) {
    return (Long) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(), TypeDescriptor.valueOf(Long.clreplaced));
}

19 Source : ExpressionUtils.java
with Apache License 2.0
from langtianya

/**
 * Attempt to convert a typed value to a byte using the supplied type converter.
 */
public static byte toByte(TypeConverter typeConverter, TypedValue typedValue) {
    return (Byte) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(), TypeDescriptor.valueOf(Byte.clreplaced));
}

19 Source : ExpressionUtils.java
with Apache License 2.0
from langtianya

/**
 * Attempt to convert a typed value to a double using the supplied type converter.
 */
public static double toDouble(TypeConverter typeConverter, TypedValue typedValue) {
    return (Double) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(), TypeDescriptor.valueOf(Double.clreplaced));
}

19 Source : ExpressionUtils.java
with Apache License 2.0
from langtianya

/**
 * Attempt to convert a typed value to a short using the supplied type converter.
 */
public static short toShort(TypeConverter typeConverter, TypedValue typedValue) {
    return (Short) typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(), TypeDescriptor.valueOf(Short.clreplaced));
}

18 Source : ReflectiveMethodResolver.java
with MIT License
from Vip-Augus

/**
 * Locate a method on a type. There are three kinds of match that might occur:
 * <ol>
 * <li>an exact match where the types of the arguments match the types of the constructor
 * <li>an in-exact match where the types we are looking for are subtypes of those defined on the constructor
 * <li>a match where we are able to convert the arguments into those expected by the constructor,
 * according to the registered type converter
 * </ol>
 */
@Override
@Nullable
public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name, List<TypeDescriptor> argumentTypes) throws AccessException {
    try {
        TypeConverter typeConverter = context.getTypeConverter();
        Clreplaced<?> type = (targetObject instanceof Clreplaced ? (Clreplaced<?>) targetObject : targetObject.getClreplaced());
        ArrayList<Method> methods = new ArrayList<>(getMethods(type, targetObject));
        // If a filter is registered for this type, call it
        MethodFilter filter = (this.filters != null ? this.filters.get(type) : null);
        if (filter != null) {
            List<Method> filtered = filter.filter(methods);
            methods = (filtered instanceof ArrayList ? (ArrayList<Method>) filtered : new ArrayList<>(filtered));
        }
        // Sort methods into a sensible order
        if (methods.size() > 1) {
            methods.sort((m1, m2) -> {
                int m1pl = m1.getParameterCount();
                int m2pl = m2.getParameterCount();
                // vararg methods go last
                if (m1pl == m2pl) {
                    if (!m1.isVarArgs() && m2.isVarArgs()) {
                        return -1;
                    } else if (m1.isVarArgs() && !m2.isVarArgs()) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
                return Integer.compare(m1pl, m2pl);
            });
        }
        // Resolve any bridge methods
        for (int i = 0; i < methods.size(); i++) {
            methods.set(i, BridgeMethodResolver.findBridgedMethod(methods.get(i)));
        }
        // Remove duplicate methods (possible due to resolved bridge methods)
        Set<Method> methodsToIterate = new LinkedHashSet<>(methods);
        Method closeMatch = null;
        int closeMatchDistance = Integer.MAX_VALUE;
        Method matchRequiringConversion = null;
        boolean multipleOptions = false;
        for (Method method : methodsToIterate) {
            if (method.getName().equals(name)) {
                Clreplaced<?>[] paramTypes = method.getParameterTypes();
                List<TypeDescriptor> paramDescriptors = new ArrayList<>(paramTypes.length);
                for (int i = 0; i < paramTypes.length; i++) {
                    paramDescriptors.add(new TypeDescriptor(new MethodParameter(method, i)));
                }
                ReflectionHelper.ArgumentsMatchInfo matchInfo = null;
                if (method.isVarArgs() && argumentTypes.size() >= (paramTypes.length - 1)) {
                    // *sigh* complicated
                    matchInfo = ReflectionHelper.compareArgumentsVarargs(paramDescriptors, argumentTypes, typeConverter);
                } else if (paramTypes.length == argumentTypes.size()) {
                    // Name and parameter number match, check the arguments
                    matchInfo = ReflectionHelper.compareArguments(paramDescriptors, argumentTypes, typeConverter);
                }
                if (matchInfo != null) {
                    if (matchInfo.isExactMatch()) {
                        return new ReflectiveMethodExecutor(method);
                    } else if (matchInfo.isCloseMatch()) {
                        if (this.useDistance) {
                            int matchDistance = ReflectionHelper.getTypeDifferenceWeight(paramDescriptors, argumentTypes);
                            if (closeMatch == null || matchDistance < closeMatchDistance) {
                                // This is a better match...
                                closeMatch = method;
                                closeMatchDistance = matchDistance;
                            }
                        } else {
                            // Take this as a close match if there isn't one already
                            if (closeMatch == null) {
                                closeMatch = method;
                            }
                        }
                    } else if (matchInfo.isMatchRequiringConversion()) {
                        if (matchRequiringConversion != null) {
                            multipleOptions = true;
                        }
                        matchRequiringConversion = method;
                    }
                }
            }
        }
        if (closeMatch != null) {
            return new ReflectiveMethodExecutor(closeMatch);
        } else if (matchRequiringConversion != null) {
            if (multipleOptions) {
                throw new SpelEvaluationException(SpelMessage.MULTIPLE_POSSIBLE_METHODS, name);
            }
            return new ReflectiveMethodExecutor(matchRequiringConversion);
        } else {
            return null;
        }
    } catch (EvaluationException ex) {
        throw new AccessException("Failed to resolve method", ex);
    }
}

18 Source : Indexer.java
with MIT License
from Vip-Augus

@SuppressWarnings("unchecked")
private <T> T convertValue(TypeConverter converter, @Nullable Object value, Clreplaced<T> targetType) {
    T result = (T) converter.convertValue(value, TypeDescriptor.forObject(value), TypeDescriptor.valueOf(targetType));
    if (result == null) {
        throw new IllegalStateException("Null conversion result for index [" + value + "]");
    }
    return result;
}

18 Source : Indexer.java
with MIT License
from Vip-Augus

private void setArrayElement(TypeConverter converter, Object ctx, int idx, @Nullable Object newValue, Clreplaced<?> arrayComponentType) throws EvaluationException {
    if (arrayComponentType == Boolean.TYPE) {
        boolean[] array = (boolean[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Boolean.clreplaced);
    } else if (arrayComponentType == Byte.TYPE) {
        byte[] array = (byte[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Byte.clreplaced);
    } else if (arrayComponentType == Character.TYPE) {
        char[] array = (char[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Character.clreplaced);
    } else if (arrayComponentType == Double.TYPE) {
        double[] array = (double[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Double.clreplaced);
    } else if (arrayComponentType == Float.TYPE) {
        float[] array = (float[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Float.clreplaced);
    } else if (arrayComponentType == Integer.TYPE) {
        int[] array = (int[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Integer.clreplaced);
    } else if (arrayComponentType == Long.TYPE) {
        long[] array = (long[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Long.clreplaced);
    } else if (arrayComponentType == Short.TYPE) {
        short[] array = (short[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Short.clreplaced);
    } else {
        Object[] array = (Object[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, arrayComponentType);
    }
}

18 Source : ConstructorReference.java
with MIT License
from Vip-Augus

private void populateIntArray(ExpressionState state, Object newArray, TypeConverter typeConverter, InlineList initializer) {
    int[] newIntArray = (int[]) newArray;
    for (int i = 0; i < newIntArray.length; i++) {
        TypedValue typedValue = initializer.getChild(i).getTypedValue(state);
        newIntArray[i] = ExpressionUtils.toInt(typeConverter, typedValue);
    }
}

18 Source : ConstructorReference.java
with MIT License
from Vip-Augus

private void populateFloatArray(ExpressionState state, Object newArray, TypeConverter typeConverter, InlineList initializer) {
    float[] newFloatArray = (float[]) newArray;
    for (int i = 0; i < newFloatArray.length; i++) {
        TypedValue typedValue = initializer.getChild(i).getTypedValue(state);
        newFloatArray[i] = ExpressionUtils.toFloat(typeConverter, typedValue);
    }
}

18 Source : ConstructorReference.java
with MIT License
from Vip-Augus

private void populateCharArray(ExpressionState state, Object newArray, TypeConverter typeConverter, InlineList initializer) {
    char[] newCharArray = (char[]) newArray;
    for (int i = 0; i < newCharArray.length; i++) {
        TypedValue typedValue = initializer.getChild(i).getTypedValue(state);
        newCharArray[i] = ExpressionUtils.toChar(typeConverter, typedValue);
    }
}

18 Source : ConstructorReference.java
with MIT License
from Vip-Augus

private void populateLongArray(ExpressionState state, Object newArray, TypeConverter typeConverter, InlineList initializer) {
    long[] newLongArray = (long[]) newArray;
    for (int i = 0; i < newLongArray.length; i++) {
        TypedValue typedValue = initializer.getChild(i).getTypedValue(state);
        newLongArray[i] = ExpressionUtils.toLong(typeConverter, typedValue);
    }
}

18 Source : ConstructorReference.java
with MIT License
from Vip-Augus

private void populateDoubleArray(ExpressionState state, Object newArray, TypeConverter typeConverter, InlineList initializer) {
    double[] newDoubleArray = (double[]) newArray;
    for (int i = 0; i < newDoubleArray.length; i++) {
        TypedValue typedValue = initializer.getChild(i).getTypedValue(state);
        newDoubleArray[i] = ExpressionUtils.toDouble(typeConverter, typedValue);
    }
}

18 Source : ConstructorReference.java
with MIT License
from Vip-Augus

private void populateBooleanArray(ExpressionState state, Object newArray, TypeConverter typeConverter, InlineList initializer) {
    boolean[] newBooleanArray = (boolean[]) newArray;
    for (int i = 0; i < newBooleanArray.length; i++) {
        TypedValue typedValue = initializer.getChild(i).getTypedValue(state);
        newBooleanArray[i] = ExpressionUtils.toBoolean(typeConverter, typedValue);
    }
}

18 Source : ConstructorReference.java
with MIT License
from Vip-Augus

private void populateShortArray(ExpressionState state, Object newArray, TypeConverter typeConverter, InlineList initializer) {
    short[] newShortArray = (short[]) newArray;
    for (int i = 0; i < newShortArray.length; i++) {
        TypedValue typedValue = initializer.getChild(i).getTypedValue(state);
        newShortArray[i] = ExpressionUtils.toShort(typeConverter, typedValue);
    }
}

18 Source : ConstructorReference.java
with MIT License
from Vip-Augus

private void populateByteArray(ExpressionState state, Object newArray, TypeConverter typeConverter, InlineList initializer) {
    byte[] newByteArray = (byte[]) newArray;
    for (int i = 0; i < newByteArray.length; i++) {
        TypedValue typedValue = initializer.getChild(i).getTypedValue(state);
        newByteArray[i] = ExpressionUtils.toByte(typeConverter, typedValue);
    }
}

18 Source : ReflectiveMethodResolver.java
with Apache License 2.0
from SourceHot

/**
 * Locate a method on a type. There are three kinds of match that might occur:
 * <ol>
 * <li>an exact match where the types of the arguments match the types of the constructor
 * <li>an in-exact match where the types we are looking for are subtypes of those defined on the constructor
 * <li>a match where we are able to convert the arguments into those expected by the constructor,
 * according to the registered type converter
 * </ol>
 */
@Override
@Nullable
public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name, List<TypeDescriptor> argumentTypes) throws AccessException {
    try {
        TypeConverter typeConverter = context.getTypeConverter();
        Clreplaced<?> type = (targetObject instanceof Clreplaced ? (Clreplaced<?>) targetObject : targetObject.getClreplaced());
        ArrayList<Method> methods = new ArrayList<>(getMethods(type, targetObject));
        // If a filter is registered for this type, call it
        MethodFilter filter = (this.filters != null ? this.filters.get(type) : null);
        if (filter != null) {
            List<Method> filtered = filter.filter(methods);
            methods = (filtered instanceof ArrayList ? (ArrayList<Method>) filtered : new ArrayList<>(filtered));
        }
        // Sort methods into a sensible order
        if (methods.size() > 1) {
            methods.sort((m1, m2) -> {
                int m1pl = m1.getParameterCount();
                int m2pl = m2.getParameterCount();
                // vararg methods go last
                if (m1pl == m2pl) {
                    if (!m1.isVarArgs() && m2.isVarArgs()) {
                        return -1;
                    } else if (m1.isVarArgs() && !m2.isVarArgs()) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
                return Integer.compare(m1pl, m2pl);
            });
        }
        // Resolve any bridge methods
        for (int i = 0; i < methods.size(); i++) {
            methods.set(i, BridgeMethodResolver.findBridgedMethod(methods.get(i)));
        }
        // Remove duplicate methods (possible due to resolved bridge methods)
        Set<Method> methodsToIterate = new LinkedHashSet<>(methods);
        Method closeMatch = null;
        int closeMatchDistance = Integer.MAX_VALUE;
        Method matchRequiringConversion = null;
        boolean multipleOptions = false;
        for (Method method : methodsToIterate) {
            if (method.getName().equals(name)) {
                int paramCount = method.getParameterCount();
                List<TypeDescriptor> paramDescriptors = new ArrayList<>(paramCount);
                for (int i = 0; i < paramCount; i++) {
                    paramDescriptors.add(new TypeDescriptor(new MethodParameter(method, i)));
                }
                ReflectionHelper.ArgumentsMatchInfo matchInfo = null;
                if (method.isVarArgs() && argumentTypes.size() >= (paramCount - 1)) {
                    // *sigh* complicated
                    matchInfo = ReflectionHelper.compareArgumentsVarargs(paramDescriptors, argumentTypes, typeConverter);
                } else if (paramCount == argumentTypes.size()) {
                    // Name and parameter number match, check the arguments
                    matchInfo = ReflectionHelper.compareArguments(paramDescriptors, argumentTypes, typeConverter);
                }
                if (matchInfo != null) {
                    if (matchInfo.isExactMatch()) {
                        return new ReflectiveMethodExecutor(method);
                    } else if (matchInfo.isCloseMatch()) {
                        if (this.useDistance) {
                            int matchDistance = ReflectionHelper.getTypeDifferenceWeight(paramDescriptors, argumentTypes);
                            if (closeMatch == null || matchDistance < closeMatchDistance) {
                                // This is a better match...
                                closeMatch = method;
                                closeMatchDistance = matchDistance;
                            }
                        } else {
                            // Take this as a close match if there isn't one already
                            if (closeMatch == null) {
                                closeMatch = method;
                            }
                        }
                    } else if (matchInfo.isMatchRequiringConversion()) {
                        if (matchRequiringConversion != null) {
                            multipleOptions = true;
                        }
                        matchRequiringConversion = method;
                    }
                }
            }
        }
        if (closeMatch != null) {
            return new ReflectiveMethodExecutor(closeMatch);
        } else if (matchRequiringConversion != null) {
            if (multipleOptions) {
                throw new SpelEvaluationException(SpelMessage.MULTIPLE_POSSIBLE_METHODS, name);
            }
            return new ReflectiveMethodExecutor(matchRequiringConversion);
        } else {
            return null;
        }
    } catch (EvaluationException ex) {
        throw new AccessException("Failed to resolve method", ex);
    }
}

18 Source : ReflectionHelper.java
with Apache License 2.0
from langtianya

/**
 * Takes an input set of argument values and converts them to the types specified as the
 * required parameter types. The arguments are converted 'in-place' in the input array.
 * @param converter the type converter to use for attempting conversions
 * @param arguments the actual arguments that need conversion
 * @param methodOrCtor the target Method or Constructor
 * @param varargsPosition the known position of the varargs argument, if any
 * ({@code null} if not varargs)
 * @return {@code true} if some kind of conversion occurred on an argument
 * @throws EvaluationException if a problem occurs during conversion
 */
static boolean convertArguments(TypeConverter converter, Object[] arguments, Object methodOrCtor, Integer varargsPosition) throws EvaluationException {
    boolean conversionOccurred = false;
    if (varargsPosition == null) {
        for (int i = 0; i < arguments.length; i++) {
            TypeDescriptor targetType = new TypeDescriptor(MethodParameter.forMethodOrConstructor(methodOrCtor, i));
            Object argument = arguments[i];
            arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType);
            conversionOccurred |= (argument != arguments[i]);
        }
    } else {
        // Convert everything up to the varargs position
        for (int i = 0; i < varargsPosition; i++) {
            TypeDescriptor targetType = new TypeDescriptor(MethodParameter.forMethodOrConstructor(methodOrCtor, i));
            Object argument = arguments[i];
            arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType);
            conversionOccurred |= (argument != arguments[i]);
        }
        MethodParameter methodParam = MethodParameter.forMethodOrConstructor(methodOrCtor, varargsPosition);
        if (varargsPosition == arguments.length - 1) {
            // If the target is varargs and there is just one more argument
            // then convert it here
            TypeDescriptor targetType = new TypeDescriptor(methodParam);
            Object argument = arguments[varargsPosition];
            TypeDescriptor sourceType = TypeDescriptor.forObject(argument);
            arguments[varargsPosition] = converter.convertValue(argument, sourceType, targetType);
            // Three outcomes of that previous line:
            // 1) the input argument was already compatible (ie. array of valid type) and nothing was done
            // 2) the input argument was correct type but not in an array so it was made into an array
            // 3) the input argument was the wrong type and got converted and put into an array
            if (argument != arguments[varargsPosition] && !isFirstEntryInArray(argument, arguments[varargsPosition])) {
                // case 3
                conversionOccurred = true;
            }
        } else {
            // Convert remaining arguments to the varargs element type
            TypeDescriptor targetType = new TypeDescriptor(methodParam).getElementTypeDescriptor();
            for (int i = varargsPosition; i < arguments.length; i++) {
                Object argument = arguments[i];
                arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType);
                conversionOccurred |= (argument != arguments[i]);
            }
        }
    }
    return conversionOccurred;
}

18 Source : Indexer.java
with Apache License 2.0
from langtianya

@SuppressWarnings("unchecked")
private <T> T convertValue(TypeConverter converter, Object value, Clreplaced<T> targetType) {
    return (T) converter.convertValue(value, TypeDescriptor.forObject(value), TypeDescriptor.valueOf(targetType));
}

18 Source : Indexer.java
with Apache License 2.0
from langtianya

private void setArrayElement(TypeConverter converter, Object ctx, int idx, Object newValue, Clreplaced<?> arrayComponentType) throws EvaluationException {
    if (arrayComponentType == Double.TYPE) {
        double[] array = (double[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Double.clreplaced);
    } else if (arrayComponentType == Float.TYPE) {
        float[] array = (float[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Float.clreplaced);
    } else if (arrayComponentType == Long.TYPE) {
        long[] array = (long[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Long.clreplaced);
    } else if (arrayComponentType == Integer.TYPE) {
        int[] array = (int[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Integer.clreplaced);
    } else if (arrayComponentType == Short.TYPE) {
        short[] array = (short[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Short.clreplaced);
    } else if (arrayComponentType == Byte.TYPE) {
        byte[] array = (byte[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Byte.clreplaced);
    } else if (arrayComponentType == Character.TYPE) {
        char[] array = (char[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Character.clreplaced);
    } else if (arrayComponentType == Boolean.TYPE) {
        boolean[] array = (boolean[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, Boolean.clreplaced);
    } else {
        Object[] array = (Object[]) ctx;
        checkAccess(array.length, idx);
        array[idx] = convertValue(converter, newValue, arrayComponentType);
    }
}

17 Source : StandardEvaluationContext.java
with MIT License
from Vip-Augus

/**
 * A powerful and highly configurable {@link EvaluationContext} implementation.
 * This context uses standard implementations of all applicable strategies,
 * based on reflection to resolve properties, methods and fields.
 *
 * <p>For a simpler builder-style context variant for data-binding purposes,
 * consider using {@link SimpleEvaluationContext} instead which allows for
 * opting into several SpEL features as needed by specific evaluation cases.
 *
 * @author Andy Clement
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @since 3.0
 * @see SimpleEvaluationContext
 * @see ReflectivePropertyAccessor
 * @see ReflectiveConstructorResolver
 * @see ReflectiveMethodResolver
 * @see StandardTypeLocator
 * @see StandardTypeConverter
 * @see StandardTypeComparator
 * @see StandardOperatorOverloader
 */
public clreplaced StandardEvaluationContext implements EvaluationContext {

    private TypedValue rootObject;

    @Nullable
    private volatile List<PropertyAccessor> propertyAccessors;

    @Nullable
    private volatile List<ConstructorResolver> constructorResolvers;

    @Nullable
    private volatile List<MethodResolver> methodResolvers;

    @Nullable
    private volatile ReflectiveMethodResolver reflectiveMethodResolver;

    @Nullable
    private BeanResolver beanResolver;

    @Nullable
    private TypeLocator typeLocator;

    @Nullable
    private TypeConverter typeConverter;

    private TypeComparator typeComparator = new StandardTypeComparator();

    private OperatorOverloader operatorOverloader = new StandardOperatorOverloader();

    private final Map<String, Object> variables = new ConcurrentHashMap<>();

    /**
     * Create a {@code StandardEvaluationContext} with a null root object.
     */
    public StandardEvaluationContext() {
        this.rootObject = TypedValue.NULL;
    }

    /**
     * Create a {@code StandardEvaluationContext} with the given root object.
     * @param rootObject the root object to use
     * @see #setRootObject
     */
    public StandardEvaluationContext(Object rootObject) {
        this.rootObject = new TypedValue(rootObject);
    }

    public void setRootObject(Object rootObject, TypeDescriptor typeDescriptor) {
        this.rootObject = new TypedValue(rootObject, typeDescriptor);
    }

    public void setRootObject(@Nullable Object rootObject) {
        this.rootObject = (rootObject != null ? new TypedValue(rootObject) : TypedValue.NULL);
    }

    @Override
    public TypedValue getRootObject() {
        return this.rootObject;
    }

    public void setPropertyAccessors(List<PropertyAccessor> propertyAccessors) {
        this.propertyAccessors = propertyAccessors;
    }

    @Override
    public List<PropertyAccessor> getPropertyAccessors() {
        return initPropertyAccessors();
    }

    public void addPropertyAccessor(PropertyAccessor accessor) {
        addBeforeDefault(initPropertyAccessors(), accessor);
    }

    public boolean removePropertyAccessor(PropertyAccessor accessor) {
        return initPropertyAccessors().remove(accessor);
    }

    public void setConstructorResolvers(List<ConstructorResolver> constructorResolvers) {
        this.constructorResolvers = constructorResolvers;
    }

    @Override
    public List<ConstructorResolver> getConstructorResolvers() {
        return initConstructorResolvers();
    }

    public void addConstructorResolver(ConstructorResolver resolver) {
        addBeforeDefault(initConstructorResolvers(), resolver);
    }

    public boolean removeConstructorResolver(ConstructorResolver resolver) {
        return initConstructorResolvers().remove(resolver);
    }

    public void setMethodResolvers(List<MethodResolver> methodResolvers) {
        this.methodResolvers = methodResolvers;
    }

    @Override
    public List<MethodResolver> getMethodResolvers() {
        return initMethodResolvers();
    }

    public void addMethodResolver(MethodResolver resolver) {
        addBeforeDefault(initMethodResolvers(), resolver);
    }

    public boolean removeMethodResolver(MethodResolver methodResolver) {
        return initMethodResolvers().remove(methodResolver);
    }

    public void setBeanResolver(BeanResolver beanResolver) {
        this.beanResolver = beanResolver;
    }

    @Override
    @Nullable
    public BeanResolver getBeanResolver() {
        return this.beanResolver;
    }

    public void setTypeLocator(TypeLocator typeLocator) {
        replacedert.notNull(typeLocator, "TypeLocator must not be null");
        this.typeLocator = typeLocator;
    }

    @Override
    public TypeLocator getTypeLocator() {
        if (this.typeLocator == null) {
            this.typeLocator = new StandardTypeLocator();
        }
        return this.typeLocator;
    }

    public void setTypeConverter(TypeConverter typeConverter) {
        replacedert.notNull(typeConverter, "TypeConverter must not be null");
        this.typeConverter = typeConverter;
    }

    @Override
    public TypeConverter getTypeConverter() {
        if (this.typeConverter == null) {
            this.typeConverter = new StandardTypeConverter();
        }
        return this.typeConverter;
    }

    public void setTypeComparator(TypeComparator typeComparator) {
        replacedert.notNull(typeComparator, "TypeComparator must not be null");
        this.typeComparator = typeComparator;
    }

    @Override
    public TypeComparator getTypeComparator() {
        return this.typeComparator;
    }

    public void setOperatorOverloader(OperatorOverloader operatorOverloader) {
        replacedert.notNull(operatorOverloader, "OperatorOverloader must not be null");
        this.operatorOverloader = operatorOverloader;
    }

    @Override
    public OperatorOverloader getOperatorOverloader() {
        return this.operatorOverloader;
    }

    @Override
    public void setVariable(@Nullable String name, @Nullable Object value) {
        // For backwards compatibility, we ignore null names here...
        // And since ConcurrentHashMap cannot store null values, we simply take null
        // as a remove from the Map (with the same result from lookupVariable below).
        if (name != null) {
            if (value != null) {
                this.variables.put(name, value);
            } else {
                this.variables.remove(name);
            }
        }
    }

    public void setVariables(Map<String, Object> variables) {
        variables.forEach(this::setVariable);
    }

    public void registerFunction(String name, Method method) {
        this.variables.put(name, method);
    }

    @Override
    @Nullable
    public Object lookupVariable(String name) {
        return this.variables.get(name);
    }

    /**
     * Register a {@code MethodFilter} which will be called during method resolution
     * for the specified type.
     * <p>The {@code MethodFilter} may remove methods and/or sort the methods which
     * will then be used by SpEL as the candidates to look through for a match.
     * @param type the type for which the filter should be called
     * @param filter a {@code MethodFilter}, or {@code null} to unregister a filter for the type
     * @throws IllegalStateException if the {@link ReflectiveMethodResolver} is not in use
     */
    public void registerMethodFilter(Clreplaced<?> type, MethodFilter filter) throws IllegalStateException {
        initMethodResolvers();
        ReflectiveMethodResolver resolver = this.reflectiveMethodResolver;
        if (resolver == null) {
            throw new IllegalStateException("Method filter cannot be set as the reflective method resolver is not in use");
        }
        resolver.registerMethodFilter(type, filter);
    }

    private List<PropertyAccessor> initPropertyAccessors() {
        List<PropertyAccessor> accessors = this.propertyAccessors;
        if (accessors == null) {
            accessors = new ArrayList<>(5);
            accessors.add(new ReflectivePropertyAccessor());
            this.propertyAccessors = accessors;
        }
        return accessors;
    }

    private List<ConstructorResolver> initConstructorResolvers() {
        List<ConstructorResolver> resolvers = this.constructorResolvers;
        if (resolvers == null) {
            resolvers = new ArrayList<>(1);
            resolvers.add(new ReflectiveConstructorResolver());
            this.constructorResolvers = resolvers;
        }
        return resolvers;
    }

    private List<MethodResolver> initMethodResolvers() {
        List<MethodResolver> resolvers = this.methodResolvers;
        if (resolvers == null) {
            resolvers = new ArrayList<>(1);
            this.reflectiveMethodResolver = new ReflectiveMethodResolver();
            resolvers.add(this.reflectiveMethodResolver);
            this.methodResolvers = resolvers;
        }
        return resolvers;
    }

    private static <T> void addBeforeDefault(List<T> resolvers, T resolver) {
        resolvers.add(resolvers.size() - 1, resolver);
    }
}

17 Source : SimpleEvaluationContext.java
with MIT License
from Vip-Augus

/**
 * A basic implementation of {@link EvaluationContext} that focuses on a subset
 * of essential SpEL features and customization options, targeting simple
 * condition evaluation and in particular data binding scenarios.
 *
 * <p>In many cases, the full extent of the SpEL language is not required and
 * should be meaningfully restricted. Examples include but are not limited to
 * data binding expressions, property-based filters, and others. To that effect,
 * {@code SimpleEvaluationContext} is tailored to support only a subset of the
 * SpEL language syntax, e.g. excluding references to Java types, constructors,
 * and bean references.
 *
 * <p>When creating a {@code SimpleEvaluationContext} you need to choose the
 * level of support that you need for property access in SpEL expressions:
 * <ul>
 * <li>A custom {@code PropertyAccessor} (typically not reflection-based),
 * potentially combined with a {@link DataBindingPropertyAccessor}</li>
 * <li>Data binding properties for read-only access</li>
 * <li>Data binding properties for read and write</li>
 * </ul>
 *
 * <p>Conveniently, {@link SimpleEvaluationContext#forReadOnlyDataBinding()}
 * enables read access to properties via {@link DataBindingPropertyAccessor};
 * same for {@link SimpleEvaluationContext#forReadWriteDataBinding()} when
 * write access is needed as well. Alternatively, configure custom accessors
 * via {@link SimpleEvaluationContext#forPropertyAccessors}, and potentially
 * activate method resolution and/or a type converter through the builder.
 *
 * <p>Note that {@code SimpleEvaluationContext} is typically not configured
 * with a default root object. Instead it is meant to be created once and
 * used repeatedly through {@code getValue} calls on a pre-compiled
 * {@link org.springframework.expression.Expression} with both an
 * {@code EvaluationContext} and a root object as arguments:
 * {@link org.springframework.expression.Expression#getValue(EvaluationContext, Object)}.
 *
 * <p>For more power and flexibility, in particular for internal configuration
 * scenarios, consider using {@link StandardEvaluationContext} instead.
 *
 * @author Rossen Stoyanchev
 * @author Juergen Hoeller
 * @since 4.3.15
 * @see #forPropertyAccessors
 * @see #forReadOnlyDataBinding()
 * @see #forReadWriteDataBinding()
 * @see StandardEvaluationContext
 * @see StandardTypeConverter
 * @see DataBindingPropertyAccessor
 */
public final clreplaced SimpleEvaluationContext implements EvaluationContext {

    private static final TypeLocator typeNotFoundTypeLocator = typeName -> {
        throw new SpelEvaluationException(SpelMessage.TYPE_NOT_FOUND, typeName);
    };

    private final TypedValue rootObject;

    private final List<PropertyAccessor> propertyAccessors;

    private final List<MethodResolver> methodResolvers;

    private final TypeConverter typeConverter;

    private final TypeComparator typeComparator = new StandardTypeComparator();

    private final OperatorOverloader operatorOverloader = new StandardOperatorOverloader();

    private final Map<String, Object> variables = new HashMap<>();

    private SimpleEvaluationContext(List<PropertyAccessor> accessors, List<MethodResolver> resolvers, @Nullable TypeConverter converter, @Nullable TypedValue rootObject) {
        this.propertyAccessors = accessors;
        this.methodResolvers = resolvers;
        this.typeConverter = (converter != null ? converter : new StandardTypeConverter());
        this.rootObject = (rootObject != null ? rootObject : TypedValue.NULL);
    }

    /**
     * Return the specified root object, if any.
     */
    @Override
    public TypedValue getRootObject() {
        return this.rootObject;
    }

    /**
     * Return the specified {@link PropertyAccessor} delegates, if any.
     * @see #forPropertyAccessors
     */
    @Override
    public List<PropertyAccessor> getPropertyAccessors() {
        return this.propertyAccessors;
    }

    /**
     * Return an empty list, always, since this context does not support the
     * use of type references.
     */
    @Override
    public List<ConstructorResolver> getConstructorResolvers() {
        return Collections.emptyList();
    }

    /**
     * Return the specified {@link MethodResolver} delegates, if any.
     * @see Builder#withMethodResolvers
     */
    @Override
    public List<MethodResolver> getMethodResolvers() {
        return this.methodResolvers;
    }

    /**
     * {@code SimpleEvaluationContext} does not support the use of bean references.
     * @return always {@code null}
     */
    @Override
    @Nullable
    public BeanResolver getBeanResolver() {
        return null;
    }

    /**
     * {@code SimpleEvaluationContext} does not support use of type references.
     * @return {@code TypeLocator} implementation that raises a
     * {@link SpelEvaluationException} with {@link SpelMessage#TYPE_NOT_FOUND}.
     */
    @Override
    public TypeLocator getTypeLocator() {
        return typeNotFoundTypeLocator;
    }

    /**
     * The configured {@link TypeConverter}.
     * <p>By default this is {@link StandardTypeConverter}.
     * @see Builder#withTypeConverter
     * @see Builder#withConversionService
     */
    @Override
    public TypeConverter getTypeConverter() {
        return this.typeConverter;
    }

    /**
     * Return an instance of {@link StandardTypeComparator}.
     */
    @Override
    public TypeComparator getTypeComparator() {
        return this.typeComparator;
    }

    /**
     * Return an instance of {@link StandardOperatorOverloader}.
     */
    @Override
    public OperatorOverloader getOperatorOverloader() {
        return this.operatorOverloader;
    }

    @Override
    public void setVariable(String name, @Nullable Object value) {
        this.variables.put(name, value);
    }

    @Override
    @Nullable
    public Object lookupVariable(String name) {
        return this.variables.get(name);
    }

    /**
     * Create a {@code SimpleEvaluationContext} for the specified {@link PropertyAccessor}
     * delegates: typically a custom {@code PropertyAccessor} specific to a use case
     * (e.g. attribute resolution in a custom data structure), potentially combined with
     * a {@link DataBindingPropertyAccessor} if property dereferences are needed as well.
     * @param accessors the accessor delegates to use
     * @see DataBindingPropertyAccessor#forReadOnlyAccess()
     * @see DataBindingPropertyAccessor#forReadWriteAccess()
     */
    public static Builder forPropertyAccessors(PropertyAccessor... accessors) {
        for (PropertyAccessor accessor : accessors) {
            if (accessor.getClreplaced() == ReflectivePropertyAccessor.clreplaced) {
                throw new IllegalArgumentException("SimpleEvaluationContext is not designed for use with a plain " + "ReflectivePropertyAccessor. Consider using DataBindingPropertyAccessor or a custom subclreplaced.");
            }
        }
        return new Builder(accessors);
    }

    /**
     * Create a {@code SimpleEvaluationContext} for read-only access to
     * public properties via {@link DataBindingPropertyAccessor}.
     * @see DataBindingPropertyAccessor#forReadOnlyAccess()
     * @see #forPropertyAccessors
     */
    public static Builder forReadOnlyDataBinding() {
        return new Builder(DataBindingPropertyAccessor.forReadOnlyAccess());
    }

    /**
     * Create a {@code SimpleEvaluationContext} for read-write access to
     * public properties via {@link DataBindingPropertyAccessor}.
     * @see DataBindingPropertyAccessor#forReadWriteAccess()
     * @see #forPropertyAccessors
     */
    public static Builder forReadWriteDataBinding() {
        return new Builder(DataBindingPropertyAccessor.forReadWriteAccess());
    }

    /**
     * Builder for {@code SimpleEvaluationContext}.
     */
    public static clreplaced Builder {

        private final List<PropertyAccessor> accessors;

        private List<MethodResolver> resolvers = Collections.emptyList();

        @Nullable
        private TypeConverter typeConverter;

        @Nullable
        private TypedValue rootObject;

        public Builder(PropertyAccessor... accessors) {
            this.accessors = Arrays.asList(accessors);
        }

        /**
         * Register the specified {@link MethodResolver} delegates for
         * a combination of property access and method resolution.
         * @param resolvers the resolver delegates to use
         * @see #withInstanceMethods()
         * @see SimpleEvaluationContext#forPropertyAccessors
         */
        public Builder withMethodResolvers(MethodResolver... resolvers) {
            for (MethodResolver resolver : resolvers) {
                if (resolver.getClreplaced() == ReflectiveMethodResolver.clreplaced) {
                    throw new IllegalArgumentException("SimpleEvaluationContext is not designed for use with a plain " + "ReflectiveMethodResolver. Consider using DataBindingMethodResolver or a custom subclreplaced.");
                }
            }
            this.resolvers = Arrays.asList(resolvers);
            return this;
        }

        /**
         * Register a {@link DataBindingMethodResolver} for instance method invocation purposes
         * (i.e. not supporting static methods) in addition to the specified property accessors,
         * typically in combination with a {@link DataBindingPropertyAccessor}.
         * @see #withMethodResolvers
         * @see SimpleEvaluationContext#forReadOnlyDataBinding()
         * @see SimpleEvaluationContext#forReadWriteDataBinding()
         */
        public Builder withInstanceMethods() {
            this.resolvers = Collections.singletonList(DataBindingMethodResolver.forInstanceMethodInvocation());
            return this;
        }

        /**
         * Register a custom {@link ConversionService}.
         * <p>By default a {@link StandardTypeConverter} backed by a
         * {@link org.springframework.core.convert.support.DefaultConversionService} is used.
         * @see #withTypeConverter
         * @see StandardTypeConverter#StandardTypeConverter(ConversionService)
         */
        public Builder withConversionService(ConversionService conversionService) {
            this.typeConverter = new StandardTypeConverter(conversionService);
            return this;
        }

        /**
         * Register a custom {@link TypeConverter}.
         * <p>By default a {@link StandardTypeConverter} backed by a
         * {@link org.springframework.core.convert.support.DefaultConversionService} is used.
         * @see #withConversionService
         * @see StandardTypeConverter#StandardTypeConverter()
         */
        public Builder withTypeConverter(TypeConverter converter) {
            this.typeConverter = converter;
            return this;
        }

        /**
         * Specify a default root object to resolve against.
         * <p>Default is none, expecting an object argument at evaluation time.
         * @see org.springframework.expression.Expression#getValue(EvaluationContext)
         * @see org.springframework.expression.Expression#getValue(EvaluationContext, Object)
         */
        public Builder withRootObject(Object rootObject) {
            this.rootObject = new TypedValue(rootObject);
            return this;
        }

        /**
         * Specify a typed root object to resolve against.
         * <p>Default is none, expecting an object argument at evaluation time.
         * @see org.springframework.expression.Expression#getValue(EvaluationContext)
         * @see org.springframework.expression.Expression#getValue(EvaluationContext, Object)
         */
        public Builder withTypedRootObject(Object rootObject, TypeDescriptor typeDescriptor) {
            this.rootObject = new TypedValue(rootObject, typeDescriptor);
            return this;
        }

        public SimpleEvaluationContext build() {
            return new SimpleEvaluationContext(this.accessors, this.resolvers, this.typeConverter, this.rootObject);
        }
    }
}

17 Source : FunctionReference.java
with MIT License
from Vip-Augus

/**
 * Execute a function represented as a {@code java.lang.reflect.Method}.
 * @param state the expression evaluation state
 * @param method the method to invoke
 * @return the return value of the invoked Java method
 * @throws EvaluationException if there is any problem invoking the method
 */
private TypedValue executeFunctionJLRMethod(ExpressionState state, Method method) throws EvaluationException {
    Object[] functionArgs = getArguments(state);
    if (!method.isVarArgs()) {
        int declaredParamCount = method.getParameterCount();
        if (declaredParamCount != functionArgs.length) {
            throw new SpelEvaluationException(SpelMessage.INCORRECT_NUMBER_OF_ARGUMENTS_TO_FUNCTION, functionArgs.length, declaredParamCount);
        }
    }
    if (!Modifier.isStatic(method.getModifiers())) {
        throw new SpelEvaluationException(getStartPosition(), SpelMessage.FUNCTION_MUST_BE_STATIC, ClreplacedUtils.getQualifiedMethodName(method), this.name);
    }
    // Convert arguments if necessary and remap them for varargs if required
    TypeConverter converter = state.getEvaluationContext().getTypeConverter();
    boolean argumentConversionOccurred = ReflectionHelper.convertAllArguments(converter, functionArgs, method);
    if (method.isVarArgs()) {
        functionArgs = ReflectionHelper.setupArgumentsForVarargsInvocation(method.getParameterTypes(), functionArgs);
    }
    boolean compilable = false;
    try {
        ReflectionUtils.makeAccessible(method);
        Object result = method.invoke(method.getClreplaced(), functionArgs);
        compilable = !argumentConversionOccurred;
        return new TypedValue(result, new TypeDescriptor(new MethodParameter(method, -1)).narrow(result));
    } catch (Exception ex) {
        throw new SpelEvaluationException(getStartPosition(), ex, SpelMessage.EXCEPTION_DURING_FUNCTION_CALL, this.name, ex.getMessage());
    } finally {
        if (compilable) {
            this.exitTypeDescriptor = CodeFlow.toDescriptor(method.getReturnType());
            this.method = method;
        } else {
            this.exitTypeDescriptor = null;
            this.method = null;
        }
    }
}

17 Source : ConstructorReference.java
with MIT License
from Vip-Augus

/**
 * Create an array and return it.
 * @param state the expression state within which this expression is being evaluated
 * @return the new array
 * @throws EvaluationException if there is a problem creating the array
 */
private TypedValue createArray(ExpressionState state) throws EvaluationException {
    // First child gives us the array type which will either be a primitive or reference type
    Object intendedArrayType = getChild(0).getValue(state);
    if (!(intendedArrayType instanceof String)) {
        throw new SpelEvaluationException(getChild(0).getStartPosition(), SpelMessage.TYPE_NAME_EXPECTED_FOR_ARRAY_CONSTRUCTION, FormatHelper.formatClreplacedNameForMessage(intendedArrayType != null ? intendedArrayType.getClreplaced() : null));
    }
    String type = (String) intendedArrayType;
    Clreplaced<?> componentType;
    TypeCode arrayTypeCode = TypeCode.forName(type);
    if (arrayTypeCode == TypeCode.OBJECT) {
        componentType = state.findType(type);
    } else {
        componentType = arrayTypeCode.getType();
    }
    Object newArray;
    if (!hasInitializer()) {
        // Confirm all dimensions were specified (for example [3][][5] is missing the 2nd dimension)
        if (this.dimensions != null) {
            for (SpelNodeImpl dimension : this.dimensions) {
                if (dimension == null) {
                    throw new SpelEvaluationException(getStartPosition(), SpelMessage.MISSING_ARRAY_DIMENSION);
                }
            }
        }
        TypeConverter typeConverter = state.getEvaluationContext().getTypeConverter();
        // Shortcut for 1 dimensional
        if (this.dimensions.length == 1) {
            TypedValue o = this.dimensions[0].getTypedValue(state);
            int arraySize = ExpressionUtils.toInt(typeConverter, o);
            newArray = Array.newInstance(componentType, arraySize);
        } else {
            // Multi-dimensional - hold onto your hat!
            int[] dims = new int[this.dimensions.length];
            for (int d = 0; d < this.dimensions.length; d++) {
                TypedValue o = this.dimensions[d].getTypedValue(state);
                dims[d] = ExpressionUtils.toInt(typeConverter, o);
            }
            newArray = Array.newInstance(componentType, dims);
        }
    } else {
        // There is an initializer
        if (this.dimensions == null || this.dimensions.length > 1) {
            // There is an initializer but this is a multi-dimensional array (e.g. new int[][]{{1,2},{3,4}}) - this
            // is not currently supported
            throw new SpelEvaluationException(getStartPosition(), SpelMessage.MULTIDIM_ARRAY_INITIALIZER_NOT_SUPPORTED);
        }
        TypeConverter typeConverter = state.getEvaluationContext().getTypeConverter();
        InlineList initializer = (InlineList) getChild(1);
        // If a dimension was specified, check it matches the initializer length
        if (this.dimensions[0] != null) {
            TypedValue dValue = this.dimensions[0].getTypedValue(state);
            int i = ExpressionUtils.toInt(typeConverter, dValue);
            if (i != initializer.getChildCount()) {
                throw new SpelEvaluationException(getStartPosition(), SpelMessage.INITIALIZER_LENGTH_INCORRECT);
            }
        }
        // Build the array and populate it
        int arraySize = initializer.getChildCount();
        newArray = Array.newInstance(componentType, arraySize);
        if (arrayTypeCode == TypeCode.OBJECT) {
            populateReferenceTypeArray(state, newArray, typeConverter, initializer, componentType);
        } else if (arrayTypeCode == TypeCode.BOOLEAN) {
            populateBooleanArray(state, newArray, typeConverter, initializer);
        } else if (arrayTypeCode == TypeCode.BYTE) {
            populateByteArray(state, newArray, typeConverter, initializer);
        } else if (arrayTypeCode == TypeCode.CHAR) {
            populateCharArray(state, newArray, typeConverter, initializer);
        } else if (arrayTypeCode == TypeCode.DOUBLE) {
            populateDoubleArray(state, newArray, typeConverter, initializer);
        } else if (arrayTypeCode == TypeCode.FLOAT) {
            populateFloatArray(state, newArray, typeConverter, initializer);
        } else if (arrayTypeCode == TypeCode.INT) {
            populateIntArray(state, newArray, typeConverter, initializer);
        } else if (arrayTypeCode == TypeCode.LONG) {
            populateLongArray(state, newArray, typeConverter, initializer);
        } else if (arrayTypeCode == TypeCode.SHORT) {
            populateShortArray(state, newArray, typeConverter, initializer);
        } else {
            throw new IllegalStateException(arrayTypeCode.name());
        }
    }
    return new TypedValue(newArray);
}

17 Source : ConstructorReference.java
with MIT License
from Vip-Augus

private void populateReferenceTypeArray(ExpressionState state, Object newArray, TypeConverter typeConverter, InlineList initializer, Clreplaced<?> componentType) {
    TypeDescriptor toTypeDescriptor = TypeDescriptor.valueOf(componentType);
    Object[] newObjectArray = (Object[]) newArray;
    for (int i = 0; i < newObjectArray.length; i++) {
        SpelNode elementNode = initializer.getChild(i);
        Object arrayEntry = elementNode.getValue(state);
        newObjectArray[i] = typeConverter.convertValue(arrayEntry, TypeDescriptor.forObject(arrayEntry), toTypeDescriptor);
    }
}

17 Source : ExpressionUtils.java
with MIT License
from Vip-Augus

@SuppressWarnings("unchecked")
private static <T> T convertValue(TypeConverter typeConverter, TypedValue typedValue, Clreplaced<T> targetType) {
    Object result = typeConverter.convertValue(typedValue.getValue(), typedValue.getTypeDescriptor(), TypeDescriptor.valueOf(targetType));
    if (result == null) {
        throw new IllegalStateException("Null conversion result for value [" + typedValue.getValue() + "]");
    }
    return (T) result;
}

17 Source : StandardEvaluationContext.java
with Apache License 2.0
from SourceHot

/**
 * A powerful and highly configurable {@link EvaluationContext} implementation.
 * This context uses standard implementations of all applicable strategies,
 * based on reflection to resolve properties, methods and fields.
 *
 * <p>For a simpler builder-style context variant for data-binding purposes,
 * consider using {@link SimpleEvaluationContext} instead which allows for
 * opting into several SpEL features as needed by specific evaluation cases.
 *
 * @author Andy Clement
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @since 3.0
 * @see SimpleEvaluationContext
 * @see ReflectivePropertyAccessor
 * @see ReflectiveConstructorResolver
 * @see ReflectiveMethodResolver
 * @see StandardTypeLocator
 * @see StandardTypeConverter
 * @see StandardTypeComparator
 * @see StandardOperatorOverloader
 */
public clreplaced StandardEvaluationContext implements EvaluationContext {

    private TypedValue rootObject;

    @Nullable
    private volatile List<PropertyAccessor> propertyAccessors;

    @Nullable
    private volatile List<ConstructorResolver> constructorResolvers;

    @Nullable
    private volatile List<MethodResolver> methodResolvers;

    @Nullable
    private volatile ReflectiveMethodResolver reflectiveMethodResolver;

    @Nullable
    private BeanResolver beanResolver;

    @Nullable
    private TypeLocator typeLocator;

    @Nullable
    private TypeConverter typeConverter;

    private TypeComparator typeComparator = new StandardTypeComparator();

    private OperatorOverloader operatorOverloader = new StandardOperatorOverloader();

    private final Map<String, Object> variables = new ConcurrentHashMap<>();

    /**
     * Create a {@code StandardEvaluationContext} with a null root object.
     */
    public StandardEvaluationContext() {
        this.rootObject = TypedValue.NULL;
    }

    /**
     * Create a {@code StandardEvaluationContext} with the given root object.
     * @param rootObject the root object to use
     * @see #setRootObject
     */
    public StandardEvaluationContext(@Nullable Object rootObject) {
        this.rootObject = new TypedValue(rootObject);
    }

    public void setRootObject(@Nullable Object rootObject, TypeDescriptor typeDescriptor) {
        this.rootObject = new TypedValue(rootObject, typeDescriptor);
    }

    public void setRootObject(@Nullable Object rootObject) {
        this.rootObject = (rootObject != null ? new TypedValue(rootObject) : TypedValue.NULL);
    }

    @Override
    public TypedValue getRootObject() {
        return this.rootObject;
    }

    public void setPropertyAccessors(List<PropertyAccessor> propertyAccessors) {
        this.propertyAccessors = propertyAccessors;
    }

    @Override
    public List<PropertyAccessor> getPropertyAccessors() {
        return initPropertyAccessors();
    }

    public void addPropertyAccessor(PropertyAccessor accessor) {
        addBeforeDefault(initPropertyAccessors(), accessor);
    }

    public boolean removePropertyAccessor(PropertyAccessor accessor) {
        return initPropertyAccessors().remove(accessor);
    }

    public void setConstructorResolvers(List<ConstructorResolver> constructorResolvers) {
        this.constructorResolvers = constructorResolvers;
    }

    @Override
    public List<ConstructorResolver> getConstructorResolvers() {
        return initConstructorResolvers();
    }

    public void addConstructorResolver(ConstructorResolver resolver) {
        addBeforeDefault(initConstructorResolvers(), resolver);
    }

    public boolean removeConstructorResolver(ConstructorResolver resolver) {
        return initConstructorResolvers().remove(resolver);
    }

    public void setMethodResolvers(List<MethodResolver> methodResolvers) {
        this.methodResolvers = methodResolvers;
    }

    @Override
    public List<MethodResolver> getMethodResolvers() {
        return initMethodResolvers();
    }

    public void addMethodResolver(MethodResolver resolver) {
        addBeforeDefault(initMethodResolvers(), resolver);
    }

    public boolean removeMethodResolver(MethodResolver methodResolver) {
        return initMethodResolvers().remove(methodResolver);
    }

    public void setBeanResolver(BeanResolver beanResolver) {
        this.beanResolver = beanResolver;
    }

    @Override
    @Nullable
    public BeanResolver getBeanResolver() {
        return this.beanResolver;
    }

    public void setTypeLocator(TypeLocator typeLocator) {
        replacedert.notNull(typeLocator, "TypeLocator must not be null");
        this.typeLocator = typeLocator;
    }

    @Override
    public TypeLocator getTypeLocator() {
        if (this.typeLocator == null) {
            this.typeLocator = new StandardTypeLocator();
        }
        return this.typeLocator;
    }

    public void setTypeConverter(TypeConverter typeConverter) {
        replacedert.notNull(typeConverter, "TypeConverter must not be null");
        this.typeConverter = typeConverter;
    }

    @Override
    public TypeConverter getTypeConverter() {
        if (this.typeConverter == null) {
            this.typeConverter = new StandardTypeConverter();
        }
        return this.typeConverter;
    }

    public void setTypeComparator(TypeComparator typeComparator) {
        replacedert.notNull(typeComparator, "TypeComparator must not be null");
        this.typeComparator = typeComparator;
    }

    @Override
    public TypeComparator getTypeComparator() {
        return this.typeComparator;
    }

    public void setOperatorOverloader(OperatorOverloader operatorOverloader) {
        replacedert.notNull(operatorOverloader, "OperatorOverloader must not be null");
        this.operatorOverloader = operatorOverloader;
    }

    @Override
    public OperatorOverloader getOperatorOverloader() {
        return this.operatorOverloader;
    }

    @Override
    public void setVariable(@Nullable String name, @Nullable Object value) {
        // For backwards compatibility, we ignore null names here...
        // And since ConcurrentHashMap cannot store null values, we simply take null
        // as a remove from the Map (with the same result from lookupVariable below).
        if (name != null) {
            if (value != null) {
                this.variables.put(name, value);
            } else {
                this.variables.remove(name);
            }
        }
    }

    public void setVariables(Map<String, Object> variables) {
        variables.forEach(this::setVariable);
    }

    public void registerFunction(String name, Method method) {
        this.variables.put(name, method);
    }

    @Override
    @Nullable
    public Object lookupVariable(String name) {
        return this.variables.get(name);
    }

    /**
     * Register a {@code MethodFilter} which will be called during method resolution
     * for the specified type.
     * <p>The {@code MethodFilter} may remove methods and/or sort the methods which
     * will then be used by SpEL as the candidates to look through for a match.
     * @param type the type for which the filter should be called
     * @param filter a {@code MethodFilter}, or {@code null} to unregister a filter for the type
     * @throws IllegalStateException if the {@link ReflectiveMethodResolver} is not in use
     */
    public void registerMethodFilter(Clreplaced<?> type, MethodFilter filter) throws IllegalStateException {
        initMethodResolvers();
        ReflectiveMethodResolver resolver = this.reflectiveMethodResolver;
        if (resolver == null) {
            throw new IllegalStateException("Method filter cannot be set as the reflective method resolver is not in use");
        }
        resolver.registerMethodFilter(type, filter);
    }

    private List<PropertyAccessor> initPropertyAccessors() {
        List<PropertyAccessor> accessors = this.propertyAccessors;
        if (accessors == null) {
            accessors = new ArrayList<>(5);
            accessors.add(new ReflectivePropertyAccessor());
            this.propertyAccessors = accessors;
        }
        return accessors;
    }

    private List<ConstructorResolver> initConstructorResolvers() {
        List<ConstructorResolver> resolvers = this.constructorResolvers;
        if (resolvers == null) {
            resolvers = new ArrayList<>(1);
            resolvers.add(new ReflectiveConstructorResolver());
            this.constructorResolvers = resolvers;
        }
        return resolvers;
    }

    private List<MethodResolver> initMethodResolvers() {
        List<MethodResolver> resolvers = this.methodResolvers;
        if (resolvers == null) {
            resolvers = new ArrayList<>(1);
            this.reflectiveMethodResolver = new ReflectiveMethodResolver();
            resolvers.add(this.reflectiveMethodResolver);
            this.methodResolvers = resolvers;
        }
        return resolvers;
    }

    private static <T> void addBeforeDefault(List<T> resolvers, T resolver) {
        resolvers.add(resolvers.size() - 1, resolver);
    }
}

17 Source : ReflectiveConstructorResolver.java
with Apache License 2.0
from SourceHot

/**
 * Locate a constructor on the type. There are three kinds of match that might occur:
 * <ol>
 * <li>An exact match where the types of the arguments match the types of the constructor
 * <li>An in-exact match where the types we are looking for are subtypes of those defined on the constructor
 * <li>A match where we are able to convert the arguments into those expected by the constructor, according to the
 * registered type converter.
 * </ol>
 */
@Override
@Nullable
public ConstructorExecutor resolve(EvaluationContext context, String typeName, List<TypeDescriptor> argumentTypes) throws AccessException {
    try {
        TypeConverter typeConverter = context.getTypeConverter();
        Clreplaced<?> type = context.getTypeLocator().findType(typeName);
        Constructor<?>[] ctors = type.getConstructors();
        Arrays.sort(ctors, (c1, c2) -> {
            int c1pl = c1.getParameterCount();
            int c2pl = c2.getParameterCount();
            return Integer.compare(c1pl, c2pl);
        });
        Constructor<?> closeMatch = null;
        Constructor<?> matchRequiringConversion = null;
        for (Constructor<?> ctor : ctors) {
            int paramCount = ctor.getParameterCount();
            List<TypeDescriptor> paramDescriptors = new ArrayList<>(paramCount);
            for (int i = 0; i < paramCount; i++) {
                paramDescriptors.add(new TypeDescriptor(new MethodParameter(ctor, i)));
            }
            ReflectionHelper.ArgumentsMatchInfo matchInfo = null;
            if (ctor.isVarArgs() && argumentTypes.size() >= paramCount - 1) {
                // *sigh* complicated
                // Basically.. we have to have all parameters match up until the varargs one, then the rest of what is
                // being provided should be
                // the same type whilst the final argument to the method must be an array of that (oh, how easy...not) -
                // or the final parameter
                // we are supplied does match exactly (it is an array already).
                matchInfo = ReflectionHelper.compareArgumentsVarargs(paramDescriptors, argumentTypes, typeConverter);
            } else if (paramCount == argumentTypes.size()) {
                // worth a closer look
                matchInfo = ReflectionHelper.compareArguments(paramDescriptors, argumentTypes, typeConverter);
            }
            if (matchInfo != null) {
                if (matchInfo.isExactMatch()) {
                    return new ReflectiveConstructorExecutor(ctor);
                } else if (matchInfo.isCloseMatch()) {
                    closeMatch = ctor;
                } else if (matchInfo.isMatchRequiringConversion()) {
                    matchRequiringConversion = ctor;
                }
            }
        }
        if (closeMatch != null) {
            return new ReflectiveConstructorExecutor(closeMatch);
        } else if (matchRequiringConversion != null) {
            return new ReflectiveConstructorExecutor(matchRequiringConversion);
        } else {
            return null;
        }
    } catch (EvaluationException ex) {
        throw new AccessException("Failed to resolve constructor", ex);
    }
}

17 Source : StandardEvaluationContext.java
with Apache License 2.0
from langtianya

/**
 * Provides a default EvaluationContext implementation.
 *
 * <p>To resolve properties/methods/fields this context uses a reflection mechanism.
 *
 * @author Andy Clement
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @since 3.0
 */
public clreplaced StandardEvaluationContext implements EvaluationContext {

    private TypedValue rootObject;

    private List<ConstructorResolver> constructorResolvers;

    private List<MethodResolver> methodResolvers;

    private BeanResolver beanResolver;

    private ReflectiveMethodResolver reflectiveMethodResolver;

    private List<PropertyAccessor> propertyAccessors;

    private TypeLocator typeLocator;

    private TypeConverter typeConverter;

    private TypeComparator typeComparator = new StandardTypeComparator();

    private OperatorOverloader operatorOverloader = new StandardOperatorOverloader();

    private final Map<String, Object> variables = new HashMap<String, Object>();

    public StandardEvaluationContext() {
        setRootObject(null);
    }

    public StandardEvaluationContext(Object rootObject) {
        setRootObject(rootObject);
    }

    public void setRootObject(Object rootObject, TypeDescriptor typeDescriptor) {
        this.rootObject = new TypedValue(rootObject, typeDescriptor);
    }

    public void setRootObject(Object rootObject) {
        this.rootObject = (rootObject != null ? new TypedValue(rootObject) : TypedValue.NULL);
    }

    @Override
    public TypedValue getRootObject() {
        return this.rootObject;
    }

    public void addConstructorResolver(ConstructorResolver resolver) {
        ensureConstructorResolversInitialized();
        this.constructorResolvers.add(this.constructorResolvers.size() - 1, resolver);
    }

    public boolean removeConstructorResolver(ConstructorResolver resolver) {
        ensureConstructorResolversInitialized();
        return this.constructorResolvers.remove(resolver);
    }

    public void setConstructorResolvers(List<ConstructorResolver> constructorResolvers) {
        this.constructorResolvers = constructorResolvers;
    }

    @Override
    public List<ConstructorResolver> getConstructorResolvers() {
        ensureConstructorResolversInitialized();
        return this.constructorResolvers;
    }

    public void addMethodResolver(MethodResolver resolver) {
        ensureMethodResolversInitialized();
        this.methodResolvers.add(this.methodResolvers.size() - 1, resolver);
    }

    public boolean removeMethodResolver(MethodResolver methodResolver) {
        ensureMethodResolversInitialized();
        return this.methodResolvers.remove(methodResolver);
    }

    public void setMethodResolvers(List<MethodResolver> methodResolvers) {
        this.methodResolvers = methodResolvers;
    }

    @Override
    public List<MethodResolver> getMethodResolvers() {
        ensureMethodResolversInitialized();
        return this.methodResolvers;
    }

    public void setBeanResolver(BeanResolver beanResolver) {
        this.beanResolver = beanResolver;
    }

    @Override
    public BeanResolver getBeanResolver() {
        return this.beanResolver;
    }

    public void addPropertyAccessor(PropertyAccessor accessor) {
        ensurePropertyAccessorsInitialized();
        this.propertyAccessors.add(this.propertyAccessors.size() - 1, accessor);
    }

    public boolean removePropertyAccessor(PropertyAccessor accessor) {
        return this.propertyAccessors.remove(accessor);
    }

    public void setPropertyAccessors(List<PropertyAccessor> propertyAccessors) {
        this.propertyAccessors = propertyAccessors;
    }

    @Override
    public List<PropertyAccessor> getPropertyAccessors() {
        ensurePropertyAccessorsInitialized();
        return this.propertyAccessors;
    }

    public void setTypeLocator(TypeLocator typeLocator) {
        replacedert.notNull(typeLocator, "TypeLocator must not be null");
        this.typeLocator = typeLocator;
    }

    @Override
    public TypeLocator getTypeLocator() {
        if (this.typeLocator == null) {
            this.typeLocator = new StandardTypeLocator();
        }
        return this.typeLocator;
    }

    public void setTypeConverter(TypeConverter typeConverter) {
        replacedert.notNull(typeConverter, "TypeConverter must not be null");
        this.typeConverter = typeConverter;
    }

    @Override
    public TypeConverter getTypeConverter() {
        if (this.typeConverter == null) {
            this.typeConverter = new StandardTypeConverter();
        }
        return this.typeConverter;
    }

    public void setTypeComparator(TypeComparator typeComparator) {
        replacedert.notNull(typeComparator, "TypeComparator must not be null");
        this.typeComparator = typeComparator;
    }

    @Override
    public TypeComparator getTypeComparator() {
        return this.typeComparator;
    }

    public void setOperatorOverloader(OperatorOverloader operatorOverloader) {
        replacedert.notNull(operatorOverloader, "OperatorOverloader must not be null");
        this.operatorOverloader = operatorOverloader;
    }

    @Override
    public OperatorOverloader getOperatorOverloader() {
        return this.operatorOverloader;
    }

    @Override
    public void setVariable(String name, Object value) {
        this.variables.put(name, value);
    }

    public void setVariables(Map<String, Object> variables) {
        this.variables.putAll(variables);
    }

    public void registerFunction(String name, Method method) {
        this.variables.put(name, method);
    }

    @Override
    public Object lookupVariable(String name) {
        return this.variables.get(name);
    }

    /**
     * Register a {@code MethodFilter} which will be called during method resolution
     * for the specified type.
     * <p>The {@code MethodFilter} may remove methods and/or sort the methods which
     * will then be used by SpEL as the candidates to look through for a match.
     * @param type the type for which the filter should be called
     * @param filter a {@code MethodFilter}, or {@code null} to unregister a filter for the type
     * @throws IllegalStateException if the {@link ReflectiveMethodResolver} is not in use
     */
    public void registerMethodFilter(Clreplaced<?> type, MethodFilter filter) throws IllegalStateException {
        ensureMethodResolversInitialized();
        if (this.reflectiveMethodResolver != null) {
            this.reflectiveMethodResolver.registerMethodFilter(type, filter);
        } else {
            throw new IllegalStateException("Method filter cannot be set as the reflective method resolver is not in use");
        }
    }

    private void ensurePropertyAccessorsInitialized() {
        if (this.propertyAccessors == null) {
            initializePropertyAccessors();
        }
    }

    private synchronized void initializePropertyAccessors() {
        if (this.propertyAccessors == null) {
            List<PropertyAccessor> defaultAccessors = new ArrayList<PropertyAccessor>();
            defaultAccessors.add(new ReflectivePropertyAccessor());
            this.propertyAccessors = defaultAccessors;
        }
    }

    private void ensureMethodResolversInitialized() {
        if (this.methodResolvers == null) {
            initializeMethodResolvers();
        }
    }

    private synchronized void initializeMethodResolvers() {
        if (this.methodResolvers == null) {
            List<MethodResolver> defaultResolvers = new ArrayList<MethodResolver>();
            this.reflectiveMethodResolver = new ReflectiveMethodResolver();
            defaultResolvers.add(this.reflectiveMethodResolver);
            this.methodResolvers = defaultResolvers;
        }
    }

    private void ensureConstructorResolversInitialized() {
        if (this.constructorResolvers == null) {
            initializeConstructorResolvers();
        }
    }

    private synchronized void initializeConstructorResolvers() {
        if (this.constructorResolvers == null) {
            List<ConstructorResolver> defaultResolvers = new ArrayList<ConstructorResolver>();
            defaultResolvers.add(new ReflectiveConstructorResolver());
            this.constructorResolvers = defaultResolvers;
        }
    }
}

17 Source : ReflectiveMethodResolver.java
with Apache License 2.0
from langtianya

/**
 * Locate a method on a type. There are three kinds of match that might occur:
 * <ol>
 * <li>an exact match where the types of the arguments match the types of the constructor
 * <li>an in-exact match where the types we are looking for are subtypes of those defined on the constructor
 * <li>a match where we are able to convert the arguments into those expected by the constructor,
 * according to the registered type converter
 * </ol>
 */
@Override
public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name, List<TypeDescriptor> argumentTypes) throws AccessException {
    try {
        TypeConverter typeConverter = context.getTypeConverter();
        Clreplaced<?> type = (targetObject instanceof Clreplaced ? (Clreplaced<?>) targetObject : targetObject.getClreplaced());
        List<Method> methods = new ArrayList<Method>(getMethods(type, targetObject));
        // If a filter is registered for this type, call it
        MethodFilter filter = (this.filters != null ? this.filters.get(type) : null);
        if (filter != null) {
            List<Method> filtered = filter.filter(methods);
            methods = (filtered instanceof ArrayList ? filtered : new ArrayList<Method>(filtered));
        }
        // Sort methods into a sensible order
        if (methods.size() > 1) {
            Collections.sort(methods, new Comparator<Method>() {

                @Override
                public int compare(Method m1, Method m2) {
                    int m1pl = m1.getParameterTypes().length;
                    int m2pl = m2.getParameterTypes().length;
                    // varargs methods go last
                    if (m1pl == m2pl) {
                        if (!m1.isVarArgs() && m2.isVarArgs()) {
                            return -1;
                        } else if (m1.isVarArgs() && !m2.isVarArgs()) {
                            return 1;
                        } else {
                            return 0;
                        }
                    }
                    return (m1pl < m2pl ? -1 : (m1pl > m2pl ? 1 : 0));
                }
            });
        }
        // Resolve any bridge methods
        for (int i = 0; i < methods.size(); i++) {
            methods.set(i, BridgeMethodResolver.findBridgedMethod(methods.get(i)));
        }
        // Remove duplicate methods (possible due to resolved bridge methods)
        Set<Method> methodsToIterate = new LinkedHashSet<Method>(methods);
        Method closeMatch = null;
        int closeMatchDistance = Integer.MAX_VALUE;
        Method matchRequiringConversion = null;
        boolean multipleOptions = false;
        for (Method method : methodsToIterate) {
            if (method.getName().equals(name)) {
                Clreplaced<?>[] paramTypes = method.getParameterTypes();
                List<TypeDescriptor> paramDescriptors = new ArrayList<TypeDescriptor>(paramTypes.length);
                for (int i = 0; i < paramTypes.length; i++) {
                    paramDescriptors.add(new TypeDescriptor(new MethodParameter(method, i)));
                }
                ReflectionHelper.ArgumentsMatchInfo matchInfo = null;
                if (method.isVarArgs() && argumentTypes.size() >= (paramTypes.length - 1)) {
                    // *sigh* complicated
                    matchInfo = ReflectionHelper.compareArgumentsVarargs(paramDescriptors, argumentTypes, typeConverter);
                } else if (paramTypes.length == argumentTypes.size()) {
                    // Name and parameter number match, check the arguments
                    matchInfo = ReflectionHelper.compareArguments(paramDescriptors, argumentTypes, typeConverter);
                }
                if (matchInfo != null) {
                    if (matchInfo.isExactMatch()) {
                        return new ReflectiveMethodExecutor(method);
                    } else if (matchInfo.isCloseMatch()) {
                        if (this.useDistance) {
                            int matchDistance = ReflectionHelper.getTypeDifferenceWeight(paramDescriptors, argumentTypes);
                            if (closeMatch == null || matchDistance < closeMatchDistance) {
                                // This is a better match...
                                closeMatch = method;
                                closeMatchDistance = matchDistance;
                            }
                        } else {
                            // Take this as a close match if there isn't one already
                            if (closeMatch == null) {
                                closeMatch = method;
                            }
                        }
                    } else if (matchInfo.isMatchRequiringConversion()) {
                        if (matchRequiringConversion != null) {
                            multipleOptions = true;
                        }
                        matchRequiringConversion = method;
                    }
                }
            }
        }
        if (closeMatch != null) {
            return new ReflectiveMethodExecutor(closeMatch);
        } else if (matchRequiringConversion != null) {
            if (multipleOptions) {
                throw new SpelEvaluationException(SpelMessage.MULTIPLE_POSSIBLE_METHODS, name);
            }
            return new ReflectiveMethodExecutor(matchRequiringConversion);
        } else {
            return null;
        }
    } catch (EvaluationException ex) {
        throw new AccessException("Failed to resolve method", ex);
    }
}

See More Examples