HHH-13361 Refactor mappers

This commit is contained in:
Chris Cranford 2021-12-18 18:50:36 -05:00 committed by Chris Cranford
parent b5755b6945
commit aa5bdab6ec
26 changed files with 463 additions and 529 deletions

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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 <T> the return type
* @return the result of the privileged call, may be {@literal null}
*/
protected <T> T doPrivileged(Supplier<T> block) {
if ( System.getSecurityManager() != null ) {
return AccessController.doPrivileged( (PrivilegedAction<T>) 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 <T> the return type
* @return the value read from the object, may be {@literal null}
*/
@SuppressWarnings("unchecked")
protected <T> 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 <T> the return type
* @return the value read from the object, may be {@literal null}
*/
@SuppressWarnings("unchecked")
protected <T> 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 <T> the return class type
* @return a new instance of the class
*/
protected <T> T newObjectInstance(Class<T> clazz, Object... args) {
return doPrivileged( () -> {
try {
final Constructor<T> 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 );
}
} );
}
}

View File

@ -11,7 +11,7 @@
* *
* @author Chris Cranford * @author Chris Cranford
*/ */
public abstract class AbstractPropertyMapper implements PropertyMapper { public abstract class AbstractPropertyMapper extends AbstractMapper implements PropertyMapper {
private boolean map; private boolean map;
@Override @Override

View File

@ -7,8 +7,6 @@
package org.hibernate.envers.internal.entities.mapper; package org.hibernate.envers.internal.entities.mapper;
import java.io.Serializable; import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -118,10 +116,7 @@ public void mapToEntityFromMap(
return; return;
} }
AccessController.doPrivileged( doPrivileged( () -> {
new PrivilegedAction<Object>() {
@Override
public Object run() {
try { try {
final Object subObj = ReflectHelper.getDefaultConstructor( componentClass ).newInstance(); final Object subObj = ReflectHelper.getDefaultConstructor( componentClass ).newInstance();
@ -152,9 +147,7 @@ public Object run() {
} }
return null; return null;
} } );
}
);
} }
private boolean isAllPropertiesNull(Map data) { private boolean isAllPropertiesNull(Map data) {

View File

@ -7,8 +7,6 @@
package org.hibernate.envers.internal.entities.mapper; package org.hibernate.envers.internal.entities.mapper;
import java.io.Serializable; import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -101,10 +99,7 @@ public boolean mapToMapFromEntity(
final Map<String, Object> data, final Map<String, Object> data,
final Object newObj, final Object newObj,
final Object oldObj) { final Object oldObj) {
return AccessController.doPrivileged( return doPrivileged( () -> {
new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
boolean ret = false; boolean ret = false;
for ( Map.Entry<PropertyData, PropertyMapper> entry : properties.entrySet() ) { for ( Map.Entry<PropertyData, PropertyMapper> entry : properties.entrySet() ) {
final PropertyData propertyData = entry.getKey(); final PropertyData propertyData = entry.getKey();
@ -141,9 +136,7 @@ else if ( oldObj != null ) {
); );
} }
return ret; return ret;
} } );
}
);
} }
@Override @Override
@ -152,10 +145,7 @@ public void mapModifiedFlagsToMapFromEntity(
final Map<String, Object> data, final Map<String, Object> data,
final Object newObj, final Object newObj,
final Object oldObj) { final Object oldObj) {
AccessController.doPrivileged( doPrivileged( () -> {
new PrivilegedAction<Object>() {
@Override
public Object run() {
for ( Map.Entry<PropertyData, PropertyMapper> entry : properties.entrySet() ) { for ( Map.Entry<PropertyData, PropertyMapper> entry : properties.entrySet() ) {
final PropertyData propertyData = entry.getKey(); final PropertyData propertyData = entry.getKey();
final PropertyMapper propertyMapper = entry.getValue(); final PropertyMapper propertyMapper = entry.getValue();
@ -192,9 +182,7 @@ else if ( oldObj != null ) {
} }
return null; return null;
} } );
}
);
} }
@Override @Override

