remove pre Java 5 workaround

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@905786 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Matthew Jason Benson 2010-02-02 20:39:36 +00:00
parent 240b7a92f6
commit b92a2b5b0c
1 changed files with 29 additions and 62 deletions

View File

@ -18,16 +18,14 @@
import java.lang.reflect.AccessibleObject; import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Member; import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ClassUtils; import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.SystemUtils;
/** /**
* Contains common code for working with Methods/Constructors, extracted and * Contains common code for working with Methods/Constructors, extracted and
* refactored from <code>MethodUtils</code> when it was imported from Commons BeanUtils. * refactored from <code>MethodUtils</code> when it was imported from Commons
* BeanUtils.
* *
* @author Apache Software Foundation * @author Apache Software Foundation
* @author Steve Cohen * @author Steve Cohen
@ -40,35 +38,20 @@ abstract class MemberUtils {
private static final int ACCESS_TEST = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE; private static final int ACCESS_TEST = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE;
private static final Method IS_SYNTHETIC;
static {
Method isSynthetic = null;
if (SystemUtils.isJavaVersionAtLeast(1.5f)) {
// cannot call synthetic methods:
try {
isSynthetic = Member.class.getMethod("isSynthetic",
ArrayUtils.EMPTY_CLASS_ARRAY);
} catch (Exception e) {
}
}
IS_SYNTHETIC = isSynthetic;
}
/** Array of primitive number types ordered by "promotability" */ /** Array of primitive number types ordered by "promotability" */
private static final Class<?>[] ORDERED_PRIMITIVE_TYPES = { Byte.TYPE, private static final Class<?>[] ORDERED_PRIMITIVE_TYPES = { Byte.TYPE, Short.TYPE,
Short.TYPE, Character.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Character.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE };
Double.TYPE };
/** /**
* XXX Default access superclass workaround * XXX Default access superclass workaround
* *
* When a public class has a default access superclass with public * When a public class has a default access superclass with public members,
* members, these members are accessible. Calling them from * these members are accessible. Calling them from compiled code works fine.
* compiled code works fine. Unfortunately, on some JVMs, using reflection to invoke these * Unfortunately, on some JVMs, using reflection to invoke these members
* members seems to (wrongly) to prevent access even when the * seems to (wrongly) to prevent access even when the modifer is public.
* modifer is public. Calling setAccessible(true) solves the problem * Calling setAccessible(true) solves the problem but will only work from
* but will only work from sufficiently privileged code. Better * sufficiently privileged code. Better workarounds would be gratefully
* workarounds would be gratefully accepted. * accepted.
* @param o the AccessibleObject to set as accessible * @param o the AccessibleObject to set as accessible
*/ */
static void setAccessibleWorkaround(AccessibleObject o) { static void setAccessibleWorkaround(AccessibleObject o) {
@ -76,7 +59,8 @@ static void setAccessibleWorkaround(AccessibleObject o) {
return; return;
} }
Member m = (Member) o; Member m = (Member) o;
if (Modifier.isPublic(m.getModifiers()) && isPackageAccess(m.getDeclaringClass().getModifiers())) { if (Modifier.isPublic(m.getModifiers())
&& isPackageAccess(m.getDeclaringClass().getModifiers())) {
try { try {
o.setAccessible(true); o.setAccessible(true);
} catch (SecurityException e) { } catch (SecurityException e) {
@ -100,33 +84,19 @@ static boolean isPackageAccess(int modifiers) {
* @return true if <code>m</code> is accessible * @return true if <code>m</code> is accessible
*/ */
static boolean isAccessible(Member m) { static boolean isAccessible(Member m) {
return m != null && Modifier.isPublic(m.getModifiers()) return m != null && Modifier.isPublic(m.getModifiers()) && !m.isSynthetic();
&& !isSynthetic(m);
}
/**
* Try to learn whether a given member, on JDK >= 1.5, is synthetic.
* @param m Member to check
* @return true if <code>m</code> was introduced by the compiler.
*/
static boolean isSynthetic(Member m) {
if (IS_SYNTHETIC != null) {
try {
return ((Boolean) IS_SYNTHETIC.invoke(m, (Object[]) null)).booleanValue();
} catch (Exception e) {
}
}
return false;
} }
/** /**
* Compare the relative fitness of two sets of parameter types in terms of * Compare the relative fitness of two sets of parameter types in terms of
* matching a third set of runtime parameter types, such that a list ordered * matching a third set of runtime parameter types, such that a list ordered
* by the results of the comparison would return the best match first (least). * by the results of the comparison would return the best match first
* (least).
* *
* @param left the "left" parameter set * @param left the "left" parameter set
* @param right the "right" parameter set * @param right the "right" parameter set
* @param actual the runtime parameter types to match against <code>left</code>/<code>right</code> * @param actual the runtime parameter types to match against
* <code>left</code>/<code>right</code>
* @return int consistent with <code>compare</code> semantics * @return int consistent with <code>compare</code> semantics
*/ */
static int compareParameterTypes(Class<?>[] left, Class<?>[] right, Class<?>[] actual) { static int compareParameterTypes(Class<?>[] left, Class<?>[] right, Class<?>[] actual) {
@ -136,14 +106,13 @@ static int compareParameterTypes(Class<?>[] left, Class<?>[] right, Class<?>[] a
} }
/** /**
* Returns the sum of the object transformation cost for each class in the source * Returns the sum of the object transformation cost for each class in the
* argument list. * source argument list.
* @param srcArgs The source arguments * @param srcArgs The source arguments
* @param destArgs The destination arguments * @param destArgs The destination arguments
* @return The total transformation cost * @return The total transformation cost
*/ */
private static float getTotalTransformationCost(Class<?>[] srcArgs, private static float getTotalTransformationCost(Class<?>[] srcArgs, Class<?>[] destArgs) {
Class<?>[] destArgs) {
float totalCost = 0.0f; float totalCost = 0.0f;
for (int i = 0; i < srcArgs.length; i++) { for (int i = 0; i < srcArgs.length; i++) {
Class<?> srcClass, destClass; Class<?> srcClass, destClass;
@ -155,22 +124,20 @@ private static float getTotalTransformationCost(Class<?>[] srcArgs,
} }
/** /**
* Gets the number of steps required needed to turn the source class into the * Gets the number of steps required needed to turn the source class into
* destination class. This represents the number of steps in the object hierarchy * the destination class. This represents the number of steps in the object
* graph. * hierarchy graph.
* @param srcClass The source class * @param srcClass The source class
* @param destClass The destination class * @param destClass The destination class
* @return The cost of transforming an object * @return The cost of transforming an object
*/ */
private static float getObjectTransformationCost(Class<?> srcClass, private static float getObjectTransformationCost(Class<?> srcClass, Class<?> destClass) {
Class<?> destClass) {
if (destClass.isPrimitive()) { if (destClass.isPrimitive()) {
return getPrimitivePromotionCost(srcClass, destClass); return getPrimitivePromotionCost(srcClass, destClass);
} }
float cost = 0.0f; float cost = 0.0f;
while (destClass != null && !destClass.equals(srcClass)) { while (destClass != null && !destClass.equals(srcClass)) {
if (destClass.isInterface() if (destClass.isInterface() && ClassUtils.isAssignable(srcClass, destClass)) {
&& ClassUtils.isAssignable(srcClass, destClass)) {
// slight penalty for interface match. // slight penalty for interface match.
// we still want an exact match to override an interface match, // we still want an exact match to override an interface match,
// but // but
@ -193,13 +160,13 @@ private static float getObjectTransformationCost(Class<?> srcClass,
} }
/** /**
* Get the number of steps required to promote a primitive number to another type. * Get the number of steps required to promote a primitive number to another
* type.
* @param srcClass the (primitive) source class * @param srcClass the (primitive) source class
* @param destClass the (primitive) destination class * @param destClass the (primitive) destination class
* @return The cost of promoting the primitive * @return The cost of promoting the primitive
*/ */
private static float getPrimitivePromotionCost(final Class<?> srcClass, private static float getPrimitivePromotionCost(final Class<?> srcClass, final Class<?> destClass) {
final Class<?> destClass) {
float cost = 0.0f; float cost = 0.0f;
Class<?> cls = srcClass; Class<?> cls = srcClass;
if (!cls.isPrimitive()) { if (!cls.isPrimitive()) {