HHH-6392 Starting to refactor JandexHelper

This commit is contained in:
Hardy Ferentschik 2011-07-08 18:57:06 +02:00
parent a353d34f78
commit 77004f5fe2
9 changed files with 362 additions and 215 deletions

View File

@ -206,7 +206,7 @@ public class EntityBinder {
);
if ( whereAnnotation != null ) {
// no null check needed, it is a required attribute
entityBindingState.setWhereFilter( JandexHelper.getValueAsString( whereAnnotation, "clause" ) );
entityBindingState.setWhereFilter( JandexHelper.getValue( whereAnnotation, "clause", String.class ) );
}
}
@ -409,9 +409,9 @@ public class EntityBinder {
entityClass.getClassInfo(), JPADotNames.TABLE
);
if ( tableAnnotation != null ) {
schemaName = JandexHelper.getValueAsString( tableAnnotation, "schema" );
catalogName = JandexHelper.getValueAsString( tableAnnotation, "catalog" );
String explicitTableName = JandexHelper.getValueAsString( tableAnnotation, "name" );
schemaName = JandexHelper.getValue( tableAnnotation, "schema", String.class);
catalogName = JandexHelper.getValue( tableAnnotation, "catalog", String.class );
String explicitTableName = JandexHelper.getValue( tableAnnotation, "name", String.class );
if ( StringHelper.isNotEmpty( explicitTableName ) ) {
tableName = meta.getNamingStrategy().tableName( explicitTableName );
}
@ -569,7 +569,7 @@ public class EntityBinder {
)
);
}
String generator = JandexHelper.getValueAsString( generatedValueAnn, "generator" );
String generator = JandexHelper.getValue( generatedValueAnn, "generator", String.class );
IdGenerator idGenerator = null;
if ( StringHelper.isNotEmpty( generator ) ) {
idGenerator = meta.getIdGenerator( generator );

View File

@ -57,29 +57,33 @@ public class FetchProfileBinder {
bind( metadata, fetchProfile );
}
for ( AnnotationInstance fetchProfiles : jandex.getAnnotations( HibernateDotNames.FETCH_PROFILES ) ) {
for ( AnnotationInstance fetchProfile : JandexHelper.getValueAsArray( fetchProfiles, "value" ) ) {
AnnotationInstance[] fetchProfileAnnotations = JandexHelper.getValue(
fetchProfiles,
"value",
AnnotationInstance[].class
);
for ( AnnotationInstance fetchProfile : fetchProfileAnnotations ) {
bind( metadata, fetchProfile );
}
}
}
private static void bind(MetadataImplementor metadata, AnnotationInstance fetchProfile) {
String name = JandexHelper.getValueAsString( fetchProfile, "name" );
String name = JandexHelper.getValue( fetchProfile, "name", String.class );
Set<Fetch> fetches = new HashSet<Fetch>();
for ( AnnotationInstance override : JandexHelper.getValueAsArray( fetchProfile, "fetchOverrides" ) ) {
AnnotationInstance[] overrideAnnotations = JandexHelper.getValue(
fetchProfile,
"fetchOverrides",
AnnotationInstance[].class
);
for ( AnnotationInstance override : overrideAnnotations ) {
FetchMode fetchMode = JandexHelper.getValueAsEnum( override, "mode", FetchMode.class );
if ( !fetchMode.equals( org.hibernate.annotations.FetchMode.JOIN ) ) {
throw new MappingException( "Only FetchMode.JOIN is currently supported" );
}
fetches.add(
new Fetch(
JandexHelper.getValueAsString( override, "entity" ), JandexHelper.getValueAsString(
override,
"association"
),
fetchMode.toString().toLowerCase()
)
);
String entityName = JandexHelper.getValue( override, "entity", String.class );
String associationName = JandexHelper.getValue( override, "association", String.class );
fetches.add( new Fetch( entityName, associationName, fetchMode.toString().toLowerCase() ) );
}
metadata.addFetchProfile( new FetchProfile( name, fetches ) );
}

View File

@ -57,25 +57,30 @@ public class FilterDefBinder {
bind( metadata, filterDef );
}
for ( AnnotationInstance filterDefs : jandex.getAnnotations( HibernateDotNames.FILTER_DEFS ) ) {
for ( AnnotationInstance filterDef : JandexHelper.getValueAsArray( filterDefs, "value" ) ) {
AnnotationInstance[] filterDefAnnotations = JandexHelper.getValue(
filterDefs,
"value",
AnnotationInstance[].class
);
for ( AnnotationInstance filterDef : filterDefAnnotations ) {
bind( metadata, filterDef );
}
}
}
private static void bind(MetadataImplementor metadata, AnnotationInstance filterDef) {
String name = JandexHelper.getValueAsString( filterDef, "name" );
String name = JandexHelper.getValue( filterDef, "name", String.class );
Map<String, Type> prms = new HashMap<String, Type>();
for ( AnnotationInstance prm : JandexHelper.getValueAsArray( filterDef, "parameters" ) ) {
for ( AnnotationInstance prm : JandexHelper.getValue( filterDef, "parameters", AnnotationInstance[].class ) ) {
prms.put(
JandexHelper.getValueAsString( prm, "name" ),
metadata.getTypeResolver().heuristicType( JandexHelper.getValueAsString( prm, "type" ) )
JandexHelper.getValue( prm, "name", String.class ),
metadata.getTypeResolver().heuristicType( JandexHelper.getValue( prm, "type", String.class ) )
);
}
metadata.addFilterDefinition(
new FilterDefinition(
name,
JandexHelper.getValueAsString( filterDef, "defaultCondition" ),
JandexHelper.getValue( filterDef, "defaultCondition", String.class ),
prms
)
);

View File

@ -23,10 +23,10 @@
*/
package org.hibernate.metamodel.source.annotations.global;
import javax.persistence.GenerationType;
import javax.persistence.SequenceGenerator;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.GenerationType;
import javax.persistence.SequenceGenerator;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.Index;
@ -64,7 +64,7 @@ public class IdGeneratorBinder {
String element,
Map<String, String> parameters,
String parameter) {
String string = JandexHelper.getValueAsString( annotation, element );
String string = JandexHelper.getValue( annotation, element, String.class );
if ( StringHelper.isNotEmpty( string ) ) {
parameters.put( parameter, string );
}
@ -88,30 +88,42 @@ public class IdGeneratorBinder {
bindGenericGenerator( metadata, generator );
}
for ( AnnotationInstance generators : jandex.getAnnotations( HibernateDotNames.GENERIC_GENERATORS ) ) {
for ( AnnotationInstance generator : JandexHelper.getValueAsArray( generators, "value" ) ) {
for ( AnnotationInstance generator : JandexHelper.getValue(
generators,
"value",
AnnotationInstance[].class
) ) {
bindGenericGenerator( metadata, generator );
}
}
}
private static void bindGenericGenerator(MetadataImplementor metadata, AnnotationInstance generator) {
String name = JandexHelper.getValueAsString( generator, "name" );
Map<String, String> prms = new HashMap<String, String>();
for ( AnnotationInstance prm : JandexHelper.getValueAsArray( generator, "parameters" ) ) {
prms.put( JandexHelper.getValueAsString( prm, "name" ), JandexHelper.getValueAsString( prm, "value" ) );
String name = JandexHelper.getValue( generator, "name", String.class );
Map<String, String> parameterMap = new HashMap<String, String>();
AnnotationInstance[] parameterAnnotations = JandexHelper.getValue(
generator,
"parameters",
AnnotationInstance[].class
);
for ( AnnotationInstance parameterAnnotation : parameterAnnotations ) {
parameterMap.put(
JandexHelper.getValue( parameterAnnotation, "name", String.class ),
JandexHelper.getValue( parameterAnnotation, "value", String.class )
);
}
metadata.addIdGenerator(
new IdGenerator(
name,
JandexHelper.getValueAsString( generator, "strategy" ),
prms
JandexHelper.getValue( generator, "strategy", String.class ),
parameterMap
)
);
LOG.tracef( "Add generic generator with name: %s", name );
}
private static void bindSequenceGenerator(MetadataImplementor metadata, AnnotationInstance generator) {
String name = JandexHelper.getValueAsString( generator, "name" );
String name = JandexHelper.getValue( generator, "name", String.class );
String strategy;
Map<String, String> prms = new HashMap<String, String>();
addStringParameter( generator, "sequenceName", prms, SequenceStyleGenerator.SEQUENCE_PARAM );
@ -122,20 +134,20 @@ public class IdGeneratorBinder {
addStringParameter( generator, "schema", prms, PersistentIdentifierGenerator.SCHEMA );
prms.put(
SequenceStyleGenerator.INCREMENT_PARAM,
String.valueOf( JandexHelper.getValueAsInt( generator, "allocationSize" ) )
String.valueOf( JandexHelper.getValue( generator, "allocationSize", Integer.class ) )
);
prms.put(
SequenceStyleGenerator.INITIAL_PARAM,
String.valueOf( JandexHelper.getValueAsInt( generator, "initialValue" ) )
String.valueOf( JandexHelper.getValue( generator, "initialValue", Integer.class ) )
);
}
else {
if ( JandexHelper.getValueAsInt( generator, "initialValue" ) != 1 ) {
if ( JandexHelper.getValue( generator, "initialValue", Integer.class ) != 1 ) {
LOG.unsupportedInitialValue( AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS );
}
prms.put(
SequenceHiLoGenerator.MAX_LO,
String.valueOf( JandexHelper.getValueAsInt( generator, "allocationSize" ) - 1 )
String.valueOf( JandexHelper.getValue( generator, "allocationSize", Integer.class ) - 1 )
);
}
metadata.addIdGenerator( new IdGenerator( name, strategy, prms ) );
@ -143,7 +155,7 @@ public class IdGeneratorBinder {
}
private static void bindTableGenerator(MetadataImplementor metadata, AnnotationInstance generator) {
String name = JandexHelper.getValueAsString( generator, "name" );
String name = JandexHelper.getValue( generator, "name", String.class );
String strategy;
Map<String, String> prms = new HashMap<String, String>();
addStringParameter( generator, "catalog", prms, PersistentIdentifierGenerator.CATALOG );
@ -158,11 +170,11 @@ public class IdGeneratorBinder {
addStringParameter( generator, "valueColumnName", prms, TableGenerator.VALUE_COLUMN_PARAM );
prms.put(
TableGenerator.INCREMENT_PARAM,
String.valueOf( JandexHelper.getValueAsInt( generator, "allocationSize" ) )
String.valueOf( JandexHelper.getValue( generator, "allocationSize", String.class ) )
);
prms.put(
TableGenerator.INITIAL_PARAM,
String.valueOf( JandexHelper.getValueAsInt( generator, "initialValue" ) + 1 )
String.valueOf( JandexHelper.getValue( generator, "initialValue", String.class ) + 1 )
);
}
else {
@ -172,10 +184,10 @@ public class IdGeneratorBinder {
addStringParameter( generator, "valueColumnName", prms, MultipleHiLoPerTableGenerator.VALUE_COLUMN_NAME );
prms.put(
TableHiLoGenerator.MAX_LO,
String.valueOf( JandexHelper.getValueAsInt( generator, "allocationSize" ) - 1 )
String.valueOf( JandexHelper.getValue( generator, "allocationSize", Integer.class ) - 1 )
);
}
if ( JandexHelper.getValueAsArray( generator, "uniqueConstraints" ).length > 0 ) {
if ( JandexHelper.getValue( generator, "uniqueConstraints", AnnotationInstance[].class ).length > 0 ) {
LOG.ignoringTableGeneratorConstraints( name );
}
metadata.addIdGenerator( new IdGenerator( name, strategy, prms ) );

View File

@ -74,7 +74,7 @@ public class QueryBinder {
bindNamedQuery( metadata, query );
}
for ( AnnotationInstance queries : jandex.getAnnotations( JPADotNames.NAMED_QUERIES ) ) {
for ( AnnotationInstance query : JandexHelper.getValueAsArray( queries, "value" ) ) {
for ( AnnotationInstance query : JandexHelper.getValue( queries, "value", AnnotationInstance[].class ) ) {
bindNamedQuery( metadata, query );
}
}
@ -82,7 +82,7 @@ public class QueryBinder {
bindNamedNativeQuery( metadata, query );
}
for ( AnnotationInstance queries : jandex.getAnnotations( JPADotNames.NAMED_NATIVE_QUERIES ) ) {
for ( AnnotationInstance query : JandexHelper.getValueAsArray( queries, "value" ) ) {
for ( AnnotationInstance query : JandexHelper.getValue( queries, "value", AnnotationInstance[].class ) ) {
bindNamedNativeQuery( metadata, query );
}
}
@ -90,7 +90,7 @@ public class QueryBinder {
bindNamedQuery( metadata, query );
}
for ( AnnotationInstance queries : jandex.getAnnotations( HibernateDotNames.NAMED_QUERIES ) ) {
for ( AnnotationInstance query : JandexHelper.getValueAsArray( queries, "value" ) ) {
for ( AnnotationInstance query : JandexHelper.getValue( queries, "value", AnnotationInstance[].class ) ) {
bindNamedQuery( metadata, query );
}
}
@ -98,7 +98,7 @@ public class QueryBinder {
bindNamedNativeQuery( metadata, query );
}
for ( AnnotationInstance queries : jandex.getAnnotations( HibernateDotNames.NAMED_NATIVE_QUERIES ) ) {
for ( AnnotationInstance query : JandexHelper.getValueAsArray( queries, "value" ) ) {
for ( AnnotationInstance query : JandexHelper.getValue( queries, "value", AnnotationInstance[].class ) ) {
bindNamedNativeQuery( metadata, query );
}
}
@ -111,14 +111,14 @@ public class QueryBinder {
* @param annotation the named query annotation
*/
private static void bindNamedQuery(MetadataImplementor metadata, AnnotationInstance annotation) {
String name = JandexHelper.getValueAsString( annotation, "name" );
String name = JandexHelper.getValue( annotation, "name", String.class );
if ( StringHelper.isEmpty( name ) ) {
throw new AnnotationException( "A named query must have a name when used in class or package level" );
}
String query = JandexHelper.getValueAsString( annotation, "query" );
String query = JandexHelper.getValue( annotation, "query", String.class );
AnnotationInstance[] hints = JandexHelper.getValueAsArray( annotation, "hints" );
AnnotationInstance[] hints = JandexHelper.getValue( annotation, "hints", AnnotationInstance[].class );
String cacheRegion = getString( hints, QueryHints.CACHE_REGION );
if ( StringHelper.isEmpty( cacheRegion ) ) {
@ -153,16 +153,16 @@ public class QueryBinder {
}
private static void bindNamedNativeQuery(MetadataImplementor metadata, AnnotationInstance annotation) {
String name = JandexHelper.getValueAsString( annotation, "name" );
String name = JandexHelper.getValue( annotation, "name", String.class );
if ( StringHelper.isEmpty( name ) ) {
throw new AnnotationException( "A named native query must have a name when used in class or package level" );
}
String query = JandexHelper.getValueAsString( annotation, "query" );
String query = JandexHelper.getValue( annotation, "query", String.class );
String resultSetMapping = JandexHelper.getValueAsString( annotation, "resultSetMapping" );
String resultSetMapping = JandexHelper.getValue( annotation, "resultSetMapping", String.class );
AnnotationInstance[] hints = JandexHelper.getValueAsArray( annotation, "hints" );
AnnotationInstance[] hints = JandexHelper.getValue( annotation, "hints", AnnotationInstance[].class );
boolean cacheable = getBoolean( hints, "org.hibernate.cacheable", name );
String cacheRegion = getString( hints, QueryHints.CACHE_REGION );
@ -309,8 +309,8 @@ public class QueryBinder {
private static String getString(AnnotationInstance[] hints, String element) {
for ( AnnotationInstance hint : hints ) {
if ( element.equals( JandexHelper.getValue( hint, "name" ) ) ) {
return JandexHelper.getValueAsString( hint, "value" );
if ( element.equals( JandexHelper.getValue( hint, "name", String.class ) ) ) {
return JandexHelper.getValue( hint, "value", String.class );
}
}
return null;

View File

@ -63,14 +63,14 @@ public class TableBinder {
bind( metadata, tableAnnotation );
}
for ( AnnotationInstance tables : jandex.getAnnotations( HibernateDotNames.TABLES ) ) {
for ( AnnotationInstance table : JandexHelper.getValueAsArray( tables, "value" ) ) {
for ( AnnotationInstance table : JandexHelper.getValue( tables, "value", AnnotationInstance[].class ) ) {
bind( metadata, table );
}
}
}
private static void bind(MetadataImplementor metadata, AnnotationInstance tableAnnotation) {
String tableName = JandexHelper.getValueAsString( tableAnnotation, "appliesTo" );
String tableName = JandexHelper.getValue( tableAnnotation, "appliesTo", String.class );
ObjectName objectName = new ObjectName( tableName );
Schema schema = metadata.getDatabase().getSchema( objectName.getSchema(), objectName.getCatalog() );
Table table = schema.getTable( objectName.getName() );
@ -80,18 +80,22 @@ public class TableBinder {
}
private static void bindHibernateTableAnnotation(Table table, AnnotationInstance tableAnnotation) {
for ( AnnotationInstance indexAnnotation : JandexHelper.getValueAsArray( tableAnnotation, "indexes" ) ) {
for ( AnnotationInstance indexAnnotation : JandexHelper.getValue(
tableAnnotation,
"indexes",
AnnotationInstance[].class
) ) {
bindIndexAnnotation( table, indexAnnotation );
}
String comment = JandexHelper.getValueAsString( tableAnnotation, "comment" );
String comment = JandexHelper.getValue( tableAnnotation, "comment", String.class );
if ( StringHelper.isNotEmpty( comment ) ) {
table.addComment( comment.trim() );
}
}
private static void bindIndexAnnotation(Table table, AnnotationInstance indexAnnotation) {
String indexName = JandexHelper.getValueAsString( indexAnnotation, "appliesTo" );
String[] columnNames = (String[]) JandexHelper.getValue( indexAnnotation, "columnNames" );
String indexName = JandexHelper.getValue( indexAnnotation, "appliesTo", String.class );
String[] columnNames = JandexHelper.getValue( indexAnnotation, "columnNames", String[].class );
if ( columnNames == null ) {
LOG.noColumnsSpecifiedForIndex( indexName, table.toLoggableString() );
return;

View File

@ -57,33 +57,50 @@ public class TypeDefBinder {
bind( metadata, typeDef );
}
for ( AnnotationInstance typeDefs : jandex.getAnnotations( HibernateDotNames.TYPE_DEFS ) ) {
for ( AnnotationInstance typeDef : JandexHelper.getValueAsArray( typeDefs, "value" ) ) {
AnnotationInstance[] typeDefAnnotations = JandexHelper.getValue(
typeDefs,
"value",
AnnotationInstance[].class
);
for ( AnnotationInstance typeDef : typeDefAnnotations ) {
bind( metadata, typeDef );
}
}
}
private static void bind(MetadataImplementor metadata, AnnotationInstance typeDef) {
String name = JandexHelper.getValueAsString( typeDef, "name" );
String defaultForType = JandexHelper.getValueAsString( typeDef, "defaultForType" );
String typeClass = JandexHelper.getValueAsString( typeDef, "typeClass" );
private static void bind(MetadataImplementor metadata, AnnotationInstance typeDefAnnotation) {
String name = JandexHelper.getValue( typeDefAnnotation, "name", String.class );
String defaultForType = JandexHelper.getValue( typeDefAnnotation, "defaultForType", String.class );
String typeClass = JandexHelper.getValue( typeDefAnnotation, "typeClass", String.class );
boolean noName = StringHelper.isEmpty( name );
boolean noDefaultForType = defaultForType == null || defaultForType.equals( void.class.getName() );
if ( noName && noDefaultForType ) {
throw new AnnotationException(
"Either name or defaultForType (or both) attribute should be set in TypeDef having typeClass "
+ typeClass
);
}
Map<String, String> prms = new HashMap<String, String>();
for ( AnnotationInstance prm : JandexHelper.getValueAsArray( typeDef, "parameters" ) ) {
prms.put( JandexHelper.getValueAsString( prm, "name" ), JandexHelper.getValueAsString( prm, "value" ) );
Map<String, String> parameterMaps = new HashMap<String, String>();
AnnotationInstance[] parameterAnnotations = JandexHelper.getValue(
typeDefAnnotation,
"parameters",
AnnotationInstance[].class
);
for ( AnnotationInstance parameterAnnotation : parameterAnnotations ) {
parameterMaps.put(
JandexHelper.getValue( parameterAnnotation, "name", String.class ),
JandexHelper.getValue( parameterAnnotation, "value", String.class )
);
}
if ( !noName ) {
bind( name, typeClass, prms, metadata );
bind( name, typeClass, parameterMaps, metadata );
}
if ( !noDefaultForType ) {
bind( defaultForType, typeClass, prms, metadata );
bind( defaultForType, typeClass, parameterMaps, metadata );
}
}

View File

@ -26,6 +26,7 @@ package org.hibernate.metamodel.source.annotations.util;
import java.beans.Introspector;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -40,6 +41,7 @@ import org.jboss.jandex.FieldInfo;
import org.jboss.jandex.Index;
import org.jboss.jandex.Indexer;
import org.jboss.jandex.MethodInfo;
import org.jboss.jandex.Type;
import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
@ -52,27 +54,89 @@ import org.hibernate.service.classloading.spi.ClassLoaderService;
* @author Hardy Ferentschik
*/
public class JandexHelper {
private static final AnnotationInstance[] EMPTY_ANNOTATIONS_ARRAY = new AnnotationInstance[0];
private static final Map<String, Object> DEFAULT_VALUES_BY_ELEMENT = new HashMap<String, Object>();
private static Object getDefaultValue(AnnotationInstance annotation, String element) {
String name = annotation.name().toString();
String fqElement = name + '.' + element;
Object val = DEFAULT_VALUES_BY_ELEMENT.get( fqElement );
if ( val != null ) {
return val;
/**
* Retrieves a jandex annotation element value. If the value is {@code null}, the default value specified in the
* annotation class is retrieved instead.
* <p>
* There are two special cases. {@code Class} parameters should be retrieved as strings (and then can later be
* loaded) and enumerated values should be retrieved via {@link #getValueAsEnum(AnnotationInstance, String, Class)}.
* </p>
*
* @param annotation the annotation containing the element with the supplied name
* @param element the name of the element value to be retrieve
* @param type the type of element to retrieve. The following types are supported:
* <ul>
* <li>Byte</li>
* <li>Short</li>
* <li>Integer</li>
* <li>Character</li>
* <li>Float</li>
* <li>Double</li>
* <li>Long</li>
* <li>Boolean</li>
* <li>String</li>
* <li>AnnotationInstance</li>
*
* @return the value if not {@code null}, else the default value if not
* {@code null}, else {@code null}.
*
* @throws AssertionFailure in case the specified {@code type} is a class instance or the specified type causes a {@code ClassCastException}
* when retrieving the value.
*/
@SuppressWarnings("unchecked")
public static <T> T getValue(AnnotationInstance annotation, String element, Class<T> type) throws AssertionFailure {
if ( Class.class.equals( type ) ) {
throw new AssertionFailure(
"Annotation parameters of type Class should be retrieved as strings (fully qualified class names)"
);
}
// try getting the untyped value from Jandex
AnnotationValue annotationValue = annotation.value( element );
try {
val = Index.class.getClassLoader().loadClass( name ).getMethod( element ).getDefaultValue();
DEFAULT_VALUES_BY_ELEMENT.put( fqElement, val );
return val == null ? null : val;
if ( annotationValue != null ) {
return explicitAnnotationParameter( annotationValue, type );
}
else {
return defaultAnnotationParameter( getDefaultValue( annotation, element ), type );
}
}
catch ( RuntimeException error ) {
throw error;
catch ( ClassCastException e ) {
throw new AssertionFailure(
String.format(
"the annotation property %s of annotation %s is not of type %s",
element,
annotation.name(),
type.getName()
)
);
}
catch ( Exception error ) {
throw new AnnotationException( error );
}
/**
* Retrieves a jandex annotation element value, converting it to the supplied enumerated type. If the value is
* <code>null</code>, the default value specified in the annotation class is retrieved instead.
*
* @param <T> an enumerated type
* @param annotation the annotation containing the enumerated element with the supplied name
* @param element the name of the enumerated element value to be retrieve
* @param type the type to which to convert the value before being returned
*
* @return the value converted to the supplied enumerated type if the value is not <code>null</code>, else the default value if
* not <code>null</code>, else <code>null</code>.
*
* @see #getValue(AnnotationInstance, String, Class)
*/
@SuppressWarnings("unchecked")
public static <T extends Enum<T>> T getValueAsEnum(AnnotationInstance annotation, String element, Class<T> type) {
AnnotationValue val = annotation.value( element );
if ( val == null ) {
return (T) getDefaultValue( annotation, element );
}
return Enum.valueOf( type, val.asEnum() );
}
/**
@ -149,98 +213,6 @@ public class JandexHelper {
}
}
/**
* Retrieves a jandex annotation element value. If the value is <code>null</code>, the default value specified in the
* annotation class is retrieved instead. Note, {@link #getValueAsEnum(AnnotationInstance, String, Class)} must be
* called to retrieve an enumerated value, and {@link #getValueAsArray(AnnotationInstance, String)} must be called to retrieve
* an object array (other than a String array).
*
* @param annotation the annotation containing the element with the supplied name
* @param element the name of the element value to be retrieve
*
* @return the value if not <code>null</code>, else the default value if not
* <code>null</code>, else <code>null</code>.
*/
public static Object getValue(AnnotationInstance annotation, String element) {
AnnotationValue val = annotation.value( element );
if ( val == null ) {
return getDefaultValue( annotation, element );
}
return val.asNested();
}
/**
* Retrieves a jandex annotation element array. Note, {@link #getValue(AnnotationInstance, String)} may be
* called to retrieve a String array (or a non-array value).
*
* @param annotation the jandex annotation containing the element with the supplied name
* @param element the name of the element array
*
* @return the element array if not <code>null</code>, else an empty array
*/
public static AnnotationInstance[] getValueAsArray(AnnotationInstance annotation, String element) {
AnnotationValue val = annotation.value( element );
return val == null ? EMPTY_ANNOTATIONS_ARRAY : val.asNestedArray();
}
/**
* Retrieves a jandex annotation element value, converting it to the supplied enumerated type. If the value is
* <code>null</code>, the default value specified in the annotation class is retrieved instead.
*
* @param <T> an enumerated type
* @param annotation the annotation containing the enumerated element with the supplied name
* @param element the name of the enumerated element value to be retrieve
* @param type the type to which to convert the value before being returned
*
* @return the value converted to the supplied enumerated type if the value is not <code>null</code>, else the default value if
* not <code>null</code>, else <code>null</code>.
*
* @see #getValue(AnnotationInstance, String)
*/
public static <T extends Enum<T>> T getValueAsEnum(AnnotationInstance annotation, String element, Class<T> type) {
AnnotationValue val = annotation.value( element );
if ( val == null ) {
return (T) getDefaultValue( annotation, element );
}
return Enum.valueOf( type, val.asEnum() );
}
/**
* Retrieves a jandex annotation element value as an Integer. If the value is <code>null</code>, the default value specified in
* the annotation class is retrieved instead.
*
* @param annotation the annotation containing the element with the supplied name
* @param element the name of the element value to be retrieve
*
* @return the value converted to an int if the value is not <code>null</code>, else the default value if not
* <code>null</code>, else <code>0</code>.
*/
public static int getValueAsInt(AnnotationInstance annotation, String element) {
AnnotationValue val = annotation.value( element );
if ( val == null ) {
return (Integer) getDefaultValue( annotation, element );
}
return val.asInt();
}
/**
* Retrieves a jandex annotation element value as a String. If the value is <code>null</code>, the default value specified in
* the annotation class is retrieved instead.
*
* @param annotation the annotation containing the element with the supplied name
* @param element the name of the element value to be retrieve
*
* @return the value converted to a String if the value is not <code>null</code>, else the default value if not
* <code>null</code>, else <code>null</code>.
*/
public static String getValueAsString(AnnotationInstance annotation, String element) {
AnnotationValue val = annotation.value( element );
if ( val == null ) {
return (String) getDefaultValue( annotation, element );
}
return val.asString();
}
/**
* Creates a jandex index for the specified classes
*
@ -334,4 +306,59 @@ public class JandexHelper {
private JandexHelper() {
}
private static Object getDefaultValue(AnnotationInstance annotation, String element) {
String name = annotation.name().toString();
String fqElement = name + '.' + element;
Object val = DEFAULT_VALUES_BY_ELEMENT.get( fqElement );
if ( val != null ) {
return val;
}
try {
val = Index.class.getClassLoader().loadClass( name ).getMethod( element ).getDefaultValue();
DEFAULT_VALUES_BY_ELEMENT.put( fqElement, val );
return val == null ? null : val;
}
catch ( RuntimeException error ) {
throw error;
}
catch ( Exception error ) {
throw new AnnotationException( error );
}
}
private static <T> T defaultAnnotationParameter(Object defaultValue, Class<T> type) {
Object returnValue = defaultValue;
// resolve some mismatches between what's stored in jandex and what the defaults are for annotations
// in case of nested annotation arrays, jandex returns arrays of AnnotationInstances, hence we return
// an empty array of this type here
if ( defaultValue.getClass().isArray() && defaultValue.getClass().getComponentType().isAnnotation() ) {
returnValue = new AnnotationInstance[0];
}
return type.cast( returnValue );
}
private static <T> T explicitAnnotationParameter(AnnotationValue annotationValue, Class<T> type) {
Object returnValue = annotationValue.value();
// if the jandex return type is Type we actually try to retrieve a class parameter
// for our purposes we just return the fqcn of the class
if ( returnValue instanceof Type ) {
returnValue = ( (Type) returnValue ).name().toString();
}
// arrays we have to handle explicitly
if ( type.isArray() ) {
AnnotationValue[] values = (AnnotationValue[]) returnValue;
Class<?> componentType = type.getComponentType();
Object[] arr = (Object[]) Array.newInstance( componentType, values.length );
for ( int i = 0; i < values.length; i++ ) {
arr[i] = componentType.cast( values[i].value() );
}
returnValue = arr;
}
return type.cast( returnValue );
}
}

View File

@ -23,26 +23,26 @@
*/
package org.hibernate.metamodel.source.annotations.util;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import java.util.List;
import java.util.Map;
import javax.persistence.AttributeOverride;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.LockModeType;
import javax.persistence.NamedQuery;
import javax.persistence.SequenceGenerator;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.Index;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.AssertionFailure;
import org.hibernate.annotations.NamedNativeQuery;
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.service.ServiceRegistryBuilder;
import org.hibernate.service.classloading.spi.ClassLoaderService;
@ -50,8 +50,12 @@ import org.hibernate.service.internal.BasicServiceRegistryImpl;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* Tests for the helper class {@link JandexHelper}.
*
* @author Hardy Ferentschik
*/
public class JandexHelperTest extends BaseUnitTestCase {
@ -75,7 +79,6 @@ public class JandexHelperTest extends BaseUnitTestCase {
@Column
@Basic
private String bar;
private String fubar;
}
Index index = JandexHelper.indexForClass( classLoaderService, Foo.class );
@ -98,47 +101,122 @@ public class JandexHelperTest extends BaseUnitTestCase {
}
@Test
public void shouldRetrieveDefaultOfUnspecifiedAnnotationElement() {
@NamedQuery(name="foo", query="bar")
@SequenceGenerator(name="fu")
public void testGettingNestedAnnotation() {
@AttributeOverride(name = "foo", column = @Column(name = "FOO"))
class Foo {
}
Index index = JandexHelper.indexForClass(classLoaderService, Foo.class);
for (AnnotationInstance query : index.getAnnotations( JPADotNames.NAMED_QUERY)) {
assertThat(JandexHelper.getValueAsEnum(query, "lockMode", LockModeType.class), is(LockModeType.NONE));
}
for (AnnotationInstance generator : index.getAnnotations( JPADotNames.SEQUENCE_GENERATOR)) {
assertThat(JandexHelper.getValueAsInt(generator, "allocationSize"), is(50));
}
Index index = JandexHelper.indexForClass( classLoaderService, Foo.class );
List<AnnotationInstance> annotationInstances = index.getAnnotations( JPADotNames.ATTRIBUTE_OVERRIDE );
assertTrue( annotationInstances.size() == 1 );
AnnotationInstance annotationInstance = annotationInstances.get( 0 );
// try to retrieve the name
String name = JandexHelper.getValue( annotationInstance, "name", String.class );
assertEquals( "Wrong nested annotation", "foo", name );
// try to retrieve the nested column annotation instance
AnnotationInstance columnAnnotationInstance = JandexHelper.getValue(
annotationInstance,
"column",
AnnotationInstance.class
);
assertNotNull( columnAnnotationInstance );
assertEquals(
"Wrong nested annotation",
"javax.persistence.Column",
columnAnnotationInstance.name().toString()
);
}
@Test
public void shouldRetrieveValueOfAnnotationElement() {
@Test(expected = AssertionFailure.class)
public void testTryingToRetrieveWrongType() {
@AttributeOverride(name = "foo", column = @Column(name = "FOO"))
class Foo {
}
@NamedQuery(name="foo", query="bar")
class Foo {
}
Index index = JandexHelper.indexForClass( classLoaderService, Foo.class );
List<AnnotationInstance> annotationInstances = index.getAnnotations( JPADotNames.ATTRIBUTE_OVERRIDE );
assertTrue( annotationInstances.size() == 1 );
AnnotationInstance annotationInstance = annotationInstances.get( 0 );
Index index = JandexHelper.indexForClass(classLoaderService, Foo.class);
for (AnnotationInstance query : index.getAnnotations( JPADotNames.NAMED_QUERY)) {
assertThat(JandexHelper.getValueAsString(query, "name"), is("foo"));
}
}
JandexHelper.getValue( annotationInstance, "name", Float.class );
}
@Test
public void shouldRetrieveValueOfEnumeratedAnnotationElement() {
@Test
public void testRetrieveDefaultEnumElement() {
@NamedQuery(name = "foo", query = "fubar")
class Foo {
}
@NamedQuery(name="foo", query="bar", lockMode=LockModeType.OPTIMISTIC)
class Foo {
}
Index index = JandexHelper.indexForClass( classLoaderService, Foo.class );
List<AnnotationInstance> annotationInstances = index.getAnnotations( JPADotNames.NAMED_QUERY );
assertTrue( annotationInstances.size() == 1 );
AnnotationInstance annotationInstance = annotationInstances.get( 0 );
Index index = JandexHelper.indexForClass(classLoaderService, Foo.class);
for (AnnotationInstance query : index.getAnnotations( JPADotNames.NAMED_QUERY)) {
assertThat(JandexHelper.getValueAsEnum(query, "lockMode", LockModeType.class), is(LockModeType.OPTIMISTIC));
}
}
LockModeType lockMode = JandexHelper.getValueAsEnum( annotationInstance, "lockMode", LockModeType.class );
assertEquals( "Wrong lock mode", LockModeType.NONE, lockMode );
}
@Test
public void testRetrieveExplicitEnumElement() {
@NamedQuery(name = "foo", query = "bar", lockMode = LockModeType.OPTIMISTIC)
class Foo {
}
Index index = JandexHelper.indexForClass( classLoaderService, Foo.class );
List<AnnotationInstance> annotationInstances = index.getAnnotations( JPADotNames.NAMED_QUERY );
assertTrue( annotationInstances.size() == 1 );
AnnotationInstance annotationInstance = annotationInstances.get( 0 );
LockModeType lockMode = JandexHelper.getValueAsEnum( annotationInstance, "lockMode", LockModeType.class );
assertEquals( "Wrong lock mode", LockModeType.OPTIMISTIC, lockMode );
}
@Test
public void testRetrieveStringArray() {
class Foo {
@org.hibernate.annotations.Index(name = "index", columnNames = { "a", "b", "c" })
private String foo;
}
Index index = JandexHelper.indexForClass( classLoaderService, Foo.class );
List<AnnotationInstance> annotationInstances = index.getAnnotations( HibernateDotNames.INDEX );
assertTrue( annotationInstances.size() == 1 );
AnnotationInstance annotationInstance = annotationInstances.get( 0 );
String[] columnNames = JandexHelper.getValue( annotationInstance, "columnNames", String[].class );
Assert.assertTrue( columnNames.length == 3 );
}
@Test(expected = AssertionFailure.class)
public void testRetrieveClassParameterAsClass() {
@NamedNativeQuery(name = "foo", query = "bar", resultClass = Foo.class)
class Foo {
}
Index index = JandexHelper.indexForClass( classLoaderService, Foo.class );
List<AnnotationInstance> annotationInstances = index.getAnnotations( HibernateDotNames.NAMED_NATIVE_QUERY );
assertTrue( annotationInstances.size() == 1 );
AnnotationInstance annotationInstance = annotationInstances.get( 0 );
JandexHelper.getValue( annotationInstance, "resultClass", Class.class );
}
@Test
public void testRetrieveClassParameterAsString() {
@NamedNativeQuery(name = "foo", query = "bar", resultClass = Foo.class)
class Foo {
}
Index index = JandexHelper.indexForClass( classLoaderService, Foo.class );
List<AnnotationInstance> annotationInstances = index.getAnnotations( HibernateDotNames.NAMED_NATIVE_QUERY );
assertTrue( annotationInstances.size() == 1 );
AnnotationInstance annotationInstance = annotationInstances.get( 0 );
String fqcn = JandexHelper.getValue( annotationInstance, "resultClass", String.class );
assertEquals( "Wrong class names", Foo.class.getName(), fqcn );
}
}