From 8e3fd81046e1f943fc2511df95e1085ec219c373 Mon Sep 17 00:00:00 2001 From: Brett Meyer Date: Tue, 30 Apr 2013 12:50:02 -0400 Subject: [PATCH] HHH-7995 Added support for TypeContributors in OSGi. Integrated with envers --- .../java/org/hibernate/cfg/Configuration.java | 46 ++++++++++++++++++- .../metamodel/spi/TypeContributor.java | 3 ++ .../org/hibernate/ejb/Ejb3Configuration.java | 14 ++++-- .../envers/entities/TypeContributorImpl.java | 38 +++++++++++++++ ...rg.hibernate.metamodel.spi.TypeContributor | 1 + .../OSGI-INF/blueprint/blueprint.xml | 3 ++ .../osgi/OsgiPersistenceProvider.java | 22 +++++---- .../osgi/OsgiSessionFactoryService.java | 6 +++ 8 files changed, 120 insertions(+), 13 deletions(-) create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/entities/TypeContributorImpl.java create mode 100644 hibernate-envers/src/main/resources/META-INF/services/org.hibernate.metamodel.spi.TypeContributor diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java index b3d6524bf3..e30628f8ab 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java @@ -81,6 +81,7 @@ import org.hibernate.dialect.MySQLDialect; import org.hibernate.dialect.function.SQLFunction; import org.hibernate.engine.ResultSetMappingDefinition; +import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.engine.spi.Mapping; import org.hibernate.engine.spi.NamedQueryDefinition; @@ -128,10 +129,13 @@ import org.hibernate.mapping.Table; import org.hibernate.mapping.TypeDef; import org.hibernate.mapping.UniqueKey; +import org.hibernate.metamodel.spi.TypeContributions; +import org.hibernate.metamodel.spi.TypeContributor; import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.secure.internal.JACCConfiguration; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistryBuilder; +import org.hibernate.service.classloading.spi.ClassLoaderService; import org.hibernate.service.internal.StandardServiceRegistryImpl; import org.hibernate.tool.hbm2ddl.DatabaseMetadata; import org.hibernate.tool.hbm2ddl.IndexMetadata; @@ -219,7 +223,9 @@ public class Configuration implements Serializable { protected Map extendsQueue; protected Map sqlFunctions; + private TypeResolver typeResolver = new TypeResolver(); + private List typeContributorRegistrations = new ArrayList(); private EntityTuplizerFactory entityTuplizerFactory; // private ComponentTuplizerFactory componentTuplizerFactory; todo : HHH-3517 and HHH-1907 @@ -1743,7 +1749,8 @@ public Map getNamedQueries() { */ public SessionFactory buildSessionFactory(ServiceRegistry serviceRegistry) throws HibernateException { LOG.debugf( "Preparing to build session factory with filters : %s", filterDefinitions ); - + + buildTypeRegistrations( serviceRegistry ); secondPassCompile(); if ( !metadataSourceQueue.isEmpty() ) { LOG.incompleteMappingMetadataCacheProcessing(); @@ -1765,6 +1772,39 @@ public SessionFactory buildSessionFactory(ServiceRegistry serviceRegistry) throw sessionFactoryObserver ); } + + private void buildTypeRegistrations(ServiceRegistry serviceRegistry) { + final TypeContributions typeContributions = new TypeContributions() { + @Override + public void contributeType(BasicType type) { + typeResolver.registerTypeOverride( type ); + } + + @Override + public void contributeType(UserType type, String[] keys) { + typeResolver.registerTypeOverride( type, keys ); + } + + @Override + public void contributeType(CompositeUserType type, String[] keys) { + typeResolver.registerTypeOverride( type, keys ); + } + }; + + // add Dialect contributed types + final Dialect dialect = serviceRegistry.getService( JdbcServices.class ).getDialect(); + dialect.contributeTypes( typeContributions, serviceRegistry ); + + // add TypeContributor contributed types. + ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class ); + for ( TypeContributor contributor : classLoaderService.loadJavaServices( TypeContributor.class ) ) { + contributor.contribute( typeContributions, serviceRegistry ); + } + // from app registrations + for ( TypeContributor contributor : typeContributorRegistrations ) { + contributor.contribute( typeContributions, serviceRegistry ); + } + } /** * Create a {@link SessionFactory} using the properties and mappings in this configuration. The @@ -2452,6 +2492,10 @@ public void registerTypeOverride(CompositeUserType type, String[] keys) { getTypeResolver().registerTypeOverride( type, keys ); } + public void registerTypeContributor(TypeContributor typeContributor) { + typeContributorRegistrations.add( typeContributor ); + } + public SessionFactoryObserver getSessionFactoryObserver() { return sessionFactoryObserver; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/TypeContributor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/TypeContributor.java index 004caef5e6..4a04173faa 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/TypeContributor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/TypeContributor.java @@ -29,6 +29,9 @@ * Contract for contributing types. * * @author Steve Ebersole + * + * NOTE: Cherry-pick of HHH-7998 from metamodel. For merging simplicity, just + * keep it in the o.h.metamodel.spi package. */ public interface TypeContributor { /** diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java index 9211a0e710..fda7c7f3ac 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java @@ -45,6 +45,7 @@ import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; + import javax.naming.BinaryRefAddr; import javax.naming.NamingException; import javax.naming.Reference; @@ -60,10 +61,6 @@ import javax.sql.DataSource; import org.dom4j.Element; -import org.jboss.logging.Logger; -import org.xml.sax.EntityResolver; -import org.xml.sax.InputSource; - import org.hibernate.HibernateException; import org.hibernate.Interceptor; import org.hibernate.MappingException; @@ -103,6 +100,7 @@ import org.hibernate.internal.util.xml.XmlDocument; import org.hibernate.mapping.AuxiliaryDatabaseObject; import org.hibernate.mapping.PersistentClass; +import org.hibernate.metamodel.spi.TypeContributor; import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.secure.internal.JACCConfiguration; import org.hibernate.service.BootstrapServiceRegistryBuilder; @@ -110,6 +108,9 @@ import org.hibernate.service.ServiceRegistryBuilder; import org.hibernate.service.internal.StandardServiceRegistryImpl; import org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl; +import org.jboss.logging.Logger; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; /** * Allow a fine tuned configuration of an EJB 3.0 EntityManagerFactory @@ -1655,6 +1656,11 @@ public Ejb3Configuration addResource(String path, ClassLoader classLoader) throw cfg.addResource( path, classLoader ); return this; } + + public Ejb3Configuration addTypeContributor(TypeContributor typeContributor) { + cfg.registerTypeContributor( typeContributor ); + return this; + } private enum XML_SEARCH { HBM, diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/entities/TypeContributorImpl.java b/hibernate-envers/src/main/java/org/hibernate/envers/entities/TypeContributorImpl.java new file mode 100644 index 0000000000..89be489d49 --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/entities/TypeContributorImpl.java @@ -0,0 +1,38 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * JBoss, Home of Professional Open Source + * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @authors tag. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * 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, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * 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, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.hibernate.envers.entities; + +import org.hibernate.metamodel.spi.TypeContributions; +import org.hibernate.metamodel.spi.TypeContributor; +import org.hibernate.service.ServiceRegistry; + +/** + * @author Brett Meyer + */ +public class TypeContributorImpl implements TypeContributor { + + @Override + public void contribute(TypeContributions typeContributions, ServiceRegistry serviceRegistry) { + typeContributions.contributeType( new RevisionTypeType(), + new String[] { RevisionTypeType.class.getName() } ); + } + +} diff --git a/hibernate-envers/src/main/resources/META-INF/services/org.hibernate.metamodel.spi.TypeContributor b/hibernate-envers/src/main/resources/META-INF/services/org.hibernate.metamodel.spi.TypeContributor new file mode 100644 index 0000000000..7d98b39bbf --- /dev/null +++ b/hibernate-envers/src/main/resources/META-INF/services/org.hibernate.metamodel.spi.TypeContributor @@ -0,0 +1 @@ +org.hibernate.envers.entities.TypeContributorImpl \ No newline at end of file diff --git a/hibernate-envers/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/hibernate-envers/src/main/resources/OSGI-INF/blueprint/blueprint.xml index c88d9a8eae..f418cfe2ca 100644 --- a/hibernate-envers/src/main/resources/OSGI-INF/blueprint/blueprint.xml +++ b/hibernate-envers/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -6,5 +6,8 @@ + + + diff --git a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiPersistenceProvider.java b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiPersistenceProvider.java index 83c09f5c43..f2e6a2a122 100644 --- a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiPersistenceProvider.java +++ b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiPersistenceProvider.java @@ -35,6 +35,7 @@ import org.hibernate.ejb.Ejb3Configuration; import org.hibernate.ejb.HibernatePersistence; import org.hibernate.integrator.spi.Integrator; +import org.hibernate.metamodel.spi.TypeContributor; import org.hibernate.osgi.util.OsgiServiceUtil; import org.hibernate.service.BootstrapServiceRegistryBuilder; import org.osgi.framework.Bundle; @@ -68,7 +69,7 @@ public OsgiPersistenceProvider(OsgiClassLoader osgiClassLoader, OsgiJtaPlatform @Override public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) { - generateProperties( properties ); + properties = generateProperties( properties ); // TODO: This needs tested. properties.put( org.hibernate.ejb.AvailableSettings.SCANNER, new OsgiScanner( requestingBundle ) ); @@ -80,12 +81,12 @@ public EntityManagerFactory createEntityManagerFactory(String persistenceUnitNam Ejb3Configuration cfg = new Ejb3Configuration(); Ejb3Configuration configured = cfg.configure( persistenceUnitName, properties ); - return configured != null ? configured.buildEntityManagerFactory( getBuilder( properties ) ) : null; + return configured != null ? configured.buildEntityManagerFactory( getBuilder( cfg, properties ) ) : null; } @Override public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) { - generateProperties( properties ); + properties = generateProperties( properties ); // OSGi ClassLoaders must implement BundleReference properties.put( org.hibernate.ejb.AvailableSettings.SCANNER, @@ -95,10 +96,10 @@ public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitI Ejb3Configuration cfg = new Ejb3Configuration(); Ejb3Configuration configured = cfg.configure( info, properties ); - return configured != null ? configured.buildEntityManagerFactory( getBuilder( properties ) ) : null; + return configured != null ? configured.buildEntityManagerFactory( getBuilder( cfg, properties ) ) : null; } - private BootstrapServiceRegistryBuilder getBuilder(Map properties) { + private BootstrapServiceRegistryBuilder getBuilder(Ejb3Configuration cfg, Map properties) { BootstrapServiceRegistryBuilder builder = new BootstrapServiceRegistryBuilder(); final Collection classLoaders = (Collection) properties @@ -114,17 +115,22 @@ private BootstrapServiceRegistryBuilder getBuilder(Map properties) { for ( Integrator integrator : integrators ) { builder.with( integrator ); } - - // TODO: other types of services? + + List typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context ); + for (TypeContributor typeContributor : typeContributors) { + cfg.addTypeContributor( typeContributor ); + } return builder; } - private void generateProperties(Map properties) { + private Map generateProperties(Map properties) { if ( properties == null ) { properties = new HashMap(); } properties.put( AvailableSettings.JTA_PLATFORM, osgiJtaPlatform ); + + return properties; } } diff --git a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiSessionFactoryService.java b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiSessionFactoryService.java index b13f378212..9499e78687 100644 --- a/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiSessionFactoryService.java +++ b/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiSessionFactoryService.java @@ -26,6 +26,7 @@ import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.Configuration; import org.hibernate.integrator.spi.Integrator; +import org.hibernate.metamodel.spi.TypeContributor; import org.hibernate.osgi.util.OsgiServiceUtil; import org.hibernate.service.BootstrapServiceRegistryBuilder; import org.hibernate.service.ServiceRegistry; @@ -84,6 +85,11 @@ public Object getService(Bundle requestingBundle, ServiceRegistration registrati builder.with( integrator ); } + List typeContributors = OsgiServiceUtil.getServiceImpls( TypeContributor.class, context ); + for (TypeContributor typeContributor : typeContributors) { + configuration.registerTypeContributor( typeContributor ); + } + ServiceRegistry serviceRegistry = new ServiceRegistryBuilder( builder.build() ) .applySettings(configuration.getProperties()).buildServiceRegistry(); return configuration.buildSessionFactory(serviceRegistry);