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 &lt;amacro&gt; 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><somebodymacro>.provide.scope.control = true</code><br/>
-Used to control the automatic provision of the $<nameofthemacro> scope
control
+<code><somebodymacro>.provide.scope.control = false</code><br/>
+Used to turn on the automatic provision of the $<nameofthemacro> 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>