geirm 00/11/29 21:29:14
Modified: src/java/org/apache/velocity/runtime/parser/node
ASTMethod.java
Log:
Fixed the 'late' introspection problem, or at least one type that is common. The
issue arises when a reference is doing something like accessing a method of an
object whose class cannot be determined until actual execution.
Example :
$foo.firstElement().length()
where
$foo -> j.u.Vector of String objects.
The introspector only knows that firstElement() returns j.l.Object, so it can't
introspect to figure out the length() method.
Anyway, it's fixed.
Revision Changes Path
1.7 +32 -4
jakarta-velocity/src/java/org/apache/velocity/runtime/parser/node/ASTMethod.java
Index: ASTMethod.java
===================================================================
RCS file:
/home/cvs/jakarta-velocity/src/java/org/apache/velocity/runtime/parser/node/ASTMethod.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- ASTMethod.java 2000/11/22 12:45:32 1.6
+++ ASTMethod.java 2000/11/30 05:29:13 1.7
@@ -59,12 +59,24 @@
*
* Method support for references : $foo.method()
*
+ * NOTE :
+ *
+ * 'late introspection' : Take the example of using in a reference a container
whose methods can
+ * return Objects, such as java.util.Vector and the firstElement() or get(i)
methods, and you
+ * you follow the container element accessor with a method call on the object
returned :
+ *
+ * $foo.firstElement().getValue()
+ *
+ * where $foo is a Vector. In this case, the introspection cannot figure
+ * out at init() time what class actually is returned by the accessor
firstElement(). To solve this
+ * we now will call init() on the ASTMethod node in execute() when the init()
failed.
+ *
* Please look at the Parser.jjt file which is
* what controls the generation of this class.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Geir Magnusson Jr.</a>
- * @version $Id: ASTMethod.java,v 1.6 2000/11/22 12:45:32 geirm Exp $
+ * @version $Id: ASTMethod.java,v 1.7 2000/11/30 05:29:13 geirm Exp $
*/
package org.apache.velocity.runtime.parser.node;
@@ -75,6 +87,7 @@
import org.apache.velocity.runtime.parser.*;
import org.apache.velocity.util.introspection.Introspector;
+
public class ASTMethod extends SimpleNode
{
private String methodName;
@@ -117,9 +130,9 @@
for (int j = 0; j < paramCount; j++)
params[j] = jjtGetChild(j + 1).value(context);
-
- method = Introspector.getMethod((Class) data, methodName, params);
-
+
+ method = Introspector.getMethod( (Class) data, methodName, params);
+
if (method == null)
return null;
@@ -143,6 +156,21 @@
try
{
+ /*
+ * it is possible that we have to do late introspection. If we don't
+ * have a valid method object, cast this object to a Class, and try
init()
+ * again. As far as I can tell, the only time that the introspection
+ * fails is when we try to case a j.l.Object to a Class, which is the
+ * fast track to a ClassCastException
+ * See the notes above.
+ */
+
+ if (method == null)
+ {
+ Class c = o.getClass();
+ init( context, c);
+ }
+
/*
* get the returned object. It may be null, and that is
* valid for something declared with a void return type.