bsh
Class Reflect

java.lang.Object
  |
  +--bsh.Reflect

class Reflect
extends java.lang.Object

All of the reflection API code lies here. It is in the form of static utilities. See the design note about object wrappers in LHS.java for lamentations regarding this. Note: More work to do in here to fix up the extended signature matching. need to work in a search along with findMostSpecificSignature...

Note: there are lots of cases here where the Java reflection API makes us catch exceptions (e.g. NoSuchFieldException) in order to do basic searching. This has to be inefficient... I wish they would add a more normal Java API for locating fields.


Constructor Summary
(package private) Reflect()
           
 
Method Summary
private static java.lang.String accessorName(java.lang.String getorset, java.lang.String propName)
           
(package private) static java.lang.Object constructObject(java.lang.Class clas, java.lang.Object[] args)
          Primary object constructor
(package private) static java.lang.Object constructObject(java.lang.String clas, java.lang.Object[] args)
           
private static java.lang.reflect.Field findAccessibleField(java.lang.Class clas, java.lang.String fieldName)
          Used when accessibility capability is available to locate an occurrance of the field in the most derived class or superclass and set its accessibility flag.
(package private) static java.lang.reflect.Method findAccessibleMethod(java.lang.Class clas, java.lang.String name, java.lang.Class[] types, boolean onlyStatic)
          Locate a version of the method with the exact signature specified that is accessible via a public interface or through a public superclass or - if accessibility is on - through any interface or superclass.
(package private) static java.lang.reflect.Constructor findExtendedConstructor(java.lang.Object[] args, java.lang.reflect.Constructor[] constructors)
          This uses the NameSpace.getAssignableForm() method to determine compatability of args.
(package private) static java.lang.reflect.Method findExtendedMethod(java.lang.String name, java.lang.Object[] args, java.lang.reflect.Method[] methods)
          This uses the NameSpace.getAssignableForm() method to determine compatability of args.
(package private) static java.lang.reflect.Constructor findMostSpecificConstructor(java.lang.Class[] idealMatch, java.lang.reflect.Constructor[] constructors)
           
(package private) static java.lang.reflect.Method findMostSpecificMethod(java.lang.String name, java.lang.Class[] idealMatch, java.lang.reflect.Method[] methods)
          Implement JLS 15.11.2 for method resolution
(package private) static int findMostSpecificSignature(java.lang.Class[] idealMatch, java.lang.Class[][] candidates)
          Implement JLS 15.11.2 Return the index of the most specific arguments match or -1 if no match is found.
static java.lang.Class getArrayBaseType(java.lang.Class arrayClass)
          Returns the base type of an array Class.
