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;
+ }
}