Modified to use MethodFinder (now provided by samskivert library) which
resolves methods based on the types of the arguments fully properly, rather than in the half-baked way I was doing it. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@379 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,14 +1,16 @@
|
|||||||
//
|
//
|
||||||
// $Id: ClassUtil.java,v 1.2 2001/08/14 06:48:08 mdb Exp $
|
// $Id: ClassUtil.java,v 1.3 2001/10/03 03:38:21 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cocktail.cher.util;
|
package com.threerings.cocktail.cher.util;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import com.samskivert.Log;
|
import com.samskivert.util.MethodFinder;
|
||||||
import com.samskivert.util.StringUtil;
|
import com.samskivert.util.StringUtil;
|
||||||
|
|
||||||
|
import com.threerings.cocktail.cher.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class related utility functions.
|
* Class related utility functions.
|
||||||
*/
|
*/
|
||||||
@@ -42,55 +44,37 @@ public class ClassUtil
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks up the method on the specified object that has a signature
|
* Looks up the method on the specified object that has a signature
|
||||||
* that matches the supplied arguments array. This has to create an
|
* that matches the supplied arguments array. This is very expensive,
|
||||||
* array of class objects correspnding to the types of all of the
|
* so you shouldn't be doing this for something that happens
|
||||||
* arguments in the args array, so none of them are allowed to be
|
* frequently.
|
||||||
* null. This is very expensive, so you shouldn't be doing this for
|
|
||||||
* something that happens frequently.
|
|
||||||
*
|
|
||||||
* <p><em>Note:</em> primitive types for arguments are preferred. What
|
|
||||||
* this means is that if an element of the <code>args</code> array is
|
|
||||||
* an instance of <code>Integer</code>, for example, then this code
|
|
||||||
* assumes that it is intended for that to be unwrapped into an
|
|
||||||
* <code>int</code> in calling the actual function. The reason this is
|
|
||||||
* necessary is that method lookup isn't smart about first checking
|
|
||||||
* for a method taking the primitive argument and then falling back to
|
|
||||||
* one taking an <code>Integer</code> object. So we insist that all
|
|
||||||
* arguments that <em>can</em> be unwrapped, <em>are</em> unwrapped.
|
|
||||||
* Why would you want to pass <code>Integer</code> objects as
|
|
||||||
* arguments to your function anyway?
|
|
||||||
*
|
*
|
||||||
* @return the best matching method with the specified name that
|
* @return the best matching method with the specified name that
|
||||||
* accepts the supplied arguments, or null if no method could be
|
* accepts the supplied arguments, or null if no method could be
|
||||||
* found.
|
* found.
|
||||||
|
*
|
||||||
|
* @see MethodFinder
|
||||||
*/
|
*/
|
||||||
public static Method getMethod (String name, Object target, Object[] args)
|
public static Method getMethod (String name, Object target, Object[] args)
|
||||||
{
|
{
|
||||||
// grab a whole crapload of class objects
|
|
||||||
Class tclass = target.getClass();
|
Class tclass = target.getClass();
|
||||||
Class[] aclasses = new Class[args.length];
|
|
||||||
for (int i = 0; i < aclasses.length; i++) {
|
|
||||||
Class aclass = args[i].getClass();
|
|
||||||
Class mclass = (Class)_classMap.get(aclass);
|
|
||||||
// use the massaged class if there is one
|
|
||||||
aclasses[i] = (mclass == null) ? aclass : mclass;
|
|
||||||
}
|
|
||||||
|
|
||||||
// now look up the method
|
|
||||||
Method meth = null;
|
Method meth = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
meth = tclass.getMethod(name, aclasses);
|
MethodFinder finder = new MethodFinder(tclass);
|
||||||
|
meth = finder.findMethod(name, args);
|
||||||
|
|
||||||
} catch (NoSuchMethodException nsme) {
|
} catch (NoSuchMethodException nsme) {
|
||||||
// nothing to do here but fall through and return null
|
// nothing to do here but fall through and return null
|
||||||
Log.info("No such method [name=" + name +
|
Log.info("No such method [name=" + name +
|
||||||
", tclass=" + tclass.getName() +
|
", tclass=" + tclass.getName() +
|
||||||
", args=" + StringUtil.toString(aclasses) + "].");
|
", args=" + StringUtil.toString(args) + "].");
|
||||||
|
|
||||||
} catch (SecurityException se) {
|
} catch (SecurityException se) {
|
||||||
Log.warning("Unable to look up method? " +
|
Log.warning("Unable to look up method? " +
|
||||||
"[tclass=" + tclass.getName() +
|
"[tclass=" + tclass.getName() +
|
||||||
", mname=" + name + "].");
|
", mname=" + name + "].");
|
||||||
}
|
}
|
||||||
|
|
||||||
return meth;
|
return meth;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,17 +95,4 @@ public class ClassUtil
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Used when massaging arguments into their primitive type. */
|
|
||||||
protected static HashMap _classMap = new HashMap();
|
|
||||||
static {
|
|
||||||
_classMap.put(Boolean.class, Boolean.TYPE);
|
|
||||||
_classMap.put(Byte.class, Byte.TYPE);
|
|
||||||
_classMap.put(Character.class, Character.TYPE);
|
|
||||||
_classMap.put(Short.class, Short.TYPE);
|
|
||||||
_classMap.put(Integer.class, Integer.TYPE);
|
|
||||||
_classMap.put(Long.class, Long.TYPE);
|
|
||||||
_classMap.put(Float.class, Float.TYPE);
|
|
||||||
_classMap.put(Double.class, Double.TYPE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user