squash some warnings in ReflectHelper + cleanups

This commit is contained in:
Gavin King 2024-10-08 09:06:05 +02:00
parent 9166d73f36
commit 2e2d2948b0
1 changed files with 140 additions and 166 deletions

View File

@ -4,7 +4,6 @@
*/
package org.hibernate.internal.util;
import java.beans.Introspector;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
@ -29,6 +28,9 @@ import org.hibernate.property.access.spi.Getter;
import jakarta.persistence.Transient;
import static java.beans.Introspector.decapitalize;
import static java.lang.Thread.currentThread;
/**
* Utility class for various reflection operations.
*
@ -120,12 +122,12 @@ public final class ReflectHelper {
if ( clazz.isRecord() || clazz.isEnum() ) {
return true;
}
Method equals;
final Method equals;
try {
equals = extractEqualsMethod( clazz );
}
catch ( NoSuchMethodException nsme ) {
return false; //its an interface so we can't really tell anything...
return false; //it's an interface so we can't really tell anything
}
return !OBJECT_EQUALS.equals( equals );
}
@ -140,12 +142,12 @@ public final class ReflectHelper {
if ( clazz.isRecord() || clazz.isEnum() ) {
return true;
}
Method hashCode;
final Method hashCode;
try {
hashCode = extractHashCodeMethod( clazz );
}
catch ( NoSuchMethodException nsme ) {
return false; //its an interface so we can't really tell anything...
return false; //it's an interface so we can't really tell anything
}
return !OBJECT_HASHCODE.equals( hashCode );
}
@ -156,7 +158,10 @@ public final class ReflectHelper {
* @param clazz The class to check
* @param intf The interface to check it against.
* @return True if the class does implement the interface, false otherwise.
*
* @deprecated No longer used
*/
@Deprecated(since = "7", forRemoval = true)
public static boolean implementsInterface(Class<?> clazz, Class<?> intf) {
assert intf.isInterface() : "Interface to check was not an interface";
return intf.isAssignableFrom( clazz );
@ -175,7 +180,7 @@ public final class ReflectHelper {
*/
public static Class<?> classForName(String name, Class<?> caller) throws ClassNotFoundException {
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
final ClassLoader classLoader = currentThread().getContextClassLoader();
if ( classLoader != null ) {
return classLoader.loadClass( name );
}
@ -202,7 +207,7 @@ public final class ReflectHelper {
@Deprecated
public static Class<?> classForName(String name) throws ClassNotFoundException {
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
final ClassLoader classLoader = currentThread().getContextClassLoader();
if ( classLoader != null ) {
return classLoader.loadClass(name);
}
@ -220,7 +225,8 @@ public final class ReflectHelper {
* @return True if the member is publicly accessible, false otherwise.
*/
public static boolean isPublic(Class<?> clazz, Member member) {
return Modifier.isPublic( member.getModifiers() ) && Modifier.isPublic( clazz.getModifiers() );
return Modifier.isPublic( member.getModifiers() )
&& Modifier.isPublic( clazz.getModifiers() );
}
/**
@ -239,7 +245,7 @@ public final class ReflectHelper {
String name,
ClassLoaderService classLoaderService) throws MappingException {
try {
Class<?> clazz = classLoaderService.classForName( className );
final Class<?> clazz = classLoaderService.classForName( className );
return getter( clazz, name ).getReturnTypeClass();
}
catch ( ClassLoadingException e ) {
@ -252,7 +258,7 @@ public final class ReflectHelper {
String name,
ClassLoaderService classLoaderService) throws MappingException {
try {
Class<?> clazz = classLoaderService.classForName( className );
final Class<?> clazz = classLoaderService.classForName( className );
return getter( clazz, name ).getReturnType();
}
catch ( ClassLoadingException e ) {
@ -289,7 +295,7 @@ public final class ReflectHelper {
}
try {
Constructor<T> constructor = clazz.getDeclaredConstructor( NO_PARAM_SIGNATURE );
final Constructor<T> constructor = clazz.getDeclaredConstructor( NO_PARAM_SIGNATURE );
ensureAccessibility( constructor );
return constructor;
}
@ -336,7 +342,7 @@ public final class ReflectHelper {
* @return True if the class is abstract, false otherwise.
*/
public static boolean isAbstractClass(Class<?> clazz) {
int modifier = clazz.getModifiers();
final int modifier = clazz.getModifiers();
return Modifier.isAbstract(modifier) || Modifier.isInterface(modifier);
}
@ -403,23 +409,21 @@ public final class ReflectHelper {
else if ( containerClass == Object.class ) {
throw new IllegalArgumentException( "Illegal attempt to locate field [" + propertyName + "] on Object.class" );
}
Field field = locateField( containerClass, propertyName );
if ( field == null ) {
throw new PropertyNotFoundException(
String.format(
Locale.ROOT,
"Could not locate field name [%s] on class [%s]",
propertyName,
containerClass.getName()
)
);
else {
final Field field = locateField( containerClass, propertyName );
if ( field == null ) {
throw new PropertyNotFoundException(
String.format(
Locale.ROOT,
"Could not locate field name [%s] on class [%s]",
propertyName,
containerClass.getName()
)
);
}
ensureAccessibility( field );
return field;
}
ensureAccessibility( field );
return field;
}
public static void ensureAccessibility(AccessibleObject accessibleObject) {
@ -434,11 +438,10 @@ public final class ReflectHelper {
}
try {
Field field = clazz.getDeclaredField( propertyName );
if ( !isStaticField( field ) ) {
return field;
}
return locateField( clazz.getSuperclass(), propertyName );
final Field field = clazz.getDeclaredField( propertyName );
return !isStaticField( field )
? field
: locateField( clazz.getSuperclass(), propertyName );
}
catch ( NoSuchFieldException nsfe ) {
return locateField( clazz.getSuperclass(), propertyName );
@ -467,18 +470,16 @@ public final class ReflectHelper {
if ( checkClass.equals( Object.class ) ) {
break;
}
getter = getGetterOrNull( checkClass, propertyName );
// if no getter found yet, check all implemented interfaces
if ( getter == null ) {
getter = getGetterOrNull( checkClass.getInterfaces(), propertyName );
else {
getter = getGetterOrNull( checkClass, propertyName );
// if no getter found yet, check all implemented interfaces
if ( getter == null ) {
getter = getGetterOrNull( checkClass.getInterfaces(), propertyName );
}
checkClass = checkClass.getSuperclass();
}
checkClass = checkClass.getSuperclass();
}
if ( getter == null ) {
throw new PropertyNotFoundException(
String.format(
@ -499,13 +500,12 @@ public final class ReflectHelper {
Method getter = null;
for ( int i = 0; getter == null && i < interfaces.length; ++i ) {
final Class<?> anInterface = interfaces[i];
if ( shouldSkipInterfaceCheck( anInterface ) ) {
continue;
}
getter = getGetterOrNull( anInterface, propertyName );
if ( getter == null ) {
// if no getter found yet, check all implemented interfaces of interface
getter = getGetterOrNull( anInterface.getInterfaces(), propertyName );
if ( !shouldSkipInterfaceCheck( anInterface ) ) {
getter = getGetterOrNull( anInterface, propertyName );
if ( getter == null ) {
// if no getter found yet, check all implemented interfaces of interface
getter = getGetterOrNull( anInterface.getInterfaces(), propertyName );
}
}
}
return getter;
@ -532,46 +532,34 @@ public final class ReflectHelper {
}
for ( Method method : containerClass.getDeclaredMethods() ) {
// if the method has parameters, skip it
if ( method.getParameterCount() != 0 ) {
continue;
}
if ( method.getParameterCount() == 0 // if the method has parameters, skip it
&& !Modifier.isStatic( method.getModifiers() )
&& !method.isBridge()
&& method.getAnnotation( Transient.class ) == null ) {
// if the method is a "bridge", skip it
if ( method.isBridge() ) {
continue;
}
final String methodName = method.getName();
if ( method.getAnnotation( Transient.class ) != null ) {
continue;
}
// try "get"
if ( methodName.startsWith( "get" ) ) {
final String stemName = methodName.substring( 3 );
if ( stemName.equals( propertyName )
|| decapitalize( stemName ).equals( propertyName ) ) {
verifyNoIsVariantExists( containerClass, propertyName, method, stemName );
return method;
}
if ( Modifier.isStatic( method.getModifiers() ) ) {
continue;
}
final String methodName = method.getName();
// try "get"
if ( methodName.startsWith( "get" ) ) {
final String stemName = methodName.substring( 3 );
final String decapitalizedStemName = Introspector.decapitalize( stemName );
if ( stemName.equals( propertyName ) || decapitalizedStemName.equals( propertyName ) ) {
verifyNoIsVariantExists( containerClass, propertyName, method, stemName );
return method;
}
}
// if not "get", then try "is"
if ( methodName.startsWith( "is" ) ) {
final String stemName = methodName.substring( 2 );
String decapitalizedStemName = Introspector.decapitalize( stemName );
if ( stemName.equals( propertyName ) || decapitalizedStemName.equals( propertyName ) ) {
// not sure that this can ever really happen given the handling of "get" above.
// but be safe
verifyNoGetVariantExists( containerClass, propertyName, method, stemName );
return method;
// if not "get", then try "is"
if ( methodName.startsWith( "is" ) ) {
final String stemName = methodName.substring( 2 );
if ( stemName.equals( propertyName )
|| decapitalize( stemName ).equals( propertyName ) ) {
// not sure that this can ever really happen given the handling of "get" above.
// but be safe
verifyNoGetVariantExists( containerClass, propertyName, method, stemName );
return method;
}
}
}
}
@ -629,7 +617,8 @@ public final class ReflectHelper {
final Method getMethod = containerClass.getDeclaredMethod( "get" + stemName );
// No such method should throw the caught exception. So if we get here, there was
// such a method.
if ( !Modifier.isStatic( getMethod.getModifiers() ) && getMethod.getAnnotation( Transient.class ) == null ) {
if ( !Modifier.isStatic( getMethod.getModifiers() )
&& getMethod.getAnnotation( Transient.class ) == null ) {
checkGetAndIsVariants( containerClass, propertyName, getMethod, isMethod );
}
}
@ -672,18 +661,17 @@ public final class ReflectHelper {
if ( checkClass.equals( Object.class ) ) {
break;
}
setter = setterOrNull( checkClass, propertyName, propertyType, likelyMethodName );
// if no setter found yet, check all implemented interfaces
if ( setter == null ) {
setter = setterOrNull( checkClass.getInterfaces(), propertyName, propertyType, likelyMethodName );
}
else {
ensureAccessibility( setter );
setter = setterOrNull( checkClass, propertyName, propertyType, likelyMethodName );
// if no setter found yet, check all implemented interfaces
if ( setter == null ) {
setter = setterOrNull( checkClass.getInterfaces(), propertyName, propertyType, likelyMethodName );
}
else {
ensureAccessibility( setter );
}
checkClass = checkClass.getSuperclass();
}
checkClass = checkClass.getSuperclass();
}
return setter; // might be null
}
@ -697,18 +685,17 @@ public final class ReflectHelper {
if ( checkClass.equals( Object.class ) ) {
break;
}
setter = setterOrNullBySetterName( checkClass, setterName, propertyType );
// if no setter found yet, check all implemented interfaces
if ( setter == null ) {
setter = setterOrNullBySetterName( checkClass.getInterfaces(), setterName, propertyType );
}
else {
ensureAccessibility( setter );
setter = setterOrNullBySetterName( checkClass, setterName, propertyType );
// if no setter found yet, check all implemented interfaces
if ( setter == null ) {
setter = setterOrNullBySetterName( checkClass.getInterfaces(), setterName, propertyType );
}
else {
ensureAccessibility( setter );
}
checkClass = checkClass.getSuperclass();
}
checkClass = checkClass.getSuperclass();
}
return setter; // might be null
}
@ -717,22 +704,21 @@ public final class ReflectHelper {
Method setter = null;
for ( int i = 0; setter == null && i < interfaces.length; ++i ) {
final Class<?> anInterface = interfaces[i];
if ( shouldSkipInterfaceCheck( anInterface ) ) {
continue;
}
setter = setterOrNullBySetterName( anInterface, setterName, propertyType );
if ( setter == null ) {
// if no setter found yet, check all implemented interfaces of interface
setter = setterOrNullBySetterName( anInterface.getInterfaces(), setterName, propertyType );
if ( !shouldSkipInterfaceCheck( anInterface ) ) {
setter = setterOrNullBySetterName( anInterface, setterName, propertyType );
if ( setter == null ) {
// if no setter found yet, check all implemented interfaces of interface
setter = setterOrNullBySetterName( anInterface.getInterfaces(), setterName, propertyType );
}
}
}
return setter;
}
private static boolean shouldSkipInterfaceCheck(final Class anInterface) {
private static boolean shouldSkipInterfaceCheck(final Class<?> anInterface) {
final String interfaceName = anInterface.getName();
//Skip checking any interface that we've added ourself via bytecode enhancement:
//there's many of those and it's pointless to look there.
//Skip checking any interface that we've added via bytecode enhancement:
//there's many of those, and it's pointless to look there.
if ( interfaceName.startsWith( "org.hibernate.engine." ) ) {
return true;
}
@ -779,19 +765,18 @@ public final class ReflectHelper {
Method setter = null;
for ( int i = 0; setter == null && i < interfaces.length; ++i ) {
final Class<?> anInterface = interfaces[i];
if ( shouldSkipInterfaceCheck( anInterface ) ) {
continue;
}
setter = setterOrNull( anInterface, propertyName, propertyType, likelyMethodName );
if ( setter == null ) {
// if no setter found yet, check all implemented interfaces of interface
setter = setterOrNull( anInterface.getInterfaces(), propertyName, propertyType, likelyMethodName );
if ( !shouldSkipInterfaceCheck( anInterface ) ) {
setter = setterOrNull( anInterface, propertyName, propertyType, likelyMethodName );
if ( setter == null ) {
// if no setter found yet, check all implemented interfaces of interface
setter = setterOrNull( anInterface.getInterfaces(), propertyName, propertyType, likelyMethodName );
}
}
}
return setter;
}
private static Method setterOrNull(Class<?> theClass, String propertyName, Class propertyType, String likelyMethodName) {
private static Method setterOrNull(Class<?> theClass, String propertyName, Class<?> propertyType, String likelyMethodName) {
try {
return theClass.getDeclaredMethod( likelyMethodName, propertyType );
}
@ -803,7 +788,7 @@ public final class ReflectHelper {
final String methodName = method.getName();
if ( method.getParameterCount() == 1 && methodName.startsWith( "set" ) ) {
final String testOldMethod = methodName.substring( 3 );
final String testStdMethod = Introspector.decapitalize( testOldMethod );
final String testStdMethod = decapitalize( testOldMethod );
if ( testStdMethod.equals( propertyName ) || testOldMethod.equals( propertyName ) ) {
potentialSetter = method;
if ( propertyType == null || method.getParameterTypes()[0].equals( propertyType ) ) {
@ -818,12 +803,9 @@ public final class ReflectHelper {
private static String likelySetterMethodNameForProperty(final String propertyName) {
final char firstCharacter = propertyName.charAt( 0 );
if ( Character.isLowerCase( firstCharacter ) ) {
return "set" + Character.toUpperCase( firstCharacter ) + propertyName.substring( 1 );
}
else {
return "set" + propertyName;
}
return Character.isLowerCase( firstCharacter )
? "set" + Character.toUpperCase( firstCharacter ) + propertyName.substring( 1 )
: "set" + propertyName;
}
/**
@ -835,37 +817,29 @@ public final class ReflectHelper {
*/
public static Method findGetterMethodForFieldAccess(Field field, String propertyName) {
for ( Method method : field.getDeclaringClass().getDeclaredMethods() ) {
// if the method has parameters, skip it
if ( method.getParameterCount() != 0 ) {
continue;
}
if ( method.getParameterCount() == 0 // if the method has parameters, skip it
&& !Modifier.isStatic( method.getModifiers() )
&& method.getReturnType().isAssignableFrom( field.getType() ) ) {
if ( Modifier.isStatic( method.getModifiers() ) ) {
continue;
}
final String methodName = method.getName();
if ( ! method.getReturnType().isAssignableFrom( field.getType() ) ) {
continue;
}
// try "get"
if ( methodName.startsWith( "get" ) ) {
final String stemName = methodName.substring( 3 );
if ( stemName.equals( propertyName )
|| decapitalize( stemName ).equals( propertyName ) ) {
return method;
}
final String methodName = method.getName();
// try "get"
if ( methodName.startsWith( "get" ) ) {
final String stemName = methodName.substring( 3 );
final String decapitalizedStemName = Introspector.decapitalize( stemName );
if ( stemName.equals( propertyName ) || decapitalizedStemName.equals( propertyName ) ) {
return method;
}
}
// if not "get", then try "is"
if ( methodName.startsWith( "is" ) ) {
final String stemName = methodName.substring( 2 );
String decapitalizedStemName = Introspector.decapitalize( stemName );
if ( stemName.equals( propertyName ) || decapitalizedStemName.equals( propertyName ) ) {
return method;
// if not "get", then try "is"
if ( methodName.startsWith( "is" ) ) {
final String stemName = methodName.substring( 2 );
if ( stemName.equals( propertyName )
|| decapitalize( stemName ).equals( propertyName ) ) {
return method;
}
}
}
}
@ -926,24 +900,24 @@ public final class ReflectHelper {
else if ( type instanceof Class<?> ) {
return (Class<T>) type;
}
else if ( type instanceof ParameterizedType ) {
return (Class<T>) ( (ParameterizedType) type ).getRawType();
else if ( type instanceof ParameterizedType parameterizedType ) {
return (Class<T>) parameterizedType.getRawType();
}
else if ( type instanceof TypeVariable ) {
return getClass( ( (TypeVariable<?>) type ).getBounds()[0] );
else if ( type instanceof TypeVariable<?> typeVariable ) {
return getClass( typeVariable.getBounds()[0] );
}
else if ( type instanceof WildcardType ) {
return getClass( ( (WildcardType) type ).getUpperBounds()[0] );
else if ( type instanceof WildcardType wildcardType ) {
return getClass( wildcardType.getUpperBounds()[0] );
}
throw new UnsupportedOperationException( "Can't get java type class from type: " + type );
}
public static Class<?> getPropertyType(Member member) {
if (member instanceof Field) {
return ( (Field) member ).getType();
if (member instanceof Field field) {
return field.getType();
}
else if (member instanceof Method) {
return ( (Method) member ).getReturnType();
else if (member instanceof Method method) {
return method.getReturnType();
}
else {
throw new AssertionFailure("member should have been a method or field");