@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
/ *
* Copyright 2002 - 2020 the original author or authors .
* Copyright 2002 - 2024 the original author or authors .
*
* Licensed under the Apache License , Version 2 . 0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
@ -21,9 +21,10 @@ import java.util.List;
@@ -21,9 +21,10 @@ import java.util.List;
import org.springframework.expression.PropertyAccessor ;
import org.springframework.lang.Nullable ;
import org.springframework.util.ObjectUtils ;
/ * *
* Utilities methods for use in the Ast classes .
* Utility methods for use in the AST classes .
*
* @author Andy Clement
* @since 3 . 0 . 2
@ -31,45 +32,48 @@ import org.springframework.lang.Nullable;
@@ -31,45 +32,48 @@ import org.springframework.lang.Nullable;
public abstract class AstUtils {
/ * *
* Determines the set of property resolvers that should be used to try and access a
* property on the specified target type . The resolvers are considered to be in an
* ordered list , however in the returned list any that are exact matches for the input
* target type ( as opposed to ' general ' resolvers that could work for any type ) are
* placed at the start of the list . In addition , there are specific resolvers that
* exactly name the class in question and resolvers that name a specific class but it
* is a supertype of the class we have . These are put at the end of the specific resolvers
* set and will be tried after exactly matching accessors but before generic accessors .
* Determine the set of property accessors that should be used to try to
* access a property on the specified target type .
* < p > The accessors are considered to be in an ordered list ; however , in the
* returned list any accessors that are exact matches for the input target
* type ( as opposed to ' general ' accessors that could work for any type ) are
* placed at the start of the list . In addition , if there are specific
* accessors that exactly name the class in question and accessors that name
* a specific class which is a supertype of the class in question , the latter
* are put at the end of the specific accessors set and will be tried after
* exactly matching accessors but before generic accessors .
* @param targetType the type upon which property access is being attempted
* @return a list of resolvers that should be tried in order to access the property
* @param propertyAccessors the list of property accessors to process
* @return a list of accessors that should be tried in order to access the property
* /
public static List < PropertyAccessor > getPropertyAccessorsToTry (
@Nullable Class < ? > targetType , List < PropertyAccessor > propertyAccessors ) {
List < PropertyAccessor > specificAccessors = new ArrayList < > ( ) ;
List < PropertyAccessor > generalAccessors = new ArrayList < > ( ) ;
for ( PropertyAccessor resolver : propertyAccessors ) {
Class < ? > [ ] targets = resolver . getSpecificTargetClasses ( ) ;
if ( targets = = null ) { // generic resolver that says it can be used for any type
generalAccessors . add ( resolver ) ;
for ( PropertyAccessor accessor : propertyAccessors ) {
Class < ? > [ ] targets = accessor . getSpecificTargetClasses ( ) ;
if ( ObjectUtils . isEmpty ( targets ) ) {
// generic accessor that says it can be used for any type
generalAccessors . add ( accessor ) ;
}
else {
if ( targetType ! = null ) {
for ( Class < ? > clazz : targets ) {
if ( clazz = = targetType ) { // put exact matches on the front to be tried first?
specificAccessors . add ( resolver ) ;
}
else if ( clazz . isAssignableFrom ( targetType ) ) { // put supertype matches at the end of the
// specificAccessor list
generalAccessors . add ( resolver ) ;
}
else if ( targetType ! = null ) {
for ( Class < ? > clazz : targets ) {
if ( clazz = = targetType ) {
// add exact matches to the specificAccessors list
specificAccessors . add ( accessor ) ;
}
else if ( clazz . isAssignableFrom ( targetType ) ) {
// add supertype matches to the front of the generalAccessors list
generalAccessors . add ( 0 , accessor ) ;
}
}
}
}
List < PropertyAccessor > resolve rs = new ArrayList < > ( specificAccessors . size ( ) + generalAccessors . size ( ) ) ;
resolve rs. addAll ( specificAccessors ) ;
resolve rs. addAll ( generalAccessors ) ;
return resolve rs;
List < PropertyAccessor > accesso rs = new ArrayList < > ( specificAccessors . size ( ) + generalAccessors . size ( ) ) ;
accesso rs. addAll ( specificAccessors ) ;
accesso rs. addAll ( generalAccessors ) ;
return accesso rs;
}
}