View File

@ -7,8 +7,6 @@
package org.hibernate.envers.internal.entities.mapper; package org.hibernate.envers.internal.entities.mapper;
import java.io.Serializable; import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -105,10 +103,7 @@ public void mapToEntityFromMap(
map.put( propertyData.getBeanName(), value ); map.put( propertyData.getBeanName(), value );
} }
else { else {
AccessController.doPrivileged( doPrivileged( () -> {
new PrivilegedAction<Object>() {
@Override
public Object run() {
final Setter setter = ReflectionTools.getSetter( final Setter setter = ReflectionTools.getSetter(
obj.getClass(), obj.getClass(),
propertyData, propertyData,
@ -121,9 +116,7 @@ public Object run() {
} }
return null; return null;
} } );
}
);
} }
} }

View File

@ -6,8 +6,6 @@
*/ */
package org.hibernate.envers.internal.entities.mapper.id; package org.hibernate.envers.internal.entities.mapper.id;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Map; import java.util.Map;
import org.hibernate.envers.exception.AuditException; import org.hibernate.envers.exception.AuditException;
@ -66,18 +64,13 @@ public void mapToEntityFromEntity(Object objectTo, Object objectFrom) {
} }
protected Object instantiateCompositeId() { protected Object instantiateCompositeId() {
return AccessController.doPrivileged( return doPrivileged( () -> {
new PrivilegedAction<Object>() {
@Override
public Object run() {
try { try {
return ReflectHelper.getDefaultConstructor( compositeIdClass ).newInstance(); return ReflectHelper.getDefaultConstructor( compositeIdClass ).newInstance();
} }
catch ( Exception e ) { catch ( Exception e ) {
throw new AuditException( e ); throw new AuditException( e );
} }
} } );
}
);
} }
} }

View File

