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 2015/09/26 09:20:15 UTC

incubator-freemarker git commit: Added checks against null returning (custom) TemplateValueFormat results. Minor cleanup and documentation additions in formatting related parts.

Repository: incubator-freemarker
Updated Branches:
  refs/heads/2.3-gae e90143c89 -> 9ce036f5d


Added checks against null returning (custom) TemplateValueFormat results. Minor cleanup and documentation additions in formatting related parts.


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

Branch: refs/heads/2.3-gae
Commit: 9ce036f5d78fef56a03b49f83e88379366f04c3e
Parents: e90143c
Author: ddekany <dd...@apache.org>
Authored: Sat Sep 26 09:19:52 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sat Sep 26 09:19:52 2015 +0200

----------------------------------------------------------------------
 .../freemarker/core/AddConcatExpression.java    |  1 -
 .../core/BuiltInsForMultipleTypes.java          |  2 +-
 .../java/freemarker/core/DollarVariable.java    |  2 +-
 src/main/java/freemarker/core/Environment.java  |  6 +--
 src/main/java/freemarker/core/EvalUtil.java     | 42 ++++++++++++++++----
 .../freemarker/core/TemplateDateFormat.java     |  2 +
 .../freemarker/core/TemplateNumberFormat.java   |  2 +
 .../java/freemarker/ext/beans/BeanModel.java    |  8 +++-
 8 files changed, 50 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9ce036f5/src/main/java/freemarker/core/AddConcatExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/AddConcatExpression.java b/src/main/java/freemarker/core/AddConcatExpression.java
index c90cb19..f92b933 100644
--- a/src/main/java/freemarker/core/AddConcatExpression.java
+++ b/src/main/java/freemarker/core/AddConcatExpression.java
@@ -82,7 +82,6 @@ final class AddConcatExpression extends Expression {
                         leftModel, leftExp, (String) null, markupOutputFormat, env);
                 Object rightOMOrStr = EvalUtil.coerceModelToMarkupOutputOrString(
                         rightModel, rightExp, (String) null, markupOutputFormat, env);
