HHH-10511 - drop EnhancedGetterMethod: use GetterMethod / GetterField instead

This commit is contained in:
barreiro 2016-03-23 18:34:06 +00:00 committed by Gail Badner
parent a24eecf7da
commit 5c567bb4bf
3 changed files with 20 additions and 215 deletions

View File

@ -12,10 +12,10 @@ import java.lang.reflect.Method;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.property.access.spi.EnhancedGetterMethodImpl;
import org.hibernate.property.access.spi.EnhancedSetterMethodImpl;
import org.hibernate.property.access.spi.EnhancedSetterImpl;
import org.hibernate.property.access.spi.Getter;
import org.hibernate.property.access.spi.GetterFieldImpl;
import org.hibernate.property.access.spi.GetterMethodImpl;
import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.property.access.spi.PropertyAccessBuildingException;
import org.hibernate.property.access.spi.PropertyAccessStrategy;
@ -23,9 +23,8 @@ import org.hibernate.property.access.spi.Setter;
import org.hibernate.property.access.spi.SetterFieldImpl;
/**
* A PropertyAccess for byte code enhanced entities. Enhanced getter / setter methods ( if available ) are used for
* field access. Regular getter / setter methods are used for property access. In both cases, delegates calls to
* EnhancedMethodGetterImpl / EnhancedMethodGetterImpl. Based upon PropertyAccessMixedImpl.
* A PropertyAccess for byte code enhanced entities. Enhanced setter methods ( if available ) are used for
* property writes. Regular getter methods/fields are used for property access. Based upon PropertyAccessMixedImpl.
*
* @author Steve Ebersole
* @author Luis Barreiro
@ -45,39 +44,24 @@ public class PropertyAccessEnhancedImpl implements PropertyAccess {
final Field field = fieldOrNull( containerJavaType, propertyName );
final Method getterMethod = getterMethodOrNull( containerJavaType, propertyName );
final Class propertyJavaType;
// need one of field or getterMethod to be non-null
if ( field == null && getterMethod == null ) {
String msg = String.format( "Could not locate field nor getter method for property named [%s#%s]",
containerJavaType.getName(),
propertyName );
throw new PropertyAccessBuildingException( msg );
throw new PropertyAccessBuildingException(
String.format(
"Could not locate field for property [%s] on bytecode-enhanced Class [%s]",
propertyName,
containerJavaType.getName()
)
);
}
else if ( field != null ) {
propertyJavaType = field.getType();
this.getter = resolveGetterForField( containerJavaType, propertyName, field );
this.getter = new GetterFieldImpl( containerJavaType, propertyName, field );
}
else {
propertyJavaType = getterMethod.getReturnType();
this.getter = new EnhancedGetterMethodImpl( containerJavaType, propertyName, getterMethod );
this.getter = new GetterMethodImpl( containerJavaType, propertyName, getterMethod );
}
final Method setterMethod = setterMethodOrNull( containerJavaType, propertyName, propertyJavaType );
// need one of field or setterMethod to be non-null
if ( field == null && setterMethod == null ) {
String msg = String.format( "Could not locate field nor getter method for property named [%s#%s]",
containerJavaType.getName(),
propertyName );
throw new PropertyAccessBuildingException( msg );
}
else if ( field != null ) {
this.setter = resolveSetterForField( containerJavaType, propertyName, field );
}
else {
this.setter = new EnhancedSetterMethodImpl( containerJavaType, propertyName, setterMethod );
}
this.setter = resolveEnhancedSetterForField( containerJavaType, propertyName, field );
}
private static Field fieldOrNull(Class containerJavaType, String propertyName) {
@ -98,36 +82,12 @@ public class PropertyAccessEnhancedImpl implements PropertyAccess {
}
}
private static Method setterMethodOrNull(Class containerJavaType, String propertyName, Class propertyJavaType) {
try {
return ReflectHelper.findSetterMethod( containerJavaType, propertyName, propertyJavaType );
}
catch (PropertyNotFoundException e) {
return null;
}
}
//
private static Getter resolveGetterForField(Class<?> containerClass, String propertyName, Field field) {
try {
String enhancedGetterName = EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX + propertyName;
Method enhancedGetter = containerClass.getDeclaredMethod( enhancedGetterName );
enhancedGetter.setAccessible( true );
return new EnhancedGetterMethodImpl( containerClass, propertyName, enhancedGetter );
}
catch (NoSuchMethodException e) {
// enhancedGetter = null --- field not enhanced: fallback to reflection using the field
return new GetterFieldImpl( containerClass, propertyName, field );
}
}
private static Setter resolveSetterForField(Class<?> containerClass, String propertyName, Field field) {
private static Setter resolveEnhancedSetterForField(Class<?> containerClass, String propertyName, Field field) {
try {
String enhancedSetterName = EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX + propertyName;
Method enhancedSetter = containerClass.getDeclaredMethod( enhancedSetterName, field.getType() );
enhancedSetter.setAccessible( true );
return new EnhancedSetterMethodImpl( containerClass, propertyName, enhancedSetter );
return new EnhancedSetterImpl( containerClass, propertyName, enhancedSetter );
}
catch (NoSuchMethodException e) {
// enhancedSetter = null --- field not enhanced: fallback to reflection using the field

View File

@ -1,155 +0,0 @@
/*
* 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.property.access.spi;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.Map;
import org.hibernate.PropertyAccessException;
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoader;
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.CoreMessageLogger;
import static org.hibernate.internal.CoreLogging.messageLogger;
/**
* @author Steve Ebersole
*/
public class EnhancedGetterMethodImpl implements Getter {
private static final Object[] EMPTY = new Object[0];
private static final CoreMessageLogger LOG = messageLogger( EnhancedGetterMethodImpl.class );
private final Class containerClass;
private final String propertyName;
private final Method getterMethod;
public EnhancedGetterMethodImpl(Class containerClass, String propertyName, Method getterMethod) {
this.containerClass = containerClass;
this.propertyName = propertyName;
this.getterMethod = getterMethod;
}
private boolean isAttributeLoaded(Object owner) {
if ( owner instanceof PersistentAttributeInterceptable ) {
PersistentAttributeInterceptor interceptor = ( (PersistentAttributeInterceptable) owner ).$$_hibernate_getInterceptor();
if ( interceptor != null && interceptor instanceof LazyAttributeLoader ) {
return ( (LazyAttributeLoader) interceptor ).isAttributeLoaded( propertyName );
}
}
return true;
}
@Override
public Object get(Object owner) {
try {
// We don't want to trigger lazy loading of byte code enhanced attributes
if ( isAttributeLoaded( owner ) ) {
return getterMethod.invoke( owner, EMPTY );
}
return null;
}
catch (InvocationTargetException ite) {
throw new PropertyAccessException(
ite,
"Exception occurred inside",
false,
containerClass,
propertyName
);
}
catch (IllegalAccessException iae) {
throw new PropertyAccessException(
iae,
"IllegalAccessException occurred while calling",
false,
containerClass,
propertyName
);
//cannot occur
}
catch (IllegalArgumentException iae) {
LOG.illegalPropertyGetterArgument( containerClass.getName(), propertyName );
throw new PropertyAccessException(
iae,
"IllegalArgumentException occurred calling",
false,
containerClass,
propertyName
);
}
}
@Override
public Object getForInsert(Object owner, Map mergeMap, SessionImplementor session) {
return get( owner );
}
@Override
public Class getReturnType() {
return getterMethod.getReturnType();
}
@Override
public Member getMember() {
return getterMethod;
}
@Override
public String getMethodName() {
return getterMethod.getName();
}
@Override
public Method getMethod() {
return getterMethod;
}
private Object writeReplace() throws ObjectStreamException {
return new SerialForm( containerClass, propertyName, getterMethod );
}
private static class SerialForm implements Serializable {
private final Class containerClass;
private final String propertyName;
private final Class declaringClass;
private final String methodName;
private SerialForm(Class containerClass, String propertyName, Method method) {
this.containerClass = containerClass;
this.propertyName = propertyName;
this.declaringClass = method.getDeclaringClass();
this.methodName = method.getName();
}
private Object readResolve() {
return new EnhancedGetterMethodImpl( containerClass, propertyName, resolveMethod() );
}
@SuppressWarnings("unchecked")
private Method resolveMethod() {
try {
return declaringClass.getDeclaredMethod( methodName );
}
catch (NoSuchMethodException e) {
throw new PropertyAccessSerializationException(
"Unable to resolve getter method on deserialization : " + declaringClass.getName() + "#" + methodName
);
}
}
}
}

View File

@ -22,8 +22,8 @@ import static org.hibernate.internal.CoreLogging.messageLogger;
/**
* @author Steve Ebersole
*/
public class EnhancedSetterMethodImpl implements Setter {
private static final CoreMessageLogger LOG = messageLogger( EnhancedSetterMethodImpl.class );
public class EnhancedSetterImpl implements Setter {
private static final CoreMessageLogger LOG = messageLogger( EnhancedSetterImpl.class );
private final Class containerClass;
private final String propertyName;
@ -31,7 +31,7 @@ public class EnhancedSetterMethodImpl implements Setter {
private final boolean isPrimitive;
public EnhancedSetterMethodImpl(Class containerClass, String propertyName, Method setterMethod) {
public EnhancedSetterImpl(Class containerClass, String propertyName, Method setterMethod) {
this.containerClass = containerClass;
this.propertyName = propertyName;
this.setterMethod = setterMethod;
@ -153,7 +153,7 @@ public class EnhancedSetterMethodImpl implements Setter {
}
private Object readResolve() {
return new EnhancedSetterMethodImpl( containerClass, propertyName, resolveMethod() );
return new EnhancedSetterImpl( containerClass, propertyName, resolveMethod() );
}
@SuppressWarnings("unchecked")