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 ) { if ( whereAnnotation != null ) {
// no null check needed, it is a required attribute // 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 entityClass.getClassInfo(), JPADotNames.TABLE
); );
if ( tableAnnotation != null ) { if ( tableAnnotation != null ) {
schemaName = JandexHelper.getValueAsString( tableAnnotation, "schema" ); schemaName = JandexHelper.getValue( tableAnnotation, "schema", String.class);
catalogName = JandexHelper.getValueAsString( tableAnnotation, "catalog" ); catalogName = JandexHelper.getValue( tableAnnotation, "catalog", String.class );
String explicitTableName = JandexHelper.getValueAsString( tableAnnotation, "name" ); String explicitTableName = JandexHelper.getValue( tableAnnotation, "name", String.class );
if ( StringHelper.isNotEmpty( explicitTableName ) ) { if ( StringHelper.isNotEmpty( explicitTableName ) ) {
tableName = meta.getNamingStrategy().tableName( 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; IdGenerator idGenerator = null;
if ( StringHelper.isNotEmpty( generator ) ) { if ( StringHelper.isNotEmpty( generator ) ) {
idGenerator = meta.getIdGenerator( generator ); idGenerator = meta.getIdGenerator( generator );

View File

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

View File

@ -57,25 +57,30 @@ public class FilterDefBinder {
bind( metadata, filterDef ); bind( metadata, filterDef );
} }
for ( AnnotationInstance filterDefs : jandex.getAnnotations( HibernateDotNames.FILTER_DEFS ) ) { 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 ); bind( metadata, filterDef );
} }
} }
} }
private static void bind(MetadataImplementor metadata, AnnotationInstance 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>(); 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( prms.put(
JandexHelper.getValueAsString( prm, "name" ), JandexHelper.getValue( prm, "name", String.class ),
metadata.getTypeResolver().heuristicType( JandexHelper.getValueAsString( prm, "type" ) ) metadata.getTypeResolver().heuristicType( JandexHelper.getValue( prm, "type", String.class ) )
); );
} }
metadata.addFilterDefinition( metadata.addFilterDefinition(
new FilterDefinition( new FilterDefinition(
name, name,
JandexHelper.getValueAsString( filterDef, "defaultCondition" ), JandexHelper.getValue( filterDef, "defaultCondition", String.class ),
prms prms
) )
); );

View File

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

View File

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

View File

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

View File

