Skip to content

Commit 1c992b1

Browse files
committed
HHH-7803 Refactored the attribute type discovery and moved into
ReflectHelper
1 parent 8acfa1c commit 1c992b1

File tree

4 files changed

+98
-106
lines changed

4 files changed

+98
-106
lines changed

hibernate-core/src/main/java/org/hibernate/internal/util/ReflectHelper.java

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,16 @@
2424
*/
2525
package org.hibernate.internal.util;
2626

27+
import java.beans.Introspector;
2728
import java.lang.reflect.Constructor;
29+
import java.lang.reflect.Field;
2830
import java.lang.reflect.Member;
2931
import java.lang.reflect.Method;
3032
import java.lang.reflect.Modifier;
33+
import java.lang.reflect.ParameterizedType;
34+
import java.lang.reflect.TypeVariable;
35+
import java.util.HashSet;
36+
import java.util.Set;
3137

3238
import org.hibernate.AssertionFailure;
3339
import org.hibernate.MappingException;
@@ -381,4 +387,87 @@ public static Method getMethod(Class clazz, Method method) {
381387
}
382388
}
383389

390+
/**
391+
* Process bean properties getter by applying the JavaBean naming conventions.
392+
*
393+
* @param member the member for which to get the property name.
394+
*
395+
* @return The bean method name with the "is" or "get" prefix stripped off, {@code null}
396+
* the method name id not according to the JavaBeans standard.
397+
*/
398+
public static String getPropertyName(Member member) {
399+
String name = null;
400+
401+
if ( member instanceof Field ) {
402+
name = member.getName();
403+
}
404+
405+
if ( member instanceof Method ) {
406+
String methodName = member.getName();
407+
if ( methodName.startsWith( "is" ) ) {
408+
name = Introspector.decapitalize( methodName.substring( 2 ) );
409+
}
410+
else if ( methodName.startsWith( "has" ) ) {
411+
name = Introspector.decapitalize( methodName.substring( 3 ) );
412+
}
413+
else if ( methodName.startsWith( "get" ) ) {
414+
name = Introspector.decapitalize( methodName.substring( 3 ) );
415+
}
416+
}
417+
return name;
418+
}
419+
420+
public static boolean isProperty(Member m) {
421+
if ( m instanceof Method ) {
422+
Method method = (Method) m;
423+
return !method.isSynthetic()
424+
&& !method.isBridge()
425+
&& !Modifier.isStatic( method.getModifiers() )
426+
&& method.getParameterTypes().length == 0
427+
&& ( method.getName().startsWith( "get" ) || method.getName().startsWith( "is" ) );
428+
}
429+
else {
430+
return !Modifier.isTransient( m.getModifiers() ) && !m.isSynthetic();
431+
}
432+
}
433+
434+
/**
435+
* Returns a Set of field types in the given class. However, for Collection
436+
* and Map fields, the value and key types are returned instead of the
437+
* Iterable class itself.
438+
*
439+
* @param clazz
440+
* @return Set<Class<?>>
441+
*/
442+
public static Set<Class<?>> getFieldTypes( Class<?> clazz ) {
443+
Set<Class<?>> fieldTypes = new HashSet<Class<?>>();
444+
445+
for ( Field declaredField : clazz.getDeclaredFields() ) {
446+
Class<?> fieldClass = declaredField.getType();
447+
if ( fieldClass.isArray() ) {
448+
fieldTypes.add( fieldClass.getComponentType() );
449+
}
450+
else if ( declaredField.getGenericType() instanceof ParameterizedType ) {
451+
final java.lang.reflect.Type[] types
452+
= ( (ParameterizedType) declaredField.getGenericType() )
453+
.getActualTypeArguments();
454+
if ( types != null ) {
455+
// assumes we want to check values *and* map keys
456+
for ( java.lang.reflect.Type type : types ) {
457+
if ( type instanceof TypeVariable ) {
458+
fieldTypes.add( (Class<?>) ( (TypeVariable) type )
459+
.getGenericDeclaration() );
460+
}
461+
else {
462+
fieldTypes.add( (Class<?>) type );
463+
}
464+
}
465+
}
466+
}
467+
else {
468+
fieldTypes.add( fieldClass );
469+
}
470+
}
471+
return fieldTypes;
472+
}
384473
}

