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.
  
  
  

Reply via email to