@ -9,6 +9,8 @@
import java.util.Iterator; import java.util.Iterator;
import java.util.List; 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.envers.internal.tools.query.Parameters;
import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistry;
@ -18,7 +20,7 @@
* @author Adam Warski (adam at warski dot org) * @author Adam Warski (adam at warski dot org)
* @author Chris Cranford * @author Chris Cranford
*/ */
public abstract class AbstractIdMapper implements IdMapper { public abstract class AbstractIdMapper extends AbstractMapper implements IdMapper {
private final ServiceRegistry serviceRegistry; private final ServiceRegistry serviceRegistry;
public AbstractIdMapper(ServiceRegistry serviceRegistry) { public AbstractIdMapper(ServiceRegistry serviceRegistry) {
@ -143,6 +145,18 @@ public void addNamedIdEqualsToQuery(Parameters parameters, String prefix1, IdMap
public abstract void mapToEntityFromEntity(Object objectTo, Object objectFrom); public abstract void mapToEntityFromEntity(Object objectTo, Object objectFrom);
protected <T> 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) { private void handleNullValue(Parameters parameters, String alias, String propertyName, boolean equals) {
if ( equals ) { if ( equals ) {
parameters.addNullRestriction( alias, propertyName ); parameters.addNullRestriction( alias, propertyName );

View File

@ -6,8 +6,6 @@
*/ */
package org.hibernate.envers.internal.entities.mapper.id; package org.hibernate.envers.internal.entities.mapper.id;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
@ -17,7 +15,6 @@
import org.hibernate.envers.internal.entities.PropertyData; import org.hibernate.envers.internal.entities.PropertyData;
import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.envers.internal.tools.ReflectionTools;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.property.access.spi.Getter;
import org.hibernate.property.access.spi.Setter; import org.hibernate.property.access.spi.Setter;
import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistry;
@ -52,22 +49,7 @@ public void mapToMapFromEntity(Map<String, Object> data, final Object obj) {
if ( obj == null ) { if ( obj == null ) {
return; return;
} }
mapToMapFromId( data, getValueFromObject( idPropertyData, obj ) );
final Object value = AccessController.doPrivileged(
new PrivilegedAction<Object>() {
@Override
public Object run() {
final Getter getter = ReflectionTools.getGetter(
obj.getClass(),
idPropertyData,
getServiceRegistry()
);
return getter.get( obj );
}
}
);
mapToMapFromId( data, value );
} }
@Override @Override
@ -76,12 +58,8 @@ public boolean mapToEntityFromMap(final Object obj, final Map data) {
return false; return false;
} }
return AccessController.doPrivileged( return doPrivileged( () -> {
new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
final Setter setter = ReflectionTools.getSetter( obj.getClass(), idPropertyData, getServiceRegistry() ); final Setter setter = ReflectionTools.getSetter( obj.getClass(), idPropertyData, getServiceRegistry() );
try { try {
final Object subObj = instantiateCompositeId(); final Object subObj = instantiateCompositeId();
@ -99,9 +77,7 @@ public Boolean run() {
catch (Exception e) { catch (Exception e) {
throw new AuditException( e ); throw new AuditException( e );
} }
} } );
}
);
} }
@Override @Override
@ -122,19 +98,7 @@ public Object mapToIdFromEntity(final Object data) {
return null; return null;
} }
return AccessController.doPrivileged( return getValueFromObject( idPropertyData, data );
new PrivilegedAction<Object>() {
@Override
public Object run() {
final Getter getter = ReflectionTools.getGetter(
data.getClass(),
idPropertyData,
getServiceRegistry()
);
return getter.get( data );
}
}
);
} }
@Override @Override

View File

@ -6,17 +6,12 @@
*/ */
package org.hibernate.envers.internal.entities.mapper.id; package org.hibernate.envers.internal.entities.mapper.id;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.hibernate.envers.exception.AuditException; import org.hibernate.envers.exception.AuditException;
import org.hibernate.envers.internal.entities.PropertyData; 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.proxy.HibernateProxy;
import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistry;
@ -63,21 +58,9 @@ public boolean mapToEntityFromMap(final Object obj, Map data) {
return false; return false;
} }
return AccessController.doPrivileged( setValueOnObject( propertyData, obj, value );
new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
final Setter setter = ReflectionTools.getSetter(
obj.getClass(),
propertyData,
getServiceRegistry()
);
setter.set( obj, value );
return true; return true;
} }
}
);
}
@Override @Override
public Object mapToIdFromMap(Map data) { public Object mapToIdFromMap(Map data) {
@ -99,19 +82,7 @@ public Object mapToIdFromEntity(final Object data) {
return hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier(); return hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier();
} }
else { else {
return AccessController.doPrivileged( return getValueFromObject( propertyData, data );
new PrivilegedAction<Object>() {
@Override
public Object run() {
final Getter getter = ReflectionTools.getGetter(
data.getClass(),
propertyData,
getServiceRegistry()
);
return getter.get( data );
}
}
);
} }
} }
@ -133,19 +104,7 @@ public void mapToMapFromEntity(Map<String, Object> data, final Object obj) {
data.put( propertyData.getName(), hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier() ); data.put( propertyData.getName(), hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier() );
} }
else { else {
final Object value = AccessController.doPrivileged( final Object value = getValueFromObject( propertyData, obj );
new PrivilegedAction<Object>() {
@Override
public Object run() {
final Getter getter = ReflectionTools.getGetter(
obj.getClass(),
propertyData,
getServiceRegistry()
);
return getter.get( obj );
}
}
);
data.put( propertyData.getName(), value ); data.put( propertyData.getName(), value );
} }
} }
@ -156,28 +115,7 @@ public void mapToEntityFromEntity(final Object objTo, final Object objFrom) {
if ( objTo == null || objFrom == null ) { if ( objTo == null || objFrom == null ) {
return; return;
} }
getAndSetValue(propertyData, objFrom, objTo );
AccessController.doPrivileged(
new PrivilegedAction<Object>() {
@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;
}
}
);
} }
@Override @Override

View File