@ -57,33 +57,50 @@ public class TypeDefBinder {
bind( metadata, typeDef ); bind( metadata, typeDef );
} }
for ( AnnotationInstance typeDefs : jandex.getAnnotations( HibernateDotNames.TYPE_DEFS ) ) { 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 ); bind( metadata, typeDef );
} }
} }
} }
private static void bind(MetadataImplementor metadata, AnnotationInstance typeDef) { private static void bind(MetadataImplementor metadata, AnnotationInstance typeDefAnnotation) {
String name = JandexHelper.getValueAsString( typeDef, "name" ); String name = JandexHelper.getValue( typeDefAnnotation, "name", String.class );
String defaultForType = JandexHelper.getValueAsString( typeDef, "defaultForType" ); String defaultForType = JandexHelper.getValue( typeDefAnnotation, "defaultForType", String.class );
String typeClass = JandexHelper.getValueAsString( typeDef, "typeClass" ); String typeClass = JandexHelper.getValue( typeDefAnnotation, "typeClass", String.class );
boolean noName = StringHelper.isEmpty( name ); boolean noName = StringHelper.isEmpty( name );
boolean noDefaultForType = defaultForType == null || defaultForType.equals( void.class.getName() ); boolean noDefaultForType = defaultForType == null || defaultForType.equals( void.class.getName() );
if ( noName && noDefaultForType ) { if ( noName && noDefaultForType ) {
throw new AnnotationException( throw new AnnotationException(
"Either name or defaultForType (or both) attribute should be set in TypeDef having typeClass " "Either name or defaultForType (or both) attribute should be set in TypeDef having typeClass "
+ typeClass + typeClass
); );
} }
Map<String, String> prms = new HashMap<String, String>();
for ( AnnotationInstance prm : JandexHelper.getValueAsArray( typeDef, "parameters" ) ) { Map<String, String> parameterMaps = new HashMap<String, String>();
prms.put( JandexHelper.getValueAsString( prm, "name" ), JandexHelper.getValueAsString( prm, "value" ) ); 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 ) { if ( !noName ) {
bind( name, typeClass, prms, metadata ); bind( name, typeClass, parameterMaps, metadata );
} }
if ( !noDefaultForType ) { 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.beans.Introspector;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -40,6 +41,7 @@ import org.jboss.jandex.FieldInfo;
import org.jboss.jandex.Index; import org.jboss.jandex.Index;
import org.jboss.jandex.Indexer; import org.jboss.jandex.Indexer;
import org.jboss.jandex.MethodInfo; import org.jboss.jandex.MethodInfo;
import org.jboss.jandex.Type;
import org.hibernate.AnnotationException; import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
@ -52,27 +54,89 @@ import org.hibernate.service.classloading.spi.ClassLoaderService;
* @author Hardy Ferentschik * @author Hardy Ferentschik
*/ */
public class JandexHelper { 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 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(); * Retrieves a jandex annotation element value. If the value is {@code null}, the default value specified in the
String fqElement = name + '.' + element; * annotation class is retrieved instead.
Object val = DEFAULT_VALUES_BY_ELEMENT.get( fqElement ); * <p>
if ( val != null ) { * There are two special cases. {@code Class} parameters should be retrieved as strings (and then can later be
return val; * 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 { try {
val = Index.class.getClassLoader().loadClass( name ).getMethod( element ).getDefaultValue(); if ( annotationValue != null ) {
DEFAULT_VALUES_BY_ELEMENT.put( fqElement, val ); return explicitAnnotationParameter( annotationValue, type );
return val == null ? null : val; }
else {
return defaultAnnotationParameter( getDefaultValue( annotation, element ), type );
}
} }
catch ( RuntimeException error ) { catch ( ClassCastException e ) {
throw error; 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 * Creates a jandex index for the specified classes
* *
@ -334,4 +306,59 @@ public class JandexHelper {
private 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; 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.List;
import java.util.Map; import java.util.Map;
import javax.persistence.AttributeOverride;
import javax.persistence.Basic; import javax.persistence.Basic;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.LockModeType; import javax.persistence.LockModeType;
import javax.persistence.NamedQuery; import javax.persistence.NamedQuery;
import javax.persistence.SequenceGenerator;
import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.ClassInfo; import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName; import org.jboss.jandex.DotName;
import org.jboss.jandex.Index; import org.jboss.jandex.Index;
import org.junit.After; import org.junit.After;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; 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.metamodel.source.annotations.JPADotNames;
import org.hibernate.service.ServiceRegistryBuilder; import org.hibernate.service.ServiceRegistryBuilder;
import org.hibernate.service.classloading.spi.ClassLoaderService; import org.hibernate.service.classloading.spi.ClassLoaderService;
@ -50,8 +50,12 @@ import org.hibernate.service.internal.BasicServiceRegistryImpl;
import org.hibernate.testing.junit4.BaseUnitTestCase; import org.hibernate.testing.junit4.BaseUnitTestCase;
import static junit.framework.Assert.assertTrue; 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 * @author Hardy Ferentschik
*/ */
public class JandexHelperTest extends BaseUnitTestCase { public class JandexHelperTest extends BaseUnitTestCase {
@ -75,7 +79,6 @@ public class JandexHelperTest extends BaseUnitTestCase {
@Column @Column
@Basic @Basic
private String bar; private String bar;
private String fubar; private String fubar;
} }
Index index = JandexHelper.indexForClass( classLoaderService, Foo.class ); Index index = JandexHelper.indexForClass( classLoaderService, Foo.class );
@ -98,47 +101,122 @@ public class JandexHelperTest extends BaseUnitTestCase {
} }
@Test @Test
public void shouldRetrieveDefaultOfUnspecifiedAnnotationElement() { public void testGettingNestedAnnotation() {
@AttributeOverride(name = "foo", column = @Column(name = "FOO"))
@NamedQuery(name="foo", query="bar")
@SequenceGenerator(name="fu")
class Foo { class Foo {
} }
Index index = JandexHelper.indexForClass(classLoaderService, Foo.class); Index index = JandexHelper.indexForClass( classLoaderService, Foo.class );
for (AnnotationInstance query : index.getAnnotations( JPADotNames.NAMED_QUERY)) { List<AnnotationInstance> annotationInstances = index.getAnnotations( JPADotNames.ATTRIBUTE_OVERRIDE );
assertThat(JandexHelper.getValueAsEnum(query, "lockMode", LockModeType.class), is(LockModeType.NONE)); assertTrue( annotationInstances.size() == 1 );
} AnnotationInstance annotationInstance = annotationInstances.get( 0 );
for (AnnotationInstance generator : index.getAnnotations( JPADotNames.SEQUENCE_GENERATOR)) {
assertThat(JandexHelper.getValueAsInt(generator, "allocationSize"), is(50)); // 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 @Test(expected = AssertionFailure.class)
public void shouldRetrieveValueOfAnnotationElement() { public void testTryingToRetrieveWrongType() {
@AttributeOverride(name = "foo", column = @Column(name = "FOO"))
class Foo {
}
@NamedQuery(name="foo", query="bar") Index index = JandexHelper.indexForClass( classLoaderService, Foo.class );
class Foo { List<AnnotationInstance> annotationInstances = index.getAnnotations( JPADotNames.ATTRIBUTE_OVERRIDE );
} assertTrue( annotationInstances.size() == 1 );
AnnotationInstance annotationInstance = annotationInstances.get( 0 );
Index index = JandexHelper.indexForClass(classLoaderService, Foo.class); JandexHelper.getValue( annotationInstance, "name", Float.class );
for (AnnotationInstance query : index.getAnnotations( JPADotNames.NAMED_QUERY)) { }
assertThat(JandexHelper.getValueAsString(query, "name"), is("foo"));
}
}
@Test @Test
public void shouldRetrieveValueOfEnumeratedAnnotationElement() { public void testRetrieveDefaultEnumElement() {
@NamedQuery(name = "foo", query = "fubar")
class Foo {
}
@NamedQuery(name="foo", query="bar", lockMode=LockModeType.OPTIMISTIC) Index index = JandexHelper.indexForClass( classLoaderService, Foo.class );
class Foo { List<AnnotationInstance> annotationInstances = index.getAnnotations( JPADotNames.NAMED_QUERY );
} assertTrue( annotationInstances.size() == 1 );
AnnotationInstance annotationInstance = annotationInstances.get( 0 );
Index index = JandexHelper.indexForClass(classLoaderService, Foo.class); LockModeType lockMode = JandexHelper.getValueAsEnum( annotationInstance, "lockMode", LockModeType.class );
for (AnnotationInstance query : index.getAnnotations( JPADotNames.NAMED_QUERY)) { assertEquals( "Wrong lock mode", LockModeType.NONE, lockMode );
assertThat(JandexHelper.getValueAsEnum(query, "lockMode", LockModeType.class), is(LockModeType.OPTIMISTIC)); }
}
} @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 );
}
} }