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
19
Source : StandardComponentsTests.java
with MIT License
from Vip-Augus
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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