-                // TODO prove that neither can be null
 
                 if (leftOMOrStr instanceof String) {
                     if (rightOMOrStr instanceof String) {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9ce036f5/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 aaaaf97..deb88b2 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.formatToString(dateModel);
+                        cachedValue = EvalUtil.formatResultNotNull(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/9ce036f5/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 4331b51..23a995b 100644
--- a/src/main/java/freemarker/core/DollarVariable.java
+++ b/src/main/java/freemarker/core/DollarVariable.java
@@ -68,7 +68,7 @@ final class DollarVariable extends Interpolation {
             } else {
                 out.write(s);
             }
-        } else { // moOrStr wasn't output yet
+        } else {
             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/9ce036f5/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 a1073c2..ca6d7b1 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.formatToString(number);
+            return EvalUtil.formatResultNotNull(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.formatToString(tdm);
+            return EvalUtil.formatResultNotNull(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.formatToString(tdm);
+            return EvalUtil.formatResultNotNull(format.formatToString(tdm));
         } catch (TemplateValueFormatException e) {
             throw MessageUtil.newCantFormatDateException(format, blamedDateSourceExp, e, useTempModelExc);
         }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9ce036f5/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 c20dcff..6dfc68d 100644
--- a/src/main/java/freemarker/core/EvalUtil.java
+++ b/src/main/java/freemarker/core/EvalUtil.java
@@ -341,26 +341,32 @@ class EvalUtil {
         }
     }
 
+    /**
+     * @return Never {@code null}
+     */
     static String coerceModelToString(TemplateModel tm, Expression exp, String seqHint,
             Environment env) throws TemplateException {
         if (tm instanceof TemplateNumberModel) {
-            return env.formatNumberToString((TemplateNumberModel) tm, exp, false);
+            return formatResultNotNull(env.formatNumberToString((TemplateNumberModel) tm, exp, false));
         } else if (tm instanceof TemplateDateModel) {
-            return env.formatDateToString((TemplateDateModel) tm, exp, false);
+            return formatResultNotNull(env.formatDateToString((TemplateDateModel) tm, exp, false));
         } else {
             return coerceModelToStringCommon(tm, exp, seqHint, false, env);
         }
     }
 
+    /**
+     * @return Never {@code null}
+     */
     static Object coerceModelToMarkupOutputOrString(TemplateModel tm, Expression exp, String seqHint,
             MarkupOutputFormat markupOutputFormat, Environment env) throws TemplateException {
         if (tm instanceof TemplateNumberModel) {
             TemplateNumberModel tnm = (TemplateNumberModel) tm; 
             TemplateNumberFormat format = env.getTemplateNumberFormat(exp, false);
             try {
-                return markupOutputFormat != null 
+                return formatResultNotNull(markupOutputFormat != null 
                         ? format.formatToMarkupOrString(tnm, markupOutputFormat)
-                        : format.formatToString(tnm);
+                        : format.formatToString(tnm));
             } catch (TemplateValueFormatException e) {
                 throw MessageUtil.newCantFormatNumberException(format, exp, e, false);
             }
@@ -368,9 +374,9 @@ class EvalUtil {
             TemplateDateModel tdm = (TemplateDateModel) tm;
             TemplateDateFormat format = env.getTemplateDateFormat(tdm, exp, false);
             try {
-                return markupOutputFormat != null
+                return formatResultNotNull(markupOutputFormat != null
                         ? format.formatToMarkupOrString(tdm, markupOutputFormat)
-                        : format.formatToString(tdm);
+                        : format.formatToString(tdm));
             } catch (TemplateValueFormatException e) {
                 throw MessageUtil.newCantFormatDateException(format, exp, e, false);
             }
@@ -382,11 +388,17 @@ class EvalUtil {
     }
 
     /**
+     * @param tm
+     *            If {@code null} that's an exception, unless we are in classic compatible mode.
+     * 
      * @param supportsTOM
      *            Whether the caller {@code coerceModelTo...} method could handle a {@link TemplateMarkupOutputModel}.
+     *            
+     * @return Never {@code null}
      */
-    private static String coerceModelToStringCommon(TemplateModel tm, Expression exp, String seqHint, boolean supportsTOM,
-            Environment env) throws TemplateModelException, InvalidReferenceException, TemplateException,
+    private static String coerceModelToStringCommon(
+            TemplateModel tm, Expression exp, String seqHint, boolean supportsTOM, Environment env)
+            throws TemplateModelException, InvalidReferenceException, TemplateException,
                     NonStringOrTemplateOutputException, NonStringException {
         if (tm instanceof TemplateScalarModel) {
             return modelToString((TemplateScalarModel) tm, exp, env);
@@ -444,6 +456,20 @@ class EvalUtil {
         }
     }
 
+    static String formatResultNotNull(String r) {
+        if (r != null) {
+            return r;
+        }
+        throw new NullPointerException("TemplateValueFormatter result can't be null");
+    }
+
+    static Object formatResultNotNull(Object r) {
+        if (r != null) {
+            return r;
+        }
+        throw new NullPointerException("TemplateValueFormatter result can't be null");
+    }
+
     /**
      * Returns an {@link ArithmeticEngine} even if {@code env} is {@code null}, because we are in parsing phase.
      */

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9ce036f5/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 6a6d66b..2f49d2d 100644
--- a/src/main/java/freemarker/core/TemplateDateFormat.java
+++ b/src/main/java/freemarker/core/TemplateDateFormat.java
@@ -62,6 +62,8 @@ public abstract class TemplateDateFormat extends TemplateValueFormat {
      * {@link #formatToString(TemplateDateModel)} escaped, it must return the {@link String} that
      * {@link #formatToString(TemplateDateModel)} does.
      * 
+     * <p>The implementation in {@link TemplateDateFormat} simply calls {@link #formatToString(TemplateDateModel)}.
+     * 
      * @param outputFormat
      *            When the result is a {@link TemplateMarkupOutputModel} result, it must be exactly of this output
      *            format.

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9ce036f5/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 eb75ea7..69a5da0 100644
--- a/src/main/java/freemarker/core/TemplateNumberFormat.java
+++ b/src/main/java/freemarker/core/TemplateNumberFormat.java
@@ -61,6 +61,8 @@ public abstract class TemplateNumberFormat extends TemplateValueFormat {
      * {@link #formatToString(TemplateNumberModel)} escaped, it must return the {@link String} that
      * {@link #formatToString(TemplateNumberModel)} does.
      * 
+     * <p>The implementation in {@link TemplateNumberFormat} simply calls {@link #formatToString(TemplateNumberModel)}.
+     * 
      * @param outputFormat
      *            When the result is a {@link TemplateMarkupOutputModel} result, it must be exactly of this output
      *            format. Not {@code null}.

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9ce036f5/src/main/java/freemarker/ext/beans/BeanModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/BeanModel.java b/src/main/java/freemarker/ext/beans/BeanModel.java
index 090deab..26eb1f5 100644
--- a/src/main/java/freemarker/ext/beans/BeanModel.java
+++ b/src/main/java/freemarker/ext/beans/BeanModel.java
@@ -337,9 +337,15 @@ implements
      * In FreeMarker 1.7 (and also at least in 2.1) {@link BeanModel} was a {@link TemplateScalarModel}. Some internal
      * FreeMarker code tries to emulate FreeMarker classic by calling this method when a {@link TemplateScalarModel} is
      * expected.
+     * 
+     * @return Never {@code null}
      */
     String getAsClassicCompatibleString() {
-        return object == null ? "null" : object.toString();        
+        if (object == null) {
+            return "null";
+        }
+        String s = object.toString();
+        return s != null ? s : "null";        
     }
     
     @Override