From 2807578a7c66df7b13ca1ba3a257b3a03ebbb041 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Wed, 12 Feb 2014 08:53:00 -0600 Subject: [PATCH] HHH-8956 - TLC for annotation pre-processor --- .../org/hibernate/metamodel/Metadata.java | 37 --- .../hibernate/metamodel/MetadataBuilder.java | 17 +- .../hibernate/metamodel/internal/Binder.java | 2 +- .../internal/MetadataBuilderImpl.java | 211 ++++++++++-------- .../metamodel/internal/MetadataImpl.java | 34 +-- .../internal/SessionFactoryBuilderImpl.java | 7 +- .../AnnotationBindingContextImpl.java | 6 + .../annotations/RootEntitySourceImpl.java | 2 +- .../annotations/attribute/BasicAttribute.java | 2 +- .../entity/EntityBindingContext.java | 6 + .../annotations/entity/EntityClass.java | 2 +- .../global/IdGeneratorProcessor.java | 4 +- .../util/EntityHierarchyBuilder.java | 88 ++++---- .../internal/source/hbm/MappingDocument.java | 6 + .../spi/MetadataBuildingOptions.java | 142 ++++++++++++ .../metamodel/spi/MetadataImplementor.java | 1 + .../binding/EntityHierarchyBindingNode.java | 33 +++ .../metamodel/spi/source/BindingContext.java | 3 + .../internal/source/AssertSourcesTest.java | 2 +- 19 files changed, 407 insertions(+), 198 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/spi/MetadataBuildingOptions.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityHierarchyBindingNode.java diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java b/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java index c5a1ec6861..d1e9f99a78 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java @@ -23,19 +23,9 @@ */ package org.hibernate.metamodel; -import java.util.List; import java.util.Map; -import javax.persistence.SharedCacheMode; -import org.jboss.jandex.IndexView; -import org.xml.sax.EntityResolver; - -import org.hibernate.MultiTenancyStrategy; import org.hibernate.SessionFactory; -import org.hibernate.boot.registry.StandardServiceRegistry; -import org.hibernate.boot.spi.CacheRegionDefinition; -import org.hibernate.cache.spi.access.AccessType; -import org.hibernate.cfg.NamingStrategy; import org.hibernate.cfg.annotations.NamedEntityGraphDefinition; import org.hibernate.engine.ResultSetMappingDefinition; import org.hibernate.engine.spi.FilterDefinition; @@ -47,39 +37,12 @@ import org.hibernate.metamodel.spi.binding.IdentifierGeneratorDefinition; import org.hibernate.metamodel.spi.binding.PluralAttributeBinding; import org.hibernate.metamodel.spi.binding.SecondaryTable; import org.hibernate.metamodel.spi.binding.TypeDefinition; -import org.hibernate.metamodel.spi.relational.Database; import org.hibernate.metamodel.spi.relational.Identifier; -import org.hibernate.type.BasicType; /** * @author Steve Ebersole */ public interface Metadata { - /** - * Exposes the options used to produce a {@link Metadata} instance. - */ - public static interface Options extends Database.Defaults { - StandardServiceRegistry getServiceRegistry(); - - MetadataSourceProcessingOrder getMetadataSourceProcessingOrder(); - NamingStrategy getNamingStrategy(); - EntityResolver getEntityResolver(); - SharedCacheMode getSharedCacheMode(); - AccessType getDefaultAccessType(); - boolean useNewIdentifierGenerators(); - MultiTenancyStrategy getMultiTenancyStrategy(); - IndexView getJandexView(); - List getBasicTypeRegistrations(); - List getCacheRegionDefinitions(); - } - - /** - * Retrieve the options used to build this {@link Metadata} instance. - * - * @return The options. - */ - Options getOptions(); - /** * Get the builder for {@link SessionFactory} instances based on this metamodel, * diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/MetadataBuilder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/MetadataBuilder.java index 4b099e03e6..8badf297d4 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/MetadataBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/MetadataBuilder.java @@ -165,7 +165,22 @@ public interface MetadataBuilder { * * @param cacheRegionDefinition The cache region definition to apply */ - public void with(CacheRegionDefinition cacheRegionDefinition); + public MetadataBuilder with(CacheRegionDefinition cacheRegionDefinition); + + /** + * Apply a ClassLoader for use while building the Metadata. + *

+ * Ideally we should avoid accessing ClassLoaders when perform 1st phase of bootstrap. This + * is a ClassLoader that can be used in cases when we have to. IN EE managed environments, this + * is the ClassLoader mandated by + * {@link javax.persistence.spi.PersistenceUnitInfo#getNewTempClassLoader()}. This ClassLoader + * is thrown away by the container afterwards. The idea being that the Class can still be enhanced + * in the application ClassLoader. In other environments, pass a ClassLoader that performs the + * same function if desired. + * + * @param tempClassLoader ClassLoader for use during building the Metadata + */ + public MetadataBuilder with(ClassLoader tempClassLoader); /** * Actually build the metamodel diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java index 78af9c46b1..84243cced8 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java @@ -726,7 +726,7 @@ public class Binder implements HelperContext { // if (1) the strategy is discriminator based and (2) the entity is not shared, we need to either (a) extract // the user supplied tenant discriminator value mapping or (b) generate an implicit one final boolean needsTenantIdentifierValueMapping = - MultiTenancyStrategy.DISCRIMINATOR == metadata.getOptions().getMultiTenancyStrategy() + MultiTenancyStrategy.DISCRIMINATOR == bindingContext().getBuildingOptions().getMultiTenancyStrategy() && !multiTenancySource.isShared(); if ( needsTenantIdentifierValueMapping ) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataBuilderImpl.java index ecc4cac3ae..d317b899e8 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataBuilderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataBuilderImpl.java @@ -52,6 +52,7 @@ import org.hibernate.metamodel.MetadataSources; import org.hibernate.metamodel.spi.MetadataSourcesContributor; import org.hibernate.metamodel.spi.TypeContributions; import org.hibernate.metamodel.spi.TypeContributor; +import org.hibernate.metamodel.spi.relational.Database; import org.hibernate.service.ServiceRegistry; import org.hibernate.type.BasicType; import org.hibernate.type.CompositeCustomType; @@ -68,7 +69,7 @@ public class MetadataBuilderImpl implements MetadataBuilder, TypeContributions { private static final Logger log = Logger.getLogger( MetadataBuilderImpl.class ); private final MetadataSources sources; - private final OptionsImpl options; + private final Options options; public MetadataBuilderImpl(MetadataSources sources) { this( @@ -110,7 +111,7 @@ public class MetadataBuilderImpl implements MetadataBuilder, TypeContributions { .loadJavaServices( MetadataSourcesContributor.class ) ) { contributor.contribute( sources, null ); } - this.options = new OptionsImpl( serviceRegistry ); + this.options = new Options( serviceRegistry ); } @Override @@ -195,41 +196,93 @@ public class MetadataBuilderImpl implements MetadataBuilder, TypeContributions { } @Override - public void with(CacheRegionDefinition cacheRegionDefinition) { + public MetadataBuilder with(CacheRegionDefinition cacheRegionDefinition) { if ( options.cacheRegionDefinitions == null ) { options.cacheRegionDefinitions = new ArrayList(); } options.cacheRegionDefinitions.add( cacheRegionDefinition ); + return this; + } + + @Override + public MetadataBuilder with(ClassLoader tempClassLoader) { + options.tempClassLoader = tempClassLoader; + return this; } @Override public Metadata build() { - return new MetadataImpl( sources, options ); + return MetadataImpl.build( sources, options ); } - public static class OptionsImpl implements Metadata.Options { - private final StandardServiceRegistry serviceRegistry; - - private MetadataSourceProcessingOrder metadataSourceProcessingOrder = MetadataSourceProcessingOrder.HBM_FIRST; - private NamingStrategy namingStrategy = EJB3NamingStrategy.INSTANCE; - // todo : entity-resolver maybe needed for ServiceRegistry building also - // maybe move there and default to looking up that value somehow? - private EntityResolver entityResolver = EJB3DTDEntityResolver.INSTANCE; - private SharedCacheMode sharedCacheMode = SharedCacheMode.ENABLE_SELECTIVE; - private AccessType defaultCacheAccessType; - private boolean useNewIdentifierGenerators; - private boolean globallyQuotedIdentifiers; + /** + * Implementation of the Database.Defaults contract + */ + public static class DatabaseDefaults implements Database.Defaults { + private boolean globallyQuotedIdentifiers; private String defaultSchemaName; private String defaultCatalogName; - private MultiTenancyStrategy multiTenancyStrategy; - private IndexView jandexView; + + public DatabaseDefaults(ConfigurationService configurationService) { + defaultSchemaName = configurationService.getSetting( + AvailableSettings.DEFAULT_SCHEMA, + StandardConverters.STRING, + null + ); + + defaultCatalogName = configurationService.getSetting( + AvailableSettings.DEFAULT_CATALOG, + StandardConverters.STRING, + null + ); + + globallyQuotedIdentifiers = configurationService.getSetting( + AvailableSettings.GLOBALLY_QUOTED_IDENTIFIERS, + StandardConverters.BOOLEAN, + false + ); + } + + @Override + public String getDefaultSchemaName() { + return defaultSchemaName; + } + + @Override + public String getDefaultCatalogName() { + return defaultCatalogName; + } + + @Override + public boolean isGloballyQuotedIdentifiers() { + return globallyQuotedIdentifiers; + } + } + + public static class Options implements org.hibernate.metamodel.spi.MetadataBuildingOptions { + private final StandardServiceRegistry serviceRegistry; + private final DatabaseDefaults databaseDefaults; + private List basicTypeRegistrations = new ArrayList(); + + private IndexView jandexView; + private ClassLoader tempClassLoader; + private NamingStrategy namingStrategy = EJB3NamingStrategy.INSTANCE; + private SharedCacheMode sharedCacheMode = SharedCacheMode.ENABLE_SELECTIVE; + private AccessType defaultCacheAccessType; + private boolean useNewIdentifierGenerators; + private MultiTenancyStrategy multiTenancyStrategy; private List cacheRegionDefinitions; - public OptionsImpl(StandardServiceRegistry serviceRegistry) { + // todo : go away + private MetadataSourceProcessingOrder metadataSourceProcessingOrder = MetadataSourceProcessingOrder.HBM_FIRST; + private EntityResolver entityResolver = EJB3DTDEntityResolver.INSTANCE; + + public Options(StandardServiceRegistry serviceRegistry) { this.serviceRegistry = serviceRegistry; - ConfigurationService configService = serviceRegistry.getService( ConfigurationService.class ); + final ConfigurationService configService = serviceRegistry.getService( ConfigurationService.class ); + this.databaseDefaults = new DatabaseDefaults( configService ); // cache access type defaultCacheAccessType = configService.getSetting( @@ -248,24 +301,6 @@ public class MetadataBuilderImpl implements MetadataBuilder, TypeContributions { false ); - defaultSchemaName = configService.getSetting( - AvailableSettings.DEFAULT_SCHEMA, - StandardConverters.STRING, - null - ); - - defaultCatalogName = configService.getSetting( - AvailableSettings.DEFAULT_CATALOG, - StandardConverters.STRING, - null - ); - - globallyQuotedIdentifiers = configService.getSetting( - AvailableSettings.GLOBALLY_QUOTED_IDENTIFIERS, - StandardConverters.BOOLEAN, - false - ); - multiTenancyStrategy = MultiTenancyStrategy.determineMultiTenancyStrategy( configService.getSettings() ); } @@ -275,58 +310,8 @@ public class MetadataBuilderImpl implements MetadataBuilder, TypeContributions { } @Override - public MetadataSourceProcessingOrder getMetadataSourceProcessingOrder() { - return metadataSourceProcessingOrder; - } - - @Override - public NamingStrategy getNamingStrategy() { - return namingStrategy; - } - - @Override - public EntityResolver getEntityResolver() { - return entityResolver; - } - - @Override - public AccessType getDefaultAccessType() { - return defaultCacheAccessType; - } - - @Override - public SharedCacheMode getSharedCacheMode() { - return sharedCacheMode; - } - - @Override - public boolean useNewIdentifierGenerators() { - return useNewIdentifierGenerators; - } - - @Override - public boolean isGloballyQuotedIdentifiers() { - return globallyQuotedIdentifiers; - } - - @Override - public String getDefaultSchemaName() { - return defaultSchemaName; - } - - @Override - public String getDefaultCatalogName() { - return defaultCatalogName; - } - - @Override - public MultiTenancyStrategy getMultiTenancyStrategy() { - return multiTenancyStrategy; - } - - @Override - public IndexView getJandexView() { - return jandexView; + public DatabaseDefaults getDatabaseDefaults() { + return databaseDefaults; } @Override @@ -334,9 +319,55 @@ public class MetadataBuilderImpl implements MetadataBuilder, TypeContributions { return basicTypeRegistrations; } + @Override + public IndexView getJandexView() { + return jandexView; + } + + @Override + public ClassLoader getTempClassLoader() { + return tempClassLoader; + } + + @Override + public NamingStrategy getNamingStrategy() { + return namingStrategy; + } + + @Override + public SharedCacheMode getSharedCacheMode() { + return sharedCacheMode; + } + + @Override + public AccessType getDefaultCacheAccessType() { + return defaultCacheAccessType; + } + + @Override + public boolean isUseNewIdentifierGenerators() { + return useNewIdentifierGenerators; + } + + @Override + public MultiTenancyStrategy getMultiTenancyStrategy() { + return multiTenancyStrategy; + } + @Override public List getCacheRegionDefinitions() { return cacheRegionDefinitions; } + + @Override + public MetadataSourceProcessingOrder getMetadataSourceProcessingOrder() { + return metadataSourceProcessingOrder; + } + + @Override + public EntityResolver getEntityResolver() { + return entityResolver; + } } + } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java index c31cc51184..db538514b3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataImpl.java @@ -67,6 +67,7 @@ import org.hibernate.metamodel.internal.source.hbm.HbmMetadataSourceProcessorImp import org.hibernate.metamodel.source.internal.jandex.Unifier; import org.hibernate.metamodel.source.internal.jaxb.JaxbEntityMappings; import org.hibernate.metamodel.spi.AdditionalJaxbRootProducer; +import org.hibernate.metamodel.spi.MetadataBuildingOptions; import org.hibernate.metamodel.spi.MetadataContributor; import org.hibernate.metamodel.spi.MetadataImplementor; import org.hibernate.metamodel.spi.MetadataSourceProcessor; @@ -126,7 +127,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable { ); private final ServiceRegistry serviceRegistry; - private final Options options; + private final MetadataBuildingOptions options; private final ClassLoaderService classLoaderService; // private final transient ValueHolder persisterClassResolverService; @@ -156,12 +157,15 @@ public class MetadataImpl implements MetadataImplementor, Serializable { private boolean globallyQuotedIdentifiers = false; - public MetadataImpl(MetadataSources metadataSources, Options options) { + public MetadataImpl(MetadataSources metadataSources, MetadataBuildingOptions options) { this.serviceRegistry = options.getServiceRegistry(); this.classLoaderService = serviceRegistry.getService( ClassLoaderService.class ); this.options = options; this.identifierGeneratorFactory = serviceRegistry.getService( MutableIdentifierGeneratorFactory.class ); - this.database = new Database( options, serviceRegistry.getService( JdbcServices.class ).getJdbcEnvironment() ); + this.database = new Database( + options.getDatabaseDefaults(), + serviceRegistry.getService( JdbcServices.class ).getJdbcEnvironment() + ); this.mappingDefaults = new MappingDefaultsImpl(); this.nameNormalizer = new ObjectNameNormalizer() { @@ -691,11 +695,6 @@ public class MetadataImpl implements MetadataImplementor, Serializable { // return persisterClassResolverService.getValue(); // } - @Override - public Options getOptions() { - return options; - } - @Override public ServiceRegistry getServiceRegistry() { return serviceRegistry; @@ -881,7 +880,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable { @Override public SessionFactoryBuilder getSessionFactoryBuilder() { - return new SessionFactoryBuilderImpl( this ); + return new SessionFactoryBuilderImpl( this, options.getServiceRegistry() ); } @Override @@ -896,7 +895,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable { @Override public boolean isGloballyQuotedIdentifiers() { - return globallyQuotedIdentifiers || getOptions().isGloballyQuotedIdentifiers(); + return globallyQuotedIdentifiers || options.getDatabaseDefaults().isGloballyQuotedIdentifiers(); } public void setGloballyQuotedIdentifiers(boolean globallyQuotedIdentifiers){ @@ -908,6 +907,11 @@ public class MetadataImpl implements MetadataImplementor, Serializable { return mappingDefaults; } + @Override + public MetadataBuildingOptions getBuildingOptions() { + return options; + } + private final MetaAttributeContext globalMetaAttributeContext = new MetaAttributeContext(); @Override @@ -965,6 +969,10 @@ public class MetadataImpl implements MetadataImplementor, Serializable { return attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping(); } + public static MetadataImpl build(MetadataSources sources, MetadataBuildingOptions options) { + return new MetadataImpl( sources, options ); + } + private class MappingDefaultsImpl implements MappingDefaults { @Override @@ -974,12 +982,12 @@ public class MetadataImpl implements MetadataImplementor, Serializable { @Override public String getSchemaName() { - return options.getDefaultSchemaName(); + return options.getDatabaseDefaults().getDefaultSchemaName(); } @Override public String getCatalogName() { - return options.getDefaultCatalogName(); + return options.getDatabaseDefaults().getDefaultCatalogName(); } @Override @@ -1014,7 +1022,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable { @Override public AccessType getCacheAccessType() { - return options.getDefaultAccessType(); + return options.getDefaultCacheAccessType(); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/SessionFactoryBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/SessionFactoryBuilderImpl.java index 17c2dc547d..0aa56f8397 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/SessionFactoryBuilderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/SessionFactoryBuilderImpl.java @@ -23,7 +23,6 @@ */ package org.hibernate.metamodel.internal; -import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -35,7 +34,6 @@ import org.hibernate.EmptyInterceptor; import org.hibernate.EntityMode; import org.hibernate.EntityNameResolver; import org.hibernate.Interceptor; -import org.hibernate.ObjectNotFoundException; import org.hibernate.SessionFactory; import org.hibernate.SessionFactoryObserver; import org.hibernate.boot.registry.StandardServiceRegistry; @@ -51,7 +49,6 @@ import org.hibernate.internal.StandardEntityNotFoundDelegate; import org.hibernate.metamodel.SessionFactoryBuilder; import org.hibernate.metamodel.spi.MetadataImplementor; import org.hibernate.proxy.EntityNotFoundDelegate; -import org.hibernate.secure.spi.JaccPermissionDeclarations; import org.hibernate.tuple.entity.EntityTuplizer; /** @@ -62,9 +59,9 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilder { private final MetadataImplementor metadata; private final SessionFactoryOptionsImpl options; - SessionFactoryBuilderImpl(MetadataImplementor metadata) { + SessionFactoryBuilderImpl(MetadataImplementor metadata, StandardServiceRegistry serviceRegistry) { this.metadata = metadata; - options = new SessionFactoryOptionsImpl( metadata.getOptions().getServiceRegistry() ); + options = new SessionFactoryOptionsImpl( serviceRegistry ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationBindingContextImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationBindingContextImpl.java index 23a615d687..4c6cd4e2d5 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationBindingContextImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/AnnotationBindingContextImpl.java @@ -25,6 +25,7 @@ package org.hibernate.metamodel.internal.source.annotations; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.cfg.NamingStrategy; +import org.hibernate.metamodel.spi.MetadataBuildingOptions; import org.hibernate.metamodel.spi.MetadataImplementor; import org.hibernate.metamodel.spi.binding.IdentifierGeneratorDefinition; import org.hibernate.metamodel.spi.domain.JavaClassReference; @@ -109,6 +110,11 @@ public class AnnotationBindingContextImpl implements AnnotationBindingContext { return metadata; } + @Override + public MetadataBuildingOptions getBuildingOptions() { + return metadata.getBuildingOptions(); + } + @Override public Class locateClassByName(String name) { return classLoaderService.classForName( name ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/RootEntitySourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/RootEntitySourceImpl.java index e37384d139..832dcf14fb 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/RootEntitySourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/RootEntitySourceImpl.java @@ -59,7 +59,7 @@ public class RootEntitySourceImpl extends EntitySourceImpl implements RootEntity switch ( idType ) { case SIMPLE: { MappedAttribute attribute = getEntityClass().getIdAttributes().values().iterator().next(); - return new SimpleIdentifierSourceImpl( this, (BasicAttribute) attribute); + return new SimpleIdentifierSourceImpl( this, (BasicAttribute) attribute ); } case COMPOSED: { return new NonAggregatedCompositeIdentifierSourceImpl( this ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java index ecd93278a9..60072ad89b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java @@ -338,7 +338,7 @@ public class BasicAttribute extends MappedAttribute { getContext().getServiceRegistry().getService( ClassLoaderService.class ) ); String strategy = EnumConversionHelper.generationTypeToGeneratorStrategyName( genType, - getContext().getMetadataImplementor().getOptions().useNewIdentifierGenerators() + getContext().getBuildingOptions().isUseNewIdentifierGenerators() ); generator = new IdentifierGeneratorDefinition( null, strategy, null ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityBindingContext.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityBindingContext.java index d505a447bc..1a7406a111 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityBindingContext.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityBindingContext.java @@ -24,6 +24,7 @@ package org.hibernate.metamodel.internal.source.annotations.entity; import org.hibernate.cfg.NamingStrategy; +import org.hibernate.metamodel.spi.MetadataBuildingOptions; import org.hibernate.metamodel.spi.domain.JavaClassReference; import org.hibernate.xml.spi.Origin; import org.hibernate.xml.spi.SourceType; @@ -85,6 +86,11 @@ public class EntityBindingContext implements LocalBindingContext, AnnotationBind return contextDelegate.getMappingDefaults(); } + @Override + public MetadataBuildingOptions getBuildingOptions() { + return contextDelegate.getBuildingOptions(); + } + @Override public MetadataImplementor getMetadataImplementor() { return contextDelegate.getMetadataImplementor(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java index 696a891060..2378a398a2 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java @@ -497,7 +497,7 @@ public class EntityClass extends ConfiguredClass { ); final boolean doCaching; - switch ( getLocalBindingContext().getMetadataImplementor().getOptions().getSharedCacheMode() ) { + switch ( getLocalBindingContext().getBuildingOptions().getSharedCacheMode() ) { case ALL: { doCaching = true; break; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/global/IdGeneratorProcessor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/global/IdGeneratorProcessor.java index b11f33aa03..719201fe20 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/global/IdGeneratorProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/global/IdGeneratorProcessor.java @@ -151,7 +151,7 @@ public class IdGeneratorProcessor { final ClassLoaderService classLoaderService = bindingContext.getServiceRegistry().getService( ClassLoaderService.class ); final String name = JandexHelper.getValue( generator, "name", String.class, classLoaderService ); - final boolean useNewIdentifierGenerators = metadata.getOptions().useNewIdentifierGenerators(); + final boolean useNewIdentifierGenerators = bindingContext.getBuildingOptions().isUseNewIdentifierGenerators(); final String strategy = EnumConversionHelper.generationTypeToGeneratorStrategyName( GenerationType.SEQUENCE, useNewIdentifierGenerators @@ -196,7 +196,7 @@ public class IdGeneratorProcessor { final ClassLoaderService classLoaderService = bindingContext.getServiceRegistry().getService( ClassLoaderService.class ); final String name = JandexHelper.getValue( generator, "name", String.class, classLoaderService ); - final boolean useNewIdentifierGenerators = metadata.getOptions().useNewIdentifierGenerators(); + final boolean useNewIdentifierGenerators = bindingContext.getBuildingOptions().isUseNewIdentifierGenerators(); final String strategy = EnumConversionHelper.generationTypeToGeneratorStrategyName( GenerationType.TABLE, useNewIdentifierGenerators diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/EntityHierarchyBuilder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/EntityHierarchyBuilder.java index 170801d635..b85ba24dca 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/EntityHierarchyBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/EntityHierarchyBuilder.java @@ -58,16 +58,21 @@ import org.hibernate.metamodel.spi.source.EntitySource; import org.hibernate.metamodel.spi.source.SubclassEntitySource; /** - * Given a (jandex) annotation index build processes all classes with JPA relevant annotations and pre-orders + * Given a (jandex) annotation index, processes all classes with JPA relevant annotations and pre-orders * JPA entities respectively their inheritance hierarchy. * * @author Hardy Ferentschik * @author Strong Liu + * @author Steve Ebersole */ public class EntityHierarchyBuilder { - private static final Logger LOG = Logger.getLogger( - EntityHierarchyBuilder.class); + private static final Logger LOG = Logger.getLogger( EntityHierarchyBuilder.class ); + private final AnnotationBindingContext bindingContext; + + private final Set hierarchies = new HashSet(); + private final Map processedEntities = new HashMap(); + private final Map> classToDirectSubclassMap = new HashMap>(); /** * Pre-processes the annotated entities from the index and create a set of entity hierarchies which can be bound @@ -78,10 +83,28 @@ public class EntityHierarchyBuilder { * @return a set of {@code EntityHierarchy} instances. */ public static Set createEntityHierarchies(AnnotationBindingContext bindingContext) { - Set hierarchies = new HashSet(); - Map processedEntities = new HashMap( ); - Map> classToDirectSubClassMap = new HashMap>(); - IndexView index = bindingContext.getIndex(); + return new EntityHierarchyBuilder( bindingContext ).process(); + } + + /** + * Constructs a EntityHierarchyBuilder. While all calls flow into this class statically via + * {@link #createEntityHierarchies}, internally each call to that method creates an instance + * used to hold instance state representing that parse. + * + * @param bindingContext Access to needed services and information + */ + private EntityHierarchyBuilder(AnnotationBindingContext bindingContext) { + this.bindingContext = bindingContext; + } + + /** + * Pre-processes the annotated entities from the index and create a set of entity hierarchies which can be bound + * to the metamodel. + * + * @return a set of {@code EntityHierarchy} instances. + */ + public Set process() { + final IndexView index = bindingContext.getIndex(); for ( ClassInfo classInfo : index.getKnownClasses() ) { if ( processedEntities.containsKey( classInfo.name() ) ) { continue; @@ -91,22 +114,15 @@ public class EntityHierarchyBuilder { } - ClassInfo rootClassInfo = findRootEntityClassInfo( index, classInfo, bindingContext ); + ClassInfo rootClassInfo = findRootEntityClassInfo( classInfo ); List rootClassWithAllSubclasses = new ArrayList(); // collect the current root entity and all its subclasses - processHierarchy( - bindingContext, - rootClassInfo, - rootClassWithAllSubclasses, - processedEntities, - classToDirectSubClassMap - ); + processHierarchy( rootClassInfo, rootClassWithAllSubclasses ); boolean hasSubclasses = rootClassWithAllSubclasses.size() > 1; // using the root entity, resolve generic parameters in the whole class hierarchy final Map resolvedTypeWithMembers = resolveGenerics( - rootClassInfo.toString(), - bindingContext + rootClassInfo.toString() ); List mappedSuperclasses = findMappedSuperclasses( index, rootClassInfo ); @@ -133,8 +149,6 @@ public class EntityHierarchyBuilder { RootEntitySourceImpl rootSource = new RootEntitySourceImpl( rootEntityClass ); addSubclassEntitySources( - bindingContext, - classToDirectSubClassMap, resolvedTypeWithMembers, defaultAccessType, hierarchyInheritanceType, @@ -147,20 +161,18 @@ public class EntityHierarchyBuilder { return hierarchies; } - private static void addSubclassEntitySources( - AnnotationBindingContext bindingContext, - Map> classToDirectSubClassMap, + private void addSubclassEntitySources( Map resolvedTypeWithMembers, AccessType defaultAccessType, InheritanceType hierarchyInheritanceType, EntityClass entityClass, EntitySource entitySource) { - List subClassInfoList = classToDirectSubClassMap.get( DotName.createSimple( entitySource.getClassName() ) ); + List subClassInfoList = classToDirectSubclassMap.get( DotName.createSimple( entitySource.getClassName() ) ); if ( subClassInfoList == null ) { return; } for ( ClassInfo subClassInfo : subClassInfoList ) { - resolvedTypeWithMembers.putAll( resolveGenerics( subClassInfo.name().toString(), bindingContext ) ); + resolvedTypeWithMembers.putAll( resolveGenerics( subClassInfo.name().toString() ) ); ResolvedTypeWithMembers typeWithMembers = resolvedTypeWithMembers.get( subClassInfo.toString() ); if ( typeWithMembers == null ) { throw new AssertionFailure( "Missing generic information for " + subClassInfo.toString() ); @@ -178,8 +190,6 @@ public class EntityHierarchyBuilder { : new SubclassEntitySourceImpl( subclassEntityClass, entitySource ); entitySource.add( subclassEntitySource ); addSubclassEntitySources( - bindingContext, - classToDirectSubClassMap, resolvedTypeWithMembers, defaultAccessType, hierarchyInheritanceType, @@ -193,19 +203,18 @@ public class EntityHierarchyBuilder { * Finds the root entity starting at the entity given by {@code info}. The root entity is not the highest superclass * in a java type sense, but the highest superclass which is also an entity (annotated w/ {@code @Entity}. * - * @param index the annotation repository * @param info the class info representing an entity * * @return Finds the root entity starting at the entity given by {@code info} */ - private static ClassInfo findRootEntityClassInfo(IndexView index, ClassInfo info, AnnotationBindingContext bindingContext) { + private ClassInfo findRootEntityClassInfo(ClassInfo info) { ClassInfo rootEntity = info; DotName superName = info.superName(); ClassInfo tmpInfo; // walk up the hierarchy until java.lang.Object while ( !JandexHelper.OBJECT.equals( superName ) ) { - tmpInfo = index.getClassByName( superName ); + tmpInfo = bindingContext.getIndex().getClassByName( superName ); if ( tmpInfo == null && superName != null ) { Class clazz = bindingContext.locateClassByName( superName.toString() ); if ( clazz != null ) { @@ -250,17 +259,12 @@ public class EntityHierarchyBuilder { *

  • Building up a map of class to direct subclass list
  • * * - * @param bindingContext the binding context * @param classInfo the current class info * @param rootClassWithAllSubclasses used to collect all classes in the hierarchy starting at {@code classInfo} - * @param processedEntities Used to keep track of all processed entities - * @param classToDirectSubclassMap Create a map of class to direct subclass */ - private static void processHierarchy(AnnotationBindingContext bindingContext, - ClassInfo classInfo, - List rootClassWithAllSubclasses, - Map processedEntities, - Map> classToDirectSubclassMap) { + private void processHierarchy( + ClassInfo classInfo, + List rootClassWithAllSubclasses) { processedEntities.put( classInfo.name(), classInfo.name() ); rootClassWithAllSubclasses.add( classInfo ); Collection subClasses = bindingContext.getIndex().getKnownDirectSubclasses( classInfo.name() ); @@ -271,13 +275,7 @@ public class EntityHierarchyBuilder { continue; } addSubClassToSubclassMap( classInfo.name(), subClassInfo, classToDirectSubclassMap ); - processHierarchy( - bindingContext, - subClassInfo, - rootClassWithAllSubclasses, - processedEntities, - classToDirectSubclassMap - ); + processHierarchy( subClassInfo, rootClassWithAllSubclasses ); } } @@ -477,7 +475,7 @@ public class EntityHierarchyBuilder { * TODO this is incorrect, we should do it from bottom to top, not inverse, since the actual type info should be dedined in the sub class. * we need this info to resolve super class type. */ - private static Map resolveGenerics(String className, AnnotationBindingContext bindingContext) { + private Map resolveGenerics(String className) { final Map resolvedTypes = new HashMap(); final Class clazz = bindingContext.locateClassByName( className ); ResolvedType resolvedType = bindingContext.getTypeResolver().resolve( clazz ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/MappingDocument.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/MappingDocument.java index 1b8d569a1b..2a073ca65b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/MappingDocument.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/MappingDocument.java @@ -27,6 +27,7 @@ import java.util.List; import org.hibernate.cfg.NamingStrategy; import org.hibernate.internal.util.collections.CollectionHelper; +import org.hibernate.metamodel.spi.MetadataBuildingOptions; import org.hibernate.metamodel.spi.domain.JavaClassReference; import org.hibernate.xml.spi.BindResult; import org.hibernate.xml.spi.Origin; @@ -118,6 +119,11 @@ public class MappingDocument { return localMappingDefaults; } + @Override + public MetadataBuildingOptions getBuildingOptions() { + return metadata.getBuildingOptions(); + } + @Override public MetadataImplementor getMetadataImplementor() { return metadata; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/MetadataBuildingOptions.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/MetadataBuildingOptions.java new file mode 100644 index 0000000000..be82c1daf8 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/MetadataBuildingOptions.java @@ -0,0 +1,142 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2014, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.spi; + +import java.util.List; +import javax.persistence.SharedCacheMode; + +import org.hibernate.MultiTenancyStrategy; +import org.hibernate.boot.registry.StandardServiceRegistry; +import org.hibernate.boot.spi.CacheRegionDefinition; +import org.hibernate.cache.spi.access.AccessType; +import org.hibernate.cfg.NamingStrategy; +import org.hibernate.metamodel.MetadataSourceProcessingOrder; +import org.hibernate.metamodel.spi.relational.Database; +import org.hibernate.type.BasicType; + +import org.jboss.jandex.IndexView; + +import org.xml.sax.EntityResolver; + +/** + * Describes the options used while building the Metadata object (during + * {@link org.hibernate.metamodel.MetadataBuilder#build()} processing). + * + * @author Steve Ebersole + */ +public interface MetadataBuildingOptions { + /** + * Access to the service registry. + * + * @return The service registry + */ + StandardServiceRegistry getServiceRegistry(); + + /** + * Access to the database defaults. + * + * @return The database defaults + */ + Database.Defaults getDatabaseDefaults(); + + /** + * Access the list of BasicType registrations. These are the BasicTypes explicitly + * registered via calls to:
      + *
    • {@link org.hibernate.metamodel.MetadataBuilder#with(org.hibernate.type.BasicType)}
    • + *
    • {@link org.hibernate.metamodel.MetadataBuilder#with(org.hibernate.usertype.UserType, java.lang.String[])}
    • + *
    • {@link org.hibernate.metamodel.MetadataBuilder#with(org.hibernate.usertype.CompositeUserType, java.lang.String[])}
    • + *
    + * + * @return The BasicType registrations + */ + List getBasicTypeRegistrations(); + + /** + * Access to the Jandex index passed by call to + * {@link org.hibernate.metamodel.MetadataBuilder#with(org.jboss.jandex.IndexView)}, if any. + * + * @return The Jandex index + */ + IndexView getJandexView(); + + /** + * Access the temporary ClassLoader passed to us as defined by + * {@link javax.persistence.spi.PersistenceUnitInfo#getNewTempClassLoader()}, if any. + * + * @return The tempo ClassLoader + */ + ClassLoader getTempClassLoader(); + + /** + * Access to the NamingStrategy which should be used. + * + * @return The NamingStrategy + */ + NamingStrategy getNamingStrategy(); + + /** + * Access to the SharedCacheMode for determining whether we should perform second level + * caching or not. + * + * @return The SharedCacheMode + */ + SharedCacheMode getSharedCacheMode(); + + /** + * Access to the default second level cache AccessType to use if not specified. + * + * @return The default AccessType + */ + AccessType getDefaultCacheAccessType(); + + /** + * Access to whether we should be using the new identifier generator scheme. + * {@code true} indicates to use the new schema, {@code false} indicates to use the + * legacy scheme. + * + * @return Whether to use the new identifier generator scheme + */ + boolean isUseNewIdentifierGenerators(); + + /** + * Access to the MultiTenancyStrategy for this environment. + * + * @return The MultiTenancyStrategy + */ + MultiTenancyStrategy getMultiTenancyStrategy(); + + /** + * Access to all explicit cache region mappings. + * + * @return Explicit cache region mappings. + */ + List getCacheRegionDefinitions(); + + + // todo : these 2 will go away... + + MetadataSourceProcessingOrder getMetadataSourceProcessingOrder(); + + EntityResolver getEntityResolver(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/MetadataImplementor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/MetadataImplementor.java index 7296149152..8472f0eb6d 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/MetadataImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/MetadataImplementor.java @@ -79,6 +79,7 @@ public interface MetadataImplementor extends Metadata, BindingContext, Mapping { void addResultSetMapping(ResultSetMappingDefinition resultSetMappingDefinition); + @Deprecated void setGloballyQuotedIdentifiers(boolean b); MetaAttributeContext getGlobalMetaAttributeContext(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityHierarchyBindingNode.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityHierarchyBindingNode.java new file mode 100644 index 0000000000..9c1c4a38fb --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityHierarchyBindingNode.java @@ -0,0 +1,33 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2014, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.spi.binding; + +/** + * Represents an Entity or MappedSuperclass in the binding model + * + * @author Steve Ebersole + */ +public interface EntityHierarchyBindingNode { + +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/BindingContext.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/BindingContext.java index df54c86f40..aeaf090396 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/BindingContext.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/BindingContext.java @@ -24,6 +24,7 @@ package org.hibernate.metamodel.spi.source; import org.hibernate.cfg.NamingStrategy; +import org.hibernate.metamodel.spi.MetadataBuildingOptions; import org.hibernate.metamodel.spi.MetadataImplementor; import org.hibernate.metamodel.spi.domain.JavaClassReference; import org.hibernate.metamodel.spi.domain.Type; @@ -39,6 +40,8 @@ public interface BindingContext { public MappingDefaults getMappingDefaults(); + public MetadataBuildingOptions getBuildingOptions(); + public MetadataImplementor getMetadataImplementor(); public Class locateClassByName(String name); diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/AssertSourcesTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/AssertSourcesTest.java index 0b5244f203..ba29a7a046 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/AssertSourcesTest.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/AssertSourcesTest.java @@ -80,7 +80,7 @@ public class AssertSourcesTest extends BaseUnitTestCase { } private MetadataImpl buildMetadata(MetadataSources sources) { - return new MetadataImpl( sources, new MetadataBuilderImpl.OptionsImpl( serviceRegistry ) ); + return new MetadataImpl( sources, new MetadataBuilderImpl.Options( serviceRegistry ) ); } private void testUserEntitySources(MetadataSourceProcessor processor) {