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...@apache.org on 2001/08/13 15:58:35 UTC

cvs commit: jakarta-velocity/src/java/org/apache/velocity/runtime RuntimeConstants.java VelocimacroFactory.java VelocimacroManager.java

geirm       01/08/13 06:58:35

  Modified:    src/java/org/apache/velocity/runtime RuntimeConstants.java
                        VelocimacroFactory.java VelocimacroManager.java
  Log:
  Added support for 'autoreload' feature for global VM libraries
  
  Revision  Changes    Path
  1.27      +8 -2      jakarta-velocity/src/java/org/apache/velocity/runtime/RuntimeConstants.java
  
  Index: RuntimeConstants.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/runtime/RuntimeConstants.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- RuntimeConstants.java	2001/05/20 21:40:40	1.26
  +++ RuntimeConstants.java	2001/08/13 13:58:34	1.27
  @@ -62,7 +62,7 @@
    * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
    * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
    * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
  - * @version $Id: RuntimeConstants.java,v 1.26 2001/05/20 21:40:40 geirm Exp $
  + * @version $Id: RuntimeConstants.java,v 1.27 2001/08/13 13:58:34 geirm Exp $
    */
   public interface RuntimeConstants
   {
  @@ -295,6 +295,12 @@
       public static final String VM_LIBRARY  = "velocimacro.library";
   
       /** 
  +     * switch for autoloading library-sourced VMs (for development) 
  +     */
  +    public final static String VM_LIBRARY_AUTORELOAD = 
  +        "velocimacro.library.autoreload";
  +
  +    /** 
        * boolean (true/false) default true : allow 
        * inline (in-template) macro definitions 
        */
  @@ -324,7 +330,7 @@
       */
       public final static String VM_CONTEXT_LOCALSCOPE = 
           "velocimacro.context.localscope";
  -
  +    
       /*
        * ----------------------------------------------------------------------
        * G E N E R A L  R U N T I M E  C O N F I G U R A T I O N
  
  
  
  1.15      +265 -51   jakarta-velocity/src/java/org/apache/velocity/runtime/VelocimacroFactory.java
  
  Index: VelocimacroFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/runtime/VelocimacroFactory.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- VelocimacroFactory.java	2001/08/07 22:06:49	1.14
  +++ VelocimacroFactory.java	2001/08/13 13:58:34	1.15
  @@ -60,6 +60,8 @@
   import org.apache.velocity.runtime.parser.node.SimpleNode;
   
   import java.util.Vector;
  +import java.util.Map;
  +import java.util.HashMap;
   
   /**
    *  VelocimacroFactory.java
  @@ -67,27 +69,82 @@
    *   manages the set of VMs in a running Velocity engine.
    *
    * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
  - * @version $Id: VelocimacroFactory.java,v 1.14 2001/08/07 22:06:49 geirm Exp $ 
  + * @version $Id: VelocimacroFactory.java,v 1.15 2001/08/13 13:58:34 geirm Exp $ 
    */
   public class VelocimacroFactory
   {
  +    /**
  +     *  runtime services for this instance
  +     */
       private RuntimeServices rsvc = null;
   
  +    /**
  +     *  VMManager : deal with namespace management
  +     *  and actually keeps all the VM definitions
  +     */
       private VelocimacroManager vmManager = null;
   
  +    /**
  +     *  determines if replacement of global VMs are allowed
  +     *  controlled by  VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL
  +     */
       private boolean replaceAllowed = false;
  +
  +    /**
  +     *  controls if new VMs can be added.  Set by
  +     *  VM_PERM_ALLOW_INLINE  Note the assumption that only
  +     *  through inline defs can this happen.
  +     *  additions through autoloaded VMs is allowed
  +     */
       private boolean addNewAllowed = true;
  +
  +    /**
  +     *  sets if template-local namespace in used
  +     */
       private boolean templateLocal = false;
  +
  +    /**
  +     *  controls log output
  +     */
       private boolean blather = false;
   
  +    /**
  +     *  determines if the libraries are auto-loaded
  +     *  when they change
  +     */
  +    private boolean autoReloadLibrary = false;
  +
  +    /**
  +     *  vector of the library names
  +     */
  +    private Vector macroLibVec = null;
  +
  +    /**
  +     *  map of the library Template objects
  +     *  used for reload determination
  +     */
  +    private Map libModMap;
  +
  +    /**
  +     *  CTOR : requires a runtime services from now
  +     *  on
  +     */
       public VelocimacroFactory( RuntimeServices rs )
       {
           this.rsvc = rs;
  +
  +        /*
  +         *  we always access in a synchronized(), so we 
  +         *  can use an unsynchronized hashmap
  +         */
  +        libModMap = new HashMap();
  +
           vmManager = new VelocimacroManager( rsvc );
       }
   
       /**
  -     *    setup
  +     *  initialize the factory - setup all permissions
  +     *  load all global libraries.
        */
       public void initVelocimacro()
       {
  @@ -119,21 +176,20 @@
                Object libfiles = rsvc.getProperty( RuntimeConstants.VM_LIBRARY );
              
                if( libfiles != null)
  -             {
  -                 Vector v = new Vector();
  -          
  +             {         
                    if (libfiles instanceof Vector)
                    {
  -                     v = (Vector) libfiles;
  +                     macroLibVec = (Vector) libfiles;
                    }
                    else if (libfiles instanceof String)
                    { 
  -                     v.addElement( libfiles );
  +                     macroLibVec = new Vector();
  +                     macroLibVec.addElement( libfiles );
                    }
                    
  -                 for( int i = 0; i < v.size(); i++)
  +                 for( int i = 0; i < macroLibVec.size(); i++)
                    {
  -                     String lib = (String) v.elementAt(i);
  +                     String lib = (String) macroLibVec.elementAt(i);
                    
                        /*
                         * only if it's a non-empty string do we bother
  @@ -141,21 +197,38 @@
   
                        if (lib != null && !lib.equals(""))
                        {
  +                         /*
  +                          *  let the VMManager know that the following is coming
  +                          *  from libraries - need to know for auto-load
  +                          */
  +
  +                         vmManager.setRegisterFromLib( true );
  +
  +                         logVMMessageInfo("Velocimacro : adding VMs from " +
  +                             "VM library template : " + lib  );
  +
                            try 
                            {
  -                             logVMMessageInfo("Velocimacro : adding VMs from " +
  -                                              "VM library template : " + lib  );
  -                             
  -                             Template template = rsvc.getTemplate( lib );   
  -                             
  -                             logVMMessageInfo("Velocimacro :  VM library template " +
  -                                              "macro registration complete." );
  +                             Template template = rsvc.getTemplate( lib );
  +
  +                             /*
  +                              *  save the template.  This depends on the assumption
  +                              *  that the Template object won't change - currently
  +                              *  this is how the Resource manager works
  +                              */
  +
  +                             libModMap.put( lib, template );
                            } 
                            catch (Exception e)
                            {
                                logVMMessageInfo("Velocimacro : error using  VM " +
                                                 "library template " + lib + " : " + e );
                            }
  +
  +                         logVMMessageInfo("Velocimacro :  VM library template " +
  +                                 "macro registration complete." );
  +            
  +                         vmManager.setRegisterFromLib( false );
                        }
                    }
                }
  @@ -244,9 +317,25 @@
               }
               else
               {
  -                rsvc.info("Velocimacro : messages off : VM system will be quiet");
  +                logVMMessageInfo("Velocimacro : messages off : VM system will be quiet");
               }
   
  +            /*
  +             *  autoload VM libraries
  +             */
  +            setAutoload( rsvc.getBoolean( RuntimeConstants.VM_LIBRARY_AUTORELOAD, false ));
  +        
  +            if (getAutoload())
  +            {
  +                logVMMessageInfo("Velocimacro : autoload on  : VM system " +
  +                                 "will automatically reload global library macros");
  +            }
  +            else
  +            {
  +                logVMMessageInfo("Velocimacro : autoload off  : VM system " +
  +                                 "will not automatically reload global library macros");
  +            }
  +
               rsvc.info("Velocimacro : initialization complete.");
           }
       
  @@ -275,6 +364,79 @@
           }
           
           /*
  +         *  see if the current ruleset allows this addition
  +         */
  +
  +        if (!canAddVelocimacro( name, sourceTemplate ))
  +        {
  +            return false;
  +        }
  +
  +        /*
  +         *  seems like all is good.  Lets do it.
  +         */
  +        synchronized( this ) 
  +        {
  +            vmManager.addVM( name, macroBody, argArray, sourceTemplate );
  +        }
  +
  +        /*
  +         *  if we are to blather, blather...
  +         */
  +        if ( blather)
  +        {
  +            String s = "#" +  argArray[0];
  +            s += "(";
  +        
  +            for( int i=1; i < argArray.length; i++)
  +            {
  +                s += " ";
  +                s += argArray[i];
  +            }
  +
  +            s += " ) : source = ";
  +            s += sourceTemplate;
  +            
  +           logVMMessageInfo( "Velocimacro : added new VM : " + s );
  +        }
  +
  +        return true;
  +    }
  +
  +    /**
  +     *  determines if a given macro/namespace (name, source) combo is allowed
  +     *  to be added
  +     *
  +     *  @param name Name of VM to add
  +     *  @param sourceTemplate Source template that contains the defintion of the VM
  +     *  @return true if it is allowed to be added, false otherwise
  +     */
  +    private boolean canAddVelocimacro( String name, String sourceTemplate)
  +    {
  +        /*
  +         *  short circuit and do it if autoloader is on, and the
  +         *  template is one of the library templates
  +         */
  +        
  +        if ( getAutoload() )
  +        {
  +            /*
  +             *  see if this is a library template
  +             */
  +
  +            for( int i = 0; i < macroLibVec.size(); i++)
  +            {
  +                String lib = (String) macroLibVec.elementAt(i);
  +
  +                if (lib.equals( sourceTemplate ) )
  +                {
  +                    return true;
  +                }
  +            }
  +        }
  +
  +           
  +        /*
            * maybe the rules should be in manager?  I dunno. It's to manage 
            * the namespace issues first, are we allowed to add VMs at all? 
            * This trumps all.
  @@ -307,34 +469,7 @@
                   return false;
               }
           }
  -
  -        /*
  -         *  seems like all is good.  Lets do it.
  -         */
  -        synchronized( this ) 
  -        {
  -            vmManager.addVM( name, macroBody, argArray, sourceTemplate );
  -        }
  -
  -        /*
  -         *  if we are to blather, blather...
  -         */
  -        if ( blather)
  -        {
  -            String s = "#" +  argArray[0];
  -            s += "(";
           
  -            for( int i=1; i < argArray.length; i++)
  -                {
  -                    s += " ";
  -                    s += argArray[i];
  -                }
  -            s += " ) : source = ";
  -            s += sourceTemplate;
  -            
  -           logVMMessageInfo( "Velocimacro : added new VM : " + s );
  -        }
  -
           return true;
       }
   
  @@ -380,18 +515,78 @@
        */
       public Directive getVelocimacro( String vmName, String sourceTemplate )
       {
  +        VelocimacroProxy vp = null;
  +
           synchronized( this ) 
           {
  -            if ( isVelocimacro( vmName, sourceTemplate ) ) 
  +            /*
  +             *  don't ask - do
  +             */
  +
  +            vp = vmManager.get( vmName, sourceTemplate);
  +
  +            /*
  +             *  if this exists, and autoload is on, we need to check
  +             *  where this VM came from
  +             */
  +
  +            if ( vp != null && getAutoload() ) 
               {    
  -                return  vmManager.get( vmName, sourceTemplate );
  +                /*
  +                 *  see if this VM came from a library.  Need to pass sourceTemplate
  +                 *  in the event namespaces are set, as it could be masked by local
  +                 */
  +                
  +                String lib = vmManager.getLibraryName( vmName, sourceTemplate );
  +
  +                if (lib != null)
  +                {
  +                    try 
  +                    {
  +                        /*
  +                         *  get the template from our map
  +                         */
  +
  +                        Template template = (Template) libModMap.get(lib );
  +
  +                        if (template != null)
  +                        {
  +                            /*
  +                             *  now, compare the last modified time of the resource
  +                             *  with the last modified time of the template
  +                             *  if the file has changed, then reload. Otherwise, we should
  +                             *  be ok.
  +                             */
  +
  +                            long tt = template.getLastModified();
  +                            long ft = template.getResourceLoader().getLastModified( template );
  +
  +                            if ( ft > tt )
  +                            {
  +                                logVMMessageInfo("Velocimacro : autoload reload for VMs from " +
  +                                                 "VM library template : " + lib  );
  +
  +                                template = rsvc.getTemplate( lib );
  +                                libModMap.put( lib, template );
  +                            }
  +                         } 
  +                    }
  +                    catch (Exception e)
  +                    {
  +                        logVMMessageInfo("Velocimacro : error using  VM " +
  +                                         "library template " + lib + " : " + e );
  +                    }
  +
  +                    /*
  +                     *  and get again
  +                     */
  +
  +                    vp = vmManager.get( vmName, sourceTemplate);
  +                }
               }
           }
  -
  -        /*
  -         *  wasn't a VM.  Sorry...
  -         */
  -        return null;
  +        
  +        return vp;
       }
   
       /**
  @@ -455,6 +650,25 @@
       {
           return blather;
       }
  +
  +    /**
  +     *  set the switch for automatic reloading of
  +     *  global library-based VMs
  +     */
  +    private void setAutoload( boolean b)
  +    {
  +        autoReloadLibrary = b;
  +    }
  +    
  +    /**
  +     *  get the switch for automatic reloading of
  +     *  global library-based VMs
  +     */
  +    private boolean getAutoload()
  +    {
  +        return autoReloadLibrary;
  +    }
  +
   }
   
   
  
  
  
  1.13      +79 -3     jakarta-velocity/src/java/org/apache/velocity/runtime/VelocimacroManager.java
  
  Index: VelocimacroManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/runtime/VelocimacroManager.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- VelocimacroManager.java	2001/08/07 22:06:49	1.12
  +++ VelocimacroManager.java	2001/08/13 13:58:35	1.13
  @@ -83,14 +83,15 @@
    *
    * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
    * @author <a href="mailto:JFernandez@viquity.com">Jose Alberto Fernandez</a>
  - * @version $Id: VelocimacroManager.java,v 1.12 2001/08/07 22:06:49 geirm Exp $ 
  + * @version $Id: VelocimacroManager.java,v 1.13 2001/08/13 13:58:35 geirm Exp $ 
    */
   public class VelocimacroManager
   {
       private RuntimeServices rsvc = null;
  -
       private static String GLOBAL_NAMESPACE = "";
   
  +    private boolean registerFromLib = false;
  +
       /*  hash of namespace hashes */
       private Hashtable namespaceHash = new Hashtable();
   
  @@ -123,6 +124,8 @@
       {
           MacroEntry me = new MacroEntry( this, vmName,  macroBody,  argArray,  namespace );
   
  +        me.setFromLibrary(registerFromLib);
  +    
           if ( usingNamespaces( namespace ) )
           {
               /*
  @@ -137,8 +140,20 @@
           }
           else
           {
  +            /*
  +             *  otherwise, add to global template.  First, check if we already have it
  +             *  to preserve some of the autoload information
  +             */
  +
  +            MacroEntry exist = (MacroEntry) (getNamespace( GLOBAL_NAMESPACE )).get( vmName );
  +            
  +            if (exist != null)
  +            {
  +                me.setFromLibrary( exist.getFromLibrary());
  +            }
  +
               /*
  -             * otherwise, add to global template
  +             *  now add it
                */
   
               (getNamespace( GLOBAL_NAMESPACE )).put( vmName, me );
  @@ -227,6 +242,12 @@
           return;
       }
   
  +    public void setRegisterFromLib( boolean b )
  +    {
  +        registerFromLib = b;
  +        return;
  +    }
  +
       public void setTemplateLocalInlineVM( boolean b )
       {
           inlineLocalMode = b;
  @@ -318,6 +339,45 @@
           return false;
       }
   
  +    public String getLibraryName( String vmName, String namespace )
  +    {
  +        if ( usingNamespaces( namespace ) )
  +        {
  +            Hashtable local =  getNamespace( namespace, false );
  +         
  +            /*
  +             *  if we have this macro defined in this namespace, then
  +             *  it is masking the global, library-based one, so 
  +             *  just return null
  +             */
  +
  +            if ( local != null)
  +            {
  +                MacroEntry me = (MacroEntry) local.get( vmName );
  +               
  +                if (me != null)
  +                {
  +                    return null;
  +                }
  +            }
  +        }
  +
  +        /*
  +         * if we didn't return from there, we need to simply see 
  +         * if it's in the global namespace
  +         */
  +        
  +        MacroEntry me = (MacroEntry) (getNamespace( GLOBAL_NAMESPACE )).get( vmName );
  +        
  +        if (me != null)
  +        {
  +            return me.getSourceTemplate();
  +        }
  + 
  +        return null;
  +    }
  +
  +
       /**
        *  wrapper class for holding VM information
        */
  @@ -329,6 +389,7 @@
           String sourcetemplate;
           SimpleNode nodeTree = null;
           VelocimacroManager manager = null;
  +        boolean fromLibrary = false;
   
           MacroEntry(VelocimacroManager vmm, String vmName, String macroBody, String argArray[],  String sourceTemplate)
           {
  @@ -339,9 +400,24 @@
               this.manager = vmm;
           }
   
  +        public void setFromLibrary( boolean b )
  +        {
  +            fromLibrary = b;
  +        }
  +        
  +        public boolean getFromLibrary()
  +        {
  +            return fromLibrary;
  +        }
  +
           public SimpleNode getNodeTree()
           {
               return nodeTree;
  +        }
  +
  +        public String getSourceTemplate()
  +        {
  +            return sourcetemplate;
           }
   
           VelocimacroProxy createVelocimacro( String namespace )