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/05 14:26:58 UTC
[38/50] incubator-freemarker git commit: Simplified (and faster)
capturing assignment implementation (backported from FM3 branch)
Simplified (and faster) capturing assignment implementation (backported from FM3 branch)
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/16ff1746
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/16ff1746
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/16ff1746
Branch: refs/heads/2.3
Commit: 16ff17463762a18e9316814e53b1ad0e5eb09559
Parents: 77e877c
Author: ddekany <dd...@apache.org>
Authored: Thu Jul 27 18:54:01 2017 +0200
Committer: ddekany <dd...@apache.org>
Committed: Thu Jul 27 19:14:57 2017 +0200
----------------------------------------------------------------------
.../java/freemarker/core/BlockAssignment.java | 84 +++++---------------
src/main/java/freemarker/core/Environment.java | 15 ++++
.../core/CapturingAssignmentTest.java | 55 +++++++++++++
3 files changed, 89 insertions(+), 65 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/16ff1746/src/main/java/freemarker/core/BlockAssignment.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BlockAssignment.java b/src/main/java/freemarker/core/BlockAssignment.java
index 07ff070..8c9e403 100644
--- a/src/main/java/freemarker/core/BlockAssignment.java
+++ b/src/main/java/freemarker/core/BlockAssignment.java
@@ -21,14 +21,11 @@ package freemarker.core;
import java.io.IOException;
import java.io.StringWriter;
-import java.io.Writer;
-import java.util.Map;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateTransformModel;
/**
* Like [#local x]...[/#local].
@@ -51,21 +48,28 @@ final class BlockAssignment extends TemplateElement {
@Override
TemplateElement[] accept(Environment env) throws TemplateException, IOException {
TemplateElement[] children = getChildBuffer();
+
+ TemplateModel value;
if (children != null) {
- env.visitAndTransform(children, new CaptureOutput(env), null);
+ StringWriter out = new StringWriter();
+ env.visit(children, out);
+ value = capturedStringToModel(out.toString());
+ } else {
+ value = capturedStringToModel("");
+ }
+
+ if (namespaceExp != null) {
+ ((Environment.Namespace) namespaceExp.eval(env)).put(varName, value);
+ } else if (scope == Assignment.NAMESPACE) {
+ env.setVariable(varName, value);
+ } else if (scope == Assignment.GLOBAL) {
+ env.setGlobalVariable(varName, value);
+ } else if (scope == Assignment.LOCAL) {
+ env.setLocalVariable(varName, value);
} else {
- TemplateModel value = capturedStringToModel("");
- if (namespaceExp != null) {
- Environment.Namespace ns = (Environment.Namespace) namespaceExp.eval(env);
- ns.put(varName, value);
- } else if (scope == Assignment.NAMESPACE) {
- env.setVariable(varName, value);
- } else if (scope == Assignment.GLOBAL) {
- env.setGlobalVariable(varName, value);
- } else if (scope == Assignment.LOCAL) {
- env.setLocalVariable(varName, value);
- }
+ throw new BugException("Unhandled scope");
}
+
return null;
}
@@ -73,56 +77,6 @@ final class BlockAssignment extends TemplateElement {
return markupOutputFormat == null ? new SimpleScalar(s) : markupOutputFormat.fromMarkup(s);
}
- private class CaptureOutput implements TemplateTransformModel {
- private final Environment env;
- private final Environment.Namespace fnsModel;
-
- CaptureOutput(Environment env) throws TemplateException {
- this.env = env;
- TemplateModel nsModel = null;
- if (namespaceExp != null) {
- nsModel = namespaceExp.eval(env);
- if (!(nsModel instanceof Environment.Namespace)) {
- throw new NonNamespaceException(namespaceExp, nsModel, env);
- }
- }
- fnsModel = (Environment.Namespace ) nsModel;
- }
-
- public Writer getWriter(Writer out, Map args) {
- return new StringWriter() {
- @Override
- public void close() throws IOException {
- TemplateModel result;
- try {
- result = capturedStringToModel(toString());
- } catch (TemplateModelException e) {
- // [Java 1.6] e to cause
- throw new IOException("Failed to create FTL value from captured string: " + e);
- }
- switch(scope) {
- case Assignment.NAMESPACE: {
- if (fnsModel != null) {
- fnsModel.put(varName, result);
- } else {
- env.setVariable(varName, result);
- }
- break;
- }
- case Assignment.LOCAL: {
- env.setLocalVariable(varName, result);
- break;
- }
- case Assignment.GLOBAL: {
- env.setGlobalVariable(varName, result);
- break;
- }
- }
- }
- };
- }
- }
-
@Override
protected String dump(boolean canonical) {
StringBuilder sb = new StringBuilder();
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/16ff1746/src/main/java/freemarker/core/Environment.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Environment.java b/src/main/java/freemarker/core/Environment.java
index 1fa59a0..c826381 100644
--- a/src/main/java/freemarker/core/Environment.java
+++ b/src/main/java/freemarker/core/Environment.java
@@ -377,6 +377,21 @@ public final class Environment extends Configurable {
}
}
+ /**
+ * Visits the elements while temporarily using the parameter output {@link Writer}.
+ *
+ * @since 2.3.27
+ */
+ final void visit(TemplateElement[] elementBuffer, Writer out) throws IOException, TemplateException {
+ Writer prevOut = this.out;
+ this.out = out;
+ try {
+ visit(elementBuffer);
+ } finally {
+ this.out = prevOut;
+ }
+ }
+
@SuppressFBWarnings(value = "RANGE_ARRAY_INDEX", justification = "Not called when stack is empty")
private TemplateElement replaceTopElement(TemplateElement element) {
return instructionStack[instructionStackSize - 1] = element;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/16ff1746/src/test/java/freemarker/core/CapturingAssignmentTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/CapturingAssignmentTest.java b/src/test/java/freemarker/core/CapturingAssignmentTest.java
new file mode 100644
index 0000000..2664dff
--- /dev/null
+++ b/src/test/java/freemarker/core/CapturingAssignmentTest.java
@@ -0,0 +1,55 @@
+package freemarker.core;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import freemarker.cache.StringTemplateLoader;
+import freemarker.template.Configuration;
+import freemarker.template.TemplateException;
+import freemarker.test.TemplateTest;
+
+public class CapturingAssignmentTest extends TemplateTest {
+
+ @Override
+ protected Configuration createConfiguration() throws Exception {
+ Configuration cfg = super.createConfiguration();
+ cfg.setTemplateLoader(new StringTemplateLoader());
+ return cfg;
+ }
+
+ @Test
+ public void testAssign() throws IOException, TemplateException {
+ assertOutput("<#assign x></#assign>[${x}]", "[]");
+ assertOutput("<#assign x><p>${1 + 1}</#assign>${x + '&'}", "<p>2&");
+ assertOutput("<#ftl outputFormat='HTML'><#assign x><p>${1 + 1}</#assign>${x + '&'}", "<p>2&");
+ }
+
+ @Test
+ public void testAssignNs() throws IOException, TemplateException {
+ addTemplate("lib.ftl", "");
+ assertOutput("<#import 'lib.ftl' as lib>"
+ + "<#assign x in lib></#assign>[${lib.x}]", "[]");
+ assertOutput("<#import 'lib.ftl' as lib>"
+ + "<#assign x in lib><p>${1 + 1}</#assign>${lib.x + '&'}", "<p>2&");
+ assertOutput("<#ftl outputFormat='HTML'>"
+ + "<#import 'lib.ftl' as lib>"
+ + "<#assign x in lib><p>${1 + 1}</#assign>${lib.x + '&'}", "<p>2&");
+ }
+
+ @Test
+ public void testGlobal() throws IOException, TemplateException {
+ assertOutput("<#global x></#global>[${.globals.x}]", "[]");
+ assertOutput("<#global x><p>${1 + 1}</#global>${.globals.x + '&'}", "<p>2&");
+ assertOutput("<#ftl outputFormat='HTML'><#global x><p>${1 + 1}</#global>${.globals.x + '&'}", "<p>2&");
+ }
+
+ @Test
+ public void testLocal() throws IOException, TemplateException {
+ assertOutput("<#macro m><#local x></#local>[${x}]</#macro><@m/>${x!}", "[]");
+ assertOutput("<#macro m><#local x><p>${1 + 1}</#local>${x + '&'}</#macro><@m/>${x!}", "<p>2&");
+ assertOutput("<#ftl outputFormat='HTML'>"
+ + "<#macro m><#local x><p>${1 + 1}</#local>${x + '&'}</#macro><@m/>${x!}", "<p>2&");
+ }
+
+}