freemarker-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ddek...@apache.org
Subject [11/12] incubator-freemarker git commit: Simplified TemplateValueFormat API-s, because the small performance benefit didn't worth the extra code complexity.
Date Thu, 24 Sep 2015 20:23:58 GMT
Simplified TemplateValueFormat API-s, because the small performance benefit didn't worth the extra code complexity.


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/f32a506a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/f32a506a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/f32a506a

Branch: refs/heads/master
Commit: f32a506a32e6eb381ee9b0badd1e54b56a09b72f
Parents: b9523f6
Author: ddekany <ddekany@apache.org>
Authored: Thu Sep 24 21:18:14 2015 +0200
Committer: ddekany <ddekany@apache.org>
Committed: Thu Sep 24 22:18:50 2015 +0200

----------------------------------------------------------------------
 .../core/BuiltInsForMultipleTypes.java          |  2 +-
 .../java/freemarker/core/DollarVariable.java    |  4 +-
 src/main/java/freemarker/core/Environment.java  |  6 +--
 src/main/java/freemarker/core/EvalUtil.java     | 53 +++-----------------
 .../core/ISOLikeTemplateDateFormat.java         | 11 +---
 .../freemarker/core/JavaTemplateDateFormat.java | 11 +---
 .../core/JavaTemplateNumberFormat.java          |  8 +--
 .../freemarker/core/TemplateDateFormat.java     | 47 ++++++-----------
 .../freemarker/core/TemplateNumberFormat.java   | 47 ++++++-----------
 src/manual/book.xml                             | 40 +++++++++++----
 .../core/AppMetaTemplateDateFormatFactory.java  | 10 +---
 .../core/BaseNTemplateNumberFormatFactory.java  | 10 +---
 .../java/freemarker/core/DateFormatTest.java    | 34 ++++++-------
 ...EpochMillisDivTemplateDateFormatFactory.java | 10 +---
 .../EpochMillisTemplateDateFormatFactory.java   | 10 +---
 .../core/HexTemplateNumberFormatFactory.java    |  8 +--
 ...AndTZSensitiveTemplateDateFormatFactory.java | 10 +---
 ...aleSensitiveTemplateNumberFormatFactory.java |  8 +--
 .../java/freemarker/core/NumberFormatTest.java  |  8 +--
 .../PrintfGTemplateNumberFormatFactory.java     | 30 +++++------
 20 files changed, 120 insertions(+), 247 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java b/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
index 5a0ee73..aaaaf97 100644
--- a/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
+++ b/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
@@ -578,7 +578,7 @@ class BuiltInsForMultipleTypes {
                                 throw new BugException();
                             }
                         }
-                        cachedValue = defaultFormat.format(dateModel);
+                        cachedValue = defaultFormat.formatToString(dateModel);
                     } catch (TemplateValueFormatException e) {
                         try {
                             throw MessageUtil.newCantFormatDateException(defaultFormat, target, e, true);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/main/java/freemarker/core/DollarVariable.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/DollarVariable.java b/src/main/java/freemarker/core/DollarVariable.java
index d08f37c..4331b51 100644
--- a/src/main/java/freemarker/core/DollarVariable.java
+++ b/src/main/java/freemarker/core/DollarVariable.java
@@ -60,7 +60,7 @@ final class DollarVariable extends Interpolation {
         final TemplateModel tm = escapedExpression.eval(env);
         final Writer out = env.getOut();
         final Object moOrStr = EvalUtil.coerceModelToMarkupOutputOrString(
-                tm, escapedExpression, null, markupOutputFormat, out, env);
+                tm, escapedExpression, null, markupOutputFormat, env);
         if (moOrStr instanceof String) {
             final String s = (String) moOrStr;
             if (autoEscape) {
@@ -68,7 +68,7 @@ final class DollarVariable extends Interpolation {
             } else {
                 out.write(s);
             }
-        } else if (moOrStr != null) { // moOrStr wasn't output yet
+        } else { // moOrStr wasn't output yet
             final TemplateMarkupOutputModel mo = (TemplateMarkupOutputModel) moOrStr;
             final MarkupOutputFormat moOF = mo.getOutputFormat();
             // ATTENTION: Keep this logic in sync. ?esc/?noEsc's logic!

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/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 5078eb7..a1073c2 100644
--- a/src/main/java/freemarker/core/Environment.java
+++ b/src/main/java/freemarker/core/Environment.java
@@ -1049,7 +1049,7 @@ public final class Environment extends Configurable {
             boolean useTempModelExc)
             throws TemplateException {
         try {
-            return format.format(number);
+            return format.formatToString(number);
         } catch (TemplateValueFormatException e) {
             throw MessageUtil.newCantFormatNumberException(format, exp, e, useTempModelExc);
         }
@@ -1324,7 +1324,7 @@ public final class Environment extends Configurable {
         TemplateDateFormat format = getTemplateDateFormat(tdm, tdmSourceExpr, useTempModelExc);
         
         try {
-            return format.format(tdm);
+            return format.formatToString(tdm);
         } catch (TemplateValueFormatException e) {
             throw MessageUtil.newCantFormatDateException(format, tdmSourceExpr, e, useTempModelExc);
         }
@@ -1347,7 +1347,7 @@ public final class Environment extends Configurable {
                 useTempModelExc);
         
         try {
-            return format.format(tdm);
+            return format.formatToString(tdm);
         } catch (TemplateValueFormatException e) {
             throw MessageUtil.newCantFormatDateException(format, blamedDateSourceExp, e, useTempModelExc);
         }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/main/java/freemarker/core/EvalUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/EvalUtil.java b/src/main/java/freemarker/core/EvalUtil.java
index 517a29e..c20dcff 100644
--- a/src/main/java/freemarker/core/EvalUtil.java
+++ b/src/main/java/freemarker/core/EvalUtil.java
@@ -19,8 +19,6 @@
 
 package freemarker.core;
 
-import java.io.IOException;
-import java.io.Writer;
 import java.util.Date;
 
 import freemarker.ext.beans.BeanModel;
@@ -356,37 +354,13 @@ class EvalUtil {
 
     static Object coerceModelToMarkupOutputOrString(TemplateModel tm, Expression exp, String seqHint,
             MarkupOutputFormat markupOutputFormat, Environment env) throws TemplateException {
-        try {
-            return coerceModelToMarkupOutputOrString(tm, exp, seqHint, markupOutputFormat, null, env);
-        } catch (IOException e) {
-            throw new BugException("Unexpected exception", e);
-        }
-    }
-
-    static Object coerceModelToMarkupOutputOrString(TemplateModel tm, Expression exp, String seqHint,
-            MarkupOutputFormat markupOutputFormat, Writer out, Environment env) throws TemplateException, IOException {
         if (tm instanceof TemplateNumberModel) {
             TemplateNumberModel tnm = (TemplateNumberModel) tm; 
             TemplateNumberFormat format = env.getTemplateNumberFormat(exp, false);
             try {
-                if (markupOutputFormat != null) {
-                    // Try to return markup output:
-                    if (out == null) {
-                        TemplateMarkupOutputModel r = format.format(tnm, markupOutputFormat);
-                        if (r != null) {
-                            return r;
-                        }
-                        // Falls through
-                    } else {
-                        if (format.format(tnm, markupOutputFormat, out)) {
-                            return null;
-                        }
-                        // Falls through
-                    }
-                }
-                
-                // Return a String:
-                return format.format(tnm);
+                return markupOutputFormat != null 
+                        ? format.formatToMarkupOrString(tnm, markupOutputFormat)
+                        : format.formatToString(tnm);
             } catch (TemplateValueFormatException e) {
                 throw MessageUtil.newCantFormatNumberException(format, exp, e, false);
             }
@@ -394,24 +368,9 @@ class EvalUtil {
             TemplateDateModel tdm = (TemplateDateModel) tm;
             TemplateDateFormat format = env.getTemplateDateFormat(tdm, exp, false);
             try {
-                if (markupOutputFormat != null) {
-                    // Try to return markup output:
-                    if (out == null) {
-                        TemplateMarkupOutputModel r = format.format(tdm, markupOutputFormat);
-                        if (r != null) {
-                            return r;
-                        }
-                        // Falls through
-                    } else {
-                        if (format.format(tdm, markupOutputFormat, out)) {
-                            return null;
-                        }
-                        // Falls through
-                    }
-                }
-                
-                // Return a String:
-                return format.format(tdm);
+                return markupOutputFormat != null
+                        ? format.formatToMarkupOrString(tdm, markupOutputFormat)
+                        : format.formatToString(tdm);
             } catch (TemplateValueFormatException e) {
                 throw MessageUtil.newCantFormatDateException(format, exp, e, false);
             }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/main/java/freemarker/core/ISOLikeTemplateDateFormat.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/ISOLikeTemplateDateFormat.java b/src/main/java/freemarker/core/ISOLikeTemplateDateFormat.java
index 9c96a08..b379413 100644
--- a/src/main/java/freemarker/core/ISOLikeTemplateDateFormat.java
+++ b/src/main/java/freemarker/core/ISOLikeTemplateDateFormat.java
@@ -177,7 +177,7 @@ abstract class ISOLikeTemplateDateFormat  extends TemplateDateFormat {
     }
     
     @Override
-    public final String format(TemplateDateModel dateModel) throws TemplateModelException {
+    public final String formatToString(TemplateDateModel dateModel) throws TemplateModelException {
         final Date date = TemplateFormatUtil.getNonNullDate(dateModel);
         return format(
                 date,
@@ -257,15 +257,6 @@ abstract class ISOLikeTemplateDateFormat  extends TemplateDateFormat {
         return true;
     }
 
-    /**
-     * Always returns {@code null} (there's no markup format).
-     */
-    @Override
-    public <MO extends TemplateMarkupOutputModel> MO format(TemplateDateModel dateModel,
-            MarkupOutputFormat<MO> outputFormat) throws TemplateValueFormatException, TemplateModelException {
-        return null;
-    }
-
     protected abstract boolean isXSMode();
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/main/java/freemarker/core/JavaTemplateDateFormat.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/JavaTemplateDateFormat.java b/src/main/java/freemarker/core/JavaTemplateDateFormat.java
index 996afcf..02a1460 100644
--- a/src/main/java/freemarker/core/JavaTemplateDateFormat.java
+++ b/src/main/java/freemarker/core/JavaTemplateDateFormat.java
@@ -39,7 +39,7 @@ class JavaTemplateDateFormat extends TemplateDateFormat {
     }
     
     @Override
-    public String format(TemplateDateModel dateModel) throws TemplateModelException {
+    public String formatToString(TemplateDateModel dateModel) throws TemplateModelException {
         return javaDateFormat.format(TemplateFormatUtil.getNonNullDate(dateModel));
     }
 
@@ -69,13 +69,4 @@ class JavaTemplateDateFormat extends TemplateDateFormat {
         return true;
     }
     
-    /**
-     * Always returns {@code null} (there's no markup format).
-     */
-    @Override
-    public <MO extends TemplateMarkupOutputModel> MO format(TemplateDateModel dateModel,
-            MarkupOutputFormat<MO> outputFormat) throws UnformattableValueException, TemplateModelException {
-        return null;
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/main/java/freemarker/core/JavaTemplateNumberFormat.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/JavaTemplateNumberFormat.java b/src/main/java/freemarker/core/JavaTemplateNumberFormat.java
index ccbfb9d..f862c2b 100644
--- a/src/main/java/freemarker/core/JavaTemplateNumberFormat.java
+++ b/src/main/java/freemarker/core/JavaTemplateNumberFormat.java
@@ -34,18 +34,12 @@ final class JavaTemplateNumberFormat extends BackwardCompatibleTemplateNumberFor
     }
 
     @Override
-    public String format(TemplateNumberModel numberModel) throws UnformattableValueException, TemplateModelException {
+    public String formatToString(TemplateNumberModel numberModel) throws UnformattableValueException, TemplateModelException {
         Number number = TemplateFormatUtil.getNonNullNumber(numberModel);
         return format(number);
     }
 
     @Override
-    public <MO extends TemplateMarkupOutputModel> MO format(TemplateNumberModel numberModel,
-            MarkupOutputFormat<MO> outputFormat) throws UnformattableValueException, TemplateModelException {
-        return null;
-    }
-
-    @Override
     public boolean isLocaleBound() {
         return true;
     }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/main/java/freemarker/core/TemplateDateFormat.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/TemplateDateFormat.java b/src/main/java/freemarker/core/TemplateDateFormat.java
index cb58aac..6a6d66b 100644
--- a/src/main/java/freemarker/core/TemplateDateFormat.java
+++ b/src/main/java/freemarker/core/TemplateDateFormat.java
@@ -19,8 +19,6 @@
 
 package freemarker.core;
 
-import java.io.IOException;
-import java.io.Writer;
 import java.text.DateFormat;
 import java.util.Date;
 
@@ -55,39 +53,26 @@ public abstract class TemplateDateFormat extends TemplateValueFormat {
      * @throws TemplateModelException
      *             Exception thrown by the {@code dateModel} object when calling its methods.
      */
-    public abstract String format(TemplateDateModel dateModel)
+    public abstract String formatToString(TemplateDateModel dateModel)
             throws TemplateValueFormatException, TemplateModelException;
 
     /**
-     * <b>[Not yet used, might changes in 2.3.24 final]</b>
-     * Formats the date/time/dateTime to markup instead of to plain text, or returns {@code null} that will make
-     * FreeMarker call {@link #format(TemplateDateModel)} and escape its result. If the markup format would be just the
-     * result of {@link #format(TemplateDateModel)} escaped, it should return {@code null}.
-     */
-    public abstract <MO extends TemplateMarkupOutputModel> MO format(
-            TemplateDateModel dateModel, MarkupOutputFormat<MO> outputFormat)
-                    throws TemplateValueFormatException, TemplateModelException;
-
-    /**
-     * <b>[Not yet used, might changes in 2.3.24 final]</b>
-     * Same as {@link #format(TemplateDateModel, MarkupOutputFormat)}, but prints the result to a {@link Writer}
-     * instead of returning it. This can be utilized for some optimizatoin. In the case where
-     * {@link #format(TemplateDateModel, MarkupOutputFormat)} would return {@code null}, it returns {@code false}. It
-     * writes to the {@link Writer} exactly if the return value is {@code true}.
+     * Formats the model to markup instead of to plain text if the result markup will be more than just plain text
+     * escaped, otherwise falls back to formatting to plain text. If the markup result would be just the result of
+     * {@link #formatToString(TemplateDateModel)} escaped, it must return the {@link String} that
+     * {@link #formatToString(TemplateDateModel)} does.
+     * 
+     * @param outputFormat
+     *            When the result is a {@link TemplateMarkupOutputModel} result, it must be exactly of this output
+     *            format.
      * 
-     * <p>
-     * The default implementation in {@link TemplateNumberFormat} builds on calls
-     * {@link #format(TemplateDateModel, MarkupOutputFormat)} and writes its result to the {@link Writer}.
+     * @return A {@link String} or a {@link TemplateMarkupOutputModel}; not {@code null}. If it's a
+     *         {@link TemplateMarkupOutputModel}, then it must have the output format specified in the
+     *         {@code outputFormat} parameter.
      */
-    public <MO extends TemplateMarkupOutputModel> boolean format(TemplateDateModel dateModel,
-            MarkupOutputFormat<MO> outputFormat, Writer out)
-                    throws TemplateValueFormatException, TemplateModelException, IOException {
-        MO mo = format(dateModel, outputFormat);
-        if (mo == null) {
-            return false;
-        }
-        mo.getOutputFormat().output(mo, out);
-        return true;
+    public Object formatToMarkupOrString(TemplateDateModel dateModel, MarkupOutputFormat<?> outputFormat)
+            throws TemplateValueFormatException, TemplateModelException {
+        return formatToString(dateModel);
     }
 
     /**
@@ -107,7 +92,7 @@ public abstract class TemplateDateFormat extends TemplateValueFormat {
      * 
      * @return The interpretation of the text either as a {@link Date} or {@link TemplateDateModel}. Typically, a
      *         {@link Date}. {@link TemplateDateModel} is used if you have to attach some application-specific
-     *         meta-information thats also extracted during {@link #format(TemplateDateModel)} (so if you format
+     *         meta-information thats also extracted during {@link #formatToString(TemplateDateModel)} (so if you format
      *         something and then parse it, you get back an equivalent result). It can't be {@code null}. Known issue
      *         (at least in FTL 2): {@code ?date}/{@code ?time}/{@code ?datetime}, when not invoked as a method, can't
      *         return the {@link TemplateDateModel}, only the {@link Date} from inside it, hence the additional

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/main/java/freemarker/core/TemplateNumberFormat.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/TemplateNumberFormat.java b/src/main/java/freemarker/core/TemplateNumberFormat.java
index 3c29738..eb75ea7 100644
--- a/src/main/java/freemarker/core/TemplateNumberFormat.java
+++ b/src/main/java/freemarker/core/TemplateNumberFormat.java
@@ -18,8 +18,6 @@
  */
 package freemarker.core;
 
-import java.io.IOException;
-import java.io.Writer;
 import java.text.NumberFormat;
 
 import freemarker.template.TemplateDateModel;
@@ -54,41 +52,28 @@ public abstract class TemplateNumberFormat extends TemplateValueFormat {
      * @throws TemplateModelException
      *             Exception thrown by the {@code dateModel} object when calling its methods.
      */
-    public abstract String format(TemplateNumberModel numberModel)
+    public abstract String formatToString(TemplateNumberModel numberModel)
             throws TemplateValueFormatException, TemplateModelException;
 
     /**
-     * <b>[Not yet used, might changes in 2.3.24 final]</b>
-     * Formats the number to markup instead of to plain text, or returns {@code null} that will make FreeMarker call
-     * {@link #format(TemplateNumberModel)} and escape its result. If the markup format would be just the result of
-     * {@link #format(TemplateNumberModel)} escaped, it should return {@code null}.
-     */
-    public abstract <MO extends TemplateMarkupOutputModel> MO format(
-            TemplateNumberModel numberModel, MarkupOutputFormat<MO> outputFormat)
-                    throws TemplateValueFormatException, TemplateModelException;
-    
-    /**
-     * <b>[Not yet used, might changes in 2.3.24 final]</b>
-     * Same as {@link #format(TemplateNumberModel, MarkupOutputFormat)}, but prints the result to a {@link Writer}
-     * instead of returning it. This can be utilized for some optimizatoin. In the case where
-     * {@link #format(TemplateNumberModel, MarkupOutputFormat)} would return {@code null}, it returns {@code false}. It
-     * writes to the {@link Writer} exactly if the return value is {@code true}.
+     * Formats the model to markup instead of to plain text if the result markup will be more than just plain text
+     * escaped, otherwise falls back to formatting to plain text. If the markup result would be just the result of
+     * {@link #formatToString(TemplateNumberModel)} escaped, it must return the {@link String} that
+     * {@link #formatToString(TemplateNumberModel)} does.
      * 
-     * <p>
-     * The default implementation in {@link TemplateNumberFormat} builds on calls
-     * {@link #format(TemplateNumberModel, MarkupOutputFormat)} and writes its result to the {@link Writer}.
+     * @param outputFormat
+     *            When the result is a {@link TemplateMarkupOutputModel} result, it must be exactly of this output
+     *            format. Not {@code null}.
+     * 
+     * @return A {@link String} or a {@link TemplateMarkupOutputModel}; not {@code null}. If it's a
+     *         {@link TemplateMarkupOutputModel}, then it must have the output format specified in the
+     *         {@code outputFormat} parameter.
      */
-    public <MO extends TemplateMarkupOutputModel> boolean format(
-            TemplateNumberModel numberModel, MarkupOutputFormat<MO> outputFormat, Writer out)
-                    throws TemplateValueFormatException, TemplateModelException, IOException {
-        MO mo = format(numberModel, outputFormat);
-        if (mo == null) {
-            return false;
-        }
-        mo.getOutputFormat().output(mo, out);
-        return true;
+    public Object formatToMarkupOrString(TemplateNumberModel numberModel, MarkupOutputFormat<?> outputFormat)
+            throws TemplateValueFormatException, TemplateModelException {
+        return formatToString(numberModel);
     }
-
+    
     /**
      * Tells if this formatter should be re-created if the locale changes.
      */

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/manual/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/book.xml b/src/manual/book.xml
index 10db216..cf1efb6 100644
--- a/src/manual/book.xml
+++ b/src/manual/book.xml
@@ -25988,6 +25988,21 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
                 </listitem>
 
                 <listitem>
+                  <para>It's now possible to have HTML or other markup in
+                  number and date/time/datetime formatting results, like
+                  <literal>1.23*10&lt;sup&gt;6&lt;/sup&gt;</literal>, which
+                  won't be accidentally auto-escaped, as FreeMarker knows that
+                  it's already HTML. (See [TODO] as an example.) Note that
+                  formatting to markup only happens in a context that has a
+                  markup <link
+                  linkend="dgui_misc_autoescaping_outputformat">output
+                  format</link>, otherwise FreeMarker will format to plain
+                  text, just as before. Also note that no out-of-the-box
+                  (non-custom) formatter formats to markup at the
+                  moment.</para>
+                </listitem>
+
+                <listitem>
                   <para>The internal format object caching architecture has
                   been reworked, so that it can handle custom formats too. But
                   this reworking also fixes some bottlenecks under highly
@@ -26223,18 +26238,21 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
             </listitem>
 
             <listitem>
-              <para><literal>TemplateNumberFormat.format</literal> and
-              <literal>TemplateDateFormat.format</literal> overload that
-              returns markup output is now actually called, so for example now
-              it's possible to use HTML in formatting results. (See
-              <literal>freemarker.core.PrintfGTemplateNumberFormatFactory</literal>
-              under <literal>src/test/java</literal> as an example.) Note that
-              formatting to markup only happens if FTL thinks that the
-              expected result is not just a string, such as for
-              <literal>${<replaceable>myNumber</replaceable>}</literal> if
-              that file has markup <link
+              <para><literal>TemplateNumberFormat.format</literal>/<literal>TemplateDateFormat.format</literal>
+              overloads were renamed to <literal>formatToString</literal> and
+              <literal>formatToMarkupOrString</literal>. The last has
+              different semantics then its predecessor (which was marked as
+              draft), and it's actually used by FreeMarker. Thus, it's now
+              possible to have HTML or other markup in number and
+              date/time/datetime formatting results, like
+              <literal>1.23*10&lt;sup&gt;6&lt;/sup&gt;</literal>, which won't
+              be accidentally auto-escaped, as FreeMarker knows that it's
+              already HTML. (See [TODO] as an example.) Note that formatting
+              to markup only happens in a context that has a markup <link
               linkend="dgui_misc_autoescaping_outputformat">output
-              format</link>.</para>
+              format</link>, otherwise FreeMarker will format to plain text,
+              just like before. Also note that no out-of-the-box (non-custom)
+              formatter formats to markup at the moment.</para>
             </listitem>
 
             <listitem>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/test/java/freemarker/core/AppMetaTemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/AppMetaTemplateDateFormatFactory.java b/src/test/java/freemarker/core/AppMetaTemplateDateFormatFactory.java
index 70a293f..e66e6f4 100644
--- a/src/test/java/freemarker/core/AppMetaTemplateDateFormatFactory.java
+++ b/src/test/java/freemarker/core/AppMetaTemplateDateFormatFactory.java
@@ -22,8 +22,6 @@ import java.util.Date;
 import java.util.Locale;
 import java.util.TimeZone;
 
-import org.apache.commons.lang.NotImplementedException;
-
 import freemarker.template.TemplateDateModel;
 import freemarker.template.TemplateModelException;
 
@@ -49,7 +47,7 @@ public class AppMetaTemplateDateFormatFactory extends TemplateDateFormatFactory
         private AppMetaTemplateDateFormat() { }
         
         @Override
-        public String format(TemplateDateModel dateModel)
+        public String formatToString(TemplateDateModel dateModel)
                 throws UnformattableValueException, TemplateModelException {
             String result = String.valueOf(TemplateFormatUtil.getNonNullDate(dateModel).getTime());
             if (dateModel instanceof AppMetaTemplateDateModel) {
@@ -69,12 +67,6 @@ public class AppMetaTemplateDateFormatFactory extends TemplateDateFormatFactory
         }
 
         @Override
-        public <MO extends TemplateMarkupOutputModel> MO format(TemplateDateModel dateModel,
-                MarkupOutputFormat<MO> outputFormat) throws UnformattableValueException, TemplateModelException {
-            throw new NotImplementedException();
-        }
-
-        @Override
         public Object parse(String s, int dateType) throws UnparsableValueException {
             int slashIdx = s.indexOf('/');
             try {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/test/java/freemarker/core/BaseNTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/BaseNTemplateNumberFormatFactory.java b/src/test/java/freemarker/core/BaseNTemplateNumberFormatFactory.java
index 18a06ea..f66559a 100644
--- a/src/test/java/freemarker/core/BaseNTemplateNumberFormatFactory.java
+++ b/src/test/java/freemarker/core/BaseNTemplateNumberFormatFactory.java
@@ -80,7 +80,7 @@ public class BaseNTemplateNumberFormatFactory extends TemplateNumberFormatFactor
         }
         
         @Override
-        public String format(TemplateNumberModel numberModel)
+        public String formatToString(TemplateNumberModel numberModel)
                 throws TemplateModelException, TemplateValueFormatException {
             Number n = TemplateFormatUtil.getNonNullNumber(numberModel);
             try {
@@ -90,18 +90,12 @@ public class BaseNTemplateNumberFormatFactory extends TemplateNumberFormatFactor
                     throw new UnformattableValueException(
                             n + " doesn't fit into an int, and there was no fallback format specified.");
                 } else {
-                    return fallbackFormat.format(numberModel);
+                    return fallbackFormat.formatToString(numberModel);
                 }
             }
         }
 
         @Override
-        public <MO extends TemplateMarkupOutputModel> MO format(TemplateNumberModel numberModel,
-                MarkupOutputFormat<MO> outputFormat) throws UnformattableValueException, TemplateModelException {
-            return null;
-        }
-
-        @Override
         public boolean isLocaleBound() {
             return false;
         }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/test/java/freemarker/core/DateFormatTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/DateFormatTest.java b/src/test/java/freemarker/core/DateFormatTest.java
index c21b83a..490ba5b 100644
--- a/src/test/java/freemarker/core/DateFormatTest.java
+++ b/src/test/java/freemarker/core/DateFormatTest.java
@@ -266,57 +266,57 @@ public class DateFormatTest extends TemplateTest {
         String dateTimeFormatStr2 = dateTimeFormatStr + "'!'";
         
         assertEquals("2015.09.06. 13:00",
-                env.getTemplateDateFormat(TemplateDateModel.DATETIME, Date.class).format(TM));
+                env.getTemplateDateFormat(TemplateDateModel.DATETIME, Date.class).formatToString(TM));
         assertEquals("2015.09.06. 13:00!",
-                env.getTemplateDateFormat(dateTimeFormatStr2, TemplateDateModel.DATETIME, Date.class).format(TM));
+                env.getTemplateDateFormat(dateTimeFormatStr2, TemplateDateModel.DATETIME, Date.class).formatToString(TM));
         
         assertEquals("2015.09.06. (+0100)",
-                env.getTemplateDateFormat(TemplateDateModel.DATE, Date.class).format(TM));
+                env.getTemplateDateFormat(TemplateDateModel.DATE, Date.class).formatToString(TM));
         assertEquals("2015.09.06. (+0100)!",
-                env.getTemplateDateFormat(dateFormatStr2, TemplateDateModel.DATE, Date.class).format(TM));
+                env.getTemplateDateFormat(dateFormatStr2, TemplateDateModel.DATE, Date.class).formatToString(TM));
         
         assertEquals("13:00",
-                env.getTemplateDateFormat(TemplateDateModel.TIME, Date.class).format(TM));
+                env.getTemplateDateFormat(TemplateDateModel.TIME, Date.class).formatToString(TM));
         assertEquals("13:00!",
-                env.getTemplateDateFormat(timeFormatStr2, TemplateDateModel.TIME, Date.class).format(TM));
+                env.getTemplateDateFormat(timeFormatStr2, TemplateDateModel.TIME, Date.class).formatToString(TM));
         
         assertEquals("2015.09.06. 13:00",
-                env.getTemplateDateFormat(TemplateDateModel.DATETIME, Timestamp.class).format(TM));
+                env.getTemplateDateFormat(TemplateDateModel.DATETIME, Timestamp.class).formatToString(TM));
         assertEquals("2015.09.06. 13:00!",
-                env.getTemplateDateFormat(dateTimeFormatStr2, TemplateDateModel.DATETIME, Timestamp.class).format(TM));
+                env.getTemplateDateFormat(dateTimeFormatStr2, TemplateDateModel.DATETIME, Timestamp.class).formatToString(TM));
 
         assertEquals("2015.09.06. (+0000)",
-                env.getTemplateDateFormat(TemplateDateModel.DATE, java.sql.Date.class).format(TM));
+                env.getTemplateDateFormat(TemplateDateModel.DATE, java.sql.Date.class).formatToString(TM));
         assertEquals("2015.09.06. (+0000)!",
-                env.getTemplateDateFormat(dateFormatStr2, TemplateDateModel.DATE, java.sql.Date.class).format(TM));
+                env.getTemplateDateFormat(dateFormatStr2, TemplateDateModel.DATE, java.sql.Date.class).formatToString(TM));
 
         assertEquals("12:00",
-                env.getTemplateDateFormat(TemplateDateModel.TIME, Time.class).format(TM));
+                env.getTemplateDateFormat(TemplateDateModel.TIME, Time.class).formatToString(TM));
         assertEquals("12:00!",
-                env.getTemplateDateFormat(timeFormatStr2, TemplateDateModel.TIME, Time.class).format(TM));
+                env.getTemplateDateFormat(timeFormatStr2, TemplateDateModel.TIME, Time.class).formatToString(TM));
 
         {
             String dateTimeFormatStrLoc = dateTimeFormatStr + " EEEE";
             // Gets into cache:
             TemplateDateFormat format1
                     = env.getTemplateDateFormat(dateTimeFormatStrLoc, TemplateDateModel.DATETIME, Date.class);
-            assertEquals("2015.09.06. 13:00 Sunday", format1.format(TM));
+            assertEquals("2015.09.06. 13:00 Sunday", format1.formatToString(TM));
             // Different locale (not cached):
             assertEquals("2015.09.06. 13:00 Sonntag",
                     env.getTemplateDateFormat(dateTimeFormatStrLoc, TemplateDateModel.DATETIME, Date.class,
-                            Locale.GERMANY).format(TM));
+                            Locale.GERMANY).formatToString(TM));
             // Different locale and zone (not cached):
             assertEquals("2015.09.06. 14:00 Sonntag",
                     env.getTemplateDateFormat(dateTimeFormatStrLoc, TemplateDateModel.DATETIME, Date.class,
-                            Locale.GERMANY, TimeZone.getTimeZone("GMT+02"), TimeZone.getTimeZone("GMT+03")).format(TM));
+                            Locale.GERMANY, TimeZone.getTimeZone("GMT+02"), TimeZone.getTimeZone("GMT+03")).formatToString(TM));
             // Different locale and zone (not cached):
             assertEquals("2015.09.06. 15:00 Sonntag",
                     env.getTemplateDateFormat(dateTimeFormatStrLoc, TemplateDateModel.DATETIME, java.sql.Date.class,
-                            Locale.GERMANY, TimeZone.getTimeZone("GMT+02"), TimeZone.getTimeZone("GMT+03")).format(TM));
+                            Locale.GERMANY, TimeZone.getTimeZone("GMT+02"), TimeZone.getTimeZone("GMT+03")).formatToString(TM));
             // Check for corrupted cache:
             TemplateDateFormat format2
                     = env.getTemplateDateFormat(dateTimeFormatStrLoc, TemplateDateModel.DATETIME, Date.class);
-            assertEquals("2015.09.06. 13:00 Sunday", format2.format(TM));
+            assertEquals("2015.09.06. 13:00 Sunday", format2.formatToString(TM));
             assertSame(format1, format2);
         }
         

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/test/java/freemarker/core/EpochMillisDivTemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/EpochMillisDivTemplateDateFormatFactory.java b/src/test/java/freemarker/core/EpochMillisDivTemplateDateFormatFactory.java
index 55fa980..1a7bf3d 100644
--- a/src/test/java/freemarker/core/EpochMillisDivTemplateDateFormatFactory.java
+++ b/src/test/java/freemarker/core/EpochMillisDivTemplateDateFormatFactory.java
@@ -22,8 +22,6 @@ import java.util.Date;
 import java.util.Locale;
 import java.util.TimeZone;
 
-import org.apache.commons.lang.NotImplementedException;
-
 import freemarker.template.TemplateDateModel;
 import freemarker.template.TemplateModelException;
 import freemarker.template.utility.StringUtil;
@@ -62,7 +60,7 @@ public class EpochMillisDivTemplateDateFormatFactory extends TemplateDateFormatF
         }
         
         @Override
-        public String format(TemplateDateModel dateModel)
+        public String formatToString(TemplateDateModel dateModel)
                 throws UnformattableValueException, TemplateModelException {
             return String.valueOf(TemplateFormatUtil.getNonNullDate(dateModel).getTime() / divisor);
         }
@@ -78,12 +76,6 @@ public class EpochMillisDivTemplateDateFormatFactory extends TemplateDateFormatF
         }
 
         @Override
