Merge pull request #249 from stliu/HHH-6964
HHH-6964 Audit Strategy class can't be found by Thread.currentThread().getContextClassLoader() under AS7
This commit is contained in:
commit
d8003efcf6
|
@ -22,6 +22,7 @@
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.hibernate.envers.configuration;
|
package org.hibernate.envers.configuration;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
@ -39,107 +40,134 @@ import org.hibernate.envers.strategy.ValidityAuditStrategy;
|
||||||
import org.hibernate.envers.synchronization.AuditProcessManager;
|
import org.hibernate.envers.synchronization.AuditProcessManager;
|
||||||
import org.hibernate.envers.tools.reflection.ReflectionTools;
|
import org.hibernate.envers.tools.reflection.ReflectionTools;
|
||||||
import org.hibernate.property.Getter;
|
import org.hibernate.property.Getter;
|
||||||
|
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adam Warski (adam at warski dot org)
|
* @author Adam Warski (adam at warski dot org)
|
||||||
* @author Stephanie Pau at Markit Group Plc
|
* @author Stephanie Pau at Markit Group Plc
|
||||||
*/
|
*/
|
||||||
public class AuditConfiguration {
|
public class AuditConfiguration {
|
||||||
private final GlobalConfiguration globalCfg;
|
private final GlobalConfiguration globalCfg;
|
||||||
private final AuditEntitiesConfiguration auditEntCfg;
|
private final AuditEntitiesConfiguration auditEntCfg;
|
||||||
private final AuditProcessManager auditProcessManager;
|
private final AuditProcessManager auditProcessManager;
|
||||||
private final AuditStrategy auditStrategy;
|
private final AuditStrategy auditStrategy;
|
||||||
private final EntitiesConfigurations entCfg;
|
private final EntitiesConfigurations entCfg;
|
||||||
private final RevisionInfoQueryCreator revisionInfoQueryCreator;
|
private final RevisionInfoQueryCreator revisionInfoQueryCreator;
|
||||||
private final RevisionInfoNumberReader revisionInfoNumberReader;
|
private final RevisionInfoNumberReader revisionInfoNumberReader;
|
||||||
private final ModifiedEntityNamesReader modifiedEntityNamesReader;
|
private final ModifiedEntityNamesReader modifiedEntityNamesReader;
|
||||||
|
private final ClassLoaderService classLoaderService;
|
||||||
|
|
||||||
public AuditEntitiesConfiguration getAuditEntCfg() {
|
public AuditEntitiesConfiguration getAuditEntCfg() {
|
||||||
return auditEntCfg;
|
return auditEntCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuditProcessManager getSyncManager() {
|
public AuditProcessManager getSyncManager() {
|
||||||
return auditProcessManager;
|
return auditProcessManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlobalConfiguration getGlobalCfg() {
|
public GlobalConfiguration getGlobalCfg() {
|
||||||
return globalCfg;
|
return globalCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntitiesConfigurations getEntCfg() {
|
public EntitiesConfigurations getEntCfg() {
|
||||||
return entCfg;
|
return entCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RevisionInfoQueryCreator getRevisionInfoQueryCreator() {
|
public RevisionInfoQueryCreator getRevisionInfoQueryCreator() {
|
||||||
return revisionInfoQueryCreator;
|
return revisionInfoQueryCreator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RevisionInfoNumberReader getRevisionInfoNumberReader() {
|
public RevisionInfoNumberReader getRevisionInfoNumberReader() {
|
||||||
return revisionInfoNumberReader;
|
return revisionInfoNumberReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModifiedEntityNamesReader getModifiedEntityNamesReader() {
|
public ModifiedEntityNamesReader getModifiedEntityNamesReader() {
|
||||||
return modifiedEntityNamesReader;
|
return modifiedEntityNamesReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuditStrategy getAuditStrategy() {
|
public AuditStrategy getAuditStrategy() {
|
||||||
return auditStrategy;
|
return auditStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuditConfiguration(Configuration cfg) {
|
public AuditConfiguration(Configuration cfg) {
|
||||||
Properties properties = cfg.getProperties();
|
this( cfg, null );
|
||||||
|
}
|
||||||
|
|
||||||
ReflectionManager reflectionManager = cfg.getReflectionManager();
|
public AuditConfiguration(Configuration cfg, ClassLoaderService classLoaderService) {
|
||||||
globalCfg = new GlobalConfiguration(properties);
|
Properties properties = cfg.getProperties();
|
||||||
RevisionInfoConfiguration revInfoCfg = new RevisionInfoConfiguration(globalCfg);
|
|
||||||
RevisionInfoConfigurationResult revInfoCfgResult = revInfoCfg.configure(cfg, reflectionManager);
|
ReflectionManager reflectionManager = cfg.getReflectionManager();
|
||||||
auditEntCfg = new AuditEntitiesConfiguration(properties, revInfoCfgResult.getRevisionInfoEntityName());
|
globalCfg = new GlobalConfiguration( properties );
|
||||||
auditProcessManager = new AuditProcessManager(revInfoCfgResult.getRevisionInfoGenerator());
|
RevisionInfoConfiguration revInfoCfg = new RevisionInfoConfiguration( globalCfg );
|
||||||
revisionInfoQueryCreator = revInfoCfgResult.getRevisionInfoQueryCreator();
|
RevisionInfoConfigurationResult revInfoCfgResult = revInfoCfg.configure( cfg, reflectionManager );
|
||||||
revisionInfoNumberReader = revInfoCfgResult.getRevisionInfoNumberReader();
|
auditEntCfg = new AuditEntitiesConfiguration( properties, revInfoCfgResult.getRevisionInfoEntityName() );
|
||||||
modifiedEntityNamesReader = revInfoCfgResult.getModifiedEntityNamesReader();
|
auditProcessManager = new AuditProcessManager( revInfoCfgResult.getRevisionInfoGenerator() );
|
||||||
auditStrategy = initializeAuditStrategy(revInfoCfgResult.getRevisionInfoClass(),
|
revisionInfoQueryCreator = revInfoCfgResult.getRevisionInfoQueryCreator();
|
||||||
revInfoCfgResult.getRevisionInfoTimestampData());
|
revisionInfoNumberReader = revInfoCfgResult.getRevisionInfoNumberReader();
|
||||||
entCfg = new EntitiesConfigurator().configure(cfg, reflectionManager, globalCfg, auditEntCfg, auditStrategy,
|
modifiedEntityNamesReader = revInfoCfgResult.getModifiedEntityNamesReader();
|
||||||
revInfoCfgResult.getRevisionInfoXmlMapping(), revInfoCfgResult.getRevisionInfoRelationMapping());
|
this.classLoaderService = classLoaderService;
|
||||||
}
|
auditStrategy = initializeAuditStrategy(
|
||||||
|
revInfoCfgResult.getRevisionInfoClass(),
|
||||||
|
revInfoCfgResult.getRevisionInfoTimestampData()
|
||||||
|
);
|
||||||
|
entCfg = new EntitiesConfigurator().configure(
|
||||||
|
cfg, reflectionManager, globalCfg, auditEntCfg, auditStrategy,
|
||||||
|
revInfoCfgResult.getRevisionInfoXmlMapping(), revInfoCfgResult.getRevisionInfoRelationMapping()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private AuditStrategy initializeAuditStrategy(Class<?> revisionInfoClass, PropertyData revisionInfoTimestampData) {
|
private AuditStrategy initializeAuditStrategy(Class<?> revisionInfoClass, PropertyData revisionInfoTimestampData) {
|
||||||
AuditStrategy strategy;
|
AuditStrategy strategy;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Class<?> auditStrategyClass = Thread.currentThread().getContextClassLoader().loadClass(auditEntCfg.getAuditStrategyName());
|
|
||||||
strategy = (AuditStrategy) auditStrategyClass.newInstance();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new MappingException(
|
|
||||||
String.format("Unable to create AuditStrategy[%s] instance." , auditEntCfg.getAuditStrategyName()),
|
|
||||||
e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strategy instanceof ValidityAuditStrategy) {
|
Class<?> auditStrategyClass = null;
|
||||||
// further initialization required
|
if ( classLoaderService != null ) {
|
||||||
Getter revisionTimestampGetter = ReflectionTools.getGetter(revisionInfoClass, revisionInfoTimestampData);
|
auditStrategyClass = classLoaderService.classForName( auditEntCfg.getAuditStrategyName() );
|
||||||
((ValidityAuditStrategy) strategy).setRevisionTimestampGetter(revisionTimestampGetter);
|
}
|
||||||
}
|
else {
|
||||||
|
auditStrategyClass = Thread.currentThread()
|
||||||
|
.getContextClassLoader()
|
||||||
|
.loadClass( auditEntCfg.getAuditStrategyName() );
|
||||||
|
}
|
||||||
|
|
||||||
return strategy;
|
strategy = (AuditStrategy) auditStrategyClass.newInstance();
|
||||||
|
}
|
||||||
|
catch ( Exception e ) {
|
||||||
|
throw new MappingException(
|
||||||
|
String.format( "Unable to create AuditStrategy[%s] instance.", auditEntCfg.getAuditStrategyName() ),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( strategy instanceof ValidityAuditStrategy ) {
|
||||||
|
// further initialization required
|
||||||
|
Getter revisionTimestampGetter = ReflectionTools.getGetter( revisionInfoClass, revisionInfoTimestampData );
|
||||||
|
( (ValidityAuditStrategy) strategy ).setRevisionTimestampGetter( revisionTimestampGetter );
|
||||||
|
}
|
||||||
|
|
||||||
|
return strategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
private static Map<Configuration, AuditConfiguration> cfgs
|
private static Map<Configuration, AuditConfiguration> cfgs
|
||||||
= new WeakHashMap<Configuration, AuditConfiguration>();
|
= new WeakHashMap<Configuration, AuditConfiguration>();
|
||||||
|
|
||||||
public synchronized static AuditConfiguration getFor(Configuration cfg) {
|
public synchronized static AuditConfiguration getFor(Configuration cfg) {
|
||||||
AuditConfiguration verCfg = cfgs.get(cfg);
|
return getFor( cfg, null );
|
||||||
|
}
|
||||||
|
|
||||||
if (verCfg == null) {
|
public synchronized static AuditConfiguration getFor(Configuration cfg, ClassLoaderService classLoaderService) {
|
||||||
verCfg = new AuditConfiguration(cfg);
|
AuditConfiguration verCfg = cfgs.get( cfg );
|
||||||
cfgs.put(cfg, verCfg);
|
|
||||||
|
|
||||||
cfg.buildMappings();
|
if ( verCfg == null ) {
|
||||||
}
|
verCfg = new AuditConfiguration( cfg, classLoaderService );
|
||||||
|
cfgs.put( cfg, verCfg );
|
||||||
|
|
||||||
return verCfg;
|
cfg.buildMappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return verCfg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.hibernate.integrator.spi.Integrator;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
import org.hibernate.metamodel.source.MetadataImplementor;
|
import org.hibernate.metamodel.source.MetadataImplementor;
|
||||||
|
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
|
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +61,7 @@ public class EnversIntegrator implements Integrator {
|
||||||
EventListenerRegistry listenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
|
EventListenerRegistry listenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
|
||||||
listenerRegistry.addDuplicationStrategy( EnversListenerDuplicationStrategy.INSTANCE );
|
listenerRegistry.addDuplicationStrategy( EnversListenerDuplicationStrategy.INSTANCE );
|
||||||
|
|
||||||
final AuditConfiguration enversConfiguration = AuditConfiguration.getFor( configuration );
|
final AuditConfiguration enversConfiguration = AuditConfiguration.getFor( configuration, serviceRegistry.getService( ClassLoaderService.class ) );
|
||||||
|
|
||||||
if (enversConfiguration.getEntCfg().hasAuditedEntities()) {
|
if (enversConfiguration.getEntCfg().hasAuditedEntities()) {
|
||||||
listenerRegistry.appendListeners( EventType.POST_DELETE, new EnversPostDeleteEventListenerImpl( enversConfiguration ) );
|
listenerRegistry.appendListeners( EventType.POST_DELETE, new EnversPostDeleteEventListenerImpl( enversConfiguration ) );
|
||||||
|
|
Loading…
Reference in New Issue