jvanzyl     00/10/19 19:18:44

  Modified:    src/java/org/apache/velocity/runtime/directive Foreach.java
  Log:
  - now using the ArrayIterator to wrap arrays, code borrowed from
    JServ. There is a neglible amount of overhead added but makes
    the code in the foreach directive a lot smaller and is making
    the template compiler easier to deal with.
  
  Revision  Changes    Path
  1.9       +28 -45    
jakarta-velocity/src/java/org/apache/velocity/runtime/directive/Foreach.java
  
  Index: Foreach.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-velocity/src/java/org/apache/velocity/runtime/directive/Foreach.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- Foreach.java      2000/10/15 20:28:05     1.8
  +++ Foreach.java      2000/10/20 02:18:43     1.9
  @@ -65,23 +65,17 @@
   import org.apache.velocity.Context;
   import org.apache.velocity.runtime.Runtime;
   import org.apache.velocity.util.ClassUtils;
  +import org.apache.velocity.util.ArrayIterator;
   
   import org.apache.velocity.runtime.parser.Node;
   import org.apache.velocity.runtime.parser.Token;
   
  -//! TODO: wrap arrays in an iterator so we can
  -//        get rid of the array/iterator check just
  -//        make everything an iterator.
  -
   /**
    * Foreach directive used for moving through arrays,
    * or objects that provide an Iterator.
    */
   public class Foreach extends Directive
   {
  -    public String getName() { return "foreach"; }        
  -    public int getType() { return BLOCK; }
  -
       private final static int ARRAY = 1;
       private final static int ITERATOR = 2;
       
  @@ -95,14 +89,22 @@
       private Object listObject;
       private Object tmp;
       private int iterator;
  +
  +    public String getName() 
  +    { 
  +        return "foreach"; 
  +    }
       
  +    public int getType() 
  +    { 
  +        return BLOCK; 
  +    }
  +
       public void init(Context context, Node node) throws Exception
       {
           Object sampleElement = null;
  +        elementKey = node.jjtGetChild(0).getFirstToken().image.substring(1);
           
  -        elementKey = node.jjtGetChild(0).getFirstToken()
  -                        .image.substring(1);
  -        
           // This is a refence node and it needs to
           // be inititialized.
           
  @@ -123,12 +125,11 @@
               node.setInfo(ITERATOR);
               sampleElement = ((Collection) listObject).iterator().next();
           }            
  -    
  +        
           // This is a little trick so that we can initialize
           // all the blocks in the foreach  properly given
           // that there are references that refer to the
           // elementKey name.
  -        
           if (sampleElement != null)
           {
               context.put(elementKey, sampleElement);
  @@ -140,41 +141,23 @@
       public void render(Context context, Writer writer, Node node)
           throws IOException
       {
  +        Iterator i;
           listObject = node.jjtGetChild(2).value(context);
  +
  +        if (node.getInfo() == ARRAY)
  +            i = new ArrayIterator((Object[]) listObject);
  +        else            
  +            i = ((Collection) listObject).iterator();
           
  -        switch(node.getInfo())
  +        iterator = COUNTER_INITIAL_VALUE;
  +        while (i.hasNext())
           {
  -            case ARRAY:
  -                int length = ((Object[]) listObject).length;
  -            
  -                for (int i = 0; i < length; i++)
  -                {
  -                    context.put(COUNTER_IDENTIFIER, 
  -                        new Integer(i + COUNTER_INITIAL_VALUE));
  -                    context.put(elementKey,((Object[])listObject)[i]);
  -                    node.jjtGetChild(3).render(context, writer);
  -                }
  -                context.remove(COUNTER_IDENTIFIER);
  -                context.remove(elementKey);
  -                break;
  -            
  -            case ITERATOR:
  -                // Maybe this could be optimized with get(index) ?
  -                // Check the interface. size() and get(index) might
  -                // be faster then using an Iterator.
  -                Iterator i = ((Collection) listObject).iterator();
  -                
  -                iterator = COUNTER_INITIAL_VALUE;
  -                while (i.hasNext())
  -                {
  -                    context.put(COUNTER_IDENTIFIER, new Integer(iterator));
  -                    context.put(elementKey,i.next());
  -                    node.jjtGetChild(3).render(context, writer);
  -                    iterator++;
  -                }
  -                context.remove(COUNTER_IDENTIFIER);
  -                context.remove(elementKey);
  -                break;
  -        }            
  +            context.put(COUNTER_IDENTIFIER, new Integer(iterator));
  +            context.put(elementKey,i.next());
  +            node.jjtGetChild(3).render(context, writer);
  +            iterator++;
  +        }
  +        context.remove(COUNTER_IDENTIFIER);
  +        context.remove(elementKey);
       }
   }
  
  
  

Reply via email to