From aa5bdab6ecc8a9475d4458cdd883046a5d90aee9 Mon Sep 17 00:00:00 2001 From: Chris Cranford Date: Sat, 18 Dec 2021 18:50:36 -0500 Subject: [PATCH] HHH-13361 Refactor mappers --- .../entities/mapper/AbstractMapper.java | 136 +++++++++++++++ .../mapper/AbstractPropertyMapper.java | 2 +- .../mapper/ComponentPropertyMapper.java | 63 ++++--- .../entities/mapper/MultiPropertyMapper.java | 156 ++++++++---------- .../entities/mapper/SinglePropertyMapper.java | 31 ++-- .../mapper/id/AbstractCompositeIdMapper.java | 23 +-- .../entities/mapper/id/AbstractIdMapper.java | 16 +- .../entities/mapper/id/EmbeddedIdMapper.java | 76 +++------ .../entities/mapper/id/SingleIdMapper.java | 72 +------- .../id/VirtualEntitySingleIdMapper.java | 129 ++++++--------- .../relation/AbstractCollectionMapper.java | 21 +-- .../mapper/relation/AbstractToOneMapper.java | 19 +-- .../AbstractMiddleComponentMapper.java | 18 ++ .../component/MiddleDummyComponentMapper.java | 2 +- .../MiddleEmbeddableComponentMapper.java | 34 +--- ...MiddleMapElementNotKeyComponentMapper.java | 2 +- .../MiddleMapKeyIdComponentMapper.java | 2 +- .../MiddleMapKeyPropertyComponentMapper.java | 24 +-- .../MiddleRelatedComponentMapper.java | 2 +- .../MiddleSimpleComponentMapper.java | 2 +- .../MiddleStraightComponentMapper.java | 2 +- .../AbstractCollectionInitializor.java | 46 ++++++ .../BasicCollectionInitializor.java | 25 +-- .../initializor/MapCollectionInitializor.java | 25 +-- .../SortedMapCollectionInitializor.java | 32 ++-- .../SortedSetCollectionInitializor.java | 32 ++-- 26 files changed, 463 insertions(+), 529 deletions(-) create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/AbstractMapper.java create mode 100644 hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/AbstractMiddleComponentMapper.java diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/AbstractMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/AbstractMapper.java new file mode 100644 index 0000000000..19c4a4ae1d --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/AbstractMapper.java @@ -0,0 +1,136 @@ +/* + * 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.internal.entities.mapper; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.function.Supplier; + +import org.hibernate.envers.exception.AuditException; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.tools.ReflectionTools; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.property.access.spi.Getter; +import org.hibernate.property.access.spi.Setter; +import org.hibernate.service.ServiceRegistry; + +/** + * A base class for all entity mapper implementations. + * + * @author Chris Cranford + */ +public abstract class AbstractMapper { + + /** + * Perform an action in a privileged block. + * + * @param block the lambda to executed in privileged. + * @param the return type + * @return the result of the privileged call, may be {@literal null} + */ + protected T doPrivileged(Supplier block) { + if ( System.getSecurityManager() != null ) { + return AccessController.doPrivileged( (PrivilegedAction) block::get ); + } + else { + return block.get(); + } + } + + /** + * Get a value from the specified object. + * + * @param propertyData the property data, should not be {@literal null} + * @param object the object for which the value should be read, should not be {@literal null} + * @param serviceRegistry the service registry, should not be {@literal null} + * @param the return type + * @return the value read from the object, may be {@literal null} + */ + @SuppressWarnings("unchecked") + protected T getValueFromObject(PropertyData propertyData, Object object, ServiceRegistry serviceRegistry) { + return doPrivileged( () -> { + final Getter getter = ReflectionTools.getGetter( object.getClass(), propertyData, serviceRegistry ); + return (T) getter.get( object ); + } ); + } + + /** + * Get a value from the specified object. + * + * @param propertyName the property name, should not be {@literal null} + * @param accessType the property access type, should not be {@literal null} + * @param object the object for hwich the value should be read, should not be {@literal null} + * @param serviceRegistry the service registry, should not be {@literal null} + * @param the return type + * @return the value read from the object, may be {@literal null} + */ + @SuppressWarnings("unchecked") + protected T getValueFromObject(String propertyName, String accessType, Object object, ServiceRegistry serviceRegistry) { + return doPrivileged( () -> { + final Getter getter = ReflectionTools.getGetter( object.getClass(), propertyName, accessType, serviceRegistry ); + return (T) getter.get( object ); + } ); + } + + /** + * Set the specified value on the object. + * + * @param propertyData the property data, should not be {@literal null} + * @param object the object for which the value should be set, should not be {@literal null} + * @param value the value ot be set, may be {@literal null} + * @param serviceRegistry the service registry, should not be {@literal null} + */ + protected void setValueOnObject(PropertyData propertyData, Object object, Object value, ServiceRegistry serviceRegistry) { + doPrivileged( () -> { + final Setter setter = ReflectionTools.getSetter(object.getClass(), propertyData, serviceRegistry ); + setter.set( object, value ); + return null; + } ); + } + + /** + * Gets the value from the source object and sets the value in the destination object. + * + * @param propertyData the property data, should not be {@literal null} + * @param source the source object, should not be {@literal null} + * @param destination the destination object, should not be {@literal null} + * @param serviceRegistry the service registry, should not be {@literal null} + */ + protected void getAndSetValue(PropertyData propertyData, Object source, Object destination, ServiceRegistry serviceRegistry) { + doPrivileged( () -> { + final Getter getter = ReflectionTools.getGetter( source.getClass(), propertyData, serviceRegistry ); + final Setter setter = ReflectionTools.getSetter( destination.getClass(), propertyData, serviceRegistry ); + setter.set( destination, getter.get( source ) ); + return null; + } ); + } + + /** + * Creates a new object based on the specified class with the given constructor arguments. + * + * @param clazz the class, must not be {@literal null} + * @param args the variadic constructor arguments, may be omitted. + * @param the return class type + * @return a new instance of the class + */ + protected T newObjectInstance(Class clazz, Object... args) { + return doPrivileged( () -> { + try { + final Constructor constructor = ReflectHelper.getDefaultConstructor( clazz ); + if ( constructor == null ) { + throw new AuditException( "Failed to locate default constructor for class: " + clazz.getName() ); + } + return constructor.newInstance( args ); + } + catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new AuditException( e ); + } + } ); + } +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/AbstractPropertyMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/AbstractPropertyMapper.java index e659a0d803..11c0445814 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/AbstractPropertyMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/AbstractPropertyMapper.java @@ -11,7 +11,7 @@ package org.hibernate.envers.internal.entities.mapper; * * @author Chris Cranford */ -public abstract class AbstractPropertyMapper implements PropertyMapper { +public abstract class AbstractPropertyMapper extends AbstractMapper implements PropertyMapper { private boolean map; @Override diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/ComponentPropertyMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/ComponentPropertyMapper.java index 47d83b1be7..8cea6aa8f0 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/ComponentPropertyMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/ComponentPropertyMapper.java @@ -7,8 +7,6 @@ package org.hibernate.envers.internal.entities.mapper; import java.io.Serializable; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -118,43 +116,38 @@ public class ComponentPropertyMapper extends AbstractPropertyMapper implements C return; } - AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Object run() { - try { - final Object subObj = ReflectHelper.getDefaultConstructor( componentClass ).newInstance(); + doPrivileged( () -> { + try { + final Object subObj = ReflectHelper.getDefaultConstructor( componentClass ).newInstance(); - if ( isDynamicComponentMap() ) { - ( (Map) obj ).put( propertyData.getBeanName(), subObj ); - delegate.mapToEntityFromMap( enversService, subObj, data, primaryKey, versionsReader, revision ); - } - else { - final Setter setter = ReflectionTools.getSetter( - obj.getClass(), - propertyData, - enversService.getServiceRegistry() - ); + if ( isDynamicComponentMap() ) { + ( (Map) obj ).put( propertyData.getBeanName(), subObj ); + delegate.mapToEntityFromMap( enversService, subObj, data, primaryKey, versionsReader, revision ); + } + else { + final Setter setter = ReflectionTools.getSetter( + obj.getClass(), + propertyData, + enversService.getServiceRegistry() + ); - if ( isAllPropertiesNull( data ) ) { - // single property, but default value need not be null, so we'll set it to null anyway - setter.set( obj, null ); - } - else { - // set the component - setter.set( obj, subObj ); - delegate.mapToEntityFromMap( enversService, subObj, data, primaryKey, versionsReader, revision ); - } - } - } - catch ( Exception e ) { - throw new AuditException( e ); - } - - return null; + if ( isAllPropertiesNull( data ) ) { + // single property, but default value need not be null, so we'll set it to null anyway + setter.set( obj, null ); + } + else { + // set the component + setter.set( obj, subObj ); + delegate.mapToEntityFromMap( enversService, subObj, data, primaryKey, versionsReader, revision ); } } - ); + } + catch ( Exception e ) { + throw new AuditException( e ); + } + + return null; + } ); } private boolean isAllPropertiesNull(Map data) { diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/MultiPropertyMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/MultiPropertyMapper.java index 744754757c..aada560f3f 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/MultiPropertyMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/MultiPropertyMapper.java @@ -7,8 +7,6 @@ package org.hibernate.envers.internal.entities.mapper; import java.io.Serializable; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.List; import java.util.Map; @@ -101,49 +99,44 @@ public class MultiPropertyMapper extends AbstractPropertyMapper implements Exten final Map data, final Object newObj, final Object oldObj) { - return AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Boolean run() { - boolean ret = false; - for ( Map.Entry entry : properties.entrySet() ) { - final PropertyData propertyData = entry.getKey(); - final PropertyMapper propertyMapper = entry.getValue(); + return doPrivileged( () -> { + boolean ret = false; + for ( Map.Entry entry : properties.entrySet() ) { + final PropertyData propertyData = entry.getKey(); + final PropertyMapper propertyMapper = entry.getValue(); - // synthetic properties are not part of the entity model; therefore they should be ignored. - if ( propertyData.isSynthetic() ) { - continue; - } - - Getter getter; - if ( newObj != null ) { - getter = ReflectionTools.getGetter( - newObj.getClass(), - propertyData, - session.getFactory().getServiceRegistry() - ); - } - else if ( oldObj != null ) { - getter = ReflectionTools.getGetter( - oldObj.getClass(), - propertyData, - session.getFactory().getServiceRegistry() - ); - } - else { - return false; - } - - ret |= propertyMapper.mapToMapFromEntity( - session, data, - newObj == null ? null : getter.get( newObj ), - oldObj == null ? null : getter.get( oldObj ) - ); - } - return ret; - } + // synthetic properties are not part of the entity model; therefore they should be ignored. + if ( propertyData.isSynthetic() ) { + continue; } - ); + + Getter getter; + if ( newObj != null ) { + getter = ReflectionTools.getGetter( + newObj.getClass(), + propertyData, + session.getFactory().getServiceRegistry() + ); + } + else if ( oldObj != null ) { + getter = ReflectionTools.getGetter( + oldObj.getClass(), + propertyData, + session.getFactory().getServiceRegistry() + ); + } + else { + return false; + } + + ret |= propertyMapper.mapToMapFromEntity( + session, data, + newObj == null ? null : getter.get( newObj ), + oldObj == null ? null : getter.get( oldObj ) + ); + } + return ret; + } ); } @Override @@ -152,49 +145,44 @@ public class MultiPropertyMapper extends AbstractPropertyMapper implements Exten final Map data, final Object newObj, final Object oldObj) { - AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Object run() { - for ( Map.Entry entry : properties.entrySet() ) { - final PropertyData propertyData = entry.getKey(); - final PropertyMapper propertyMapper = entry.getValue(); + doPrivileged( () -> { + for ( Map.Entry entry : properties.entrySet() ) { + final PropertyData propertyData = entry.getKey(); + final PropertyMapper propertyMapper = entry.getValue(); - // synthetic properties are not part of the entity model; therefore they should be ignored. - if ( propertyData.isSynthetic() ) { - continue; - } - - Getter getter; - if ( newObj != null ) { - getter = ReflectionTools.getGetter( - newObj.getClass(), - propertyData, - session.getFactory().getServiceRegistry() - ); - } - else if ( oldObj != null ) { - getter = ReflectionTools.getGetter( - oldObj.getClass(), - propertyData, - session.getFactory().getServiceRegistry() - ); - } - else { - break; - } - - propertyMapper.mapModifiedFlagsToMapFromEntity( - session, data, - newObj == null ? null : getter.get( newObj ), - oldObj == null ? null : getter.get( oldObj ) - ); - } - - return null; - } + // synthetic properties are not part of the entity model; therefore they should be ignored. + if ( propertyData.isSynthetic() ) { + continue; } - ); + + Getter getter; + if ( newObj != null ) { + getter = ReflectionTools.getGetter( + newObj.getClass(), + propertyData, + session.getFactory().getServiceRegistry() + ); + } + else if ( oldObj != null ) { + getter = ReflectionTools.getGetter( + oldObj.getClass(), + propertyData, + session.getFactory().getServiceRegistry() + ); + } + else { + break; + } + + propertyMapper.mapModifiedFlagsToMapFromEntity( + session, data, + newObj == null ? null : getter.get( newObj ), + oldObj == null ? null : getter.get( oldObj ) + ); + } + + return null; + } ); } @Override diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/SinglePropertyMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/SinglePropertyMapper.java index 81fd9fb357..81852628d6 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/SinglePropertyMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/SinglePropertyMapper.java @@ -7,8 +7,6 @@ package org.hibernate.envers.internal.entities.mapper; import java.io.Serializable; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.List; import java.util.Map; import java.util.Objects; @@ -105,25 +103,20 @@ public class SinglePropertyMapper extends AbstractPropertyMapper implements Simp map.put( propertyData.getBeanName(), value ); } else { - AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Object run() { - final Setter setter = ReflectionTools.getSetter( - obj.getClass(), - propertyData, - enversService.getServiceRegistry() - ); + doPrivileged( () -> { + final Setter setter = ReflectionTools.getSetter( + obj.getClass(), + propertyData, + enversService.getServiceRegistry() + ); - // We only set a null value if the field is not primitive. Otherwise, we leave it intact. - if ( value != null || !isPrimitive( setter, propertyData, obj.getClass() ) ) { - setter.set( obj, value ); - } + // We only set a null value if the field is not primitive. Otherwise, we leave it intact. + if ( value != null || !isPrimitive( setter, propertyData, obj.getClass() ) ) { + setter.set( obj, value ); + } - return null; - } - } - ); + return null; + } ); } } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/AbstractCompositeIdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/AbstractCompositeIdMapper.java index cee7177971..a690ef4cfa 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/AbstractCompositeIdMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/AbstractCompositeIdMapper.java @@ -6,8 +6,6 @@ */ package org.hibernate.envers.internal.entities.mapper.id; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Map; import org.hibernate.envers.exception.AuditException; @@ -66,18 +64,13 @@ public abstract class AbstractCompositeIdMapper extends AbstractIdMapper impleme } protected Object instantiateCompositeId() { - return AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Object run() { - try { - return ReflectHelper.getDefaultConstructor( compositeIdClass ).newInstance(); - } - catch ( Exception e ) { - throw new AuditException( e ); - } - } - } - ); + return doPrivileged( () -> { + try { + return ReflectHelper.getDefaultConstructor( compositeIdClass ).newInstance(); + } + catch ( Exception e ) { + throw new AuditException( e ); + } + } ); } } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/AbstractIdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/AbstractIdMapper.java index 3c1801da2d..f5e21eb22d 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/AbstractIdMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/AbstractIdMapper.java @@ -9,6 +9,8 @@ package org.hibernate.envers.internal.entities.mapper.id; import java.util.Iterator; import java.util.List; +import org.hibernate.envers.internal.entities.PropertyData; +import org.hibernate.envers.internal.entities.mapper.AbstractMapper; import org.hibernate.envers.internal.tools.query.Parameters; import org.hibernate.service.ServiceRegistry; @@ -18,7 +20,7 @@ import org.hibernate.service.ServiceRegistry; * @author Adam Warski (adam at warski dot org) * @author Chris Cranford */ -public abstract class AbstractIdMapper implements IdMapper { +public abstract class AbstractIdMapper extends AbstractMapper implements IdMapper { private final ServiceRegistry serviceRegistry; public AbstractIdMapper(ServiceRegistry serviceRegistry) { @@ -143,6 +145,18 @@ public abstract class AbstractIdMapper implements IdMapper { public abstract void mapToEntityFromEntity(Object objectTo, Object objectFrom); + protected T getValueFromObject(PropertyData propertyData, Object object) { + return getValueFromObject( propertyData, object, getServiceRegistry() ); + } + + protected void setValueOnObject(PropertyData propertyData, Object object, Object value) { + setValueOnObject( propertyData, object, value, getServiceRegistry() ); + } + + protected void getAndSetValue(PropertyData propertyData, Object source, Object destination) { + getAndSetValue( propertyData, source, destination, getServiceRegistry() ); + } + private void handleNullValue(Parameters parameters, String alias, String propertyName, boolean equals) { if ( equals ) { parameters.addNullRestriction( alias, propertyName ); diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/EmbeddedIdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/EmbeddedIdMapper.java index ad9673540d..32eb3becac 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/EmbeddedIdMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/EmbeddedIdMapper.java @@ -6,8 +6,6 @@ */ package org.hibernate.envers.internal.entities.mapper.id; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -17,7 +15,6 @@ import org.hibernate.envers.exception.AuditException; import org.hibernate.envers.internal.entities.PropertyData; import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.mapping.Component; -import org.hibernate.property.access.spi.Getter; import org.hibernate.property.access.spi.Setter; import org.hibernate.service.ServiceRegistry; @@ -52,22 +49,7 @@ public class EmbeddedIdMapper extends AbstractCompositeIdMapper implements Simpl if ( obj == null ) { return; } - - final Object value = AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Object run() { - final Getter getter = ReflectionTools.getGetter( - obj.getClass(), - idPropertyData, - getServiceRegistry() - ); - return getter.get( obj ); - } - } - ); - - mapToMapFromId( data, value ); + mapToMapFromId( data, getValueFromObject( idPropertyData, obj ) ); } @Override @@ -76,32 +58,26 @@ public class EmbeddedIdMapper extends AbstractCompositeIdMapper implements Simpl return false; } - return AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Boolean run() { - final Setter setter = ReflectionTools.getSetter( obj.getClass(), idPropertyData, getServiceRegistry() ); + return doPrivileged( () -> { + final Setter setter = ReflectionTools.getSetter( obj.getClass(), idPropertyData, getServiceRegistry() ); + try { + final Object subObj = instantiateCompositeId(); - try { - final Object subObj = instantiateCompositeId(); - - boolean ret = true; - for ( IdMapper idMapper : ids.values() ) { - ret &= idMapper.mapToEntityFromMap( subObj, data ); - } - - if ( ret ) { - setter.set( obj, subObj ); - } - - return ret; - } - catch (Exception e) { - throw new AuditException( e ); - } - } + boolean ret = true; + for ( IdMapper idMapper : ids.values() ) { + ret &= idMapper.mapToEntityFromMap( subObj, data ); } - ); + + if ( ret ) { + setter.set( obj, subObj ); + } + + return ret; + } + catch (Exception e) { + throw new AuditException( e ); + } + } ); } @Override @@ -122,19 +98,7 @@ public class EmbeddedIdMapper extends AbstractCompositeIdMapper implements Simpl return null; } - return AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Object run() { - final Getter getter = ReflectionTools.getGetter( - data.getClass(), - idPropertyData, - getServiceRegistry() - ); - return getter.get( data ); - } - } - ); + return getValueFromObject( idPropertyData, data ); } @Override diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/SingleIdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/SingleIdMapper.java index 20b4ce329f..905d311ffb 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/SingleIdMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/SingleIdMapper.java @@ -6,17 +6,12 @@ */ package org.hibernate.envers.internal.entities.mapper.id; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.hibernate.envers.exception.AuditException; import org.hibernate.envers.internal.entities.PropertyData; -import org.hibernate.envers.internal.tools.ReflectionTools; -import org.hibernate.property.access.spi.Getter; -import org.hibernate.property.access.spi.Setter; import org.hibernate.proxy.HibernateProxy; import org.hibernate.service.ServiceRegistry; @@ -63,20 +58,8 @@ public class SingleIdMapper extends AbstractIdMapper implements SimpleIdMapperBu return false; } - return AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Boolean run() { - final Setter setter = ReflectionTools.getSetter( - obj.getClass(), - propertyData, - getServiceRegistry() - ); - setter.set( obj, value ); - return true; - } - } - ); + setValueOnObject( propertyData, obj, value ); + return true; } @Override @@ -99,19 +82,7 @@ public class SingleIdMapper extends AbstractIdMapper implements SimpleIdMapperBu return hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier(); } else { - return AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Object run() { - final Getter getter = ReflectionTools.getGetter( - data.getClass(), - propertyData, - getServiceRegistry() - ); - return getter.get( data ); - } - } - ); + return getValueFromObject( propertyData, data ); } } @@ -133,19 +104,7 @@ public class SingleIdMapper extends AbstractIdMapper implements SimpleIdMapperBu data.put( propertyData.getName(), hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier() ); } else { - final Object value = AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Object run() { - final Getter getter = ReflectionTools.getGetter( - obj.getClass(), - propertyData, - getServiceRegistry() - ); - return getter.get( obj ); - } - } - ); + final Object value = getValueFromObject( propertyData, obj ); data.put( propertyData.getName(), value ); } } @@ -156,28 +115,7 @@ public class SingleIdMapper extends AbstractIdMapper implements SimpleIdMapperBu if ( objTo == null || objFrom == null ) { return; } - - AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Object run() { - final Getter getter = ReflectionTools.getGetter( - objFrom.getClass(), - propertyData, - getServiceRegistry() - ); - - final Setter setter = ReflectionTools.getSetter( - objTo.getClass(), - propertyData, - getServiceRegistry() - ); - - setter.set( objTo, getter.get( objFrom ) ); - return null; - } - } - ); + getAndSetValue(propertyData, objFrom, objTo ); } @Override diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/VirtualEntitySingleIdMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/VirtualEntitySingleIdMapper.java index 4e5b74250c..a814275010 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/VirtualEntitySingleIdMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/id/VirtualEntitySingleIdMapper.java @@ -6,9 +6,6 @@ */ package org.hibernate.envers.internal.entities.mapper.id; -import java.io.Serializable; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Map; import org.hibernate.Session; @@ -48,19 +45,7 @@ public class VirtualEntitySingleIdMapper extends SingleIdMapper { @Override public void mapToMapFromId(Session session, Map data, Object obj) { - final Serializable value = AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Serializable run() { - final Getter getter = ReflectionTools.getGetter( - obj.getClass(), - propertyData, - getServiceRegistry() - ); - return (Serializable) getter.get( obj ); - } - } - ); + final Object value = getValueFromObject( propertyData, obj ); // Either loads the entity from the session's 1LC if it already exists or potentially creates a // proxy object to represent the entity by identifier so that we can reference it in the map. @@ -74,40 +59,35 @@ public class VirtualEntitySingleIdMapper extends SingleIdMapper { return; } - AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Object run() { - final Getter getter = ReflectionTools.getGetter( - objFrom.getClass(), - propertyData, - getServiceRegistry() - ); + doPrivileged( () -> { + final Getter getter = ReflectionTools.getGetter( + objFrom.getClass(), + propertyData, + getServiceRegistry() + ); - final Setter setter = ReflectionTools.getSetter( - objTo.getClass(), - propertyData, - getServiceRegistry() - ); + final Setter setter = ReflectionTools.getSetter( + objTo.getClass(), + propertyData, + getServiceRegistry() + ); - // Get the value from the containing entity - final Object value = getter.get( objFrom ); - if ( value == null ) { - return null; - } + // Get the value from the containing entity + final Object value = getter.get( objFrom ); + if ( value == null ) { + return null; + } - if ( !value.getClass().equals( propertyData.getVirtualReturnClass() ) ) { - setter.set( objTo, getAssociatedEntityIdMapper().mapToIdFromEntity( value ) ); - } - else { - // This means we're setting the object - setter.set( objTo, value ); - } + if ( !value.getClass().equals( propertyData.getVirtualReturnClass() ) ) { + setter.set( objTo, getAssociatedEntityIdMapper().mapToIdFromEntity( value ) ); + } + else { + // This means we're setting the object + setter.set( objTo, value ); + } - return null; - } - } - ); + return null; + } ); } @Override @@ -121,32 +101,27 @@ public class VirtualEntitySingleIdMapper extends SingleIdMapper { return false; } - return AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Boolean run() { - final Setter setter = ReflectionTools.getSetter( - obj.getClass(), - propertyData, - getServiceRegistry() - ); - final Class paramClass = ReflectionTools.getType( - obj.getClass(), - propertyData, - getServiceRegistry() - ); + return doPrivileged( () -> { + final Setter setter = ReflectionTools.getSetter( + obj.getClass(), + propertyData, + getServiceRegistry() + ); + final Class paramClass = ReflectionTools.getType( + obj.getClass(), + propertyData, + getServiceRegistry() + ); - if ( paramClass != null && paramClass.equals( propertyData.getVirtualReturnClass() ) ) { - setter.set( obj, getAssociatedEntityIdMapper().mapToIdFromEntity( value ) ); - } - else { - setter.set( obj, value ); - } + if ( paramClass != null && paramClass.equals( propertyData.getVirtualReturnClass() ) ) { + setter.set( obj, getAssociatedEntityIdMapper().mapToIdFromEntity( value ) ); + } + else { + setter.set( obj, value ); + } - return true; - } - } - ); + return true; + } ); } @Override @@ -160,19 +135,7 @@ public class VirtualEntitySingleIdMapper extends SingleIdMapper { data.put( propertyData.getName(), proxy.getHibernateLazyInitializer().getInternalIdentifier() ); } else { - final Object value = AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Object run() { - final Getter getter = ReflectionTools.getGetter( - obj.getClass(), - propertyData, - getServiceRegistry() - ); - return getter.get( obj ); - } - } - ); + final Object value = getValueFromObject( propertyData, obj ); if ( propertyData.getVirtualReturnClass().isInstance( value ) ) { // The value is the primary key, need to map it via IdMapper diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractCollectionMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractCollectionMapper.java index 5c34905b5e..0e4d0825d2 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractCollectionMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractCollectionMapper.java @@ -8,8 +8,6 @@ package org.hibernate.envers.internal.entities.mapper.relation; import java.io.Serializable; import java.lang.reflect.Constructor; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -30,9 +28,7 @@ import org.hibernate.envers.internal.entities.mapper.AbstractPropertyMapper; import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData; import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor; import org.hibernate.envers.internal.reader.AuditReaderImplementor; -import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.persister.collection.CollectionPersister; -import org.hibernate.property.access.spi.Setter; /** * @author Adam Warski (adam at warski dot org) @@ -306,22 +302,7 @@ public abstract class AbstractCollectionMapper extends AbstractPropertyMapper map.put( collectionPropertyData.getBeanName(), collectionProxy ); } else { - AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Object run() { - final Setter setter = ReflectionTools.getSetter( - obj.getClass(), - collectionPropertyData, - enversService.getServiceRegistry() - ); - - setter.set( obj, collectionProxy ); - - return null; - } - } - ); + setValueOnObject( collectionPropertyData, obj, collectionProxy, enversService.getServiceRegistry() ); } } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractToOneMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractToOneMapper.java index 3ebc142c60..fa234133d4 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractToOneMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/AbstractToOneMapper.java @@ -7,8 +7,6 @@ package org.hibernate.envers.internal.entities.mapper.relation; import java.io.Serializable; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.List; import java.util.Map; @@ -21,7 +19,6 @@ import org.hibernate.envers.internal.entities.mapper.AbstractPropertyMapper; import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData; import org.hibernate.envers.internal.reader.AuditReaderImplementor; import org.hibernate.envers.internal.tools.ReflectionTools; -import org.hibernate.property.access.spi.Setter; import org.hibernate.service.ServiceRegistry; /** @@ -96,21 +93,7 @@ public abstract class AbstractToOneMapper extends AbstractPropertyMapper { map.put( propertyData.getBeanName(), value ); } else { - AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Object run() { - final Setter setter = ReflectionTools.getSetter( - targetObject.getClass(), - propertyData, - serviceRegistry - ); - setter.set( targetObject, value ); - - return null; - } - } - ); + setValueOnObject( propertyData, targetObject, value, serviceRegistry ); } } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/AbstractMiddleComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/AbstractMiddleComponentMapper.java new file mode 100644 index 0000000000..b216a3d8c1 --- /dev/null +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/AbstractMiddleComponentMapper.java @@ -0,0 +1,18 @@ +/* + * 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.internal.entities.mapper.relation.component; + +import org.hibernate.envers.internal.entities.mapper.AbstractMapper; + +/** + * An abstract base class for all middle component mappers. + * + * @author Chris Cranford + */ +public abstract class AbstractMiddleComponentMapper extends AbstractMapper implements MiddleComponentMapper { + +} diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleDummyComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleDummyComponentMapper.java index e0acf753f4..9eb4c7c39e 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleDummyComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleDummyComponentMapper.java @@ -15,7 +15,7 @@ import org.hibernate.envers.internal.tools.query.Parameters; /** * @author Adam Warski (adam at warski dot org) */ -public final class MiddleDummyComponentMapper implements MiddleComponentMapper { +public final class MiddleDummyComponentMapper extends AbstractMiddleComponentMapper { public Object mapToObjectFromFullMap( EntityInstantiator entityInstantiator, Map data, Object dataObject, Number revision) { diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleEmbeddableComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleEmbeddableComponentMapper.java index d2b78cd70b..8365abcbb6 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleEmbeddableComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleEmbeddableComponentMapper.java @@ -6,9 +6,6 @@ */ package org.hibernate.envers.internal.entities.mapper.relation.component; -import java.lang.reflect.InvocationTargetException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Map; import org.hibernate.engine.spi.SessionImplementor; @@ -20,16 +17,16 @@ import org.hibernate.envers.internal.entities.mapper.MultiPropertyMapper; import org.hibernate.envers.internal.entities.mapper.PropertyMapper; import org.hibernate.envers.internal.entities.mapper.relation.ToOneIdMapper; import org.hibernate.envers.internal.tools.query.Parameters; -import org.hibernate.internal.util.ReflectHelper; /** * @author Kristoffer Lundberg (kristoffer at cambio dot se) */ -public class MiddleEmbeddableComponentMapper implements MiddleComponentMapper, CompositeMapperBuilder { - private final MultiPropertyMapper delegate; - private final Class componentClass; +public class MiddleEmbeddableComponentMapper extends AbstractMiddleComponentMapper implements CompositeMapperBuilder { - public MiddleEmbeddableComponentMapper(MultiPropertyMapper delegate, Class componentClass) { + private final MultiPropertyMapper delegate; + private final Class componentClass; + + public MiddleEmbeddableComponentMapper(MultiPropertyMapper delegate, Class componentClass) { this.delegate = delegate; this.componentClass = componentClass; } @@ -65,26 +62,7 @@ public class MiddleEmbeddableComponentMapper implements MiddleComponentMapper, C if ( dataObject != null ) { return dataObject; } - - return AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Object run() { - try { - return ReflectHelper.getDefaultConstructor( componentClass ).newInstance(); - } - catch ( InstantiationException e ) { - throw new AuditException( e ); - } - catch ( IllegalAccessException e ) { - throw new AuditException( e ); - } - catch ( InvocationTargetException e ) { - throw new AuditException( e ); - } - } - } - ); + return newObjectInstance( componentClass ); } @Override diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapElementNotKeyComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapElementNotKeyComponentMapper.java index 705749081f..c5613d618b 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapElementNotKeyComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapElementNotKeyComponentMapper.java @@ -28,7 +28,7 @@ import org.hibernate.envers.internal.tools.query.Parameters; * * @author Chris Cranford */ -public class MiddleMapElementNotKeyComponentMapper implements MiddleComponentMapper { +public class MiddleMapElementNotKeyComponentMapper extends AbstractMiddleComponentMapper { private final String propertyName; public MiddleMapElementNotKeyComponentMapper(String propertyName) { diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapKeyIdComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapKeyIdComponentMapper.java index a71c831380..3c985e639b 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapKeyIdComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapKeyIdComponentMapper.java @@ -22,7 +22,7 @@ import org.hibernate.envers.internal.tools.query.Parameters; * @author Adam Warski (adam at warski dot org) * @author Chris Cranford */ -public final class MiddleMapKeyIdComponentMapper implements MiddleComponentMapper { +public final class MiddleMapKeyIdComponentMapper extends AbstractMiddleComponentMapper { private final Configuration configuration; private final IdMapper relatedIdMapper; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapKeyPropertyComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapKeyPropertyComponentMapper.java index 461c5a8cb6..da66804a01 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapKeyPropertyComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleMapKeyPropertyComponentMapper.java @@ -6,15 +6,11 @@ */ package org.hibernate.envers.internal.entities.mapper.relation.component; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Map; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.envers.internal.entities.EntityInstantiator; -import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.envers.internal.tools.query.Parameters; -import org.hibernate.property.access.spi.Getter; /** * A component mapper for the @MapKey mapping with the name parameter specified: the value of the map's key @@ -23,7 +19,7 @@ import org.hibernate.property.access.spi.Getter; * * @author Adam Warski (adam at warski dot org) */ -public class MiddleMapKeyPropertyComponentMapper implements MiddleComponentMapper { +public class MiddleMapKeyPropertyComponentMapper extends AbstractMiddleComponentMapper { private final String propertyName; private final String accessType; @@ -39,19 +35,11 @@ public class MiddleMapKeyPropertyComponentMapper implements MiddleComponentMappe final Object dataObject, Number revision) { // dataObject is not null, as this mapper can only be used in an index. - return AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Object run() { - final Getter getter = ReflectionTools.getGetter( - dataObject.getClass(), - propertyName, - accessType, - entityInstantiator.getEnversService().getServiceRegistry() - ); - return getter.get( dataObject ); - } - } + return getValueFromObject( + propertyName, + accessType, + dataObject, + entityInstantiator.getEnversService().getServiceRegistry() ); } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleRelatedComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleRelatedComponentMapper.java index c551bdc52f..1a07539eba 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleRelatedComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleRelatedComponentMapper.java @@ -16,7 +16,7 @@ import org.hibernate.envers.internal.tools.query.Parameters; /** * @author Adam Warski (adam at warski dot org) */ -public final class MiddleRelatedComponentMapper implements MiddleComponentMapper { +public final class MiddleRelatedComponentMapper extends AbstractMiddleComponentMapper { private final MiddleIdData relatedIdData; public MiddleRelatedComponentMapper(MiddleIdData relatedIdData) { diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleSimpleComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleSimpleComponentMapper.java index c4d80c1df7..79e0b0dffa 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleSimpleComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleSimpleComponentMapper.java @@ -17,7 +17,7 @@ import org.hibernate.envers.internal.tools.query.Parameters; * @author Adam Warski (adam at warski dot org) * @author Chris Cranford */ -public final class MiddleSimpleComponentMapper implements MiddleComponentMapper { +public final class MiddleSimpleComponentMapper extends AbstractMiddleComponentMapper { private final Configuration configuration; private final String propertyName; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleStraightComponentMapper.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleStraightComponentMapper.java index 9f81fce69c..5f4e24a661 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleStraightComponentMapper.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/component/MiddleStraightComponentMapper.java @@ -18,7 +18,7 @@ import org.hibernate.envers.internal.tools.query.Parameters; * * @author Adam Warski (adam at warski dot org) */ -public final class MiddleStraightComponentMapper implements MiddleComponentMapper { +public final class MiddleStraightComponentMapper extends AbstractMiddleComponentMapper { private final String propertyName; public MiddleStraightComponentMapper(String propertyName) { diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/AbstractCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/AbstractCollectionInitializor.java index 65c9d44f01..62d15404d1 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/AbstractCollectionInitializor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/AbstractCollectionInitializor.java @@ -6,13 +6,20 @@ */ package org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.List; +import java.util.function.Supplier; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.envers.boot.internal.EnversService; +import org.hibernate.envers.exception.AuditException; import org.hibernate.envers.internal.entities.EntityInstantiator; import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; import org.hibernate.envers.internal.reader.AuditReaderImplementor; +import org.hibernate.internal.util.ReflectHelper; /** * Initializes a persistent collection. @@ -58,4 +65,43 @@ public abstract class AbstractCollectionInitializor implements Initializor return collection; } + + /** + * Perform an action in a privileged block. + * + * @param block the lambda to executed in privileged. + * @param the return type + * @return the result of the privileged call, may be {@literal null} + */ + protected R doPrivileged(Supplier block) { + if ( System.getSecurityManager() != null ) { + return AccessController.doPrivileged( (PrivilegedAction) block::get ); + } + else { + return block.get(); + } + } + + /** + * Creates a new object based on the specified class with the given constructor arguments. + * + * @param clazz the class, must not be {@literal null} + * @param args the variadic constructor arguments, may be omitted. + * @param the return class type + * @return a new instance of the class + */ + protected R newObjectInstance(Class clazz, Object... args) { + return doPrivileged( () -> { + try { + final Constructor constructor = ReflectHelper.getDefaultConstructor( clazz ); + if ( constructor == null ) { + throw new AuditException( "Failed to locate default constructor for class: " + clazz.getName() ); + } + return constructor.newInstance( args ); + } + catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new AuditException( e ); + } + } ); + } } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/BasicCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/BasicCollectionInitializor.java index 77e490ae58..d2d5458ff8 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/BasicCollectionInitializor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/BasicCollectionInitializor.java @@ -6,19 +6,14 @@ */ package org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor; -import java.lang.reflect.InvocationTargetException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Collection; import java.util.List; import java.util.Map; import org.hibernate.envers.boot.internal.EnversService; -import org.hibernate.envers.exception.AuditException; import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; import org.hibernate.envers.internal.reader.AuditReaderImplementor; -import org.hibernate.internal.util.ReflectHelper; /** * Initializes a non-indexed java collection (set or list, eventually sorted). @@ -45,25 +40,7 @@ public class BasicCollectionInitializor extends AbstractCo @Override @SuppressWarnings("unchecked") protected T initializeCollection(int size) { - return AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public T run() { - try { - return (T) ReflectHelper.getDefaultConstructor( collectionClass ).newInstance(); - } - catch (InstantiationException e) { - throw new AuditException( e ); - } - catch (IllegalAccessException e) { - throw new AuditException( e ); - } - catch (InvocationTargetException e) { - throw new AuditException( e ); - } - } - } - ); + return newObjectInstance( collectionClass ); } @Override diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/MapCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/MapCollectionInitializor.java index 7f54e4751a..b326bda06b 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/MapCollectionInitializor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/MapCollectionInitializor.java @@ -6,18 +6,13 @@ */ package org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor; -import java.lang.reflect.InvocationTargetException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.List; import java.util.Map; import org.hibernate.envers.boot.internal.EnversService; -import org.hibernate.envers.exception.AuditException; import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData; import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; import org.hibernate.envers.internal.reader.AuditReaderImplementor; -import org.hibernate.internal.util.ReflectHelper; /** * Initializes a map. @@ -47,25 +42,7 @@ public class MapCollectionInitializor extends AbstractCollectionI @Override @SuppressWarnings("unchecked") protected T initializeCollection(int size) { - return AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public T run() { - try { - return (T) ReflectHelper.getDefaultConstructor( collectionClass ).newInstance(); - } - catch (InstantiationException e) { - throw new AuditException( e ); - } - catch (IllegalAccessException e) { - throw new AuditException( e ); - } - catch (InvocationTargetException e) { - throw new AuditException( e ); - } - } - } - ); + return newObjectInstance( collectionClass ); } @Override diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/SortedMapCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/SortedMapCollectionInitializor.java index c91d1ecb9e..48f1962059 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/SortedMapCollectionInitializor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/SortedMapCollectionInitializor.java @@ -51,21 +51,23 @@ public class SortedMapCollectionInitializor extends MapCollectionInitializor { + try { + return collectionClass.getConstructor( Comparator.class ).newInstance( comparator ); + } + catch (InstantiationException e) { + throw new AuditException( e ); + } + catch (IllegalAccessException e) { + throw new AuditException( e ); + } + catch (NoSuchMethodException e) { + throw new AuditException( e ); + } + catch (InvocationTargetException e) { + throw new AuditException( e ); + } + } ); } } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/SortedSetCollectionInitializor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/SortedSetCollectionInitializor.java index a074fa04ed..1aae06eaec 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/SortedSetCollectionInitializor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/initializor/SortedSetCollectionInitializor.java @@ -52,20 +52,22 @@ public class SortedSetCollectionInitializor extends BasicCollectionInitializor { + try { + return collectionClass.getConstructor( Comparator.class ).newInstance(comparator); + } + catch (InstantiationException e) { + throw new AuditException( e ); + } + catch (IllegalAccessException e) { + throw new AuditException( e ); + } + catch (NoSuchMethodException e) { + throw new AuditException( e ); + } + catch (InvocationTargetException e) { + throw new AuditException( e ); + } + } ); } }