HHH-8107 - JandexHelper.getValue() returns Boolean instead of boolean, causing ClassCastException
This commit is contained in:
parent
d184cb3eb4
commit
31219e25d7
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.internal.util.type;
|
||||
|
||||
/**
|
||||
* Helper for primitive/wrapper utilities.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class PrimitiveWrapperHelper {
|
||||
/**
|
||||
* Describes a particular primitive/wrapper combo
|
||||
*/
|
||||
public static interface PrimitiveWrapperDescriptor<T> {
|
||||
public Class<T> getPrimitiveClass();
|
||||
public Class<T> getWrapperClass();
|
||||
}
|
||||
|
||||
public static class BooleanDescriptor implements PrimitiveWrapperDescriptor<Boolean> {
|
||||
public static final BooleanDescriptor INSTANCE = new BooleanDescriptor();
|
||||
|
||||
private BooleanDescriptor() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Boolean> getPrimitiveClass() {
|
||||
return boolean.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Boolean> getWrapperClass() {
|
||||
return Boolean.class;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CharacterDescriptor implements PrimitiveWrapperDescriptor<Character> {
|
||||
public static final CharacterDescriptor INSTANCE = new CharacterDescriptor();
|
||||
|
||||
private CharacterDescriptor() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Character> getPrimitiveClass() {
|
||||
return char.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Character> getWrapperClass() {
|
||||
return Character.class;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ByteDescriptor implements PrimitiveWrapperDescriptor<Byte> {
|
||||
public static final ByteDescriptor INSTANCE = new ByteDescriptor();
|
||||
|
||||
private ByteDescriptor() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Byte> getPrimitiveClass() {
|
||||
return byte.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Byte> getWrapperClass() {
|
||||
return Byte.class;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ShortDescriptor implements PrimitiveWrapperDescriptor<Short> {
|
||||
public static final ShortDescriptor INSTANCE = new ShortDescriptor();
|
||||
|
||||
private ShortDescriptor() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Short> getPrimitiveClass() {
|
||||
return short.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Short> getWrapperClass() {
|
||||
return Short.class;
|
||||
}
|
||||
}
|
||||
|
||||
public static class IntegerDescriptor implements PrimitiveWrapperDescriptor<Integer> {
|
||||
public static final IntegerDescriptor INSTANCE = new IntegerDescriptor();
|
||||
|
||||
private IntegerDescriptor() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Integer> getPrimitiveClass() {
|
||||
return int.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Integer> getWrapperClass() {
|
||||
return Integer.class;
|
||||
}
|
||||
}
|
||||
|
||||
public static class LongDescriptor implements PrimitiveWrapperDescriptor<Long> {
|
||||
public static final LongDescriptor INSTANCE = new LongDescriptor();
|
||||
|
||||
private LongDescriptor() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Long> getPrimitiveClass() {
|
||||
return long.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Long> getWrapperClass() {
|
||||
return Long.class;
|
||||
}
|
||||
}
|
||||
|
||||
public static class FloatDescriptor implements PrimitiveWrapperDescriptor<Float> {
|
||||
public static final FloatDescriptor INSTANCE = new FloatDescriptor();
|
||||
|
||||
private FloatDescriptor() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Float> getPrimitiveClass() {
|
||||
return float.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Float> getWrapperClass() {
|
||||
return Float.class;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DoubleDescriptor implements PrimitiveWrapperDescriptor<Double> {
|
||||
public static final DoubleDescriptor INSTANCE = new DoubleDescriptor();
|
||||
|
||||
private DoubleDescriptor() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Double> getPrimitiveClass() {
|
||||
return double.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Double> getWrapperClass() {
|
||||
return Double.class;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <X> PrimitiveWrapperDescriptor<X> getDescriptorByPrimitiveType(Class<X> primitiveClazz) {
|
||||
if ( ! primitiveClazz.isPrimitive() ) {
|
||||
throw new IllegalArgumentException( "Given class is not a primitive type : " + primitiveClazz.getName() );
|
||||
}
|
||||
|
||||
if ( boolean.class == primitiveClazz ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) BooleanDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
if ( char.class == primitiveClazz ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) CharacterDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
if ( byte.class == primitiveClazz ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) ByteDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
if ( short.class == primitiveClazz ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) ShortDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
if ( int.class == primitiveClazz ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) IntegerDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
if ( long.class == primitiveClazz ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) LongDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
if ( float.class == primitiveClazz ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) FloatDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
if ( double.class == primitiveClazz ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) DoubleDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
// most likely void.class, which we can't really handle here
|
||||
throw new IllegalArgumentException( "Unrecognized primitive type class : " + primitiveClazz.getName() );
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <X> PrimitiveWrapperDescriptor<X> getDescriptorByWrapperType(Class<X> wrapperClass) {
|
||||
if ( wrapperClass.isPrimitive() ) {
|
||||
throw new IllegalArgumentException( "Given class is a primitive type : " + wrapperClass.getName() );
|
||||
}
|
||||
|
||||
if ( Boolean.class.equals( wrapperClass ) ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) BooleanDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
if ( Character.class == wrapperClass ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) CharacterDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
if ( Byte.class == wrapperClass ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) ByteDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
if ( Short.class == wrapperClass ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) ShortDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
if ( Integer.class == wrapperClass ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) IntegerDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
if ( Long.class == wrapperClass ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) LongDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
if ( Float.class == wrapperClass ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) FloatDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
if ( Double.class == wrapperClass ) {
|
||||
return (PrimitiveWrapperDescriptor<X>) DoubleDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
// most likely void.class, which we can't really handle here
|
||||
throw new IllegalArgumentException( "Unrecognized wrapper type class : " + wrapperClass.getName() );
|
||||
}
|
||||
|
||||
public static boolean isWrapper(Class<?> clazz) {
|
||||
try {
|
||||
getDescriptorByWrapperType( clazz );
|
||||
return true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -46,6 +46,7 @@ import org.jboss.jandex.Type;
|
|||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.internal.util.type.PrimitiveWrapperHelper;
|
||||
|
||||
/**
|
||||
* Utility methods for working with the jandex annotation index.
|
||||
|
@ -95,6 +96,10 @@ public class JandexHelper {
|
|||
);
|
||||
}
|
||||
|
||||
if ( type.isPrimitive() ) {
|
||||
type = PrimitiveWrapperHelper.getDescriptorByPrimitiveType( type ).getWrapperClass();
|
||||
}
|
||||
|
||||
// try getting the untyped value from Jandex
|
||||
AnnotationValue annotationValue = annotation.value( element );
|
||||
|
||||
|
@ -113,7 +118,8 @@ public class JandexHelper {
|
|||
element,
|
||||
annotation.name(),
|
||||
type.getName()
|
||||
)
|
||||
),
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,11 +23,15 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.source.annotations.util;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.AttributeOverride;
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Converter;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.LockModeType;
|
||||
import javax.persistence.NamedQuery;
|
||||
|
@ -42,6 +46,7 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.annotations.NamedNativeQuery;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
|
||||
|
@ -244,6 +249,36 @@ public class JandexHelperTest extends BaseUnitTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPrimitiveAnnotationAttributeTypes() {
|
||||
@Converter( autoApply = true )
|
||||
class MyConverter implements AttributeConverter<URL,String> {
|
||||
|
||||
@Override
|
||||
public String convertToDatabaseColumn(URL attribute) {
|
||||
return attribute.toExternalForm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL convertToEntityAttribute(String dbData) {
|
||||
try {
|
||||
return new URL( dbData );
|
||||
}
|
||||
catch (MalformedURLException e) {
|
||||
throw new HibernateException( "Could not convert string [" + dbData + "] to url", e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Index index = JandexHelper.indexForClass( classLoaderService, MyConverter.class );
|
||||
List<AnnotationInstance> annotationInstances = index.getAnnotations( JPADotNames.CONVERTER );
|
||||
assertTrue( annotationInstances.size() == 1 );
|
||||
AnnotationInstance annotationInstance = annotationInstances.get( 0 );
|
||||
|
||||
boolean value = JandexHelper.getValue( annotationInstance, "autoApply", boolean.class );
|
||||
Assert.assertTrue( value );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue