You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2017/08/07 22:32:17 UTC
[15/21] incubator-freemarker git commit: FREEMARKER-63: Added
isNestedContentSupported() to templateDirectiveModel
FREEMARKER-63: Added isNestedContentSupported() to templateDirectiveModel
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/5bd19ade
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/5bd19ade
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/5bd19ade
Branch: refs/heads/3
Commit: 5bd19adeb8dd24cde34987c4724c7a5d5d227f52
Parents: 589d9b8
Author: ddekany <dd...@apache.org>
Authored: Sun Jul 30 23:07:29 2017 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sun Jul 30 23:07:29 2017 +0200
----------------------------------------------------------------------
FM3-CHANGE-LOG.txt | 2 ++
.../freemarker/core/DirectiveCallPlaceTest.java | 16 ++++++++++++++++
.../core/EnvironmentGetTemplateVariantsTest.java | 6 ++++++
.../core/TemplateCallableModelTest.java | 4 ++++
.../core/TheadInterruptingSupportTest.java | 16 +++++++++++++++-
.../core/userpkg/AllFeaturesDirective.java | 6 ++++++
.../core/userpkg/NamedVarargsOnlyDirective.java | 7 +++++++
.../userpkg/PositionalVarargsOnlyDirective.java | 7 +++++++
.../core/userpkg/TwoNamedParamsDirective.java | 8 ++++++--
.../userpkg/TwoNestedContentParamsDirective.java | 6 ++++++
.../userpkg/TwoPositionalParamsDirective.java | 8 ++++++--
.../core/userpkg/UpperCaseDirective.java | 6 ++++++
.../core/valueformat/NumberFormatTest.java | 5 +++++
.../core/templatesuite/expected/interpret.txt | 4 +---
.../core/templatesuite/templates/interpret.ftl | 7 ++++---
.../freemarker/core/ASTDynamicTopLevelCall.java | 18 +++++++++++++-----
.../freemarker/core/BuiltInsForStringsMisc.java | 6 +++++-
.../core/model/TemplateDirectiveModel.java | 13 +++++++++++++
.../apache/freemarker/servlet/IncludePage.java | 5 +++++
.../jsp/CustomTagAndELFunctionCombiner.java | 10 ++++++++++
.../servlet/jsp/SimpleTagDirectiveModel.java | 5 +++++
.../freemarker/servlet/jsp/TagDirectiveModel.java | 5 +++++
.../test/templateutil/AssertDirective.java | 5 +++++
.../test/templateutil/AssertEqualsDirective.java | 14 ++++++++++----
.../test/templateutil/AssertFailsDirective.java | 14 ++++++++++----
.../test/templateutil/NoOutputDirective.java | 6 ++++++
26 files changed, 184 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/FM3-CHANGE-LOG.txt
----------------------------------------------------------------------
diff --git a/FM3-CHANGE-LOG.txt b/FM3-CHANGE-LOG.txt
index 6b347e5..938f9bf 100644
--- a/FM3-CHANGE-LOG.txt
+++ b/FM3-CHANGE-LOG.txt
@@ -108,6 +108,8 @@ Node: Changes already mentioned above aren't repeated here!
of the `execute` method.
- ?isTransform was removed (as there are no transforms anymore).
Converter note: The template converter tool replaces it with ?isDirective
+- The directive returned by `?interpret` doesn't allow nested content anymore. (It wasn't useful earlier either;
+ the nested content was simply executed after the interpreted string.)
Java API changes
================
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java
index 94cd199..f959b1d 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java
@@ -142,6 +142,11 @@ public class DirectiveCallPlaceTest extends TemplateTest {
return ArgumentArrayLayout.PARAMETERLESS;
}
+ @Override
+ public boolean isNestedContentSupported() {
+ return true;
+ }
+
protected abstract Class getTextConversionIdentity();
private String convertBodyText(CallPlace callPlace, Environment env) throws TemplateException,
@@ -207,6 +212,11 @@ public class DirectiveCallPlaceTest extends TemplateTest {
return ArgumentArrayLayout.PARAMETERLESS;
}
+ @Override
+ public boolean isNestedContentSupported() {
+ return true;
+ }
+
private String getTemplateSourceName(CallPlace callPlace) {
return callPlace.getTemplate().getSourceName();
}
@@ -239,6 +249,12 @@ public class DirectiveCallPlaceTest extends TemplateTest {
public ArgumentArrayLayout getArgumentArrayLayout() {
return ARGS_LAYOUT;
}
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return true;
+ }
+
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core-test/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java
index 40f7c63..10205e9 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java
@@ -211,6 +211,12 @@ public class EnvironmentGetTemplateVariantsTest extends TemplateTest {
public ArgumentArrayLayout getArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
+
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return false;
+ }
});
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateCallableModelTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateCallableModelTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateCallableModelTest.java
index a51c657..b7d55f5 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateCallableModelTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateCallableModelTest.java
@@ -167,6 +167,10 @@ public class TemplateCallableModelTest extends TemplateTest {
assertErrorContains("<@tncp ; i>${i}</@>", " 1 ", "\"i\"", " 2 ");
assertOutput("<@tncp ; i, j>${i} ${j}</@>", "1 2");
assertErrorContains("<@tncp ; i, j, k>${i}</@>", " 3 ", "\"i\", \"j\", \"k\"", " 2 ");
+
+ assertOutput("<@p...@p>",
+ "#p(p1=null, p2=null)");
+ assertErrorContains("<@p> </...@p>", "Nested content", "not supported");
}
@Test
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core-test/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java
index 2ab270a..a6b01ac 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java
@@ -133,10 +133,14 @@ public class TheadInterruptingSupportTest {
public ArgumentArrayLayout getArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return false;
+ }
}
public class CustomLoopDirective implements TemplateDirectiveModel {
-
@Override
public void execute(TemplateModel[] args, CallPlace callPlace, Writer out, Environment env)
throws TemplateException, IOException {
@@ -150,6 +154,11 @@ public class TheadInterruptingSupportTest {
public ArgumentArrayLayout getArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return true;
+ }
}
public class SleepDirective implements TemplateDirectiveModel {
@@ -168,6 +177,11 @@ public class TheadInterruptingSupportTest {
public ArgumentArrayLayout getArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return false;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesDirective.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesDirective.java
index e3be217..24a3a4e 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesDirective.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesDirective.java
@@ -123,4 +123,10 @@ public class AllFeaturesDirective extends TestTemplateDirectiveModel {
public ArgumentArrayLayout getArgumentArrayLayout() {
return ARGS_LAYOUT;
}
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return true;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/NamedVarargsOnlyDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/NamedVarargsOnlyDirective.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/NamedVarargsOnlyDirective.java
index aa69e8f..f978dbe 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/NamedVarargsOnlyDirective.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/NamedVarargsOnlyDirective.java
@@ -56,4 +56,11 @@ public class NamedVarargsOnlyDirective extends TestTemplateDirectiveModel {
public ArgumentArrayLayout getArgumentArrayLayout() {
return ARGS_LAYOUT;
}
+
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return false;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PositionalVarargsOnlyDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PositionalVarargsOnlyDirective.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PositionalVarargsOnlyDirective.java
index cc3f9d8..b9d2b92 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PositionalVarargsOnlyDirective.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PositionalVarargsOnlyDirective.java
@@ -54,4 +54,11 @@ public class PositionalVarargsOnlyDirective extends TestTemplateDirectiveModel {
public ArgumentArrayLayout getArgumentArrayLayout() {
return ARGS_LAYOUT;
}
+
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return false;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNamedParamsDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNamedParamsDirective.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNamedParamsDirective.java
index dbff203..b4b85d3 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNamedParamsDirective.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNamedParamsDirective.java
@@ -23,7 +23,6 @@ import java.io.IOException;
import java.io.Writer;
import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.NestedContentNotSupportedException;
import org.apache.freemarker.core.TemplateException;
import org.apache.freemarker.core.model.ArgumentArrayLayout;
import org.apache.freemarker.core.model.CallPlace;
@@ -55,7 +54,6 @@ public class TwoNamedParamsDirective extends TestTemplateDirectiveModel {
@Override
public void execute(TemplateModel[] args, CallPlace callPlace, Writer out, Environment env)
throws TemplateException, IOException {
- NestedContentNotSupportedException.check(callPlace);
out.write("#n(");
printParam(N1_ARG_NAME, args[N1_ARG_IDX], out, true);
printParam(N2_ARG_NAME, args[N2_ARG_IDX], out);
@@ -66,4 +64,10 @@ public class TwoNamedParamsDirective extends TestTemplateDirectiveModel {
public ArgumentArrayLayout getArgumentArrayLayout() {
return ARGS_LAYOUT;
}
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return false;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNestedContentParamsDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNestedContentParamsDirective.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNestedContentParamsDirective.java
index eee1978..ff47315 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNestedContentParamsDirective.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNestedContentParamsDirective.java
@@ -50,4 +50,10 @@ public class TwoNestedContentParamsDirective extends TestTemplateDirectiveModel
public ArgumentArrayLayout getArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return true;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoPositionalParamsDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoPositionalParamsDirective.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoPositionalParamsDirective.java
index 52fe77e..4bd671e 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoPositionalParamsDirective.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoPositionalParamsDirective.java
@@ -23,7 +23,6 @@ import java.io.IOException;
import java.io.Writer;
import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.NestedContentNotSupportedException;
import org.apache.freemarker.core.TemplateException;
import org.apache.freemarker.core.model.ArgumentArrayLayout;
import org.apache.freemarker.core.model.CallPlace;
@@ -44,7 +43,6 @@ public class TwoPositionalParamsDirective extends TestTemplateDirectiveModel {
@Override
public void execute(TemplateModel[] args, CallPlace callPlace, Writer out, Environment env)
throws TemplateException, IOException {
- NestedContentNotSupportedException.check(callPlace);
out.write("#p(");
printParam("p1", args[0], out, true);
printParam("p2", args[1], out);
@@ -55,4 +53,10 @@ public class TwoPositionalParamsDirective extends TestTemplateDirectiveModel {
public ArgumentArrayLayout getArgumentArrayLayout() {
return ARGS_LAYOUT;
}
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return false;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/UpperCaseDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/UpperCaseDirective.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/UpperCaseDirective.java
index 507b820..220aeef 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/UpperCaseDirective.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/UpperCaseDirective.java
@@ -50,4 +50,10 @@ public class UpperCaseDirective implements TemplateDirectiveModel {
public ArgumentArrayLayout getArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return true;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java
index 830a16c..318e7ae 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java
@@ -189,6 +189,11 @@ public class NumberFormatTest extends TemplateTest {
public ArgumentArrayLayout getArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return false;
+ }
});
assertOutput(
"<#assign s1 = n?string>"
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/interpret.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/interpret.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/interpret.txt
index fe862e6..0ecb929 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/interpret.txt
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/interpret.txt
@@ -16,8 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-abcdef
-abcdef
-abcdef
+abcabcabc
M
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/interpret.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/interpret.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/interpret.ftl
index 41f8425..f0240e4 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/interpret.ftl
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/interpret.ftl
@@ -18,8 +18,9 @@
-->
<#global x=["a", "b", "c"]>
<#global templateSource = r"<#list x as y>${y}</#list>">
-<@templateSource?interpret>def</@>
-<@[templateSource]?interpret>def</@>
-<@[templateSource,"id"]?interpret>def</@>
+<@templateSource?interpret />
+<@[templateSource]?interpret />
+<@[templateSource,"id"]?interpret />
+<@assertFails message="nested content"><@templateSource?interpret>x</@></@>
<#assign t = '<#macro m>M</#macro>'?interpret><@t /><@m/>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDynamicTopLevelCall.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDynamicTopLevelCall.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDynamicTopLevelCall.java
index eb06e23..32f14ca 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDynamicTopLevelCall.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDynamicTopLevelCall.java
@@ -45,7 +45,8 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
* AST node: {@code <@exp ...>}.
* Executes a {@link TemplateCallableModel} that's embeddable directly into the static text (hence "top level"). At
* least in the default template language the value must be a {@link TemplateDirectiveModel}, though technically
- * calling a {@link TemplateFunctionModel} is possible as well (hence it's not called "dynamic directive call").
+ * calling a {@link TemplateFunctionModel} is possible as well (hence this class is not called "dynamic directive
+ * call").
* <p>
* The {@link TemplateCallableModel} object is obtained on runtime by evaluating an expression, and the parameter list
* is also validated (how many positional parameters are allowed, what named parameters are supported) then. Hence, the
@@ -99,12 +100,14 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
TemplateCallableModel callableValue;
TemplateDirectiveModel directive;
TemplateFunctionModel function;
+ boolean nestedContentSupported;
{
TemplateModel callableValueTM = callableValueExp._eval(env);
if (callableValueTM instanceof TemplateDirectiveModel) {
callableValue = (TemplateCallableModel) callableValueTM;
directive = (TemplateDirectiveModel) callableValueTM;
function = null;
+ nestedContentSupported = directive.isNestedContentSupported();
} else if (callableValueTM instanceof TemplateFunctionModel) {
if (!allowCallingFunctions) {
// TODO [FM3][CF] Better exception
@@ -114,6 +117,7 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
callableValue = (TemplateCallableModel) callableValueTM;
directive = null;
function = (TemplateFunctionModel) callableValue;
+ nestedContentSupported = false;
} else if (callableValueTM instanceof ASTDirMacro) {
// TODO [FM3][CF] Until macros were refactored to be TemplateDirectiveModel-s, we have this hack here.
ASTDirMacro macro = (ASTDirMacro) callableValueTM;
@@ -147,6 +151,10 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
}
}
+ if (!nestedContentSupported && hasNestedContent()) {
+ throw new _MiscTemplateException(env, "Nested content is not supported by this directive.");
+ }
+
ArgumentArrayLayout argsLayout = callableValue.getArgumentArrayLayout();
int predefPosArgCnt = argsLayout.getPredefinedPositionalArgumentCount();
int posVarargsArgIdx = argsLayout.getPositionalVarargsArgumentIndex();
@@ -175,7 +183,7 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
}
execArgs[posVarargsArgIdx] = varargsSeq;
} else if (positionalArgs != null && positionalArgs.length > predefPosArgCnt) {
- throw new _MiscTemplateException(this,
+ throw new _MiscTemplateException(env,
"The target callable ",
(predefPosArgCnt != 0
? new Object[] { "can only have ", predefPosArgCnt }
@@ -197,7 +205,7 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
if (namedVarargsHash == null) {
if (namedVarargsArgumentIndex == -1) {
Collection<String> validNames = predefNamedArgsMap.getKeys();
- throw new _MiscTemplateException(this,
+ throw new _MiscTemplateException(env,
validNames == null || validNames.isEmpty()
? new Object[] {
"The target callable doesn't have any by-name-passed parameters (like ",
@@ -225,7 +233,7 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
} else {
TemplateModel result = function.execute(execArgs, env, this);
if (result == null) {
- throw new _MiscTemplateException(this, "Function has returned no value (or null)");
+ throw new _MiscTemplateException(env, "Function has returned no value (or null)");
}
// TODO [FM3][CF]
throw new BugException("Top-level function call not yet implemented");
@@ -389,7 +397,7 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
int nestedContentParamNamesSize = nestedContentParamNames != null ? nestedContentParamNames.size() : 0;
int nestedContentParamValuesSize = nestedContentParamValues != null ? nestedContentParamValues.length : 0;
if (nestedContentParamValuesSize != nestedContentParamNamesSize) {
- throw new _MiscTemplateException(this,
+ throw new _MiscTemplateException(env,
"The invocation declares ", (nestedContentParamNamesSize != 0 ? nestedContentParamNamesSize : "no"),
" nested content parameter(s)",
(nestedContentParamNamesSize != 0
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsMisc.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsMisc.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsMisc.java
index 4d15516..d9ad1bf 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsMisc.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsMisc.java
@@ -200,7 +200,6 @@ class BuiltInsForStringsMisc {
@Override
public void execute(TemplateModel[] args, CallPlace callPlace, Writer out, Environment env)
throws TemplateException, IOException {
- // TODO [FM3] Disallow loop vars, and nested content
try {
boolean lastFIRE = env.setFastInvalidReferenceExceptions(false);
try {
@@ -222,6 +221,11 @@ class BuiltInsForStringsMisc {
public ArgumentArrayLayout getArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return false;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveModel.java
index 6995afe..3529c8c 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveModel.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveModel.java
@@ -45,4 +45,17 @@ public interface TemplateDirectiveModel extends TemplateCallableModel {
void execute(TemplateModel[] args, CallPlace callPlace, Writer out, Environment env)
throws TemplateException, IOException;
+ /**
+ * Tells if this directive supports having nested content. If {@code false}, yet the caller specifies a non-empty
+ * (strictly 0-length, not even whitespace is allowed), FreeMarker will throw a {@link TemplateException} with
+ * descriptive error message, and {@link #execute(TemplateModel[], CallPlace, Writer, Environment)} won't be called.
+ * If {@code true}, the author of the directive shouldn't forget calling {@link
+ * CallPlace#executeNestedContent(TemplateModel[], Writer, Environment)}, unless the intent was to skip the nested
+ * content. (This property was added to prevent the frequent oversight (in FreeMarker 2) where a directive that
+ * isn't supposed to have nested content doesn't examine if there's a nested content to throw an exception in that
+ * case. Then if there's nested content, it will be silently skipped during execution, as the directive never
+ * calls {@link CallPlace#executeNestedContent(TemplateModel[], Writer, Environment)}.)
+ */
+ boolean isNestedContentSupported();
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/IncludePage.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/IncludePage.java b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/IncludePage.java
index c6adead..6199fcc 100644
--- a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/IncludePage.java
+++ b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/IncludePage.java
@@ -189,6 +189,11 @@ public class IncludePage implements TemplateDirectiveModel {
return ARGS_LAYOUT;
}
+ @Override
+ public boolean isNestedContentSupported() {
+ return false;
+ }
+
private static final class CustomParamsRequest extends HttpServletRequestWrapper {
private final HashMap paramsMap;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java
index c51e611..2302f22 100644
--- a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java
+++ b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java
@@ -113,6 +113,11 @@ class CustomTagAndELFunctionCombiner {
public ArgumentArrayLayout getArgumentArrayLayout() {
return templateDirectiveModel.getArgumentArrayLayout();
}
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return templateDirectiveModel.isNestedContentSupported();
+ }
}
private static class TemplateDirectiveModelAndTemplateMethodModelEx extends CombinedTemplateModel
@@ -142,6 +147,11 @@ class CustomTagAndELFunctionCombiner {
public ArgumentArrayLayout getArgumentArrayLayout() {
return templateDirectiveModel.getArgumentArrayLayout();
}
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return templateDirectiveModel.isNestedContentSupported();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/SimpleTagDirectiveModel.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/SimpleTagDirectiveModel.java b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/SimpleTagDirectiveModel.java
index 810a50c..4e7d6c7 100644
--- a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/SimpleTagDirectiveModel.java
+++ b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/SimpleTagDirectiveModel.java
@@ -111,6 +111,11 @@ class SimpleTagDirectiveModel extends JspTagModelBase implements TemplateDirecti
return ARGS_LAYOUT;
}
+ @Override
+ public boolean isNestedContentSupported() {
+ return true;
+ }
+
static final class TemplateExceptionWrapperJspException extends JspException {
public TemplateExceptionWrapperJspException(Throwable cause) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TagDirectiveModel.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TagDirectiveModel.java b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TagDirectiveModel.java
index 661046f..86febfa 100644
--- a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TagDirectiveModel.java
+++ b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TagDirectiveModel.java
@@ -121,6 +121,11 @@ class TagDirectiveModel extends JspTagModelBase implements TemplateDirectiveMode
return ARGS_LAYOUT;
}
+ @Override
+ public boolean isNestedContentSupported() {
+ return true;
+ }
+
/**
* Implements extra methods to help mimicking JSP container behavior around the
* {@link TemplateDirectiveModel#execute(TemplateModel[], CallPlace, Writer, Environment)} call.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertDirective.java b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertDirective.java
index 0a9e9cd..ffb2c40 100644
--- a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertDirective.java
+++ b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertDirective.java
@@ -70,4 +70,9 @@ public class AssertDirective implements TemplateDirectiveModel {
public ArgumentArrayLayout getArgumentArrayLayout() {
return ARGS_LAYOUT;
}
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertEqualsDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertEqualsDirective.java b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertEqualsDirective.java
index a02308f..8334c20 100644
--- a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertEqualsDirective.java
+++ b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertEqualsDirective.java
@@ -80,6 +80,16 @@ public class AssertEqualsDirective implements TemplateDirectiveModel {
}
}
+ @Override
+ public ArgumentArrayLayout getArgumentArrayLayout() {
+ return ARGS_LAYOUT;
+ }
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return false;
+ }
+
private String tryUnwrap(TemplateModel value) throws TemplateModelException {
if (value == null) return "null";
// This is the same order as comparison goes:
@@ -91,8 +101,4 @@ public class AssertEqualsDirective implements TemplateDirectiveModel {
else return value.toString();
}
- @Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
- return ARGS_LAYOUT;
- }
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertFailsDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertFailsDirective.java b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertFailsDirective.java
index effc0e7..c089300 100644
--- a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertFailsDirective.java
+++ b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertFailsDirective.java
@@ -135,6 +135,16 @@ public class AssertFailsDirective implements TemplateDirectiveModel {
}
}
+ @Override
+ public ArgumentArrayLayout getArgumentArrayLayout() {
+ return ARGS_LAYOUT;
+ }
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return true;
+ }
+
private String getAsString(TemplateModel value, String paramName, Environment env)
throws BadParameterTypeException, TemplateModelException {
if (value == null) {
@@ -166,8 +176,4 @@ public class AssertFailsDirective implements TemplateDirectiveModel {
}
}
- @Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
- return ARGS_LAYOUT;
- }
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5bd19ade/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/NoOutputDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/NoOutputDirective.java b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/NoOutputDirective.java
index b027974..7e53023 100644
--- a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/NoOutputDirective.java
+++ b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/NoOutputDirective.java
@@ -48,4 +48,10 @@ public class NoOutputDirective implements TemplateDirectiveModel {
public ArgumentArrayLayout getArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return true;
+ }
+
}