From 5ba6a8a829a7758f3c77fefb749aff435e74b0fd Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Sun, 22 Oct 2023 22:21:38 -0500 Subject: [PATCH] #46 - Support overrides #47 - Support dynamic and mappings https://github.com/sebersole/hibernate-models2/issues/46 https://github.com/sebersole/hibernate-models2/issues/47 --- .../hibernate-models-orm.gradle | 2 +- .../annotations/internal/Extends.java | 26 + .../models/orm/HibernateAnnotations.java | 2 + .../orm/internal/GlobalRegistrationsImpl.java | 62 +- .../orm/internal/ProcessResultCollector.java | 16 +- .../orm/spi/EntityListenerRegistration.java | 4 +- .../hibernate/models/orm/spi/Processor.java | 24 +- .../orm/xml/internal/AttributeProcessor.java | 251 ++++--- .../xml/internal/ManagedTypeProcessor.java | 680 ++++++++++++++++-- .../internal/PersistenceUnitMetadataImpl.java | 14 +- .../orm/xml/internal/XmlAnnotationHelper.java | 174 +++-- .../orm/xml/internal/XmlDocumentImpl.java | 132 ++-- .../orm/xml/internal/XmlProcessingHelper.java | 6 +- .../orm/xml/spi/PersistenceUnitMetadata.java | 4 +- .../models/orm/xml/spi/XmlDocument.java | 56 +- .../models/orm/xml/spi/XmlResources.java | 14 +- .../org/hibernate/models/orm/XmlHelper.java | 10 +- .../orm/xml/XmlProcessingSmokeTests.java | 12 +- .../orm/xml/dynamic/DynamicModelTests.java | 75 ++ .../xml/override/SimpleOverrideXmlTests.java | 1 - .../mappings/dynamic/dynamic-simple.xml | 29 + .../internal/dynamic/MapModeFieldDetails.java | 43 ++ .../internal/jandex/JandexBuilders.java | 45 +- settings.gradle | 3 +- todos.adoc | 9 +- 25 files changed, 1282 insertions(+), 412 deletions(-) create mode 100644 hibernate-models-orm/src/main/java/org/hibernate/annotations/internal/Extends.java create mode 100644 hibernate-models-orm/src/test/java/org/hibernate/models/orm/xml/dynamic/DynamicModelTests.java create mode 100644 hibernate-models-orm/src/test/resources/mappings/dynamic/dynamic-simple.xml create mode 100644 hibernate-models-source/src/main/java/org/hibernate/models/source/internal/dynamic/MapModeFieldDetails.java diff --git a/hibernate-models-orm/hibernate-models-orm.gradle b/hibernate-models-orm/hibernate-models-orm.gradle index 894fabb..91f3f6d 100644 --- a/hibernate-models-orm/hibernate-models-orm.gradle +++ b/hibernate-models-orm/hibernate-models-orm.gradle @@ -18,7 +18,7 @@ dependencies { annotationProcessor libs.loggingAnnotations testImplementation project( ":hibernate-models-testing" ) - testImplementation libs.hibernateTesting +// testImplementation libs.hibernateTesting testImplementation testLibs.jpa testRuntimeOnly testLibs.log4j } diff --git a/hibernate-models-orm/src/main/java/org/hibernate/annotations/internal/Extends.java b/hibernate-models-orm/src/main/java/org/hibernate/annotations/internal/Extends.java new file mode 100644 index 0000000..82a96ee --- /dev/null +++ b/hibernate-models-orm/src/main/java/org/hibernate/annotations/internal/Extends.java @@ -0,0 +1,26 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright: Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.annotations.internal; + +import java.lang.annotation.ElementType; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.Retention; + +/** + * Used to configure inheritance in dynamic models defined in XML + * + * @author Steve Ebersole + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Extends { + /** + * The type extended. String because dynamic models have named "classes". + */ + String superType(); +} diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/HibernateAnnotations.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/HibernateAnnotations.java index e1a5b48..446bc9d 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/HibernateAnnotations.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/HibernateAnnotations.java @@ -10,6 +10,7 @@ import java.util.function.Consumer; import org.hibernate.annotations.*; +import org.hibernate.annotations.internal.Extends; import org.hibernate.models.orm.internal.OrmAnnotationHelper; import org.hibernate.models.source.spi.AnnotationDescriptor; @@ -67,6 +68,7 @@ public interface HibernateAnnotations { AnnotationDescriptor EMBEDDABLE_INSTANTIATOR = createOrmDescriptor( EmbeddableInstantiator.class ); AnnotationDescriptor EMBEDDABLE_INSTANTIATOR_REGS = createOrmDescriptor( EmbeddableInstantiatorRegistrations.class ); AnnotationDescriptor EMBEDDABLE_INSTANTIATOR_REG = createOrmDescriptor( EmbeddableInstantiatorRegistration.class, EMBEDDABLE_INSTANTIATOR_REGS ); + AnnotationDescriptor EXTENDS = createOrmDescriptor( Extends.class ); AnnotationDescriptor FETCH = createOrmDescriptor( Fetch.class ); AnnotationDescriptor FETCH_PROFILES = createOrmDescriptor( FetchProfiles.class ); AnnotationDescriptor FETCH_PROFILE = createOrmDescriptor( FetchProfile.class, FETCH_PROFILES ); diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/GlobalRegistrationsImpl.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/GlobalRegistrationsImpl.java index a457bb5..9192028 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/GlobalRegistrationsImpl.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/internal/GlobalRegistrationsImpl.java @@ -18,20 +18,20 @@ import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.ParamDef; 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.JaxbFilterDef; -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.boot.jaxb.mapping.spi.JaxbCollectionUserTypeRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbCompositeUserTypeRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbConfigurationParameterImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbConverterRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddableInstantiatorRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListenerImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbFilterDefImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbGenericIdGeneratorImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbJavaTypeRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbJdbcTypeRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbSequenceGeneratorImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbTableGeneratorImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbUserTypeRegistrationImpl; import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.metamodel.CollectionClassification; import org.hibernate.models.internal.StringHelper; @@ -167,7 +167,7 @@ public void collectJavaTypeRegistrations(AnnotationTarget annotationTarget) { ) ); } - public void collectJavaTypeRegistrations(List registrations) { + public void collectJavaTypeRegistrations(List registrations) { if ( CollectionHelper.isEmpty( registrations ) ) { return; } @@ -200,7 +200,7 @@ public void collectJdbcTypeRegistrations(AnnotationTarget annotationTarget) { ) ); } - public void collectJdbcTypeRegistrations(List registrations) { + public void collectJdbcTypeRegistrations(List registrations) { if ( CollectionHelper.isEmpty( registrations ) ) { return; } @@ -231,7 +231,7 @@ public void collectConverterRegistrations(AnnotationTarget annotationTarget) { } ); } - public void collectConverterRegistrations(List registrations) { + public void collectConverterRegistrations(List registrations) { if ( CollectionHelper.isEmpty( registrations ) ) { return; } @@ -269,7 +269,7 @@ public void collectUserTypeRegistrations(AnnotationTarget annotationTarget) { ) ); } - public void collectUserTypeRegistrations(List registrations) { + public void collectUserTypeRegistrations(List registrations) { if ( CollectionHelper.isEmpty( registrations ) ) { return; } @@ -299,7 +299,7 @@ public void collectCompositeUserTypeRegistrations(AnnotationTarget annotationTar ) ); } - public void collectCompositeUserTypeRegistrations(List registrations) { + public void collectCompositeUserTypeRegistrations(List registrations) { if ( CollectionHelper.isEmpty( registrations ) ) { return; } @@ -342,7 +342,7 @@ private Map extractParameterMap(AnnotationUsage registrations) { + public void collectCollectionTypeRegistrations(List registrations) { if ( CollectionHelper.isEmpty( registrations ) ) { return; } @@ -354,7 +354,7 @@ public void collectCollectionTypeRegistrations(List extractParameterMap(List parameters) { + private Map extractParameterMap(List parameters) { if ( CollectionHelper.isEmpty( parameters ) ) { return Collections.emptyMap(); } @@ -385,7 +385,7 @@ public void collectEmbeddableInstantiatorRegistrations(AnnotationTarget annotati ) ); } - public void collectEmbeddableInstantiatorRegistrations(List registrations) { + public void collectEmbeddableInstantiatorRegistrations(List registrations) { if ( CollectionHelper.isEmpty( registrations ) ) { return; } @@ -424,7 +424,7 @@ private Map extractFilterParameters(AnnotationUsage filterDefinitions) { + public void collectFilterDefinitions(List filterDefinitions) { if ( CollectionHelper.isEmpty( filterDefinitions ) ) { return; } @@ -436,14 +436,14 @@ public void collectFilterDefinitions(List filterDefinitions) { ) ); } - private Map extractFilterParameters(JaxbFilterDef source) { - final List parameters = source.getFilterParam(); + private Map extractFilterParameters(JaxbFilterDefImpl source) { + final List parameters = source.getFilterParam(); // todo : update the mapping.xsd to account for new @ParamDef definition // todo : handle simplified type names for XML, e.g. "String" instead of "java.lang.String" final Map result = new HashMap<>( parameters.size() ); - for ( JaxbFilterDef.JaxbFilterParam parameter : parameters ) { + for ( JaxbFilterDefImpl.JaxbFilterParamImpl parameter : parameters ) { result.put( parameter.getName(), classDetailsRegistry.resolveClassDetails( parameter.getType() ) ); } return result; @@ -463,7 +463,7 @@ public void collectFilterDefinition(String name, String defaultCondition, Map listeners) { + public void collectEntityListenerRegistrations(List listeners) { if ( CollectionHelper.isEmpty( listeners ) ) { return; } @@ -482,7 +482,7 @@ public void collectEntityListenerRegistrations(List listener // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Id generators - public void collectIdGenerators(JaxbEntityMappings jaxbRoot) { + public void collectIdGenerators(JaxbEntityMappingsImpl jaxbRoot) { collectSequenceGenerators( jaxbRoot.getSequenceGenerators() ); collectTableGenerators( jaxbRoot.getTableGenerators() ); collectGenericGenerators( jaxbRoot.getGenericGenerators() ); @@ -500,7 +500,7 @@ public void collectIdGenerators(ClassDetails classDetails) { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Sequence generator - public void collectSequenceGenerators(List sequenceGenerators) { + public void collectSequenceGenerators(List sequenceGenerators) { if ( CollectionHelper.isEmpty( sequenceGenerators ) ) { return; } @@ -534,7 +534,7 @@ public void collectSequenceGenerator(SequenceGeneratorRegistration generatorRegi // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Table generator - public void collectTableGenerators(List tableGenerators) { + public void collectTableGenerators(List tableGenerators) { if ( CollectionHelper.isEmpty( tableGenerators ) ) { return; } @@ -571,7 +571,7 @@ public void collectTableGenerator(TableGeneratorRegistration generatorRegistrati // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Generic generators - private void collectGenericGenerators(List genericGenerators) { + private void collectGenericGenerators(List genericGenerators) { if ( CollectionHelper.isEmpty( genericGenerators ) ) { return; } 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 40adf9f..6f06208 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 @@ -9,10 +9,10 @@ import java.util.Map; import java.util.Set; -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.boot.jaxb.mapping.spi.JaxbEntityListenersImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitDefaultsImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitMetadataImpl; import org.hibernate.models.orm.spi.ProcessResult; import org.hibernate.models.orm.spi.EntityHierarchy; import org.hibernate.models.source.spi.ClassDetails; @@ -42,7 +42,7 @@ public GlobalRegistrationsImpl getGlobalRegistrations() { } - public void apply(JaxbEntityMappings jaxbRoot) { + public void apply(JaxbEntityMappingsImpl jaxbRoot) { getGlobalRegistrations().collectJavaTypeRegistrations( jaxbRoot.getJavaTypeRegistrations() ); getGlobalRegistrations().collectJdbcTypeRegistrations( jaxbRoot.getJdbcTypeRegistrations() ); getGlobalRegistrations().collectConverterRegistrations( jaxbRoot.getConverterRegistrations() ); @@ -52,10 +52,10 @@ public void apply(JaxbEntityMappings jaxbRoot) { getGlobalRegistrations().collectEmbeddableInstantiatorRegistrations( jaxbRoot.getEmbeddableInstantiatorRegistrations() ); getGlobalRegistrations().collectFilterDefinitions( jaxbRoot.getFilterDefinitions() ); - final JaxbPersistenceUnitMetadata persistenceUnitMetadata = jaxbRoot.getPersistenceUnitMetadata(); + final JaxbPersistenceUnitMetadataImpl persistenceUnitMetadata = jaxbRoot.getPersistenceUnitMetadata(); if ( persistenceUnitMetadata != null ) { - final JaxbPersistenceUnitDefaults persistenceUnitDefaults = persistenceUnitMetadata.getPersistenceUnitDefaults(); - final JaxbEntityListeners entityListeners = persistenceUnitDefaults.getEntityListeners(); + final JaxbPersistenceUnitDefaultsImpl persistenceUnitDefaults = persistenceUnitMetadata.getPersistenceUnitDefaults(); + final JaxbEntityListenersImpl entityListeners = persistenceUnitDefaults.getEntityListeners(); if ( entityListeners != null ) { getGlobalRegistrations().collectEntityListenerRegistrations( entityListeners.getEntityListener() ); } diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/spi/EntityListenerRegistration.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/spi/EntityListenerRegistration.java index afff5b7..2fd609f 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/spi/EntityListenerRegistration.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/spi/EntityListenerRegistration.java @@ -6,7 +6,7 @@ */ package org.hibernate.models.orm.spi; -import org.hibernate.boot.jaxb.mapping.JaxbEntityListener; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListenerImpl; import org.hibernate.internal.util.MutableObject; import org.hibernate.models.ModelsException; import org.hibernate.models.source.spi.ClassDetails; @@ -96,7 +96,7 @@ public MethodDetails getPostUpdateMethod() { public MethodDetails getPostLoadMethod() { return postLoadMethod; } - public static EntityListenerRegistration from(JaxbEntityListener jaxbMapping, ClassDetailsRegistry classDetailsRegistry) { + public static EntityListenerRegistration from(JaxbEntityListenerImpl jaxbMapping, ClassDetailsRegistry classDetailsRegistry) { final ClassDetails listenerClassDetails = classDetailsRegistry.resolveClassDetails( jaxbMapping.getClazz() ); final MutableObject prePersistMethod = new MutableObject<>(); final MutableObject postPersistMethod = new MutableObject<>(); 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 fe351b9..a463f3e 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 @@ -14,11 +14,11 @@ import java.util.Set; import org.hibernate.boot.internal.ClassmateContext; -import org.hibernate.boot.jaxb.mapping.JaxbEmbeddable; -import org.hibernate.boot.jaxb.mapping.JaxbEntity; -import org.hibernate.boot.jaxb.mapping.JaxbEntityMappings; -import org.hibernate.boot.jaxb.mapping.JaxbMappedSuperclass; -import org.hibernate.boot.jaxb.mapping.ManagedType; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddableImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbManagedType; +import org.hibernate.boot.jaxb.mapping.spi.JaxbMappedSuperclassImpl; import org.hibernate.models.internal.CollectionHelper; import org.hibernate.models.internal.StringHelper; import org.hibernate.models.orm.JpaAnnotations; @@ -78,16 +78,16 @@ public static ProcessResult process( return process( managedResources, explicitlyListedClasses, options, sourceModelBuildingContext, ormModelBuildingContext ); } - public static class OverrideTuple { - private final JaxbEntityMappings jaxbRoot; + public static class OverrideTuple { + private final JaxbEntityMappingsImpl jaxbRoot; private final M managedType; - public OverrideTuple(JaxbEntityMappings jaxbRoot, M managedType) { + public OverrideTuple(JaxbEntityMappingsImpl jaxbRoot, M managedType) { this.jaxbRoot = jaxbRoot; this.managedType = managedType; } - public JaxbEntityMappings getJaxbRoot() { + public JaxbEntityMappingsImpl getJaxbRoot() { return jaxbRoot; } @@ -116,9 +116,9 @@ public static ProcessResult process( final XmlResources collectedXmlResources = XmlResources.collectXmlResources( managedResources, sourceModelBuildingContext ); final boolean xmlMappingsGloballyComplete = collectedXmlResources.getPersistenceUnitMetadata().areXmlMappingsComplete(); - final List> entityOverrides = new ArrayList<>(); - final List> mappedSuperclassesOverrides = new ArrayList<>(); - final List> embeddableOverrides = new ArrayList<>(); + final List> entityOverrides = new ArrayList<>(); + final List> mappedSuperclassesOverrides = new ArrayList<>(); + final List> embeddableOverrides = new ArrayList<>(); collectedXmlResources.getDocuments().forEach( (jaxbRoot) -> { processResultCollector.apply( jaxbRoot ); diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/AttributeProcessor.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/AttributeProcessor.java index 274c5e1..d4cbb7b 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/AttributeProcessor.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/AttributeProcessor.java @@ -6,20 +6,21 @@ */ package org.hibernate.models.orm.xml.internal; -import org.hibernate.boot.jaxb.mapping.AttributesContainer; -import org.hibernate.boot.jaxb.mapping.JaxbBasic; -import org.hibernate.boot.jaxb.mapping.JaxbElementCollection; -import org.hibernate.boot.jaxb.mapping.JaxbEmbedded; -import org.hibernate.boot.jaxb.mapping.JaxbEmbeddedId; -import org.hibernate.boot.jaxb.mapping.JaxbHbmAnyMapping; -import org.hibernate.boot.jaxb.mapping.JaxbHbmManyToAny; -import org.hibernate.boot.jaxb.mapping.JaxbId; -import org.hibernate.boot.jaxb.mapping.JaxbManyToMany; -import org.hibernate.boot.jaxb.mapping.JaxbManyToOne; -import org.hibernate.boot.jaxb.mapping.JaxbNaturalId; -import org.hibernate.boot.jaxb.mapping.JaxbOneToMany; -import org.hibernate.boot.jaxb.mapping.JaxbOneToOne; -import org.hibernate.boot.jaxb.mapping.PersistentAttribute; +import org.hibernate.boot.jaxb.mapping.spi.JaxbAnyMappingImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributesContainer; +import org.hibernate.boot.jaxb.mapping.spi.JaxbBaseAttributesContainer; +import org.hibernate.boot.jaxb.mapping.spi.JaxbBasicImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbElementCollectionImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedIdImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbIdImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToManyImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToOneImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbNaturalId; +import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToManyImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToOneImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistentAttribute; +import org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAnyMappingImpl; import org.hibernate.models.source.internal.MutableClassDetails; import org.hibernate.models.source.internal.MutableMemberDetails; import org.hibernate.models.source.internal.dynamic.DynamicAnnotationUsage; @@ -41,153 +42,195 @@ public static void processNaturalId( MutableClassDetails mutableClassDetails, AccessType classAccessType, SourceModelBuildingContext sourceModelBuildingContext) { + processNaturalId( jaxbNaturalId, mutableClassDetails, classAccessType, null, sourceModelBuildingContext ); + } + + public static void processNaturalId( + JaxbNaturalId jaxbNaturalId, + MutableClassDetails mutableClassDetails, + AccessType classAccessType, + MemberAdjuster memberAdjuster, + SourceModelBuildingContext sourceModelBuildingContext) { if ( jaxbNaturalId == null ) { return; } XmlAnnotationHelper.applyNaturalIdCache( jaxbNaturalId, mutableClassDetails, sourceModelBuildingContext ); - jaxbNaturalId.getBasic().forEach( (jaxbBasic) -> { - final MutableMemberDetails backingMember = processBasicAttribute( - jaxbBasic, - mutableClassDetails, - classAccessType, - sourceModelBuildingContext - ); - XmlAnnotationHelper.applyNaturalId( jaxbNaturalId, backingMember, sourceModelBuildingContext ); - } ); - jaxbNaturalId.getEmbedded().forEach( (jaxbEmbedded) -> { - final MutableMemberDetails backingMember = processEmbeddedAttribute( - jaxbEmbedded, - mutableClassDetails, - classAccessType, - sourceModelBuildingContext - ); - XmlAnnotationHelper.applyNaturalId( jaxbNaturalId, backingMember, sourceModelBuildingContext ); - } ); - jaxbNaturalId.getManyToOne().forEach( (jaxbManyToOne) -> { - final MutableMemberDetails backingMember = processManyToOneAttribute( - jaxbManyToOne, - mutableClassDetails, - classAccessType, - sourceModelBuildingContext - ); - XmlAnnotationHelper.applyNaturalId( jaxbNaturalId, backingMember, sourceModelBuildingContext ); - } ); - jaxbNaturalId.getAny().forEach( (jaxbAny) -> { - final MutableMemberDetails backingMember = processDiscriminatedAssociationAttribute( - jaxbAny, - mutableClassDetails, - classAccessType, - sourceModelBuildingContext - ); - XmlAnnotationHelper.applyNaturalId( jaxbNaturalId, backingMember, sourceModelBuildingContext ); - } ); + processBaseAttributes( jaxbNaturalId, mutableClassDetails, classAccessType, memberAdjuster, sourceModelBuildingContext ); } - public static void processAttributes( - AttributesContainer attributesContainer, + public static void processBaseAttributes( + JaxbBaseAttributesContainer attributesContainer, + MutableClassDetails mutableClassDetails, + AccessType classAccessType, + SourceModelBuildingContext sourceModelBuildingContext) { + processBaseAttributes( + attributesContainer, + mutableClassDetails, + classAccessType, + null, + sourceModelBuildingContext + ); + } + + public static void processBaseAttributes( + JaxbBaseAttributesContainer attributesContainer, MutableClassDetails mutableClassDetails, AccessType classAccessType, + MemberAdjuster memberAdjuster, SourceModelBuildingContext sourceModelBuildingContext) { for ( int i = 0; i < attributesContainer.getBasicAttributes().size(); i++ ) { - processBasicAttribute( - attributesContainer.getBasicAttributes().get( i ), + final JaxbBasicImpl jaxbBasic = attributesContainer.getBasicAttributes().get( i ); + final MutableMemberDetails memberDetails = processBasicAttribute( + jaxbBasic, mutableClassDetails, classAccessType, sourceModelBuildingContext ); + if ( memberAdjuster != null ) { + memberAdjuster.adjust( memberDetails, jaxbBasic, sourceModelBuildingContext ); + } } for ( int i = 0; i < attributesContainer.getEmbeddedAttributes().size(); i++ ) { - processEmbeddedAttribute( - attributesContainer.getEmbeddedAttributes().get( i ), + final JaxbEmbeddedImpl jaxbEmbedded = attributesContainer.getEmbeddedAttributes().get( i ); + final MutableMemberDetails memberDetails = processEmbeddedAttribute( + jaxbEmbedded, mutableClassDetails, classAccessType, sourceModelBuildingContext ); + if ( memberAdjuster != null ) { + memberAdjuster.adjust( memberDetails, jaxbEmbedded, sourceModelBuildingContext ); + } } - for ( int i = 0; i < attributesContainer.getOneToOneAttributes().size(); i++ ) { - processOneToOneAttribute( - attributesContainer.getOneToOneAttributes().get( i ), + for ( int i = 0; i < attributesContainer.getManyToOneAttributes().size(); i++ ) { + final JaxbManyToOneImpl jaxbManyToOne = attributesContainer.getManyToOneAttributes().get( i ); + final MutableMemberDetails memberDetails = processManyToOneAttribute( + jaxbManyToOne, mutableClassDetails, classAccessType, sourceModelBuildingContext ); + if ( memberAdjuster != null ) { + memberAdjuster.adjust( memberDetails, jaxbManyToOne, sourceModelBuildingContext ); + } } - for ( int i = 0; i < attributesContainer.getManyToOneAttributes().size(); i++ ) { - processManyToOneAttribute( - attributesContainer.getManyToOneAttributes().get( i ), + for ( int i = 0; i < attributesContainer.getAnyMappingAttributes().size(); i++ ) { + final JaxbAnyMappingImpl jaxbAnyMapping = attributesContainer.getAnyMappingAttributes().get( i ); + final MutableMemberDetails memberDetails = processAnyMappingAttribute( + jaxbAnyMapping, mutableClassDetails, classAccessType, sourceModelBuildingContext ); + if ( memberAdjuster != null ) { + memberAdjuster.adjust( memberDetails, jaxbAnyMapping, sourceModelBuildingContext ); + } } + } - for ( int i = 0; i < attributesContainer.getDiscriminatedAssociations().size(); i++ ) { - processDiscriminatedAssociationAttribute( - attributesContainer.getDiscriminatedAssociations().get( i ), + @FunctionalInterface + public interface MemberAdjuster { + void adjust(M member, JaxbPersistentAttribute jaxbPersistentAttribute, SourceModelBuildingContext sourceModelBuildingContext); + } + + public static void processAttributes( + JaxbAttributesContainer attributesContainer, + MutableClassDetails mutableClassDetails, + AccessType classAccessType, + SourceModelBuildingContext sourceModelBuildingContext) { + processAttributes( attributesContainer, mutableClassDetails, classAccessType, null, sourceModelBuildingContext ); + } + + public static void processAttributes( + JaxbAttributesContainer attributesContainer, + MutableClassDetails mutableClassDetails, + AccessType classAccessType, + MemberAdjuster memberAdjuster, + SourceModelBuildingContext sourceModelBuildingContext) { + processBaseAttributes( attributesContainer, mutableClassDetails, classAccessType, memberAdjuster, sourceModelBuildingContext ); + + for ( int i = 0; i < attributesContainer.getOneToOneAttributes().size(); i++ ) { + final JaxbOneToOneImpl jaxbOneToOne = attributesContainer.getOneToOneAttributes().get( i ); + final MutableMemberDetails memberDetails = processOneToOneAttribute( + jaxbOneToOne, mutableClassDetails, classAccessType, sourceModelBuildingContext ); + if ( memberAdjuster != null ) { + memberAdjuster.adjust( memberDetails, jaxbOneToOne, sourceModelBuildingContext ); + } } for ( int i = 0; i < attributesContainer.getElementCollectionAttributes().size(); i++ ) { - processElementCollectionAttribute( - attributesContainer.getElementCollectionAttributes().get( i ), + final JaxbElementCollectionImpl jaxbElementCollection = attributesContainer.getElementCollectionAttributes().get( i ); + final MutableMemberDetails memberDetails = processElementCollectionAttribute( + jaxbElementCollection, mutableClassDetails, classAccessType, sourceModelBuildingContext ); + if ( memberAdjuster != null ) { + memberAdjuster.adjust( memberDetails, jaxbElementCollection, sourceModelBuildingContext ); + } } for ( int i = 0; i < attributesContainer.getOneToManyAttributes().size(); i++ ) { - processOneToManyAttribute( - attributesContainer.getOneToManyAttributes().get( i ), + final JaxbOneToManyImpl jaxbOneToMany = attributesContainer.getOneToManyAttributes().get( i ); + final MutableMemberDetails memberDetails = processOneToManyAttribute( + jaxbOneToMany, mutableClassDetails, classAccessType, sourceModelBuildingContext ); + if ( memberAdjuster != null ) { + memberAdjuster.adjust( memberDetails, jaxbOneToMany, sourceModelBuildingContext ); + } } for ( int i = 0; i < attributesContainer.getManyToManyAttributes().size(); i++ ) { - processManyToManyAttribute( - attributesContainer.getManyToManyAttributes().get( i ), + final JaxbManyToManyImpl jaxbManyToMany = attributesContainer.getManyToManyAttributes().get( i ); + final MutableMemberDetails memberDetails = processManyToManyAttribute( + jaxbManyToMany, mutableClassDetails, classAccessType, sourceModelBuildingContext ); + if ( memberAdjuster != null ) { + memberAdjuster.adjust( memberDetails, jaxbManyToMany, sourceModelBuildingContext ); + } } - for ( int i = 0; i < attributesContainer.getPluralDiscriminatedAssociations().size(); i++ ) { - processPluralDiscriminatedAssociationAttribute( - attributesContainer.getPluralDiscriminatedAssociations().get( i ), + for ( int i = 0; i < attributesContainer.getPluralAnyMappingAttributes().size(); i++ ) { + final JaxbPluralAnyMappingImpl jaxbPluralAnyMapping = attributesContainer.getPluralAnyMappingAttributes() + .get( i ); + final MutableMemberDetails memberDetails = processPluralAnyMappingAttributes( + jaxbPluralAnyMapping, mutableClassDetails, classAccessType, sourceModelBuildingContext ); + if ( memberAdjuster != null ) { + memberAdjuster.adjust( memberDetails, jaxbPluralAnyMapping, sourceModelBuildingContext ); + } } - } public static void processCommonAttributeAnnotations( - PersistentAttribute jaxbAttribute, + JaxbPersistentAttribute jaxbAttribute, MutableMemberDetails memberDetails, AccessType accessType, SourceModelBuildingContext sourceModelBuildingContext) { XmlAnnotationHelper.applyAccess( accessType, memberDetails, sourceModelBuildingContext ); - XmlAnnotationHelper.applyAttributeAccessor( - jaxbAttribute.getAttributeAccessor(), - memberDetails, - sourceModelBuildingContext - ); } - public static void processBasicIdAttribute( - JaxbId jaxbId, + public static MutableMemberDetails processBasicIdAttribute( + JaxbIdImpl jaxbId, MutableClassDetails declarer, AccessType classAccessType, SourceModelBuildingContext sourceModelBuildingContext) { @@ -218,8 +261,13 @@ public static void processBasicIdAttribute( memberDetails, sourceModelBuildingContext ); - XmlAnnotationHelper.applyJdbcTypeCode( - jaxbId.getJdbcTypeCode(), + XmlAnnotationHelper.applyTargetClass( + jaxbId.getTargetClass(), + memberDetails, + sourceModelBuildingContext + ); + XmlAnnotationHelper.applyJdbcType( + jaxbId.getJdbcType(), memberDetails, sourceModelBuildingContext ); @@ -251,10 +299,12 @@ public static void processBasicIdAttribute( ); // todo : unsaved-value? + + return memberDetails; } - public static void processEmbeddedIdAttribute( - JaxbEmbeddedId jaxbEmbeddedId, + public static MutableMemberDetails processEmbeddedIdAttribute( + JaxbEmbeddedIdImpl jaxbEmbeddedId, MutableClassDetails classDetails, AccessType classAccessType, SourceModelBuildingContext sourceModelBuildingContext) { @@ -279,10 +329,12 @@ public static void processEmbeddedIdAttribute( memberDetails, sourceModelBuildingContext ); + + return memberDetails; } public static MutableMemberDetails processBasicAttribute( - JaxbBasic jaxbBasic, + JaxbBasicImpl jaxbBasic, MutableClassDetails declarer, AccessType classAccessType, SourceModelBuildingContext sourceModelBuildingContext) { @@ -308,17 +360,18 @@ public static MutableMemberDetails processBasicAttribute( XmlAnnotationHelper.applyConvert( jaxbBasic.getConvert(), memberDetails, sourceModelBuildingContext ); XmlAnnotationHelper.applyUserType( jaxbBasic.getType(), memberDetails, sourceModelBuildingContext ); + XmlAnnotationHelper.applyTargetClass( jaxbBasic.getTargetClass(), memberDetails, sourceModelBuildingContext ); + XmlAnnotationHelper.applyJdbcType( jaxbBasic.getJdbcType(), memberDetails, sourceModelBuildingContext ); XmlAnnotationHelper.applyTemporal( jaxbBasic.getTemporal(), memberDetails, sourceModelBuildingContext ); XmlAnnotationHelper.applyLob( jaxbBasic.getLob(), memberDetails, sourceModelBuildingContext ); XmlAnnotationHelper.applyEnumerated( jaxbBasic.getEnumerated(), memberDetails, sourceModelBuildingContext ); XmlAnnotationHelper.applyNationalized( jaxbBasic.getNationalized(), memberDetails, sourceModelBuildingContext ); - XmlAnnotationHelper.applyJdbcTypeCode( jaxbBasic.getJdbcTypeCode(), memberDetails, sourceModelBuildingContext ); return memberDetails; } public static MutableMemberDetails processEmbeddedAttribute( - JaxbEmbedded jaxbEmbedded, + JaxbEmbeddedImpl jaxbEmbedded, MutableClassDetails declarer, AccessType classAccessType, SourceModelBuildingContext sourceModelBuildingContext) { @@ -345,7 +398,7 @@ public static MutableMemberDetails processEmbeddedAttribute( @SuppressWarnings("UnusedReturnValue") public static MutableMemberDetails processOneToOneAttribute( - JaxbOneToOne jaxbOneToOne, + JaxbOneToOneImpl jaxbOneToOne, MutableClassDetails mutableClassDetails, AccessType classAccessType, SourceModelBuildingContext sourceModelBuildingContext) { @@ -353,15 +406,15 @@ public static MutableMemberDetails processOneToOneAttribute( } public static MutableMemberDetails processManyToOneAttribute( - JaxbManyToOne jaxbOneToOne, + JaxbManyToOneImpl jaxbOneToOne, MutableClassDetails mutableClassDetails, AccessType classAccessType, SourceModelBuildingContext sourceModelBuildingContext) { throw new UnsupportedOperationException( "Support for many-to-one attributes not yet implemented" ); } - public static MutableMemberDetails processDiscriminatedAssociationAttribute( - JaxbHbmAnyMapping jaxbHbmAnyMapping, + public static MutableMemberDetails processAnyMappingAttribute( + JaxbAnyMappingImpl jaxbHbmAnyMapping, MutableClassDetails mutableClassDetails, AccessType classAccessType, SourceModelBuildingContext sourceModelBuildingContext) { @@ -370,7 +423,7 @@ public static MutableMemberDetails processDiscriminatedAssociationAttribute( @SuppressWarnings("UnusedReturnValue") public static MutableMemberDetails processElementCollectionAttribute( - JaxbElementCollection jaxbElementCollection, + JaxbElementCollectionImpl jaxbElementCollection, MutableClassDetails mutableClassDetails, AccessType classAccessType, SourceModelBuildingContext sourceModelBuildingContext) { @@ -379,7 +432,7 @@ public static MutableMemberDetails processElementCollectionAttribute( @SuppressWarnings("UnusedReturnValue") public static MutableMemberDetails processOneToManyAttribute( - JaxbOneToMany jaxbOneToMany, + JaxbOneToManyImpl jaxbOneToMany, MutableClassDetails mutableClassDetails, AccessType classAccessType, SourceModelBuildingContext sourceModelBuildingContext) { @@ -388,7 +441,7 @@ public static MutableMemberDetails processOneToManyAttribute( @SuppressWarnings("UnusedReturnValue") public static MutableMemberDetails processManyToManyAttribute( - JaxbManyToMany jaxbManyToMany, + JaxbManyToManyImpl jaxbManyToMany, MutableClassDetails mutableClassDetails, AccessType classAccessType, SourceModelBuildingContext sourceModelBuildingContext) { @@ -396,8 +449,8 @@ public static MutableMemberDetails processManyToManyAttribute( } @SuppressWarnings("UnusedReturnValue") - public static MutableMemberDetails processPluralDiscriminatedAssociationAttribute( - JaxbHbmManyToAny jaxbHbmManyToAny, + public static MutableMemberDetails processPluralAnyMappingAttributes( + JaxbPluralAnyMappingImpl jaxbHbmManyToAny, MutableClassDetails mutableClassDetails, AccessType classAccessType, SourceModelBuildingContext sourceModelBuildingContext) { diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/ManagedTypeProcessor.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/ManagedTypeProcessor.java index 51a4729..192b7dc 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/ManagedTypeProcessor.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/ManagedTypeProcessor.java @@ -8,22 +8,36 @@ import java.util.List; -import org.hibernate.boot.jaxb.mapping.JaxbAttributes; -import org.hibernate.boot.jaxb.mapping.JaxbEmbeddable; -import org.hibernate.boot.jaxb.mapping.JaxbEmbeddableAttributes; -import org.hibernate.boot.jaxb.mapping.JaxbEmbeddedId; -import org.hibernate.boot.jaxb.mapping.JaxbEntity; -import org.hibernate.boot.jaxb.mapping.JaxbEntityMappings; -import org.hibernate.boot.jaxb.mapping.JaxbId; -import org.hibernate.boot.jaxb.mapping.JaxbMappedSuperclass; +import org.hibernate.annotations.internal.Extends; +import org.hibernate.boot.jaxb.mapping.spi.JaxbAnyMappingImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributesContainer; +import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributesContainerImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbBasicImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddableImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedIdImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbIdImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbManagedType; +import org.hibernate.boot.jaxb.mapping.spi.JaxbMappedSuperclassImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToOneImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistentAttribute; +import org.hibernate.models.ModelsException; import org.hibernate.models.internal.CollectionHelper; import org.hibernate.models.internal.StringHelper; import org.hibernate.models.orm.spi.Processor; import org.hibernate.models.orm.xml.spi.PersistenceUnitMetadata; import org.hibernate.models.source.internal.MutableClassDetails; +import org.hibernate.models.source.internal.MutableMemberDetails; import org.hibernate.models.source.internal.SourceModelLogging; +import org.hibernate.models.source.internal.dynamic.DynamicAnnotationUsage; import org.hibernate.models.source.internal.dynamic.DynamicClassDetails; +import org.hibernate.models.source.internal.dynamic.MapModeFieldDetails; +import org.hibernate.models.source.spi.ClassDetails; +import org.hibernate.models.source.spi.ClassDetailsRegistry; import org.hibernate.models.source.spi.SourceModelBuildingContext; +import org.hibernate.property.access.spi.BuiltInPropertyAccessStrategies; import jakarta.persistence.AccessType; import jakarta.persistence.Embeddable; @@ -45,111 +59,585 @@ public class ManagedTypeProcessor { // Entity public static void processCompleteEntity( - JaxbEntityMappings jaxbRoot, - JaxbEntity jaxbEntity, + JaxbEntityMappingsImpl jaxbRoot, + JaxbEntityImpl jaxbEntity, PersistenceUnitMetadata persistenceUnitMetadata, SourceModelBuildingContext sourceModelBuildingContext) { final MutableClassDetails classDetails; + final AccessType classAccessType; + final AttributeProcessor.MemberAdjuster memberAdjuster; + final boolean isDynamic; if ( StringHelper.isEmpty( jaxbEntity.getClazz() ) ) { - // should indicate a dynamic entity - assert StringHelper.isNotEmpty( jaxbEntity.getName() ); + // no class == dynamic + if ( StringHelper.isEmpty( jaxbEntity.getName() ) ) { + throw new ModelsException( "Assumed dynamic entity did not define entity-name" ); + } + + memberAdjuster = ManagedTypeProcessor::adjustDynamicTypeMember; + classAccessType = AccessType.FIELD; classDetails = (MutableClassDetails) sourceModelBuildingContext.getClassDetailsRegistry().resolveClassDetails( jaxbEntity.getName(), - () -> new DynamicClassDetails( - jaxbEntity.getName(), - null, - false, - null, - sourceModelBuildingContext - ) + () -> { + final DynamicClassDetails dynamicClassDetails = new DynamicClassDetails( + jaxbEntity.getName(), + null, + false, + null, + sourceModelBuildingContext + ); + return dynamicClassDetails; + } ); + + prepareDynamicClass( classDetails, jaxbEntity, persistenceUnitMetadata, sourceModelBuildingContext ); } else { + memberAdjuster = ManagedTypeProcessor::adjustNonDynamicTypeMember; final String className = XmlProcessingHelper.determineClassName( jaxbRoot, jaxbEntity ); classDetails = (MutableClassDetails) sourceModelBuildingContext.getClassDetailsRegistry().resolveClassDetails( className ); + classAccessType = coalesce( + jaxbEntity.getAccess(), + persistenceUnitMetadata.getAccessType() + ); } classDetails.clearMemberAnnotationUsages(); classDetails.clearAnnotationUsages(); - // from here, processing is the same between override and metadata-complete modes - processEntityMetadata( jaxbEntity, classDetails, persistenceUnitMetadata, sourceModelBuildingContext ); + // from here, processing is the same between override and metadata-complete modes (aside from the dynamic model handling) + + processEntityMetadata( + classDetails, + jaxbEntity, + AccessType.FIELD, + ManagedTypeProcessor::adjustDynamicTypeMember, + persistenceUnitMetadata, + sourceModelBuildingContext + ); } - public static void processOverrideEntity( - List> entityOverrides, + /** + * Creates fake FieldDetails for each attribute defined in the XML + */ + private static void prepareDynamicClass( + MutableClassDetails classDetails, + JaxbManagedType jaxbManagedType, PersistenceUnitMetadata persistenceUnitMetadata, SourceModelBuildingContext sourceModelBuildingContext) { - entityOverrides.forEach( (overrideTuple) -> { - final JaxbEntityMappings jaxbRoot = overrideTuple.getJaxbRoot(); - final JaxbEntity jaxbEntity = overrideTuple.getManagedType(); - final String className = XmlProcessingHelper.determineClassName( jaxbRoot, jaxbEntity ); - final MutableClassDetails classDetails = (MutableClassDetails) sourceModelBuildingContext - .getClassDetailsRegistry() - .resolveClassDetails( className ); + if ( jaxbManagedType instanceof JaxbEntityImpl ) { + final JaxbEntityImpl jaxbDynamicEntity = (JaxbEntityImpl) jaxbManagedType; + final JaxbAttributesContainerImpl attributes = jaxbDynamicEntity.getAttributes(); + + if ( CollectionHelper.isNotEmpty( attributes.getIdAttributes() ) ) { + // + attributes.getIdAttributes().forEach( (jaxbId) -> { + final ClassDetails attributeJavaType = determineDynamicAttributeJavaType( + jaxbId, + sourceModelBuildingContext + ); + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbId.getName(), + attributeJavaType, + sourceModelBuildingContext + ); + classDetails.addField( member ); + } ); + } + else { + // + final JaxbEmbeddedIdImpl embeddedId = attributes.getEmbeddedIdAttribute(); + final ClassDetails attributeJavaType = determineDynamicAttributeJavaType( + embeddedId, + sourceModelBuildingContext + ); + final MapModeFieldDetails member = new MapModeFieldDetails( + embeddedId.getName(), + attributeJavaType, + sourceModelBuildingContext + ); + classDetails.addField( member ); + } - // from here, processing is the same between override and metadata-complete modes - processEntityMetadata( jaxbEntity, classDetails, persistenceUnitMetadata, sourceModelBuildingContext ); + // + if ( attributes.getNaturalId() != null ) { + attributes.getNaturalId().getBasicAttributes().forEach( (jaxbBasic) -> { + final ClassDetails attributeJavaType = determineDynamicAttributeJavaType( + jaxbBasic, + sourceModelBuildingContext + ); + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbBasic.getName(), + attributeJavaType, + sourceModelBuildingContext + ); + classDetails.addField( member ); + } ); + + attributes.getNaturalId().getEmbeddedAttributes().forEach( (jaxbEmbedded) -> { + final ClassDetails attributeJavaType = determineDynamicAttributeJavaType( + jaxbEmbedded, + sourceModelBuildingContext + ); + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbEmbedded.getName(), + attributeJavaType, + sourceModelBuildingContext + ); + classDetails.addField( member ); + } ); + + attributes.getNaturalId().getManyToOneAttributes().forEach( (jaxbManyToOne) -> { + final ClassDetails attributeJavaType = determineDynamicAttributeJavaType( + jaxbManyToOne, + sourceModelBuildingContext + ); + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbManyToOne.getName(), + attributeJavaType, + sourceModelBuildingContext + ); + classDetails.addField( member ); + } ); + + attributes.getNaturalId().getAnyMappingAttributes().forEach( (jaxbAnyMapping) -> { + final ClassDetails attributeJavaType = determineDynamicAttributeJavaType( + jaxbAnyMapping, + sourceModelBuildingContext + ); + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbAnyMapping.getName(), + attributeJavaType, + sourceModelBuildingContext + ); + classDetails.addField( member ); + } ); + } + } + + final JaxbAttributesContainer attributes = jaxbManagedType.getAttributes(); + attributes.getBasicAttributes().forEach( (jaxbBasic) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbBasic.getName(), + determineDynamicAttributeJavaType( jaxbBasic, sourceModelBuildingContext ), + sourceModelBuildingContext + ); + classDetails.addField( member ); + } ); + + attributes.getEmbeddedAttributes().forEach( (jaxbEmbedded) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbEmbedded.getName(), + determineDynamicAttributeJavaType( jaxbEmbedded, sourceModelBuildingContext ), + sourceModelBuildingContext + ); + classDetails.addField( member ); + } ); + + attributes.getOneToOneAttributes().forEach( (jaxbOneToOne) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbOneToOne.getName(), + determineDynamicAttributeJavaType( jaxbOneToOne, sourceModelBuildingContext ), + sourceModelBuildingContext + ); + classDetails.addField( member ); + } ); + + attributes.getManyToOneAttributes().forEach( (jaxbManyToOne) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbManyToOne.getName(), + determineDynamicAttributeJavaType( jaxbManyToOne, sourceModelBuildingContext ), + sourceModelBuildingContext + ); + classDetails.addField( member ); } ); + attributes.getAnyMappingAttributes().forEach( (jaxbAnyMapping) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbAnyMapping.getName(), + determineDynamicAttributeJavaType( jaxbAnyMapping, sourceModelBuildingContext ), + sourceModelBuildingContext + ); + classDetails.addField( member ); + } ); + + attributes.getElementCollectionAttributes().forEach( (jaxbElementCollection) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbElementCollection.getName(), + determineDynamicAttributeJavaType( jaxbElementCollection, sourceModelBuildingContext ), + sourceModelBuildingContext + ); + classDetails.addField( member ); + } ); + + attributes.getOneToManyAttributes().forEach( (jaxbOneToMany) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbOneToMany.getName(), + determineDynamicAttributeJavaType( jaxbOneToMany, sourceModelBuildingContext ), + sourceModelBuildingContext + ); + classDetails.addField( member ); + } ); + + attributes.getManyToManyAttributes().forEach( (jaxbManyToMany) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbManyToMany.getName(), + determineDynamicAttributeJavaType( jaxbManyToMany, sourceModelBuildingContext ), + sourceModelBuildingContext + ); + classDetails.addField( member ); + } ); + + attributes.getPluralAnyMappingAttributes().forEach( (jaxbPluralAnyMapping) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbPluralAnyMapping.getName(), + determineDynamicAttributeJavaType( jaxbPluralAnyMapping, sourceModelBuildingContext ), + sourceModelBuildingContext + ); + classDetails.addField( member ); + } ); + } + + private static ClassDetails determineDynamicAttributeJavaType( + JaxbPersistentAttribute jaxbPersistentAttribute, + SourceModelBuildingContext sourceModelBuildingContext) { + + if ( jaxbPersistentAttribute instanceof JaxbIdImpl ) { + final JaxbIdImpl jaxbId = (JaxbIdImpl) jaxbPersistentAttribute; + if ( jaxbId.getJavaType() == null || jaxbId.getJavaType().getClazz() == null ) { + return null; + } + else { + return XmlAnnotationHelper.resolveJavaType( + jaxbId.getJavaType().getClazz(), + sourceModelBuildingContext + ); + } + } + + if ( jaxbPersistentAttribute instanceof JaxbEmbeddedIdImpl ) { + final JaxbEmbeddedIdImpl jaxbEmbeddedId = (JaxbEmbeddedIdImpl) jaxbPersistentAttribute; + // need target-class here... + throw new UnsupportedOperationException( "Not yet implemented" ); + } + + if ( jaxbPersistentAttribute instanceof JaxbBasicImpl ) { + final JaxbBasicImpl jaxbBasic = (JaxbBasicImpl) jaxbPersistentAttribute; + if ( jaxbBasic.getJavaType() == null || jaxbBasic.getJavaType().getClazz() == null ) { + return null; + } + else { + return XmlAnnotationHelper.resolveJavaType( + jaxbBasic.getJavaType().getClazz(), + sourceModelBuildingContext + ); + } + } + + if ( jaxbPersistentAttribute instanceof JaxbEmbeddedImpl ) { + final JaxbEmbeddedImpl jaxbEmbedded = (JaxbEmbeddedImpl) jaxbPersistentAttribute; + if ( jaxbEmbedded.getEmbeddable() == null ) { + return null; + } + final ClassDetailsRegistry classDetailsRegistry = sourceModelBuildingContext.getClassDetailsRegistry(); + return classDetailsRegistry.resolveClassDetails( + jaxbEmbedded.getEmbeddable(), + () -> new DynamicClassDetails( + jaxbEmbedded.getEmbeddable(), + null, + false, + null, + sourceModelBuildingContext + ) + ); + } + + if ( jaxbPersistentAttribute instanceof JaxbOneToOneImpl ) { + final JaxbOneToOneImpl jaxbOneToOne = (JaxbOneToOneImpl) jaxbPersistentAttribute; + final String targetEntity = jaxbOneToOne.getTargetEntity(); + } + + if ( jaxbPersistentAttribute instanceof JaxbAnyMappingImpl ) { + return sourceModelBuildingContext.getClassDetailsRegistry().getClassDetails( Object.class.getName() ); + } + + throw new UnsupportedOperationException( "Resolution of dynamic attribute Java type not yet implemented for " + jaxbPersistentAttribute ); + } + + private static void adjustDynamicTypeMember( + MutableMemberDetails memberDetails, + JaxbPersistentAttribute jaxbAttribute, + SourceModelBuildingContext sourceModelBuildingContext) { + XmlAnnotationHelper.applyAttributeAccessor( + BuiltInPropertyAccessStrategies.MAP.getExternalName(), + memberDetails, + sourceModelBuildingContext + ); + } + + private static void processNonDynamicEntity( + MutableClassDetails classDetails, + JaxbEntityImpl jaxbEntity, + AccessType classAccessType, + PersistenceUnitMetadata persistenceUnitMetadata, + SourceModelBuildingContext sourceModelBuildingContext) { + processEntityMetadata( + classDetails, + jaxbEntity, + classAccessType, + ManagedTypeProcessor::adjustNonDynamicTypeMember, + persistenceUnitMetadata, + sourceModelBuildingContext + ); + } private static void processEntityMetadata( - JaxbEntity jaxbEntity, MutableClassDetails classDetails, + JaxbEntityImpl jaxbEntity, + AccessType classAccessType, + AttributeProcessor.MemberAdjuster memberAdjuster, PersistenceUnitMetadata persistenceUnitMetadata, SourceModelBuildingContext sourceModelBuildingContext) { XmlAnnotationHelper.applyEntity( jaxbEntity, classDetails, sourceModelBuildingContext ); XmlAnnotationHelper.applyInheritance( jaxbEntity, classDetails, sourceModelBuildingContext ); + classDetails.addAnnotationUsage( XmlAnnotationHelper.createAccessAnnotation( classAccessType, classDetails ) ); + + if ( StringHelper.isNotEmpty( jaxbEntity.getExtends() ) ) { + final DynamicAnnotationUsage extendsAnn = XmlProcessingHelper.makeAnnotation( + Extends.class, + classDetails + ); + extendsAnn.setAttributeValue( "superType", jaxbEntity.getExtends() ); + } if ( jaxbEntity.getTable() != null ) { XmlAnnotationHelper.applyTable( jaxbEntity.getTable(), classDetails, persistenceUnitMetadata ); } - final AccessType classAccessType = coalesce( - jaxbEntity.getAccess(), - persistenceUnitMetadata.getAccessType() + final JaxbAttributesContainerImpl attributes = jaxbEntity.getAttributes(); + processIdMappings( + attributes, + classAccessType, + classDetails, + memberAdjuster, + sourceModelBuildingContext + ); + processNaturalId( + attributes.getNaturalId(), + classDetails, + classAccessType, + memberAdjuster, + sourceModelBuildingContext + ); + processAttributes( + attributes, + classDetails, + classAccessType, + memberAdjuster, + sourceModelBuildingContext ); - classDetails.addAnnotationUsage( XmlAnnotationHelper.createAccessAnnotation( classAccessType, classDetails ) ); - - final JaxbAttributes attributes = jaxbEntity.getAttributes(); - processIdMappings( attributes, classAccessType, classDetails, sourceModelBuildingContext ); - processNaturalId( attributes.getNaturalId(), classDetails, classAccessType, sourceModelBuildingContext ); - processAttributes( attributes, classDetails, classAccessType, sourceModelBuildingContext ); // todo : id-class - // todo : entity-listeners // todo : callbacks + // todo : entity-listeners // todo : secondary-tables } + + private static void adjustNonDynamicTypeMember( + MutableMemberDetails memberDetails, + JaxbPersistentAttribute jaxbAttribute, + SourceModelBuildingContext sourceModelBuildingContext) { + XmlAnnotationHelper.applyAttributeAccessor( + jaxbAttribute.getAttributeAccessor(), + memberDetails, + sourceModelBuildingContext + ); + } + + private static void applyAttributesToDynamicClass( + MutableClassDetails dynamicClassDetails, + JaxbAttributesContainer attributes, + SourceModelBuildingContext sourceModelBuildingContext) { + attributes.getBasicAttributes().forEach( (jaxbBasic) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbBasic.getName(), + XmlAnnotationHelper.resolveJavaType( jaxbBasic.getType().getValue(), sourceModelBuildingContext ), + sourceModelBuildingContext + ); + dynamicClassDetails.addField( member ); + XmlAnnotationHelper.applyAttributeAccessor( + BuiltInPropertyAccessStrategies.MAP.getExternalName(), + member, + sourceModelBuildingContext + ); + } ); + attributes.getEmbeddedAttributes().forEach( (jaxbEmbedded) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbEmbedded.getName(), + null, + sourceModelBuildingContext + ); + dynamicClassDetails.addField( member ); + XmlAnnotationHelper.applyAttributeAccessor( + BuiltInPropertyAccessStrategies.MAP.getExternalName(), + member, + sourceModelBuildingContext + ); + } ); + attributes.getOneToOneAttributes().forEach( (jaxbOneToOne) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbOneToOne.getName(), + null, + sourceModelBuildingContext + ); + dynamicClassDetails.addField( member ); + XmlAnnotationHelper.applyAttributeAccessor( + BuiltInPropertyAccessStrategies.MAP.getExternalName(), + member, + sourceModelBuildingContext + ); + } ); + attributes.getManyToOneAttributes().forEach( (jaxbOneToOne) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbOneToOne.getName(), + null, + sourceModelBuildingContext + ); + dynamicClassDetails.addField( member ); + XmlAnnotationHelper.applyAttributeAccessor( + BuiltInPropertyAccessStrategies.MAP.getExternalName(), + member, + sourceModelBuildingContext + ); + } ); + attributes.getAnyMappingAttributes().forEach( (jaxbAny) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbAny.getName(), + null, + sourceModelBuildingContext + ); + dynamicClassDetails.addField( member ); + XmlAnnotationHelper.applyAttributeAccessor( + BuiltInPropertyAccessStrategies.MAP.getExternalName(), + member, + sourceModelBuildingContext + ); + } ); + attributes.getElementCollectionAttributes().forEach( (jaxbElementCollection) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbElementCollection.getName(), + null, + sourceModelBuildingContext + ); + dynamicClassDetails.addField( member ); + XmlAnnotationHelper.applyAttributeAccessor( + BuiltInPropertyAccessStrategies.MAP.getExternalName(), + member, + sourceModelBuildingContext + ); + } ); + attributes.getOneToManyAttributes().forEach( (jaxbOneToMany) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbOneToMany.getName(), + null, + sourceModelBuildingContext + ); + dynamicClassDetails.addField( member ); + XmlAnnotationHelper.applyAttributeAccessor( + BuiltInPropertyAccessStrategies.MAP.getExternalName(), + member, + sourceModelBuildingContext + ); + } ); + attributes.getManyToManyAttributes().forEach( (jaxbManyToMany) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbManyToMany.getName(), + null, + sourceModelBuildingContext + ); + dynamicClassDetails.addField( member ); + XmlAnnotationHelper.applyAttributeAccessor( + BuiltInPropertyAccessStrategies.MAP.getExternalName(), + member, + sourceModelBuildingContext + ); + } ); + attributes.getPluralAnyMappingAttributes().forEach( (jaxbManyToAny) -> { + final MapModeFieldDetails member = new MapModeFieldDetails( + jaxbManyToAny.getName(), + null, + sourceModelBuildingContext + ); + dynamicClassDetails.addField( member ); + XmlAnnotationHelper.applyAttributeAccessor( + BuiltInPropertyAccessStrategies.MAP.getExternalName(), + member, + sourceModelBuildingContext + ); + } ); + + } + public static void processOverrideEntity( + List> entityOverrides, + PersistenceUnitMetadata persistenceUnitMetadata, + SourceModelBuildingContext sourceModelBuildingContext) { + entityOverrides.forEach( (overrideTuple) -> { + final JaxbEntityMappingsImpl jaxbRoot = overrideTuple.getJaxbRoot(); + final JaxbEntityImpl jaxbEntity = overrideTuple.getManagedType(); + final String className = XmlProcessingHelper.determineClassName( jaxbRoot, jaxbEntity ); + final MutableClassDetails classDetails = (MutableClassDetails) sourceModelBuildingContext + .getClassDetailsRegistry() + .resolveClassDetails( className ); + + final AccessType classAccessType = coalesce( + jaxbEntity.getAccess(), + persistenceUnitMetadata.getAccessType() + ); + + // from here, processing is the same between override and metadata-complete modes + processEntityMetadata( + classDetails, + jaxbEntity, + classAccessType, + ManagedTypeProcessor::adjustNonDynamicTypeMember, + persistenceUnitMetadata, + sourceModelBuildingContext + ); + } ); + + } + private static void processIdMappings( - JaxbAttributes attributes, + JaxbAttributesContainerImpl attributes, AccessType classAccessType, MutableClassDetails classDetails, + AttributeProcessor.MemberAdjuster memberAdjuster, SourceModelBuildingContext sourceModelBuildingContext) { - final List jaxbIds = attributes.getId(); - final JaxbEmbeddedId jaxbEmbeddedId = attributes.getEmbeddedId(); + final List jaxbIds = attributes.getIdAttributes(); + final JaxbEmbeddedIdImpl jaxbEmbeddedId = attributes.getEmbeddedIdAttribute(); if ( CollectionHelper.isNotEmpty( jaxbIds ) ) { for ( int i = 0; i < jaxbIds.size(); i++ ) { - final JaxbId jaxbId = jaxbIds.get( i ); - AttributeProcessor.processBasicIdAttribute( + final JaxbIdImpl jaxbId = jaxbIds.get( i ); + final MutableMemberDetails memberDetails = AttributeProcessor.processBasicIdAttribute( jaxbId, classDetails, classAccessType, sourceModelBuildingContext ); + memberAdjuster.adjust( memberDetails, jaxbId, sourceModelBuildingContext ); } } else if ( jaxbEmbeddedId != null ) { - AttributeProcessor.processEmbeddedIdAttribute( + final MutableMemberDetails memberDetails = AttributeProcessor.processEmbeddedIdAttribute( jaxbEmbeddedId, classDetails, classAccessType, sourceModelBuildingContext ); + memberAdjuster.adjust( memberDetails, jaxbEmbeddedId, sourceModelBuildingContext ); } else { SourceModelLogging.SOURCE_MODEL_LOGGER.debugf( @@ -164,8 +652,8 @@ else if ( jaxbEmbeddedId != null ) { // MappedSuperclass public static void processCompleteMappedSuperclass( - JaxbEntityMappings jaxbRoot, - JaxbMappedSuperclass jaxbMappedSuperclass, + JaxbEntityMappingsImpl jaxbRoot, + JaxbMappedSuperclassImpl jaxbMappedSuperclass, PersistenceUnitMetadata persistenceUnitMetadata, SourceModelBuildingContext sourceModelBuildingContext) { // todo : should we allow mapped-superclass in dynamic models? @@ -183,7 +671,7 @@ public static void processCompleteMappedSuperclass( } private static void processMappedSuperclassMetadata( - JaxbMappedSuperclass jaxbMappedSuperclass, + JaxbMappedSuperclassImpl jaxbMappedSuperclass, MutableClassDetails classDetails, PersistenceUnitMetadata persistenceUnitMetadata, SourceModelBuildingContext sourceModelBuildingContext) { @@ -195,7 +683,7 @@ private static void processMappedSuperclassMetadata( ); classDetails.addAnnotationUsage( XmlAnnotationHelper.createAccessAnnotation( classAccessType, classDetails ) ); - final JaxbAttributes attributes = jaxbMappedSuperclass.getAttributes(); + final JaxbAttributesContainer attributes = jaxbMappedSuperclass.getAttributes(); processAttributes( attributes, classDetails, classAccessType, sourceModelBuildingContext ); // todo : id-class @@ -204,12 +692,12 @@ private static void processMappedSuperclassMetadata( } public static void processOverrideMappedSuperclass( - List> mappedSuperclassesOverrides, + List> mappedSuperclassesOverrides, PersistenceUnitMetadata persistenceUnitMetadata, SourceModelBuildingContext sourceModelBuildingContext) { mappedSuperclassesOverrides.forEach( (overrideTuple) -> { - final JaxbEntityMappings jaxbRoot = overrideTuple.getJaxbRoot(); - final JaxbMappedSuperclass jaxbMappedSuperclass = overrideTuple.getManagedType(); + final JaxbEntityMappingsImpl jaxbRoot = overrideTuple.getJaxbRoot(); + final JaxbMappedSuperclassImpl jaxbMappedSuperclass = overrideTuple.getManagedType(); final String className = XmlProcessingHelper.determineClassName( jaxbRoot, jaxbMappedSuperclass ); final MutableClassDetails classDetails = (MutableClassDetails) sourceModelBuildingContext .getClassDetailsRegistry() @@ -220,55 +708,89 @@ public static void processOverrideMappedSuperclass( } public static void processCompleteEmbeddable( - JaxbEntityMappings jaxbRoot, - JaxbEmbeddable jaxbEmbeddable, + JaxbEntityMappingsImpl jaxbRoot, + JaxbEmbeddableImpl jaxbEmbeddable, PersistenceUnitMetadata persistenceUnitMetadata, SourceModelBuildingContext sourceModelBuildingContext) { - // todo : add support for dynamic embeddables in XSD - final String className = XmlProcessingHelper.determineClassName( jaxbRoot, jaxbEmbeddable ); - final MutableClassDetails classDetails = (MutableClassDetails) sourceModelBuildingContext - .getClassDetailsRegistry() - .resolveClassDetails( className ); + final MutableClassDetails classDetails; + final AccessType classAccessType; + final AttributeProcessor.MemberAdjuster memberAdjuster; + + if ( StringHelper.isEmpty( jaxbEmbeddable.getClazz() ) ) { + // no class == dynamic... +// classDetails = (MutableClassDetails) sourceModelBuildingContext +// .getClassDetailsRegistry() +// .resolveClassDetails( jaxbEmbeddable.getName() ); +// classAccessType = AccessType.FIELD; +// memberAdjuster = ManagedTypeProcessor::adjustDynamicTypeMember; +// +// prepareDynamicClass( classDetails, jaxbEmbeddable, persistenceUnitMetadata, sourceModelBuildingContext ); + + throw new UnsupportedOperationException( "Not yet implemented" ); + } + else { + final String className = XmlProcessingHelper.determineClassName( jaxbRoot, jaxbEmbeddable ); + classDetails = (MutableClassDetails) sourceModelBuildingContext + .getClassDetailsRegistry() + .resolveClassDetails( className ); + classAccessType = coalesce( + jaxbEmbeddable.getAccess(), + persistenceUnitMetadata.getAccessType() + ); + memberAdjuster = ManagedTypeProcessor::adjustNonDynamicTypeMember; + } classDetails.clearMemberAnnotationUsages(); classDetails.clearAnnotationUsages(); - processEmbeddableMetadata( jaxbEmbeddable, classDetails, persistenceUnitMetadata, sourceModelBuildingContext ); + processEmbeddableMetadata( + jaxbEmbeddable, + classDetails, + classAccessType, + memberAdjuster, + persistenceUnitMetadata, + sourceModelBuildingContext + ); } - /** - * Process common between complete and override metadata - */ private static void processEmbeddableMetadata( - JaxbEmbeddable jaxbEmbeddable, + JaxbEmbeddableImpl jaxbEmbeddable, MutableClassDetails classDetails, + AccessType classAccessType, + AttributeProcessor.MemberAdjuster memberAdjuster, PersistenceUnitMetadata persistenceUnitMetadata, SourceModelBuildingContext sourceModelBuildingContext) { XmlProcessingHelper.getOrMakeAnnotation( Embeddable.class, classDetails ); - - final AccessType classAccessType = coalesce( - jaxbEmbeddable.getAccess(), - persistenceUnitMetadata.getAccessType() - ); classDetails.addAnnotationUsage( XmlAnnotationHelper.createAccessAnnotation( classAccessType, classDetails ) ); - final JaxbEmbeddableAttributes attributes = jaxbEmbeddable.getAttributes(); - processAttributes( attributes, classDetails, classAccessType, sourceModelBuildingContext ); + processAttributes( + jaxbEmbeddable.getAttributes(), + classDetails, + AccessType.FIELD, + memberAdjuster, + sourceModelBuildingContext + ); } public static void processOverrideEmbeddable( - List> embeddableOverrides, + List> embeddableOverrides, PersistenceUnitMetadata persistenceUnitMetadata, SourceModelBuildingContext sourceModelBuildingContext) { embeddableOverrides.forEach( (overrideTuple) -> { - final JaxbEntityMappings jaxbRoot = overrideTuple.getJaxbRoot(); - final JaxbEmbeddable jaxbEmbeddable = overrideTuple.getManagedType(); + final JaxbEntityMappingsImpl jaxbRoot = overrideTuple.getJaxbRoot(); + final JaxbEmbeddableImpl jaxbEmbeddable = overrideTuple.getManagedType(); final String className = XmlProcessingHelper.determineClassName( jaxbRoot, jaxbEmbeddable ); final MutableClassDetails classDetails = (MutableClassDetails) sourceModelBuildingContext .getClassDetailsRegistry() .resolveClassDetails( className ); - processEmbeddableMetadata( jaxbEmbeddable, classDetails, persistenceUnitMetadata, sourceModelBuildingContext ); + processAttributes( + jaxbEmbeddable.getAttributes(), + classDetails, + AccessType.FIELD, + ManagedTypeProcessor::adjustNonDynamicTypeMember, + sourceModelBuildingContext + ); } ); } } diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/PersistenceUnitMetadataImpl.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/PersistenceUnitMetadataImpl.java index c79ec56..071907f 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/PersistenceUnitMetadataImpl.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/PersistenceUnitMetadataImpl.java @@ -11,9 +11,9 @@ import java.util.Set; import org.hibernate.annotations.CascadeType; -import org.hibernate.boot.jaxb.mapping.JaxbEntityListener; -import org.hibernate.boot.jaxb.mapping.JaxbPersistenceUnitDefaults; -import org.hibernate.boot.jaxb.mapping.JaxbPersistenceUnitMetadata; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListenerImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitDefaultsImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitMetadataImpl; import org.hibernate.models.orm.internal.OrmModelLogging; import org.hibernate.models.orm.xml.spi.PersistenceUnitMetadata; @@ -39,7 +39,7 @@ public final class PersistenceUnitMetadataImpl implements PersistenceUnitMetadat private String defaultAccessStrategy; private final EnumSet defaultCascadeTypes = EnumSet.noneOf( CascadeType.class ); - private final Set globalEntityListeners = new HashSet<>(); + private final Set globalEntityListeners = new HashSet<>(); @Override public boolean areXmlMappingsComplete() { @@ -77,18 +77,18 @@ public boolean useQuotedIdentifiers() { } @Override - public Set getEntityListeners() { + public Set getEntityListeners() { return globalEntityListeners; } - public void apply(JaxbPersistenceUnitMetadata metadata) { + public void apply(JaxbPersistenceUnitMetadataImpl metadata) { if ( metadata == null ) { return; } xmlComplete = xmlComplete || metadata.getXmlMappingMetadataComplete() != null; - final JaxbPersistenceUnitDefaults defaults = metadata.getPersistenceUnitDefaults(); + final JaxbPersistenceUnitDefaultsImpl defaults = metadata.getPersistenceUnitDefaults(); if ( defaults == null ) { return; } diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlAnnotationHelper.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlAnnotationHelper.java index 82f170f..db4618c 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlAnnotationHelper.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlAnnotationHelper.java @@ -7,38 +7,46 @@ package org.hibernate.models.orm.xml.internal; import java.lang.annotation.Annotation; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import org.hibernate.annotations.AttributeAccessor; import org.hibernate.annotations.Formula; +import org.hibernate.annotations.JdbcType; import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.annotations.Nationalized; import org.hibernate.annotations.NaturalId; import org.hibernate.annotations.NaturalIdCache; import org.hibernate.annotations.OptimisticLock; import org.hibernate.annotations.Parameter; +import org.hibernate.annotations.Target; import org.hibernate.annotations.Type; import org.hibernate.annotations.UuidGenerator; -import org.hibernate.boot.jaxb.mapping.JaxbAssociationOverride; -import org.hibernate.boot.jaxb.mapping.JaxbAttributeOverride; -import org.hibernate.boot.jaxb.mapping.JaxbBasic; -import org.hibernate.boot.jaxb.mapping.JaxbCaching; -import org.hibernate.boot.jaxb.mapping.JaxbColumn; -import org.hibernate.boot.jaxb.mapping.JaxbColumnType; -import org.hibernate.boot.jaxb.mapping.JaxbConfigurationParameter; -import org.hibernate.boot.jaxb.mapping.JaxbConvert; -import org.hibernate.boot.jaxb.mapping.JaxbEmbeddedId; -import org.hibernate.boot.jaxb.mapping.JaxbEntity; -import org.hibernate.boot.jaxb.mapping.JaxbGeneratedValue; -import org.hibernate.boot.jaxb.mapping.JaxbId; -import org.hibernate.boot.jaxb.mapping.JaxbLob; -import org.hibernate.boot.jaxb.mapping.JaxbNationalized; -import org.hibernate.boot.jaxb.mapping.JaxbNaturalId; -import org.hibernate.boot.jaxb.mapping.JaxbSequenceGenerator; -import org.hibernate.boot.jaxb.mapping.JaxbTable; -import org.hibernate.boot.jaxb.mapping.JaxbTableGenerator; -import org.hibernate.boot.jaxb.mapping.JaxbUuidGenerator; +import org.hibernate.boot.jaxb.mapping.spi.JaxbAssociationOverrideImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributeOverrideImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbBasicImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbCachingImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbColumnImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbConfigurationParameterImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbConvertImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedIdImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntity; +import org.hibernate.boot.jaxb.mapping.spi.JaxbGeneratedValueImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbIdImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbJavaTypeImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbJdbcTypeImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbLobImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbNationalizedImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbNaturalId; +import org.hibernate.boot.jaxb.mapping.spi.JaxbNaturalIdImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbSequenceGeneratorImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbTableGeneratorImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbTableImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbUserTypeImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbUuidGeneratorImpl; import org.hibernate.models.internal.CollectionHelper; import org.hibernate.models.internal.StringHelper; import org.hibernate.models.orm.xml.spi.PersistenceUnitMetadata; @@ -78,6 +86,7 @@ import static java.util.Collections.emptyList; import static org.hibernate.internal.util.NullnessHelper.coalesce; import static org.hibernate.models.orm.xml.internal.XmlProcessingHelper.getOrMakeAnnotation; +import static org.hibernate.models.orm.xml.internal.XmlProcessingHelper.makeAnnotation; /** * Helper for creating annotation from equivalent JAXB @@ -101,7 +110,7 @@ public static void applyEntity( } public static void applyBasic( - JaxbId jaxbId, + JaxbIdImpl jaxbId, MutableMemberDetails memberDetails, SourceModelBuildingContext sourceModelBuildingContext) { final DynamicAnnotationUsage annotationUsage = new DynamicAnnotationUsage<>( Basic.class, memberDetails ); @@ -111,7 +120,7 @@ public static void applyBasic( } public static void applyBasic( - JaxbBasic jaxbBasic, + JaxbBasicImpl jaxbBasic, MutableMemberDetails memberDetails, SourceModelBuildingContext sourceModelBuildingContext) { final MutableAnnotationUsage basicAnn = XmlProcessingHelper.getOrMakeAnnotation( Basic.class, memberDetails ); @@ -156,7 +165,7 @@ public static void applyAttributeAccessor( } public static void applyColumn( - JaxbColumn jaxbColumn, + JaxbColumnImpl jaxbColumn, MutableMemberDetails memberDetails, SourceModelBuildingContext sourceModelBuildingContext) { if ( jaxbColumn == null ) { @@ -167,7 +176,7 @@ public static void applyColumn( } private static MutableAnnotationUsage createColumnAnnotation( - JaxbColumn jaxbColumn, + JaxbColumnImpl jaxbColumn, MutableAnnotationTarget target) { final MutableAnnotationUsage columnAnn = XmlProcessingHelper.getOrMakeAnnotation( Column.class, target ); @@ -237,7 +246,7 @@ private static AnnotationUsage createFormulaAnnotation( } public static void applyUserType( - JaxbColumnType jaxbType, + JaxbUserTypeImpl jaxbType, MutableMemberDetails memberDetails, SourceModelBuildingContext buildingContext) { if ( jaxbType == null ) { @@ -247,13 +256,13 @@ public static void applyUserType( final DynamicAnnotationUsage typeAnn = new DynamicAnnotationUsage<>( Type.class, memberDetails ); memberDetails.addAnnotationUsage( typeAnn ); - final ClassDetails userTypeImpl = buildingContext.getClassDetailsRegistry().resolveClassDetails( jaxbType.getValue() ); + final ClassDetails userTypeImpl = resolveJavaType( jaxbType.getValue(), buildingContext ); typeAnn.setAttributeValue( "value", userTypeImpl ); typeAnn.setAttributeValue( "parameters", collectParameters( jaxbType.getParameters(), memberDetails ) ); } private static List> collectParameters( - List jaxbParameters, + List jaxbParameters, AnnotationTarget target) { if ( CollectionHelper.isEmpty( jaxbParameters ) ) { return emptyList(); @@ -269,6 +278,43 @@ private static List> collectParameters( return parameterAnnList; } + public static void applyTargetClass( + String name, + MutableMemberDetails memberDetails, + SourceModelBuildingContext sourceModelBuildingContext) { + final ClassDetails classDetails = resolveJavaType( name, sourceModelBuildingContext ); + final DynamicAnnotationUsage targetAnn = makeAnnotation( Target.class, memberDetails ); + targetAnn.setAttributeValue( "value", classDetails ); + } + + public static void applyJdbcType( + JaxbJdbcTypeImpl jaxbJdbcType, + MutableMemberDetails memberDetails, + SourceModelBuildingContext sourceModelBuildingContext) { + if ( jaxbJdbcType == null ) { + return; + } + + if ( jaxbJdbcType.getCode() != null ) { + applyJdbcTypeCode( jaxbJdbcType.getCode(), memberDetails, sourceModelBuildingContext ); + } + else if ( jaxbJdbcType.getDescriptor() != null ) { + applyJdbcTypeDescriptor( jaxbJdbcType.getDescriptor(), memberDetails, sourceModelBuildingContext ); + } + } + + private static void applyJdbcTypeDescriptor( + String descriptorName, + MutableMemberDetails memberDetails, + SourceModelBuildingContext sourceModelBuildingContext) { + final ClassDetails descriptorClassDetails = sourceModelBuildingContext + .getClassDetailsRegistry() + .resolveClassDetails( descriptorName ); + final DynamicAnnotationUsage jdbcTypeAnn = makeAnnotation( JdbcType.class, memberDetails ); + jdbcTypeAnn.setAttributeValue( "value", descriptorClassDetails ); + + } + public static void applyJdbcTypeCode( Integer jdbcTypeCode, MutableMemberDetails memberDetails, @@ -296,7 +342,7 @@ public static void applyTemporal( } public static void applyLob( - JaxbLob jaxbLob, + JaxbLobImpl jaxbLob, MutableMemberDetails memberDetails, SourceModelBuildingContext sourceModelBuildingContext) { if ( jaxbLob == null ) { @@ -325,7 +371,7 @@ public static void applyEnumerated( } public static void applyNationalized( - JaxbNationalized jaxbNationalized, + JaxbNationalizedImpl jaxbNationalized, MutableMemberDetails memberDetails, SourceModelBuildingContext sourceModelBuildingContext) { if ( jaxbNationalized == null ) { @@ -340,7 +386,7 @@ public static void applyNationalized( } public static void applyGeneratedValue( - JaxbGeneratedValue jaxbGeneratedValue, + JaxbGeneratedValueImpl jaxbGeneratedValue, MutableMemberDetails memberDetails, SourceModelBuildingContext sourceModelBuildingContext) { if ( jaxbGeneratedValue == null ) { @@ -354,7 +400,7 @@ public static void applyGeneratedValue( } public static void applySequenceGenerator( - JaxbSequenceGenerator jaxbGenerator, + JaxbSequenceGeneratorImpl jaxbGenerator, MutableMemberDetails memberDetails, SourceModelBuildingContext sourceModelBuildingContext) { if ( jaxbGenerator == null ) { @@ -378,7 +424,7 @@ public static void applySequenceGenerator( } public static void applyTableGenerator( - JaxbTableGenerator jaxbGenerator, + JaxbTableGeneratorImpl jaxbGenerator, MutableMemberDetails memberDetails, SourceModelBuildingContext sourceModelBuildingContext) { if ( jaxbGenerator == null ) { @@ -401,7 +447,7 @@ public static void applyTableGenerator( } public static void applyUuidGenerator( - JaxbUuidGenerator jaxbGenerator, + JaxbUuidGeneratorImpl jaxbGenerator, MutableMemberDetails memberDetails, SourceModelBuildingContext sourceModelBuildingContext) { if ( jaxbGenerator == null ) { @@ -414,7 +460,7 @@ public static void applyUuidGenerator( } public static void applyAttributeOverrides( - List jaxbOverrides, + List jaxbOverrides, MutableMemberDetails memberDetails, SourceModelBuildingContext sourceModelBuildingContext) { if ( CollectionHelper.isEmpty( jaxbOverrides ) ) { @@ -433,7 +479,7 @@ public static void applyAttributeOverrides( } public static void applyAssociationOverrides( - List jaxbOverrides, + List jaxbOverrides, MutableMemberDetails memberDetails, SourceModelBuildingContext sourceModelBuildingContext) { if ( CollectionHelper.isEmpty( jaxbOverrides ) ) { @@ -466,7 +512,7 @@ public static void applyOptimisticLockInclusion( } public static void applyConvert( - JaxbConvert jaxbConvert, + JaxbConvertImpl jaxbConvert, MutableMemberDetails memberDetails, SourceModelBuildingContext sourceModelBuildingContext) { if ( jaxbConvert == null ) { @@ -487,7 +533,7 @@ public static void applyConvert( } public static void applyTable( - JaxbTable jaxbTable, + JaxbTableImpl jaxbTable, MutableAnnotationTarget target, PersistenceUnitMetadata persistenceUnitMetadata) { final DynamicAnnotationUsage tableAnn = new DynamicAnnotationUsage<>( Table.class, target ); @@ -500,7 +546,7 @@ public static void applyTable( } public static void applyTableOverride( - JaxbTable jaxbTable, + JaxbTableImpl jaxbTable, MutableAnnotationTarget target, PersistenceUnitMetadata persistenceUnitMetadata) { if ( jaxbTable == null ) { @@ -517,7 +563,7 @@ public static void applyTableOverride( private static void applyTableAttributes( MutableAnnotationUsage
tableAnn, - JaxbTable jaxbTable, + JaxbTableImpl jaxbTable, PersistenceUnitMetadata persistenceUnitMetadata) { applyAttributeIfSpecified( tableAnn, "name", jaxbTable.getName() ); applyAttributeIfSpecified( tableAnn, "catalog", jaxbTable.getCatalog(), persistenceUnitMetadata.getDefaultCatalog() ); @@ -571,7 +617,7 @@ public static void applyNaturalIdCache( JaxbNaturalId jaxbNaturalId, MutableClassDetails classDetails, SourceModelBuildingContext sourceModelBuildingContext) { - if ( jaxbNaturalId == null || jaxbNaturalId.getCache() == null ) { + if ( jaxbNaturalId == null || jaxbNaturalId.getCaching() == null ) { return; } @@ -581,12 +627,12 @@ public static void applyNaturalIdCache( ); classDetails.addAnnotationUsage( annotationUsage ); - final JaxbCaching jaxbCaching = jaxbNaturalId.getCache(); + final JaxbCachingImpl jaxbCaching = jaxbNaturalId.getCaching(); annotationUsage.setAttributeValue( "region", jaxbCaching.getRegion() ); } public static void applyId( - JaxbId jaxbId, + JaxbIdImpl jaxbId, MutableMemberDetails memberDetails, SourceModelBuildingContext sourceModelBuildingContext) { if ( jaxbId == null ) { @@ -600,7 +646,7 @@ public static void applyId( } public static void applyEmbeddedId( - JaxbEmbeddedId jaxbEmbeddedId, + JaxbEmbeddedIdImpl jaxbEmbeddedId, MutableMemberDetails memberDetails, SourceModelBuildingContext sourceModelBuildingContext) { if ( jaxbEmbeddedId == null ) { @@ -627,4 +673,48 @@ static void applyInheritance( ); inheritanceAnn.setAttributeValue( "strategy", jaxbEntity.getInheritance().getStrategy() ); } + + public static ClassDetails resolveJavaType(String value, SourceModelBuildingContext sourceModelBuildingContext) { + if ( StringHelper.isEmpty( value ) ) { + value = Object.class.getName(); + } + else if ( Byte.class.getSimpleName().equals( value ) ) { + value = Byte.class.getName(); + } + else if ( Boolean.class.getSimpleName().equals( value ) ) { + value = Boolean.class.getName(); + } + else if ( Short.class.getSimpleName().equals( value ) ) { + value = Short.class.getName(); + } + else if ( Integer.class.getSimpleName().equals( value ) ) { + value = Integer.class.getName(); + } + else if ( Long.class.getSimpleName().equals( value ) ) { + value = Long.class.getName(); + } + else if ( Double.class.getSimpleName().equals( value ) ) { + value = Double.class.getName(); + } + else if ( Float.class.getSimpleName().equals( value ) ) { + value = Float.class.getName(); + } + else if ( BigInteger.class.getSimpleName().equals( value ) ) { + value = BigInteger.class.getName(); + } + else if ( BigDecimal.class.getSimpleName().equals( value ) ) { + value = BigDecimal.class.getName(); + } + else if ( String.class.getSimpleName().equals( value ) ) { + value = String.class.getName(); + } + else if ( Character.class.getSimpleName().equals( value ) ) { + value = Character.class.getName(); + } + else if ( UUID.class.getSimpleName().equals( value ) ) { + value = Character.class.getName(); + } + + return sourceModelBuildingContext.getClassDetailsRegistry().resolveClassDetails( value ); + } } diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlDocumentImpl.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlDocumentImpl.java index e45412e..55d5122 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlDocumentImpl.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlDocumentImpl.java @@ -13,21 +13,21 @@ import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNamedNativeQueryType; import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNamedQueryType; -import org.hibernate.boot.jaxb.mapping.JaxbCollectionUserTypeRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbCompositeUserTypeRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbConverter; -import org.hibernate.boot.jaxb.mapping.JaxbConverterRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbEmbeddable; -import org.hibernate.boot.jaxb.mapping.JaxbEmbeddableInstantiatorRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbEntity; -import org.hibernate.boot.jaxb.mapping.JaxbEntityMappings; -import org.hibernate.boot.jaxb.mapping.JaxbJavaTypeRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbJdbcTypeRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbMappedSuperclass; -import org.hibernate.boot.jaxb.mapping.JaxbNamedNativeQuery; -import org.hibernate.boot.jaxb.mapping.JaxbNamedQuery; -import org.hibernate.boot.jaxb.mapping.JaxbNamedStoredProcedureQuery; -import org.hibernate.boot.jaxb.mapping.JaxbUserTypeRegistration; +import org.hibernate.boot.jaxb.mapping.spi.JaxbCollectionUserTypeRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbCompositeUserTypeRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbConverterImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbConverterRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddableImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddableInstantiatorRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbJavaTypeRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbJdbcTypeRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbMappedSuperclassImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbNamedNativeQueryImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbNamedQueryImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbNamedStoredProcedureQueryImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbUserTypeRegistrationImpl; import org.hibernate.internal.util.NullnessHelper; import org.hibernate.models.orm.xml.spi.PersistenceUnitMetadata; import org.hibernate.models.orm.xml.spi.XmlDocument; @@ -41,39 +41,39 @@ */ public class XmlDocumentImpl implements XmlDocument { private final DefaultsImpl defaults; - private final List entityMappings; - private final List mappedSuperclassMappings; - private final List embeddableMappings; - private final List converters; - private final List converterRegistrations; - private final List javaTypeRegistrations; - private final List jdbcTypeRegistrations; - private final List userTypeRegistrations; - private final List compositeUserTypeRegistrations; - private final List collectionUserTypeRegistrations; - private final List embeddableInstantiatorRegistrations; - private final Map jpaNamedQueries; - private final Map jpaNamedNativeQueries; + private final List entityMappings; + private final List mappedSuperclassMappings; + private final List embeddableMappings; + private final List converters; + private final List converterRegistrations; + private final List javaTypeRegistrations; + private final List jdbcTypeRegistrations; + private final List userTypeRegistrations; + private final List compositeUserTypeRegistrations; + private final List collectionUserTypeRegistrations; + private final List embeddableInstantiatorRegistrations; + private final Map jpaNamedQueries; + private final Map jpaNamedNativeQueries; private final Map hibernateNamedQueries; private final Map hibernateNamedNativeQueries; - private final Map namedStoredProcedureQueries; + private final Map namedStoredProcedureQueries; private XmlDocumentImpl( DefaultsImpl defaults, - List entityMappings, - List mappedSuperclassMappings, - List embeddableMappings, - List converters, - List converterRegistrations, - List javaTypeRegistrations, - List jdbcTypeRegistrations, - List userTypeRegistrations, - List compositeUserTypeRegistrations, - List collectionUserTypeRegistrations, - List embeddableInstantiatorRegistrations, - Map jpaNamedQueries, - Map jpaNamedNativeQueries, - Map namedStoredProcedureQueries, + List entityMappings, + List mappedSuperclassMappings, + List embeddableMappings, + List converters, + List converterRegistrations, + List javaTypeRegistrations, + List jdbcTypeRegistrations, + List userTypeRegistrations, + List compositeUserTypeRegistrations, + List collectionUserTypeRegistrations, + List embeddableInstantiatorRegistrations, + Map jpaNamedQueries, + Map jpaNamedNativeQueries, + Map namedStoredProcedureQueries, Map hibernateNamedQueries, Map hibernateNamedNativeQueries) { this.defaults = defaults; @@ -101,67 +101,67 @@ public Defaults getDefaults() { } @Override - public List getEntityMappings() { + public List getEntityMappings() { return entityMappings; } - @Override - public List getMappedSuperclassMappings() { + @Override + public List getMappedSuperclassMappings() { return mappedSuperclassMappings; } @Override - public List getEmbeddableMappings() { + public List getEmbeddableMappings() { return embeddableMappings; } @Override - public List getConverters() { + public List getConverters() { return converters; } @Override - public List getConverterRegistrations() { + public List getConverterRegistrations() { return converterRegistrations; } @Override - public List getJavaTypeRegistrations() { + public List getJavaTypeRegistrations() { return javaTypeRegistrations; } @Override - public List getJdbcTypeRegistrations() { + public List getJdbcTypeRegistrations() { return jdbcTypeRegistrations; } @Override - public List getUserTypeRegistrations() { + public List getUserTypeRegistrations() { return userTypeRegistrations; } @Override - public List getCompositeUserTypeRegistrations() { + public List getCompositeUserTypeRegistrations() { return compositeUserTypeRegistrations; } @Override - public List getCollectionUserTypeRegistrations() { + public List getCollectionUserTypeRegistrations() { return collectionUserTypeRegistrations; } @Override - public List getEmbeddableInstantiatorRegistrations() { + public List getEmbeddableInstantiatorRegistrations() { return embeddableInstantiatorRegistrations; } @Override - public Map getJpaNamedQueries() { + public Map getJpaNamedQueries() { return jpaNamedQueries; } @Override - public Map getJpaNamedNativeQueries() { + public Map getJpaNamedNativeQueries() { return jpaNamedNativeQueries; } @@ -176,7 +176,7 @@ public Map getHibernateNamedNativeQueries() } @Override - public Map getNamedStoredProcedureQueries() { + public Map getNamedStoredProcedureQueries() { return namedStoredProcedureQueries; } @@ -241,7 +241,7 @@ public boolean isLazinessImplied() { return impliedLaziness; } - static DefaultsImpl consume(JaxbEntityMappings jaxbRoot, PersistenceUnitMetadata metadata) { + static DefaultsImpl consume(JaxbEntityMappingsImpl jaxbRoot, PersistenceUnitMetadata metadata) { return new DefaultsImpl( jaxbRoot.getPackage(), NullnessHelper.coalesce( jaxbRoot.getAccess(), metadata.getAccessType() ), @@ -254,7 +254,7 @@ static DefaultsImpl consume(JaxbEntityMappings jaxbRoot, PersistenceUnitMetadata } } - public static XmlDocumentImpl consume(JaxbEntityMappings jaxbRoot, PersistenceUnitMetadata metadata) { + public static XmlDocumentImpl consume(JaxbEntityMappingsImpl jaxbRoot, PersistenceUnitMetadata metadata) { return new XmlDocumentImpl( DefaultsImpl.consume( jaxbRoot, metadata ), jaxbRoot.getEntities(), @@ -277,32 +277,32 @@ public static XmlDocumentImpl consume(JaxbEntityMappings jaxbRoot, PersistenceUn ); } - private static Map toNamedQueryMap(List namedQueries) { + private static Map toNamedQueryMap(List namedQueries) { if ( isEmpty( namedQueries ) ) { return Collections.emptyMap(); } - final Map map = new HashMap<>(); + final Map map = new HashMap<>(); namedQueries.forEach( (query) -> map.put( query.getName(), query ) ); return map; } - private static Map toNamedNativeQueryMap(List namedQueries) { + private static Map toNamedNativeQueryMap(List namedQueries) { if ( isEmpty( namedQueries ) ) { return Collections.emptyMap(); } - final Map map = new HashMap<>(); + final Map map = new HashMap<>(); namedQueries.forEach( (query) -> map.put( query.getName(), query ) ); return map; } - private static Map toNamedProcedureQueryMap(List namedQueries) { + private static Map toNamedProcedureQueryMap(List namedQueries) { if ( isEmpty( namedQueries ) ) { return Collections.emptyMap(); } - final Map map = new HashMap<>(); + final Map map = new HashMap<>(); namedQueries.forEach( (query) -> map.put( query.getName(), query ) ); return map; } diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlProcessingHelper.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlProcessingHelper.java index e1f9156..9aaa127 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlProcessingHelper.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/internal/XmlProcessingHelper.java @@ -9,8 +9,8 @@ import java.beans.Introspector; import java.lang.annotation.Annotation; -import org.hibernate.boot.jaxb.mapping.JaxbEntityMappings; -import org.hibernate.boot.jaxb.mapping.ManagedType; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbManagedType; import org.hibernate.models.internal.StringHelper; import org.hibernate.models.orm.MemberResolutionException; import org.hibernate.models.source.internal.MutableAnnotationTarget; @@ -37,7 +37,7 @@ public class XmlProcessingHelper { * @param jaxbRoot The {@code } node for access to the package (if one) * @param jaxbManagedType The class JAXB node */ - public static String determineClassName(JaxbEntityMappings jaxbRoot, ManagedType jaxbManagedType) { + public static String determineClassName(JaxbEntityMappingsImpl jaxbRoot, JaxbManagedType jaxbManagedType) { if ( StringHelper.isQualified( jaxbManagedType.getClazz() ) ) { return jaxbManagedType.getClazz(); } diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/PersistenceUnitMetadata.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/PersistenceUnitMetadata.java index 191febe..138fdff 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/PersistenceUnitMetadata.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/PersistenceUnitMetadata.java @@ -10,7 +10,7 @@ import java.util.Set; import org.hibernate.annotations.CascadeType; -import org.hibernate.boot.jaxb.mapping.JaxbEntityListener; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListenerImpl; import org.hibernate.property.access.spi.PropertyAccessStrategy; import jakarta.persistence.AccessType; @@ -69,5 +69,5 @@ public interface PersistenceUnitMetadata { * Entity listeners in effect for the entire persistence unit * See {@code entity-mappings/persistence-unit-metadata/persistence-unit-defaults/entity-listeners} */ - Set getEntityListeners(); + Set getEntityListeners(); } diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/XmlDocument.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/XmlDocument.java index 93c3480..680eb8f 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/XmlDocument.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/XmlDocument.java @@ -11,20 +11,20 @@ import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNamedNativeQueryType; import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNamedQueryType; -import org.hibernate.boot.jaxb.mapping.JaxbCollectionUserTypeRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbCompositeUserTypeRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbConverter; -import org.hibernate.boot.jaxb.mapping.JaxbConverterRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbEmbeddable; -import org.hibernate.boot.jaxb.mapping.JaxbEmbeddableInstantiatorRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbEntity; -import org.hibernate.boot.jaxb.mapping.JaxbJavaTypeRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbJdbcTypeRegistration; -import org.hibernate.boot.jaxb.mapping.JaxbMappedSuperclass; -import org.hibernate.boot.jaxb.mapping.JaxbNamedNativeQuery; -import org.hibernate.boot.jaxb.mapping.JaxbNamedQuery; -import org.hibernate.boot.jaxb.mapping.JaxbNamedStoredProcedureQuery; -import org.hibernate.boot.jaxb.mapping.JaxbUserTypeRegistration; +import org.hibernate.boot.jaxb.mapping.spi.JaxbCollectionUserTypeRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbCompositeUserTypeRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbConverterImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbConverterRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddableImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddableInstantiatorRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbJavaTypeRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbJdbcTypeRegistrationImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbMappedSuperclassImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbNamedNativeQueryImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbNamedQueryImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbNamedStoredProcedureQueryImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbUserTypeRegistrationImpl; import jakarta.persistence.AccessType; @@ -32,37 +32,37 @@ * @author Steve Ebersole */ public interface XmlDocument { - List getEntityMappings(); + List getEntityMappings(); - List getMappedSuperclassMappings(); + List getMappedSuperclassMappings(); - List getEmbeddableMappings(); + List getEmbeddableMappings(); - List getConverters(); + List getConverters(); - List getConverterRegistrations(); + List getConverterRegistrations(); - List getJavaTypeRegistrations(); + List getJavaTypeRegistrations(); - List getJdbcTypeRegistrations(); + List getJdbcTypeRegistrations(); - List getUserTypeRegistrations(); + List getUserTypeRegistrations(); - List getCompositeUserTypeRegistrations(); + List getCompositeUserTypeRegistrations(); - List getCollectionUserTypeRegistrations(); + List getCollectionUserTypeRegistrations(); - List getEmbeddableInstantiatorRegistrations(); + List getEmbeddableInstantiatorRegistrations(); - Map getJpaNamedQueries(); + Map getJpaNamedQueries(); - Map getJpaNamedNativeQueries(); + Map getJpaNamedNativeQueries(); Map getHibernateNamedQueries(); Map getHibernateNamedNativeQueries(); - Map getNamedStoredProcedureQueries(); + Map getNamedStoredProcedureQueries(); interface Defaults { String getPackage(); diff --git a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/XmlResources.java b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/XmlResources.java index 6b907df..3bc1ebd 100644 --- a/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/XmlResources.java +++ b/hibernate-models-orm/src/main/java/org/hibernate/models/orm/xml/spi/XmlResources.java @@ -15,9 +15,9 @@ import org.hibernate.boot.jaxb.Origin; import org.hibernate.boot.jaxb.SourceType; import org.hibernate.boot.jaxb.internal.MappingBinder; -import org.hibernate.boot.jaxb.mapping.JaxbEntityMappings; -import org.hibernate.boot.jaxb.spi.BindableMappingDescriptor; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl; import org.hibernate.boot.jaxb.spi.Binding; +import org.hibernate.boot.jaxb.spi.JaxbBindableMappingDescriptor; import org.hibernate.models.orm.spi.ManagedResources; import org.hibernate.models.orm.xml.XmlResourceException; import org.hibernate.models.orm.xml.internal.PersistenceUnitMetadataImpl; @@ -35,7 +35,7 @@ */ public class XmlResources { private final PersistenceUnitMetadataImpl persistenceUnitMetadata = new PersistenceUnitMetadataImpl(); - private final List documents = new ArrayList<>(); + private final List documents = new ArrayList<>(); public XmlResources() { } @@ -59,11 +59,11 @@ public static XmlResources collectXmlResources( throw new XmlResourceException( "Unable to locate XML mapping - " + xmlMapping ); } try (InputStream inputStream = resource.openStream()) { - final Binding binding = mappingBinder.bind( + final Binding binding = mappingBinder.bind( inputStream, new Origin( SourceType.RESOURCE, xmlMapping ) ); - collected.addDocument( (JaxbEntityMappings) binding.getRoot() ); + collected.addDocument( (JaxbEntityMappingsImpl) binding.getRoot() ); } catch (IOException e) { throw new XmlResourceException( "Unable to bind XML mapping - " + xmlMapping, e ); @@ -84,11 +84,11 @@ public PersistenceUnitMetadata getPersistenceUnitMetadata() { /** * All documents in the persistence-unit */ - public List getDocuments() { + public List getDocuments() { return documents; } - public void addDocument(JaxbEntityMappings document) { + public void addDocument(JaxbEntityMappingsImpl document) { persistenceUnitMetadata.apply( document.getPersistenceUnitMetadata() ); documents.add( document ); } diff --git a/hibernate-models-orm/src/test/java/org/hibernate/models/orm/XmlHelper.java b/hibernate-models-orm/src/test/java/org/hibernate/models/orm/XmlHelper.java index 4d80478..641b3c3 100644 --- a/hibernate-models-orm/src/test/java/org/hibernate/models/orm/XmlHelper.java +++ b/hibernate-models-orm/src/test/java/org/hibernate/models/orm/XmlHelper.java @@ -14,9 +14,9 @@ import org.hibernate.boot.jaxb.Origin; import org.hibernate.boot.jaxb.SourceType; import org.hibernate.boot.jaxb.internal.MappingBinder; -import org.hibernate.boot.jaxb.mapping.JaxbEntityMappings; -import org.hibernate.boot.jaxb.spi.BindableMappingDescriptor; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl; import org.hibernate.boot.jaxb.spi.Binding; +import org.hibernate.boot.jaxb.spi.JaxbBindableMappingDescriptor; import org.hibernate.models.orm.xml.XmlResourceException; import org.hibernate.models.spi.ClassLoading; @@ -26,14 +26,14 @@ * @author Steve Ebersole */ public class XmlHelper { - public static JaxbEntityMappings loadMapping(String resourceName, ClassLoading classLoadingAccess) { + public static JaxbEntityMappingsImpl loadMapping(String resourceName, ClassLoading classLoadingAccess) { final ResourceStreamLocatorImpl resourceStreamLocator = new ResourceStreamLocatorImpl( classLoadingAccess ); final MappingBinder mappingBinder = new MappingBinder( resourceStreamLocator, NON_VALIDATING ); - final Binding binding = mappingBinder.bind( + final Binding binding = mappingBinder.bind( resourceStreamLocator.locateResourceStream( resourceName ), new Origin( SourceType.RESOURCE, resourceName ) ); - return (JaxbEntityMappings) binding.getRoot(); + return (JaxbEntityMappingsImpl) binding.getRoot(); } private static class ResourceStreamLocatorImpl implements ResourceStreamLocator { 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 5817408..c00aeb8 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,7 +9,7 @@ import java.util.List; import java.util.Map; -import org.hibernate.boot.jaxb.mapping.JaxbEntityMappings; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl; import org.hibernate.models.orm.spi.FilterDefRegistration; import org.hibernate.models.orm.internal.GlobalRegistrationsImpl; import org.hibernate.models.orm.internal.ProcessResultCollector; @@ -40,8 +40,8 @@ public class XmlProcessingSmokeTests { void testPersistenceUnitDefaults1() { final XmlResources collector = new XmlResources(); - final JaxbEntityMappings simple1 = loadMapping( "mappings/simple1.xml", SIMPLE_CLASS_LOADING ); - final JaxbEntityMappings simple2 = loadMapping( "mappings/simple2.xml", SIMPLE_CLASS_LOADING ); + final JaxbEntityMappingsImpl simple1 = loadMapping( "mappings/simple1.xml", SIMPLE_CLASS_LOADING ); + final JaxbEntityMappingsImpl simple2 = loadMapping( "mappings/simple2.xml", SIMPLE_CLASS_LOADING ); collector.addDocument( simple1 ); collector.addDocument( simple2); @@ -88,8 +88,8 @@ void testPersistenceUnitDefaults2() { void testSimpleXmlDocumentBuilding() { final XmlResources collector = new XmlResources(); - final JaxbEntityMappings simple1 = loadMapping( "mappings/simple1.xml", SIMPLE_CLASS_LOADING ); - final JaxbEntityMappings simple2 = loadMapping( "mappings/simple2.xml", SIMPLE_CLASS_LOADING ); + final JaxbEntityMappingsImpl simple1 = loadMapping( "mappings/simple1.xml", SIMPLE_CLASS_LOADING ); + final JaxbEntityMappingsImpl simple2 = loadMapping( "mappings/simple2.xml", SIMPLE_CLASS_LOADING ); collector.addDocument( simple1 ); collector.addDocument( simple2 ); @@ -115,7 +115,7 @@ void testSimpleGlobalXmlProcessing() { final SourceModelBuildingContext buildingContext = SourceModelTestHelper.createBuildingContext(); final XmlResources collectedXmlResources = new XmlResources(); - final JaxbEntityMappings xmlMapping = loadMapping( "mappings/globals.xml", SIMPLE_CLASS_LOADING ); + final JaxbEntityMappingsImpl xmlMapping = loadMapping( "mappings/globals.xml", SIMPLE_CLASS_LOADING ); collectedXmlResources.addDocument( xmlMapping ); final ProcessResultCollector processResultCollector = new ProcessResultCollector( false, buildingContext ); diff --git a/hibernate-models-orm/src/test/java/org/hibernate/models/orm/xml/dynamic/DynamicModelTests.java b/hibernate-models-orm/src/test/java/org/hibernate/models/orm/xml/dynamic/DynamicModelTests.java new file mode 100644 index 0000000..15b07bf --- /dev/null +++ b/hibernate-models-orm/src/test/java/org/hibernate/models/orm/xml/dynamic/DynamicModelTests.java @@ -0,0 +1,75 @@ +/* + * 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.dynamic; + +import org.hibernate.models.orm.internal.ManagedResourcesImpl; +import org.hibernate.models.orm.spi.EntityHierarchy; +import org.hibernate.models.orm.spi.EntityTypeMetadata; +import org.hibernate.models.orm.spi.ManagedResources; +import org.hibernate.models.orm.spi.ProcessResult; +import org.hibernate.models.orm.spi.Processor; +import org.hibernate.models.orm.xml.SimpleEntity; +import org.hibernate.models.source.SourceModelTestHelper; +import org.hibernate.models.source.internal.SourceModelBuildingContextImpl; +import org.hibernate.models.source.spi.FieldDetails; + +import org.junit.jupiter.api.Test; + +import org.jboss.jandex.Index; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hibernate.models.internal.SimpleClassLoading.SIMPLE_CLASS_LOADING; + +/** + * @author Steve Ebersole + */ +public class DynamicModelTests { + @Test + void testSimpleDynamicModel() { + final ManagedResources managedResources = new ManagedResourcesImpl.Builder() + .addXmlMappings( "mappings/dynamic/dynamic-simple.xml" ) + .build(); + final Index jandexIndex = SourceModelTestHelper.buildJandexIndex( SIMPLE_CLASS_LOADING ); + final SourceModelBuildingContextImpl buildingContext = SourceModelTestHelper.createBuildingContext( + jandexIndex, + SIMPLE_CLASS_LOADING + ); + + final ProcessResult processResult = Processor.process( + managedResources, + null, + new Processor.Options() { + @Override + public boolean areGeneratorsGlobal() { + return false; + } + + @Override + public boolean shouldIgnoreUnlistedClasses() { + return false; + } + }, + buildingContext + ); + + assertThat( processResult.getEntityHierarchies() ).hasSize( 1 ); + final EntityHierarchy hierarchy = processResult.getEntityHierarchies().iterator().next(); + final EntityTypeMetadata rootEntity = hierarchy.getRoot(); + assertThat( rootEntity.getClassDetails().getClassName() ).isNull(); + assertThat( rootEntity.getClassDetails().getName() ).isEqualTo( "SimpleEntity" ); + + final FieldDetails idField = rootEntity.getClassDetails().findFieldByName( "id" ); + assertThat( idField.getType().getClassName() ).isEqualTo( Integer.class.getName() ); + + final FieldDetails nameField = rootEntity.getClassDetails().findFieldByName( "name" ); + assertThat( nameField.getType().getClassName() ).isEqualTo( String.class.getName() ); + + final FieldDetails qtyField = rootEntity.getClassDetails().findFieldByName( "quantity" ); + assertThat( qtyField.getType().getClassName() ).isEqualTo( int.class.getName() ); + } + +} diff --git a/hibernate-models-orm/src/test/java/org/hibernate/models/orm/xml/override/SimpleOverrideXmlTests.java b/hibernate-models-orm/src/test/java/org/hibernate/models/orm/xml/override/SimpleOverrideXmlTests.java index beb42f9..58fbe4a 100644 --- a/hibernate-models-orm/src/test/java/org/hibernate/models/orm/xml/override/SimpleOverrideXmlTests.java +++ b/hibernate-models-orm/src/test/java/org/hibernate/models/orm/xml/override/SimpleOverrideXmlTests.java @@ -18,7 +18,6 @@ import org.hibernate.models.source.internal.SourceModelBuildingContextImpl; import org.hibernate.models.source.spi.AnnotationUsage; -import org.hibernate.testing.orm.junit.FailureExpected; import org.junit.jupiter.api.Test; import org.jboss.jandex.Index; diff --git a/hibernate-models-orm/src/test/resources/mappings/dynamic/dynamic-simple.xml b/hibernate-models-orm/src/test/resources/mappings/dynamic/dynamic-simple.xml new file mode 100644 index 0000000..6abd606 --- /dev/null +++ b/hibernate-models-orm/src/test/resources/mappings/dynamic/dynamic-simple.xml @@ -0,0 +1,29 @@ + + + + + + + Integer + + + + + String + + + + + int + + + + + \ No newline at end of file diff --git a/hibernate-models-source/src/main/java/org/hibernate/models/source/internal/dynamic/MapModeFieldDetails.java b/hibernate-models-source/src/main/java/org/hibernate/models/source/internal/dynamic/MapModeFieldDetails.java new file mode 100644 index 0000000..43511ac --- /dev/null +++ b/hibernate-models-source/src/main/java/org/hibernate/models/source/internal/dynamic/MapModeFieldDetails.java @@ -0,0 +1,43 @@ +/* + * 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 org.hibernate.models.source.internal.MutableMemberDetails; +import org.hibernate.models.source.spi.ClassDetails; +import org.hibernate.models.source.spi.FieldDetails; +import org.hibernate.models.source.spi.SourceModelBuildingContext; + +/** + * Member used to represent map key access for dynamic models ("MAP mode") + * + * @author Steve Ebersole + */ +public class MapModeFieldDetails extends AbstractAnnotationTarget implements FieldDetails, MutableMemberDetails { + private final String name; + private final ClassDetails type; + + public MapModeFieldDetails(String name, ClassDetails type, SourceModelBuildingContext buildingContext) { + super( buildingContext ); + this.name = name; + this.type = type; + } + + @Override + public String getName() { + return name; + } + + @Override + public ClassDetails getType() { + return type; + } + + @Override + public boolean isPersistable() { + return true; + } +} diff --git a/hibernate-models-source/src/main/java/org/hibernate/models/source/internal/jandex/JandexBuilders.java b/hibernate-models-source/src/main/java/org/hibernate/models/source/internal/jandex/JandexBuilders.java index b43b54a..14f08e6 100644 --- a/hibernate-models-source/src/main/java/org/hibernate/models/source/internal/jandex/JandexBuilders.java +++ b/hibernate-models-source/src/main/java/org/hibernate/models/source/internal/jandex/JandexBuilders.java @@ -8,6 +8,8 @@ import org.hibernate.models.internal.StringHelper; import org.hibernate.models.source.UnknownClassException; +import org.hibernate.models.source.internal.jdk.JdkBuilders; +import org.hibernate.models.source.spi.ClassDetails; import org.hibernate.models.source.spi.ClassDetailsBuilder; import org.hibernate.models.source.spi.MethodDetails; import org.hibernate.models.source.spi.SourceModelBuildingContext; @@ -29,17 +31,17 @@ public JandexBuilders() { } @Override - public JandexClassDetails buildClassDetails(String name, SourceModelBuildingContext buildingContext) { + public ClassDetails buildClassDetails(String name, SourceModelBuildingContext buildingContext) { return buildClassDetailsStatic( name, buildingContext.getJandexIndex(), buildingContext ); } - public static JandexClassDetails buildClassDetailsStatic( + public static ClassDetails buildClassDetailsStatic( String name, SourceModelBuildingContext processingContext) { return buildClassDetailsStatic( name, processingContext.getJandexIndex(), processingContext ); } - public static JandexClassDetails buildClassDetailsStatic( + public static ClassDetails buildClassDetailsStatic( String name, IndexView jandexIndex, SourceModelBuildingContext processingContext) { @@ -49,10 +51,9 @@ public static JandexClassDetails buildClassDetailsStatic( final ClassInfo classInfo = jandexIndex.getClassByName( name ); if ( StringHelper.isNotEmpty( name ) && classInfo == null ) { // potentially handle primitives - final Class primitiveWrapperClass = resolveMatchingPrimitiveWrapper( name ); - if ( primitiveWrapperClass != null ) { - final ClassInfo wrapperClassInfo = jandexIndex.getClassByName( primitiveWrapperClass.getName() ); - return new JandexClassDetails( wrapperClassInfo, processingContext ); + final Class primitiveClass = resolvePrimitiveClass( name ); + if ( primitiveClass != null ) { + return JdkBuilders.buildClassDetailsStatic( primitiveClass, processingContext ); } throw new UnknownClassException( "Could not find class [" + name + "] in Jandex index" ); @@ -60,32 +61,60 @@ public static JandexClassDetails buildClassDetailsStatic( return new JandexClassDetails( classInfo, processingContext ); } - public static Class resolveMatchingPrimitiveWrapper(String className) { + public static Class resolvePrimitiveClass(String className) { if ( "boolean".equals( className ) ) { + return boolean.class; + } + + if ( Boolean.class.getSimpleName().equalsIgnoreCase( className ) || Boolean.class.getName().equals( className ) ) { return Boolean.class; } if ( "byte".equals( className ) ) { + return byte.class; + } + + if ( Byte.class.getSimpleName().equals( className ) || Byte.class.getName().equals( className ) ) { return Byte.class; } if ( "short".equals( className ) ) { + return short.class; + } + + if ( Short.class.getSimpleName().equals( className ) || Short.class.getName().equals( className ) ) { return Short.class; } if ( "int".equals( className ) ) { + return int.class; + } + + if ( Integer.class.getSimpleName().equals( className ) || Integer.class.getName().equals( className ) ) { return Integer.class; } if ( "long".equals( className ) ) { + return long.class; + } + + if ( Long.class.getSimpleName().equals( className ) || Long.class.getName().equals( className ) ) { return Long.class; } if ( "double".equals( className ) ) { + return double.class; + } + + if ( Double.class.getSimpleName().equals( className ) || Double.class.getName().equals( className ) ) { return Double.class; } if ( "float".equals( className ) ) { + return float.class; + } + + if ( Float.class.getSimpleName().equals( className ) || Float.class.getName().equals( className ) ) { return Float.class; } diff --git a/settings.gradle b/settings.gradle index 3f0a6c4..9f7cadc 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,6 +4,7 @@ rootProject.name = 'hibernate-models2' dependencyResolutionManagement { repositories { mavenCentral() + mavenLocal() } versionCatalogs { @@ -19,7 +20,7 @@ dependencyResolutionManagement { def classmateVersion = version "classmate", "1.5.1" library( "classmate", "com.fasterxml", "classmate" ).versionRef( classmateVersion ) - def hibernateVersion = version "hibernateOrm", "6.3.0.Final" + def hibernateVersion = version "hibernateOrm", "7.0.0-XSD" library( "hibernateCore", "org.hibernate.orm", "hibernate-core" ).versionRef( hibernateVersion ) library( "hibernateTesting", "org.hibernate.orm", "hibernate-testing" ).versionRef( hibernateVersion ) library( "hibernatePlatform", "org.hibernate.orm", "hibernate-platform" ).versionRef( hibernateVersion ) diff --git a/todos.adoc b/todos.adoc index a734f83..fb12a0f 100644 --- a/todos.adoc +++ b/todos.adoc @@ -1,8 +1,9 @@ = Open Questions and To-do items * Hierarchical packages? E.g. should things defined on the `com.acme` package apply to things in the `com.acme.model` package? Should `PackageDetails` have reference to its "parent" `PackageDetails`? -* Model `AnnotationAttributeValue`? Dropped that here from earlier iterations - its only real benefit was to help model the idea of implicit (unspecified) values. But since the quorum is to simply follow JLS, "this is the way". It simplifies the code quite a bit and imo only makes sense if we want to be able to model that implicitness aspect -* Support ``? This comes from hbm.xml world, but not seeing its usefulness. -* Support for dynamic embeddables in XSD +* [.line-through]#Model `AnnotationAttributeValue`? Dropped that here from earlier iterations - its only real benefit was to help model the idea of implicit (unspecified) values. But since the quorum is to simply follow JLS, "this is the way". It simplifies the code quite a bit and imo only makes sense if we want to be able to model that implicitness aspect# - Dropped `AnnotationAttributeValue` +* Support ``? "Needed" for dynamic models and inheritance (if that's something we want to support). Will also need a (internal) annotation * Allow mapped-superclass in dynamic models? XSD change -* Update the mapping.xsd to account for new @GenericGenerator definition \ No newline at end of file +* [.line-through]#Support for dynamic embeddables in XSD# - see `` and `` +* [.line-through]#Update the mapping.xsd to account for new @GenericGenerator definition# +* [.line-through]#todo : we need some form of "attribute (java) type" in the XSD for dynamic models# - see the new `` element plus `target-entity`