@ -6,9 +6,6 @@
*/ */
package org.hibernate.envers.internal.entities.mapper.id; 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 java.util.Map;
import org.hibernate.Session; import org.hibernate.Session;
@ -48,19 +45,7 @@ public VirtualEntitySingleIdMapper(ServiceRegistry serviceRegistry, PropertyData
@Override @Override
public void mapToMapFromId(Session session, Map<String, Object> data, Object obj) { public void mapToMapFromId(Session session, Map<String, Object> data, Object obj) {
final Serializable value = AccessController.doPrivileged( final Object value = getValueFromObject( propertyData, obj );
new PrivilegedAction<Serializable>() {
@Override
public Serializable run() {
final Getter getter = ReflectionTools.getGetter(
obj.getClass(),
propertyData,
getServiceRegistry()
);
return (Serializable) getter.get( obj );
}
}
);
// Either loads the entity from the session's 1LC if it already exists or potentially creates a // 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. // proxy object to represent the entity by identifier so that we can reference it in the map.
@ -74,10 +59,7 @@ public void mapToEntityFromEntity(Object objTo, Object objFrom) {
return; return;
} }
AccessController.doPrivileged( doPrivileged( () -> {
new PrivilegedAction<Object>() {
@Override
public Object run() {
final Getter getter = ReflectionTools.getGetter( final Getter getter = ReflectionTools.getGetter(
objFrom.getClass(), objFrom.getClass(),
propertyData, propertyData,
@ -105,9 +87,7 @@ public Object run() {
} }
return null; return null;
} } );
}
);
} }
@Override @Override
@ -121,10 +101,7 @@ public boolean mapToEntityFromMap(Object obj, Map data) {
return false; return false;
} }
return AccessController.doPrivileged( return doPrivileged( () -> {
new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
final Setter setter = ReflectionTools.getSetter( final Setter setter = ReflectionTools.getSetter(
obj.getClass(), obj.getClass(),
propertyData, propertyData,
@ -144,9 +121,7 @@ public Boolean run() {
} }
return true; return true;
} } );
}
);
} }
@Override @Override
@ -160,19 +135,7 @@ public void mapToMapFromEntity(Map<String, Object> data, Object obj) {
data.put( propertyData.getName(), proxy.getHibernateLazyInitializer().getInternalIdentifier() ); data.put( propertyData.getName(), proxy.getHibernateLazyInitializer().getInternalIdentifier() );
} }
else { else {
final Object value = AccessController.doPrivileged( final Object value = getValueFromObject( propertyData, obj );
new PrivilegedAction<Object>() {
@Override
public Object run() {
final Getter getter = ReflectionTools.getGetter(
obj.getClass(),
propertyData,
getServiceRegistry()
);
return getter.get( obj );
}
}
);
if ( propertyData.getVirtualReturnClass().isInstance( value ) ) { if ( propertyData.getVirtualReturnClass().isInstance( value ) ) {
// The value is the primary key, need to map it via IdMapper // The value is the primary key, need to map it via IdMapper

View File

@ -8,8 +8,6 @@
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -30,9 +28,7 @@
import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData; import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData;
import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor; import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor;
import org.hibernate.envers.internal.reader.AuditReaderImplementor; import org.hibernate.envers.internal.reader.AuditReaderImplementor;
import org.hibernate.envers.internal.tools.ReflectionTools;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.property.access.spi.Setter;
/** /**
* @author Adam Warski (adam at warski dot org) * @author Adam Warski (adam at warski dot org)
@ -306,22 +302,7 @@ public void mapToEntityFromMap(
map.put( collectionPropertyData.getBeanName(), collectionProxy ); map.put( collectionPropertyData.getBeanName(), collectionProxy );
} }
else { else {
AccessController.doPrivileged( setValueOnObject( collectionPropertyData, obj, collectionProxy, enversService.getServiceRegistry() );
new PrivilegedAction<Object>() {
@Override
public Object run() {
final Setter setter = ReflectionTools.getSetter(
obj.getClass(),
collectionPropertyData,
enversService.getServiceRegistry()
);
setter.set( obj, collectionProxy );
return null;
}
}
);
} }
} }

View File

@ -7,8 +7,6 @@
package org.hibernate.envers.internal.entities.mapper.relation; package org.hibernate.envers.internal.entities.mapper.relation;
import java.io.Serializable; import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -21,7 +19,6 @@
import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData; import org.hibernate.envers.internal.entities.mapper.PersistentCollectionChangeData;
import org.hibernate.envers.internal.reader.AuditReaderImplementor; import org.hibernate.envers.internal.reader.AuditReaderImplementor;
import org.hibernate.envers.internal.tools.ReflectionTools; import org.hibernate.envers.internal.tools.ReflectionTools;
import org.hibernate.property.access.spi.Setter;
import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistry;
/** /**
@ -96,21 +93,7 @@ protected void setPropertyValue(Object targetObject, Object value) {
map.put( propertyData.getBeanName(), value ); map.put( propertyData.getBeanName(), value );
} }
else { else {
AccessController.doPrivileged( setValueOnObject( propertyData, targetObject, value, serviceRegistry );
new PrivilegedAction<Object>() {
@Override
public Object run() {
final Setter setter = ReflectionTools.getSetter(
targetObject.getClass(),
propertyData,
serviceRegistry
);
setter.set( targetObject, value );
return null;
}
}
);
} }
} }

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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 {
}

View File

@ -15,7 +15,7 @@
/** /**
* @author Adam Warski (adam at warski dot org) * @author Adam Warski (adam at warski dot org)
*/ */
public final class MiddleDummyComponentMapper implements MiddleComponentMapper { public final class MiddleDummyComponentMapper extends AbstractMiddleComponentMapper {
public Object mapToObjectFromFullMap( public Object mapToObjectFromFullMap(
EntityInstantiator entityInstantiator, Map<String, Object> data, EntityInstantiator entityInstantiator, Map<String, Object> data,
Object dataObject, Number revision) { Object dataObject, Number revision) {

View File

@ -6,9 +6,6 @@
*/ */
package org.hibernate.envers.internal.entities.mapper.relation.component; 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 java.util.Map;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
@ -20,16 +17,16 @@
import org.hibernate.envers.internal.entities.mapper.PropertyMapper; import org.hibernate.envers.internal.entities.mapper.PropertyMapper;
import org.hibernate.envers.internal.entities.mapper.relation.ToOneIdMapper; import org.hibernate.envers.internal.entities.mapper.relation.ToOneIdMapper;
import org.hibernate.envers.internal.tools.query.Parameters; import org.hibernate.envers.internal.tools.query.Parameters;
import org.hibernate.internal.util.ReflectHelper;
/** /**
* @author Kristoffer Lundberg (kristoffer at cambio dot se) * @author Kristoffer Lundberg (kristoffer at cambio dot se)
*/ */
public class MiddleEmbeddableComponentMapper implements MiddleComponentMapper, CompositeMapperBuilder { public class MiddleEmbeddableComponentMapper extends AbstractMiddleComponentMapper implements CompositeMapperBuilder {
private final MultiPropertyMapper delegate;
private final Class componentClass;
public MiddleEmbeddableComponentMapper(MultiPropertyMapper delegate, Class componentClass) { private final MultiPropertyMapper delegate;
private final Class<?> componentClass;
public MiddleEmbeddableComponentMapper(MultiPropertyMapper delegate, Class<?> componentClass) {
this.delegate = delegate; this.delegate = delegate;
this.componentClass = componentClass; this.componentClass = componentClass;
} }
@ -65,26 +62,7 @@ private Object getComponentInstance(Object dataObject) {
if ( dataObject != null ) { if ( dataObject != null ) {
return dataObject; return dataObject;
} }
return newObjectInstance( componentClass );
return AccessController.doPrivileged(
new PrivilegedAction<Object>() {
@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 );
}
}
}
);
} }
@Override @Override

View File

@ -28,7 +28,7 @@
* *
* @author Chris Cranford * @author Chris Cranford
*/ */
public class MiddleMapElementNotKeyComponentMapper implements MiddleComponentMapper { public class MiddleMapElementNotKeyComponentMapper extends AbstractMiddleComponentMapper {
private final String propertyName; private final String propertyName;
public MiddleMapElementNotKeyComponentMapper(String propertyName) { public MiddleMapElementNotKeyComponentMapper(String propertyName) {

View File

@ -22,7 +22,7 @@
* @author Adam Warski (adam at warski dot org) * @author Adam Warski (adam at warski dot org)
* @author Chris Cranford * @author Chris Cranford
*/ */
public final class MiddleMapKeyIdComponentMapper implements MiddleComponentMapper { public final class MiddleMapKeyIdComponentMapper extends AbstractMiddleComponentMapper {
private final Configuration configuration; private final Configuration configuration;
private final IdMapper relatedIdMapper; private final IdMapper relatedIdMapper;

View File

@ -6,15 +6,11 @@
*/ */
package org.hibernate.envers.internal.entities.mapper.relation.component; package org.hibernate.envers.internal.entities.mapper.relation.component;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Map; import java.util.Map;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.envers.internal.entities.EntityInstantiator; 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.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 * A component mapper for the @MapKey mapping with the name parameter specified: the value of the map's key
@ -23,7 +19,7 @@
* *
* @author Adam Warski (adam at warski dot org) * @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 propertyName;
private final String accessType; private final String accessType;
@ -39,20 +35,12 @@ public Object mapToObjectFromFullMap(
final Object dataObject, final Object dataObject,
Number revision) { Number revision) {
// dataObject is not null, as this mapper can only be used in an index. // dataObject is not null, as this mapper can only be used in an index.
return AccessController.doPrivileged( return getValueFromObject(
new PrivilegedAction<Object>() {
@Override
public Object run() {
final Getter getter = ReflectionTools.getGetter(
dataObject.getClass(),
propertyName, propertyName,
accessType, accessType,
dataObject,
entityInstantiator.getEnversService().getServiceRegistry() entityInstantiator.getEnversService().getServiceRegistry()
); );
return getter.get( dataObject );
}
}
);
} }
@Override @Override

View File

@ -16,7 +16,7 @@
/** /**
* @author Adam Warski (adam at warski dot org) * @author Adam Warski (adam at warski dot org)
*/ */
public final class MiddleRelatedComponentMapper implements MiddleComponentMapper { public final class MiddleRelatedComponentMapper extends AbstractMiddleComponentMapper {
private final MiddleIdData relatedIdData; private final MiddleIdData relatedIdData;
public MiddleRelatedComponentMapper(MiddleIdData relatedIdData) { public MiddleRelatedComponentMapper(MiddleIdData relatedIdData) {

View File

@ -17,7 +17,7 @@
* @author Adam Warski (adam at warski dot org) * @author Adam Warski (adam at warski dot org)
* @author Chris Cranford * @author Chris Cranford
*/ */
public final class MiddleSimpleComponentMapper implements MiddleComponentMapper { public final class MiddleSimpleComponentMapper extends AbstractMiddleComponentMapper {
private final Configuration configuration; private final Configuration configuration;
private final String propertyName; private final String propertyName;

View File

@ -18,7 +18,7 @@
* *
* @author Adam Warski (adam at warski dot org) * @author Adam Warski (adam at warski dot org)
*/ */
public final class MiddleStraightComponentMapper implements MiddleComponentMapper { public final class MiddleStraightComponentMapper extends AbstractMiddleComponentMapper {
private final String propertyName; private final String propertyName;
public MiddleStraightComponentMapper(String propertyName) { public MiddleStraightComponentMapper(String propertyName) {

View File

@ -6,13 +6,20 @@
*/ */
package org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor; 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.List;
import java.util.function.Supplier;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.envers.boot.internal.EnversService; 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.EntityInstantiator;
import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator;
import org.hibernate.envers.internal.reader.AuditReaderImplementor; import org.hibernate.envers.internal.reader.AuditReaderImplementor;
import org.hibernate.internal.util.ReflectHelper;
/** /**
* Initializes a persistent collection. * Initializes a persistent collection.
@ -58,4 +65,43 @@ public T initialize() {
return collection; return collection;
} }
/**
* Perform an action in a privileged block.
*
* @param block the lambda to executed in privileged.
* @param <R> the return type
* @return the result of the privileged call, may be {@literal null}
*/
protected <R> R doPrivileged(Supplier<R> block) {
if ( System.getSecurityManager() != null ) {
return AccessController.doPrivileged( (PrivilegedAction<R>) 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 <R> the return class type
* @return a new instance of the class
*/
protected <R> R newObjectInstance(Class<R> clazz, Object... args) {
return doPrivileged( () -> {
try {
final Constructor<R> 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 );
}
} );
}
} }

View File

@ -6,19 +6,14 @@
*/ */
package org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor; 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.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.hibernate.envers.boot.internal.EnversService; 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.MiddleComponentData;
import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator;
import org.hibernate.envers.internal.reader.AuditReaderImplementor; import org.hibernate.envers.internal.reader.AuditReaderImplementor;
import org.hibernate.internal.util.ReflectHelper;
/** /**
* Initializes a non-indexed java collection (set or list, eventually sorted). * Initializes a non-indexed java collection (set or list, eventually sorted).
@ -45,25 +40,7 @@ public BasicCollectionInitializor(
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected T initializeCollection(int size) { protected T initializeCollection(int size) {
return AccessController.doPrivileged( return newObjectInstance( collectionClass );
new PrivilegedAction<T>() {
@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 );
}
}
}
);
} }
@Override @Override

View File

@ -6,18 +6,13 @@
*/ */
package org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor; 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.List;
import java.util.Map; import java.util.Map;
import org.hibernate.envers.boot.internal.EnversService; 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.MiddleComponentData;
import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator; import org.hibernate.envers.internal.entities.mapper.relation.query.RelationQueryGenerator;
import org.hibernate.envers.internal.reader.AuditReaderImplementor; import org.hibernate.envers.internal.reader.AuditReaderImplementor;
import org.hibernate.internal.util.ReflectHelper;
/** /**
* Initializes a map. * Initializes a map.
@ -47,25 +42,7 @@ public MapCollectionInitializor(
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected T initializeCollection(int size) { protected T initializeCollection(int size) {
return AccessController.doPrivileged( return newObjectInstance( collectionClass );
new PrivilegedAction<T>() {
@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 );
}
}
}
);
} }
@Override @Override

View File

@ -51,6 +51,7 @@ protected SortedMap initializeCollection(int size) {
if ( comparator == null ) { if ( comparator == null ) {
return super.initializeCollection( size ); return super.initializeCollection( size );
} }
return doPrivileged( () -> {
try { try {
return collectionClass.getConstructor( Comparator.class ).newInstance( comparator ); return collectionClass.getConstructor( Comparator.class ).newInstance( comparator );
} }
@ -66,6 +67,7 @@ protected SortedMap initializeCollection(int size) {
catch (InvocationTargetException e) { catch (InvocationTargetException e) {
throw new AuditException( e ); throw new AuditException( e );
} }
} );
} }
} }

View File

@ -52,8 +52,9 @@ protected SortedSet initializeCollection(int size) {
if ( comparator == null ) { if ( comparator == null ) {
return super.initializeCollection( size ); return super.initializeCollection( size );
} }
return doPrivileged( () -> {
try { try {
return collectionClass.getConstructor( Comparator.class ).newInstance( comparator ); return collectionClass.getConstructor( Comparator.class ).newInstance(comparator);
} }
catch (InstantiationException e) { catch (InstantiationException e) {
throw new AuditException( e ); throw new AuditException( e );
@ -67,5 +68,6 @@ protected SortedSet initializeCollection(int size) {
catch (InvocationTargetException e) { catch (InvocationTargetException e) {
throw new AuditException( e ); throw new AuditException( e );
} }
} );
} }
} }