hibernate-core/src/main/java/org/hibernate/metamodel/MetadataSources.java

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.hibernate.boot.registry.StandardServiceRegistry;
4747
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
4848
import org.hibernate.boot.spi.CacheRegionDefinition;
49+
import org.hibernate.internal.util.ReflectHelper;
4950
import org.hibernate.jaxb.internal.JaxbMappingProcessor;
5051
import org.hibernate.jaxb.spi.JaxbRoot;
5152
import org.hibernate.jaxb.spi.Origin;
@@ -522,27 +523,15 @@ private void indexClass(Class clazz, Indexer indexer, Set<Class<?>> processedCla
522523
// For backward compatibility, don't require @Embeddable
523524
// classes to be explicitly identified.
524525
// Automatically find them by checking the fields' types.
525-
// TODO: There has to be a better way to do this.
526-
for ( Field declaredField : clazz.getDeclaredFields() ) {
527-
Class<?> fieldClass = declaredField.getType();
528-
if ( fieldClass.isArray() ) {
529-
fieldClass = fieldClass.getComponentType();
530-
}
531-
else if ( Collection.class.isAssignableFrom( fieldClass )
532-
&& declaredField.getGenericType() instanceof ParameterizedType ) {
533-
ParameterizedType listType = (ParameterizedType) declaredField.getGenericType();
534-
fieldClass = (Class<?>) listType.getActualTypeArguments()[0];
535-
}
536-
// TODO: Map
537-
538-
if ( !fieldClass.isPrimitive() && fieldClass != Object.class ) {
526+
for ( Class<?> fieldType : ReflectHelper.getFieldTypes( clazz ) ) {
527+
if ( !fieldType.isPrimitive() && fieldType != Object.class ) {
539528
try {
540529
Index fieldIndex = JandexHelper.indexForClass(
541530
serviceRegistry.getService( ClassLoaderService.class ),
542-
fieldClass );
531+
fieldType );
543532
if ( !fieldIndex.getAnnotations(
544533
JPADotNames.EMBEDDABLE ).isEmpty() ) {
545-
indexClass( fieldClass, indexer, processedClasses );
534+
indexClass( fieldType, indexer, processedClasses );
546535
}
547536
} catch ( Exception e ) {
548537
// do nothing

hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/ConfiguredClass.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import org.hibernate.EntityMode;
4545
import org.hibernate.HibernateException;
4646
import org.hibernate.internal.CoreMessageLogger;
47+
import org.hibernate.internal.util.ReflectHelper;
4748
import org.hibernate.internal.util.StringHelper;
4849
import org.hibernate.metamodel.internal.source.annotations.AnnotationBindingContext;
4950
import org.hibernate.metamodel.internal.source.annotations.attribute.AssociationAttribute;
@@ -54,9 +55,9 @@
5455
import org.hibernate.metamodel.internal.source.annotations.util.HibernateDotNames;
5556
import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames;
5657
import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper;
57-
import org.hibernate.metamodel.internal.source.annotations.util.ReflectionHelper;
5858
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
5959
import org.hibernate.metamodel.spi.source.MappingException;
60+
import org.hibernate.validator.util.ReflectionHelper;
6061
import org.jboss.jandex.AnnotationInstance;
6162
import org.jboss.jandex.AnnotationTarget;
6263
import org.jboss.jandex.ClassInfo;
@@ -304,7 +305,7 @@ private void collectAttributes() {
304305
}
305306

306307
private boolean isPersistentMember(Set<String> transientNames, Set<String> explicitlyConfiguredMemberNames, Member member) {
307-
if ( !ReflectionHelper.isProperty( member ) ) {
308+
if ( !ReflectHelper.isProperty( member ) ) {
308309
return false;
309310
}
310311

@@ -393,7 +394,7 @@ private Set<String> createExplicitlyConfiguredAccessProperties(ResolvedTypeWithM
393394
);
394395
}
395396
}
396-
if ( ReflectionHelper.isProperty( member ) ) {
397+
if ( ReflectHelper.isProperty( member ) ) {
397398
createMappedAttribute( member, resolvedMembers, accessType );
398399
explicitAccessPropertyNames.add( ReflectionHelper.getPropertyName( member ) );
399400
}

hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/ReflectionHelper.java

Lines changed: 0 additions & 87 deletions
This file was deleted.

0 commit comments

Comments
 (0)