From a859344faf342bd5c0e9e9b60aa59fe583134836 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Wed, 18 Oct 2023 09:19:05 -0500 Subject: [PATCH] Global id generator registrations --- .../GenericGeneratorRegistration.java | 35 ++ .../orm/internal/GlobalRegistrations.java | 506 ++++++++++++++++++ .../orm/internal/IdGeneratorRegistration.java | 57 -- .../orm/internal/ProcessResultCollector.java | 409 +++----------- .../orm/internal/ProcessResultImpl.java | 8 - .../SequenceGeneratorRegistration.java | 36 ++ .../internal/TableGeneratorRegistration.java | 36 ++ .../models/orm/spi/ProcessResult.java | 3 - .../hibernate/models/orm/spi/Processor.java | 77 +-- .../orm/xml/internal/XmlProcessingState.java | 29 - .../orm/xml/spi/XmlProcessingContext.java | 13 - .../orm/xml/XmlProcessingSmokeTests.java | 32 +- .../dynamic/DynamicAnnotationUsage.java | 58 ++ 13 files changed, 788 insertions(+), 511 deletions(-) create mode 100644 hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/GenericGeneratorRegistration.java create mode 100644 hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/GlobalRegistrations.java delete mode 100644 hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/IdGeneratorRegistration.java create mode 100644 hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/SequenceGeneratorRegistration.java create mode 100644 hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/TableGeneratorRegistration.java delete mode 100644 hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlProcessingState.java delete mode 100644 hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/XmlProcessingContext.java create mode 100644 hibernate-models-source/src/main/java/org/hibernate/models/source/internal/dynamic/DynamicAnnotationUsage.java diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/GenericGeneratorRegistration.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/GenericGeneratorRegistration.java new file mode 100644 index 0000000..483c985 --- /dev/null +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/GenericGeneratorRegistration.java @@ -0,0 +1,35 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright: Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.models.orm.internal; + +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.models.source.spi.AnnotationUsage; + +/** + * Global registration of a generic generator + * + * @see org.hibernate.models.orm.spi.Processor.Options#areGeneratorsGlobal() + * + * @author Steve Ebersole + */ +public class GenericGeneratorRegistration { + private final String name; + private final AnnotationUsage configuration; + + public GenericGeneratorRegistration(String name, AnnotationUsage configuration) { + this.name = name; + this.configuration = configuration; + } + + public String getName() { + return name; + } + + public AnnotationUsage getConfiguration() { + return configuration; + } +} diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/GlobalRegistrations.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/GlobalRegistrations.java new file mode 100644 index 0000000..3947f44 --- /dev/null +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/GlobalRegistrations.java @@ -0,0 +1,506 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright: Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.models.orm.internal; + +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Parameter; +import org.hibernate.boot.jaxb.mapping.JaxbCollectionUserTypeRegistration; +import org.hibernate.boot.jaxb.mapping.JaxbCompositeUserTypeRegistration; +import org.hibernate.boot.jaxb.mapping.JaxbConfigurationParameter; +import org.hibernate.boot.jaxb.mapping.JaxbConverterRegistration; +import org.hibernate.boot.jaxb.mapping.JaxbEmbeddableInstantiatorRegistration; +import org.hibernate.boot.jaxb.mapping.JaxbEntityListener; +import org.hibernate.boot.jaxb.mapping.JaxbEntityMappings; +import org.hibernate.boot.jaxb.mapping.JaxbGenericIdGenerator; +import org.hibernate.boot.jaxb.mapping.JaxbJavaTypeRegistration; +import org.hibernate.boot.jaxb.mapping.JaxbJdbcTypeRegistration; +import org.hibernate.boot.jaxb.mapping.JaxbSequenceGenerator; +import org.hibernate.boot.jaxb.mapping.JaxbTableGenerator; +import org.hibernate.boot.jaxb.mapping.JaxbUserTypeRegistration; +import org.hibernate.internal.util.collections.CollectionHelper; +import org.hibernate.metamodel.CollectionClassification; +import org.hibernate.models.internal.StringHelper; +import org.hibernate.models.source.internal.dynamic.DynamicAnnotationUsage; +import org.hibernate.models.source.spi.AnnotationDescriptorRegistry; +import org.hibernate.models.source.spi.AnnotationTarget; +import org.hibernate.models.source.spi.AnnotationUsage; +import org.hibernate.models.source.spi.ClassDetails; +import org.hibernate.models.source.spi.ClassDetailsRegistry; +import org.hibernate.models.source.spi.SourceModelBuildingContext; + +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.TableGenerator; + +import static java.util.Collections.emptyList; +import static org.hibernate.models.orm.spi.HibernateAnnotations.COLLECTION_TYPE_REG; +import static org.hibernate.models.orm.spi.HibernateAnnotations.COMPOSITE_TYPE_REG; +import static org.hibernate.models.orm.spi.HibernateAnnotations.CONVERTER_REG; +import static org.hibernate.models.orm.spi.HibernateAnnotations.EMBEDDABLE_INSTANTIATOR_REG; +import static org.hibernate.models.orm.spi.HibernateAnnotations.JAVA_TYPE_REG; +import static org.hibernate.models.orm.spi.HibernateAnnotations.JDBC_TYPE_REG; +import static org.hibernate.models.orm.spi.HibernateAnnotations.TYPE_REG; + +/** + * @author Steve Ebersole + */ +public class GlobalRegistrations { + private final ClassDetailsRegistry classDetailsRegistry; + private final AnnotationDescriptorRegistry annotationDescriptorRegistry; + + private List entityListenerRegistrations; + private List autoAppliedConverters; + private List converterRegistrations; + private List javaTypeRegistrations; + private List jdbcTypeRegistrations; + private List userTypeRegistrations; + private List compositeUserTypeRegistrations; + private List collectionTypeRegistrations; + private List embeddableInstantiatorRegistrations; + + private Map sequenceGeneratorRegistrations; + private Map tableGeneratorRegistrations; + private Map genericGeneratorRegistrations; + + private Map jpaNamedQueries; + private Map hibernateNamedHqlQueries; + private Map hibernateNamedNativeQueries; + + public GlobalRegistrations(SourceModelBuildingContext sourceModelBuildingContext) { + this( sourceModelBuildingContext.getClassDetailsRegistry(), sourceModelBuildingContext.getAnnotationDescriptorRegistry() ); + } + + public GlobalRegistrations(ClassDetailsRegistry classDetailsRegistry, AnnotationDescriptorRegistry annotationDescriptorRegistry) { + this.classDetailsRegistry = classDetailsRegistry; + this.annotationDescriptorRegistry = annotationDescriptorRegistry; + } + + public List getEntityListenerRegistrations() { + return entityListenerRegistrations; + } + + public List getConverterRegistrations() { + return converterRegistrations == null ? emptyList() : converterRegistrations; + } + + public List getAutoAppliedConverters() { + return autoAppliedConverters == null ? emptyList() : autoAppliedConverters; + } + + public List getJavaTypeRegistrations() { + return javaTypeRegistrations == null ? emptyList() : javaTypeRegistrations; + } + + public List getJdbcTypeRegistrations() { + return jdbcTypeRegistrations == null ? emptyList() : jdbcTypeRegistrations; + } + + public List getUserTypeRegistrations() { + return userTypeRegistrations == null ? emptyList() : userTypeRegistrations; + } + + public List getCompositeUserTypeRegistrations() { + return compositeUserTypeRegistrations == null ? emptyList() : compositeUserTypeRegistrations; + } + + public List getCollectionTypeRegistrations() { + return collectionTypeRegistrations == null ? emptyList() : collectionTypeRegistrations; + } + + public List getEmbeddableInstantiatorRegistrations() { + return embeddableInstantiatorRegistrations == null ? emptyList() : embeddableInstantiatorRegistrations; + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // JavaTypeRegistration + + public void collectJavaTypeRegistrations(AnnotationTarget annotationTarget) { + annotationTarget.forEachUsage( JAVA_TYPE_REG, (usage) -> collectJavaTypeRegistration( + usage.getAttributeValue( "javaType" ), + usage.getAttributeValue( "descriptorClass" ) + ) ); + } + + public void collectJavaTypeRegistrations(List registrations) { + if ( CollectionHelper.isEmpty( registrations ) ) { + return; + } + + registrations.forEach( (reg) -> collectJavaTypeRegistration( + classDetailsRegistry.resolveClassDetails( reg.getClazz() ), + classDetailsRegistry.resolveClassDetails( reg.getDescriptor() ) + ) ); + } + + public void collectJavaTypeRegistration(ClassDetails javaType, ClassDetails descriptor) { + if ( javaTypeRegistrations == null ) { + javaTypeRegistrations = new ArrayList<>(); + } + javaTypeRegistrations.add( new JavaTypeRegistration( javaType, descriptor ) ); + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // JdbcTypeRegistration + + public void collectJdbcTypeRegistrations(AnnotationTarget annotationTarget) { + annotationTarget.forEachUsage( JDBC_TYPE_REG, (usage) -> collectJdbcTypeRegistration( + usage.getAttributeValue( "registrationCode" ), + usage.getAttributeValue( "value" ) + ) ); + } + + public void collectJdbcTypeRegistrations(List registrations) { + if ( CollectionHelper.isEmpty( registrations ) ) { + return; + } + + registrations.forEach( (reg) -> collectJdbcTypeRegistration( + reg.getCode(), + classDetailsRegistry.resolveClassDetails( reg.getDescriptor() ) + ) ); + } + + public void collectJdbcTypeRegistration(Integer registrationCode, ClassDetails descriptor) { + if ( jdbcTypeRegistrations == null ) { + jdbcTypeRegistrations = new ArrayList<>(); + } + jdbcTypeRegistrations.add( new JdbcTypeRegistration( registrationCode, descriptor ) ); + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // ConversionRegistration + + public void collectConverterRegistrations(AnnotationTarget annotationTarget) { + annotationTarget.forEachUsage( CONVERTER_REG, (usage) -> { + final ClassDetails domainType = usage.getAttributeValue( "domainType" ); + final ClassDetails converterType = usage.getAttributeValue( "converter" ); + final boolean autoApply = usage.getAttributeValue( "autoApply" ); + collectConverterRegistration( new ConversionRegistration( domainType, converterType, autoApply ) ); + } ); + } + + public void collectConverterRegistrations(List registrations) { + if ( CollectionHelper.isEmpty( registrations ) ) { + return; + } + + registrations.forEach( (registration) -> { + final ClassDetails explicitDomainType; + final String explicitDomainTypeName = registration.getClazz(); + if ( StringHelper.isNotEmpty( explicitDomainTypeName ) ) { + explicitDomainType = classDetailsRegistry.resolveClassDetails( explicitDomainTypeName ); + } + else { + explicitDomainType = null; + } + final ClassDetails converterType = classDetailsRegistry.resolveClassDetails( registration.getConverter() ); + final boolean autoApply = registration.isAutoApply(); + collectConverterRegistration( new ConversionRegistration( explicitDomainType, converterType, autoApply ) ); + } ); + } + + public void collectConverterRegistration(ConversionRegistration conversion) { + if ( converterRegistrations == null ) { + converterRegistrations = new ArrayList<>(); + } + converterRegistrations.add( conversion ); + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // UserTypeRegistration + + public void collectUserTypeRegistrations(AnnotationTarget annotationTarget) { + annotationTarget.forEachUsage( TYPE_REG, (usage) -> collectUserTypeRegistration( + usage.getAttributeValue( "basicClass" ), + usage.getAttributeValue( "userType" ) + ) ); + } + + public void collectUserTypeRegistrations(List registrations) { + if ( CollectionHelper.isEmpty( registrations ) ) { + return; + } + + registrations.forEach( (reg) -> { + final ClassDetails domainTypeDetails = classDetailsRegistry.resolveClassDetails( reg.getClazz() ); + final ClassDetails descriptorDetails = classDetailsRegistry.resolveClassDetails( reg.getDescriptor() ); + collectUserTypeRegistration( domainTypeDetails, descriptorDetails ); + } ); + } + + public void collectUserTypeRegistration(ClassDetails domainClass, ClassDetails userTypeClass) { + if ( userTypeRegistrations == null ) { + userTypeRegistrations = new ArrayList<>(); + } + userTypeRegistrations.add( new UserTypeRegistration( domainClass, userTypeClass ) ); + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CompositeUserTypeRegistration + + public void collectCompositeUserTypeRegistrations(AnnotationTarget annotationTarget) { + annotationTarget.forEachUsage( COMPOSITE_TYPE_REG, (usage) -> collectCompositeUserTypeRegistration( + usage.getAttributeValue( "embeddableClass" ), + usage.getAttributeValue( "userType" ) + ) ); + } + + public void collectCompositeUserTypeRegistrations(List registrations) { + if ( CollectionHelper.isEmpty( registrations ) ) { + return; + } + + registrations.forEach( (reg) -> collectCompositeUserTypeRegistration( + classDetailsRegistry.resolveClassDetails( reg.getClazz() ), + classDetailsRegistry.resolveClassDetails( reg.getDescriptor() ) + ) ); + } + + public void collectCompositeUserTypeRegistration(ClassDetails domainClass, ClassDetails userTypeClass) { + if ( compositeUserTypeRegistrations == null ) { + compositeUserTypeRegistrations = new ArrayList<>(); + } + compositeUserTypeRegistrations.add( new CompositeUserTypeRegistration( domainClass, userTypeClass ) ); + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CollectionTypeRegistration + + public void collectCollectionTypeRegistrations(AnnotationTarget annotationTarget) { + annotationTarget.forEachUsage( COLLECTION_TYPE_REG, (usage) -> collectCollectionTypeRegistration( + usage.getAttributeValue( "classification" ), + usage.getAttributeValue( "type" ), + extractParameterMap( usage ) + ) ); + } + + private Map extractParameterMap(AnnotationUsage source) { + final List> parameters = source.getAttributeValue( "parameters" ); + + final Map result = new HashMap<>(); + for ( AnnotationUsage parameter : parameters ) { + result.put( + parameter.getAttributeValue( "name" ), + parameter.getAttributeValue( "value" ) + ); + } + return result; + } + + public void collectCollectionTypeRegistrations(List registrations) { + if ( CollectionHelper.isEmpty( registrations ) ) { + return; + } + + registrations.forEach( (reg) -> collectCollectionTypeRegistration( + reg.getClassification(), + classDetailsRegistry.resolveClassDetails( reg.getDescriptor() ), + extractParameterMap( reg.getParameters() ) + ) ); + } + + private Map extractParameterMap(List parameters) { + if ( CollectionHelper.isEmpty( parameters ) ) { + return Collections.emptyMap(); + } + + final Map result = new HashMap<>(); + parameters.forEach( parameter -> result.put( parameter.getName(), parameter.getValue() ) ); + return result; + } + + public void collectCollectionTypeRegistration( + CollectionClassification classification, + ClassDetails userTypeClass, + Map parameters) { + if ( collectionTypeRegistrations == null ) { + collectionTypeRegistrations = new ArrayList<>(); + } + collectionTypeRegistrations.add( new CollectionTypeRegistration( classification, userTypeClass, parameters ) ); + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // EmbeddableInstantiatorRegistration + + public void collectEmbeddableInstantiatorRegistrations(AnnotationTarget annotationTarget) { + annotationTarget.forEachUsage( EMBEDDABLE_INSTANTIATOR_REG, (usage) -> collectEmbeddableInstantiatorRegistration( + usage.getAttributeValue( "embeddableClass" ), + usage.getAttributeValue( "instantiator" ) + ) ); + } + + public void collectEmbeddableInstantiatorRegistrations(List registrations) { + if ( CollectionHelper.isEmpty( registrations ) ) { + return; + } + + registrations.forEach( (reg) -> collectEmbeddableInstantiatorRegistration( + classDetailsRegistry.resolveClassDetails( reg.getEmbeddableClass() ), + classDetailsRegistry.resolveClassDetails( reg.getInstantiator() ) + ) ); + } + + public void collectEmbeddableInstantiatorRegistration(ClassDetails embeddableClass, ClassDetails instantiator) { + if ( embeddableInstantiatorRegistrations == null ) { + embeddableInstantiatorRegistrations = new ArrayList<>(); + } + embeddableInstantiatorRegistrations.add( new EmbeddableInstantiatorRegistration( embeddableClass, instantiator ) ); + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // EntityListenerRegistration + + public void collectEntityListenerRegistrations(List listeners) { + if ( CollectionHelper.isEmpty( listeners ) ) { + return; + } + + if ( entityListenerRegistrations == null ) { + entityListenerRegistrations = new ArrayList<>(); + } + + listeners.forEach( (listener) -> { + final EntityListenerRegistration listenerRegistration = EntityListenerRegistration.from( listener, classDetailsRegistry ); + entityListenerRegistrations.add( listenerRegistration ); + } ); + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Id generators + + public void collectIdGenerators(JaxbEntityMappings jaxbRoot) { + collectSequenceGenerators( jaxbRoot.getSequenceGenerators() ); + collectTableGenerators( jaxbRoot.getTableGenerators() ); + collectGenericGenerators( jaxbRoot.getGenericGenerators() ); + + // todo : add support for @IdGeneratorType in mapping.xsd? + } + + public void collectIdGenerators(ClassDetails classDetails) { + classDetails.forEachUsage( SequenceGenerator.class, this::collectSequenceGenerator ); + classDetails.forEachUsage( TableGenerator.class, this::collectTableGenerator ); + classDetails.forEachUsage( GenericGenerator.class, this::collectGenericGenerator ); + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Sequence generator + + public void collectSequenceGenerators(List sequenceGenerators) { + if ( CollectionHelper.isEmpty( sequenceGenerators ) ) { + return; + } + + sequenceGenerators.forEach( (generator) -> { + final DynamicAnnotationUsage annotationUsage = new DynamicAnnotationUsage<>( SequenceGenerator.class ); + annotationUsage.setAttributeValue( "name", generator.getName() ); + annotationUsage.setAttributeValue( "sequenceName", generator.getSequenceName() ); + annotationUsage.setAttributeValue( "catalog", generator.getCatalog() ); + annotationUsage.setAttributeValue( "schema", generator.getSchema() ); + annotationUsage.setAttributeValue( "initialValue", generator.getInitialValue() ); + annotationUsage.setAttributeValue( "allocationSize", generator.getAllocationSize() ); + + collectSequenceGenerator( new SequenceGeneratorRegistration( generator.getName(), annotationUsage ) ); + } ); + } + + public void collectSequenceGenerator(AnnotationUsage usage) { + collectSequenceGenerator( new SequenceGeneratorRegistration( usage.getAttributeValue( "name" ), usage ) ); + } + + public void collectSequenceGenerator(SequenceGeneratorRegistration generatorRegistration) { + if ( sequenceGeneratorRegistrations == null ) { + sequenceGeneratorRegistrations = new HashMap<>(); + } + + sequenceGeneratorRegistrations.put( generatorRegistration.getName(), generatorRegistration ); + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Table generator + + public void collectTableGenerators(List tableGenerators) { + if ( CollectionHelper.isEmpty( tableGenerators ) ) { + return; + } + + tableGenerators.forEach( (generator) -> { + final DynamicAnnotationUsage annotationUsage = new DynamicAnnotationUsage<>( TableGenerator.class ); + annotationUsage.setAttributeValue( "name", generator.getName() ); + annotationUsage.setAttributeValue( "table", generator.getTable() ); + annotationUsage.setAttributeValue( "catalog", generator.getCatalog() ); + annotationUsage.setAttributeValue( "schema", generator.getSchema() ); + annotationUsage.setAttributeValue( "pkColumnName", generator.getPkColumnName() ); + annotationUsage.setAttributeValue( "valueColumnName", generator.getValueColumnName() ); + annotationUsage.setAttributeValue( "pkColumnValue", generator.getPkColumnValue() ); + annotationUsage.setAttributeValue( "initialValue", generator.getInitialValue() ); + annotationUsage.setAttributeValue( "allocationSize", generator.getAllocationSize() ); + + collectTableGenerator( new TableGeneratorRegistration( generator.getName(), annotationUsage ) ); + } ); + } + + public void collectTableGenerator(AnnotationUsage usage) { + collectTableGenerator( new TableGeneratorRegistration( usage.getAttributeValue( "name" ), usage ) ); + } + + public void collectTableGenerator(TableGeneratorRegistration generatorRegistration) { + if ( tableGeneratorRegistrations == null ) { + tableGeneratorRegistrations = new HashMap<>(); + } + + tableGeneratorRegistrations.put( generatorRegistration.getName(), generatorRegistration ); + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Generic generators + + private void collectGenericGenerators(List genericGenerators) { + if ( CollectionHelper.isEmpty( genericGenerators ) ) { + return; + } + + genericGenerators.forEach( (generator) -> { + final DynamicAnnotationUsage annotationUsage = new DynamicAnnotationUsage<>( GenericGenerator.class ); + annotationUsage.setAttributeValue( "name", generator.getName() ); + annotationUsage.setAttributeValue( "strategy", generator.getClazz() ); + + // todo : update the mapping.xsd to account for new @GenericGenerator definition + + collectGenericGenerator( new GenericGeneratorRegistration( generator.getName(), annotationUsage ) ); + } ); + } + + public void collectGenericGenerator(AnnotationUsage usage) { + collectGenericGenerator( new GenericGeneratorRegistration( usage.getAttributeValue( "name" ), usage ) ); + } + + public void collectGenericGenerator(GenericGeneratorRegistration generatorRegistration) { + if ( genericGeneratorRegistrations == null ) { + genericGeneratorRegistrations = new HashMap<>(); + } + + genericGeneratorRegistrations.put( generatorRegistration.getName(), generatorRegistration ); + } +} diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/IdGeneratorRegistration.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/IdGeneratorRegistration.java deleted file mode 100644 index 3bb66ba..0000000 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/IdGeneratorRegistration.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright: Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.models.orm.internal; - -import java.lang.annotation.Annotation; - -import org.hibernate.models.source.spi.AnnotationUsage; - -/** - * Represents both global and local id generator registrations - * - * @author Steve Ebersole - */ -public class IdGeneratorRegistration { - public enum Kind { - SEQUENCE, - TABLE, - UUID, - META, - GENERIC - } - - private final String name; - private final Kind kind; - private final AnnotationUsage configuration; - - public IdGeneratorRegistration(String name, Kind kind, AnnotationUsage configuration) { - this.name = name; - this.kind = kind; - this.configuration = configuration; - } - - /** - * The registration name. For local generators, this may be {@code null} - */ - public String getName() { - return name; - } - - /** - * The kind of generation - */ - public Kind getKind() { - return kind; - } - - /** - * The annotation which configures the generator - */ - public AnnotationUsage getConfiguration() { - return configuration; - } -} diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/ProcessResultCollector.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/ProcessResultCollector.java index be08302..3f8ddc5 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/ProcessResultCollector.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/ProcessResultCollector.java @@ -6,46 +6,20 @@ */ package org.hibernate.models.orm.internal; -import java.lang.annotation.Annotation; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.Set; -import org.hibernate.annotations.Parameter; -import org.hibernate.boot.jaxb.mapping.JaxbCollectionUserTypeRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbCompositeUserTypeRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbConfigurationParameter; -import org.hibernate.boot.jaxb.mapping.JaxbConverterRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbEmbeddableInstantiatorRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbEntityListener; -import org.hibernate.boot.jaxb.mapping.JaxbJavaTypeRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbJdbcTypeRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbUserTypeRegistration; -import org.hibernate.internal.util.collections.CollectionHelper; -import org.hibernate.metamodel.CollectionClassification; -import org.hibernate.models.internal.StringHelper; -import org.hibernate.models.orm.spi.ManagedResources; +import org.hibernate.boot.jaxb.mapping.JaxbEntityListeners; +import org.hibernate.boot.jaxb.mapping.JaxbEntityMappings; +import org.hibernate.boot.jaxb.mapping.JaxbPersistenceUnitDefaults; +import org.hibernate.boot.jaxb.mapping.JaxbPersistenceUnitMetadata; import org.hibernate.models.orm.spi.ProcessResult; import org.hibernate.models.orm.spi.EntityHierarchy; -import org.hibernate.models.orm.spi.Processor; -import org.hibernate.models.source.spi.AnnotationTarget; -import org.hibernate.models.source.spi.AnnotationUsage; import org.hibernate.models.source.spi.ClassDetails; import org.hibernate.models.source.spi.ClassDetailsRegistry; +import org.hibernate.models.source.spi.PackageDetails; import org.hibernate.models.source.spi.SourceModelBuildingContext; -import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; -import static org.hibernate.models.orm.spi.HibernateAnnotations.COLLECTION_TYPE_REG; -import static org.hibernate.models.orm.spi.HibernateAnnotations.COMPOSITE_TYPE_REG; -import static org.hibernate.models.orm.spi.HibernateAnnotations.CONVERTER_REG; -import static org.hibernate.models.orm.spi.HibernateAnnotations.EMBEDDABLE_INSTANTIATOR_REG; -import static org.hibernate.models.orm.spi.HibernateAnnotations.JAVA_TYPE_REG; -import static org.hibernate.models.orm.spi.HibernateAnnotations.JDBC_TYPE_REG; -import static org.hibernate.models.orm.spi.HibernateAnnotations.TYPE_REG; /** * In-flight holder for various types of "global" registrations. Also acts as the @@ -55,327 +29,70 @@ * @author Steve Ebersole */ public class ProcessResultCollector { - private final ClassDetailsRegistry classDetailsRegistry; + private final GlobalRegistrations globalRegistrations; + private final boolean areIdGeneratorsGlobal; - private List entityListenerRegistrations; - private List autoAppliedConverters; - private List converterRegistrations; - private List javaTypeRegistrations; - private List jdbcTypeRegistrations; - private List userTypeRegistrations; - private List compositeUserTypeRegistrations; - private List collectionTypeRegistrations; - private List embeddableInstantiatorRegistrations; - - private Map globalIdGeneratorRegistrations; - private Map jpaNamedQueries; - private Map hibernateNamedHqlQueries; - private Map hibernateNamedNativeQueries; - - public ProcessResultCollector(SourceModelBuildingContext buildingContext) { - this( buildingContext.getClassDetailsRegistry() ); - } - public ProcessResultCollector(ClassDetailsRegistry classDetailsRegistry) { - this.classDetailsRegistry = classDetailsRegistry; - } - - public List getEntityListenerRegistrations() { - return entityListenerRegistrations; - } - - public List getConverterRegistrations() { - return converterRegistrations; - } - - public List getJavaTypeRegistrations() { - return javaTypeRegistrations; - } - - public List getJdbcTypeRegistrations() { - return jdbcTypeRegistrations; - } - - public List getUserTypeRegistrations() { - return userTypeRegistrations; - } - - public List getCompositeUserTypeRegistrations() { - return compositeUserTypeRegistrations; - } - - public List getCollectionTypeRegistrations() { - return collectionTypeRegistrations; - } - - public List getEmbeddableInstantiatorRegistrations() { - return embeddableInstantiatorRegistrations; - } - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // JavaTypeRegistration - - public void collectJavaTypeRegistrations(AnnotationTarget annotationTarget) { - annotationTarget.forEachUsage( JAVA_TYPE_REG, (usage) -> collectJavaTypeRegistration( - usage.getAttributeValue( "javaType" ), - usage.getAttributeValue( "descriptorClass" ) - ) ); - } - - public void collectJavaTypeRegistrations(List registrations) { - if ( CollectionHelper.isEmpty( registrations ) ) { - return; - } - - registrations.forEach( (reg) -> collectJavaTypeRegistration( - classDetailsRegistry.resolveClassDetails( reg.getClazz() ), - classDetailsRegistry.resolveClassDetails( reg.getDescriptor() ) - ) ); + public ProcessResultCollector(boolean areIdGeneratorsGlobal, SourceModelBuildingContext sourceModelBuildingContext) { + this.globalRegistrations = new GlobalRegistrations( sourceModelBuildingContext ); + this.areIdGeneratorsGlobal = areIdGeneratorsGlobal; } - public void collectJavaTypeRegistration(ClassDetails javaType, ClassDetails descriptor) { - if ( javaTypeRegistrations == null ) { - javaTypeRegistrations = new ArrayList<>(); - } - javaTypeRegistrations.add( new JavaTypeRegistration( javaType, descriptor ) ); - } - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // JdbcTypeRegistration - - public void collectJdbcTypeRegistrations(AnnotationTarget annotationTarget) { - annotationTarget.forEachUsage( JDBC_TYPE_REG, (usage) -> collectJdbcTypeRegistration( - usage.getAttributeValue( "registrationCode" ), - usage.getAttributeValue( "value" ) - ) ); + public GlobalRegistrations getGlobalRegistrations() { + return globalRegistrations; } - public void collectJdbcTypeRegistrations(List registrations) { - if ( CollectionHelper.isEmpty( registrations ) ) { - return; - } - - registrations.forEach( (reg) -> collectJdbcTypeRegistration( - reg.getCode(), - classDetailsRegistry.resolveClassDetails( reg.getDescriptor() ) - ) ); - } - - public void collectJdbcTypeRegistration(Integer registrationCode, ClassDetails descriptor) { - if ( jdbcTypeRegistrations == null ) { - jdbcTypeRegistrations = new ArrayList<>(); - } - jdbcTypeRegistrations.add( new JdbcTypeRegistration( registrationCode, descriptor ) ); - } + public void apply(JaxbEntityMappings jaxbRoot) { + getGlobalRegistrations().collectJavaTypeRegistrations( jaxbRoot.getJavaTypeRegistrations() ); + getGlobalRegistrations().collectJdbcTypeRegistrations( jaxbRoot.getJdbcTypeRegistrations() ); + getGlobalRegistrations().collectConverterRegistrations( jaxbRoot.getConverterRegistrations() ); + getGlobalRegistrations().collectUserTypeRegistrations( jaxbRoot.getUserTypeRegistrations() ); + getGlobalRegistrations().collectCompositeUserTypeRegistrations( jaxbRoot.getCompositeUserTypeRegistrations() ); + getGlobalRegistrations().collectCollectionTypeRegistrations( jaxbRoot.getCollectionUserTypeRegistrations() ); + getGlobalRegistrations().collectEmbeddableInstantiatorRegistrations( jaxbRoot.getEmbeddableInstantiatorRegistrations() ); - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // ConversionRegistration - - public void collectConverterRegistrations(AnnotationTarget annotationTarget) { - annotationTarget.forEachUsage( CONVERTER_REG, (usage) -> { - final ClassDetails domainType = usage.getAttributeValue( "domainType" ); - final ClassDetails converterType = usage.getAttributeValue( "converter" ); - final boolean autoApply = usage.getAttributeValue( "autoApply" ); - collectConverterRegistration( new ConversionRegistration( domainType, converterType, autoApply ) ); - } ); - } - - public void collectConverterRegistrations(List registrations) { - if ( CollectionHelper.isEmpty( registrations ) ) { - return; - } - - registrations.forEach( (registration) -> { - final ClassDetails explicitDomainType; - final String explicitDomainTypeName = registration.getClazz(); - if ( StringHelper.isNotEmpty( explicitDomainTypeName ) ) { - explicitDomainType = classDetailsRegistry.resolveClassDetails( explicitDomainTypeName ); - } - else { - explicitDomainType = null; + final JaxbPersistenceUnitMetadata persistenceUnitMetadata = jaxbRoot.getPersistenceUnitMetadata(); + if ( persistenceUnitMetadata != null ) { + final JaxbPersistenceUnitDefaults persistenceUnitDefaults = persistenceUnitMetadata.getPersistenceUnitDefaults(); + final JaxbEntityListeners entityListeners = persistenceUnitDefaults.getEntityListeners(); + if ( entityListeners != null ) { + getGlobalRegistrations().collectEntityListenerRegistrations( entityListeners.getEntityListener() ); } - final ClassDetails converterType = classDetailsRegistry.resolveClassDetails( registration.getConverter() ); - final boolean autoApply = registration.isAutoApply(); - collectConverterRegistration( new ConversionRegistration( explicitDomainType, converterType, autoApply ) ); - } ); - } - - public void collectConverterRegistration(ConversionRegistration conversion) { - if ( converterRegistrations == null ) { - converterRegistrations = new ArrayList<>(); } - converterRegistrations.add( conversion ); - } + getGlobalRegistrations().collectIdGenerators( jaxbRoot ); - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // UserTypeRegistration - - public void collectUserTypeRegistrations(AnnotationTarget annotationTarget) { - annotationTarget.forEachUsage( TYPE_REG, (usage) -> collectUserTypeRegistration( - usage.getAttributeValue( "basicClass" ), - usage.getAttributeValue( "userType" ) - ) ); + // todo : named queries + // todo : named graphs } - public void collectUserTypeRegistrations(List registrations) { - if ( CollectionHelper.isEmpty( registrations ) ) { - return; - } + public void apply(ClassDetails classDetails) { + getGlobalRegistrations().collectJavaTypeRegistrations( classDetails ); + getGlobalRegistrations().collectJdbcTypeRegistrations( classDetails ); + getGlobalRegistrations().collectConverterRegistrations( classDetails ); + getGlobalRegistrations().collectUserTypeRegistrations( classDetails ); + getGlobalRegistrations().collectCompositeUserTypeRegistrations( classDetails ); + getGlobalRegistrations().collectCollectionTypeRegistrations( classDetails ); + getGlobalRegistrations().collectEmbeddableInstantiatorRegistrations( classDetails ); - registrations.forEach( (reg) -> { - final ClassDetails domainTypeDetails = classDetailsRegistry.resolveClassDetails( reg.getClazz() ); - final ClassDetails descriptorDetails = classDetailsRegistry.resolveClassDetails( reg.getDescriptor() ); - collectUserTypeRegistration( domainTypeDetails, descriptorDetails ); - } ); - } - - public void collectUserTypeRegistration(ClassDetails domainClass, ClassDetails userTypeClass) { - if ( userTypeRegistrations == null ) { - userTypeRegistrations = new ArrayList<>(); + if ( areIdGeneratorsGlobal ) { + getGlobalRegistrations().collectIdGenerators( classDetails ); } - userTypeRegistrations.add( new UserTypeRegistration( domainClass, userTypeClass ) ); - } - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CompositeUserTypeRegistration - public void collectCompositeUserTypeRegistrations(AnnotationTarget annotationTarget) { - annotationTarget.forEachUsage( COMPOSITE_TYPE_REG, (usage) -> collectCompositeUserTypeRegistration( - usage.getAttributeValue( "embeddableClass" ), - usage.getAttributeValue( "userType" ) - ) ); + // todo : named queries + // todo : named graphs } - public void collectCompositeUserTypeRegistrations(List registrations) { - if ( CollectionHelper.isEmpty( registrations ) ) { - return; - } - - registrations.forEach( (reg) -> collectCompositeUserTypeRegistration( - classDetailsRegistry.resolveClassDetails( reg.getClazz() ), - classDetailsRegistry.resolveClassDetails( reg.getDescriptor() ) - ) ); - } - - public void collectCompositeUserTypeRegistration(ClassDetails domainClass, ClassDetails userTypeClass) { - if ( compositeUserTypeRegistrations == null ) { - compositeUserTypeRegistrations = new ArrayList<>(); - } - compositeUserTypeRegistrations.add( new CompositeUserTypeRegistration( domainClass, userTypeClass ) ); - } - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CollectionTypeRegistration - - public void collectCollectionTypeRegistrations(AnnotationTarget annotationTarget) { - annotationTarget.forEachUsage( COLLECTION_TYPE_REG, (usage) -> collectCollectionTypeRegistration( - usage.getAttributeValue( "classification" ), - usage.getAttributeValue( "type" ), - extractParameterMap( usage ) - ) ); - } - - private Map extractParameterMap(AnnotationUsage source) { - final List> parameters = source.getAttributeValue( "parameters" ); - - final Map result = new HashMap<>(); - for ( AnnotationUsage parameter : parameters ) { - result.put( - parameter.getAttributeValue( "name" ), - parameter.getAttributeValue( "value" ) - ); - } - return result; - } - - public void collectCollectionTypeRegistrations(List registrations) { - if ( CollectionHelper.isEmpty( registrations ) ) { - return; - } - - registrations.forEach( (reg) -> collectCollectionTypeRegistration( - reg.getClassification(), - classDetailsRegistry.resolveClassDetails( reg.getDescriptor() ), - extractParameterMap( reg.getParameters() ) - ) ); - } - - private Map extractParameterMap(List parameters) { - if ( CollectionHelper.isEmpty( parameters ) ) { - return Collections.emptyMap(); - } - - final Map result = new HashMap<>(); - parameters.forEach( parameter -> result.put( parameter.getName(), parameter.getValue() ) ); - return result; - } - - public void collectCollectionTypeRegistration( - CollectionClassification classification, - ClassDetails userTypeClass, - Map parameters) { - if ( collectionTypeRegistrations == null ) { - collectionTypeRegistrations = new ArrayList<>(); - } - collectionTypeRegistrations.add( new CollectionTypeRegistration( classification, userTypeClass, parameters ) ); - } - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // EmbeddableInstantiatorRegistration - - public void collectEmbeddableInstantiatorRegistrations(AnnotationTarget annotationTarget) { - annotationTarget.forEachUsage( EMBEDDABLE_INSTANTIATOR_REG, (usage) -> collectEmbeddableInstantiatorRegistration( - usage.getAttributeValue( "embeddableClass" ), - usage.getAttributeValue( "instantiator" ) - ) ); - } - - public void collectEmbeddableInstantiatorRegistrations(List registrations) { - if ( CollectionHelper.isEmpty( registrations ) ) { - return; - } - - registrations.forEach( (reg) -> collectEmbeddableInstantiatorRegistration( - classDetailsRegistry.resolveClassDetails( reg.getEmbeddableClass() ), - classDetailsRegistry.resolveClassDetails( reg.getInstantiator() ) - ) ); - } - - public void collectEmbeddableInstantiatorRegistration(ClassDetails embeddableClass, ClassDetails instantiator) { - if ( embeddableInstantiatorRegistrations == null ) { - embeddableInstantiatorRegistrations = new ArrayList<>(); - } - embeddableInstantiatorRegistrations.add( new EmbeddableInstantiatorRegistration( embeddableClass, instantiator ) ); - } - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // EntityListenerRegistration - - public void collectEntityListenerRegistrations(List listeners) { - if ( CollectionHelper.isEmpty( listeners ) ) { - return; - } - - listeners.forEach( (listener) -> EntityListenerRegistration.from( listener, classDetailsRegistry ) ); - } - - - public void collectGlobalIdGeneratorRegistration( - String name, - IdGeneratorRegistration.Kind kind, - AnnotationUsage annotation) { - if ( globalIdGeneratorRegistrations == null ) { - globalIdGeneratorRegistrations = new HashMap<>(); - } + public void apply(PackageDetails packageDetails) { + getGlobalRegistrations().collectJavaTypeRegistrations( packageDetails ); + getGlobalRegistrations().collectJdbcTypeRegistrations( packageDetails ); + getGlobalRegistrations().collectConverterRegistrations( packageDetails ); + getGlobalRegistrations().collectUserTypeRegistrations( packageDetails ); + getGlobalRegistrations().collectCompositeUserTypeRegistrations( packageDetails ); + getGlobalRegistrations().collectCollectionTypeRegistrations( packageDetails ); + getGlobalRegistrations().collectEmbeddableInstantiatorRegistrations( packageDetails ); - globalIdGeneratorRegistrations.put( name, new IdGeneratorRegistration( name, kind, annotation ) ); + // todo : others? } /** @@ -390,18 +107,20 @@ public void collectGlobalIdGeneratorRegistration( public ProcessResult createResult(Set entityHierarchies) { return new ProcessResultImpl( entityHierarchies, - javaTypeRegistrations == null ? emptyList() : javaTypeRegistrations, - jdbcTypeRegistrations == null ? emptyList() : jdbcTypeRegistrations, - converterRegistrations == null ? emptyList() : converterRegistrations, - autoAppliedConverters == null ? emptyList() : autoAppliedConverters, - userTypeRegistrations == null ? emptyList() : userTypeRegistrations, - compositeUserTypeRegistrations == null ? emptyList() : compositeUserTypeRegistrations, - collectionTypeRegistrations == null ? emptyList() : collectionTypeRegistrations, - embeddableInstantiatorRegistrations == null ? emptyList() : embeddableInstantiatorRegistrations, - globalIdGeneratorRegistrations == null ? emptyMap() : globalIdGeneratorRegistrations, - jpaNamedQueries == null ? emptyMap() : jpaNamedQueries, - hibernateNamedHqlQueries == null ? emptyMap() : hibernateNamedHqlQueries, - hibernateNamedNativeQueries == null ? emptyMap() : hibernateNamedNativeQueries + getGlobalRegistrations().getJavaTypeRegistrations(), + getGlobalRegistrations().getJdbcTypeRegistrations(), + getGlobalRegistrations().getConverterRegistrations(), + getGlobalRegistrations().getAutoAppliedConverters(), + getGlobalRegistrations().getUserTypeRegistrations(), + getGlobalRegistrations().getCompositeUserTypeRegistrations(), + getGlobalRegistrations().getCollectionTypeRegistrations(), + getGlobalRegistrations().getEmbeddableInstantiatorRegistrations(), +// jpaNamedQueries == null ? emptyMap() : jpaNamedQueries, +// hibernateNamedHqlQueries == null ? emptyMap() : hibernateNamedHqlQueries, +// hibernateNamedNativeQueries == null ? emptyMap() : hibernateNamedNativeQueries + emptyMap(), + emptyMap(), + emptyMap() ); } } diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/ProcessResultImpl.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/ProcessResultImpl.java index 203548f..2fb0706 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/ProcessResultImpl.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/ProcessResultImpl.java @@ -28,7 +28,6 @@ public class ProcessResultImpl implements ProcessResult { private final List compositeUserTypeRegistrations; private final List collectionTypeRegistrations; private final List embeddableInstantiatorRegistrations; - private final Map globalIdGeneratorRegistrations; private final Map jpaNamedQueries; private final Map hibernateNamedHqlQueries; private final Map hibernateNamedNativeQueries; @@ -43,7 +42,6 @@ public ProcessResultImpl( List compositeUserTypeRegistrations, List collectionTypeRegistrations, List embeddableInstantiatorRegistrations, - Map globalIdGeneratorRegistrations, Map jpaNamedQueries, Map hibernateNamedHqlQueries, Map hibernateNamedNativeQueries) { @@ -56,7 +54,6 @@ public ProcessResultImpl( this.compositeUserTypeRegistrations = compositeUserTypeRegistrations; this.collectionTypeRegistrations = collectionTypeRegistrations; this.embeddableInstantiatorRegistrations = embeddableInstantiatorRegistrations; - this.globalIdGeneratorRegistrations = globalIdGeneratorRegistrations; this.jpaNamedQueries = jpaNamedQueries; this.hibernateNamedHqlQueries = hibernateNamedHqlQueries; this.hibernateNamedNativeQueries = hibernateNamedNativeQueries; @@ -107,11 +104,6 @@ public List getEmbeddableInstantiatorRegistr return embeddableInstantiatorRegistrations; } - @Override - public Map getGlobalIdGeneratorRegistrations() { - return globalIdGeneratorRegistrations; - } - @Override public Map getJpaNamedQueries() { return jpaNamedQueries; diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/SequenceGeneratorRegistration.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/SequenceGeneratorRegistration.java new file mode 100644 index 0000000..d81257f --- /dev/null +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/SequenceGeneratorRegistration.java @@ -0,0 +1,36 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright: Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.models.orm.internal; + +import org.hibernate.models.source.spi.AnnotationUsage; + +import jakarta.persistence.SequenceGenerator; + +/** + * Global registration of a sequence generator + * + * @see org.hibernate.models.orm.spi.Processor.Options#areGeneratorsGlobal() + * + * @author Steve Ebersole + */ +public class SequenceGeneratorRegistration { + private final String name; + private final AnnotationUsage configuration; + + public SequenceGeneratorRegistration(String name, AnnotationUsage configuration) { + this.name = name; + this.configuration = configuration; + } + + public String getName() { + return name; + } + + public AnnotationUsage getConfiguration() { + return configuration; + } +} diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/TableGeneratorRegistration.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/TableGeneratorRegistration.java new file mode 100644 index 0000000..eede186 --- /dev/null +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/TableGeneratorRegistration.java @@ -0,0 +1,36 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright: Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.models.orm.internal; + +import org.hibernate.models.source.spi.AnnotationUsage; + +import jakarta.persistence.TableGenerator; + +/** + * Global registration of a table generator + * + * @see org.hibernate.models.orm.spi.Processor.Options#areGeneratorsGlobal() + * + * @author Steve Ebersole + */ +public class TableGeneratorRegistration { + private final String name; + private final AnnotationUsage configuration; + + public TableGeneratorRegistration(String name, AnnotationUsage configuration) { + this.name = name; + this.configuration = configuration; + } + + public String getName() { + return name; + } + + public AnnotationUsage getConfiguration() { + return configuration; + } +} diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/spi/ProcessResult.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/spi/ProcessResult.java index 2d81e38..e7e3cc6 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/spi/ProcessResult.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/spi/ProcessResult.java @@ -14,7 +14,6 @@ import org.hibernate.models.orm.internal.CompositeUserTypeRegistration; import org.hibernate.models.orm.internal.ConversionRegistration; import org.hibernate.models.orm.internal.EmbeddableInstantiatorRegistration; -import org.hibernate.models.orm.internal.IdGeneratorRegistration; import org.hibernate.models.orm.internal.JavaTypeRegistration; import org.hibernate.models.orm.internal.JdbcTypeRegistration; import org.hibernate.models.orm.internal.NamedQueryRegistration; @@ -45,8 +44,6 @@ public interface ProcessResult { List getEmbeddableInstantiatorRegistrations(); - Map getGlobalIdGeneratorRegistrations(); - Map getJpaNamedQueries(); Map getHibernateNamedHqlQueries(); diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/spi/Processor.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/spi/Processor.java index 0f0653e..918a364 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/spi/Processor.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/spi/Processor.java @@ -90,7 +90,7 @@ public static ProcessResult process( SourceModelBuildingContext sourceModelBuildingContext, OrmModelBuildingContext mappingBuildingContext) { final XmlResources collectedXmlResources = collectXmlResources( managedResources, mappingBuildingContext ); - final ProcessResultCollector processResultCollector = new ProcessResultCollector( sourceModelBuildingContext.getClassDetailsRegistry() ); + final ProcessResultCollector processResultCollector = new ProcessResultCollector( options.areGeneratorsGlobal(), sourceModelBuildingContext ); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // process XML @@ -107,14 +107,7 @@ public static ProcessResult process( final boolean xmlMappingsGloballyComplete = collectedXmlResources.getPersistenceUnitMetadata().areXmlMappingsComplete(); collectedXmlResources.getDocuments().forEach( (jaxbRoot) -> { - processResultCollector.collectJavaTypeRegistrations( jaxbRoot.getJavaTypeRegistrations() ); - processResultCollector.collectJdbcTypeRegistrations( jaxbRoot.getJdbcTypeRegistrations() ); - processResultCollector.collectConverterRegistrations( jaxbRoot.getConverterRegistrations() ); - processResultCollector.collectUserTypeRegistrations( jaxbRoot.getUserTypeRegistrations() ); - processResultCollector.collectCompositeUserTypeRegistrations( jaxbRoot.getCompositeUserTypeRegistrations() ); - processResultCollector.collectCollectionTypeRegistrations( jaxbRoot.getCollectionUserTypeRegistrations() ); - processResultCollector.collectEmbeddableInstantiatorRegistrations( jaxbRoot.getEmbeddableInstantiatorRegistrations() ); - processResultCollector.collectEntityListenerRegistrations( jaxbRoot.getPersistenceUnitMetadata().getPersistenceUnitDefaults().getEntityListeners().getEntityListener() ); + processResultCollector.apply( jaxbRoot ); jaxbRoot.getEmbeddables().forEach( (embeddable) -> { if ( xmlMappingsGloballyComplete || embeddable.isMetadataComplete() ) { @@ -144,18 +137,16 @@ public static ProcessResult process( } ); } ); - final ClassInclusions classInclusions; - final PackageInclusions packageInclusions; + final ActiveClassInclusions classInclusions; + final ActivePackageInclusions packageInclusions; if ( options.shouldIgnoreUnlistedClasses() ) { - final List listedClasses = new ArrayList<>(); - final List listedPackages = new ArrayList<>(); - classInclusions = listedClasses::contains; - packageInclusions = listedPackages::contains; + classInclusions = new ActiveClassInclusions(); + packageInclusions = new ActivePackageInclusions(); if ( CollectionHelper.isEmpty( explicitlyListedClasses ) ) { OrmModelLogging.ORM_MODEL_LOGGER.debugf( "Ignore unlisted classes was requested, but no classes were listed" ); } else { - collectListedResources( explicitlyListedClasses, listedClasses, listedPackages, sourceModelBuildingContext ); + collectListedResources( explicitlyListedClasses, classInclusions, packageInclusions, sourceModelBuildingContext ); } } else { @@ -180,7 +171,6 @@ public static ProcessResult process( allEntities, mappedSuperClasses, embeddables, - options, mappingBuildingContext ); @@ -249,8 +239,8 @@ private static void applyCompleteEmbeddableMapping(JaxbEmbeddable embeddable, private static void collectListedResources( List explicitlyListedClasses, - List listedClasses, - List listedPackages, + ActiveClassInclusions classInclusions, + ActivePackageInclusions packageInclusions, SourceModelBuildingContext sourceModelBuildingContext) { final ClassDetailsRegistry classDetailsRegistry = sourceModelBuildingContext.getClassDetailsRegistry(); final ClassLoading classLoading = sourceModelBuildingContext.getClassLoadingAccess(); @@ -261,7 +251,7 @@ private static void collectListedResources( final String packageName = StringHelper.qualifier( listed ); final Package packageForName = classLoading.packageForName( packageName ); assert packageForName != null; - listedPackages.add( classDetailsRegistry.resolvePackageDetails( + packageInclusions.addInclusion( classDetailsRegistry.resolvePackageDetails( packageName, () -> new JdkPackageDetailsImpl( packageForName, sourceModelBuildingContext ) ) ); @@ -271,7 +261,7 @@ private static void collectListedResources( try { final ClassDetails classDetails = classDetailsRegistry.resolveClassDetails( listed ); if ( classDetails != null ) { - listedClasses.add( classDetails ); + classInclusions.addInclusion( classDetails ); } } catch (UnknownClassException e) { @@ -281,7 +271,7 @@ private static void collectListedResources( // todo : what to do here? } else { - listedPackages.add( classDetailsRegistry.resolvePackageDetails( + packageInclusions.addInclusion( classDetailsRegistry.resolvePackageDetails( listed, () -> new JdkPackageDetailsImpl( packageForName, sourceModelBuildingContext ) ) ); @@ -364,7 +354,6 @@ private static void processResources( Map allEntities, Map mappedSuperClasses, Map embeddables, - Options options, OrmModelBuildingContext mappingBuildingContext) { final ClassDetailsRegistry classDetailsRegistry = mappingBuildingContext.getClassDetailsRegistry(); classDetailsRegistry.forEachClassDetails( (classDetails) -> { @@ -373,13 +362,7 @@ private static void processResources( return; } - processResultCollector.collectJavaTypeRegistrations( classDetails ); - processResultCollector.collectJdbcTypeRegistrations( classDetails ); - processResultCollector.collectConverterRegistrations( classDetails ); - processResultCollector.collectUserTypeRegistrations( classDetails ); - processResultCollector.collectCompositeUserTypeRegistrations( classDetails ); - processResultCollector.collectCollectionTypeRegistrations( classDetails ); - processResultCollector.collectEmbeddableInstantiatorRegistrations( classDetails ); + processResultCollector.apply( classDetails ); if ( classDetails.getUsage( JpaAnnotations.MAPPED_SUPERCLASS ) != null ) { if ( classDetails.getClassName() != null ) { @@ -413,13 +396,7 @@ else if ( classDetails.getUsage( Embeddable.class ) != null ) { return; } - processResultCollector.collectJavaTypeRegistrations( packageDetails ); - processResultCollector.collectJdbcTypeRegistrations( packageDetails ); - processResultCollector.collectConverterRegistrations( packageDetails ); - processResultCollector.collectUserTypeRegistrations( packageDetails ); - processResultCollector.collectCompositeUserTypeRegistrations( packageDetails ); - processResultCollector.collectCollectionTypeRegistrations( packageDetails ); - processResultCollector.collectEmbeddableInstantiatorRegistrations( packageDetails ); + processResultCollector.apply( packageDetails ); } ); } @@ -428,11 +405,37 @@ private interface ClassInclusions { boolean shouldInclude(ClassDetails classDetails); } + private static class ActiveClassInclusions implements ClassInclusions { + private final Set inclusionList = new HashSet<>(); + + private void addInclusion(ClassDetails classDetails) { + inclusionList.add( classDetails ); + } + + @Override + public boolean shouldInclude(ClassDetails classDetails) { + return inclusionList.contains( classDetails ); + } + } + @FunctionalInterface private interface PackageInclusions { boolean shouldInclude(PackageDetails packageDetails); } + private static class ActivePackageInclusions implements PackageInclusions { + private final Set inclusionList = new HashSet<>(); + + private void addInclusion(PackageDetails packageDetails) { + inclusionList.add( packageDetails ); + } + + @Override + public boolean shouldInclude(PackageDetails packageDetails) { + return inclusionList.contains( packageDetails ); + } + } + private static void processIdentifiableType( ClassDetails classDetails, OrmModelBuildingContext mappingBuildingContext) { diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlProcessingState.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlProcessingState.java deleted file mode 100644 index 376b666..0000000 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlProcessingState.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright: Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.models.orm.xml.internal; - -import java.util.ArrayList; -import java.util.List; - -import org.hibernate.boot.jaxb.mapping.ManagedType; -import org.hibernate.models.orm.xml.spi.XmlProcessingContext; - -/** - * @author Steve Ebersole - */ -public class XmlProcessingState { - private final XmlProcessingContext processingContext; - private final PersistenceUnitMetadataImpl persistenceUnitMetadata = new PersistenceUnitMetadataImpl(); - - private final List xmlOverrideMappings = new ArrayList<>(); - private final List completeMappings = new ArrayList<>(); - - public XmlProcessingState(XmlProcessingContext processingContext) { - this.processingContext = processingContext; - } - -} diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/XmlProcessingContext.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/XmlProcessingContext.java deleted file mode 100644 index a61a99e..0000000 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/XmlProcessingContext.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright: Red Hat Inc. and Hibernate Authors - */ -package org.hibernate.models.orm.xml.spi; - -/** - * @author Steve Ebersole - */ -public interface XmlProcessingContext { -} diff --git a/hibernate-models-orm/src/test/java/org/hibernate/models/orm/xml/XmlProcessingSmokeTests.java b/hibernate-models-orm/src/test/java/org/hibernate/models/orm/xml/XmlProcessingSmokeTests.java index 051827d..f0b6f1b 100644 --- a/hibernate-models-orm/src/test/java/org/hibernate/models/orm/xml/XmlProcessingSmokeTests.java +++ b/hibernate-models-orm/src/test/java/org/hibernate/models/orm/xml/XmlProcessingSmokeTests.java @@ -9,6 +9,7 @@ import java.util.List; import org.hibernate.boot.jaxb.mapping.JaxbEntityMappings; +import org.hibernate.models.orm.internal.GlobalRegistrations; import org.hibernate.models.orm.internal.ProcessResultCollector; import org.hibernate.models.orm.xml.internal.XmlDocumentImpl; import org.hibernate.models.orm.xml.spi.XmlResources; @@ -114,31 +115,24 @@ void testSimpleGlobalXmlProcessing() { final JaxbEntityMappings xmlMapping = loadMapping( "mappings/globals.xml", SIMPLE_CLASS_LOADING ); collectedXmlResources.addDocument( xmlMapping ); - final ProcessResultCollector processResultCollector = new ProcessResultCollector( buildingContext.getClassDetailsRegistry() ); - collectedXmlResources.getDocuments().forEach( (jaxbRoot) -> { - processResultCollector.collectJavaTypeRegistrations( jaxbRoot.getJavaTypeRegistrations() ); - processResultCollector.collectJdbcTypeRegistrations( jaxbRoot.getJdbcTypeRegistrations() ); - processResultCollector.collectConverterRegistrations( jaxbRoot.getConverterRegistrations() ); - processResultCollector.collectUserTypeRegistrations( jaxbRoot.getUserTypeRegistrations() ); - processResultCollector.collectCompositeUserTypeRegistrations( jaxbRoot.getCompositeUserTypeRegistrations() ); - processResultCollector.collectCollectionTypeRegistrations( jaxbRoot.getCollectionUserTypeRegistrations() ); - processResultCollector.collectEmbeddableInstantiatorRegistrations( jaxbRoot.getEmbeddableInstantiatorRegistrations() ); - } ); - - assertThat( processResultCollector.getJavaTypeRegistrations() ).hasSize( 1 ); - assertThat( processResultCollector.getJavaTypeRegistrations().get(0).getDescriptor().getClassName() ) + final ProcessResultCollector processResultCollector = new ProcessResultCollector( false, buildingContext ); + collectedXmlResources.getDocuments().forEach( processResultCollector::apply ); + + final GlobalRegistrations globalRegistrations = processResultCollector.getGlobalRegistrations(); + assertThat( globalRegistrations.getJavaTypeRegistrations() ).hasSize( 1 ); + assertThat( globalRegistrations.getJavaTypeRegistrations().get(0).getDescriptor().getClassName() ) .isEqualTo( StringTypeDescriptor.class.getName() ); - assertThat( processResultCollector.getJdbcTypeRegistrations() ).hasSize( 1 ); - assertThat( processResultCollector.getJdbcTypeRegistrations().get(0).getDescriptor().getClassName() ) + assertThat( globalRegistrations.getJdbcTypeRegistrations() ).hasSize( 1 ); + assertThat( globalRegistrations.getJdbcTypeRegistrations().get(0).getDescriptor().getClassName() ) .isEqualTo( ClobJdbcType.class.getName() ); - assertThat( processResultCollector.getUserTypeRegistrations() ).hasSize( 1 ); - assertThat( processResultCollector.getUserTypeRegistrations().get(0).getUserTypeClass().getClassName() ) + assertThat( globalRegistrations.getUserTypeRegistrations() ).hasSize( 1 ); + assertThat( globalRegistrations.getUserTypeRegistrations().get(0).getUserTypeClass().getClassName() ) .isEqualTo( MyUserType.class.getName() ); - assertThat( processResultCollector.getConverterRegistrations() ).hasSize( 1 ); - assertThat( processResultCollector.getConverterRegistrations().get(0).getConverterType().getClassName() ) + assertThat( globalRegistrations.getConverterRegistrations() ).hasSize( 1 ); + assertThat( globalRegistrations.getConverterRegistrations().get(0).getConverterType().getClassName() ) .isEqualTo( org.hibernate.type.YesNoConverter.class.getName() ); } } diff --git a/hibernate-models-source/src/main/java/org/hibernate/models/source/internal/dynamic/DynamicAnnotationUsage.java b/hibernate-models-source/src/main/java/org/hibernate/models/source/internal/dynamic/DynamicAnnotationUsage.java new file mode 100644 index 0000000..87e6db0 --- /dev/null +++ b/hibernate-models-source/src/main/java/org/hibernate/models/source/internal/dynamic/DynamicAnnotationUsage.java @@ -0,0 +1,58 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright: Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.models.source.internal.dynamic; + +import java.lang.annotation.Annotation; +import java.util.HashMap; +import java.util.Map; + +import org.hibernate.models.source.spi.AnnotationTarget; +import org.hibernate.models.source.spi.AnnotationUsage; + +/** + * @author Steve Ebersole + */ +public class DynamicAnnotationUsage implements AnnotationUsage { + private final Class annotationType; + private final AnnotationTarget target; + + private Map values; + + public DynamicAnnotationUsage(Class annotationType) { + this( annotationType, null ); + } + + public DynamicAnnotationUsage(Class annotationType, AnnotationTarget target) { + this.annotationType = annotationType; + this.target = target; + } + + @Override + public Class getAnnotationType() { + return annotationType; + } + + @Override + public AnnotationTarget getAnnotationTarget() { + return target; + } + + @Override + public V getAttributeValue(String name) { + //noinspection unchecked + return values == null ? null : (V) values.get( name ); + } + + public V setAttributeValue(String name, V value) { + if ( values == null ) { + values = new HashMap<>(); + } + + //noinspection unchecked + return (V) values.put( name, value ); + } +}