All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.virjar.sekiro.utils.MemberUtils Maven / Gradle / Ivy

Go to download

ratel api,used for developer on ratel system,an extension for xposed framewrok,ratel api compatable with original xposed framework

There is a newer version: 1.0.5
Show newest version
package com.virjar.sekiro.utils;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Member;
import java.lang.reflect.Modifier;

import static com.virjar.sekiro.utils.ReflectUtil.isAssignable;
import static com.virjar.sekiro.utils.ReflectUtil.wrapperToPrimitive;


/**
 * Contains common code for working with Methods/Constructors, extracted and
 * refactored from MethodUtils when it was imported from Commons
 * BeanUtils.
 *
 * @version $Id: MemberUtils.java 1143537 2011-07-06 19:30:22Z joehni $
 * @since 2.5
 */
public abstract class MemberUtils {

    private static final int ACCESS_TEST = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE;

    /**
     * Array of primitive number types ordered by "promotability"
     */
    private static final Class[] ORDERED_PRIMITIVE_TYPES = {Byte.TYPE, Short.TYPE,
            Character.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE};

    /**
     * XXX Default access superclass workaround
     * 

* When a public class has a default access superclass with public members, * these members are accessible. Calling them from compiled code works fine. * Unfortunately, on some JVMs, using reflection to invoke these members * seems to (wrongly) prevent access even when the modifier is public. * Calling setAccessible(true) solves the problem but will only work from * sufficiently privileged code. Better workarounds would be gratefully * accepted. * * @param o the AccessibleObject to set as accessible */ static void setAccessibleWorkaround(AccessibleObject o) { if (o == null || o.isAccessible()) { return; } Member m = (Member) o; if (Modifier.isPublic(m.getModifiers()) && isPackageAccess(m.getDeclaringClass().getModifiers())) { try { o.setAccessible(true); } catch (SecurityException e) { // NOPMD // ignore in favor of subsequent IllegalAccessException } } } /** * Returns whether a given set of modifiers implies package access. * * @param modifiers to test * @return true unless package/protected/private modifier detected */ static boolean isPackageAccess(int modifiers) { return (modifiers & ACCESS_TEST) == 0; } /** * Returns whether a Member is accessible. * * @param m Member to check * @return true if m is accessible */ static boolean isAccessible(Member m) { return m != null && Modifier.isPublic(m.getModifiers()) && !m.isSynthetic(); } /** * Compares 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 * by the results of the comparison would return the best match first * (least). * * @param left the "left" parameter set * @param right the "right" parameter set * @param actual the runtime parameter types to match against * left/right * @return int consistent with compare semantics */ public static int compareParameterTypes(Class[] left, Class[] right, Class[] actual) { float leftCost = getTotalTransformationCost(actual, left); float rightCost = getTotalTransformationCost(actual, right); return leftCost < rightCost ? -1 : rightCost < leftCost ? 1 : 0; } /** * Returns the sum of the object transformation cost for each class in the * source argument list. * * @param srcArgs The source arguments * @param destArgs The destination arguments * @return The total transformation cost */ private static float getTotalTransformationCost(Class[] srcArgs, Class[] destArgs) { float totalCost = 0.0f; for (int i = 0; i < srcArgs.length; i++) { Class srcClass, destClass; srcClass = srcArgs[i]; destClass = destArgs[i]; totalCost += getObjectTransformationCost(srcClass, destClass); } return totalCost; } /** * Gets the number of steps required needed to turn the source class into * the destination class. This represents the number of steps in the object * hierarchy graph. * * @param srcClass The source class * @param destClass The destination class * @return The cost of transforming an object */ private static float getObjectTransformationCost(Class srcClass, Class destClass) { if (destClass.isPrimitive()) { return getPrimitivePromotionCost(srcClass, destClass); } float cost = 0.0f; while (srcClass != null && !destClass.equals(srcClass)) { if (destClass.isInterface() && isAssignable(srcClass, destClass, true)) { // slight penalty for interface match. // we still want an exact match to override an interface match, // but // an interface match should override anything where we have to // get a superclass. cost += 0.25f; break; } cost++; srcClass = srcClass.getSuperclass(); } /* * If the destination class is null, we've travelled all the way up to * an Object match. We'll penalize this by adding 1.5 to the cost. */ if (srcClass == null) { cost += 1.5f; } return cost; } /** * Gets the number of steps required to promote a primitive number to another * type. * * @param srcClass the (primitive) source class * @param destClass the (primitive) destination class * @return The cost of promoting the primitive */ private static float getPrimitivePromotionCost(final Class srcClass, final Class destClass) { float cost = 0.0f; Class cls = srcClass; if (!cls.isPrimitive()) { // slight unwrapping penalty cost += 0.1f; cls = wrapperToPrimitive(cls); } for (int i = 0; cls != destClass && i < ORDERED_PRIMITIVE_TYPES.length; i++) { if (cls == ORDERED_PRIMITIVE_TYPES[i]) { cost += 0.1f; if (i < ORDERED_PRIMITIVE_TYPES.length - 1) { cls = ORDERED_PRIMITIVE_TYPES[i + 1]; } } } return cost; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy