geirm       01/10/21 03:58:35

  Modified:    src/java/org/apache/velocity/runtime VelocimacroFactory.java
  Log:
  Fix to prevent infinite loops in autoload when VMs reference each other.
  Should be fairly safe, as the code modified only pertains to autoload. Will
  let the interested parties test, and then roll back into 1.2 as it's broken
  there too.
  
  Revision  Changes    Path
  1.16      +49 -10    
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.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- VelocimacroFactory.java   2001/08/13 13:58:34     1.15
  +++ VelocimacroFactory.java   2001/10/21 10:58:35     1.16
  @@ -69,7 +69,7 @@
    *   manages the set of VMs in a running Velocity engine.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Geir Magnusson Jr.</a>
  - * @version $Id: VelocimacroFactory.java,v 1.15 2001/08/13 13:58:34 geirm Exp $ 
  + * @version $Id: VelocimacroFactory.java,v 1.16 2001/10/21 10:58:35 geirm Exp $ 
    */
   public class VelocimacroFactory
   {
  @@ -138,7 +138,6 @@
            *  can use an unsynchronized hashmap
            */
           libModMap = new HashMap();
  -
           vmManager = new VelocimacroManager( rsvc );
       }
   
  @@ -217,7 +216,10 @@
                                 *  this is how the Resource manager works
                                 */
   
  -                             libModMap.put( lib, template );
  +                             Twonk twonk = new Twonk();
  +                             twonk.template = template;
  +                             twonk.modificationTime = template.getLastModified();
  +                             libModMap.put( lib, twonk );                         
                            } 
                            catch (Exception e)
                            {
  @@ -546,11 +548,13 @@
                           /*
                            *  get the template from our map
                            */
  -
  -                        Template template = (Template) libModMap.get(lib );
   
  -                        if (template != null)
  +                        Twonk tw = (Twonk) libModMap.get( lib );
  +                        
  +                        if ( tw != null)
                           {
  +                            Template template = tw.template;
  +                            
                               /*
                                *  now, compare the last modified time of the resource
                                *  with the last modified time of the template
  @@ -558,17 +562,39 @@
                                *  be ok.
                                */
   
  -                            long tt = template.getLastModified();
  +                            long tt = tw.modificationTime;
                               long ft = template.getResourceLoader().getLastModified( 
template );
   
                               if ( ft > tt )
                               {
                                   logVMMessageInfo("Velocimacro : autoload reload for 
VMs from " +
                                                    "VM library template : " + lib  );
  -
  +             
  +                                /*
  +                                 *  when there are VMs in a library that invoke 
each other,
  +                                 *  there are calls into getVelocimacro() from the 
init() 
  +                                 *  process of the VM directive.  To stop the 
infinite loop
  +                                 *  we save the current time reported by the 
resource loader
  +                                 *  and then be honest when the reload is complete
  +                                 */
  +                                 
  +                                tw.modificationTime = ft;
  +                                                                       
                                   template = rsvc.getTemplate( lib );
  -                                libModMap.put( lib, template );
  -                            }
  + 
  +                                /*
  +                                 * and now we be honest
  +                                 */
  +
  +                                tw.template = template;
  +                                tw.modificationTime = template.getLastModified();
  +
  +                                /*
  +                                 *  note that we don't need to put this twonk back 
  +                                 *  into the map, as we can just use the same 
reference
  +                                 *  and this block is synchronized
  +                                 */                                  
  +                             }
                            } 
                       }
                       catch (Exception e)
  @@ -669,6 +695,19 @@
           return autoReloadLibrary;
       }
   
  +    /**
  +     * small continer class to hold the duple
  +     * of a template and modification time.
  +     * We keep the modification time so we can 
  +     * 'override' it on a reload to prevent
  +     * recursive reload due to inter-calling
  +     * VMs in a library
  +     */
  +    private class Twonk
  +    {
  +        public Template template;
  +        public long modificationTime;
  +    }
   }
   
   
  
  
  


Reply via email to