-        public <MO extends TemplateMarkupOutputModel> MO format(TemplateDateModel dateModel,
-                MarkupOutputFormat<MO> outputFormat) throws UnformattableValueException, TemplateModelException {
-            throw new NotImplementedException();
-        }
-
-        @Override
         public Date parse(String s, int dateType) throws UnparsableValueException {
             try {
                 return new Date(Long.parseLong(s));

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/test/java/freemarker/core/EpochMillisTemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/EpochMillisTemplateDateFormatFactory.java b/src/test/java/freemarker/core/EpochMillisTemplateDateFormatFactory.java
index 63e1287..216f8c0 100644
--- a/src/test/java/freemarker/core/EpochMillisTemplateDateFormatFactory.java
+++ b/src/test/java/freemarker/core/EpochMillisTemplateDateFormatFactory.java
@@ -22,8 +22,6 @@ import java.util.Date;
 import java.util.Locale;
 import java.util.TimeZone;
 
-import org.apache.commons.lang.NotImplementedException;
-
 import freemarker.template.TemplateDateModel;
 import freemarker.template.TemplateModelException;
 
@@ -49,7 +47,7 @@ public class EpochMillisTemplateDateFormatFactory extends TemplateDateFormatFact
         private EpochMillisTemplateDateFormat() { }
         
         @Override
-        public String format(TemplateDateModel dateModel)
+        public String formatToString(TemplateDateModel dateModel)
                 throws UnformattableValueException, TemplateModelException {
             return String.valueOf(TemplateFormatUtil.getNonNullDate(dateModel).getTime());
         }
@@ -65,12 +63,6 @@ public class EpochMillisTemplateDateFormatFactory extends TemplateDateFormatFact
         }
 
         @Override
-        public <MO extends TemplateMarkupOutputModel> MO format(TemplateDateModel dateModel,
-                MarkupOutputFormat<MO> outputFormat) throws UnformattableValueException, TemplateModelException {
-            throw new NotImplementedException();
-        }
-
-        @Override
         public Date parse(String s, int dateType) throws UnparsableValueException {
             try {
                 return new Date(Long.parseLong(s));

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/test/java/freemarker/core/HexTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/HexTemplateNumberFormatFactory.java b/src/test/java/freemarker/core/HexTemplateNumberFormatFactory.java
index 8687b58..4b5bf0b 100644
--- a/src/test/java/freemarker/core/HexTemplateNumberFormatFactory.java
+++ b/src/test/java/freemarker/core/HexTemplateNumberFormatFactory.java
@@ -46,7 +46,7 @@ public class HexTemplateNumberFormatFactory extends TemplateNumberFormatFactory
         private HexTemplateNumberFormat() { }
         
         @Override
-        public String format(TemplateNumberModel numberModel)
+        public String formatToString(TemplateNumberModel numberModel)
                 throws UnformattableValueException, TemplateModelException {
             Number n = TemplateFormatUtil.getNonNullNumber(numberModel);
             try {
@@ -57,12 +57,6 @@ public class HexTemplateNumberFormatFactory extends TemplateNumberFormatFactory
         }
 
         @Override
-        public <MO extends TemplateMarkupOutputModel> MO format(TemplateNumberModel numberModel,
-                MarkupOutputFormat<MO> outputFormat) throws UnformattableValueException, TemplateModelException {
-            return null;
-        }
-
-        @Override
         public boolean isLocaleBound() {
             return false;
         }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/test/java/freemarker/core/LocAndTZSensitiveTemplateDateFormatFactory.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/LocAndTZSensitiveTemplateDateFormatFactory.java b/src/test/java/freemarker/core/LocAndTZSensitiveTemplateDateFormatFactory.java
index 94edd6e..b307f2a 100644
--- a/src/test/java/freemarker/core/LocAndTZSensitiveTemplateDateFormatFactory.java
+++ b/src/test/java/freemarker/core/LocAndTZSensitiveTemplateDateFormatFactory.java
@@ -22,8 +22,6 @@ import java.util.Date;
 import java.util.Locale;
 import java.util.TimeZone;
 
-import org.apache.commons.lang.NotImplementedException;
-
 import freemarker.template.TemplateDateModel;
 import freemarker.template.TemplateModelException;
 
@@ -53,7 +51,7 @@ public class LocAndTZSensitiveTemplateDateFormatFactory extends TemplateDateForm
         }
 
         @Override
-        public String format(TemplateDateModel dateModel)
+        public String formatToString(TemplateDateModel dateModel)
                 throws UnformattableValueException, TemplateModelException {
             return String.valueOf(TemplateFormatUtil.getNonNullDate(dateModel).getTime() + "@" + locale + ":" + timeZone.getID());
         }
@@ -69,12 +67,6 @@ public class LocAndTZSensitiveTemplateDateFormatFactory extends TemplateDateForm
         }
 
         @Override
-        public <MO extends TemplateMarkupOutputModel> MO format(TemplateDateModel dateModel,
-                MarkupOutputFormat<MO> outputFormat) throws UnformattableValueException, TemplateModelException {
-            throw new NotImplementedException();
-        }
-
-        @Override
         public Date parse(String s, int dateType) throws UnparsableValueException {
             try {
                 int atIdx = s.indexOf("@");

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/test/java/freemarker/core/LocaleSensitiveTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/LocaleSensitiveTemplateNumberFormatFactory.java b/src/test/java/freemarker/core/LocaleSensitiveTemplateNumberFormatFactory.java
index fb989b9..0b2baef 100644
--- a/src/test/java/freemarker/core/LocaleSensitiveTemplateNumberFormatFactory.java
+++ b/src/test/java/freemarker/core/LocaleSensitiveTemplateNumberFormatFactory.java
@@ -47,7 +47,7 @@ public class LocaleSensitiveTemplateNumberFormatFactory extends TemplateNumberFo
         }
         
         @Override
-        public String format(TemplateNumberModel numberModel)
+        public String formatToString(TemplateNumberModel numberModel)
                 throws UnformattableValueException, TemplateModelException {
             Number n = numberModel.getAsNumber();
             try {
@@ -58,12 +58,6 @@ public class LocaleSensitiveTemplateNumberFormatFactory extends TemplateNumberFo
         }
     
         @Override
-        public <MO extends TemplateMarkupOutputModel> MO format(TemplateNumberModel numberModel,
-                MarkupOutputFormat<MO> outputFormat) throws UnformattableValueException, TemplateModelException {
-            return null;
-        }
-    
-        @Override
         public boolean isLocaleBound() {
             return true;
         }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/test/java/freemarker/core/NumberFormatTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/NumberFormatTest.java b/src/test/java/freemarker/core/NumberFormatTest.java
index 46f4d07..2c2fd40 100644
--- a/src/test/java/freemarker/core/NumberFormatTest.java
+++ b/src/test/java/freemarker/core/NumberFormatTest.java
@@ -151,17 +151,17 @@ public class NumberFormatTest extends TemplateTest {
         TemplateNumberFormat defF = env.getTemplateNumberFormat();
         //
         TemplateNumberFormat explF = env.getTemplateNumberFormat("0.00");
-        assertEquals("1.25", explF.format(new SimpleNumber(1.25)));
+        assertEquals("1.25", explF.formatToString(new SimpleNumber(1.25)));
         //
         TemplateNumberFormat expl2F = env.getTemplateNumberFormat("@loc");
-        assertEquals("1.25_en_US", expl2F.format(new SimpleNumber(1.25)));
+        assertEquals("1.25_en_US", expl2F.formatToString(new SimpleNumber(1.25)));
         
         TemplateNumberFormat explFFr = env.getTemplateNumberFormat("0.00", Locale.FRANCE);
         assertNotSame(explF, explFFr);
-        assertEquals("1,25", explFFr.format(new SimpleNumber(1.25)));
+        assertEquals("1,25", explFFr.formatToString(new SimpleNumber(1.25)));
         //
         TemplateNumberFormat expl2FFr = env.getTemplateNumberFormat("@loc", Locale.FRANCE);
-        assertEquals("1.25_fr_FR", expl2FFr.format(new SimpleNumber(1.25)));
+        assertEquals("1.25_fr_FR", expl2FFr.formatToString(new SimpleNumber(1.25)));
         
         assertSame(env.getTemplateNumberFormat(), defF);
         //

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f32a506a/src/test/java/freemarker/core/PrintfGTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/PrintfGTemplateNumberFormatFactory.java b/src/test/java/freemarker/core/PrintfGTemplateNumberFormatFactory.java
index dd3c2be..47d46b1 100644
--- a/src/test/java/freemarker/core/PrintfGTemplateNumberFormatFactory.java
+++ b/src/test/java/freemarker/core/PrintfGTemplateNumberFormatFactory.java
@@ -68,7 +68,7 @@ public class PrintfGTemplateNumberFormatFactory extends TemplateNumberFormatFact
         }
         
         @Override
-        public String format(TemplateNumberModel numberModel)
+        public String formatToString(TemplateNumberModel numberModel)
                 throws UnformattableValueException, TemplateModelException {
             final Number n = TemplateFormatUtil.getNonNullNumber(numberModel);
             
@@ -90,32 +90,32 @@ public class PrintfGTemplateNumberFormatFactory extends TemplateNumberFormatFact
         }
 
         @Override
-        public <MO extends TemplateMarkupOutputModel> MO format(TemplateNumberModel numberModel,
-                MarkupOutputFormat<MO> outputFormat) throws UnformattableValueException, TemplateModelException {
+        public Object formatToMarkupOrString(TemplateNumberModel numberModel, MarkupOutputFormat<?> outputFormat)
+                throws UnformattableValueException, TemplateModelException {
+            String strResult = formatToString(numberModel);
             if (!(outputFormat instanceof HTMLOutputFormat || outputFormat instanceof XHTMLOutputFormat)) {
-                return null;
+                return strResult;
             }
             
-            String s = StringUtil.XHTMLEnc(format(numberModel));
-            int eIdx = s.indexOf('E');
-            if (eIdx == -1) {
-                return outputFormat.fromMarkup(s);
+            int expIdx = strResult.indexOf('E');
+            if (expIdx == -1) {
+                return strResult;
             }
                 
-            String expStr = s.substring(eIdx + 1);
-            int expNumStart = 0;
-            while (expNumStart < expStr.length() && isExpSignificantDigitPrefix(expStr.charAt(expNumStart))) {
-                expNumStart++;
+            String expStr = strResult.substring(expIdx + 1);
+            int expSignifNumBegin = 0;
+            while (expSignifNumBegin < expStr.length() && isExpSignifNumPrefix(expStr.charAt(expSignifNumBegin))) {
+                expSignifNumBegin++;
             }
             
             return outputFormat.fromMarkup(
-                    s.substring(0, eIdx)
+                    strResult.substring(0, expIdx)
                     + "*10<sup>"
-                    + (expStr.charAt(0) == '-' ? "-" : "") + expStr.substring(expNumStart)
+                    + (expStr.charAt(0) == '-' ? "-" : "") + expStr.substring(expSignifNumBegin)
                     + "</sup>");
         }
 
-        private boolean isExpSignificantDigitPrefix(char c) {
+        private boolean isExpSignifNumPrefix(char c) {
             return c == '+' || c == '-' || c == '0';
         }
 


Mime
View raw message