package org.hibernate.cfg; import org.hibernate.boot.Metadata; import org.hibernate.boot.internal.ClassLoaderAccessImpl; import org.hibernate.boot.internal.InFlightMetadataCollectorImpl; import org.hibernate.boot.internal.MetadataBuildingContextRootImpl; import org.hibernate.boot.internal.MetadataBuilderImpl.MetadataBuildingOptionsImpl; import org.hibernate.boot.model.TypeContributions; import org.hibernate.boot.model.TypeContributor; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.spi.BasicTypeRegistration; import org.hibernate.boot.spi.ClassLoaderAccess; import org.hibernate.boot.spi.MetadataBuildingContext; import org.hibernate.boot.spi.MetadataBuildingOptions; import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.mapping.PersistentClass; import org.hibernate.type.BasicType; import org.hibernate.type.BasicTypeRegistry; import org.hibernate.type.TypeFactory; import org.hibernate.type.TypeResolver; import org.hibernate.usertype.CompositeUserType; import org.hibernate.usertype.UserType; public class PojoMetaDataConfiguration extends Configuration { private StandardServiceRegistry serviceRegistry = null; private InFlightMetadataCollectorImpl metadataCollector; private ClassLoaderAccess classLoaderAccess = null; private MetadataBuildingOptions metadataBuildingOptions = null; private MetadataBuildingContext metadataBuildingContext = null; private Metadata metadata = null; public void addClass(PersistentClass persistentClass) { getMetadataCollector().addEntityBinding(persistentClass); } public Metadata getMetadata() { if (metadata == null) { metadata = getMetadataCollector().buildMetadataInstance(getMetadataBuildingContext()); } return metadata; } public MetadataImplementor getMetadataImplementor() { return getMetadataCollector(); } private ClassLoaderAccess getClassLoaderAccess() { if (classLoaderAccess == null) { MetadataBuildingOptions options = getMetadataBuildingOptions(); ClassLoaderService classLoaderService = options.getServiceRegistry().getService( ClassLoaderService.class ); classLoaderAccess = new ClassLoaderAccessImpl( options.getTempClassLoader(), classLoaderService ); } return classLoaderAccess; } private MetadataBuildingOptions getMetadataBuildingOptions() { if (metadataBuildingOptions == null) { metadataBuildingOptions = new MetadataBuildingOptionsImpl( getServiceRegistry() ); } return metadataBuildingOptions; } private InFlightMetadataCollectorImpl getMetadataCollector() { if (metadataCollector == null) { MetadataBuildingOptions options = getMetadataBuildingOptions(); BasicTypeRegistry basicTypeRegistry = handleTypes( options ); metadataCollector = new InFlightMetadataCollectorImpl( options, new TypeResolver( basicTypeRegistry, new TypeFactory() ) ); } return metadataCollector; } private MetadataBuildingContext getMetadataBuildingContext() { if (metadataBuildingContext == null) { metadataBuildingContext = new MetadataBuildingContextRootImpl( getMetadataBuildingOptions(), getClassLoaderAccess(), getMetadataCollector()); } return metadataBuildingContext; } private StandardServiceRegistry getServiceRegistry(){ if(serviceRegistry == null){ serviceRegistry = new StandardServiceRegistryBuilder() .applySettings(getProperties()) .build(); } return serviceRegistry; } private static BasicTypeRegistry handleTypes(MetadataBuildingOptions options) { final ClassLoaderService classLoaderService = options.getServiceRegistry().getService( ClassLoaderService.class ); // ultimately this needs to change a little bit to account for HHH-7792 final BasicTypeRegistry basicTypeRegistry = new BasicTypeRegistry(); final TypeContributions typeContributions = new TypeContributions() { public void contributeType(BasicType type) { basicTypeRegistry.register( type ); } public void contributeType(BasicType type, String... keys) { basicTypeRegistry.register( type, keys ); } public void contributeType(UserType type, String... keys) { basicTypeRegistry.register( type, keys ); } public void contributeType(CompositeUserType type, String... keys) { basicTypeRegistry.register( type, keys ); } }; // add Dialect contributed types final Dialect dialect = options.getServiceRegistry().getService( JdbcServices.class ).getDialect(); dialect.contributeTypes( typeContributions, options.getServiceRegistry() ); // add TypeContributor contributed types. for ( TypeContributor contributor : classLoaderService.loadJavaServices( TypeContributor.class ) ) { contributor.contribute( typeContributions, options.getServiceRegistry() ); } // add explicit application registered types for ( BasicTypeRegistration basicTypeRegistration : options.getBasicTypeRegistrations() ) { basicTypeRegistry.register( basicTypeRegistration.getBasicType(), basicTypeRegistration.getRegistrationKeys() ); } return basicTypeRegistry; } }