Switch from java.lang.Class to java.lang.reflect.Type in the metamodel to support parameterized types

This commit is contained in:
Christian Beikov 2021-03-08 16:22:20 +01:00
parent 4a1a084def
commit 350fd81cf5
27 changed files with 176 additions and 85 deletions

View File

@ -138,7 +138,7 @@ public class InferredBasicValueResolver {
if ( jdbcMapping == null ) {
throw new MappingException(
"Could not determine JavaTypeDescriptor nor SqlTypeDescriptor to use" + "" +
" for " + ( (BasicValue) stdIndicators ).getResolvedJavaClass() +
" for " + ( (BasicValue) stdIndicators ).getResolvedJavaType() +
"; table = " + table.getName() +
"; column = " + selectable.getText()
);

View File

@ -35,7 +35,7 @@ public class VersionResolution<E> implements BasicValue.Resolution<E> {
@SuppressWarnings({"rawtypes", "unchecked"})
public static <E> VersionResolution<E> from(
Function<TypeConfiguration, Class> implicitJavaTypeAccess,
Function<TypeConfiguration, java.lang.reflect.Type> implicitJavaTypeAccess,
Function<TypeConfiguration, BasicJavaDescriptor> explicitJtdAccess,
Function<TypeConfiguration, SqlTypeDescriptor> explicitStdAccess,
TypeConfiguration typeConfiguration,
@ -43,7 +43,7 @@ public class VersionResolution<E> implements BasicValue.Resolution<E> {
// todo (6.0) : add support for Dialect-specific interpretation?
final Class implicitJavaType = implicitJavaTypeAccess.apply( typeConfiguration );
final java.lang.reflect.Type implicitJavaType = implicitJavaTypeAccess.apply( typeConfiguration );
final JavaTypeDescriptor registered = typeConfiguration.getJavaTypeDescriptorRegistry().resolveDescriptor( implicitJavaType );
if ( registered instanceof PrimitiveByteArrayTypeDescriptor ) {

View File

@ -50,6 +50,7 @@ import org.hibernate.cfg.SetBasicValueTypeSecondPass;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.mapping.BasicValue;
import org.hibernate.mapping.Table;
import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
@ -98,7 +99,7 @@ public class BasicValueBinder<T> implements SqlTypeDescriptorIndicators {
private Function<TypeConfiguration,SqlTypeDescriptor> explicitSqlTypeAccess;
private Function<TypeConfiguration, BasicJavaDescriptor> explicitJtdAccess;
private Function<TypeConfiguration, MutabilityPlan> explicitMutabilityAccess;
private Function<TypeConfiguration, Class> implicitJavaTypeAccess;
private Function<TypeConfiguration, java.lang.reflect.Type> implicitJavaTypeAccess;
private AccessType accessType;
@ -595,7 +596,7 @@ public class BasicValueBinder<T> implements SqlTypeDescriptorIndicators {
}
// see if the value's type Class is annotated `@Immutable`
final Class attributeType = implicitJavaTypeAccess.apply( typeConfiguration );
final Class attributeType = ReflectHelper.getClass( implicitJavaTypeAccess.apply( typeConfiguration ) );
if ( attributeType.isAnnotationPresent( Immutable.class ) ) {
return ImmutableMutabilityPlan.instance();
}

View File

@ -13,6 +13,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.Locale;
import java.util.regex.Pattern;
import javax.persistence.Transient;
@ -214,6 +215,19 @@ public final class ReflectHelper {
String className,
String name,
ClassLoaderService classLoaderService) throws MappingException {
try {
Class clazz = classLoaderService.classForName( className );
return getter( clazz, name ).getReturnTypeClass();
}
catch ( ClassLoadingException e ) {
throw new MappingException( "class " + className + " not found while looking for property: " + name, e );
}
}
public static java.lang.reflect.Type reflectedPropertyType(
String className,
String name,
ClassLoaderService classLoaderService) throws MappingException {
try {
Class clazz = classLoaderService.classForName( className );
return getter( clazz, name ).getReturnType();
@ -232,7 +246,7 @@ public final class ReflectHelper {
* @throws MappingException Indicates we were unable to locate the property.
*/
public static Class reflectedPropertyClass(Class clazz, String name) throws MappingException {
return getter( clazz, name ).getReturnType();
return getter( clazz, name ).getReturnTypeClass();
}
private static Getter getter(Class clazz, String name) throws MappingException {
@ -723,4 +737,17 @@ public final class ReflectHelper {
return null;
}
public static <T> Class<T> getClass(java.lang.reflect.Type type) {
if ( type == null ) {
return null;
}
else if ( type instanceof Class<?> ) {
return (Class<T>) type;
}
else if ( type instanceof ParameterizedType ) {
return (Class<T>) ( (ParameterizedType) type ).getRawType();
}
throw new UnsupportedOperationException( "Can't get java type class from type: " + type );
}
}

View File

@ -62,15 +62,15 @@ public class BasicValue extends SimpleValue implements SqlTypeDescriptorIndicato
private String explicitTypeName;
private Map explicitLocalTypeParams;
private Function<TypeConfiguration,BasicJavaDescriptor> explicitJavaTypeAccess;
private Function<TypeConfiguration,SqlTypeDescriptor> explicitSqlTypeAccess;
private Function<TypeConfiguration,MutabilityPlan> explicitMutabilityPlanAccess;
private Function<TypeConfiguration,Class> implicitJavaTypeAccess;
private Function<TypeConfiguration, BasicJavaDescriptor> explicitJavaTypeAccess;
private Function<TypeConfiguration, SqlTypeDescriptor> explicitSqlTypeAccess;
private Function<TypeConfiguration, MutabilityPlan> explicitMutabilityPlanAccess;
private Function<TypeConfiguration, java.lang.reflect.Type> implicitJavaTypeAccess;
private EnumType enumerationStyle;
private TemporalType temporalPrecision;
private Class resolvedJavaClass;
private java.lang.reflect.Type resolvedJavaType;
private String ownerName;
private String propertyName;
@ -138,7 +138,7 @@ public class BasicValue extends SimpleValue implements SqlTypeDescriptorIndicato
this.explicitMutabilityPlanAccess = explicitMutabilityPlanAccess;
}
public void setImplicitJavaTypeAccess(Function<TypeConfiguration, Class> implicitJavaTypeAccess) {
public void setImplicitJavaTypeAccess(Function<TypeConfiguration, java.lang.reflect.Type> implicitJavaTypeAccess) {
this.implicitJavaTypeAccess = implicitJavaTypeAccess;
}
@ -149,8 +149,8 @@ public class BasicValue extends SimpleValue implements SqlTypeDescriptorIndicato
return getColumn( 0 );
}
public Class getResolvedJavaClass() {
return resolvedJavaClass;
public java.lang.reflect.Type getResolvedJavaType() {
return resolvedJavaType;
}
@Override
@ -344,7 +344,7 @@ public class BasicValue extends SimpleValue implements SqlTypeDescriptorIndicato
if ( jtd == null ) {
if ( implicitJavaTypeAccess != null ) {
final Class implicitJtd = implicitJavaTypeAccess.apply( typeConfiguration );
final java.lang.reflect.Type implicitJtd = implicitJavaTypeAccess.apply( typeConfiguration );
if ( implicitJtd != null ) {
jtd = typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( implicitJtd );
}
@ -403,10 +403,10 @@ public class BasicValue extends SimpleValue implements SqlTypeDescriptorIndicato
}
private JavaTypeDescriptor determineReflectedJavaTypeDescriptor() {
final Class impliedJavaType;
final java.lang.reflect.Type impliedJavaType;
if ( resolvedJavaClass != null ) {
impliedJavaType = resolvedJavaClass;
if ( resolvedJavaType != null ) {
impliedJavaType = resolvedJavaType;
}
else if ( implicitJavaTypeAccess != null ) {
impliedJavaType = implicitJavaTypeAccess.apply( typeConfiguration );
@ -415,7 +415,7 @@ public class BasicValue extends SimpleValue implements SqlTypeDescriptorIndicato
final ServiceRegistry serviceRegistry = typeConfiguration.getServiceRegistry();
final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
impliedJavaType = ReflectHelper.reflectedPropertyClass(
impliedJavaType = ReflectHelper.reflectedPropertyType(
ownerName,
propertyName,
classLoaderService
@ -425,7 +425,7 @@ public class BasicValue extends SimpleValue implements SqlTypeDescriptorIndicato
return null;
}
resolvedJavaClass = impliedJavaType;
resolvedJavaType = impliedJavaType;
return typeConfiguration.getJavaTypeDescriptorRegistry().resolveDescriptor( impliedJavaType );
}
@ -434,7 +434,7 @@ public class BasicValue extends SimpleValue implements SqlTypeDescriptorIndicato
private static Resolution interpretExplicitlyNamedType(
String name,
EnumType enumerationStyle,
Function<TypeConfiguration, Class> implicitJavaTypeAccess,
Function<TypeConfiguration, java.lang.reflect.Type> implicitJavaTypeAccess,
Function<TypeConfiguration, BasicJavaDescriptor> explicitJtdAccess,
Function<TypeConfiguration, SqlTypeDescriptor> explicitStdAccess,
Function<TypeConfiguration, MutabilityPlan> explicitMutabilityPlanAccess,

View File

@ -90,7 +90,7 @@ public class Property implements Serializable, MetaAttributable {
}
public boolean isPrimitive(Class clazz) {
return getGetter(clazz).getReturnType().isPrimitive();
return getGetter(clazz).getReturnTypeClass().isPrimitive();
}
public CascadeStyle getCascadeStyle() throws MappingException {

View File

@ -159,7 +159,7 @@ public class StandardPojoEmbeddableRepresentationStrategy extends AbstractEmbedd
getterNames[i] = propertyAccess.getGetter().getMethodName();
setterNames[i] = propertyAccess.getSetter().getMethodName();
propTypes[i] = propertyAccess.getGetter().getReturnType();
propTypes[i] = propertyAccess.getGetter().getReturnTypeClass();
}
return Environment.getBytecodeProvider().getReflectionOptimizer(

View File

@ -288,7 +288,7 @@ public class StandardPojoEntityRepresentationStrategy implements EntityRepresent
}
getterNames.add( propertyAccess.getGetter().getMethodName() );
getterTypes.add( propertyAccess.getGetter().getReturnType() );
getterTypes.add( propertyAccess.getGetter().getReturnTypeClass() );
setterNames.add( propertyAccess.getSetter().getMethodName() );

View File

@ -8,6 +8,7 @@ package org.hibernate.property.access.internal;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import org.hibernate.engine.spi.SessionFactoryImplementor;
@ -21,7 +22,7 @@ import org.hibernate.property.access.spi.Setter;
* PropertyAccess for handling non-aggregated composites.
* <p/>
* IMPL NOTE : We actually use a singleton for the Setter; we cannot for the getter mainly
* because we need to differentiate {@link Getter#getReturnType()}. Ultimately I'd prefer to
* because we need to differentiate {@link Getter#getReturnTypeClass()}. Ultimately I'd prefer to
* model that "common information" on PropertyAccess itself.
*
* @author Gavin King
@ -73,7 +74,12 @@ public class PropertyAccessEmbeddedImpl implements PropertyAccess {
}
@Override
public Class getReturnType() {
public Class<?> getReturnTypeClass() {
return containerType;
}
@Override
public Type getReturnType() {
return containerType;
}

View File

@ -8,6 +8,7 @@ package org.hibernate.property.access.internal;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import org.hibernate.engine.spi.SessionFactoryImplementor;
@ -68,11 +69,16 @@ public class PropertyAccessMapImpl implements PropertyAccess {
}
@Override
public Class getReturnType() {
public Class<?> getReturnTypeClass() {
// we just don't know...
return Object.class;
}
@Override
public Type getReturnType() {
return Object.class;
}
@Override
public Member getMember() {
return null;

View File

@ -9,6 +9,7 @@ package org.hibernate.property.access.internal;
import java.io.Serializable;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import org.hibernate.engine.spi.SessionFactoryImplementor;
@ -102,7 +103,12 @@ public class PropertyAccessStrategyBackRefImpl implements PropertyAccessStrategy
}
@Override
public Class getReturnType() {
public Class<?> getReturnTypeClass() {
return Object.class;
}
@Override
public Type getReturnType() {
return Object.class;
}

View File

@ -8,6 +8,7 @@ package org.hibernate.property.access.internal;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import org.hibernate.engine.spi.SessionFactoryImplementor;
@ -85,7 +86,12 @@ public class PropertyAccessStrategyIndexBackRefImpl implements PropertyAccessStr
}
@Override
public Class getReturnType() {
public Class<?> getReturnTypeClass() {
return Object.class;
}
@Override
public Type getReturnType() {
return Object.class;
}

View File

@ -8,6 +8,7 @@ package org.hibernate.property.access.internal;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import org.hibernate.engine.spi.SessionFactoryImplementor;
@ -74,7 +75,12 @@ public class PropertyAccessStrategyNoopImpl implements PropertyAccessStrategy {
}
@Override
public Class getReturnType() {
public Class<?> getReturnTypeClass() {
return Object.class;
}
@Override
public Type getReturnType() {
return Object.class;
}

View File

@ -11,6 +11,7 @@ import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import org.hibernate.PropertyAccessException;
@ -102,10 +103,15 @@ public class EnhancedGetterMethodImpl implements Getter {
}
@Override
public Class getReturnType() {
public Class<?> getReturnTypeClass() {
return getterMethod.getReturnType();
}
@Override
public Type getReturnType() {
return getterMethod.getGenericReturnType();
}
@Override
public Member getMember() {
return getterMethod;

View File

@ -9,6 +9,7 @@ package org.hibernate.property.access.spi;
import java.io.Serializable;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
@ -44,12 +45,19 @@ public interface Getter extends Serializable {
*/
Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session);
/**
* Retrieve the declared Java type class
*
* @return The declared java type class.
*/
Class<?> getReturnTypeClass();
/**
* Retrieve the declared Java type
*
* @return The declared java type.
*/
Class getReturnType();
Type getReturnType();
/**
* Retrieve the member to which this property maps. This might be the

View File

@ -11,6 +11,7 @@ import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Locale;
import java.util.Map;
@ -91,10 +92,15 @@ public class GetterFieldImpl implements Getter {
}
@Override
public Class getReturnType() {
public Class<?> getReturnTypeClass() {
return field.getType();
}
@Override
public Type getReturnType() {
return field.getGenericType();
}
@Override
public Member getMember() {
return field;

View File

@ -11,6 +11,7 @@ import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import org.hibernate.PropertyAccessException;
@ -79,10 +80,15 @@ public class GetterMethodImpl implements Getter {
}
@Override
public Class getReturnType() {
public Class<?> getReturnTypeClass() {
return getterMethod.getReturnType();
}
@Override
public Type getReturnType() {
return getterMethod.getGenericReturnType();
}
@Override
public Member getMember() {
return getterMethod;

View File

@ -764,7 +764,7 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
parameterName
);
final Getter getter = propertyAccess.getGetter();
final Class retType = getter.getReturnType();
final Class<?> retType = getter.getReturnTypeClass();
final Object object = getter.get( bean );
if ( Collection.class.isAssignableFrom( retType ) ) {
setParameterList( parameterName, (Collection) object );

View File

@ -1287,7 +1287,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
paramName
);
final Getter getter = propertyAccess.getGetter();
final Class<?> retType = getter.getReturnType();
final Class<?> retType = getter.getReturnTypeClass();
final Object object = getter.get( bean );
if ( Collection.class.isAssignableFrom( retType ) ) {
setParameterList( paramName, (Collection<?>) object );

View File

@ -7,6 +7,7 @@
package org.hibernate.sql.results.graph.instantiation.internal;
import java.lang.reflect.Constructor;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@ -143,7 +144,8 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
// find a constructor matching argument types
constructor_loop:
for ( Constructor<?> constructor : javaTypeDescriptor.getJavaTypeClass().getDeclaredConstructors() ) {
if ( constructor.getParameterTypes().length != argumentReaders.size() ) {
final Type[] genericParameterTypes = constructor.getGenericParameterTypes();
if ( genericParameterTypes.length != argumentReaders.size() ) {
continue;
}
@ -153,7 +155,7 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
.getDomainModel()
.getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.resolveDescriptor( constructor.getParameterTypes()[i] );
.resolveDescriptor( genericParameterTypes[i] );
final boolean assignmentCompatible = Compatibility.areAssignmentCompatible(
argumentTypeDescriptor,

View File

@ -49,7 +49,7 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer {
for ( int i = 0; i < propertySpan; i++ ) {
getterNames[i] = getters[i].getMethodName();
setterNames[i] = setters[i].getMethodName();
propTypes[i] = getters[i].getReturnType();
propTypes[i] = getters[i].getReturnTypeClass();
}
final String parentPropertyName = component.getParentProperty();

View File

@ -61,7 +61,7 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
for ( int i = 0; i < propertySpan; i++ ) {
getterNames[i] = getters[i].getMethodName();
setterNames[i] = setters[i].getMethodName();
propTypes[i] = getters[i].getReturnType();
propTypes[i] = getters[i].getReturnTypeClass();
}
if ( hasCustomAccessors || !Environment.useReflectionOptimizer() ) {

View File

@ -7,13 +7,13 @@
package org.hibernate.type.descriptor.java;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Comparator;
import java.util.Objects;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.compare.ComparableComparator;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
@ -185,17 +185,7 @@ public interface JavaTypeDescriptor<T> extends Serializable {
* @return The Java type.
*/
default Class<T> getJavaTypeClass() {
final Type type = getJavaType();
if ( type == null ) {
return null;
}
else if ( type instanceof Class<?> ) {
return (Class<T>) type;
}
else if ( type instanceof ParameterizedType ) {
return (Class<T>) ( (ParameterizedType) type ).getRawType();
}
throw new UnsupportedOperationException( "Can't get java type class from type: " + type );
return ReflectHelper.getClass( getJavaType() );
}
/**

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.type.descriptor.java.spi;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@ -72,8 +73,8 @@ import org.hibernate.type.descriptor.java.ZonedDateTimeJavaDescriptor;
*/
public class JavaTypeDescriptorBaseline {
public interface BaselineTarget {
void addBaselineDescriptor(JavaTypeDescriptor descriptor);
void addBaselineDescriptor(Class describedJavaType, JavaTypeDescriptor descriptor);
void addBaselineDescriptor(JavaTypeDescriptor<?> descriptor);
void addBaselineDescriptor(Type describedJavaType, JavaTypeDescriptor<?> descriptor);
}
@SuppressWarnings("unchecked")

View File

@ -7,9 +7,12 @@
package org.hibernate.type.descriptor.java.spi;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import org.hibernate.type.descriptor.java.AbstractClassTypeDescriptor;
import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.SerializableTypeDescriptor;
@ -30,7 +33,7 @@ public class JavaTypeDescriptorRegistry implements JavaTypeDescriptorBaseline.Ba
private static final Logger log = Logger.getLogger( JavaTypeDescriptorRegistry.class );
private final TypeConfiguration typeConfiguration;
private ConcurrentHashMap<Class, JavaTypeDescriptor> descriptorsByClass = new ConcurrentHashMap<>();
private final ConcurrentHashMap<Type, JavaTypeDescriptor<?>> descriptorsByType = new ConcurrentHashMap<>();
@SuppressWarnings("unused")
public JavaTypeDescriptorRegistry(TypeConfiguration typeConfiguration) {
@ -43,20 +46,20 @@ public class JavaTypeDescriptorRegistry implements JavaTypeDescriptorBaseline.Ba
// baseline descriptors
@Override
public void addBaselineDescriptor(JavaTypeDescriptor descriptor) {
public void addBaselineDescriptor(JavaTypeDescriptor<?> descriptor) {
if ( descriptor.getJavaType() == null ) {
throw new IllegalStateException( "Illegal to add BasicJavaTypeDescriptor with null Java type" );
}
addBaselineDescriptor( descriptor.getJavaTypeClass(), descriptor );
addBaselineDescriptor( descriptor.getJavaType(), descriptor );
}
@Override
public void addBaselineDescriptor(Class describedJavaType, JavaTypeDescriptor descriptor) {
public void addBaselineDescriptor(Type describedJavaType, JavaTypeDescriptor<?> descriptor) {
performInjections( descriptor );
descriptorsByClass.put( describedJavaType, descriptor );
descriptorsByType.put( describedJavaType, descriptor );
}
private void performInjections(JavaTypeDescriptor descriptor) {
private void performInjections(JavaTypeDescriptor<?> descriptor) {
if ( descriptor instanceof TypeConfigurationAware ) {
// would be nice to make the JavaTypeDescriptor for an entity, e.g., aware of the the TypeConfiguration
( (TypeConfigurationAware) descriptor ).setTypeConfiguration( typeConfiguration );
@ -67,7 +70,7 @@ public class JavaTypeDescriptorRegistry implements JavaTypeDescriptorBaseline.Ba
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// descriptor access
public <T> JavaTypeDescriptor<T> getDescriptor(Class<T> javaType) {
public <T> JavaTypeDescriptor<T> getDescriptor(Type javaType) {
return resolveDescriptor( javaType );
// return RegistryHelper.INSTANCE.resolveDescriptor(
// descriptorsByClass,
@ -98,8 +101,8 @@ public class JavaTypeDescriptorRegistry implements JavaTypeDescriptorBaseline.Ba
// );
}
public void addDescriptor(JavaTypeDescriptor descriptor) {
JavaTypeDescriptor old = descriptorsByClass.put( descriptor.getJavaTypeClass(), descriptor );
public void addDescriptor(JavaTypeDescriptor<?> descriptor) {
JavaTypeDescriptor<?> old = descriptorsByType.put( descriptor.getJavaType(), descriptor );
if ( old != null ) {
log.debugf(
"JavaTypeDescriptorRegistry entry replaced : %s -> %s (was %s)",
@ -111,34 +114,45 @@ public class JavaTypeDescriptorRegistry implements JavaTypeDescriptorBaseline.Ba
performInjections( descriptor );
}
public <J> JavaTypeDescriptor<J> resolveDescriptor(Class<J> javaType, Supplier<JavaTypeDescriptor<J>> creator) {
final JavaTypeDescriptor cached = descriptorsByClass.get( javaType );
public <J> JavaTypeDescriptor<J> resolveDescriptor(Type javaType, Supplier<JavaTypeDescriptor<J>> creator) {
final JavaTypeDescriptor<?> cached = descriptorsByType.get( javaType );
if ( cached != null ) {
//noinspection unchecked
return cached;
return (JavaTypeDescriptor<J>) cached;
}
final JavaTypeDescriptor<J> created = creator.get();
descriptorsByClass.put( javaType, created );
descriptorsByType.put( javaType, created );
return created;
}
@SuppressWarnings("unchecked")
public <J> JavaTypeDescriptor<J> resolveDescriptor(Class<J> javaType) {
public <J> JavaTypeDescriptor<J> resolveDescriptor(Type javaType) {
return resolveDescriptor(
javaType,
() -> {
// the fallback will always be a basic type
final JavaTypeDescriptor<J> fallbackDescriptor;
if ( javaType.isEnum() ) {
fallbackDescriptor = new EnumJavaTypeDescriptor( javaType );
}
else if ( Serializable.class.isAssignableFrom( javaType ) ) {
fallbackDescriptor = new SerializableTypeDescriptor( javaType );
final AbstractClassTypeDescriptor<J> fallbackDescriptor;
final Class<?> javaTypeClass;
if ( javaType instanceof Class<?> ) {
javaTypeClass = (Class<?>) javaType;
}
else {
fallbackDescriptor = new JavaTypeDescriptorBasicAdaptor( javaType );
final ParameterizedType parameterizedType = (ParameterizedType) javaType;
javaTypeClass = (Class<?>) parameterizedType.getRawType();
}
if ( javaTypeClass.isEnum() ) {
//noinspection rawtypes
fallbackDescriptor = new EnumJavaTypeDescriptor( javaTypeClass );
}
else if ( Serializable.class.isAssignableFrom( javaTypeClass ) ) {
//noinspection rawtypes
fallbackDescriptor = new SerializableTypeDescriptor( javaTypeClass );
}
else {
//noinspection rawtypes
fallbackDescriptor = new JavaTypeDescriptorBasicAdaptor( javaTypeClass );
}
// todo (6.0) : here we assume that all temporal type descriptors are registered

View File

@ -74,13 +74,13 @@ public class BasicPropertyAccessorTest extends BaseUnitTestCase {
{
final PropertyAccess access = accessStrategy.buildPropertyAccess( Duper.class, "it" );
assertEquals( String.class, access.getGetter().getReturnType() );
assertEquals( String.class, access.getGetter().getReturnTypeClass() );
assertEquals( Object.class, access.getSetter().getMethod().getParameterTypes()[0] );
}
{
final PropertyAccess access = accessStrategy.buildPropertyAccess( Duper2.class, "it" );
assertEquals( String.class, access.getGetter().getReturnType() );
assertEquals( String.class, access.getGetter().getReturnTypeClass() );
assertEquals( String.class, access.getSetter().getMethod().getParameterTypes()[0] );
}
}

View File

@ -32,49 +32,49 @@ public class BeanReflectionHelper {
Getter getter = propertyAccess.getGetter();
Setter setter = propertyAccess.getSetter();
getterNames[0] = getter.getMethodName();
types[0] = getter.getReturnType();
types[0] = getter.getReturnTypeClass();
setterNames[0] = setter.getMethodName();
propertyAccess = propertyAccessStrategy.buildPropertyAccess( Bean.class, "someLong" );
getter = propertyAccess.getGetter();
setter = propertyAccess.getSetter();
getterNames[1] = getter.getMethodName();
types[1] = getter.getReturnType();
types[1] = getter.getReturnTypeClass();
setterNames[1] = setter.getMethodName();
propertyAccess = propertyAccessStrategy.buildPropertyAccess( Bean.class, "someInteger" );
getter = propertyAccess.getGetter();
setter = propertyAccess.getSetter();
getterNames[2] = getter.getMethodName();
types[2] = getter.getReturnType();
types[2] = getter.getReturnTypeClass();
setterNames[2] = setter.getMethodName();
propertyAccess = propertyAccessStrategy.buildPropertyAccess( Bean.class, "someDate" );
getter = propertyAccess.getGetter();
setter = propertyAccess.getSetter();
getterNames[3] = getter.getMethodName();
types[3] = getter.getReturnType();
types[3] = getter.getReturnTypeClass();
setterNames[3] = setter.getMethodName();
propertyAccess = propertyAccessStrategy.buildPropertyAccess( Bean.class, "somelong" );
getter = propertyAccess.getGetter();
setter = propertyAccess.getSetter();
getterNames[4] = getter.getMethodName();
types[4] = getter.getReturnType();
types[4] = getter.getReturnTypeClass();
setterNames[4] = setter.getMethodName();
propertyAccess = propertyAccessStrategy.buildPropertyAccess( Bean.class, "someint" );
getter = propertyAccess.getGetter();
setter = propertyAccess.getSetter();
getterNames[5] = getter.getMethodName();
types[5] = getter.getReturnType();
types[5] = getter.getReturnTypeClass();
setterNames[5] = setter.getMethodName();
propertyAccess = propertyAccessStrategy.buildPropertyAccess( Bean.class, "someObject" );
getter = propertyAccess.getGetter();
setter = propertyAccess.getSetter();
getterNames[6] = getter.getMethodName();
types[6] = getter.getReturnType();
types[6] = getter.getReturnTypeClass();
setterNames[6] = setter.getMethodName();
}