Author: nbubna
Date: Sat May 23 22:17:46 2009
New Revision: 778045

URL: http://svn.apache.org/viewvc?rev=778045&view=rev
Log:
VELOCITY-704 default all scope controls to off, except $foreach and do a few 
other tiny, scope-related performance boosts

Modified:
    velocity/engine/trunk/src/changes/changes.xml
    velocity/engine/trunk/src/java/org/apache/velocity/Template.java
    
velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java
    
velocity/engine/trunk/src/java/org/apache/velocity/runtime/defaults/velocity.properties
    
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Directive.java
    
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Scope.java
    
velocity/engine/trunk/src/test/org/apache/velocity/test/BreakDirectiveTestCase.java
    
velocity/engine/trunk/src/test/org/apache/velocity/test/EvaluateTestCase.java
    velocity/engine/trunk/src/test/org/apache/velocity/test/ScopeTestCase.java
    velocity/engine/trunk/xdocs/docs/developer-guide.xml

Modified: velocity/engine/trunk/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/src/changes/changes.xml?rev=778045&r1=778044&r2=778045&view=diff
==============================================================================
--- velocity/engine/trunk/src/changes/changes.xml (original)
+++ velocity/engine/trunk/src/changes/changes.xml Sat May 23 22:17:46 2009
@@ -37,9 +37,10 @@
     Change the scoping behavior of Velocity, keeping it optional (everything 
global
     scoped by default) but now providing an explicit namespace in 
content-containing
     directives (like macros, #foreach, #parse, etc.) in which references that 
should
-    stay local may be kept.  This is accompanied by numerous related changes, 
including:
+    stay local may be kept. This is accompanied by numerous related changes, 
including:
     <ul>
-    <li>A Scope reference is now available within each content directive:
+    <li>A Scope reference can now be automatically made
+              available within each content directive:
         <ul>
         <li>$template in Template.merge and #parse content<li>
         <li>$macro in #macro</li>
@@ -50,8 +51,9 @@
               (where <amacro> is the name of a macro being 
called with a body)</li>
         </ul>
     </li>
-    <li>Allowing the above to be suppressed by setting a velocity 
property like:
-        <br/><code>foreach.provide.scope.control = 
false</code></li>
+    <li>For performance and compatibility these are all off by
+    default, *except* for $foreach. The others may be enabled by setting a 
velocity property like:
+        <br/><code>macro.provide.scope.control = 
true</code></li>
     <li>When scopes of the same type are nested make the parent Scope 
available
         through the child (e.g. $foreach.parent or 
$foreach.topmost).</li>
     <li>When a Scope reference overrides an existing reference that is 
not a Scope,

Modified: velocity/engine/trunk/src/java/org/apache/velocity/Template.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/Template.java?rev=778045&r1=778044&r2=778045&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/Template.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/Template.java Sat May 23 
22:17:46 2009
@@ -71,7 +71,7 @@
      * the scope object into the context.
      */
     private String scopeName = "template";
-    private boolean provideScope = true;
+    private boolean provideScope = false;
 
     private VelocityException errorCondition = null;
 

Modified: 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java?rev=778045&r1=778044&r2=778045&view=diff
==============================================================================
--- 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java 
(original)
+++ 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java 
Sat May 23 22:17:46 2009
@@ -194,7 +194,7 @@
      * Settings for provision of root scope for evaluate(...) calls.
      */
     private String evaluateScopeName = "evaluate";
-    private boolean provideEvaluateScope = true;
+    private boolean provideEvaluateScope = false;
 
     /*
      *  Opaque reference to something specificed by the

Modified: 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/defaults/velocity.properties
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/defaults/velocity.properties?rev=778045&r1=778044&r2=778045&view=diff
==============================================================================
--- 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/defaults/velocity.properties
 (original)
+++ 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/defaults/velocity.properties
 Sat May 23 22:17:46 2009
@@ -91,12 +91,12 @@
 # These are the properties that govern whether or not a Scope object
 # is automatically provided for each of the given scopes to serve as a
 # scope-safe reference namespace and "label" for #break calls. The default
-# for all of these is true.  Note that <bodymacroname> should be replaced by
+# for most of these is false.  Note that <bodymacroname> should be replaced by
 # name of macros that take bodies for which you want to suppress the scope.
 # ----------------------------------------------------------------------------
 # template.provide.scope.control = false
 # evaluate.provide.scope.control = false
-# foreach.provide.scope.control = false
+foreach.provide.scope.control = true
 # macro.provide.scope.control = false
 # define.provide.scope.control = false
 # <bodymacroname>.provide.scope.control = false

Modified: 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Directive.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Directive.java?rev=778045&r1=778044&r2=778045&view=diff
==============================================================================
--- 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Directive.java
 (original)
+++ 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Directive.java
 Sat May 23 22:17:46 2009
@@ -45,7 +45,7 @@
 {
     private int line = 0;
     private int column = 0;
-    private boolean provideScope = true;
+    private boolean provideScope = false;
     private String templateName;
 
     /**
@@ -146,7 +146,7 @@
         rsvc = rs;
 
         String property = 
getScopeName()+'.'+RuntimeConstants.PROVIDE_SCOPE_CONTROL;
-        this.provideScope = rsvc.getBoolean(property, true);
+        this.provideScope = rsvc.getBoolean(property, provideScope);
     }
 
     /**
@@ -176,10 +176,15 @@
         {
             String name = getScopeName();
             Object previous = context.get(name);
-            context.put(name, new Scope(this, previous));
+            context.put(name, makeScope(previous));
         }
     }
 
+    protected Scope makeScope(Object prev)
+    {
+        return new Scope(this, prev);
+    }
+
     /**
      * This cleans up any scope control for this directive after rendering,
      * assuming the scope control was turned on.
@@ -191,13 +196,7 @@
             String name = getScopeName();
             Object obj = context.get(name);
             
-            // the user can override the scope with a #set,
-            // since that means they don't care about a replaced value
-            // and obviously aren't too keen on their scope control,
-            // and especially since #set is meant to be handled globally,
-            // we'll assume they know what they're doing and not worry
-            // about replacing anything superseded by this directive's scope
-            if (obj instanceof Scope)
+            try
             {
                 Scope scope = (Scope)obj;
                 if (scope.getParent() != null)
@@ -213,6 +212,15 @@
                     context.remove(name);
                 }
             }
+            catch (ClassCastException cce)
+            {
+                // the user can override the scope with a #set,
+                // since that means they don't care about a replaced value
+                // and obviously aren't too keen on their scope control,
+                // and especially since #set is meant to be handled globally,
+                // we'll assume they know what they're doing and not worry
+                // about replacing anything superseded by this directive's 
scope
+            }
         }
     }
 

Modified: 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Scope.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Scope.java?rev=778045&r1=778044&r2=778045&view=diff
==============================================================================
--- 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Scope.java 
(original)
+++ 
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Scope.java 
Sat May 23 22:17:46 2009
@@ -33,23 +33,23 @@
 public class Scope extends AbstractMap
 {
     private Map storage;
-    protected final Object replaced;
-    protected final Scope parent;
+    private Object replaced;
+    private Scope parent;
     protected final Object owner;
 
     public Scope(Object owner, Object previous)
     {
         this.owner = owner;
-        if (previous instanceof Scope)
+        if (previous != null)
         {
-            this.parent = (Scope)previous;
-            // keep easy access to the user's object
-            this.replaced = this.parent.replaced;
-        }
-        else
-        {
-            this.parent = null;
-            this.replaced = previous;
+            try
+            {
+                this.parent = (Scope)previous;
+            }
+            catch (ClassCastException cce)
+            {
+                this.replaced = previous;
+            }
         }
     }
 
@@ -135,6 +135,10 @@
      */
     public Object getReplaced()
     {
+        if (replaced == null && parent != null)
+        {
+            return parent.getReplaced();
+        }
         return replaced;
     }
 

Modified: 
velocity/engine/trunk/src/test/org/apache/velocity/test/BreakDirectiveTestCase.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/src/test/org/apache/velocity/test/BreakDirectiveTestCase.java?rev=778045&r1=778044&r2=778045&view=diff
==============================================================================
--- 
velocity/engine/trunk/src/test/org/apache/velocity/test/BreakDirectiveTestCase.java
 (original)
+++ 
velocity/engine/trunk/src/test/org/apache/velocity/test/BreakDirectiveTestCase.java
 Sat May 23 22:17:46 2009
@@ -19,6 +19,8 @@
  * under the License.    
  */
 
+import org.apache.velocity.app.VelocityEngine;
+
 /**
  * This class tests the break directive.
  */
@@ -29,6 +31,15 @@
         super(name);
     }
 
+    protected void setUpEngine(VelocityEngine engine)
+    {
+        engine.setProperty("a.provide.scope.control", "true");
+        engine.setProperty("define.provide.scope.control", "true");
+        engine.setProperty("evaluate.provide.scope.control", "true");
+        engine.setProperty("macro.provide.scope.control", "true");
+        engine.setProperty("template.provide.scope.control", "true");
+    }
+
     public void testBadArgs()
     {
         context.put("foo","foo");

Modified: 
velocity/engine/trunk/src/test/org/apache/velocity/test/EvaluateTestCase.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/src/test/org/apache/velocity/test/EvaluateTestCase.java?rev=778045&r1=778044&r2=778045&view=diff
==============================================================================
--- 
velocity/engine/trunk/src/test/org/apache/velocity/test/EvaluateTestCase.java 
(original)
+++ 
velocity/engine/trunk/src/test/org/apache/velocity/test/EvaluateTestCase.java 
Sat May 23 22:17:46 2009
@@ -141,6 +141,7 @@
      */
     public void testStopAndBreak()
     {
+        engine.setProperty("evaluate.provide.scope.control", "true");
         assertEvalEquals("t ", "t #stop t2 #evaluate('t3')");
         assertEvalEquals("t ", "t #break t2 #evaluate('t3')");
         //assertEvalEquals("t t2 t3 ", "t t2 #evaluate('t3 #stop t4') t5");

Modified: 
velocity/engine/trunk/src/test/org/apache/velocity/test/ScopeTestCase.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/src/test/org/apache/velocity/test/ScopeTestCase.java?rev=778045&r1=778044&r2=778045&view=diff
==============================================================================
--- velocity/engine/trunk/src/test/org/apache/velocity/test/ScopeTestCase.java 
(original)
+++ velocity/engine/trunk/src/test/org/apache/velocity/test/ScopeTestCase.java 
Sat May 23 22:17:46 2009
@@ -21,6 +21,7 @@
 
 import java.util.HashMap;
 import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
 import org.apache.velocity.runtime.RuntimeConstants;
 import org.apache.velocity.runtime.directive.Scope;
 
@@ -34,9 +35,15 @@
        super(name);
     }
 
-    public void setUp() throws Exception
+    protected void setUpEngine(VelocityEngine engine)
     {
-        super.setUp();
+        engine.setProperty("a.provide.scope.control", "true");
+        engine.setProperty("define.provide.scope.control", "true");
+        engine.setProperty("evaluate.provide.scope.control", "true");
+        engine.setProperty("foo.provide.scope.control", "true");
+        engine.setProperty("macro.provide.scope.control", "true");
+        engine.setProperty("template.provide.scope.control", "true");
+        engine.setProperty("vm.provide.scope.control", "true");
         engine.setProperty(RuntimeConstants.SET_NULL_ALLOWED, Boolean.TRUE);
     }
 

Modified: velocity/engine/trunk/xdocs/docs/developer-guide.xml
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/xdocs/docs/developer-guide.xml?rev=778045&r1=778044&r2=778045&view=diff
==============================================================================
--- velocity/engine/trunk/xdocs/docs/developer-guide.xml (original)
+++ velocity/engine/trunk/xdocs/docs/developer-guide.xml Sat May 23 22:17:46 
2009
@@ -1614,10 +1614,12 @@
 </p>
 
 <p>
-<code>define.provide.scope.control = true</code><br/>
-Used to control the automatic provision of the $define scope control
-during #define() calls. The default is true.
-Set it to false if unused and you want a tiny performance boost.
+<code>define.provide.scope.control = false</code><br/>
+Used to turn on the automatic provision of the $define scope control
+during #define() calls. The default is false.
+Set it to true if you want a local, managed namespace
+you can put references in when within a #define block or if you want it for
+more advanced #break usage.
 </p>
 
 <p>
@@ -1625,10 +1627,12 @@
 </p>
 
 <p>
-<code>evaluate.provide.scope.control = true</code><br/>
-Used to control the automatic provision of the $evaluate scope
+<code>evaluate.provide.scope.control = false</code><br/>
+Used to turn on the automatic provision of the $evaluate scope
 during #evaluate() or Velocity[Engine].evaluate(...) calls. The default
-is true.  Set it to false if unused and you want a tiny performance boost.
+is false.  Set it to true if you want a local, managed namespace
+you can put references in during an evaluation or if you want it for
+more advanced #break usage.
 </p>
 
 <p>
@@ -1638,7 +1642,8 @@
 <p>
 <code>foreach.provide.scope.control = true</code><br/>
 Used to control the automatic provision of the $foreach scope
-during #foreach calls. The default is true.
+during #foreach calls.  This gives access to the foreach status information
+(e.g. $foreach.index or $foreach.hasNext). The default is true.
 Set it to false if unused and you want a tiny performance boost.
 </p>
 
@@ -1687,10 +1692,11 @@
 prevents runaway #parse() recursion.
 </p>
 <p>
-<code>template.provide.scope.control = true</code><br/>
-Used to control the automatic provision of the $template scope control
-during #parse calls (and template.merge(...) calls). The default is true.
-Set it to false if unused and you want a tiny performance boost.
+<code>template.provide.scope.control = false</code><br/>
+Used to turn on the automatic provision of the $template scope control
+during #parse calls and template.merge(...) calls. The default is false.
+Set it to true if you want a secure namespace for your template variables
+or more advanced #break control.
 </p>
 
 
@@ -1871,17 +1877,18 @@
 macro feature was introduced in Velocity 1.7.
 </p>
 <p>
-<code>macro.provide.scope.control = true</code><br/>
-Used to control the automatic provision of the $macro scope control
-during #macro calls. The default is true.
-Set it to false if unused and you want a tiny performance boost.
+<code>macro.provide.scope.control = false</code><br/>
+Used to turn on the automatic provision of the $macro scope control
+during #macro calls. The default is false.
+Set it to true if you need a local namespace in macros or more
+advanced #break controls.
 </p>
 <p>
-<code>&lt;somebodymacro&gt;.provide.scope.control = true</code><br/>
-Used to control the automatic provision of the $&lt;nameofthemacro&gt; scope 
control
+<code>&lt;somebodymacro&gt;.provide.scope.control = false</code><br/>
+Used to turn on the automatic provision of the $&lt;nameofthemacro&gt; scope 
control
 during a call to a macro with a body (e.g. #...@foo #set($foo.a=$b) ... $foo.a 
#end).
-The default is true. Set it to false if you heavily use that body macro without
-using the scope control and you want a tiny performance boost.
+The default is false. Set it to true if you happen to need a namespace just
+for your macro's body content or more advanced #break controls.
 </p>
 
 <p>


Reply via email to