static int getArrayDimensions(java.lang.Class arrayClass)
          [ returns the dimensionality of the Class returns 0 if the Class is not an array class
private static java.lang.reflect.Field getField(java.lang.Class clas, java.lang.String fieldName)
          All field lookup should come through here.
private static java.lang.Object getFieldValue(java.lang.Class clas, java.lang.Object object, java.lang.String fieldName)
           
static java.lang.Object getIndex(java.lang.Object array, int index)
           
(package private) static LHS getLHSObjectField(java.lang.Object object, java.lang.String fieldName)
          Get an LHS reference to an object field.
(package private) static LHS getLHSStaticField(java.lang.Class clas, java.lang.String fieldName)
           
static java.lang.Object getObjectField(java.lang.Object object, java.lang.String fieldName)
           
static java.lang.Object getObjectProperty(java.lang.Object obj, java.lang.String propName)
           
static java.lang.Object getStaticField(java.lang.Class clas, java.lang.String fieldName)
           
static java.lang.Class[] getTypes(java.lang.Object[] args)
           
static boolean hasObjectPropertyGetter(java.lang.Class clas, java.lang.String propName)
           
static boolean hasObjectPropertySetter(java.lang.Class clas, java.lang.String propName)
           
private static java.lang.Object invokeMethod(java.lang.Class clas, java.lang.Object object, java.lang.String name, java.lang.Object[] args, boolean onlyStatic)
          The full blown invoke method.
static java.lang.Object invokeObjectMethod(Interpreter interpreter, java.lang.Object object, java.lang.String methodName, java.lang.Object[] args, SimpleNode callerInfo)
          Invoke method on object.
static java.lang.Object invokeStaticMethod(java.lang.Class clas, java.lang.String methodName, java.lang.Object[] args)
          Invoke a static method.
(package private) static boolean isAssignable(java.lang.Class[] from, java.lang.Class[] to)
          Determine if the 'from' signature is assignable to the 'to' signature 'from' arg types, 'to' candidate types null value in 'to' type parameter indicates loose type.
(package private) static boolean isAssignableFrom(java.lang.Class lhs, java.lang.Class rhs)
          This base method is meant to address a deficiency of Class.isAssignableFrom() which does not take primitive widening conversions into account.
static java.lang.String normalizeClassName(java.lang.Class type)
          This method is meant to convert a JVM-array class name to the correct 'fully-qualified name' for the array class - JLS 6.7
private static java.lang.reflect.Method[] retainStaticMethods(java.lang.reflect.Method[] methods)
          Return only the static methods
static void setIndex(java.lang.Object array, int index, java.lang.Object val)
           
static void setObjectProperty(java.lang.Object obj, java.lang.String propName, java.lang.Object value)
           
private static boolean showThisMethod(java.lang.String name)
          Allow invocations of these method names on This type objects.
private static java.lang.Object unwrapPrimitive(java.lang.Object arg)
           
private static void unwrapPrimitives(java.lang.Object[] args)
           
private static java.lang.Object wrapPrimitive(java.lang.Object value, java.lang.Class returnType)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Reflect

Reflect()
Method Detail

invokeObjectMethod

public static java.lang.Object invokeObjectMethod(Interpreter interpreter,
                                                  java.lang.Object object,
                                                  java.lang.String methodName,
                                                  java.lang.Object[] args,
                                                  SimpleNode callerInfo)
                                           throws ReflectError,
                                                  java.lang.reflect.InvocationTargetException,
                                                  EvalError
Invoke method on object. invocation may be static (through the object instance) or dynamic. Object may be This type. The This handling is necessary here (previously thought it might not be).

Parameters:
callerInfo - will be passed along in the caes where the method is a bsh scripted method. It may be null to indicate no caller info.
ReflectError
java.lang.reflect.InvocationTargetException
EvalError

showThisMethod

private static boolean showThisMethod(java.lang.String name)
Allow invocations of these method names on This type objects. Don't give bsh.This a chance to override their behavior.


invokeStaticMethod

public static java.lang.Object invokeStaticMethod(java.lang.Class clas,
                                                  java.lang.String methodName,
                                                  java.lang.Object[] args)
                                           throws ReflectError,
                                                  java.lang.reflect.InvocationTargetException,
                                                  EvalError
Invoke a static method. No object instance is provided.

ReflectError
java.lang.reflect.InvocationTargetException
EvalError

getIndex

public static java.lang.Object getIndex(java.lang.Object array,
                                        int index)
                                 throws ReflectError,
                                        TargetError
ReflectError
TargetError

setIndex

public static void setIndex(java.lang.Object array,
                            int index,
                            java.lang.Object val)
                     throws ReflectError,
                            TargetError
ReflectError
TargetError

getStaticField

public static java.lang.Object getStaticField(java.lang.Class clas,
                                              java.lang.String fieldName)
                                       throws ReflectError
ReflectError

getObjectField

public static java.lang.Object getObjectField(java.lang.Object object,
                                              java.lang.String fieldName)
                                       throws ReflectError
ReflectError

getLHSStaticField

static LHS getLHSStaticField(java.lang.Class clas,
                             java.lang.String fieldName)
                      throws ReflectError
ReflectError

getLHSObjectField

static LHS getLHSObjectField(java.lang.Object object,
                             java.lang.String fieldName)
                      throws ReflectError
Get an LHS reference to an object field. This method also deals with the field style property access. In the field does not exist we check for a property setter.

ReflectError

getFieldValue

private static java.lang.Object getFieldValue(java.lang.Class clas,
                                              java.lang.Object object,
                                              java.lang.String fieldName)
                                       throws ReflectError
ReflectError

getField

private static java.lang.reflect.Field getField(java.lang.Class clas,
                                                java.lang.String fieldName)
                                         throws ReflectError
All field lookup should come through here. i.e. this method owns Class getField();

ReflectError

findAccessibleField

private static java.lang.reflect.Field findAccessibleField(java.lang.Class clas,
                                                           java.lang.String fieldName)
                                                    throws java.lang.NoSuchFieldException
Used when accessibility capability is available to locate an occurrance of the field in the most derived class or superclass and set its accessibility flag. Note that this method is not needed in the simple non accessible case because we don't have to hunt for fields. Note that classes may declare overlapping private fields, so the distinction about the most derived is important. Java doesn't normally allow this kind of access (super won't show private variables) so there is no real syntax for specifying which class scope to use...

java.lang.NoSuchFieldException

invokeMethod

private static java.lang.Object invokeMethod(java.lang.Class clas,
                                             java.lang.Object object,
                                             java.lang.String name,
                                             java.lang.Object[] args,
                                             boolean onlyStatic)
                                      throws ReflectError,
                                             java.lang.reflect.InvocationTargetException,
                                             EvalError
The full blown invoke method. Everybody should come here. The invoked method may be static or dynamic unless onlyStatic is set (in which case object may be null).

Parameters:
onlyStatic - The method located must be static, the object param may be null. Note: Method invocation could probably be speeded up if we eliminated the throwing of exceptions in the search for the proper method. We could probably cache our knowledge of method structure as well.
ReflectError
java.lang.reflect.InvocationTargetException
EvalError

retainStaticMethods

private static java.lang.reflect.Method[] retainStaticMethods(java.lang.reflect.Method[] methods)
Return only the static methods


findAccessibleMethod

static java.lang.reflect.Method findAccessibleMethod(java.lang.Class clas,
                                                     java.lang.String name,
                                                     java.lang.Class[] types,
                                                     boolean onlyStatic)
Locate a version of the method with the exact signature specified that is accessible via a public interface or through a public superclass or - if accessibility is on - through any interface or superclass. In the normal (non-accessible) case this still solves the problem that arises when a package private class or private inner class implements a public interface or derives from a public type.

Parameters:
onlyStatic - the method located must be static.
Returns:
null on not found

wrapPrimitive

private static java.lang.Object wrapPrimitive(java.lang.Object value,
                                              java.lang.Class returnType)
                                       throws ReflectError
ReflectError

getTypes

public static java.lang.Class[] getTypes(java.lang.Object[] args)

unwrapPrimitives

private static void unwrapPrimitives(java.lang.Object[] args)

unwrapPrimitive

private static java.lang.Object unwrapPrimitive(java.lang.Object arg)

constructObject

static java.lang.Object constructObject(java.lang.String clas,
                                        java.lang.Object[] args)
                                 throws ReflectError,
                                        java.lang.reflect.InvocationTargetException
ReflectError
java.lang.reflect.InvocationTargetException

constructObject

static java.lang.Object constructObject(java.lang.Class clas,
                                        java.lang.Object[] args)
                                 throws ReflectError,
                                        java.lang.reflect.InvocationTargetException
Primary object constructor

ReflectError
java.lang.reflect.InvocationTargetException

findMostSpecificMethod

static java.lang.reflect.Method findMostSpecificMethod(java.lang.String name,
                                                       java.lang.Class[] idealMatch,
                                                       java.lang.reflect.Method[] methods)
Implement JLS 15.11.2 for method resolution

Returns:
null on no match

findExtendedMethod

static java.lang.reflect.Method findExtendedMethod(java.lang.String name,
                                                   java.lang.Object[] args,
                                                   java.lang.reflect.Method[] methods)
This uses the NameSpace.getAssignableForm() method to determine compatability of args. This allows special (non standard Java) bsh widening operations...

Returns:
null on not found

findMostSpecificConstructor

static java.lang.reflect.Constructor findMostSpecificConstructor(java.lang.Class[] idealMatch,
                                                                 java.lang.reflect.Constructor[] constructors)

findExtendedConstructor

static java.lang.reflect.Constructor findExtendedConstructor(java.lang.Object[] args,
                                                             java.lang.reflect.Constructor[] constructors)
This uses the NameSpace.getAssignableForm() method to determine compatability of args. This allows special (non standard Java) bsh widening operations...


findMostSpecificSignature

static int findMostSpecificSignature(java.lang.Class[] idealMatch,
                                     java.lang.Class[][] candidates)
Implement JLS 15.11.2 Return the index of the most specific arguments match or -1 if no match is found.


isAssignable

static boolean isAssignable(java.lang.Class[] from,
                            java.lang.Class[] to)
Determine if the 'from' signature is assignable to the 'to' signature 'from' arg types, 'to' candidate types null value in 'to' type parameter indicates loose type. null value in either arg is considered empty array


isAssignableFrom

static boolean isAssignableFrom(java.lang.Class lhs,
                                java.lang.Class rhs)
This base method is meant to address a deficiency of Class.isAssignableFrom() which does not take primitive widening conversions into account. Note that the getAssigbableForm() method in NameSpace is the primary bsh method for checking assignability. It adds extended bsh conversions, etc.

Parameters:
lhs - assigning from rhs to lhs
rhs - assigning from rhs to lsh

accessorName

private static java.lang.String accessorName(java.lang.String getorset,
                                             java.lang.String propName)

hasObjectPropertyGetter

public static boolean hasObjectPropertyGetter(java.lang.Class clas,
                                              java.lang.String propName)

hasObjectPropertySetter

public static boolean hasObjectPropertySetter(java.lang.Class clas,
                                              java.lang.String propName)

getObjectProperty

public static java.lang.Object getObjectProperty(java.lang.Object obj,
                                                 java.lang.String propName)
                                          throws ReflectError
ReflectError

setObjectProperty

public static void setObjectProperty(java.lang.Object obj,
                                     java.lang.String propName,
                                     java.lang.Object value)
                              throws ReflectError,
                                     EvalError
ReflectError
EvalError

normalizeClassName

public static java.lang.String normalizeClassName(java.lang.Class type)
This method is meant to convert a JVM-array class name to the correct 'fully-qualified name' for the array class - JLS 6.7


getArrayDimensions

public static int getArrayDimensions(java.lang.Class arrayClass)
[ returns the dimensionality of the Class returns 0 if the Class is not an array class


getArrayBaseType

public static java.lang.Class getArrayBaseType(java.lang.Class arrayClass)
                                        throws ReflectError
Returns the base type of an array Class. throws ReflectError if the Class is not an array class.

ReflectError