From 67fb26b0be3d5bc6848608b59c26dd216befbaa8 Mon Sep 17 00:00:00 2001 From: daniel Date: Fri, 29 Jun 2018 11:20:31 +0800 Subject: [PATCH] =?UTF-8?q?druid=20spring=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fine-druid/pom.xml | 18 ++ .../stat/JdbcStatManagerFactoryBean.java | 2 +- .../SpringIbatisBeanNameAutoProxyCreator.java | 4 +- .../SpringIbatisBeanTypeAutoProxyCreator.java | 12 +- .../spring/MBeanServerFactoryBean.java | 2 +- .../spring/mvc/StatHandlerInterceptor.java | 10 +- .../spring/stat/BeanTypeAutoProxyCreator.java | 20 +-- .../spring/stat/DruidStatInterceptor.java | 10 +- .../annotation/StatAnnotationAdvisor.java | 14 +- .../StatAnnotationBeanPostProcessor.java | 8 +- .../config/DruidStatBeanDefinitionParser.java | 16 +- .../config/DruidStatNamespaceHandler.java | 2 +- fine-hibernate/pom.xml | 18 ++ .../access/spi/UnsafeGetterFieldImpl.java | 116 +++++++++++++ .../access/spi/UnsafeSetterMethodImpl.java | 160 ++++++++++++++++++ 15 files changed, 362 insertions(+), 50 deletions(-) create mode 100644 fine-druid/pom.xml create mode 100644 fine-hibernate/pom.xml create mode 100644 fine-hibernate/src/com/fr/third/org/hibernate/property/access/spi/UnsafeGetterFieldImpl.java create mode 100644 fine-hibernate/src/com/fr/third/org/hibernate/property/access/spi/UnsafeSetterMethodImpl.java diff --git a/fine-druid/pom.xml b/fine-druid/pom.xml new file mode 100644 index 000000000..299bfd9f2 --- /dev/null +++ b/fine-druid/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + + com.fr.third + base-third-code + 10.0-RELEASE-SNAPSHOT + + + com.fr.third + fine-druid + 10.0-RELEASE-SNAPSHOT + + + \ No newline at end of file diff --git a/fine-druid/src/com/fr/third/alibaba/druid/stat/JdbcStatManagerFactoryBean.java b/fine-druid/src/com/fr/third/alibaba/druid/stat/JdbcStatManagerFactoryBean.java index 8a9476640..c11c3f7ea 100644 --- a/fine-druid/src/com/fr/third/alibaba/druid/stat/JdbcStatManagerFactoryBean.java +++ b/fine-druid/src/com/fr/third/alibaba/druid/stat/JdbcStatManagerFactoryBean.java @@ -15,7 +15,7 @@ */ package com.fr.third.alibaba.druid.stat; -import org.springframework.beans.factory.FactoryBean; +import com.fr.third.springframework.beans.factory.FactoryBean; public class JdbcStatManagerFactoryBean implements FactoryBean { diff --git a/fine-druid/src/com/fr/third/alibaba/druid/support/ibatis/SpringIbatisBeanNameAutoProxyCreator.java b/fine-druid/src/com/fr/third/alibaba/druid/support/ibatis/SpringIbatisBeanNameAutoProxyCreator.java index 7ed48fe12..a90775d1a 100644 --- a/fine-druid/src/com/fr/third/alibaba/druid/support/ibatis/SpringIbatisBeanNameAutoProxyCreator.java +++ b/fine-druid/src/com/fr/third/alibaba/druid/support/ibatis/SpringIbatisBeanNameAutoProxyCreator.java @@ -20,8 +20,8 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.aop.TargetSource; -import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator; +import com.fr.third.springframework.aop.TargetSource; +import com.fr.third.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator; import com.ibatis.sqlmap.client.SqlMapClient; import com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient; diff --git a/fine-druid/src/com/fr/third/alibaba/druid/support/ibatis/SpringIbatisBeanTypeAutoProxyCreator.java b/fine-druid/src/com/fr/third/alibaba/druid/support/ibatis/SpringIbatisBeanTypeAutoProxyCreator.java index e89525de6..6a49278c0 100644 --- a/fine-druid/src/com/fr/third/alibaba/druid/support/ibatis/SpringIbatisBeanTypeAutoProxyCreator.java +++ b/fine-druid/src/com/fr/third/alibaba/druid/support/ibatis/SpringIbatisBeanTypeAutoProxyCreator.java @@ -19,11 +19,11 @@ import com.ibatis.sqlmap.client.SqlMapClient; import com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.aop.TargetSource; -import org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.util.PatternMatchUtils; +import com.fr.third.springframework.aop.TargetSource; +import com.fr.third.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator; +import com.fr.third.springframework.beans.factory.BeanFactory; +import com.fr.third.springframework.beans.factory.FactoryBean; +import com.fr.third.springframework.util.PatternMatchUtils; import java.util.ArrayList; import java.util.List; @@ -95,7 +95,7 @@ public class SpringIbatisBeanTypeAutoProxyCreator extends AbstractAutoProxyCreat * @param beanName the bean name to check * @param mappedName the name in the configured list of names * @return if the names match - * @see org.springframework.util.PatternMatchUtils#simpleMatch(String, String) + * @see com.fr.third.springframework.util.PatternMatchUtils#simpleMatch(String, String) */ protected boolean isMatch(String beanName, String mappedName) { return PatternMatchUtils.simpleMatch(mappedName, beanName); diff --git a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/MBeanServerFactoryBean.java b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/MBeanServerFactoryBean.java index 323b487f2..f09efc077 100644 --- a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/MBeanServerFactoryBean.java +++ b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/MBeanServerFactoryBean.java @@ -19,7 +19,7 @@ import java.lang.management.ManagementFactory; import javax.management.MBeanServer; -import org.springframework.beans.factory.FactoryBean; +import com.fr.third.springframework.beans.factory.FactoryBean; public class MBeanServerFactoryBean implements FactoryBean { diff --git a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/mvc/StatHandlerInterceptor.java b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/mvc/StatHandlerInterceptor.java index 310a44dc3..834c028f8 100644 --- a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/mvc/StatHandlerInterceptor.java +++ b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/mvc/StatHandlerInterceptor.java @@ -24,11 +24,11 @@ import javax.servlet.http.HttpServletResponse; import com.fr.third.alibaba.druid.filter.stat.StatFilterContext; import com.fr.third.alibaba.druid.support.http.stat.WebSessionStat; import com.fr.third.alibaba.druid.support.http.stat.WebURIStat; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.HandlerMapping; -import org.springframework.web.servlet.ModelAndView; +import com.fr.third.springframework.beans.factory.DisposableBean; +import com.fr.third.springframework.beans.factory.InitializingBean; +import com.fr.third.springframework.web.servlet.HandlerInterceptor; +import com.fr.third.springframework.web.servlet.HandlerMapping; +import com.fr.third.springframework.web.servlet.ModelAndView; import com.fr.third.alibaba.druid.support.http.AbstractWebStatImpl; import com.fr.third.alibaba.druid.support.http.stat.WebAppStat; diff --git a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/BeanTypeAutoProxyCreator.java b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/BeanTypeAutoProxyCreator.java index 49de94af4..131fb9a20 100644 --- a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/BeanTypeAutoProxyCreator.java +++ b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/BeanTypeAutoProxyCreator.java @@ -15,15 +15,15 @@ */ package com.fr.third.alibaba.druid.support.spring.stat; -import org.springframework.aop.TargetSource; -import org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.util.Assert; -import org.springframework.util.PatternMatchUtils; +import com.fr.third.springframework.aop.TargetSource; +import com.fr.third.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator; +import com.fr.third.springframework.beans.factory.BeanFactory; +import com.fr.third.springframework.beans.factory.FactoryBean; +import com.fr.third.springframework.beans.factory.InitializingBean; +import com.fr.third.springframework.context.ApplicationContext; +import com.fr.third.springframework.context.ApplicationContextAware; +import com.fr.third.springframework.util.Assert; +import com.fr.third.springframework.util.PatternMatchUtils; import java.util.ArrayList; import java.util.Collections; @@ -83,7 +83,7 @@ public class BeanTypeAutoProxyCreator extends AbstractAutoProxyCreator implement * @param beanName the bean name to check * @param mappedName the name in the configured list of names * @return if the names match - * @see org.springframework.util.PatternMatchUtils#simpleMatch(String, String) + * @see com.fr.third.springframework.util.PatternMatchUtils#simpleMatch(String, String) */ protected boolean isMatch(String beanName, String mappedName) { return PatternMatchUtils.simpleMatch(mappedName, beanName); diff --git a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/DruidStatInterceptor.java b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/DruidStatInterceptor.java index 5c50b63f4..82a2604b4 100644 --- a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/DruidStatInterceptor.java +++ b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/DruidStatInterceptor.java @@ -21,9 +21,9 @@ import com.fr.third.alibaba.druid.support.logging.Log; import com.fr.third.alibaba.druid.support.logging.LogFactory; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; -import org.springframework.aop.TargetSource; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; +import com.fr.third.springframework.aop.TargetSource; +import com.fr.third.springframework.beans.factory.DisposableBean; +import com.fr.third.springframework.beans.factory.InitializingBean; import java.lang.reflect.Method; @@ -123,8 +123,8 @@ public class DruidStatInterceptor implements MethodInterceptor, InitializingBean try { // 最多支持10层代理 for (int i = 0; i < 10; ++i) { - if (thisObject instanceof org.springframework.aop.framework.Advised) { - TargetSource targetSource = ((org.springframework.aop.framework.Advised) thisObject).getTargetSource(); + if (thisObject instanceof com.fr.third.springframework.aop.framework.Advised) { + TargetSource targetSource = ((com.fr.third.springframework.aop.framework.Advised) thisObject).getTargetSource(); if (targetSource == null) { break; diff --git a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/annotation/StatAnnotationAdvisor.java b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/annotation/StatAnnotationAdvisor.java index 5c0ab8524..622a57f08 100644 --- a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/annotation/StatAnnotationAdvisor.java +++ b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/annotation/StatAnnotationAdvisor.java @@ -17,13 +17,13 @@ package com.fr.third.alibaba.druid.support.spring.stat.annotation; import com.fr.third.alibaba.druid.support.spring.stat.DruidStatInterceptor; import org.aopalliance.aop.Advice; -import org.springframework.aop.Pointcut; -import org.springframework.aop.support.AbstractPointcutAdvisor; -import org.springframework.aop.support.ComposablePointcut; -import org.springframework.aop.support.annotation.AnnotationMatchingPointcut; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; +import com.fr.third.springframework.aop.Pointcut; +import com.fr.third.springframework.aop.support.AbstractPointcutAdvisor; +import com.fr.third.springframework.aop.support.ComposablePointcut; +import com.fr.third.springframework.aop.support.annotation.AnnotationMatchingPointcut; +import com.fr.third.springframework.beans.BeansException; +import com.fr.third.springframework.beans.factory.BeanFactory; +import com.fr.third.springframework.beans.factory.BeanFactoryAware; @SuppressWarnings("serial") public class StatAnnotationAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware { diff --git a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/annotation/StatAnnotationBeanPostProcessor.java b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/annotation/StatAnnotationBeanPostProcessor.java index a585c3da0..44033243e 100644 --- a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/annotation/StatAnnotationBeanPostProcessor.java +++ b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/annotation/StatAnnotationBeanPostProcessor.java @@ -18,10 +18,10 @@ package com.fr.third.alibaba.druid.support.spring.stat.annotation; import javax.annotation.Resource; import com.fr.third.alibaba.druid.support.spring.stat.DruidStatInterceptor; -import org.springframework.aop.framework.AbstractAdvisingBeanPostProcessor; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; +import com.fr.third.springframework.aop.framework.AbstractAdvisingBeanPostProcessor; +import com.fr.third.springframework.beans.BeansException; +import com.fr.third.springframework.beans.factory.BeanFactory; +import com.fr.third.springframework.beans.factory.BeanFactoryAware; @SuppressWarnings("serial") public class StatAnnotationBeanPostProcessor extends AbstractAdvisingBeanPostProcessor implements BeanFactoryAware { diff --git a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/config/DruidStatBeanDefinitionParser.java b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/config/DruidStatBeanDefinitionParser.java index 8491f7ae5..28a519369 100644 --- a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/config/DruidStatBeanDefinitionParser.java +++ b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/config/DruidStatBeanDefinitionParser.java @@ -15,14 +15,14 @@ */ package com.fr.third.alibaba.druid.support.spring.stat.config; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanDefinitionHolder; -import org.springframework.beans.factory.parsing.BeanComponentDefinition; -import org.springframework.beans.factory.parsing.CompositeComponentDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.xml.BeanDefinitionParser; -import org.springframework.beans.factory.xml.ParserContext; +import com.fr.third.springframework.beans.factory.config.BeanDefinition; +import com.fr.third.springframework.beans.factory.config.BeanDefinitionHolder; +import com.fr.third.springframework.beans.factory.parsing.BeanComponentDefinition; +import com.fr.third.springframework.beans.factory.parsing.CompositeComponentDefinition; +import com.fr.third.springframework.beans.factory.support.BeanDefinitionBuilder; +import com.fr.third.springframework.beans.factory.support.BeanDefinitionRegistry; +import com.fr.third.springframework.beans.factory.xml.BeanDefinitionParser; +import com.fr.third.springframework.beans.factory.xml.ParserContext; import org.w3c.dom.Element; public class DruidStatBeanDefinitionParser implements BeanDefinitionParser { diff --git a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/config/DruidStatNamespaceHandler.java b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/config/DruidStatNamespaceHandler.java index 5e6be134f..34f679280 100644 --- a/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/config/DruidStatNamespaceHandler.java +++ b/fine-druid/src/com/fr/third/alibaba/druid/support/spring/stat/config/DruidStatNamespaceHandler.java @@ -15,7 +15,7 @@ */ package com.fr.third.alibaba.druid.support.spring.stat.config; -import org.springframework.beans.factory.xml.NamespaceHandlerSupport; +import com.fr.third.springframework.beans.factory.xml.NamespaceHandlerSupport; public class DruidStatNamespaceHandler extends NamespaceHandlerSupport { diff --git a/fine-hibernate/pom.xml b/fine-hibernate/pom.xml new file mode 100644 index 000000000..3fca883d7 --- /dev/null +++ b/fine-hibernate/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + + com.fr.third + base-third-code + 10.0-RELEASE-SNAPSHOT + + + com.fr.third + fine-hibernate + 10.0-RELEASE-SNAPSHOT + + + \ No newline at end of file diff --git a/fine-hibernate/src/com/fr/third/org/hibernate/property/access/spi/UnsafeGetterFieldImpl.java b/fine-hibernate/src/com/fr/third/org/hibernate/property/access/spi/UnsafeGetterFieldImpl.java new file mode 100644 index 000000000..054e5c213 --- /dev/null +++ b/fine-hibernate/src/com/fr/third/org/hibernate/property/access/spi/UnsafeGetterFieldImpl.java @@ -0,0 +1,116 @@ +/* + * 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 com.fr.third.org.hibernate.property.access.spi; + +import com.fr.third.org.hibernate.engine.spi.SessionImplementor; +import com.fr.third.org.hibernate.property.access.internal.AbstractFieldSerialForm; +import sun.misc.Unsafe; +import sun.reflect.FieldAccessor; +import sun.reflect.ReflectionFactory; + +import java.io.ObjectStreamException; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.security.AccessController; +import java.util.Locale; +import java.util.Map; + +/** + * Field-based implementation of Getter + * + * @author Steve Ebersole + */ +public class UnsafeGetterFieldImpl implements Getter { + private final Class containerClass; + private final String propertyName; + private final Field field; + private final FieldAccessor accessor; + + static ReflectionFactory reflectionFactory = + AccessController.doPrivileged( + new sun.reflect.ReflectionFactory.GetReflectionFactoryAction()); + + + + + public UnsafeGetterFieldImpl(Class containerClass, String propertyName, Field field) { + this.containerClass = containerClass; + this.propertyName = propertyName; + this.field = field; + accessor = reflectionFactory.newFieldAccessor(field, false); + } + + @Override + public Object get(Object owner) { + if(accessor != null){ + return accessor.get(owner); + } + try { + return field.get( owner ); + } + catch (Exception e) { + throw new PropertyAccessException( + String.format( + Locale.ROOT, + "Error accessing field [%s] by reflection for persistent property [%s#%s] : %s", + field.toGenericString(), + containerClass.getName(), + propertyName, + owner + ), + e + ); + } + } + + @Override + public Object getForInsert(Object owner, Map mergeMap, SessionImplementor session) { + return get( owner ); + } + + @Override + public Class getReturnType() { + return field.getType(); + } + + @Override + public Member getMember() { + return field; + } + + @Override + public String getMethodName() { + return null; + } + + @Override + public Method getMethod() { + return null; + } + + private Object writeReplace() throws ObjectStreamException { + return new SerialForm( containerClass, propertyName, field ); + } + + private static class SerialForm extends AbstractFieldSerialForm implements Serializable { + private final Class containerClass; + private final String propertyName; + + private SerialForm(Class containerClass, String propertyName, Field field) { + super( field ); + this.containerClass = containerClass; + this.propertyName = propertyName; + } + + private Object readResolve() { + return new UnsafeGetterFieldImpl( containerClass, propertyName, resolveField() ); + } + } +} diff --git a/fine-hibernate/src/com/fr/third/org/hibernate/property/access/spi/UnsafeSetterMethodImpl.java b/fine-hibernate/src/com/fr/third/org/hibernate/property/access/spi/UnsafeSetterMethodImpl.java new file mode 100644 index 000000000..69f070d30 --- /dev/null +++ b/fine-hibernate/src/com/fr/third/org/hibernate/property/access/spi/UnsafeSetterMethodImpl.java @@ -0,0 +1,160 @@ +/* + * 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 com.fr.third.org.hibernate.property.access.spi; + +import com.fr.third.org.hibernate.PropertyAccessException; +import com.fr.third.org.hibernate.PropertySetterAccessException; +import com.fr.third.org.hibernate.engine.spi.SessionFactoryImplementor; +import com.fr.third.org.hibernate.internal.CoreMessageLogger; + +import java.io.ObjectStreamException; +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import static com.fr.third.org.hibernate.internal.CoreLogging.messageLogger; + +/** + * @author Steve Ebersole + */ +public class UnsafeSetterMethodImpl implements Setter { + private static final CoreMessageLogger LOG = messageLogger( UnsafeSetterMethodImpl.class ); + + private final Class containerClass; + private final String propertyName; + private final Method setterMethod; + + private final boolean isPrimitive; + + public UnsafeSetterMethodImpl(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 { + 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 UnsafeSetterMethodImpl( containerClass, propertyName, resolveMethod() ); + } + + @SuppressWarnings("unchecked") + private Method resolveMethod() { + try { + final Method method = declaringClass.getDeclaredMethod( methodName, argumentType ); + method.setAccessible( true ); + return method; + } + catch (NoSuchMethodException e) { + throw new PropertyAccessSerializationException( + "Unable to resolve setter method on deserialization : " + declaringClass.getName() + "#" + + methodName + "(" + argumentType.getName() + ")" + ); + } + } + } +}