You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by ge...@locus.apache.org on 2000/12/31 00:46:22 UTC

cvs commit: jakarta-velocity/whiteboard/geir_context_20001228 InternalContextAdapter.java Template.java AbstractContext.java Context.java DBContext.java HashMapContext.java InternalContext.java InternalContextBase.java README.txt TreeMapContext.java VelocityContext.java velocity-0.71.jar

geirm       00/12/30 15:46:20

  Modified:    whiteboard/geir_context_20001228 AbstractContext.java
                        Context.java DBContext.java HashMapContext.java
                        InternalContext.java InternalContextBase.java
                        README.txt TreeMapContext.java VelocityContext.java
                        velocity-0.71.jar
  Added:       whiteboard/geir_context_20001228 InternalContextAdapter.java
                        Template.java
  Log:
  Another update to decouple the internal context from app level context in
  a safe and secure way.  Now the two are separate.  All caching functionality
  is still supported across context uses if so desired.  See notes.
  
  Revision  Changes    Path
  1.4       +3 -3      jakarta-velocity/whiteboard/geir_context_20001228/AbstractContext.java
  
  Index: AbstractContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/AbstractContext.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- AbstractContext.java	2000/12/30 14:42:00	1.3
  +++ AbstractContext.java	2000/12/30 23:46:18	1.4
  @@ -1,4 +1,4 @@
  -package org.apache.velocity;
  +package org.apache.velocity.context;
   
   /*
    * The Apache Software License, Version 1.1
  @@ -62,7 +62,7 @@
   import java.util.Enumeration;
   
   import org.apache.velocity.util.ArrayIterator;
  -import org.apache.velocity.InternalContextBase;
  +import org.apache.velocity.context.InternalContextBase;
   
   /**
    * This class is the abstract base class for all Velocity Context 
  @@ -70,10 +70,10 @@
    * abstract routines that access your preferred storage method.
    *
    * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
  - * @version $Id: AbstractContext.java,v 1.3 2000/12/30 14:42:00 geirm Exp $
  + * @version $Id: AbstractContext.java,v 1.4 2000/12/30 23:46:18 geirm Exp $
    */
   
  -public abstract class AbstractContext extends InternalContextBase  implements Context, InternalContext,  Serializable
  +public abstract class AbstractContext extends InternalContextBase  implements Context, Serializable
   {
       /**
        *  we handle the context wrapping
  
  
  
  1.3       +1 -2      jakarta-velocity/whiteboard/geir_context_20001228/Context.java
  
  Index: Context.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/Context.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Context.java	2000/12/30 14:42:00	1.2
  +++ Context.java	2000/12/30 23:46:18	1.3
  @@ -1,4 +1,4 @@
  -package org.apache.velocity;
  +package org.apache.velocity.context;
   
   /*
    * The Apache Software License, Version 1.1
  @@ -58,7 +58,6 @@
   import java.io.Serializable;
   
   import org.apache.velocity.util.ArrayIterator;
  -import org.apache.velocity.InternalContext;
   
   /**
    * This class provides the storage location for all dynamic
  @@ -69,7 +68,7 @@
    * are stored in a Hashtable. 
    * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
    * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
  - * @version $Id: Context.java,v 1.2 2000/12/30 14:42:00 geirm Exp $
  + * @version $Id: Context.java,v 1.3 2000/12/30 23:46:18 geirm Exp $
    */
   public interface Context
   {
  
  
  
  1.2       +3 -0      jakarta-velocity/whiteboard/geir_context_20001228/DBContext.java
  
  Index: DBContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/DBContext.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DBContext.java	2000/12/29 23:09:00	1.1
  +++ DBContext.java	2000/12/30 23:46:18	1.2
  @@ -4,6 +4,9 @@
   import java.io.Serializable;
   import java.io.*;
   
  +import org.apache.velocity.context.AbstractContext;
  +import org.apache.velocity.context.Context;
  +
   /**
    *   Example context impl that uses a database to store stuff :)
    *
  @@ -19,7 +22,7 @@
    *  very fragile, crappy code.... just a demo!
    *
    * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
  - * @version $Id: DBContext.java,v 1.1 2000/12/29 23:09:00 geirm Exp $
  + * @version $Id: DBContext.java,v 1.2 2000/12/30 23:46:18 geirm Exp $
    */
   
   public class DBContext extends AbstractContext
  
  
  
  1.2       +2 -0      jakarta-velocity/whiteboard/geir_context_20001228/HashMapContext.java
  
  Index: HashMapContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/HashMapContext.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- HashMapContext.java	2000/12/29 19:21:28	1.1
  +++ HashMapContext.java	2000/12/30 23:46:18	1.2
  @@ -56,12 +56,14 @@
   
   import java.util.HashMap;
   import java.io.Serializable;
  +import org.apache.velocity.context.AbstractContext;
  +import org.apache.velocity.context.Context;
   
   /**
    *   Example context impl that uses a HashMap
    *
    * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
  - * @version $Id: HashMapContext.java,v 1.1 2000/12/29 19:21:28 geirm Exp $
  + * @version $Id: HashMapContext.java,v 1.2 2000/12/30 23:46:18 geirm Exp $
    */
   
   public class HashMapContext extends AbstractContext
  
  
  
  1.2       +5 -5      jakarta-velocity/whiteboard/geir_context_20001228/InternalContext.java
  
  Index: InternalContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/InternalContext.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- InternalContext.java	2000/12/30 14:42:00	1.1
  +++ InternalContext.java	2000/12/30 23:46:18	1.2
  @@ -1,4 +1,4 @@
  -package org.apache.velocity;
  +package org.apache.velocity.context;
   
   /*
    * The Apache Software License, Version 1.1
  @@ -68,7 +68,7 @@
    *  support, as well as node-local context data introspection caching.
    *
    * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
  - * @version $Id: InternalContext.java,v 1.1 2000/12/30 14:42:00 geirm Exp $
  + * @version $Id: InternalContext.java,v 1.2 2000/12/30 23:46:18 geirm Exp $
    */
   public interface InternalContext
   {
  @@ -77,14 +77,14 @@
        *
        *  @param s current template name to set
        */
  -    public void setCurrentTemplateName( String s );
  +     void setCurrentTemplateName( String s );
       
       /**
        *  get the current template name
        *
        *  @return String current template name
        */
  -    public String getCurrentTemplateName();
  +     String getCurrentTemplateName();
   
       /**
        *  returns an IntrospectionCache Data (@see IntrospectionCacheData)
  @@ -93,7 +93,7 @@
        *  @param key  key to find in cache
        *  @return cache object
        */
  -    public IntrospectionCacheData icacheGet( Object key );
  +     IntrospectionCacheData icacheGet( Object key );
       
       /**
        *  places an IntrospectionCache Data (@see IntrospectionCacheData)
  @@ -102,5 +102,5 @@
        *  @param key  key 
        *  @param o  IntrospectionCacheData object to place in cache
        */
  -    public void icachePut( Object key, IntrospectionCacheData o );
  +     void icachePut( Object key, IntrospectionCacheData o );
   }
  
  
  
  1.2       +6 -6      jakarta-velocity/whiteboard/geir_context_20001228/InternalContextBase.java
  
  Index: InternalContextBase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/InternalContextBase.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- InternalContextBase.java	2000/12/30 14:42:00	1.1
  +++ InternalContextBase.java	2000/12/30 23:46:18	1.2
  @@ -1,4 +1,4 @@
  -package org.apache.velocity;
  +package org.apache.velocity.context;
   
   /*
    * The Apache Software License, Version 1.1
  @@ -68,9 +68,9 @@
    *  support, as well as node-local context data introspection caching.
    *
    * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
  - * @version $Id: InternalContextBase.java,v 1.1 2000/12/30 14:42:00 geirm Exp $
  + * @version $Id: InternalContextBase.java,v 1.2 2000/12/30 23:46:18 geirm Exp $
    */
  -public class InternalContextBase implements InternalContext, Serializable
  +public class InternalContextBase implements Serializable
   {
       /**
        *  cache for node/context specific introspection information
  @@ -87,7 +87,7 @@
        *
        *  @param s current template name to set
        */
  -    public void setCurrentTemplateName( String s )
  +    protected void setCurrentTemplateName( String s )
       {
           strCurrentTemplate = s;
           return;
  @@ -98,7 +98,7 @@
        *
        *  @return String current template name
        */
  -    public String getCurrentTemplateName()
  +    protected String getCurrentTemplateName()
       {
           return strCurrentTemplate;
       }
  @@ -110,7 +110,7 @@
        *  @param key  key to find in cache
        *  @return cache object
        */
  -    public IntrospectionCacheData icacheGet( Object key )
  +    protected IntrospectionCacheData icacheGet( Object key )
       {
           return ( IntrospectionCacheData ) introspectionCache.get( key );
       }
  @@ -122,7 +122,7 @@
        *  @param key  key 
        *  @param o  IntrospectionCacheData object to place in cache
        */
  -    public void icachePut( Object key, IntrospectionCacheData o )
  +    protected void icachePut( Object key, IntrospectionCacheData o )
       {
           introspectionCache.put( key, o );
       }
  
  
  
  1.3       +61 -5     jakarta-velocity/whiteboard/geir_context_20001228/README.txt
  
  Index: README.txt
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/README.txt,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- README.txt	2000/12/30 14:42:00	1.2
  +++ README.txt	2000/12/30 23:46:18	1.3
  @@ -1,8 +1,21 @@
   Here is my impl of all the context stuff we have been 
   talking about for a while.
   
  +New approach :
  +
  +The code now reflects a new approach to dealing with the whole context issue.  
  +The big issue was that we have an internal 'context' that is used for a few 
  +purposes (and more in the future), and the first rev or so of this code showed
  +that.  This latest rev hides completely the internal context, allows us to add
  +more kinds of 'stuff' to the internal context in the future.  It places no 
  +requirements upon users, and app level code is unable to access the internal context
  +methods.
  +
  +The big difference is that Context is now in it's own package.  VelocityContext is 
  +still at org.apache.velocity level, but all the guts are safe in their own package.
  +
   Note that this code won't drop in and run as it requires 
  -small non-functional mods to a few AST nodes to decouple
  +lots of non-functional mods to a few AST nodes to decouple
    the internal context stuff from the app-level context stuff,
   which is a Good Thing.  There are also changes to 
   everything from VelocityServlet to Anakia to Texen etc to
  @@ -32,18 +45,57 @@
   
   Included
   ---------
  -Context.java : basic interface defintion.  It looks exactly like 
  -the current Context, for the most part, except that put optionally
  +
  +Context.java :  interface defintion for app-level data context. This is 
  +what the application writer thinks of the context to be.  The app
  +writer has several choices for using this :
  +
  +1) Use the provided VelocityContext() implementation, providing the current
  +facilities of the current Context class. It looks exactly like 
  +the current Context, for the most part, except that put() optionally
   returns the Object it replaces.
   
  +2) Create their own class to use as a context by extending AbstractContext.
  +This would automatically support context chaining/wrapping, tool support if
  +we decide to do that, and fully caches node-specific cache info across merges.
  +This would be the most efficient and easy way to make a Context-compatible 
  +object.  It could be stored in a servlet session and reused with any applicable
  +cache information preserved. The included HashMapContext, TreeMapContext, 
  +and DBContext are examples of how this is done.
  +
  +3) Create their own class to use as a context by simply implementing the
  +Context interface.  They would be responsible for supporting chaining if desired.
  +This seems to be more appropriate for specialized applications, frameworks, 
  +whatever.  The disadvange to this is that node-specific cache info is lost
  +after use.  This is fine for codeing patterns where the context is created, used
  +and destroyed. (Our current VelocityServlet does this...)
  +
   AbstractContext.java : abstract class for a usable app-level Context.
   Handles the wrapping/chaining support as well as interfacing with the
  -maybe upcoming 'toolsmith', the global context tool manager/dispenser.
  +possibly upcoming tool management. To make a usable Context object, a user
  +could simply subclass this and implement the storage mechanism and the 5 required 
  +methods.
   
   VelocityContext.java : replaces the current Context.java implementation.
   This is a working hashtable-based concrete implementation of 
   AbstractContext.java.   You would use it wherever you use Context now.
  -(and indeed, it is used in the included jar)
  +(and indeed, it is used in the included jar).  The name isn't important...
  +we can also change to hashmap or whatever.  The point is to have a default
  +concrete context for people to use easily.
  +
  +InternalContextBase.java : internal cache object, used for node-specific caching of 
  +introspection information, carrying temlpate names, etc.  Will need to extend
  +or add another in the future, I bet.  The functionality is inaccessable to any
  +app-layer code.
  +
  +InternalContextAdapter.java : used by Template to carry all context and internalContext
  +information down into the AST.  Decouples the app-level context from the 'context'
  +expected by the AST internals.  Further, provides the InternalContext support for 
  +app-level Contexts that don't subclass from AbstractContext, so performance is 
  +preserved.  And further, we can add more kinds of information to be carried into 
  +the AST free of app-level code changes.  Used by Template.java as well as all AST nodes.
  +Fundamentally, all AST nodes would no longer care about the 'Context' interface, but expect
  +InternalContextAdapter to support it.
   
   HashMapContext.java : example of creating another kind of Context, it uses
   a HashMap for storage.
  @@ -72,6 +124,10 @@
   be completely hidden from app level if possible - needed to remove 
   the getInternalContext() accessor method from the Context interface and
   the AbstractContext abstract base class.  So that's done.
  +
  +12/30/00 pm
  +-----------
  +not done enough....  See above notes and new code if you care...
   
   geir
   
  
  
  
  1.2       +2 -0      jakarta-velocity/whiteboard/geir_context_20001228/TreeMapContext.java
  
  Index: TreeMapContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/TreeMapContext.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TreeMapContext.java	2000/12/29 19:21:28	1.1
  +++ TreeMapContext.java	2000/12/30 23:46:19	1.2
  @@ -56,12 +56,14 @@
   
   import java.util.TreeMap;
   import java.io.Serializable;
  +import org.apache.velocity.context.AbstractContext;
  +import org.apache.velocity.context.Context;
   
   /**
    *   Example context impl that uses a HashMap
    *
    * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
  - * @version $Id: TreeMapContext.java,v 1.1 2000/12/29 19:21:28 geirm Exp $
  + * @version $Id: TreeMapContext.java,v 1.2 2000/12/30 23:46:19 geirm Exp $
    */
   
   public class TreeMapContext extends AbstractContext
  
  
  
  1.2       +4 -1      jakarta-velocity/whiteboard/geir_context_20001228/VelocityContext.java
  
  Index: VelocityContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/whiteboard/geir_context_20001228/VelocityContext.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- VelocityContext.java	2000/12/29 19:21:28	1.1
  +++ VelocityContext.java	2000/12/30 23:46:19	1.2
  @@ -58,11 +58,14 @@
   import java.util.Properties;
   import java.io.Serializable;
   
  +import org.apache.velocity.context.AbstractContext;
  +import org.apache.velocity.context.Context;
  +
   /**
    *  Default basic implementation of a Context object
    *
    * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
  - * @version $Id: VelocityContext.java,v 1.1 2000/12/29 19:21:28 geirm Exp $
  + * @version $Id: VelocityContext.java,v 1.2 2000/12/30 23:46:19 geirm Exp $
    */
   
   public  class VelocityContext extends AbstractContext implements Cloneable
  @@ -78,7 +81,7 @@
       {
           super( inner );
       }
  -
  + 
       public Object internalGet( String key )
       {
           return context.get( key );
  
  
  
  1.4       +483 -490  jakarta-velocity/whiteboard/geir_context_20001228/velocity-0.71.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-velocity/whiteboard/geir_context_20001228/InternalContextAdapter.java
  
  Index: InternalContextAdapter.java
  ===================================================================
  
  package org.apache.velocity.context;
  
  import org.apache.velocity.util.introspection.IntrospectionCacheData;
  
  public final class InternalContextAdapter implements Context
  {
      Context context = null;
      InternalContextBase icb = null;
  
      public InternalContextAdapter( Context c )
      {
          context = c;
  
          if ( !( c instanceof InternalContextBase ))
          {
              System.out.println("Woog!");
              icb = new InternalContextBase();
          }
          else
              icb = (InternalContextBase) context;
               
      }
  
      public void setCurrentTemplateName( String s )
      {
         icb.setCurrentTemplateName( s );
      }
    
      public String getCurrentTemplateName()
      {
          return icb.getCurrentTemplateName();
      }
  
      public IntrospectionCacheData icacheGet( Object key )
      {
          return icb.icacheGet( key );
      }
      
      public void icachePut( Object key, IntrospectionCacheData o )
      {
          icb.icachePut( key, o );
      }
  
      /** ----------------- */
  
      public Object put(String key, Object value)
      {
          return context.put( key , value );
      }
  
      public Object get(String key)
      {
          return context.get( key );
      }
  
      public boolean containsKey(Object key)
      {
          return context.containsKey( key );
      }
  
      public Object[] getKeys()
      {
          return context.getKeys();
      }
  
      public Object remove(Object key)
      {
          return context.remove( key );
      }
  }
  
  
  
  1.1                  jakarta-velocity/whiteboard/geir_context_20001228/Template.java
  
  Index: Template.java
  ===================================================================
  package org.apache.velocity;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.InputStream;
  import java.io.IOException;
  import java.io.Writer;
  
  import org.apache.velocity.runtime.Runtime;
  import org.apache.velocity.runtime.resource.Resource;
  import org.apache.velocity.runtime.parser.ParseException;
  import org.apache.velocity.runtime.parser.node.SimpleNode;
  
  import org.apache.velocity.VelocityContext;
  import org.apache.velocity.context.Context;
  import org.apache.velocity.context.InternalContext;
  import org.apache.velocity.context.InternalContextAdapter;
  
  
  /**
   * This class is used for controlling all template
   * operations. This class uses a parser created
   * by JavaCC to create an AST that is subsequently
   * traversed by a ProcessVisitor. This class is in
   * the process of changing over to use the
   * InjectorVistor, this is part of the planned
   * caching mechanism.
   *
   * <pre>
   * Template template = Runtime.getTemplate("test.wm");
   * Context context = new Context();
   *
   * context.put("foo", "bar");
   * context.put("customer", new Customer());
   *
   * template.merge(context, writer);
   * </pre>
   *
   * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
   * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
   * @version $Id: Template.java,v 1.1 2000/12/30 23:46:19 geirm Exp $
   */
  public class Template extends Resource
  {
      /**
       * To keep track of whether this template has been
       * initialized. We use the document.init(context)
       * to perform this. The AST walks itself optimizing
       * nodes creating objects that can be reused during
       * rendering. For example all reflection metadata
       * is stored in ASTReference nodes, the Method objects 
       * are determine in the init() phase and reused 
       * during rendering.
       */
      private boolean initialized = false;
  
      /** Default constructor */
      public Template()
      {
      }
  
      public boolean process()
      {
          try
          {
              InputStream is = resourceLoader.getResourceStream(name);
          
              if (is != null)
              {
                  data = Runtime.parse(is, name);
                  initDocument();
                  return true;
              }
              else
                  return false;
          }
          catch (Exception e)
          {
              return false;
          }            
      }
  
      /**
       *  initializes the document.  init() is not longer 
       *  dependant upon context, but we need to let the 
       *  init() carry the template name down throught for VM
       *  namespace features
       */
      public void initDocument() throws Exception
      {
          VelocityContext c = new VelocityContext();
          
          InternalContextAdapter ica = new InternalContextAdapter( c );
  
          ica.setCurrentTemplateName( name );
          
          ((SimpleNode)data).init( ica, null);
      }
  
      /**
       * The AST node structure is merged with the
       * context to produce the final output. We
       * also init() the AST node structure if
       * it hasn't been already. It might actually
       * be better to move the init() phase up into
       * the parse(), but it would require the passing
       * in of the context. The context is required to
       * determine the objects being used by reflection.
       */
      public void merge( Context context, Writer writer)
          throws IOException, Exception
      {
          if( data != null)
          {
              InternalContextAdapter ica = new InternalContextAdapter( context );
  
              ica.setCurrentTemplateName( name );
              ((SimpleNode)data).render( ica, writer);
          }
          else
              Runtime.error("Template.merge() failure. The document is null, " + 
                            "most likely due to parsing error.");
      }
  }