From bf4e92fd0a98858fb831d4f3157eab6b50beb3da Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Fri, 10 Jun 2016 15:33:15 -0700 Subject: [PATCH] HHH-10511: Restore and deprecate org.hibernate.property.access.spi.EnhancedGetterMethodImpl and EnhancedSetterImpl to maintain backward-compatibility --- .../access/spi/EnhancedGetterMethodImpl.java | 158 ++++++++++++++++ .../access/spi/EnhancedSetterMethodImpl.java | 175 ++++++++++++++++++ 2 files changed, 333 insertions(+) create mode 100644 hibernate-core/src/main/java/org/hibernate/property/access/spi/EnhancedGetterMethodImpl.java create mode 100644 hibernate-core/src/main/java/org/hibernate/property/access/spi/EnhancedSetterMethodImpl.java diff --git a/hibernate-core/src/main/java/org/hibernate/property/access/spi/EnhancedGetterMethodImpl.java b/hibernate-core/src/main/java/org/hibernate/property/access/spi/EnhancedGetterMethodImpl.java new file mode 100644 index 0000000000..71dfcb1077 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/property/access/spi/EnhancedGetterMethodImpl.java @@ -0,0 +1,158 @@ +/* + * 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.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 + * + * @deprecated No longer used; {@link GetterFieldImpl} or {@link GetterMethodImpl} should be used instead. + */ +@Deprecated +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 + ); + } + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/property/access/spi/EnhancedSetterMethodImpl.java b/hibernate-core/src/main/java/org/hibernate/property/access/spi/EnhancedSetterMethodImpl.java new file mode 100644 index 0000000000..b802424f18 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/property/access/spi/EnhancedSetterMethodImpl.java @@ -0,0 +1,175 @@ +/* + * 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.property.access.spi; + +import java.io.ObjectStreamException; +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.hibernate.PropertyAccessException; +import org.hibernate.PropertySetterAccessException; +import org.hibernate.engine.spi.SelfDirtinessTracker; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.CoreMessageLogger; + +import static org.hibernate.internal.CoreLogging.messageLogger; + +/** + * @author Steve Ebersole + * + * @deprecated No longer used; {@link EnhancedSetterImpl} should be used instead. + */ +@Deprecated +public class EnhancedSetterMethodImpl implements Setter { + private static final CoreMessageLogger LOG = messageLogger( EnhancedSetterMethodImpl.class ); + + private final Class containerClass; + private final String propertyName; + private final Method setterMethod; + + private final boolean isPrimitive; + + public EnhancedSetterMethodImpl(Class containerClass, String propertyName, Method setterMethod) { + this.containerClass = containerClass; + this.propertyName = propertyName; + this.setterMethod = setterMethod; + this.isPrimitive = setterMethod.getParameterTypes()[0].isPrimitive(); + } + + @Override + public void set(Object target, Object value, SessionFactoryImplementor factory) { + try { + + // for enhanced attribute, don't flag as dirty + if ( target instanceof SelfDirtinessTracker ) { + ( (SelfDirtinessTracker) target ).$$_hibernate_suspendDirtyTracking( true ); + try { + setterMethod.invoke( target, value ); + } + finally { + ( (SelfDirtinessTracker) target ).$$_hibernate_suspendDirtyTracking( false ); + } + } + else { + setterMethod.invoke( target, value ); + } + + } + catch (NullPointerException npe) { + if ( value == null && isPrimitive ) { + throw new PropertyAccessException( + npe, + "Null value was assigned to a property of primitive type", + true, + containerClass, + propertyName + ); + } + else { + throw new PropertyAccessException( + npe, + "NullPointerException occurred while calling", + true, + containerClass, + propertyName + ); + } + } + catch (InvocationTargetException ite) { + throw new PropertyAccessException( + ite, + "Exception occurred inside", + true, + containerClass, + propertyName + ); + } + catch (IllegalAccessException iae) { + throw new PropertyAccessException( + iae, + "IllegalAccessException occurred while calling", + true, + containerClass, + propertyName + ); + //cannot occur + } + catch (IllegalArgumentException iae) { + if ( value == null && isPrimitive ) { + throw new PropertyAccessException( + iae, + "Null value was assigned to a property of primitive type", + true, + containerClass, + propertyName + ); + } + else { + final Class expectedType = setterMethod.getParameterTypes()[0]; + LOG.illegalPropertySetterArgument( containerClass.getName(), propertyName ); + LOG.expectedType( expectedType.getName(), value == null ? null : value.getClass().getName() ); + throw new PropertySetterAccessException( + iae, + containerClass, + propertyName, + expectedType, + target, + value + ); + } + } + } + + @Override + public String getMethodName() { + return setterMethod.getName(); + } + + @Override + public Method getMethod() { + return setterMethod; + } + + private Object writeReplace() throws ObjectStreamException { + return new SerialForm( containerClass, propertyName, setterMethod ); + } + + private static class SerialForm implements Serializable { + private final Class containerClass; + private final String propertyName; + + private final Class declaringClass; + private final String methodName; + private final Class argumentType; + + private SerialForm(Class containerClass, String propertyName, Method method) { + this.containerClass = containerClass; + this.propertyName = propertyName; + this.declaringClass = method.getDeclaringClass(); + this.methodName = method.getName(); + this.argumentType = method.getParameterTypes()[0]; + } + + private Object readResolve() { + return new EnhancedSetterMethodImpl( containerClass, propertyName, resolveMethod() ); + } + + @SuppressWarnings("unchecked") + private Method resolveMethod() { + try { + return declaringClass.getDeclaredMethod( methodName, argumentType ); + } + catch (NoSuchMethodException e) { + throw new PropertyAccessSerializationException( + "Unable to resolve setter method on deserialization : " + declaringClass.getName() + "#" + + methodName + "(" + argumentType.getName() + ")" + ); + } + } + } +}