/** * Adds the AttributeConverter Class to this Configuration. * * @param attributeConverterClass The AttributeConverter class. * @param autoApply Should the AttributeConverter be auto applied to property types as specified * by its "entity attribute" parameterized type? */ public void addAttributeConverter(Class<? extends AttributeConverter> attributeConverterClass, boolean autoApply) { addAttributeConverter( AttributeConverterDefinition.from( attributeConverterClass, autoApply ) ); }
/** * Build an AttributeConverterDefinition from the AttributeConverter Class reference and * whether or not to auto-apply it. * * @param attributeConverterClass The AttributeConverter Class * @param autoApply Should the AttributeConverter be auto-applied? * * @return The constructed definition */ public static AttributeConverterDefinition from(Class<? extends AttributeConverter> attributeConverterClass, boolean autoApply) { return new AttributeConverterDefinition( instantiateAttributeConverter( attributeConverterClass ), autoApply ); }
private ParameterizedType extractAttributeConverterParameterizedType(Type base) { if ( base != null ) { Class clazz = extractClass( base ); List<Type> types = new ArrayList<>(); types.add( clazz.getGenericSuperclass() ); types.addAll( Arrays.asList( clazz.getGenericInterfaces() ) ); for ( Type type : types ) { type = resolveType( type, base ); if ( ParameterizedType.class.isInstance( type ) ) { final ParameterizedType parameterizedType = (ParameterizedType) type; if ( AttributeConverter.class.equals( parameterizedType.getRawType() ) ) { return parameterizedType; } } ParameterizedType parameterizedType = extractAttributeConverterParameterizedType( type ); if ( parameterizedType != null ) { return parameterizedType; } } } return null; }
/** * Build an AttributeConverterDefinition from the AttributeConverter Class reference. The * converter is searched for a {@link Converter} annotation to determine whether it should * be treated as auto-apply. If the annotation is present, {@link Converter#autoApply()} is * used to make that determination. If the annotation is not present, {@code false} is assumed. * * @param attributeConverterClass The converter class * * @return The constructed definition */ public static AttributeConverterDefinition from(Class<? extends AttributeConverter> attributeConverterClass) { return from( instantiateAttributeConverter( attributeConverterClass ) ); }
private static Type resolveType(Type target, Type context) { if ( target instanceof ParameterizedType ) { return resolveParameterizedType( (ParameterizedType) target, context ); } else if ( target instanceof TypeVariable ) { return resolveTypeVariable( (TypeVariable) target, (ParameterizedType) context ); } return target; }
@Test public void testTypeVariableAttributeConverterTypeArguments() { AttributeConverterDefinition def = AttributeConverterDefinition.from( StringNoopAttributeConverter.class ); assertEquals( String.class, def.getEntityAttributeType() ); }
private static Type resolveTypeVariable(TypeVariable typeVariable, ParameterizedType context) { Class clazz = extractClass( context.getRawType() ); TypeVariable[] typeParameters = clazz.getTypeParameters(); for ( int idx = 0; idx < typeParameters.length; idx++ ) { if ( typeVariable.getName().equals( typeParameters[idx].getName() ) ) { return resolveType( context.getActualTypeArguments()[idx], context ); } } return typeVariable; }
@Override public ConverterDescriptor toConverterDescriptor(MetadataBuildingContext context) { return new InstanceBasedConverterDescriptor( getAttributeConverter(), isAutoApply(), context.getBootstrapContext().getClassmateContext() ); } }
final ParameterizedType attributeConverterSignature = extractAttributeConverterParameterizedType( attributeConverterClass ); if ( attributeConverterSignature == null ) { throw new AssertionFailure( ); entityAttributeType = extractClass( attributeConverterSignature.getActualTypeArguments()[0] ); if ( entityAttributeType == null ) { throw new AnnotationException( databaseColumnType = extractClass(attributeConverterSignature.getActualTypeArguments()[1]); if ( databaseColumnType == null ) { throw new AnnotationException(
/** * Build an AttributeConverterDefinition from the AttributeConverter instance and * whether or not to auto-apply it. * * @param attributeConverter The AttributeConverter instance * @param autoApply Should the AttributeConverter be auto-applied? * * @return The constructed definition */ public static AttributeConverterDefinition from(AttributeConverter attributeConverter, boolean autoApply) { return new AttributeConverterDefinition( attributeConverter, autoApply ); }
public void addAttributeConverter(AttributeConverterDefinition definition) { if ( attributeConverterDefinitionsByClass == null ) { attributeConverterDefinitionsByClass = new HashMap<Class, AttributeConverterDefinition>(); } attributeConverterDefinitionsByClass.put( definition.getAttributeConverter().getClass(), definition ); }
private static Class extractClass(Type type) { if ( type instanceof Class ) { return (Class) type; } else if ( type instanceof ParameterizedType ) { return extractClass( ( (ParameterizedType) type ).getRawType() ); } return null; }
private static ParameterizedType resolveParameterizedType(final ParameterizedType parameterizedType, Type context) { Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); final Type[] resolvedTypeArguments = new Type[actualTypeArguments.length]; for ( int idx = 0; idx < actualTypeArguments.length; idx++ ) { resolvedTypeArguments[idx] = resolveType( actualTypeArguments[idx], context ); } return new ParameterizedType() { @Override public Type[] getActualTypeArguments() { return resolvedTypeArguments; } @Override public Type getRawType() { return parameterizedType.getRawType(); } @Override public Type getOwnerType() { return parameterizedType.getOwnerType(); } }; }
@Test public void testAttributeConverterOnSuperclass() { AttributeConverterDefinition def = AttributeConverterDefinition.from( StringIntegerConverterSubclass.class ); assertEquals( String.class, def.getEntityAttributeType() ); }
/** * Build an AttributeConverterDefinition from an AttributeConverter instance. The * converter is searched for a {@link Converter} annotation to determine whether it should * be treated as auto-apply. If the annotation is present, {@link Converter#autoApply()} is * used to make that determination. If the annotation is not present, {@code false} is assumed. * * @param attributeConverter The AttributeConverter instance * * @return The constructed definition */ public static AttributeConverterDefinition from(AttributeConverter attributeConverter) { boolean autoApply = false; Converter converterAnnotation = attributeConverter.getClass().getAnnotation( Converter.class ); if ( converterAnnotation != null ) { autoApply = converterAnnotation.autoApply(); } return new AttributeConverterDefinition( attributeConverter, autoApply ); }
void addAttributeConverter(ConverterDescriptor descriptor);
@Test public void testAttributeConverterOnInterface() { AttributeConverterDefinition def = AttributeConverterDefinition.from( StringLongAttributeConverterImpl.class ); assertEquals( String.class, def.getEntityAttributeType() ); }
/** * Adds the AttributeConverter instance to this Configuration. This form is mainly intended for developers * to programmatically add their own AttributeConverter instance. HEM, instead, uses the * {@link #addAttributeConverter(Class, boolean)} form * * @param attributeConverter The AttributeConverter instance. * @param autoApply Should the AttributeConverter be auto applied to property types as specified * by its "entity attribute" parameterized type? */ public void addAttributeConverter(AttributeConverter attributeConverter, boolean autoApply) { addAttributeConverter( AttributeConverterDefinition.from( attributeConverter, autoApply ) ); }
@SuppressWarnings("unchecked") private void setLocalAttributeConverterDefinitions(List<Element> converterElements) { for ( Element converterElement : converterElements ) { final String className = converterElement.attributeValue( "class" ); final String autoApplyAttribute = converterElement.attributeValue( "auto-apply" ); final boolean autoApply = autoApplyAttribute != null && Boolean.parseBoolean( autoApplyAttribute ); try { final Class<? extends AttributeConverter> attributeConverterClass = classLoaderAccess.classForName( className ); attributeConverterInfoList.add( new AttributeConverterDefinition( attributeConverterClass.newInstance(), autoApply ) ); } catch (ClassLoadingException e) { throw new AnnotationException( "Unable to locate specified AttributeConverter implementation class : " + className, e ); } catch (Exception e) { throw new AnnotationException( "Unable to instantiate specified AttributeConverter implementation class : " + className, e ); } } }
@Test public void testParameterizedTypeWithTypeVariableAttributeConverterTypeArguments() { AttributeConverterDefinition def = AttributeConverterDefinition.from( StringListNoopAttributeConverter.class ); assertEquals( List.class, def.getEntityAttributeType() ); }