OK, I see the problem case you state:
> I think that has a problem in this case : when a VM invokes another VM

So the solution there is to have a MacroContext which is just a
wrapper to the base context:
  class MacroContext extends Context
  {
    private Context callerContext;

    public MacroContext(Context context)
    {
        super(10);
        callerContext = context;
    }
    public Context getRootContext()
    {
        if (callerContext instanceof MacroContext) // recurse
            return ((MacroContext) callerContext).getRootContext();
        else
            return callerContext;
    }
    public void putLocal(String key, Object value)
    {
        context.put(key, value);
    }
    public void put(String key, Object value)
    {
        getRootContext().put(key, value);
    }
    public Object get(String key)
    {
        if ( containsKey(key) )
            return context.get(key);
        else
            return getRootContext().get(key);
    }        
    /*
     * Get all the keys for the values in the context
     */
    public Object[] getKeys()
    {
        Vector v = new Vector(getRootContext().keySet())
        for (Iterator iter = context.getIterator(), iter.hasNext(); )
        {
            Object key = iter.next();
            if ( !v.contains(key) )
                v.add(key);
        }
        return v.toArray();
    }
  }

Then you create new a MacroContext for rendering and populate it
with the passed arguments via putLocal(). The rest is same as
the #foreach directive...

Thats all!

:) Christoph

Reply via email to