HHH-2268 - Skip bridge methods during getter determination (JDK Bug 5062759)
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@19624 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
39c75a50c6
commit
6d01dd07b0
|
@ -63,7 +63,7 @@ public class BasicPropertyAccessor implements PropertyAccessor {
|
|||
public void set(Object target, Object value, SessionFactoryImplementor factory)
|
||||
throws HibernateException {
|
||||
try {
|
||||
method.invoke( target, new Object[] { value } );
|
||||
method.invoke( target, value );
|
||||
}
|
||||
catch (NullPointerException npe) {
|
||||
if ( value==null && method.getParameterTypes()[0].isPrimitive() ) {
|
||||
|
@ -169,7 +169,7 @@ public class BasicPropertyAccessor implements PropertyAccessor {
|
|||
*/
|
||||
public Object get(Object target) throws HibernateException {
|
||||
try {
|
||||
return method.invoke(target, null);
|
||||
return method.invoke( target, (Object[]) null );
|
||||
}
|
||||
catch (InvocationTargetException ite) {
|
||||
throw new PropertyAccessException(
|
||||
|
@ -299,15 +299,15 @@ public class BasicPropertyAccessor implements PropertyAccessor {
|
|||
|
||||
Method[] methods = theClass.getDeclaredMethods();
|
||||
Method potentialSetter = null;
|
||||
for (int i=0; i<methods.length; i++) {
|
||||
String methodName = methods[i].getName();
|
||||
for ( Method method : methods ) {
|
||||
final String methodName = method.getName();
|
||||
|
||||
if ( methods[i].getParameterTypes().length==1 && methodName.startsWith("set") ) {
|
||||
String testStdMethod = Introspector.decapitalize( methodName.substring(3) );
|
||||
String testOldMethod = methodName.substring(3);
|
||||
if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
|
||||
potentialSetter = methods[i];
|
||||
if ( returnType==null || methods[i].getParameterTypes()[0].equals(returnType) ) {
|
||||
if ( method.getParameterTypes().length == 1 && methodName.startsWith( "set" ) ) {
|
||||
String testStdMethod = Introspector.decapitalize( methodName.substring( 3 ) );
|
||||
String testOldMethod = methodName.substring( 3 );
|
||||
if ( testStdMethod.equals( propertyName ) || testOldMethod.equals( propertyName ) ) {
|
||||
potentialSetter = method;
|
||||
if ( returnType == null || method.getParameterTypes()[0].equals( returnType ) ) {
|
||||
return potentialSetter;
|
||||
}
|
||||
}
|
||||
|
@ -316,13 +316,11 @@ public class BasicPropertyAccessor implements PropertyAccessor {
|
|||
return potentialSetter;
|
||||
}
|
||||
|
||||
public Getter getGetter(Class theClass, String propertyName)
|
||||
throws PropertyNotFoundException {
|
||||
public Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException {
|
||||
return createGetter(theClass, propertyName);
|
||||
}
|
||||
|
||||
public static Getter createGetter(Class theClass, String propertyName)
|
||||
throws PropertyNotFoundException {
|
||||
public static Getter createGetter(Class theClass, String propertyName) throws PropertyNotFoundException {
|
||||
BasicGetter result = getGetterOrNull(theClass, propertyName);
|
||||
if (result==null) {
|
||||
throw new PropertyNotFoundException(
|
||||
|
@ -333,17 +331,19 @@ public class BasicPropertyAccessor implements PropertyAccessor {
|
|||
);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
private static BasicGetter getGetterOrNull(Class theClass, String propertyName) {
|
||||
|
||||
if (theClass==Object.class || theClass==null) return null;
|
||||
if (theClass==Object.class || theClass==null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Method method = getterMethod(theClass, propertyName);
|
||||
|
||||
if (method!=null) {
|
||||
if ( !ReflectHelper.isPublic(theClass, method) ) method.setAccessible(true);
|
||||
if ( !ReflectHelper.isPublic(theClass, method) ) {
|
||||
method.setAccessible(true);
|
||||
}
|
||||
return new BasicGetter(theClass, method, propertyName);
|
||||
}
|
||||
else {
|
||||
|
@ -359,33 +359,38 @@ public class BasicPropertyAccessor implements PropertyAccessor {
|
|||
}
|
||||
|
||||
private static Method getterMethod(Class theClass, String propertyName) {
|
||||
|
||||
Method[] methods = theClass.getDeclaredMethods();
|
||||
for (int i=0; i<methods.length; i++) {
|
||||
// only carry on if the method has no parameters
|
||||
if ( methods[i].getParameterTypes().length == 0 ) {
|
||||
String methodName = methods[i].getName();
|
||||
|
||||
// try "get"
|
||||
if ( methodName.startsWith("get") ) {
|
||||
String testStdMethod = Introspector.decapitalize( methodName.substring(3) );
|
||||
String testOldMethod = methodName.substring(3);
|
||||
if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
|
||||
return methods[i];
|
||||
for ( Method method : methods ) {
|
||||
// if the method has parameters, skip it
|
||||
if ( method.getParameterTypes().length != 0 ) {
|
||||
continue;
|
||||
}
|
||||
// if the method is a "bridge", skip it
|
||||
if ( method.isBridge() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String methodName = method.getName();
|
||||
|
||||
// try "get"
|
||||
if ( methodName.startsWith( "get" ) ) {
|
||||
String testStdMethod = Introspector.decapitalize( methodName.substring( 3 ) );
|
||||
String testOldMethod = methodName.substring( 3 );
|
||||
if ( testStdMethod.equals( propertyName ) || testOldMethod.equals( propertyName ) ) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
||||
// if not "get", then try "is"
|
||||
if ( methodName.startsWith("is") ) {
|
||||
String testStdMethod = Introspector.decapitalize( methodName.substring(2) );
|
||||
String testOldMethod = methodName.substring(2);
|
||||
if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
|
||||
return methods[i];
|
||||
}
|
||||
if ( methodName.startsWith( "is" ) ) {
|
||||
String testStdMethod = Introspector.decapitalize( methodName.substring( 2 ) );
|
||||
String testOldMethod = methodName.substring( 2 );
|
||||
if ( testStdMethod.equals( propertyName ) || testOldMethod.equals( propertyName ) ) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.property;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BasicPropertyAccessorTest extends TestCase {
|
||||
public static abstract class Super {
|
||||
public abstract Object getIt();
|
||||
public abstract void setIt(Object it);
|
||||
}
|
||||
|
||||
public static class Duper extends Super {
|
||||
private String it;
|
||||
|
||||
public Duper(String it) {
|
||||
this.it = it;
|
||||
}
|
||||
|
||||
public String getIt() {
|
||||
return it;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIt(Object it) {
|
||||
this.it = ( it == null || String.class.isInstance( it ) )
|
||||
? (String) it
|
||||
: it.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Duper2 extends Super {
|
||||
private String it;
|
||||
|
||||
public Duper2(String it) {
|
||||
this.it = it;
|
||||
}
|
||||
|
||||
public String getIt() {
|
||||
return it;
|
||||
}
|
||||
|
||||
public void setIt(String it) {
|
||||
this.it = it;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIt(Object it) {
|
||||
if ( it == null || String.class.isInstance( it ) ) {
|
||||
setIt( (String) it );
|
||||
}
|
||||
else {
|
||||
setIt( it.toString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testBridgeMethodDisregarded() {
|
||||
BasicPropertyAccessor accessor = new BasicPropertyAccessor();
|
||||
|
||||
{
|
||||
BasicPropertyAccessor.BasicGetter getter = (BasicPropertyAccessor.BasicGetter) accessor.getGetter( Duper.class, "it" );
|
||||
assertEquals( String.class, getter.getReturnType() );
|
||||
|
||||
BasicPropertyAccessor.BasicSetter setter = (BasicPropertyAccessor.BasicSetter) accessor.getSetter( Duper.class, "it" );
|
||||
assertEquals( Object.class, setter.getMethod().getParameterTypes()[0] );
|
||||
}
|
||||
|
||||
{
|
||||
BasicPropertyAccessor.BasicGetter getter = (BasicPropertyAccessor.BasicGetter) accessor.getGetter( Duper2.class, "it" );
|
||||
assertEquals( String.class, getter.getReturnType() );
|
||||
|
||||
BasicPropertyAccessor.BasicSetter setter = (BasicPropertyAccessor.BasicSetter) accessor.getSetter( Duper2.class, "it" );
|
||||
assertEquals( String.class, setter.getMethod().getParameterTypes()[0] );
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue