diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationBindingContext.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationBindingContext.java index 415edfc014..71d0a75209 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationBindingContext.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationBindingContext.java @@ -70,7 +70,6 @@ public interface AnnotationBindingContext extends BindingContext { */ MemberResolver getMemberResolver(); - Iterable extractIdentifierGeneratorSources(IdentifierGeneratorSourceContainer container); IdentifierGeneratorDefinition findIdGenerator(String name); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationBindingContextImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationBindingContextImpl.java index 97fa8aa85b..889113aca2 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationBindingContextImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationBindingContextImpl.java @@ -55,8 +55,6 @@ public class AnnotationBindingContextImpl implements AnnotationBindingContext { private final ValueHolder classLoaderService; private final IndexView index; - private final IdentifierGeneratorExtractionDelegate identifierGeneratorSourceCreationDelegate; - /** * Constructor * @@ -76,9 +74,6 @@ public class AnnotationBindingContextImpl implements AnnotationBindingContext { } ); this.index = index; - this.identifierGeneratorSourceCreationDelegate = new IdentifierGeneratorExtractionDelegate( - metadata.getOptions().useNewIdentifierGenerators() - ); } @Override @@ -102,11 +97,6 @@ public class AnnotationBindingContextImpl implements AnnotationBindingContext { return TYPE_RESOLVER; } - @Override - public Iterable extractIdentifierGeneratorSources(IdentifierGeneratorSourceContainer container) { - return identifierGeneratorSourceCreationDelegate.extractIdentifierGeneratorSources( container ); - } - @Override public IdentifierGeneratorDefinition findIdGenerator(String name) { return getMetadataImplementor().getIdGenerator( name ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationMetadataSourceProcessorImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationMetadataSourceProcessorImpl.java index 248184fc99..2b647bb7d3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationMetadataSourceProcessorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationMetadataSourceProcessorImpl.java @@ -24,6 +24,7 @@ package org.hibernate.metamodel.internal.source.annotations; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -36,6 +37,7 @@ import org.hibernate.AssertionFailure; import org.hibernate.metamodel.MetadataSources; import org.hibernate.metamodel.internal.MetadataImpl; import org.hibernate.metamodel.internal.source.annotations.global.FetchProfileProcessor; +import org.hibernate.metamodel.internal.source.annotations.global.IdGeneratorProcessor; import org.hibernate.metamodel.internal.source.annotations.global.QueryProcessor; import org.hibernate.metamodel.internal.source.annotations.global.SqlResultSetProcessor; import org.hibernate.metamodel.internal.source.annotations.global.TableProcessor; @@ -73,80 +75,44 @@ public class AnnotationMetadataSourceProcessorImpl implements MetadataSourceProc metadata.setGloballyQuotedIdentifiers( true ); } - bindingContext = new AnnotationBindingContextImpl( metadata, jandexView ); + this.bindingContext = new AnnotationBindingContextImpl( metadata, jandexView ); } @Override public Iterable extractTypeDefinitionSources() { - assertBindingContextExists(); - List typeDescriptorSources = new ArrayList(); - Collection annotations = bindingContext.getIndex().getAnnotations( HibernateDotNames.TYPE_DEF ); + Collection annotations = JandexHelper.getAnnotations( + bindingContext.getIndex(), + HibernateDotNames.TYPE_DEF, + HibernateDotNames.TYPE_DEFS + ); for ( AnnotationInstance typeDef : annotations ) { typeDescriptorSources.add( new TypeDescriptorSourceImpl( typeDef ) ); } - - annotations = bindingContext.getIndex().getAnnotations( HibernateDotNames.TYPE_DEFS ); - for ( AnnotationInstance typeDefs : annotations ) { - AnnotationInstance[] typeDefAnnotations = JandexHelper.getValue( - typeDefs, - "value", - AnnotationInstance[].class - ); - for ( AnnotationInstance typeDef : typeDefAnnotations ) { - typeDescriptorSources.add( new TypeDescriptorSourceImpl( typeDef ) ); - } - } return typeDescriptorSources; } - private void assertBindingContextExists() { - if ( bindingContext == null ) { - throw new AssertionFailure( "The binding context should exist. Has prepare been called!?" ); - } - } - @Override public Iterable extractFilterDefinitionSources() { - assertBindingContextExists(); - List filterDefinitionSources = new ArrayList(); - Collection annotations = bindingContext.getIndex().getAnnotations( HibernateDotNames.FILTER_DEF ); + Collection annotations = JandexHelper.getAnnotations( + bindingContext.getIndex(), + HibernateDotNames.FILTER_DEF, + HibernateDotNames.FILTER_DEFS + ); for ( AnnotationInstance filterDef : annotations ) { filterDefinitionSources.add( new FilterDefinitionSourceImpl( filterDef ) ); } - - annotations = bindingContext.getIndex().getAnnotations( HibernateDotNames.FILTER_DEFS ); - for ( AnnotationInstance filterDefs : annotations ) { - AnnotationInstance[] filterDefAnnotations = JandexHelper.getValue( - filterDefs, - "value", - AnnotationInstance[].class - ); - for ( AnnotationInstance filterDef : filterDefAnnotations ) { - filterDefinitionSources.add( new FilterDefinitionSourceImpl( filterDef ) ); - } - } return filterDefinitionSources; } @Override public Iterable extractGlobalIdentifierGeneratorSources() { - assertBindingContextExists(); - - return bindingContext.extractIdentifierGeneratorSources( - new IdentifierGeneratorSourceContainerImpl() { - @Override - protected Collection getAnnotations(DotName name) { - return bindingContext.getIndex().getAnnotations( name ); - } - } - ); + return IdGeneratorProcessor.extractGlobalIdentifierGeneratorSources( bindingContext ); } @Override public Iterable extractEntityHierarchies() { - assertBindingContextExists(); // need to order our annotated entities into an order we can process return EntityHierarchyBuilder.createEntityHierarchies( bindingContext ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/IdentifierGeneratorExtractionDelegate.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/IdentifierGeneratorExtractionDelegate.java deleted file mode 100644 index 430194ce5b..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/IdentifierGeneratorExtractionDelegate.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2012, 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.metamodel.internal.source.annotations; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.persistence.GenerationType; - -import org.jboss.jandex.AnnotationInstance; -import org.jboss.logging.Logger; - -import org.hibernate.cfg.AvailableSettings; -import org.hibernate.id.MultipleHiLoPerTableGenerator; -import org.hibernate.id.PersistentIdentifierGenerator; -import org.hibernate.id.SequenceHiLoGenerator; -import org.hibernate.id.TableHiLoGenerator; -import org.hibernate.id.enhanced.SequenceStyleGenerator; -import org.hibernate.id.enhanced.TableGenerator; -import org.hibernate.internal.CoreMessageLogger; -import org.hibernate.internal.util.StringHelper; -import org.hibernate.metamodel.internal.source.annotations.util.EnumConversionHelper; -import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper; -import org.hibernate.metamodel.spi.source.IdentifierGeneratorSource; - -/** - * @author Steve Ebersole - */ -public class IdentifierGeneratorExtractionDelegate { - - private static final CoreMessageLogger LOG = Logger.getMessageLogger( - CoreMessageLogger.class, - IdentifierGeneratorExtractionDelegate.class.getName() - ); - - private final boolean useNewIdentifierGenerators; - - public IdentifierGeneratorExtractionDelegate(boolean useNewIdentifierGenerators) { - this.useNewIdentifierGenerators = useNewIdentifierGenerators; - } - - public Iterable extractIdentifierGeneratorSources(IdentifierGeneratorSourceContainer container) { - List identifierGeneratorSources = new ArrayList(); - processIdentifierGeneratorSources( identifierGeneratorSources, container ); - return identifierGeneratorSources; - } - - private void processIdentifierGeneratorSources( - List identifierGeneratorSources, - IdentifierGeneratorSourceContainer identifierGeneratorSourceContainer) { - - processSequenceGenerators( - identifierGeneratorSources, - identifierGeneratorSourceContainer.getSequenceGeneratorSources() - ); - - processTableGenerators( - identifierGeneratorSources, - identifierGeneratorSourceContainer.getTableGeneratorSources() - ); - - processGenericGenerators( - identifierGeneratorSources, - identifierGeneratorSourceContainer.getGenericGeneratorSources() - ); - } - - private void processSequenceGenerators( - List identifierGeneratorSources, - Collection generatorAnnotations) { - for ( AnnotationInstance generatorAnnotation : generatorAnnotations ) { - final String generatorName = JandexHelper.getValue( generatorAnnotation, "name", String.class ); - - final String generatorImplementationName = EnumConversionHelper.generationTypeToGeneratorStrategyName( - GenerationType.SEQUENCE, - useNewIdentifierGenerators - ); - - Map parameterMap = new HashMap(); - final String sequenceName = JandexHelper.getValue( generatorAnnotation, "sequenceName", String.class ); - if ( StringHelper.isNotEmpty( sequenceName ) ) { - parameterMap.put( SequenceStyleGenerator.SEQUENCE_PARAM, sequenceName ); - } - - if ( useNewIdentifierGenerators ) { - final String catalog = JandexHelper.getValue( generatorAnnotation, "catalog", String.class ); - if ( StringHelper.isNotEmpty( catalog ) ) { - parameterMap.put( PersistentIdentifierGenerator.CATALOG, catalog ); - } - final String schema = JandexHelper.getValue( generatorAnnotation, "schema", String.class ); - if ( StringHelper.isNotEmpty( schema ) ) { - parameterMap.put( PersistentIdentifierGenerator.SCHEMA, schema ); - } - parameterMap.put( - SequenceStyleGenerator.INCREMENT_PARAM, - String.valueOf( JandexHelper.getValue( generatorAnnotation, "allocationSize", Integer.class ) ) - ); - parameterMap.put( - SequenceStyleGenerator.INITIAL_PARAM, - String.valueOf( JandexHelper.getValue( generatorAnnotation, "initialValue", Integer.class ) ) - ); - } - else { - if ( JandexHelper.getValue( generatorAnnotation, "initialValue", Integer.class ) != 1 ) { - LOG.unsupportedInitialValue( AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS ); - } - parameterMap.put( - SequenceHiLoGenerator.MAX_LO, - String.valueOf( JandexHelper.getValue( generatorAnnotation, "allocationSize", Integer.class ) - 1 ) - ); - } - - identifierGeneratorSources.add( - new IdentifierGeneratorSourceImpl( generatorName, generatorImplementationName, parameterMap ) - ); - } - } - - private void processTableGenerators( - List identifierGeneratorSources, - Collection annotations) { - for ( AnnotationInstance generatorAnnotation : annotations ) { - final String generatorName = JandexHelper.getValue( generatorAnnotation, "name", String.class ); - - final String generatorImplementationName = EnumConversionHelper.generationTypeToGeneratorStrategyName( - GenerationType.TABLE, - useNewIdentifierGenerators - ); - - Map parameterMap = new HashMap(); - final String catalog = JandexHelper.getValue( generatorAnnotation, "catalog", String.class ); - if ( StringHelper.isNotEmpty( catalog ) ) { - parameterMap.put( PersistentIdentifierGenerator.CATALOG, catalog ); - } - final String schema = JandexHelper.getValue( generatorAnnotation, "schema", String.class ); - if ( StringHelper.isNotEmpty( schema ) ) { - parameterMap.put( PersistentIdentifierGenerator.SCHEMA, schema ); - } - - if ( useNewIdentifierGenerators ) { - parameterMap.put( TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY, "true" ); - final String tableName = JandexHelper.getValue( generatorAnnotation, "table", String.class ); - if ( StringHelper.isNotEmpty( tableName ) ) { - parameterMap.put( TableGenerator.TABLE_PARAM, tableName ); - } - - final String segmentColumnName = JandexHelper.getValue( - generatorAnnotation, - "pkColumnName", - String.class - ); - if ( StringHelper.isNotEmpty( segmentColumnName ) ) { - parameterMap.put( TableGenerator.SEGMENT_COLUMN_PARAM, segmentColumnName ); - } - - final String segmentColumnValue = JandexHelper.getValue( generatorAnnotation, "pkColumnValue", String.class ); - if ( StringHelper.isNotEmpty( segmentColumnValue ) ) { - parameterMap.put( TableGenerator.SEGMENT_VALUE_PARAM, segmentColumnValue ); - } - - final String valueColumnName = JandexHelper.getValue( generatorAnnotation, "valueColumnName", String.class ); - if ( StringHelper.isNotEmpty( valueColumnName ) ) { - parameterMap.put( TableGenerator.VALUE_COLUMN_PARAM, valueColumnName ); - } - - parameterMap.put( - TableGenerator.INCREMENT_PARAM, - String.valueOf( JandexHelper.getValue( generatorAnnotation, "allocationSize", Integer.class ) ) - ); - - parameterMap.put( - TableGenerator.INITIAL_PARAM, - String.valueOf( JandexHelper.getValue( generatorAnnotation, "initialValue", Integer.class ) + 1 ) - ); - } - else { - final String tableName = JandexHelper.getValue( generatorAnnotation, "table", String.class ); - if ( StringHelper.isNotEmpty( tableName ) ) { - parameterMap.put( MultipleHiLoPerTableGenerator.ID_TABLE, tableName ); - } - - final String segmentColumnName = JandexHelper.getValue( generatorAnnotation, "pkColumnName", String.class ); - if ( StringHelper.isNotEmpty( segmentColumnName ) ) { - parameterMap.put( MultipleHiLoPerTableGenerator.PK_COLUMN_NAME, segmentColumnName ); - } - - final String segmentColumnValue = JandexHelper.getValue( generatorAnnotation, "pkColumnValue", String.class ); - if ( StringHelper.isNotEmpty( segmentColumnValue ) ) { - parameterMap.put( MultipleHiLoPerTableGenerator.PK_VALUE_NAME, segmentColumnValue ); - } - - final String valueColumnName = JandexHelper.getValue( generatorAnnotation, "valueColumnName", String.class ); - if ( StringHelper.isNotEmpty( valueColumnName ) ) { - parameterMap.put( MultipleHiLoPerTableGenerator.VALUE_COLUMN_NAME, valueColumnName ); - } - - parameterMap.put( - TableHiLoGenerator.MAX_LO, - String.valueOf( JandexHelper.getValue( generatorAnnotation, "allocationSize", Integer.class ) - 1 ) - ); - } - - if ( JandexHelper.getValue( generatorAnnotation, "uniqueConstraints", AnnotationInstance[].class ).length > 0 ) { - LOG.ignoringTableGeneratorConstraints( generatorName ); - } - - identifierGeneratorSources.add( - new IdentifierGeneratorSourceImpl( generatorName, generatorImplementationName, parameterMap ) - ); - } - } - - private void processGenericGenerators( - List identifierGeneratorSources, - Collection genericGeneratorSources) { - for ( AnnotationInstance generatorAnnotation : genericGeneratorSources ) { - Map parameterMap = new HashMap(); - AnnotationInstance[] parameterAnnotations = JandexHelper.getValue( - generatorAnnotation, - "parameters", - AnnotationInstance[].class - ); - for ( AnnotationInstance parameterAnnotation : parameterAnnotations ) { - parameterMap.put( - JandexHelper.getValue( parameterAnnotation, "name", String.class ), - JandexHelper.getValue( parameterAnnotation, "value", String.class ) - ); - } - - identifierGeneratorSources.add( - new IdentifierGeneratorSourceImpl( - JandexHelper.getValue( generatorAnnotation, "name", String.class ), - JandexHelper.getValue( generatorAnnotation, "strategy", String.class ), - parameterMap - ) - ); - } - } - - private static class IdentifierGeneratorSourceImpl implements IdentifierGeneratorSource { - private final String generatorName; - private final String generatorImplementationName; - private final Map parameterMap; - - public IdentifierGeneratorSourceImpl( - String generatorName, - String generatorImplementationName, - Map parameterMap) { - this.generatorName = generatorName; - this.generatorImplementationName = generatorImplementationName; - this.parameterMap = parameterMap; - } - - @Override - public String getGeneratorName() { - return generatorName; - } - - @Override - public String getGeneratorImplementationName() { - return generatorImplementationName; - } - - @Override - public Map getParameters() { - return parameterMap; - } - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java index a222a3f1cb..42b1bcec7c 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java @@ -25,6 +25,7 @@ package org.hibernate.metamodel.internal.source.annotations.attribute; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -457,35 +458,23 @@ public class AssociationAttribute extends MappedAttribute { } private void determineJoinColumnAnnotations(Map> annotations) { - // single @JoinColumn - AnnotationInstance joinColumnAnnotation = JandexHelper.getSingleAnnotation( + Collection joinColumnAnnotations = JandexHelper.getAnnotations( annotations, - JPADotNames.JOIN_COLUMN + JPADotNames.JOIN_COLUMN, + JPADotNames.JOIN_COLUMNS, + true ); - if ( joinColumnAnnotation != null ) { + for ( AnnotationInstance joinColumnAnnotation : joinColumnAnnotations ) { joinColumnValues.add( new Column( joinColumnAnnotation ) ); } - // @JoinColumns - AnnotationInstance joinColumnsAnnotation = JandexHelper.getSingleAnnotation( - annotations, - JPADotNames.JOIN_COLUMNS - ); - if ( joinColumnsAnnotation != null ) { - List columnsList = Arrays.asList( - JandexHelper.getValue( joinColumnsAnnotation, "value", AnnotationInstance[].class ) - ); - for ( AnnotationInstance annotation : columnsList ) { - joinColumnValues.add( new Column( annotation ) ); - } - } // @JoinColumn as part of @CollectionTable AnnotationInstance collectionTableAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.COLLECTION_TABLE ); - if(collectionTableAnnotation != null) { + if ( collectionTableAnnotation != null ) { List columnsList = Arrays.asList( JandexHelper.getValue( collectionTableAnnotation, "joinColumns", AnnotationInstance[].class ) ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java index 598228ecfc..fa767413ad 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java @@ -98,7 +98,6 @@ public class BasicAttribute extends MappedAttribute { private final String customWriteFragment; private final String customReadFragment; - private final Map localIdentifierGeneratorDefinitionMap; private AttributeTypeResolver resolver; public static BasicAttribute createSimpleAttribute( @@ -135,7 +134,6 @@ public class BasicAttribute extends MappedAttribute { } if ( isId() ) { - localIdentifierGeneratorDefinitionMap = buildAttributeLocalIdentifierGeneratorDefinitions(); // an id must be unique and cannot be nullable for ( Column columnValue : getColumnValues() ) { columnValue.setUnique( true ); @@ -144,7 +142,6 @@ public class BasicAttribute extends MappedAttribute { identifierGeneratorDefinition = checkGeneratedValueAnnotation(); } else { - localIdentifierGeneratorDefinitionMap = Collections.EMPTY_MAP; identifierGeneratorDefinition = null; } @@ -334,7 +331,7 @@ public class BasicAttribute extends MappedAttribute { IdentifierGeneratorDefinition generator = null; String name = JandexHelper.getValue( generatedValueAnnotation, "generator", String.class ); if ( StringHelper.isNotEmpty( name ) ) { - generator = locateIdentifierGeneratorDefinition( name ); + generator = getContext().findIdGenerator( name ); if ( generator == null ) { throw new MappingException( String.format( "Unable to find named generator %s", getRole() ), getContext().getOrigin() ); } @@ -350,42 +347,6 @@ public class BasicAttribute extends MappedAttribute { return generator; } - protected IdentifierGeneratorDefinition locateIdentifierGeneratorDefinition(String name) { - // look locally first - IdentifierGeneratorDefinition generator = localIdentifierGeneratorDefinitionMap.get( name ); - - if ( generator == null ) { - // if not found locally, look "upward" - generator = getContext().findIdGenerator( name ); - } - - return generator; - } - - protected Map buildAttributeLocalIdentifierGeneratorDefinitions() { - Iterable identifierGeneratorSources = getContext().extractIdentifierGeneratorSources( - new IdentifierGeneratorSourceContainerImpl() { - @Override - protected Collection getAnnotations(DotName name) { - return annotations().get( name ); - } - } - ); - - Map map = new HashMap(); - for ( IdentifierGeneratorSource source : identifierGeneratorSources ) { - map.put( - source.getGeneratorName(), - new IdentifierGeneratorDefinition( - source.getGeneratorName(), - source.getGeneratorImplementationName(), - source.getParameters() - ) - ); - } - return map; - } - @Override public AttributeTypeResolver getHibernateTypeResolver() { if ( resolver == null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityBindingContext.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityBindingContext.java index 305681764c..29ffe4e187 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityBindingContext.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityBindingContext.java @@ -23,15 +23,9 @@ */ package org.hibernate.metamodel.internal.source.annotations.entity; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - import com.fasterxml.classmate.MemberResolver; import com.fasterxml.classmate.TypeResolver; -import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.ClassInfo; -import org.jboss.jandex.DotName; import org.jboss.jandex.IndexView; import org.hibernate.cfg.NamingStrategy; @@ -40,7 +34,6 @@ import org.hibernate.jaxb.spi.Origin; import org.hibernate.jaxb.spi.SourceType; import org.hibernate.metamodel.internal.source.annotations.AnnotationBindingContext; import org.hibernate.metamodel.internal.source.annotations.IdentifierGeneratorSourceContainer; -import org.hibernate.metamodel.internal.source.annotations.IdentifierGeneratorSourceContainerImpl; import org.hibernate.metamodel.spi.MetadataImplementor; import org.hibernate.metamodel.spi.binding.IdentifierGeneratorDefinition; import org.hibernate.metamodel.spi.domain.Type; @@ -59,35 +52,9 @@ public class EntityBindingContext implements LocalBindingContext, AnnotationBind private final AnnotationBindingContext contextDelegate; private final Origin origin; - private final Map localIdentifierGeneratorDefinitionMap; - public EntityBindingContext(AnnotationBindingContext contextDelegate, ConfiguredClass source) { this.contextDelegate = contextDelegate; this.origin = new Origin( SourceType.ANNOTATION, source.getName() ); - this.localIdentifierGeneratorDefinitionMap = processLocalIdentifierGeneratorDefinitions( source.getClassInfo() ); - } - private Map processLocalIdentifierGeneratorDefinitions(final ClassInfo classInfo) { - Iterable identifierGeneratorSources = extractIdentifierGeneratorSources( - new IdentifierGeneratorSourceContainerImpl() { - @Override - protected Collection getAnnotations(DotName name) { - return classInfo.annotations().get( name ); - } - } - ); - - Map map = new HashMap(); - for ( IdentifierGeneratorSource source : identifierGeneratorSources ) { - map.put( - source.getGeneratorName(), - new IdentifierGeneratorDefinition( - source.getGeneratorName(), - source.getGeneratorImplementationName(), - source.getParameters() - ) - ); - } - return map; } @Override @@ -177,10 +144,6 @@ public class EntityBindingContext implements LocalBindingContext, AnnotationBind @Override public IdentifierGeneratorDefinition findIdGenerator(String name) { - IdentifierGeneratorDefinition definition = localIdentifierGeneratorDefinitionMap.get( name ); - if ( definition == null ) { - definition= contextDelegate.findIdGenerator( name ); - } - return definition; + return contextDelegate.findIdGenerator( name ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java index 4d4d0ae975..0991530bfc 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java @@ -321,7 +321,7 @@ public class EntityClass extends ConfiguredClass { ClassInfo.class ); - if(primaryKeyJoinColumn!=null || primaryKeyJoinColumns!=null){ + if ( primaryKeyJoinColumn != null || primaryKeyJoinColumns != null ) { ensureJoinedSubEntity(); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/global/IdGeneratorProcessor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/global/IdGeneratorProcessor.java index cfe698db38..a30272419e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/global/IdGeneratorProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/global/IdGeneratorProcessor.java @@ -23,8 +23,10 @@ */ package org.hibernate.metamodel.internal.source.annotations.global; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.persistence.GenerationType; import javax.persistence.SequenceGenerator; @@ -50,6 +52,7 @@ import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames; import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper; import org.hibernate.metamodel.spi.MetadataImplementor; import org.hibernate.metamodel.spi.binding.IdentifierGeneratorDefinition; +import org.hibernate.metamodel.spi.source.IdentifierGeneratorSource; /** * Binds {@link SequenceGenerator}, {@link javax.persistence.TableGenerator}, {@link GenericGenerator}, and @@ -73,49 +76,47 @@ public class IdGeneratorProcessor { * * @param bindingContext the context for annotation binding */ - public static void bind(AnnotationBindingContext bindingContext) { + public static Iterable extractGlobalIdentifierGeneratorSources(AnnotationBindingContext bindingContext) { + List identifierGeneratorSources = new ArrayList(); Collection annotations = bindingContext.getIndex() .getAnnotations( JPADotNames.SEQUENCE_GENERATOR ); for ( AnnotationInstance generator : annotations ) { - bindSequenceGenerator( bindingContext.getMetadataImplementor(), generator ); + bindSequenceGenerator( bindingContext.getMetadataImplementor(), generator, identifierGeneratorSources ); } annotations = bindingContext.getIndex().getAnnotations( JPADotNames.TABLE_GENERATOR ); for ( AnnotationInstance generator : annotations ) { - bindTableGenerator( bindingContext.getMetadataImplementor(), generator ); + bindTableGenerator( bindingContext.getMetadataImplementor(), generator, identifierGeneratorSources ); } - annotations = bindingContext.getIndex().getAnnotations( HibernateDotNames.GENERIC_GENERATOR ); + annotations = JandexHelper.getAnnotations( + bindingContext.getIndex(), + HibernateDotNames.GENERIC_GENERATOR, + HibernateDotNames.GENERIC_GENERATORS + ); for ( AnnotationInstance generator : annotations ) { - bindGenericGenerator( bindingContext.getMetadataImplementor(), generator ); - } - - annotations = bindingContext.getIndex().getAnnotations( HibernateDotNames.GENERIC_GENERATORS ); - for ( AnnotationInstance generators : annotations ) { - for ( AnnotationInstance generator : JandexHelper.getValue( - generators, - "value", - AnnotationInstance[].class - ) ) { - bindGenericGenerator( bindingContext.getMetadataImplementor(), generator ); - } + bindGenericGenerator( generator, identifierGeneratorSources ); } + return identifierGeneratorSources; } - private static void addStringParameter(AnnotationInstance annotation, - String element, - Map parameters, - String parameter) { + private static void addStringParameter( + final AnnotationInstance annotation, + final String element, + final Map parameters, + final String parameter) { String string = JandexHelper.getValue( annotation, element, String.class ); if ( StringHelper.isNotEmpty( string ) ) { parameters.put( parameter, string ); } } - private static void bindGenericGenerator(MetadataImplementor metadata, AnnotationInstance generator) { - String name = JandexHelper.getValue( generator, "name", String.class ); - Map parameterMap = new HashMap(); - AnnotationInstance[] parameterAnnotations = JandexHelper.getValue( + private static void bindGenericGenerator( + final AnnotationInstance generator, + final List identifierGeneratorSources) { + final String name = JandexHelper.getValue( generator, "name", String.class ); + final Map parameterMap = new HashMap(); + final AnnotationInstance[] parameterAnnotations = JandexHelper.getValue( generator, "parameters", AnnotationInstance[].class @@ -126,8 +127,8 @@ public class IdGeneratorProcessor { JandexHelper.getValue( parameterAnnotation, "value", String.class ) ); } - metadata.addIdGenerator( - new IdentifierGeneratorDefinition( + identifierGeneratorSources.add( + new IdentifierGeneratorSourceImpl( name, JandexHelper.getValue( generator, "strategy", String.class ), parameterMap @@ -136,15 +137,21 @@ public class IdGeneratorProcessor { LOG.tracef( "Add generic generator with name: %s", name ); } - private static void bindSequenceGenerator(MetadataImplementor metadata, AnnotationInstance generator) { - String name = JandexHelper.getValue( generator, "name", String.class ); - Map parameterMap = new HashMap(); - addStringParameter( generator, "sequenceName", parameterMap, SequenceStyleGenerator.SEQUENCE_PARAM ); - boolean useNewIdentifierGenerators = metadata.getOptions().useNewIdentifierGenerators(); - String strategy = EnumConversionHelper.generationTypeToGeneratorStrategyName( + private static void bindSequenceGenerator( + final MetadataImplementor metadata, + final AnnotationInstance generator, + final List identifierGeneratorSources) { + final String name = JandexHelper.getValue( generator, "name", String.class ); + + final boolean useNewIdentifierGenerators = metadata.getOptions().useNewIdentifierGenerators(); + final String strategy = EnumConversionHelper.generationTypeToGeneratorStrategyName( GenerationType.SEQUENCE, useNewIdentifierGenerators ); + + final Map parameterMap = new HashMap(); + addStringParameter( generator, "sequenceName", parameterMap, SequenceStyleGenerator.SEQUENCE_PARAM ); + if ( useNewIdentifierGenerators ) { addStringParameter( generator, "catalog", parameterMap, PersistentIdentifierGenerator.CATALOG ); addStringParameter( generator, "schema", parameterMap, PersistentIdentifierGenerator.SCHEMA ); @@ -166,20 +173,26 @@ public class IdGeneratorProcessor { String.valueOf( JandexHelper.getValue( generator, "allocationSize", Integer.class ) - 1 ) ); } - metadata.addIdGenerator( new IdentifierGeneratorDefinition( name, strategy, parameterMap ) ); + identifierGeneratorSources.add( new IdentifierGeneratorSourceImpl( name, strategy, parameterMap ) ); LOG.tracef( "Add sequence generator with name: %s", name ); } - private static void bindTableGenerator(MetadataImplementor metadata, AnnotationInstance generator) { - String name = JandexHelper.getValue( generator, "name", String.class ); - Map parameterMap = new HashMap(); - addStringParameter( generator, "catalog", parameterMap, PersistentIdentifierGenerator.CATALOG ); - addStringParameter( generator, "schema", parameterMap, PersistentIdentifierGenerator.SCHEMA ); - boolean useNewIdentifierGenerators = metadata.getOptions().useNewIdentifierGenerators(); - String strategy = EnumConversionHelper.generationTypeToGeneratorStrategyName( + private static void bindTableGenerator( + final MetadataImplementor metadata, + final AnnotationInstance generator, + final List identifierGeneratorSources) { + final String name = JandexHelper.getValue( generator, "name", String.class ); + + final boolean useNewIdentifierGenerators = metadata.getOptions().useNewIdentifierGenerators(); + final String strategy = EnumConversionHelper.generationTypeToGeneratorStrategyName( GenerationType.TABLE, useNewIdentifierGenerators ); + + final Map parameterMap = new HashMap(); + addStringParameter( generator, "catalog", parameterMap, PersistentIdentifierGenerator.CATALOG ); + addStringParameter( generator, "schema", parameterMap, PersistentIdentifierGenerator.SCHEMA ); + if ( useNewIdentifierGenerators ) { parameterMap.put( TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY, "true" ); addStringParameter( generator, "table", parameterMap, TableGenerator.TABLE_PARAM ); @@ -188,18 +201,23 @@ public class IdGeneratorProcessor { addStringParameter( generator, "valueColumnName", parameterMap, TableGenerator.VALUE_COLUMN_PARAM ); parameterMap.put( TableGenerator.INCREMENT_PARAM, - String.valueOf( JandexHelper.getValue( generator, "allocationSize", String.class ) ) + String.valueOf( JandexHelper.getValue( generator, "allocationSize", Integer.class ) ) ); parameterMap.put( TableGenerator.INITIAL_PARAM, - String.valueOf( JandexHelper.getValue( generator, "initialValue", String.class ) + 1 ) + String.valueOf( JandexHelper.getValue( generator, "initialValue", Integer.class ) + 1 ) ); } else { addStringParameter( generator, "table", parameterMap, MultipleHiLoPerTableGenerator.ID_TABLE ); addStringParameter( generator, "pkColumnName", parameterMap, MultipleHiLoPerTableGenerator.PK_COLUMN_NAME ); addStringParameter( generator, "pkColumnValue", parameterMap, MultipleHiLoPerTableGenerator.PK_VALUE_NAME ); - addStringParameter( generator, "valueColumnName", parameterMap, MultipleHiLoPerTableGenerator.VALUE_COLUMN_NAME ); + addStringParameter( + generator, + "valueColumnName", + parameterMap, + MultipleHiLoPerTableGenerator.VALUE_COLUMN_NAME + ); parameterMap.put( TableHiLoGenerator.MAX_LO, String.valueOf( JandexHelper.getValue( generator, "allocationSize", Integer.class ) - 1 ) @@ -208,7 +226,37 @@ public class IdGeneratorProcessor { if ( JandexHelper.getValue( generator, "uniqueConstraints", AnnotationInstance[].class ).length > 0 ) { LOG.ignoringTableGeneratorConstraints( name ); } - metadata.addIdGenerator( new IdentifierGeneratorDefinition( name, strategy, parameterMap ) ); + identifierGeneratorSources.add( new IdentifierGeneratorSourceImpl( name, strategy, parameterMap ) ); LOG.tracef( "Add table generator with name: %s", name ); } + + private static class IdentifierGeneratorSourceImpl implements IdentifierGeneratorSource { + private final String generatorName; + private final String generatorImplementationName; + private final Map parameterMap; + + public IdentifierGeneratorSourceImpl( + String generatorName, + String generatorImplementationName, + Map parameterMap) { + this.generatorName = generatorName; + this.generatorImplementationName = generatorImplementationName; + this.parameterMap = parameterMap; + } + + @Override + public String getGeneratorName() { + return generatorName; + } + + @Override + public String getGeneratorImplementationName() { + return generatorImplementationName; + } + + @Override + public Map getParameters() { + return parameterMap; + } + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/global/QueryProcessor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/global/QueryProcessor.java index 1581ebf9f9..b9373104c4 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/global/QueryProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/global/QueryProcessor.java @@ -85,53 +85,41 @@ public class QueryProcessor { * @param bindingContext the context for annotation binding */ public static void bind(AnnotationBindingContext bindingContext) { - Collection annotations = bindingContext.getIndex().getAnnotations( JPADotNames.NAMED_QUERY ); + Collection annotations = JandexHelper.getAnnotations( + bindingContext.getIndex(), + JPADotNames.NAMED_QUERY, + JPADotNames.NAMED_QUERIES + ); for ( AnnotationInstance query : annotations ) { bindNamedQuery( bindingContext.getMetadataImplementor(), query ); } - annotations = bindingContext.getIndex().getAnnotations( JPADotNames.NAMED_QUERIES ); - for ( AnnotationInstance queries : annotations ) { - for ( AnnotationInstance query : JandexHelper.getValue( queries, "value", AnnotationInstance[].class ) ) { - bindNamedQuery( bindingContext.getMetadataImplementor(), query ); - } - } - - annotations = bindingContext.getIndex().getAnnotations( JPADotNames.NAMED_NATIVE_QUERY ); + annotations = JandexHelper.getAnnotations( + bindingContext.getIndex(), + JPADotNames.NAMED_NATIVE_QUERY, + JPADotNames.NAMED_NATIVE_QUERIES + ); for ( AnnotationInstance query : annotations ) { bindNamedNativeQuery( bindingContext.getMetadataImplementor(), query ); } - annotations = bindingContext.getIndex().getAnnotations( JPADotNames.NAMED_NATIVE_QUERIES ); - for ( AnnotationInstance queries : annotations ) { - for ( AnnotationInstance query : JandexHelper.getValue( queries, "value", AnnotationInstance[].class ) ) { - bindNamedNativeQuery( bindingContext.getMetadataImplementor(), query ); - } - } - - annotations = bindingContext.getIndex().getAnnotations( HibernateDotNames.NAMED_QUERY ); + annotations = JandexHelper.getAnnotations( + bindingContext.getIndex(), + HibernateDotNames.NAMED_QUERY, + HibernateDotNames.NAMED_QUERIES + ); for ( AnnotationInstance query : annotations ) { bindNamedQuery( bindingContext.getMetadataImplementor(), query ); } - annotations = bindingContext.getIndex().getAnnotations( HibernateDotNames.NAMED_QUERIES ); - for ( AnnotationInstance queries : annotations ) { - for ( AnnotationInstance query : JandexHelper.getValue( queries, "value", AnnotationInstance[].class ) ) { - bindNamedQuery( bindingContext.getMetadataImplementor(), query ); - } - } - - annotations = bindingContext.getIndex().getAnnotations( HibernateDotNames.NAMED_NATIVE_QUERY ); + annotations = JandexHelper.getAnnotations( + bindingContext.getIndex(), + HibernateDotNames.NAMED_NATIVE_QUERY, + HibernateDotNames.NAMED_NATIVE_QUERIES + ); for ( AnnotationInstance query : annotations ) { bindNamedNativeQuery( bindingContext.getMetadataImplementor(), query ); } - - annotations = bindingContext.getIndex().getAnnotations( HibernateDotNames.NAMED_NATIVE_QUERIES ); - for ( AnnotationInstance queries : annotations ) { - for ( AnnotationInstance query : JandexHelper.getValue( queries, "value", AnnotationInstance[].class ) ) { - bindNamedNativeQuery( bindingContext.getMetadataImplementor(), query ); - } - } } /** diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/JandexHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/JandexHelper.java index b873c1be17..cfc56211e3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/JandexHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/JandexHelper.java @@ -30,6 +30,8 @@ import java.io.InputStream; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; @@ -199,6 +201,68 @@ public class JandexHelper { } } + + + public static Collection getAnnotations( + final IndexView indexView, + final DotName singularDotName, + final DotName pluralDotName + ) { + List annotationInstances = new ArrayList(); + annotationInstances.addAll( indexView.getAnnotations( singularDotName ) ); + + Collection pluralAnnotations = indexView.getAnnotations( pluralDotName ); + for ( AnnotationInstance ann : pluralAnnotations ) { + AnnotationInstance[] typeDefAnnotations = JandexHelper.getValue( + ann, + "value", + AnnotationInstance[].class + ); + annotationInstances.addAll( Arrays.asList( typeDefAnnotations ) ); + } + return annotationInstances; + } + + public static Collection getAnnotations( + final Map> annotations, + final DotName singularDotName, + final DotName pluralDotName) { + return getAnnotations( annotations, singularDotName, pluralDotName, false ); + } + + public static Collection getAnnotations( + final Map> annotations, + final DotName singularDotName, + final DotName pluralDotName, + final boolean checkSingle) { + List annotationInstances = new ArrayList(); + + List list = annotations.get( singularDotName ); + if ( list != null ) { + if ( checkSingle ) { + assertSingularAnnotationInstances( list ); + } + annotationInstances.addAll( list ); + } + Collection pluralAnnotations = annotations.get( pluralDotName ); + if ( pluralAnnotations != null ) { + if ( checkSingle ) { + assertSingularAnnotationInstances( pluralAnnotations ); + } + for ( AnnotationInstance ann : pluralAnnotations ) { + AnnotationInstance[] typeDefAnnotations = JandexHelper.getValue( + ann, + "value", + AnnotationInstance[].class + ); + annotationInstances.addAll( Arrays.asList( typeDefAnnotations ) ); + } + } + + + return annotationInstances; + } + /** * @param classInfo the class info from which to retrieve the annotation instance * @param annotationName the annotation to retrieve from the class info @@ -241,10 +305,18 @@ public class JandexHelper { if ( annotationList.size() == 1 ) { return annotationList.get( 0 ); } - throw new AssertionFailure( - "Found more than one instance of the annotation " - + annotationList.get( 0 ).name().toString() - + ". Expected was one." ); + assertSingularAnnotationInstances( annotationList ); + return null;//only here to make compiler happy + } + + private static void assertSingularAnnotationInstances(Collection annotationInstances) { + if ( annotationInstances.size() > 1 ) { + throw new AssertionFailure( + "Found more than one instance of the annotation " + + annotationInstances.iterator().next().name().toString() + + ". Expected was one." + ); + } } /** @@ -258,20 +330,6 @@ public class JandexHelper { public static AnnotationInstance getSingleAnnotation(Map> annotations, DotName annotationName) throws AssertionFailure { return getSingleAnnotation( annotations, annotationName, null ); -// List annotationList = annotations.get( annotationName ); -// if ( annotationList == null ) { -// return null; -// } -// else if ( annotationList.size() == 1 ) { -// return annotationList.get( 0 ); -// } -// else { -// throw new AssertionFailure( -// "Found more than one instance of the annotation " -// + annotationList.get( 0 ).name().toString() -// + ". Expected was one." -// ); -// } } /** diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/JandexHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/JandexHelper.java deleted file mode 100644 index cf48b624d3..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/JandexHelper.java +++ /dev/null @@ -1,369 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2011, 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.metamodel.source.annotations; - -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; -import java.util.Map; - -import org.jboss.jandex.AnnotationInstance; -import org.jboss.jandex.AnnotationTarget; -import org.jboss.jandex.AnnotationValue; -import org.jboss.jandex.ClassInfo; -import org.jboss.jandex.DotName; -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.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. - * - * @author Hardy Ferentschik - */ -public class JandexHelper { - private static final Map DEFAULT_VALUES_BY_ELEMENT = new HashMap(); - - private JandexHelper() { - } - - /** - * Retrieves a jandex annotation element value. If the value is {@code null}, the default value specified in the - * annotation class is retrieved instead. - *

- * 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 #getEnumValue(AnnotationInstance, String, Class)}. - *

- * - * @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: - *
    - *
  • Byte
  • - *
  • Short
  • - *
  • Integer
  • - *
  • Character
  • - *
  • Float
  • - *
  • Double
  • - *
  • Long
  • - *
  • Boolean
  • - *
  • String
  • - *
  • AnnotationInstance
  • - * - * @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 getValue(AnnotationInstance annotation, String element, Class 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)" - ); - } - - if ( type.isPrimitive() ) { - type = PrimitiveWrapperHelper.getDescriptorByPrimitiveType( type ).getWrapperClass(); - } - - // try getting the untyped value from Jandex - AnnotationValue annotationValue = annotation.value( element ); - - try { - if ( annotationValue != null ) { - return explicitAnnotationParameter( annotationValue, type ); - } - else { - return defaultAnnotationParameter( getDefaultValue( annotation, element ), type ); - } - } - 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() - ), - e - ); - } - } - - /** - * Retrieves a jandex annotation element value, converting it to the supplied enumerated type. If the value is - * null, the default value specified in the annotation class is retrieved instead. - * - * @param 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 null, else the default value if - * not null, else null. - * - * @see #getValue(AnnotationInstance, String, Class) - */ - @SuppressWarnings("unchecked") - public static > T getEnumValue(AnnotationInstance annotation, String element, Class type) { - AnnotationValue val = annotation.value( element ); - if ( val == null ) { - return (T) getDefaultValue( annotation, element ); - } - return Enum.valueOf( type, val.asEnum() ); - } - - /** - * Expects a method or field annotation target and returns the property name for this target - * - * @param target the annotation target - * - * @return the property name of the target. For a field it is the field name and for a method name it is - * the method name stripped of 'is', 'has' or 'get' - */ - public static String getPropertyName(AnnotationTarget target) { - if ( !( target instanceof MethodInfo || target instanceof FieldInfo ) ) { - throw new AssertionFailure( "Unexpected annotation target " + target.toString() ); - } - - if ( target instanceof FieldInfo ) { - return ( (FieldInfo) target ).name(); - } - else { - final String methodName = ( (MethodInfo) target ).name(); - String propertyName; - if ( methodName.startsWith( "is" ) ) { - propertyName = Introspector.decapitalize( methodName.substring( 2 ) ); - } - else if ( methodName.startsWith( "has" ) ) { - propertyName = Introspector.decapitalize( methodName.substring( 3 ) ); - } - else if ( methodName.startsWith( "get" ) ) { - propertyName = Introspector.decapitalize( methodName.substring( 3 ) ); - } - else { - throw new AssertionFailure( "Expected a method following the Java Bean notation" ); - } - return propertyName; - } - } - - /** - * @param classInfo the class info from which to retrieve the annotation instance - * @param annotationName the annotation to retrieve from the class info - * - * @return the single annotation defined on the class or {@code null} in case the annotation is not specified at all - * - * @throws org.hibernate.AssertionFailure in case there is there is more than one annotation of this type. - */ - public static AnnotationInstance getSingleAnnotation(ClassInfo classInfo, DotName annotationName) - throws AssertionFailure { - return getSingleAnnotation( classInfo.annotations(), annotationName ); - } - - /** - * @param annotations List of annotation instances keyed against their dot name. - * @param annotationName the annotation to retrieve from map - * - * @return the single annotation of the specified dot name or {@code null} in case the annotation is not specified at all - * - * @throws org.hibernate.AssertionFailure in case there is there is more than one annotation of this type. - */ - public static AnnotationInstance getSingleAnnotation(Map> annotations, DotName annotationName) - throws AssertionFailure { - List annotationList = annotations.get( annotationName ); - if ( annotationList == null ) { - return null; - } - else if ( annotationList.size() == 1 ) { - return annotationList.get( 0 ); - } - else { - throw new AssertionFailure( - "Found more than one instance of the annotation " - + annotationList.get( 0 ).name().toString() - + ". Expected was one." - ); - } - } - - /** - * @param annotations List of annotation instances keyed against their dot name. - * @param annotationName the annotation to check - * - * @return returns {@code true} if the map contains only a single instance of specified annotation or {@code false} otherwise. - * - * @throws org.hibernate.AssertionFailure in case there is there is more than one annotation of this type. - */ - public static boolean containsSingleAnnotations(Map> annotations, DotName annotationName) - throws AssertionFailure { - return getSingleAnnotation( annotations, annotationName ) != null; - } - - /** - * Creates a jandex index for the specified classes - * - * @param classLoaderService class loader service - * @param classes the classes to index - * - * @return an annotation repository w/ all the annotation discovered in the specified classes - */ - public static Index indexForClass(ClassLoaderService classLoaderService, Class... classes) { - Indexer indexer = new Indexer(); - for ( Class clazz : classes ) { - InputStream stream = classLoaderService.locateResourceStream( - clazz.getName().replace( '.', '/' ) + ".class" - ); - try { - indexer.index( stream ); - } - catch ( IOException e ) { - StringBuilder builder = new StringBuilder(); - builder.append( "[" ); - int count = 0; - for ( Class c : classes ) { - builder.append( c.getName() ); - if ( count < classes.length - 1 ) { - builder.append( "," ); - } - count++; - } - builder.append( "]" ); - throw new HibernateException( "Unable to create annotation index for " + builder.toString() ); - } - } - return indexer.complete(); - } - - public static Map> getMemberAnnotations(ClassInfo classInfo, String name) { - if ( classInfo == null ) { - throw new IllegalArgumentException( "classInfo cannot be null" ); - } - - if ( name == null ) { - throw new IllegalArgumentException( "name cannot be null" ); - } - - Map> annotations = new HashMap>(); - for ( List annotationList : classInfo.annotations().values() ) { - for ( AnnotationInstance instance : annotationList ) { - String targetName = null; - if ( instance.target() instanceof FieldInfo ) { - targetName = ( (FieldInfo) instance.target() ).name(); - } - else if ( instance.target() instanceof MethodInfo ) { - targetName = ( (MethodInfo) instance.target() ).name(); - } - if ( targetName != null && name.equals( targetName ) ) { - addAnnotationToMap( instance, annotations ); - } - } - } - return annotations; - } - - private static void addAnnotationToMap(AnnotationInstance instance, Map> annotations) { - DotName dotName = instance.name(); - List list; - if ( annotations.containsKey( dotName ) ) { - list = annotations.get( dotName ); - } - else { - list = new ArrayList(); - annotations.put( dotName, list ); - } - list.add( instance ); - } - - 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 AssertionFailure( - String.format( "The annotation %s does not define a parameter '%s'", name, element ), - error - ); - } - } - - private static T defaultAnnotationParameter(Object defaultValue, Class 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 explicitAnnotationParameter(AnnotationValue annotationValue, Class 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 ); - } -}