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 2016/12/04 23:49:52 UTC

[2/2] incubator-freemarker git commit: FREEMARKER-42: ?first now works with FTL collections (things that can be listed but doesn't support getting items by index), not only with sequences. The practical importance of this is that ?first now always works

FREEMARKER-42: ?first now works with FTL collections (things that can be listed but doesn't support getting items by index), not only with sequences. The practical importance of this is that ?first now always works on Java Set-s (which is useful for Set-s with well defined ordering), while earlier it has failed depending on the object_wrapper configuration setting.


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

Branch: refs/heads/2.3-gae
Commit: 496ddfbc08c6d3242ab5c31694db152d9c1e4c58
Parents: ed403c8
Author: ddekany <dd...@apache.org>
Authored: Mon Dec 5 00:49:38 2016 +0100
Committer: ddekany <dd...@apache.org>
Committed: Mon Dec 5 00:49:38 2016 +0100

----------------------------------------------------------------------
 .../freemarker/core/BuiltInsForSequences.java   | 33 ++++++++++--
 src/manual/en_US/book.xml                       | 57 ++++++++++++++++++--
 .../test/templatesuite/TemplateTestCase.java    |  1 +
 .../expected/sequence-builtins.txt              |  7 +++
 .../templates/sequence-builtins.ftl             |  8 ++-
 5 files changed, 98 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/496ddfbc/src/main/java/freemarker/core/BuiltInsForSequences.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BuiltInsForSequences.java b/src/main/java/freemarker/core/BuiltInsForSequences.java
index a12d274..d56a95f 100644
--- a/src/main/java/freemarker/core/BuiltInsForSequences.java
+++ b/src/main/java/freemarker/core/BuiltInsForSequences.java
@@ -138,15 +138,40 @@ class BuiltInsForSequences {
         
     }
     
-    static class firstBI extends BuiltInForSequence {
+    static class firstBI extends BuiltIn {
+        
         @Override
-        TemplateModel calculateResult(TemplateSequenceModel tsm)
+        TemplateModel _eval(Environment env)
+                throws TemplateException {
+            TemplateModel model = target.eval(env);
+            // In 2.3.x only, we prefer TemplateSequenceModel for
+            // backward compatibility. In 2.4.x, we prefer TemplateCollectionModel. 
+            if (model instanceof TemplateSequenceModel && !isBuggySeqButGoodCollection(model)) {
+                return calculateResultForSequence((TemplateSequenceModel) model);
+            } else if (model instanceof TemplateCollectionModel) {
+                return calculateResultForColletion((TemplateCollectionModel) model);
+            } else {
+                throw new NonSequenceOrCollectionException(target, model, env);
+            }
+        }        
+        
+        private TemplateModel calculateResultForSequence(TemplateSequenceModel seq)
         throws TemplateModelException {
-            if (tsm.size() == 0) {
+            if (seq.size() == 0) {
+                return null;
+            }
+            return seq.get(0);
+        }
+        
+        private TemplateModel calculateResultForColletion(TemplateCollectionModel coll)
+        throws TemplateModelException {
+            TemplateModelIterator iter = coll.iterator();
+            if (!iter.hasNext()) {
                 return null;
             }
-            return tsm.get(0);
+            return iter.next();
         }
+        
     }
 
     static class joinBI extends BuiltIn {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/496ddfbc/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index e592d47..4adf154 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -30,7 +30,7 @@
 
     <titleabbrev>Manual</titleabbrev>
 
-    <productname>Freemarker 2.3.25</productname>
+    <productname>Freemarker 2.3.26</productname>
   </info>
 
   <preface role="index.html" xml:id="preface">
@@ -16416,8 +16416,19 @@ N
             <primary>first built-in</primary>
           </indexterm>
 
-          <para>The first subvariable of the sequence. Template processing
-          will die with error if the sequence is empty.</para>
+          <para>Returns the first item of the sequence. Thus
+          <literal><replaceable>value</replaceable>?first</literal> is the
+          same as <literal><replaceable>value</replaceable>[0]</literal>,
+          except that, since FreeMarker 2.3.26,
+          <literal><replaceable>value</replaceable>?first</literal> also works
+          if <literal><replaceable>value</replaceable></literal> doesn't
+          support getting items with numerical index, but still supports to be
+          listed (i.e., with FTL collection values).</para>
+
+          <para>If the sequence or collection is empty, the result will be a
+          missing value (as in
+          <literal><replaceable>empty</replaceable>?first!'No item was
+          found'</literal>).</para>
         </section>
 
         <section xml:id="ref_builtin_join">
@@ -26603,6 +26614,46 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
     <appendix xml:id="app_versions">
       <title>Version history</title>
 
+      <section xml:id="versions_2_3_26">
+        <title>2.3.26 (incubating at Apache)</title>
+
+        <para>Release date: FIXME</para>
+
+        <para><emphasis role="bold">This is a stable, final
+        release.</emphasis> The <quote>incubating</quote> suffix is required
+        by the Apache Software Foundation until the project becomes a fully
+        accepted (graduated) Apache project.</para>
+
+        <section>
+          <title>Changes on the FTL side</title>
+
+          <itemizedlist>
+            <listitem>
+              <para>Bug fixed (<link
+              xlink:href="https://issues.apache.org/jira/browse/FREEMARKER-42">FREEMARKER-42</link>):
+              <literal>?first</literal> now works with FTL collections (things
+              that can be listed but doesn't support getting items by index),
+              not only with sequences. The practical importance of this is
+              that <literal>?first</literal> now always works on Java
+              <literal>Set</literal>-s (which is useful for
+              <literal>Set</literal>-s with well defined ordering), while
+              earlier it has failed depending on the
+              <literal>object_wrapper</literal> configuration setting.</para>
+            </listitem>
+          </itemizedlist>
+        </section>
+
+        <section>
+          <title>Changes on the Java side</title>
+
+          <itemizedlist>
+            <listitem>
+              <para>FIXME</para>
+            </listitem>
+          </itemizedlist>
+        </section>
+      </section>
+
       <section xml:id="versions_2_3_25">
         <title>2.3.25 (incubating at Apache)</title>
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/496ddfbc/src/test/java/freemarker/test/templatesuite/TemplateTestCase.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/test/templatesuite/TemplateTestCase.java b/src/test/java/freemarker/test/templatesuite/TemplateTestCase.java
index dfac6b3..24b67f8 100644
--- a/src/test/java/freemarker/test/templatesuite/TemplateTestCase.java
+++ b/src/test/java/freemarker/test/templatesuite/TemplateTestCase.java
@@ -377,6 +377,7 @@ public class TemplateTestCase extends FileTestCase {
             abcSet.add("b");
             abcSet.add("c");
             dataModel.put("abcSet", abcSet);
+            dataModel.put("abcSetNonSeq", DefaultNonListCollectionAdapter.adapt(abcSet, beansWrapper));
             
             List<String> listWithNull = new ArrayList<String>();
             listWithNull.add("a");

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/496ddfbc/src/test/resources/freemarker/test/templatesuite/expected/sequence-builtins.txt
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/test/templatesuite/expected/sequence-builtins.txt b/src/test/resources/freemarker/test/templatesuite/expected/sequence-builtins.txt
index 664c95b..1201da9 100644
--- a/src/test/resources/freemarker/test/templatesuite/expected/sequence-builtins.txt
+++ b/src/test/resources/freemarker/test/templatesuite/expected/sequence-builtins.txt
@@ -395,3 +395,10 @@ Join
 - (empty)
 - a, b, c.
 - a, b, c.
+
+
+Misc
+----
+
+First of set 1: a
+First of set 2: a
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/496ddfbc/src/test/resources/freemarker/test/templatesuite/templates/sequence-builtins.ftl
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/test/templatesuite/templates/sequence-builtins.ftl b/src/test/resources/freemarker/test/templatesuite/templates/sequence-builtins.ftl
index c431048..1586ad9 100644
--- a/src/test/resources/freemarker/test/templatesuite/templates/sequence-builtins.ftl
+++ b/src/test/resources/freemarker/test/templatesuite/templates/sequence-builtins.ftl
@@ -351,4 +351,10 @@ Join
 - ${listWithNullsOnly?join(", ", "(empty)", ".")}
 - ${abcSet?join(", ", "(empty)", ".")}
 - ${abcCollection?join(", ", "(empty)", ".")}
-<@assertFails message="index 1">${['a', [], 'c']?join(", ", "(empty)", ".")}</@>
\ No newline at end of file
+<@assertFails message="index 1">${['a', [], 'c']?join(", ", "(empty)", ".")}</@>
+
+Misc
+----
+
+First of set 1: ${abcSet?first}
+First of set 2: ${abcSetNonSeq?first}
\ No newline at end of file