public abstract class SymbolResolver extends java.lang.Object implements CompilerConstants
General Use
In order to enable full support for user expressions which are sensitive
to the context of the application, client code must register one or more
objects as callback libraries before expressions are submitted to the
engine for processing. This is done using the registerLibrary(com.goldencode.expr.Scope, java.lang.String, java.lang.Object)
method, which exposes the public methods of the registered object's class
to user expressions. Once a library object is registered, the following
user expression library constructs/concepts are managed at this abstract
implementation level:
get/isXXXX()
or
setXXXX(<property>)
), these methods are used to
expose the backing property to user expressions. Each property can
then be used in an expression by its simple name for access and
assignment purposes (e.g., "Larry" == name
or
stooge.name = "Moe"
). Properties may be referenced in
an expression either with a library qualifier or without. In the
latter case, the property name must be unambiguous among all
registered libraries, else an exception will be thrown at expression
compile time.
<target>.<method>([argument-list...])
.
It is not necessary for the concrete symbol resolver implementation
to know how to resolve or invoke these types of method calls;
however, it will have an opportunity to deny permission for an
expression to access any class or invoke any method via the built-in
security mechanism.
In addition to callback libraries, the symbol resolver manages variable
pools, segregated by scope and within scope, by name.
A variable has a data type, which is declared at the time it is registered
. Optionally, it also has an initializer
expression associated with it, which is used to set the value of the
variable whenever it is reset
.
A Variable
is referenced in user expressions by its name. During
expression parsing, a variable's name symbol is resolved into one of the
following method invocations:
CompiledExpression.getVar(int)
- used if the value of the variable
is being retrieved in the context of the expression (e.g.,
myVar + 50 == 100
).
CompiledExpression.setVar(int, java.lang.Object)
- used if the value of the variable
is being set in the context of the expression, via an assignment
(e.g., myVar = 100 - 50
).
Variable pools are maintained transparently by the expression engine.
References to variable names in expressions are resolved using the
resolver's current scope
, and any enclosing
scopes if not found in the current scope. Thus, variables must be
registered within a defined scope. Variables may contain simple literal
values or more complex objects. It is legal to invoke a method against
a variable symbol in a user expression. It is not necessary to
unwrap primitive literals from their Java wrappers, such as
Long
, Integer
, Boolean
, and
Double
. Autoboxing and some simple type conversion is done
automatically by the expression engine.
A concrete symbol resolver implementation is responsible for managing
only one construct in a user expression: constants. Constants are symbols
which are resolved at expression parse time into simple objects. These
objects represent numeric or string literals. Although a constant is an
object, it is illegal to invoke a method against a constant symbol in a
user expression. Constants are resolved when the expression engine calls
the resolveConstant(java.lang.String, java.lang.String)
method. The default implementation of this
method returns null
. Subclasses should override this method
if it is necessary to support an application-specific set of constant
values.
Care should be taken when choosing constant and variable names to avoid conflicts with the names of properties exposed via registered callback libraries. The order of precedence when resolving these is:
These conflicts are not detected automatically by the expression engine. A conflict will manifest itself as the lack of a call to a getter/setter method (for properties) or the lack of a request to resolve a symbol name to an object (for variables).
Scope
A concrete implementation of this class is also responsible for defining
a scoping mechanism. Scopes are used to segregate variable pools and
library reference mappings, such that sibling scopes can each have
variables and libraries mapped to the same names without producing
conflicts. Scopes may be nested, which allows a user expression to refer
to variables and libraries defined for scopes which enclose the current
scope. The details of how scopes are arranged and defined are completely
up to the client code layer. The mechanism defined by the client is
shared with the expression engine through several methods:
registerLibrary(com.goldencode.expr.Scope, java.lang.String, java.lang.Object)
registerVariable(com.goldencode.expr.Scope, java.lang.String, java.lang.Class<?>, com.goldencode.expr.Initializer, boolean)
getCurrentScope()
resetVariables(com.goldencode.expr.Scope, boolean)
Scope.getEnclosingScope()
Scope
is used to define the context
of the libraries and/or variables being manipulated.
Important: it is critical that certain method invocations on Expression
be allowed to complete within the context of a single scope.
The scope should not change while any of the following method invocations
are in progress:
Security Considerations
The ability to invoke arbitrary methods from within a user expression has
obvious security implications. Security is enforced by an implementation
of this class by overriding the checkPermission(java.lang.Class<?>, java.lang.reflect.Method, boolean)
method. This
callback is invoked by the expression engine during parsing of an
expression. As method invocations are detected, this hook is used to
request permission to allow the method to be invoked at runtime. In the
event that the method is detected to be within a registered library, the
registered
parameter of checkPermission
is
set to true
; otherwise, it is set to false
.
No additional runtime check is made, so if a method invocation
is permitted at parse time, it will be permitted each time the
expression is executed..
By default, security is disabled. To enable the permission check
mechanism, subclasses must override the checkPermission
method.
Modifier and Type | Class and Description |
---|---|
private static class |
SymbolResolver.CacheKey
Helper class which is used to assist in lookups of methods when
introspecting invocation target classes.
|
private static class |
SymbolResolver.TestResolver
Concrete implementation of a
SymbolResolver for simple
testing and debug purposes. |
Modifier and Type | Field and Description |
---|---|
private java.lang.ref.SoftReference |
cacheRef
Cache of functions, used for quick method lookups during parsing
|
private Scope |
currentScope
Current scope for library and variable resolution
|
private static java.util.Map<Scope,java.util.Map<java.lang.Object,CompiledExpression>> |
instCache
Compiled expression instance cache
|
private static java.util.concurrent.locks.ReentrantLock |
instCacheLock
Mutex lock on compiled expression instance cache
|
private java.util.Map |
libraries
Map of libraries by scope, name; used at parse and compile time
|
private java.util.Map |
libraryClasses
Map of library classes by scope
|
private java.util.Map<Scope,java.util.Map<java.lang.Class<?>,java.lang.Object>> |
libsByClass
Library targets by scope, then by class
|
private static java.lang.reflect.Method |
METH_GET_LIB
Static method within CompiledExpression to get library at runtime
|
private static java.lang.reflect.Method |
METH_GET_VAR
Static method within CompiledExpression to get variable at runtime
|
private static java.lang.reflect.Method |
METH_SET_VAR
Static method within CompiledExpression to set variable at runtime
|
private java.util.Map |
variables
Map of user variables by scope, name; used at parse and compile time
|
_aastore, _aconst_null, _aload_0, _aload_1, _aload_2, _aload_3, _anewarray, _areturn, _astore_1, _astore_2, _astore_3, _checkcast, _d2i, _d2l, _dadd, _dcmpg, _dconst_0, _dconst_1, _ddiv, _dmul, _dneg, _drem, _dreturn, _dsub, _dup, _getfield, _goto, _i2d, _i2l, _iadd, _iand, _iconst_0, _iconst_1, _iconst_2, _iconst_3, _iconst_4, _iconst_5, _idiv, _if_icmpeq, _if_icmpge, _if_icmpgt, _if_icmple, _if_icmplt, _if_icmpne, _ifeq, _ifge, _ifgt, _ifle, _iflt, _ifne, _ifnonnull, _ifnull, _imul, _ineg, _invokeinterface, _invokespecial, _invokestatic, _invokevirtual, _ior, _irem, _ireturn, _ishl, _ishr, _isub, _iushr, _ixor, _l2d, _l2i, _ladd, _land, _lcmp, _lconst_0, _lconst_1, _ldc_w, _ldc2_w, _ldiv, _lmul, _lneg, _lor, _lrem, _lshl, _lshr, _lsub, _lushr, _lxor, _new, _pop, _pop2, _return, _swap, CLASS_COMPILEDEXPRESSION, METHDESC_EXECUTE, METHNAME_EXECUTE, METHOD_INIT
Constructor and Description |
---|
SymbolResolver() |
Modifier and Type | Method and Description |
---|---|
private void |
accessCheck(Function func,
boolean registered)
Performs an access check to obtain permission to compile a method
invocation into a compiled expression.
|
protected boolean |
checkPermission(java.lang.Class<?> target,
java.lang.reflect.Method method,
boolean registered)
Check whether a user expression has permission to invoke the specified
method on the specified target class.
|
void |
dropLibrary(Scope scope,
java.lang.String name)
Drop a particular function library from the scope of libraries
registered at the given scope.
|
void |
dropVariable(Scope scope,
java.lang.String name)
Drop a particular variable from a variable pool.
|
void |
dropVariablePool(Scope scope)
Drop a pool of variables.
|
(package private) void |
dumpVariablePool()
A debug method which dumps the contents of the combined pool of
variables (across all scopes) to
stderr . |
(package private) CompiledExpression |
getCachedInstance(Scope scope,
java.lang.Object key)
Obtain a cached expression instance if the given key exists in the
cache at the given scope.
|
protected abstract Scope |
getCurrentScope()
This method should return the scope currently associated with the
symbol resolver.
|
(package private) java.lang.Object |
getLibraryTarget(Scope scope,
java.lang.Class<?> cls)
Retrieve a callback library object of the given type which is registered
within the context of the given scope.
|
(package private) java.lang.Object |
getLibraryTarget(Scope scope,
java.lang.String name)
Retrieve a callback library object with the given name which is
registered within the context of the given scope.
|
(package private) static SymbolResolver |
getTestResolver()
Return an implementation of this abstract class for test and debugging
purposes.
|
Variable |
getVariable(Scope scope,
java.lang.String name)
Retrieve a variable with the given name which is registered within the
context of the given scope.
|
private Function |
introspectFunction(SymbolResolver.CacheKey key)
Use introspection to find a specific method within a specific target
class by an exact match of the method's name and an exact or fuzzy
match of the method's parameter signature.
|
private boolean |
isRegisteredLibrary(Scope scope,
java.lang.Class<?> cls)
Convenience method to determine whether
cls represents
a callback library which has previously been registered in
scope . |
(package private) void |
lockInstanceCache()
Lock the compiled expression instance cache.
|
private Function |
matchTargetMethod(java.lang.Class<?> target,
java.lang.String name,
java.lang.Class<?>[] signature,
boolean registered,
boolean strict)
Introspect the specified target class to try to match a method with
the specified name and signature.
|
(package private) void |
putCachedInstance(Scope scope,
java.lang.Object key,
CompiledExpression ce)
Add a cached expression instance to the cache and map it with the
given key at the given scope.
|
void |
registerLibrary(Scope scope,
java.lang.String name,
java.lang.Object target)
Register the target object as a runtime callback library.
|
Variable |
registerVariable(Scope scope,
java.lang.String name,
java.lang.Class<?> type,
Initializer initializer,
boolean readOnly)
Create a new user variable and register it for use within expressions.
|
void |
resetVariables(Scope scope,
boolean nullify)
Reset all variables in the specified scope to the values generated by
their respective initializer expressions, or to
null . |
protected java.lang.Object |
resolveConstant(java.lang.String qualifier,
java.lang.String constant)
Overriding implementations of this method should resolve the specified
string constant to a literal object.
|
(package private) Function |
resolveFunction(Function function,
java.lang.String name,
boolean isSetter)
Resolve the symbol
name to a Java bean-style "getter" or
"setter" method, where name represents the name of the
object being accessed or set. |
private Function |
resolveFunction(Function function,
java.lang.String name,
boolean isSetter,
Scope scope)
Resolve the symbol
name to a Java bean-style "getter" or
"setter" method, where name represents the name of the
object being accessed or set. |
(package private) Function |
resolveFunction(Function function,
java.lang.String name,
java.lang.Class<?>[] signature)
Resolve the symbol
name to a Java method with the given
signature, where function , if not null ,
defines the method which will be invoked to retrieve the target object
upon which the method represented by name will be invoked. |
private Function |
resolveFunction(Function function,
java.lang.String name,
java.lang.Class<?>[] signature,
Scope scope)
Resolve the symbol
name to a Java method with the given
signature, where function , if not null ,
defines the method which will be invoked to retrieve the target object
upon which the method represented by name will be invoked. |
(package private) void |
unlockInstanceCache()
Unock the compiled expression instance cache.
|
private static final java.lang.reflect.Method METH_GET_LIB
private static final java.lang.reflect.Method METH_GET_VAR
private static final java.lang.reflect.Method METH_SET_VAR
private static final java.util.Map<Scope,java.util.Map<java.lang.Object,CompiledExpression>> instCache
private static final java.util.concurrent.locks.ReentrantLock instCacheLock
private final java.util.Map libraries
private final java.util.Map variables
private final java.util.Map libraryClasses
private final java.util.Map<Scope,java.util.Map<java.lang.Class<?>,java.lang.Object>> libsByClass
private java.lang.ref.SoftReference cacheRef
private Scope currentScope
static SymbolResolver getTestResolver()
SymbolResolver
implementation.public final void registerLibrary(Scope scope, java.lang.String name, java.lang.Object target)
lib.format = "zz9"
is
an acceptable notation which would translate to a library call of
lib.setFormat("zz9")
, and test(lib.format)
would translate to test(lib.getFormat())
, where
public void setFormat(String)
and public String
getFormat()
are members of the registered library named
lib
.scope
- Scope associated with the library being registered. May not
be null
.name
- Name associated with the library being registered. If
provided, this name may be used in expressions to qualify
references to methods and properties (exposed via Java-bean
style getters/setters) in the registered library. Only one
library target may be registered to this name per scope.
A single library per scope can be registered with a
null
name.target
- Target object whose class implements public methods which
are exposed to expressions.java.lang.NullPointerException
- if scope
is null
.AmbiguousSymbolException
- if name
is already in use within the specified
scope, or if an instance of target
's class is
already registered in this scope.getCurrentScope()
public final void dropLibrary(Scope scope, java.lang.String name)
scope
- Scope with which target library is associated.name
- Name of library to be dropped.public final Variable registerVariable(Scope scope, java.lang.String name, java.lang.Class<?> type, Initializer initializer, boolean readOnly)
myVar + 50 == 100
), or to set the value of the
variable using assignment syntax (e.g., myVar = 100 - 50
).
If a variable is registered as read-only, the latter syntax is not
permitted, however. Variables may also have methods invoked upon them.
The methods permitted are those supported by the variable's data type.
If a variable represents an object wrapper which contains a primitive
value (e.g., an instance of java.lang.Integer
), it is
not necessary to invoke any method to unwrap the primitive
(e.g. myVar.intValue()
) value in order to use it.
Autoboxing and some simple type conversions are performed automatically
by the expression engine when compiling the expression.scope
- Scope associated with the variable being registered. May not
be null
.name
- The name under which the variable is registered in this scope.
Must not be null
.type
- The data type of the variable. If null
, the
return type of initializer
is used. If not
null
, it must be assignment compatible
(considering autoboxing and simple type conversions) with
the return type of initializer
. If
initializer
is null
, this parameter
is required.initializer
- A helper which is used to initialize the value of the
new variable. See description of type
parameter
for details on how this helper's return type is considered
with respect to the variable's data type. This parameter may
be null
if type
is not. If no
initializer is provided, the variable's value will be
initialized to null
whenever the variable is
reset
. The initializer is applied
immediately during construction of the variable, so any
libraries or variables it references must already be
registered. It should be assumed that any initializer
expression for a variable will execute in the same scope as
is defined for the variable.readOnly
- If true
, this variable's value may not be set
from within an expression. If false
, assignments
to this variable in an expression are permitted. Regardless
of whether a variable is registered as read-only, its value
may always be changed programmatically using Variable.setValue(java.lang.Object)
.Variable
object will be
required after registration (e.g., to invoke the object's
Variable.setValue(java.lang.Object)
method directly). An alternate
method to retrieve the variable object after registration is
the getVariable(com.goldencode.expr.Scope, java.lang.String)
method.java.lang.NullPointerException
- if either scope
or name
is
null
.SymbolException
- if name
is already registered to a variable
declared in scope
; if type
represents a primitive class; if type
was
null
and could not be determined from
initializer
's return type; if type
was not null
and was incompatible with
initializer
's return type.public final Variable getVariable(Scope scope, java.lang.String name)
scope
- Scope under which variable is registered.name
- Name under which variable is registered.null
if none was
found.public final void dropVariable(Scope scope, java.lang.String name)
scope
- Scope with which target variable pool is associated.name
- Name of variable to be dropped.public final void dropVariablePool(Scope scope)
scope
- Scope with which the target variable pool is associated.public final void resetVariables(Scope scope, boolean nullify)
null
. If a
variable has no associated initializer expression or the parameter
nullify
is set to true, that variable's value is reset to
null
.
The current scope of the symbol resolver is temporarily overridden to be the specified scope, such that the initializer expressions associated with the variables in this pool are executed in the proper scope.
Currently, variables are not reset recursively within nested scopes;
only the variables directly associated with scope
are
reset.
scope
- Scope for which variables are to be reset.nullify
- If true
, null out variables' values; else use
the variables' default reset behavior.protected boolean checkPermission(java.lang.Class<?> target, java.lang.reflect.Method method, boolean registered)
This method is called only while an expression is parsed, never during
expression execution. It may be called multiple times for the same
combination of target
and method
while
parsing a single expression, if a symbol representing that method
invocation is encountered multiple times in that expression.
If permission is denied with a return of false
, a
SecurityException
will be thrown during expression
parsing, and the expression will not be compiled or executed.
The default implementation of this method always returns
true
; this method must be overridden to implement a
stricter security policy.
target
- Class containing method
.method
- Method which would be invoked at expression execution time
if permission is granted.registered
- true
if the method is registered as part of a
function library; false
if the method
is one that is invoked explicitly on an object symbol within
a user expression.true
to grant permission; false
to
deny it. This determination is completely at the discretion
of the implementing class, based upon its required security
policy.protected abstract Scope getCurrentScope()
Scope
interface, but its implementation is completely up to the
concrete implementation of this class. This method is called at
the moment an expression is first executed, during parsing and
compilation.protected java.lang.Object resolveConstant(java.lang.String qualifier, java.lang.String constant)
A return of any other type will cause a parsing error.
This method is invoked once per expression, at the time the expression
is first parsed by the ExpressionParser
. It is invoked for a
string which is not enclosed in any quotation marks, which is
embedded within an expression.
qualifier
- An optional qualifier for concrete implementations which must
support multiple namespaces. A qualifier is not mandatory for
constants, so this parameter may be null
.constant
- The string constant to be resolved to a literal.symbol
, or
null
if the symbol is not recognized.final java.lang.Object getLibraryTarget(Scope scope, java.lang.String name)
scope
- Scope under which library is registered.name
- Name under which library is registered.null
if none was
found.final java.lang.Object getLibraryTarget(Scope scope, java.lang.Class<?> cls)
scope
- Scope under which library is registered.cls
- Type of the library.null
if none was
found.final Function resolveFunction(Function function, java.lang.String name, boolean isSetter)
name
to a Java bean-style "getter" or
"setter" method, where name
represents the name of the
object being accessed or set. This may be (in the order of matching
precedence):
The search for a matching method commences in the resolver's current scope
and continues in enclosing scopes
as necessary, until a match
is found, or no more enclosing scopes exist.
This method is called by the ExpressionParser
when a symbol
is encountered which could not be resolved as a constant.
function
- Function object which contains the class upon which the
getter/setter will be invoked. May be null
, in
which case it is assumed the method is invoked on a registered
callback library.name
- Name of the object for which the getter or setter method is
required. Should begin with a lower case character.isSetter
- true
if looking up the setter method;
false
if looking up the getter method.Method
which
will be invoked, the class of the target object upon which
the method will be invoked, and the target object reference.
If none can be found in the current scope, or in progressively
broader enclosing scopes, null
is returned.CompiledExpression getCachedInstance(Scope scope, java.lang.Object key)
scope
- Scope at which the target expression would be cached.key
- Used to lookup the instance in our cache.null
if no instance is
mapped to the given key.void putCachedInstance(Scope scope, java.lang.Object key, CompiledExpression ce)
scope
- Scope at which the target expression is to be cached.key
- Used to lookup the instance in our cache.ce
- The instance to store.void lockInstanceCache()
unlockInstanceCache()
.void unlockInstanceCache()
lockInstanceCache()
.private Function resolveFunction(Function function, java.lang.String name, boolean isSetter, Scope scope)
name
to a Java bean-style "getter" or
"setter" method, where name
represents the name of the
object being accessed or set. This may be (in the order of matching
precedence):
The search for a matching method is limited to the specified scope.
function
- Function object which contains the class upon which the
getter/setter will be invoked. May be null
, in
which case it is assumed the method is invoked on a registered
callback library.name
- Name of the object for which the getter or setter method is
required. Should begin with a lower case character.isSetter
- true
if looking up the setter method;
false
if looking up the getter method.scope
- Scope to be searched.Method
which
will be invoked, the class of the target object upon which
the method will be invoked, and the target object reference.
If none can be found in the current scope, null
is returned.final Function resolveFunction(Function function, java.lang.String name, java.lang.Class<?>[] signature)
name
to a Java method with the given
signature, where function
, if not null
,
defines the method which will be invoked to retrieve the target object
upon which the method represented by name
will be invoked.
The search for a matching method commences in the resolver's current scope
and continues in enclosing scopes
as necessary, until a match
is found, or no more enclosing scopes exist.
This method is called by the ExpressionParser
when the syntax
which represents a method invocation is encountered in an expression.
function
- Object which holds information about the method which is
invoked to retrieve the target object. If null
,
it is assumed that name
represents a method in
a registered callback library.name
- Full name of the target method, with proper case.signature
- An array of the classes which comprise the target method's
parameter list. This represents the list of argument types
as parsed from a user expression. If a null
parameter is passed to a method/function in the expression,
and there is no corresponding, explicit cast, the associated
slot in the array will have no corresponding class. Also, for
methods which simulate variable argument lists by using an
array of Object
s as the last parameter, the
lookup logic takes into account that this final argument
has been "flattened out" in the user expression, such that
we only see a one dimensional array of classes here.Method
which
will be invoked, the class of the target object upon which
the method will be invoked, and the target object reference.
If none can be found in the current scope, or in progressively
broader enclosing scopes, null
is returned.private Function resolveFunction(Function function, java.lang.String name, java.lang.Class<?>[] signature, Scope scope)
name
to a Java method with the given
signature, where function
, if not null
,
defines the method which will be invoked to retrieve the target object
upon which the method represented by name
will be invoked.
The search for a matching method is limited to the specified scope.
This method is called by the ExpressionParser
when the syntax
which represents a method invocation is encountered in an expression.
function
- Object which holds information about the method which is
invoked to retrieve the target object. If null
,
it is assumed that name
represents a method in
a registered callback library.name
- Full name of the target method, with proper case.signature
- An array of the classes which comprise the target method's
parameter list. This represents the list of argument types
as parsed from a user expression. If a null
parameter is passed to a method/function in the expression,
and there is no corresponding, explicit cast, the associated
slot in the array will have no corresponding class. Also, for
methods which simulate variable argument lists by using an
array of Object
s as the last parameter, the
lookup logic takes into account that this final argument
has been "flattened out" in the user expression, such that
we only see a one dimensional array of classes here.scope
- Scope to be searched.Method
which
will be invoked, the class of the target object upon which
the method will be invoked, and the target object reference.
If none can be found in the current scope, null
is returned.private Function introspectFunction(SymbolResolver.CacheKey key)
A cache is employed to short-circuit the search logic and quickly provide a return if we have conducted a search with the same criteria before. The cache records criteria for failed searches as well as those for successful searches, so that we have a quick response in either case.
If a method match is found, an access check
is
conducted to ensure we have permission to compile this method
invocation into the compiled expression. By default, this check will
always pass, unless the concrete, symbol resolver subclass has
overridden checkPermission(java.lang.Class<?>, java.lang.reflect.Method, boolean)
to behave differently.
The search for a method match considers that the expression may be using a variable length argument list. This is only the case when the invocation target is a registered callback library. For targets which are not registered callback library objects, a reflexive method lookup which assumes an exact parameter signature match is attempted first. If this fails, or if the target class is the type of a registered callback library, several "fuzzy" signature matches are attempted, in the following order:
int
and java.lang.Integer
).
If the invocation target type is an interface, the above sequence is
performed first for all methods of the interface (and all
superinterfaces). If this fails to produce a match, the sequence is
repeated for the java.lang.Object
class.
Whether or not a method is detected, the result is stored in the lookup
cache under the provided CacheKey
(null
is
stored for a failed lookup).
key
- A cache key which defines scope, invocation target type,
method name, and method signature.Method
which
will be invoked, the class of the target object upon which
the method will be invoked, and class of the object which
is expected to be returned from the method invocation. If no
match is found, null
is returned.java.lang.SecurityException
- if the method invocation is disallowed by the security policy
of the concrete implementation of this class.AmbiguousSymbolException
- if any single application of a strict or lenient signature
match algorithm against the list of methods in the target
class being introspected detects more than one method which
matches the search criteria.private Function matchTargetMethod(java.lang.Class<?> target, java.lang.String name, java.lang.Class<?>[] signature, boolean registered, boolean strict)
strict
parameter:
int
and java.lang.Integer
).
target
- Method invocation target; the class being introspected for a
matching method.name
- Exact (case-sensitive) name of the method to be matched.signature
- Array of types of the parameters being passed to the target
method. May contain null
elements if the type
could not be determined.registered
- true
if target
is the class of a
registered callback library; else false
.strict
- true
to perform a strict signature match;
false
to perform a lenient signature match.Method
which
will be invoked, the class of the target object upon which
the method will be invoked, and class of the object which
is expected to be returned from the method invocation. If no
match is found, null
is returned.AmbiguousSymbolException
- if more than one method which matches the search criteria is
detected.private void accessCheck(Function func, boolean registered)
func
- Object from which the invocation target and method are
retrieved.registered
- true
if the invocation target represents a
registered callback library; false
if it
represents an unregistered class.java.lang.SecurityException
- if permission to compile the method invocation into the
expression is denied.private boolean isRegisteredLibrary(Scope scope, java.lang.Class<?> cls)
cls
represents
a callback library which has previously been registered in
scope
.scope
- Scope in which to check.cls
- The class for which we are searching.true
if cls
was found in
scope
, else false
.void dumpVariablePool()
stderr
.