This is an automated email from the ASF dual-hosted git repository.

ddekany pushed a commit to branch 3
in repository https://gitbox.apache.org/repos/asf/freemarker.git


The following commit(s) were added to refs/heads/3 by this push:
     new ab2865bc Forward ported from 2.3-gae: MarkupOutputFormat.outputForeign 
PR
ab2865bc is described below

commit ab2865bc7139aa09dddf6d535c2501a7fea9668f
Author: ddekany <[email protected]>
AuthorDate: Thu Jan 5 02:39:54 2023 +0100

    Forward ported from 2.3-gae: MarkupOutputFormat.outputForeign PR
---
 .../apache/freemarker/core/OutputFormatTest.java   | 35 ++++++++++++----------
 .../freemarker/core/userpkg/DummyOutputFormat.java | 22 ++++++++++++--
 .../org/apache/freemarker/core/Environment.java    |  3 +-
 .../org/apache/freemarker/core/_EvalUtils.java     | 29 ++++++++----------
 .../core/outputformat/MarkupOutputFormat.java      | 13 +++++++-
 .../impl/CombinedMarkupOutputFormat.java           | 13 ++++++--
 6 files changed, 75 insertions(+), 40 deletions(-)

diff --git 
a/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java
 
b/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java
index 8b18c043..12338661 100644
--- 
a/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java
+++ 
b/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java
@@ -18,20 +18,9 @@
  */
 package org.apache.freemarker.core;
 
-import static org.apache.freemarker.core.AutoEscapingPolicy.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.Collections;
-
+import com.google.common.collect.ImmutableList;
 import org.apache.freemarker.core.outputformat.OutputFormat;
-import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
-import org.apache.freemarker.core.outputformat.impl.PlainTextOutputFormat;
-import org.apache.freemarker.core.outputformat.impl.RTFOutputFormat;
-import org.apache.freemarker.core.outputformat.impl.UndefinedOutputFormat;
-import org.apache.freemarker.core.outputformat.impl.XMLOutputFormat;
+import org.apache.freemarker.core.outputformat.impl.*;
 import 
org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory;
 import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher;
 import org.apache.freemarker.core.templateresolver.OrMatcher;
@@ -43,7 +32,14 @@ import org.apache.freemarker.test.TemplateTest;
 import org.junit.Before;
 import org.junit.Test;
 
-import com.google.common.collect.ImmutableList;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Collections;
+
+import static org.apache.freemarker.core.AutoEscapingPolicy.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
 
 public class OutputFormatTest extends TemplateTest {
 
@@ -706,7 +702,16 @@ public class OutputFormatTest extends TemplateTest {
                 + "${.autoEsc?c}",
                 "true\n  x\ntrue");
     }
