An instance of this class represents a method or function that is invoked by the Ptolemy II expression evaluator. Instances of this class are returned by the static findMethod() method, and can be invoked by the apply() method. This class is used by the expression language to find Java methods that are bound in expressions that use function application, i.e. an ASTPtFunctionApplicationNode, and in method invocation, i.e. an ASTPtMethodNode.
This class is used to represent two distinct types of Java methods that can be invoked. The METHOD type corresponds to an instance method of a java class, invoked on an object of an appropriate class (the base class). The FUNCTION type corresponds to a static method of a java class. These types corresponds to the two distinct expression constructs that can be used to invoke Java methods. The type of construct reflected can be queried using the getCachedMethodType() method, which returns either {@link #FUNCTION}or {@link #METHOD}. Additionally, this class can be used to represent Java methods that were not found. If the CachedMethod corresponds to an invokeable Java method, then the isValid() method will return true. CachedMethods that are not valid cannot be invoked by the invoke() method.
This class provides several services that distinguish it from Java's built-in reflection mechanism:
- Methods are found based on name and the types of ptolemy token arguments, represented by instances of the ptolemy.data.type.Type base class.
- FUNCTIONS are searched for in a set of classes registered with the parser.
- METHODS are searched for a base class, and in all superclasses of the base class.
- Found methods, represented by instances of this class, are cached and indexed to improve the speed of method lookup. The cache is synchronized so that it can be safely accessed from multiple threads.
- Allows for the possibility of several automatic conversions that increase the applicability of single methods
The automatic conversions that are allowed on the arguments of reflected Java methods can be particularly tricky to understand. The findMethod() method is fairly aggressive about finding valid methods to invoke. In particular, given a set of arguments with token types, the findMethod() method might return a cached method that:
- Accepts token arguments of exactly the same type.
- Accepts token arguments that are of a type that the given types can be automatically converted to, as determined by the Ptolemy type lattice.
- Accepts the corresponding Java native type of either of the first two cases, i.e. an IntToken argument may reflect a method that accepts a Java int.
- Accepts a corresponding Java array type, if the argument type is an ArrayType.
- Accepts a corresponding Java array of array type, if the argument type is a MatrixType.
The underlying conversions are implemented by the {@link ConversionUtilities} class, which has more specific documentation theunderlying conversions. The inverse of the same conversions are performed on the results of a Java method invocation, in order to convert the result back into a Ptolemy token.
Since there may be many methods that match a particular function application or method invocation, under the above conversions, the findMethod() method attempts to return the most specific Java method that can be called. Generally speaking, conversions are preferred in the above order. If one Java method is not clearly preferable to all others, then the findMethod() method will throw an exception. This may happen if there are multiple functions defined with varying argument types.
Additionally, the findMethod() method may return a CachedMethod that automatically "maps" arrays and matrices over a scalar function. The result of invoking the CachedMethod is an array or matrix of whatever type is returned by the original function.
As an example of how this works, evaluation of the expression "fix([0.5, 0.1; 0.4, 0.3], 16, 1)" performs results in the invocation of the method named "fix" in the ptolemy.data.expr.FixPointFunctions that takes a Java double and two Java ints and returns an instance of ptolemy.math.FixPoint. This function is invoked once for each element of the matrix (converting each DoubleToken into the corresponding double, and each IntToken into the corresponding int), and the results are packaged back into a 2x2 FixMatrixToken.
Additional classes to be searched for static methods can be added through the method registerFunctionClass() in PtParser. This class assumes that new classes are added to the search path before models are constructed, and simply clears the internal cache and index when new classes are registered.
@author Zoltan Kemenczy, Research in Motion Limited., Steve Neuendorffer, Edward Lee
@version $Id: CachedMethod.java,v 1.88 2008/01/26 00:47:50 cxh Exp $
@since Ptolemy II 2.0
@Pt.ProposedRating Green (neuendor)
@Pt.AcceptedRating Yellow (neuendor)
@see ptolemy.data.expr.ASTPtFunctionApplicationNode
@see ptolemy.data.expr.PtParser