From 26c3a1f32bdec3cc3af2492c143f53418390da6e Mon Sep 17 00:00:00 2001 From: Chris Cranford Date: Fri, 26 Nov 2021 02:15:00 -0500 Subject: [PATCH] HHH-12077 Support short-naming of audit strategies --- .../AuditStrategyRegistrationProvider.java | 57 ++++++++++++ .../envers/configuration/Configuration.java | 40 +++------ ...stry.selector.StrategyRegistrationProvider | 3 +- .../strategy/AuditStraegySelectorTest.java | 86 +++++++++++++++++++ 4 files changed, 156 insertions(+), 30 deletions(-) create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/boot/internal/AuditStrategyRegistrationProvider.java create mode 100644 hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/strategy/AuditStraegySelectorTest.java diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/boot/internal/AuditStrategyRegistrationProvider.java b/hibernate-envers/src/main/java/org/hibernate/envers/boot/internal/AuditStrategyRegistrationProvider.java new file mode 100644 index 0000000000..233ea2e889 --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/boot/internal/AuditStrategyRegistrationProvider.java @@ -0,0 +1,57 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.envers.boot.internal; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.boot.registry.selector.SimpleStrategyRegistrationImpl; +import org.hibernate.boot.registry.selector.StrategyRegistration; +import org.hibernate.boot.registry.selector.StrategyRegistrationProvider; +import org.hibernate.boot.registry.selector.spi.StrategySelector; +import org.hibernate.envers.strategy.AuditStrategy; +import org.hibernate.envers.strategy.DefaultAuditStrategy; +import org.hibernate.envers.strategy.ValidityAuditStrategy; + +/** + * Provides the audit strategy implementations to the {@link StrategySelector} service. + * + * @author Chris Cranford + * @since 6.0 + */ +public class AuditStrategyRegistrationProvider implements StrategyRegistrationProvider { + + private static final List STRATEGIES = new ArrayList<>(); + + static { + STRATEGIES.add( + new SimpleStrategyRegistrationImpl( + AuditStrategy.class, + DefaultAuditStrategy.class, + "default", + DefaultAuditStrategy.class.getName(), + DefaultAuditStrategy.class.getSimpleName(), + org.hibernate.envers.strategy.internal.DefaultAuditStrategy.class.getName() + ) + ); + STRATEGIES.add( + new SimpleStrategyRegistrationImpl( + AuditStrategy.class, + ValidityAuditStrategy.class, + "validity", + ValidityAuditStrategy.class.getName(), + ValidityAuditStrategy.class.getSimpleName(), + org.hibernate.envers.strategy.internal.ValidityAuditStrategy.class.getName() + ) + ); + } + + @Override + public Iterable getStrategyRegistrations() { + return STRATEGIES; + } +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/Configuration.java b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/Configuration.java index 118cdad266..c16cf07f63 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/configuration/Configuration.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/configuration/Configuration.java @@ -7,7 +7,6 @@ package org.hibernate.envers.configuration; import java.util.HashMap; -import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.concurrent.Callable; @@ -21,7 +20,6 @@ import org.hibernate.dialect.HSQLDialect; import org.hibernate.envers.RevisionListener; import org.hibernate.envers.boot.EnversMappingException; import org.hibernate.envers.boot.internal.EnversService; -import org.hibernate.envers.boot.internal.EnversServiceImpl; import org.hibernate.envers.boot.internal.LegacyModifiedColumnNamingStrategy; import org.hibernate.envers.boot.spi.ModifiedColumnNamingStrategy; import org.hibernate.envers.configuration.internal.RevisionInfoConfiguration; @@ -29,7 +27,6 @@ import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.envers.internal.tools.StringTools; import org.hibernate.envers.strategy.AuditStrategy; import org.hibernate.envers.strategy.DefaultAuditStrategy; -import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.config.ConfigurationHelper; /** @@ -109,8 +106,10 @@ public class Configuration { modifiedFlagsSuffix = configProps.getString( EnversSettings.MODIFIED_FLAG_SUFFIX, DEFAULT_MODIFIED_FLAG_SUFFIX ); revisionListenerClass = resolveRevisionListener( configProps, enversService ); - modifiedColumnNamingStrategy = resolveModifiedColumnNamingStrategy( configProps, enversService ); - auditStrategy = resolveAuditStrategy( configProps, enversService ); + + final StrategySelector strategySelector = enversService.getServiceRegistry().getService( StrategySelector.class ); + modifiedColumnNamingStrategy = resolveModifiedColumnNamingStrategy( configProps, strategySelector ); + auditStrategy = resolveAuditStrategy( configProps, strategySelector ); nativeIdEnabled = configProps.getBoolean( EnversSettings.USE_REVISION_ENTITY_WITH_NATIVE_ID, true ); allowIdentifierReuse = configProps.getBoolean( EnversSettings.ALLOW_IDENTIFIER_REUSE, false ); @@ -373,8 +372,7 @@ public class Configuration { private static ModifiedColumnNamingStrategy resolveModifiedColumnNamingStrategy( ConfigurationProperties configProps, - EnversService enversService) { - final StrategySelector selector = enversService.getServiceRegistry().getService( StrategySelector.class ); + StrategySelector selector) { return selector.resolveDefaultableStrategy( ModifiedColumnNamingStrategy.class, configProps.getString( EnversSettings.MODIFIED_COLUMN_NAMING_STRATEGY ), @@ -386,28 +384,12 @@ public class Configuration { ); } - private static AuditStrategy resolveAuditStrategy(ConfigurationProperties configProps, EnversService enversService) { - final String className = configProps.getString( EnversSettings.AUDIT_STRATEGY, DefaultAuditStrategy.class.getName() ); - try { - Class auditStrategy = null; - try { - auditStrategy = EnversServiceImpl.class.getClassLoader().loadClass( className ); - } - catch (Exception e) { - auditStrategy = ReflectionTools.loadClass( className, enversService.getClassLoaderService() ); - } - return (AuditStrategy) ReflectHelper.getDefaultConstructor( auditStrategy ).newInstance(); - } - catch (Exception e) { - throw new EnversMappingException( - String.format( - Locale.ENGLISH, - "Unable to create AuditStrategy [%s] instance.", - className - ), - e - ); - } + private static AuditStrategy resolveAuditStrategy(ConfigurationProperties configProps, StrategySelector selector) { + return selector.resolveDefaultableStrategy( + AuditStrategy.class, + configProps.getString( EnversSettings.AUDIT_STRATEGY, DefaultAuditStrategy.class.getName() ), + (Callable) () -> new DefaultAuditStrategy() + ); } private static class ConfigurationProperties { diff --git a/hibernate-envers/src/main/resources/META-INF/services/org.hibernate.boot.registry.selector.StrategyRegistrationProvider b/hibernate-envers/src/main/resources/META-INF/services/org.hibernate.boot.registry.selector.StrategyRegistrationProvider index 350bf85966..e8cf913f16 100644 --- a/hibernate-envers/src/main/resources/META-INF/services/org.hibernate.boot.registry.selector.StrategyRegistrationProvider +++ b/hibernate-envers/src/main/resources/META-INF/services/org.hibernate.boot.registry.selector.StrategyRegistrationProvider @@ -10,4 +10,5 @@ # License: GNU Lesser General Public License (LGPL), version 2.1 or later. # See the lgpl.txt file in the root directory or . # -org.hibernate.envers.boot.internal.ModifiedColumnNamingStrategyRegistrationProvider \ No newline at end of file +org.hibernate.envers.boot.internal.ModifiedColumnNamingStrategyRegistrationProvider +org.hibernate.envers.boot.internal.AuditStrategyRegistrationProvider \ No newline at end of file diff --git a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/strategy/AuditStraegySelectorTest.java b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/strategy/AuditStraegySelectorTest.java new file mode 100644 index 0000000000..13a334ced7 --- /dev/null +++ b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/strategy/AuditStraegySelectorTest.java @@ -0,0 +1,86 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.orm.test.envers.integration.strategy; + +import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; + +import java.util.HashMap; +import java.util.Map; + +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.spi.MetadataImplementor; +import org.hibernate.envers.boot.internal.EnversService; +import org.hibernate.envers.configuration.Configuration; +import org.hibernate.envers.configuration.EnversSettings; +import org.hibernate.envers.strategy.AuditStrategy; +import org.hibernate.envers.strategy.DefaultAuditStrategy; +import org.hibernate.envers.strategy.ValidityAuditStrategy; +import org.hibernate.service.ServiceRegistry; +import org.junit.Test; + +import org.hibernate.testing.ServiceRegistryBuilder; +import org.hibernate.testing.TestForIssue; + +/** + * A set of unit tests that verify that the audit strategy selector appropriately selects and + * creators the correct strategy class. + * + * @author Chris Cranford + */ +@TestForIssue( jiraKey = "HHH-12077" ) +public class AuditStraegySelectorTest { + + @Test + public void testAuditStrategySelectorNoneSpecified() { + testAuditStrategySelector( null, DefaultAuditStrategy.class ); + } + + @Test + public void testAuditStrategySelectorDefaultSpecified() { + // test old implementations + testAuditStrategySelector( "default", DefaultAuditStrategy.class ); + testAuditStrategySelector( DefaultAuditStrategy.class.getSimpleName(), DefaultAuditStrategy.class ); + testAuditStrategySelector( DefaultAuditStrategy.class.getName(), DefaultAuditStrategy.class ); + + // test new implementation + testAuditStrategySelector( + org.hibernate.envers.strategy.internal.DefaultAuditStrategy.class.getName(), + org.hibernate.envers.strategy.internal.DefaultAuditStrategy.class + ); + } + + @Test + public void testAuditStrategySelectorValiditySpecified() { + // test old implementations + testAuditStrategySelector( "validity", ValidityAuditStrategy.class ); + testAuditStrategySelector( ValidityAuditStrategy.class.getSimpleName(), ValidityAuditStrategy.class ); + testAuditStrategySelector( ValidityAuditStrategy.class.getName(), ValidityAuditStrategy.class ); + + // test new implementation + testAuditStrategySelector( + org.hibernate.envers.strategy.internal.ValidityAuditStrategy.class.getName(), + org.hibernate.envers.strategy.internal.ValidityAuditStrategy.class + ); + } + + private void testAuditStrategySelector(String propertyValue, Class expectedStrategyClass) { + final Map properties = new HashMap<>(); + if ( propertyValue != null ) { + properties.put( EnversSettings.AUDIT_STRATEGY, propertyValue ); + } + + final ServiceRegistry sr = ServiceRegistryBuilder.buildServiceRegistry( properties ); + try { + final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( sr ).buildMetadata(); + final Configuration configuration = sr.getService( EnversService.class ).getConfig(); + assertTyping( expectedStrategyClass, configuration.getAuditStrategy() ); + } + finally { + ServiceRegistryBuilder.destroy( sr ); + } + } +}