-    
+
+    @Test
+    public void testMixedContent() throws Exception {
+        
setConfiguration(newConfigurationBuilder().outputFormat(DummyOutputFormat.INSTANCE));
+        addToDataModel("m1", HTMLOutputFormat.INSTANCE.fromMarkup("x"));
+        addToDataModel("m2", XMLOutputFormat.INSTANCE.fromMarkup("y"));
+        assertOutput("${m1}", "x");
+        assertErrorContains("${m2}", "is incompatible with");
+    }
+
     @Test
     public void testExplicitAutoEscBannedForNonMarkup() throws Exception {
         // While this restriction is technically unnecessary, we can catch a 
dangerous and probably common user
diff --git 
a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/DummyOutputFormat.java
 
b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/DummyOutputFormat.java
index edafa0e2..8628d746 100644
--- 
a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/DummyOutputFormat.java
+++ 
b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/DummyOutputFormat.java
@@ -18,11 +18,14 @@
  */
 package org.apache.freemarker.core.userpkg;
 
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core._DelayedToString;
+import org.apache.freemarker.core.model.TemplateMarkupOutputModel;
+import org.apache.freemarker.core.outputformat.CommonMarkupOutputFormat;
+
 import java.io.IOException;
 import java.io.Writer;
 
-import org.apache.freemarker.core.outputformat.CommonMarkupOutputFormat;
-
 public class DummyOutputFormat extends 
CommonMarkupOutputFormat<TemplateDummyOutputModel> {
     
     public static final DummyOutputFormat INSTANCE = new DummyOutputFormat();
@@ -46,6 +49,21 @@ public class DummyOutputFormat extends 
CommonMarkupOutputFormat<TemplateDummyOut
         out.write(escapePlainText(textToEsc));
     }
 
+    @Override
+    public boolean isOutputFormatMixingAllowed() {
+        return true;
+    }
+
+    @Override
+    public <MO extends TemplateMarkupOutputModel<MO>> void outputForeign(MO 
mo, Writer out)
+            throws IOException, TemplateException {
+        if (mo.getOutputFormat().getMimeType().equals("text/html")) {
+            mo.getOutputFormat().output(mo, out);
+        } else {
+            throw new TemplateException("DummyOutputFormat is incompatible 
with ", new _DelayedToString(mo.getOutputFormat()));
+        }
+    }
+
     @Override
     public String escapePlainText(String plainTextContent) {
         return plainTextContent.replaceAll("(\\.|\\\\)", "\\\\$1");
diff --git 
a/freemarker-core/src/main/java/org/apache/freemarker/core/Environment.java 
b/freemarker-core/src/main/java/org/apache/freemarker/core/Environment.java
index b670dd77..c6ab7154 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/Environment.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/Environment.java
@@ -1117,9 +1117,8 @@ public final class Environment extends 
MutableProcessingConfiguration<Environmen
         if (moOrStr instanceof String) {
             final String s = (String) moOrStr;
             
-            MarkupOutputFormat markupOutputFormat;
             if (outputFormat instanceof MarkupOutputFormat) {
-                markupOutputFormat = (MarkupOutputFormat) outputFormat;
+                MarkupOutputFormat markupOutputFormat = (MarkupOutputFormat) 
outputFormat;
                 if (autoEscapingPolicy == 
AutoEscapingPolicy.ENABLE_IF_SUPPORTED
                         || autoEscapingPolicy == 
AutoEscapingPolicy.ENABLE_IF_DEFAULT
                                 && 
markupOutputFormat.isAutoEscapedByDefault()) {
diff --git 
a/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtils.java 
b/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtils.java
index 1f87d8c4..2d01bf50 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtils.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtils.java
@@ -19,24 +19,9 @@
 
 package org.apache.freemarker.core;
 
-import static org.apache.freemarker.core.MessageUtils.*;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Date;
-
 import org.apache.freemarker.core.arithmetic.ArithmeticEngine;
 import org.apache.freemarker.core.arithmetic.impl.BigDecimalArithmeticEngine;
-import org.apache.freemarker.core.model.AdapterTemplateModel;
-import org.apache.freemarker.core.model.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateIterableModel;
-import org.apache.freemarker.core.model.TemplateMarkupOutputModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateNullModel;
-import org.apache.freemarker.core.model.TemplateNumberModel;
-import org.apache.freemarker.core.model.TemplateStringModel;
-import org.apache.freemarker.core.model.WrapperTemplateModel;
+import org.apache.freemarker.core.model.*;
 import org.apache.freemarker.core.outputformat.MarkupOutputFormat;
 import org.apache.freemarker.core.outputformat.OutputFormat;
 import org.apache.freemarker.core.util.BugException;
@@ -46,6 +31,12 @@ import 
org.apache.freemarker.core.valueformat.TemplateNumberFormat;
 import org.apache.freemarker.core.valueformat.TemplateValueFormat;
 import org.apache.freemarker.core.valueformat.TemplateValueFormatException;
 
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Date;
+
+import static org.apache.freemarker.core.MessageUtils.*;
+
 /**
  * Internally used static utilities for evaluation expressions.
  */
@@ -548,7 +539,9 @@ public class _EvalUtils {
             final Writer out, ASTExpression exp) throws TemplateException, 
IOException {
         final MarkupOutputFormat moOF = mo.getOutputFormat();
         // ATTENTION: Keep this logic in sync. ?esc/?noEsc's logic!
-        if (moOF != outputFormat && 
!outputFormat.isOutputFormatMixingAllowed()) {
+        if (moOF == outputFormat) {
+            moOF.output(mo, out);
+        } else if (!outputFormat.isOutputFormatMixingAllowed()) {
             final String srcPlainText;
             // ATTENTION: Keep this logic in sync. ?esc/?noEsc's logic!
             srcPlainText = moOF.getSourcePlainText(mo);
@@ -563,6 +556,8 @@ public class _EvalUtils {
             } else {
                 out.write(srcPlainText);
             }
+        } else if (outputFormat instanceof MarkupOutputFormat) {
+            ((MarkupOutputFormat<?>) outputFormat).outputForeign(mo, out);
         } else {
             moOF.output(mo, out);
         }
diff --git 
a/freemarker-core/src/main/java/org/apache/freemarker/core/outputformat/MarkupOutputFormat.java
 
b/freemarker-core/src/main/java/org/apache/freemarker/core/outputformat/MarkupOutputFormat.java
index b0eeee6e..fe695ae4 100644
--- 
a/freemarker-core/src/main/java/org/apache/freemarker/core/outputformat/MarkupOutputFormat.java
+++ 
b/freemarker-core/src/main/java/org/apache/freemarker/core/outputformat/MarkupOutputFormat.java
@@ -81,7 +81,18 @@ public abstract class MarkupOutputFormat<MO extends 
TemplateMarkupOutputModel> e
      * {@link #output(TemplateMarkupOutputModel, Writer)}, but the 
implementation may use a more efficient solution.
      */
     public abstract void output(String textToEsc, Writer out) throws 
IOException, TemplateException;
-    
+
+    /**
+     * Outputs a value from a foreign output format; only used if {@link 
#isOutputFormatMixingAllowed()} return
+     * {@code true}. The default implementation in {@link MarkupOutputFormat} 
will just let the other
+     * {@link OutputFormat} to output value, but it can be overridden to 
support more nuanced conversions, or to check if outputting without
+     * conversion should be allowed.
+     */
+    public <MO2 extends TemplateMarkupOutputModel<MO2>> void outputForeign(MO2 
mo, Writer out)
+            throws IOException, TemplateException {
+        mo.getOutputFormat().output(mo, out);
+    }
+
     /**
      * If this {@link TemplateMarkupOutputModel} was created with {@link 
#fromPlainTextByEscaping(String)}, it returns
      * the original plain text, otherwise it returns {@code null}. Useful for 
converting between different types
diff --git 
a/freemarker-core/src/main/java/org/apache/freemarker/core/outputformat/impl/CombinedMarkupOutputFormat.java
 
b/freemarker-core/src/main/java/org/apache/freemarker/core/outputformat/impl/CombinedMarkupOutputFormat.java
index 4d0f060f..e431d028 100644
--- 
a/freemarker-core/src/main/java/org/apache/freemarker/core/outputformat/impl/CombinedMarkupOutputFormat.java
+++ 
b/freemarker-core/src/main/java/org/apache/freemarker/core/outputformat/impl/CombinedMarkupOutputFormat.java
@@ -18,13 +18,14 @@
  */
 package org.apache.freemarker.core.outputformat.impl;
 
-import java.io.IOException;
-import java.io.Writer;
-
 import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core.model.TemplateMarkupOutputModel;
 import org.apache.freemarker.core.outputformat.CommonMarkupOutputFormat;
 import org.apache.freemarker.core.outputformat.MarkupOutputFormat;
 
+import java.io.IOException;
+import java.io.Writer;
+
 /**
  * Represents two markup formats nested into each other. For example, markdown 
nested into HTML.
  */
@@ -69,6 +70,12 @@ public final class CombinedMarkupOutputFormat extends 
CommonMarkupOutputFormat<T
         outer.output(inner.escapePlainText(textToEsc), out);
     }
 
+    @Override
+    public <MO2 extends TemplateMarkupOutputModel<MO2>> void outputForeign(MO2 
mo, Writer out)
+            throws IOException, TemplateException {
+        outer.outputForeign(mo, out);
+    }
+
     @Override
     public String escapePlainText(String plainTextContent) throws 
TemplateException {
         return outer.escapePlainText(inner.escapePlainText(plainTextContent));

Reply via email to