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/03/13 10:43:17 UTC

[01/25] incubator-freemarker git commit: Manual: Document ?groups in more detail

Repository: incubator-freemarker
Updated Branches:
  refs/heads/2.3 617ad6fc0 -> 0254eca3f


Manual: Document ?groups in more detail


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

Branch: refs/heads/2.3
Commit: 779e74a844364820a4fefb5531218469ccd6e44b
Parents: 83eac15
Author: ddekany <dd...@apache.org>
Authored: Fri Mar 3 11:33:55 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Fri Mar 3 11:33:55 2017 +0100

----------------------------------------------------------------------
 src/manual/en_US/book.xml | 49 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/779e74a8/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index c3e683a..48b754e 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -7,9 +7,9 @@
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at
-
+  
     http://www.apache.org/licenses/LICENSE-2.0
-
+  
   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -13848,9 +13848,48 @@ Matching sub-strings:
   - "aa/rx;" is "a" per "a/rx"
   - " ab/r;" is " " per "ab/r"</programlisting>
 
-          <para>Note above that <literal>groups</literal> has worked both with
-          substring matches and with the result of entire string
-          matching.</para>
+          <para>Notes regarding the behavior of the <literal>groups</literal>
+          built-in:</para>
+
+          <itemizedlist>
+            <listitem>
+              <para>It works both with substring matches and with the result
+              of entire string matching (as it was shown in the above
+              example)</para>
+            </listitem>
+
+            <listitem>
+              <para>The first item in the sequence that
+              <literal>groups</literal> returns is the whole substring matched
+              by the regular expression. Hence, the index of the first
+              explicit regular expression group (with other words, of the
+              first <literal>(<replaceable>...</replaceable>)</literal> in the
+              regular expression) is 1, and not 0. Also, because of this, the
+              size of the sequence is one more than the number of explicit
+              regular expression groups.</para>
+            </listitem>
+
+            <listitem>
+              <para>The size of the sequence returned by
+              <literal>groups</literal> only depends on the number of explicit
+              groups in the regular expression, and so it will be the same
+              (non-0) even if there was no match found for the regular
+              expression. Attempting to access an item of the sequence (as in
+              <literal>res?groups[1]</literal>) when there was match will
+              cause an error. Thus, before accessing the groups, you should
+              always check if there was any match (as in <literal>&lt;#if
+              res&gt;<replaceable>access the groups
+              here</replaceable>&lt;/#if&gt;</literal>).</para>
+            </listitem>
+
+            <listitem>
+              <para>When there's a match for the regular expression, but not
+              for a certain explicit group inside the regular expression, then
+              for that group the sequence will contain a 0 length string. So
+              accessing a group that matches nothing is safe, as far as the
+              containing regular expression has matched something.</para>
+            </listitem>
+          </itemizedlist>
 
           <para><literal>matches</literal> accepts an optional 2nd parameter,
           the <link linkend="ref_builtin_string_flags">flags</link>. Note that


[05/25] incubator-freemarker git commit: (Removed unused variable)

Posted by dd...@apache.org.
(Removed unused variable)


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

Branch: refs/heads/2.3
Commit: b13a8763dbc5b4952ff46c479b535522cf1ca207
Parents: df03e03
Author: ddekany <dd...@apache.org>
Authored: Fri Mar 3 22:19:35 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Fri Mar 3 22:19:35 2017 +0100

----------------------------------------------------------------------
 src/main/javacc/FTL.jj | 5 -----
 1 file changed, 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/b13a8763/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj
index 46e565a..c6a9d8b 100644
--- a/src/main/javacc/FTL.jj
+++ b/src/main/javacc/FTL.jj
@@ -85,11 +85,6 @@ public class FMParser {
      */
     private int breakableDirectiveNesting;
     
-    /**
-     * Keeps track of the flags of the innermost parent #list or #foreach directive.
-     */
-    private int parentListAndForeachFlags;
-    
     private boolean inMacro, inFunction;
     private LinkedList escapes = new LinkedList();
     private int mixedContentNesting; // for stripText


[18/25] incubator-freemarker git commit: DefaultObjectWrapper, only with its incompatible_improvements set to 2.3.26, wraps java.util.Enumeration-s into freemarker.template.DefaultEnumerationAdapter (a new class) instead of into freemarker.ext.beans.Enu

Posted by dd...@apache.org.
DefaultObjectWrapper, only with its incompatible_improvements set to 2.3.26, wraps java.util.Enumeration-s into  freemarker.template.DefaultEnumerationAdapter (a new class) instead of into freemarker.ext.beans.EnumerationModel (as far as useAdaptersForContainers is true, which is the default). This adapter is cleaner than EnumerationModel as it only implements the minimally required FTL type, which avoids some ambiguous situations. (Note that Java API methods aren't exposed anymore as subvariables; if you really need them, you can use ?api).


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

Branch: refs/heads/2.3
Commit: 544e9105c54c0afbdcea6d2eac00cf19aa0f4daa
Parents: 593d35d
Author: ddekany <dd...@apache.org>
Authored: Sun Mar 12 15:42:24 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sun Mar 12 15:42:24 2017 +0100

----------------------------------------------------------------------
 .../template/DefaultEnumerationAdapter.java     | 96 ++++++++++++++++++++
 .../template/DefaultObjectWrapper.java          | 16 ++++
 src/manual/en_US/book.xml                       | 22 ++++-
 .../template/DefaultObjectWrapperTest.java      | 40 ++++++++
 4 files changed, 172 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/544e9105/src/main/java/freemarker/template/DefaultEnumerationAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/DefaultEnumerationAdapter.java b/src/main/java/freemarker/template/DefaultEnumerationAdapter.java
new file mode 100644
index 0000000..570e0e8
--- /dev/null
+++ b/src/main/java/freemarker/template/DefaultEnumerationAdapter.java
@@ -0,0 +1,96 @@
+package freemarker.template;
+
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.Iterator;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import freemarker.ext.util.WrapperTemplateModel;
+
+/**
+ * Adapts an {@link Enumeration} to the corresponding {@link TemplateModel} interface(s), most importantly to
+ * {@link TemplateCollectionModel}. Putting aside that it wraps an {@link Enumeration} instead of an {@link Iterator},
+ * this is identical to {@link DefaultIteratorAdapter}, so see further details there.
+ * 
+ * @since 2.3.26
+ */
+@SuppressWarnings("serial")
+public class DefaultEnumerationAdapter extends WrappingTemplateModel implements TemplateCollectionModel,
+        AdapterTemplateModel, WrapperTemplateModel, Serializable {
+
+    @SuppressFBWarnings(value="SE_BAD_FIELD", justification="We hope it's Seralizable")
+    private final Enumeration<?> enumeration;
+    private boolean enumerationOwnedBySomeone;
+
+    /**
+     * Factory method for creating new adapter instances.
+     *
+     * @param enumeration
+     *            The enumeration to adapt; can't be {@code null}.
+     */
+    public static DefaultEnumerationAdapter adapt(Enumeration<?> enumeration, ObjectWrapper wrapper) {
+        return new DefaultEnumerationAdapter(enumeration, wrapper);
+    }
+
+    private DefaultEnumerationAdapter(Enumeration<?> enumeration, ObjectWrapper wrapper) {
+        super(wrapper);
+        this.enumeration = enumeration;
+    }
+
+    @Override
+    public Object getWrappedObject() {
+        return enumeration;
+    }
+
+    @Override
+    public Object getAdaptedObject(Class<?> hint) {
+        return getWrappedObject();
+    }
+
+    @Override
+    public TemplateModelIterator iterator() throws TemplateModelException {
+        return new SimpleTemplateModelIterator();
+    }
+
+    /**
+     * Not thread-safe.
+     */
+    private class SimpleTemplateModelIterator implements TemplateModelIterator {
+
+        private boolean enumerationOwnedByMe;
+
+        @Override
+        public TemplateModel next() throws TemplateModelException {
+            if (!enumerationOwnedByMe) {
+                checkNotOwner();
+                enumerationOwnedBySomeone = true;
+                enumerationOwnedByMe = true;
+            }
+
+            if (!enumeration.hasMoreElements()) {
+                throw new TemplateModelException("The collection has no more items.");
+            }
+
+            Object value = enumeration.nextElement();
+            return value instanceof TemplateModel ? (TemplateModel) value : wrap(value);
+        }
+
+        @Override
+        public boolean hasNext() throws TemplateModelException {
+            // Calling hasNext may looks safe, but I have met sync. problems.
+            if (!enumerationOwnedByMe) {
+                checkNotOwner();
+            }
+
+            return enumeration.hasMoreElements();
+        }
+
+        private void checkNotOwner() throws TemplateModelException {
+            if (enumerationOwnedBySomeone) {
+                throw new TemplateModelException(
+                        "This collection value wraps a java.util.Enumeration, thus it can be listed only once.");
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/544e9105/src/main/java/freemarker/template/DefaultObjectWrapper.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/DefaultObjectWrapper.java b/src/main/java/freemarker/template/DefaultObjectWrapper.java
index 1398be4..4c5a39d 100644
--- a/src/main/java/freemarker/template/DefaultObjectWrapper.java
+++ b/src/main/java/freemarker/template/DefaultObjectWrapper.java
@@ -22,6 +22,7 @@ package freemarker.template;
 import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -31,6 +32,7 @@ import org.w3c.dom.Node;
 
 import freemarker.ext.beans.BeansWrapper;
 import freemarker.ext.beans.BeansWrapperConfiguration;
+import freemarker.ext.beans.EnumerationModel;
 import freemarker.ext.dom.NodeModel;
 import freemarker.log.Logger;
 
@@ -68,6 +70,7 @@ public class DefaultObjectWrapper extends freemarker.ext.beans.BeansWrapper {
     private boolean useAdaptersForContainers;
     private boolean forceLegacyNonListCollections;
     private boolean iterableSupport;
+    private final boolean useAdapterForEnumerations;
     
     /**
      * Creates a new instance with the incompatible-improvements-version specified in
@@ -97,6 +100,13 @@ public class DefaultObjectWrapper extends freemarker.ext.beans.BeansWrapper {
      *                  won't cause the a later iteration (or further emptiness check) to fail anymore. Earlier, in
      *                  certain situations, the second operation has failed saying that the iterator "can be listed only
      *                  once".  
+     *              <li>2.3.26 (or higher): {@link Enumeration}-s are wrapped into {@link DefaultEnumerationAdapter}
+     *                  instead of into {@link EnumerationModel} (as far as
+     *                  {@link #setUseAdaptersForContainers(boolean) useAdaptersForContainers} is {@code true}, which is
+     *                  the default). This adapter is cleaner than {@link EnumerationModel} as it only implements the
+     *                  minimally required FTL type, which avoids some ambiguous situations. (Note that Java API methods
+     *                  aren't exposed anymore as subvariables; if you really need them, you can use {@code ?api}). 
+     *                  </li>
      *            </ul>
      * 
      * @since 2.3.21
@@ -117,6 +127,8 @@ public class DefaultObjectWrapper extends freemarker.ext.beans.BeansWrapper {
                 ? (DefaultObjectWrapperConfiguration) bwCfg
                 : new DefaultObjectWrapperConfiguration(bwCfg.getIncompatibleImprovements()) { }; 
         useAdaptersForContainers = dowDowCfg.getUseAdaptersForContainers();
+        useAdapterForEnumerations = useAdaptersForContainers
+                && getIncompatibleImprovements().intValue() >= _TemplateAPI.VERSION_INT_2_3_26;
         forceLegacyNonListCollections = dowDowCfg.getForceLegacyNonListCollections();
         iterableSupport = dowDowCfg.getIterableSupport();
         finalizeConstruction(writeProtected);
@@ -226,9 +238,13 @@ public class DefaultObjectWrapper extends freemarker.ext.beans.BeansWrapper {
                     ? (TemplateModel) DefaultIteratorAdapter.adapt((Iterator<?>) obj, this)
                     : (TemplateModel) new SimpleCollection((Iterator<?>) obj, this);
         }
+        if (useAdapterForEnumerations && obj instanceof Enumeration) {
+            return DefaultEnumerationAdapter.adapt((Enumeration<?>) obj, this);
+        }        
         if (iterableSupport && obj instanceof Iterable) {
             return DefaultIterableAdapter.adapt((Iterable<?>) obj, this);
         }
+        
         return handleUnknownType(obj);
     }
     

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/544e9105/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index 3e0814f..beee581 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -7,9 +7,9 @@
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at
-
+  
     http://www.apache.org/licenses/LICENSE-2.0
-
+  
   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -26887,6 +26887,24 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
             </listitem>
 
             <listitem>
+              <para><literal>DefaultObjectWrapper</literal>, only with its
+              <literal>incompatible_improvements</literal> set to 2.3.26
+              (<link linkend="topic.defaultObjectWrapperIcI">see how
+              here...</link>), wraps
+              <literal>java.util.Enumeration</literal>-s into
+              <literal>freemarker.template.DefaultEnumerationAdapter</literal>
+              (a new class) instead of into
+              <literal>freemarker.ext.beans.EnumerationModel</literal> (as far
+              as <literal>useAdaptersForContainers</literal> is
+              <literal>true</literal>, which is the default). This adapter is
+              cleaner than <literal>EnumerationModel</literal> as it only
+              implements the minimally required FTL type, which avoids some
+              ambiguous situations. (Note that Java API methods aren't exposed
+              anymore as subvariables; if you really need them, you can use
+              <literal>?api</literal>).</para>
+            </listitem>
+
+            <listitem>
               <para>Better error messages when someone tries to get an invalid
               <literal>@@<replaceable>...</replaceable></literal> subvariable
               of an XML DOM node. (Now it's not issued by the XPath

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/544e9105/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/template/DefaultObjectWrapperTest.java b/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
index 5d3ad2b..4be352a 100644
--- a/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
+++ b/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
@@ -39,6 +39,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.TreeSet;
+import java.util.Vector;
 
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -53,6 +54,7 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
 import freemarker.ext.beans.BeansWrapper;
+import freemarker.ext.beans.EnumerationModel;
 import freemarker.ext.beans.HashAdapter;
 import freemarker.ext.util.WrapperTemplateModel;
 
@@ -943,6 +945,44 @@ public class DefaultObjectWrapperTest {
             assertTemplateOutput(OW22IS, iterable, listingFTL, "a, b, c");
         }
     }
+
+    @Test
+    public void testNoEnumerationAdapter() throws TemplateModelException {
+         DefaultObjectWrapper ow = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_25).build();
+         Vector<String> vector = new Vector<String>();
+         vector.add("a");
+         vector.add("b");
+         
+         TemplateModel wrappedEnumeration = ow.wrap(vector.elements());
+         assertThat(wrappedEnumeration, instanceOf(EnumerationModel.class));
+         EnumerationModel enumModel = (EnumerationModel) wrappedEnumeration;
+         assertNotNull(enumModel.get("nextElement"));
+    }
+    
+    @Test
+    public void testEnumerationAdapter() throws TemplateModelException {
+         DefaultObjectWrapper ow = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_26).build();
+         Vector<String> vector = new Vector<String>();
+         vector.add("a");
+         vector.add("b");
+         
+         TemplateModel wrappedEnumeration = ow.wrap(vector.elements());
+         assertThat(wrappedEnumeration, instanceOf(DefaultEnumerationAdapter.class));
+         DefaultEnumerationAdapter enumAdapter = (DefaultEnumerationAdapter) wrappedEnumeration;
+         TemplateModelIterator iterator = enumAdapter.iterator();
+         assertTrue(iterator.hasNext());
+         assertEquals("a", ((TemplateScalarModel) iterator.next()).getAsString());
+         assertTrue(iterator.hasNext());
+         assertEquals("b", ((TemplateScalarModel) iterator.next()).getAsString());
+         assertFalse(iterator.hasNext());
+         
+         iterator = enumAdapter.iterator();
+         try {
+             iterator.hasNext();
+         } catch (TemplateException e) {
+             assertThat(e.getMessage(), containsStringIgnoringCase("only once"));
+         }
+    }
     
     @Test
     public void assertCanWrapDOM() throws SAXException, IOException, ParserConfigurationException,


[25/25] incubator-freemarker git commit: Merge remote-tracking branch 'origin/2.3-gae' into 2.3

Posted by dd...@apache.org.
Merge remote-tracking branch 'origin/2.3-gae' into 2.3


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

Branch: refs/heads/2.3
Commit: 0254eca3f288149d32fb87672a1db4d359ab650a
Parents: 617ad6f edc0e41
Author: ddekany <dd...@apache.org>
Authored: Mon Mar 13 11:43:03 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Mon Mar 13 11:43:03 2017 +0100

----------------------------------------------------------------------
 .gitignore                                      |   1 +
 README                                          |   8 +-
 build.properties.sample                         |   1 +
 build.xml                                       |  33 +-
 src/main/java/freemarker/core/Interpret.java    |   4 +-
 .../freemarker/core/TemplateConfiguration.java  |   4 +-
 src/main/java/freemarker/core/_Java6Impl.java   |   2 +
 src/main/java/freemarker/core/_Java8.java       |  34 ++
 src/main/java/freemarker/core/_Java8Impl.java   |  41 ++
 .../java/freemarker/core/_JavaVersions.java     |  45 +++
 .../java/freemarker/ext/beans/BeansWrapper.java |  77 +++-
 .../ext/beans/BeansWrapperConfiguration.java    |  37 +-
 .../freemarker/ext/beans/ClassIntrospector.java | 400 ++++++++++++++++---
 .../ext/beans/ClassIntrospectorBuilder.java     |  15 +
 .../java/freemarker/ext/beans/MethodSorter.java |   6 +-
 .../java/freemarker/ext/beans/_MethodUtil.java  |  26 ++
 .../java/freemarker/ext/dom/NodeListModel.java  |  10 +-
 .../java/freemarker/template/Configuration.java |   8 +
 .../template/DefaultEnumerationAdapter.java     | 119 ++++++
 .../template/DefaultIteratorAdapter.java        |   7 +-
 .../DefaultNonListCollectionAdapter.java        |   2 +-
 .../template/DefaultObjectWrapper.java          |  16 +
 .../freemarker/template/SimpleCollection.java   |  10 +-
 .../template/TemplateCollectionModelEx.java     |   8 -
 src/main/javacc/FTL.jj                          |   5 -
 src/manual/en_US/book.xml                       | 119 +++++-
 .../core/InterpretAndEvalTemplateNameTest.java  |  17 +-
 .../ext/beans/AlphabeticalMethodSorter.java     |   9 +-
 .../beans/BeansWrapperBridgeMethodsTest.java    |  65 +++
 .../ext/beans/BeansWrapperJava8Test.java        | 239 +++++++++++
 .../ext/beans/BeansWrapperSingletonsTest.java   | 141 +++----
 .../freemarker/ext/beans/BridgeMethodsBean.java |  30 ++
 .../ext/beans/BridgeMethodsBeanBase.java        |  29 ++
 .../BridgeMethodsWithDefaultMethodBean.java     |  29 ++
 .../BridgeMethodsWithDefaultMethodBean2.java    |  23 ++
 .../BridgeMethodsWithDefaultMethodBeanBase.java |  31 ++
 ...BridgeMethodsWithDefaultMethodBeanBase2.java |  28 ++
 ...GetPropertyNameFromReaderMethodNameTest.java |  61 +++
 .../ext/beans/Java8DefaultMethodsBean.java      |  83 ++++
 .../ext/beans/Java8DefaultMethodsBeanBase.java  |  90 +++++
 .../freemarker/template/ConfigurationTest.java  |   5 +
 .../template/DefaultObjectWrapperTest.java      |  76 +++-
 .../test/templatesuite/templates/exthash.ftl    |  48 ---
 43 files changed, 1766 insertions(+), 276 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0254eca3/build.xml
----------------------------------------------------------------------


[20/25] incubator-freemarker git commit: DefaultIteratorAdapter now supports ?api. It was an oversight that it didn't. Also, added ?api support to the recently added DefaultEnumerationAdapter too.

Posted by dd...@apache.org.
DefaultIteratorAdapter now supports ?api. It was an oversight that it didn't. Also, added ?api support to the recently added DefaultEnumerationAdapter too.


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

Branch: refs/heads/2.3
Commit: 696ca6b911fda275aa3d7e3136986878e9284773
Parents: da310dd
Author: ddekany <dd...@apache.org>
Authored: Sun Mar 12 16:03:06 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sun Mar 12 16:03:06 2017 +0100

----------------------------------------------------------------------
 src/manual/en_US/book.xml | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/696ca6b9/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index c98b35e..c9248de 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -26959,8 +26959,9 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
             </listitem>
 
             <listitem>
-              <para><literal>DefaultIteratorAdapter</literal> now support
-              <literal>?api</literal>.</para>
+              <para><literal>DefaultIteratorAdapter</literal> now supports
+              <literal>?api</literal>. It was an oversight that it
+              didn't.</para>
             </listitem>
 
             <listitem>


[16/25] incubator-freemarker git commit: (Test cleanup. Also added methodAppearanceFineTuner to equality test.)

Posted by dd...@apache.org.
(Test cleanup. Also added methodAppearanceFineTuner to equality test.)


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

Branch: refs/heads/2.3
Commit: f9204fe158414907eb02d59ceaff008ea39bc8c5
Parents: b855872
Author: ddekany <dd...@apache.org>
Authored: Sun Mar 12 13:57:58 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sun Mar 12 13:57:58 2017 +0100

----------------------------------------------------------------------
 .../ext/beans/BeansWrapperSingletonsTest.java   | 133 ++++++++++---------
 1 file changed, 70 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f9204fe1/src/test/java/freemarker/ext/beans/BeansWrapperSingletonsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BeansWrapperSingletonsTest.java b/src/test/java/freemarker/ext/beans/BeansWrapperSingletonsTest.java
index 60d5c0a..bc3d0eb 100644
--- a/src/test/java/freemarker/ext/beans/BeansWrapperSingletonsTest.java
+++ b/src/test/java/freemarker/ext/beans/BeansWrapperSingletonsTest.java
@@ -65,76 +65,83 @@ public class BeansWrapperSingletonsTest extends TestCase {
             assertThat(e.getMessage(), containsString("upgrade"));
         }
 
-        BeansWrapperBuilder pa1;
-        BeansWrapperBuilder pa2;
-        
-        pa1 = new BeansWrapperBuilder(Configuration.VERSION_2_3_21);
-        pa2 = new BeansWrapperBuilder(Configuration.VERSION_2_3_21);
-        assertEquals(pa1, pa2);
-        
-        pa1.setSimpleMapWrapper(true);
-        assertNotEquals(pa1, pa2);
-        assertFalse(pa1.hashCode() == pa2.hashCode());
-        pa2.setSimpleMapWrapper(true);
-        assertEquals(pa1, pa2);
-        assertTrue(pa1.hashCode() == pa2.hashCode());
-        
-        pa1.setExposeFields(true);
-        assertNotEquals(pa1, pa2);
-        assertFalse(pa1.hashCode() == pa2.hashCode());
-        pa2.setExposeFields(true);
-        assertEquals(pa1, pa2);
-        assertTrue(pa1.hashCode() == pa2.hashCode());
-        
-        pa1.setExposureLevel(0);
-        assertNotEquals(pa1, pa2);
-        assertFalse(pa1.hashCode() == pa2.hashCode());
-        pa2.setExposureLevel(0);
-        assertEquals(pa1, pa2);
-        assertTrue(pa1.hashCode() == pa2.hashCode());
-        
-        pa1.setExposureLevel(1);
-        assertNotEquals(pa1, pa2);
-        assertFalse(pa1.hashCode() == pa2.hashCode());
-        pa2.setExposureLevel(1);
-        assertEquals(pa1, pa2);
-        assertTrue(pa1.hashCode() == pa2.hashCode());
-        
-        pa1.setDefaultDateType(TemplateDateModel.DATE);
-        assertNotEquals(pa1, pa2);
-        pa2.setDefaultDateType(TemplateDateModel.DATE);
-        assertEquals(pa1, pa2);
-        assertTrue(pa1.hashCode() == pa2.hashCode());
-        
-        pa1.setStrict(true);
-        assertNotEquals(pa1, pa2);
-        assertFalse(pa1.hashCode() == pa2.hashCode());
-        pa2.setStrict(true);
-        assertEquals(pa1, pa2);
-        assertTrue(pa1.hashCode() == pa2.hashCode());
+        BeansWrapperBuilder builder1;
+        BeansWrapperBuilder builder2;
+        
+        builder1 = new BeansWrapperBuilder(Configuration.VERSION_2_3_21);
+        builder2 = new BeansWrapperBuilder(Configuration.VERSION_2_3_21);
+        assertEquals(builder1, builder2);
+        
+        builder1.setSimpleMapWrapper(true);
+        assertNotEquals(builder1, builder2);
+        assertNotEquals(builder1.hashCode(), builder2.hashCode());
+        builder2.setSimpleMapWrapper(true);
+        assertEquals(builder1, builder2);
+        assertEquals(builder1.hashCode(), builder2.hashCode());
+        
+        builder1.setExposeFields(true);
+        assertNotEquals(builder1, builder2);
+        assertNotEquals(builder1.hashCode(), builder2.hashCode());
+        builder2.setExposeFields(true);
+        assertEquals(builder1, builder2);
+        assertEquals(builder1.hashCode(), builder2.hashCode());
+        
+        builder1.setExposureLevel(0);
+        assertNotEquals(builder1, builder2);
+        assertNotEquals(builder1.hashCode(), builder2.hashCode());
+        builder2.setExposureLevel(0);
+        assertEquals(builder1, builder2);
+        assertEquals(builder1.hashCode(), builder2.hashCode());
+        
+        builder1.setExposureLevel(1);
+        assertNotEquals(builder1, builder2);
+        assertNotEquals(builder1.hashCode(), builder2.hashCode());
+        builder2.setExposureLevel(1);
+        assertEquals(builder1, builder2);
+        assertEquals(builder1.hashCode(), builder2.hashCode());
+        
+        builder1.setDefaultDateType(TemplateDateModel.DATE);
+        assertNotEquals(builder1, builder2);
+        builder2.setDefaultDateType(TemplateDateModel.DATE);
+        assertEquals(builder1, builder2);
+        assertEquals(builder1.hashCode(), builder2.hashCode());
+        
+        builder1.setStrict(true);
+        assertNotEquals(builder1, builder2);
+        assertNotEquals(builder1.hashCode(), builder2.hashCode());
+        builder2.setStrict(true);
+        assertEquals(builder1, builder2);
+        assertEquals(builder1.hashCode(), builder2.hashCode());
 
-        pa1.setUseModelCache(true);
-        assertNotEquals(pa1, pa2);
-        assertFalse(pa1.hashCode() == pa2.hashCode());
-        pa2.setUseModelCache(true);
-        assertEquals(pa1, pa2);
-        assertTrue(pa1.hashCode() == pa2.hashCode());
+        builder1.setUseModelCache(true);
+        assertNotEquals(builder1, builder2);
+        assertNotEquals(builder1.hashCode(), builder2.hashCode());
+        builder2.setUseModelCache(true);
+        assertEquals(builder1, builder2);
+        assertEquals(builder1.hashCode(), builder2.hashCode());
         
         AlphabeticalMethodSorter ms = new AlphabeticalMethodSorter(true);
-        pa1.setMethodSorter(ms);
-        assertNotEquals(pa1, pa2);
-        pa2.setMethodSorter(ms);
-        assertEquals(pa1, pa2);
-        assertTrue(pa1.hashCode() == pa2.hashCode());
+        builder1.setMethodSorter(ms);
+        assertNotEquals(builder1, builder2);
+        builder2.setMethodSorter(ms);
+        assertEquals(builder1, builder2);
+        assertEquals(builder1.hashCode(), builder2.hashCode());
         
         MethodAppearanceFineTuner maft = new MethodAppearanceFineTuner() {
             public void process(MethodAppearanceDecisionInput in, MethodAppearanceDecision out) { }
         };
-        pa1.setMethodAppearanceFineTuner(maft);
-        assertNotEquals(pa1, pa2);
-        pa2.setMethodAppearanceFineTuner(maft);
-        assertEquals(pa1, pa2);
-        assertTrue(pa1.hashCode() == pa2.hashCode());
+        builder1.setMethodAppearanceFineTuner(maft);
+        assertNotEquals(builder1, builder2);
+        builder2.setMethodAppearanceFineTuner(maft);
+        assertEquals(builder1, builder2);
+        assertEquals(builder1.hashCode(), builder2.hashCode());
+        
+        builder1.setTreatDefaultMethodsAsBeanMembers(true);
+        assertNotEquals(builder1, builder2);
+        assertNotEquals(builder1.hashCode(), builder2.hashCode());
+        builder2.setTreatDefaultMethodsAsBeanMembers(true);
+        assertEquals(builder1, builder2);
+        assertEquals(builder1.hashCode(), builder2.hashCode());
     }
     
     public void testBeansWrapperFactoryProducts() throws Exception {


[14/25] incubator-freemarker git commit: Fixed problem in default method support, where the bridge method and the related reified method appears as overloaded methods with same parameter types, if the reified method comes from a default method, and the b

Posted by dd...@apache.org.
Fixed problem in default method support, where the bridge method and the related reified method appears as overloaded methods with same parameter types, if the reified method comes from a default method, and the bridge method comes from a class.


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

Branch: refs/heads/2.3
Commit: d095f5ae38b0bdefa87a5d732aceb9acb6997581
Parents: cbc4495
Author: ddekany <dd...@apache.org>
Authored: Sun Mar 12 13:42:59 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sun Mar 12 13:42:59 2017 +0100

----------------------------------------------------------------------
 .../freemarker/ext/beans/ClassIntrospector.java | 72 +++++++++++++++-----
 .../beans/BeansWrapperBridgeMethodsTest.java    | 47 +++++++++++++
 .../freemarker/ext/beans/BridgeMethodsBean.java | 12 ++++
 .../ext/beans/BridgeMethodsBeanBase.java        | 11 +++
 .../BridgeMethodsWithDefaultMethodBean.java     | 11 +++
 .../BridgeMethodsWithDefaultMethodBean2.java    |  5 ++
 .../BridgeMethodsWithDefaultMethodBeanBase.java | 13 ++++
 ...BridgeMethodsWithDefaultMethodBeanBase2.java | 10 +++
 8 files changed, 163 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d095f5ae/src/main/java/freemarker/ext/beans/ClassIntrospector.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/ClassIntrospector.java b/src/main/java/freemarker/ext/beans/ClassIntrospector.java
index 8fa0037..911b14d 100644
--- a/src/main/java/freemarker/ext/beans/ClassIntrospector.java
+++ b/src/main/java/freemarker/ext/beans/ClassIntrospector.java
@@ -597,25 +597,47 @@ class ClassIntrospector {
             // java.beans.Introspector was good enough then.
             return introspectionMDs;
         }
-        
-        boolean anyDefaultMethodsAdded = false;
-        findDefaultMethods: for (Method method : clazz.getMethods()) {
-            if (_JavaVersions.JAVA_8.isDefaultMethod(method)) {
-                if (!anyDefaultMethodsAdded) {
-                    for (MethodDescriptor methodDescriptor : introspectionMDs) {
-                        // Check if java.bean.Introspector now finds default methods (it did not in Java 1.8.0_66):
-                        if (_JavaVersions.JAVA_8.isDefaultMethod(methodDescriptor.getMethod())) {
-                            break findDefaultMethods;
-                        }
-                        
-                        // Recreate introspectionMDs so that its size can grow: 
-                        ArrayList<MethodDescriptor> newIntrospectionMDs
-                                = new ArrayList<MethodDescriptor>(introspectionMDs.size() + 16);
-                        newIntrospectionMDs.addAll(introspectionMDs);
-                        introspectionMDs = newIntrospectionMDs;
-                    }
-                    anyDefaultMethodsAdded = true;
+
+        Map<String, List<Method>> defaultMethodsToAddByName = null;
+        for (Method method : clazz.getMethods()) {
+            if (_JavaVersions.JAVA_8.isDefaultMethod(method) && !method.isBridge()) {
+                if (defaultMethodsToAddByName == null) {
+                    defaultMethodsToAddByName = new HashMap<String, List<Method>>();
+                }
+                List<Method> overloads = defaultMethodsToAddByName.get(method.getName());
+                if (overloads == null) {
+                    overloads = new ArrayList<Method>(0);
+                    defaultMethodsToAddByName.put(method.getName(), overloads);
                 }
+                overloads.add(method);
+            }
+        }
+        
+        if (defaultMethodsToAddByName == null) {
+            // We had no interfering default methods:
+            return introspectionMDs;
+        }
+
+        // Recreate introspectionMDs so that its size can grow: 
+        ArrayList<MethodDescriptor> newIntrospectionMDs
+                = new ArrayList<MethodDescriptor>(introspectionMDs.size() + 16);
+        for (MethodDescriptor introspectorMD : introspectionMDs) {
+            Method introspectorM = introspectorMD.getMethod();
+            // Prevent cases where the same method is added with different return types both from the list of default
+            // methods and from the list of Introspector-discovered methods, as that would lead to overloaded method
+            // selection ambiguity later. This is known to happen when the default method in an interface has reified
+            // return type, and then the interface is implemented by a class where the compiler generates an override
+            // for the bridge method only. (Other tricky cases might exist.)
+            if (!containsMethodWithSameParameterTypes(
+                    defaultMethodsToAddByName.get(introspectorM.getName()), introspectorM)) {
+                newIntrospectionMDs.add(introspectorMD);
+            }
+        }
+        introspectionMDs = newIntrospectionMDs;
+        
+        // Add default methods:
+        for (Entry<String, List<Method>> entry : defaultMethodsToAddByName.entrySet()) {
+            for (Method method : entry.getValue()) {
                 introspectionMDs.add(new MethodDescriptor(method));
             }
         }
@@ -623,6 +645,20 @@ class ClassIntrospector {
         return introspectionMDs;
     }
 
+    private boolean containsMethodWithSameParameterTypes(List<Method> overloads, Method m) {
+        if (overloads == null) {
+            return false;
+        }
+        
+        Class<?>[] paramTypes = m.getParameterTypes();
+        for (Method overload : overloads) {
+            if (Arrays.equals(overload.getParameterTypes(), paramTypes)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void addPropertyDescriptorToClassIntrospectionData(Map<Object, Object> introspData,
             PropertyDescriptor pd, Class<?> clazz, Map<MethodSignature, List<Method>> accessibleMethods) {
         if (pd instanceof IndexedPropertyDescriptor) {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d095f5ae/src/test/java/freemarker/ext/beans/BeansWrapperBridgeMethodsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BeansWrapperBridgeMethodsTest.java b/src/test/java/freemarker/ext/beans/BeansWrapperBridgeMethodsTest.java
new file mode 100644
index 0000000..5f73d0e
--- /dev/null
+++ b/src/test/java/freemarker/ext/beans/BeansWrapperBridgeMethodsTest.java
@@ -0,0 +1,47 @@
+package freemarker.ext.beans;
+
+import static org.junit.Assert.*;
+
+import java.util.Collections;
+
+import org.junit.Test;
+
+import freemarker.template.Configuration;
+import freemarker.template.TemplateHashModel;
+import freemarker.template.TemplateMethodModelEx;
+import freemarker.template.TemplateModelException;
+
+public class BeansWrapperBridgeMethodsTest {
+    
+    @Test
+    public void testWithoutDefaultMethod() throws TemplateModelException {
+        test(BridgeMethodsBean.class);
+    }
+
+    @Test
+    public void testWithDefaultMethod() throws TemplateModelException {
+        test(BridgeMethodsWithDefaultMethodBean.class);
+    }
+
+    @Test
+    public void testWithDefaultMethod2() throws TemplateModelException {
+        test(BridgeMethodsWithDefaultMethodBean2.class);
+    }
+
+    private void test(Class<?> pClass) throws TemplateModelException {
+        BeansWrapper ow = new BeansWrapperBuilder(Configuration.VERSION_2_3_26).build();
+        TemplateHashModel wrapped;
+        try {
+            wrapped = (TemplateHashModel) ow.wrap(pClass.newInstance());
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+        
+        TemplateMethodModelEx m1 = (TemplateMethodModelEx) wrapped.get("m1");
+        assertEquals(BridgeMethodsBean.M1_RETURN_VALUE, "" + m1.exec(Collections.emptyList()));
+        
+        TemplateMethodModelEx m2 = (TemplateMethodModelEx) wrapped.get("m2");
+        assertNull(m2.exec(Collections.emptyList()));
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d095f5ae/src/test/java/freemarker/ext/beans/BridgeMethodsBean.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BridgeMethodsBean.java b/src/test/java/freemarker/ext/beans/BridgeMethodsBean.java
new file mode 100644
index 0000000..a32853c
--- /dev/null
+++ b/src/test/java/freemarker/ext/beans/BridgeMethodsBean.java
@@ -0,0 +1,12 @@
+package freemarker.ext.beans;
+
+public class BridgeMethodsBean extends BridgeMethodsBeanBase<String> {
+
+    static final String M1_RETURN_VALUE = "m1ReturnValue"; 
+    
+    @Override
+    public String m1() {
+        return M1_RETURN_VALUE;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d095f5ae/src/test/java/freemarker/ext/beans/BridgeMethodsBeanBase.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BridgeMethodsBeanBase.java b/src/test/java/freemarker/ext/beans/BridgeMethodsBeanBase.java
new file mode 100644
index 0000000..4823400
--- /dev/null
+++ b/src/test/java/freemarker/ext/beans/BridgeMethodsBeanBase.java
@@ -0,0 +1,11 @@
+package freemarker.ext.beans;
+
+public abstract class BridgeMethodsBeanBase<T> {
+
+    public abstract T m1();
+    
+    public T m2() {
+        return null;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d095f5ae/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean.java b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean.java
new file mode 100644
index 0000000..0c18991
--- /dev/null
+++ b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean.java
@@ -0,0 +1,11 @@
+package freemarker.ext.beans;
+
+public class BridgeMethodsWithDefaultMethodBean implements BridgeMethodsWithDefaultMethodBeanBase<String> {
+
+    static final String M1_RETURN_VALUE = "m1ReturnValue"; 
+    
+    public String m1() {
+        return M1_RETURN_VALUE;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d095f5ae/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean2.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean2.java b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean2.java
new file mode 100644
index 0000000..85bc232
--- /dev/null
+++ b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean2.java
@@ -0,0 +1,5 @@
+package freemarker.ext.beans;
+
+public class BridgeMethodsWithDefaultMethodBean2 implements BridgeMethodsWithDefaultMethodBeanBase2 {
+    // All inherited
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d095f5ae/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase.java b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase.java
new file mode 100644
index 0000000..68960de
--- /dev/null
+++ b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase.java
@@ -0,0 +1,13 @@
+package freemarker.ext.beans;
+
+public interface BridgeMethodsWithDefaultMethodBeanBase<T> {
+
+    default T m1() {
+        return null;
+    }
+    
+    default T m2() {
+        return null;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d095f5ae/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase2.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase2.java b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase2.java
new file mode 100644
index 0000000..be46d4f
--- /dev/null
+++ b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase2.java
@@ -0,0 +1,10 @@
+package freemarker.ext.beans;
+
+public interface BridgeMethodsWithDefaultMethodBeanBase2 extends BridgeMethodsWithDefaultMethodBeanBase<String> {
+
+    @Override
+    default String m1() {
+        return BridgeMethodsWithDefaultMethodBean.M1_RETURN_VALUE;
+    }
+    
+}


[07/25] incubator-freemarker git commit: Added support for Java 8 features (not yet utilized)

Posted by dd...@apache.org.
Added support for Java 8 features (not yet utilized)


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

Branch: refs/heads/2.3
Commit: 9df633caaec0a594a4496890c8ae9b7b62778740
Parents: 5ca7e14
Author: ddekany <dd...@apache.org>
Authored: Tue Mar 7 15:11:12 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Tue Mar 7 15:11:12 2017 +0100

----------------------------------------------------------------------
 README                                          |  6 +--
 build.properties.sample                         |  1 +
 build.xml                                       | 33 ++++++++++++--
 src/main/java/freemarker/core/_Java6Impl.java   |  2 +
 src/main/java/freemarker/core/_Java8.java       | 34 +++++++++++++++
 src/main/java/freemarker/core/_Java8Impl.java   | 23 ++++++++++
 .../java/freemarker/core/_JavaVersions.java     | 45 ++++++++++++++++++++
 7 files changed, 137 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9df633ca/README
----------------------------------------------------------------------
diff --git a/README b/README
index 8fa6e07..d5ab3b7 100644
--- a/README
+++ b/README
@@ -167,7 +167,7 @@ apply it to your development environment:
     Number of imports required for .*: 99
     Number of static imports needed for .*: 1
   - Java -> Installed JRE-s:
-    Ensure that you have JDK 6 installed, and that it was added to Eclipse.
+    Ensure that you have JDK 8 installed, and that it was added to Eclipse.
     Note that it's not JRE, but JDK.
   - Java -> Compiler -> Javadoc:
     "Malformed Javadoc comments": Error
@@ -190,7 +190,7 @@ apply it to your development environment:
         src/test/resources
     - On the "Libraries" tab:
       - Delete everyhing from there, except the "JRE System Library [...]"
-      - Edit "JRE System Library [...]" to "Execution Environment" "JavaSE 1.6"
+      - Edit "JRE System Library [...]" to "Execution Environment" "JavaSE 1.8"
       - Add all jar-s that are directly under the "ide-dependencies" directory
         (use the "Add JARs..." and select all those files).
     - On the "Order and Export" tab find dom4j-*.jar, and send it to the
@@ -207,7 +207,7 @@ apply it to your development environment:
 - You will still have errors on these java files (because different java
   files depend on different versions of the same library, and Eclipse can't
   handle that). Exclude those java files from the Build Path (in the Package
-  Explorer, right click on the problematic file -> "Build Path" -> "Exclude").
+  Explorer, right click on the problematic file -> "Build Path" -> "Exclude"):
     _Jython20*.java
     _Jython22*.java
     _FreeMarkerPageContext2.java

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9df633ca/build.properties.sample
----------------------------------------------------------------------
diff --git a/build.properties.sample b/build.properties.sample
index c5dc8ff..56315b3 100644
--- a/build.properties.sample
+++ b/build.properties.sample
@@ -19,5 +19,6 @@
 # These propeties should point to the rt.jar-s of the respective J2SE versions:
 boot.classpath.j2se1.5=C:/Program Files (x86)/Java/jdk1.5.0_16/jre/lib/rt.jar
 boot.classpath.j2se1.6=C:/Program Files/Java/jdk1.6.0_24/jre/lib/rt.jar
+boot.classpath.j2se1.8=C:/Program Files/Java/jdk1.8.0_66/jre/lib/rt.jar
 mvnCommand=C:/Program Files (x86)/maven3/bin/mvn.bat
 gpgCommand=C:/Program Files (x86)/GNU/GnuPG/pub/gpg.exe
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9df633ca/build.xml
----------------------------------------------------------------------
diff --git a/build.xml b/build.xml
index 9b29946..4e1f979 100644
--- a/build.xml
+++ b/build.xml
@@ -49,10 +49,14 @@
   <condition property="has.explicit.boot.classpath.j2se1.6">
     <isset property="boot.classpath.j2se1.6"/>
   </condition>
+  <condition property="has.explicit.boot.classpath.j2se1.8">
+    <isset property="boot.classpath.j2se1.8"/>
+  </condition>
   <condition property="has.all.explicit.boot.classpaths">
     <and>
       <isset property="has.explicit.boot.classpath.j2se1.5"/>
       <isset property="has.explicit.boot.classpath.j2se1.6"/>
+      <isset property="has.explicit.boot.classpath.j2se1.8"/>
     </and>
   </condition>
   <available property="atLeastJDK8" classname="java.util.function.Predicate"/>
@@ -61,6 +65,7 @@
   <!-- Note: Target "dist" doesn't allow using these. -->
   <property name="boot.classpath.j2se1.5" value="${sun.boot.class.path}" />
   <property name="boot.classpath.j2se1.6" value="${sun.boot.class.path}" />
+  <property name="boot.classpath.j2se1.8" value="${sun.boot.class.path}" />
   
   <!-- For checking the correctness of the boot.classpath.j2se* -->
   <available classpath="${boot.classpath.j2se1.5}"
@@ -71,6 +76,10 @@
     classname="java.util.ServiceLoader" ignoresystemclasses="true" 
     property="boot.classpath.j2se1.6.correct"
   />
+  <available classpath="${boot.classpath.j2se1.8}"
+    classname="java.time.Instant" ignoresystemclasses="true" 
+    property="boot.classpath.j2se1.8.correct"
+  />
   
   <!-- Set up version/timestamp filters and the version property: -->
   <tstamp>
@@ -207,10 +216,17 @@
       -->the &lt;projectDir>/build.properties file, or wherever you <!--
       -->set it.<!--
     --></fail>
+    <fail unless="boot.classpath.j2se1.8.correct"><!--
+      -->The "boot.classpath.j2se1.8" property value (${boot.classpath.j2se1.8}) <!--
+      -->seems to be an incorrect boot classpath. Please fix it in <!--
+      -->the &lt;projectDir>/build.properties file, or wherever you <!--
+      -->set it.<!--
+    --></fail>
     <echo level="info"><!--
       -->Using boot classpaths:<!--
       -->Java 5: ${boot.classpath.j2se1.5}; <!--
       -->Java 6: ${boot.classpath.j2se1.6}<!--
+      -->Java 8: ${boot.classpath.j2se1.8}<!--
     --></echo>
 
     <!-- Comment out @SuppressFBWarnings, as it causes compilation warnings in dependent Gradle projects -->    
@@ -242,7 +258,7 @@
       classpathref="ivy.dep"
       bootclasspath="${boot.classpath.j2se1.5}"
       excludes="
-        freemarker/core/_Java6Impl.java,
+        freemarker/core/_Java?*Impl.java,
         freemarker/ext/jsp/**,
         freemarker/ext/servlet/**,
         freemarker/cache/WebappTemplateLoader.java,
@@ -259,12 +275,21 @@
 
     <ivy:cachepath conf="build.base" pathid="ivy.dep" />
     <javac srcdir="build/src-main-java-filtered" destdir="build/classes" deprecation="off" 
-      debug="on" optimize="off" target="1.5" source="1.5" encoding="utf-8"
+      debug="on" optimize="off" target="1.6" source="1.6" encoding="utf-8"
       includeantruntime="false"
       classpathref="ivy.dep"
       bootclasspath="${boot.classpath.j2se1.6}"
       includes="freemarker/core/_Java6Impl.java"
     />
+
+    <ivy:cachepath conf="build.base" pathid="ivy.dep" />
+    <javac srcdir="build/src-main-java-filtered" destdir="build/classes" deprecation="off" 
+      debug="on" optimize="off" target="1.8" source="1.8" encoding="utf-8"
+      includeantruntime="false"
+      classpathref="ivy.dep"
+      bootclasspath="${boot.classpath.j2se1.8}"
+      includes="freemarker/core/_Java8Impl.java"
+    />
     
     <rmic
       base="build/classes" includes="freemarker/debug/impl/Rmi*Impl.class"
@@ -376,11 +401,11 @@
   
     <ivy:cachepath conf="build.test" pathid="ivy.dep.build.test" />
     <javac srcdir="src/test/java" destdir="build/test-classes" deprecation="off" 
-      debug="on" optimize="off" target="1.5" source="1.5" encoding="utf-8"
+      debug="on" optimize="off" target="1.8" source="1.8" encoding="utf-8"
       includeantruntime="false"
       classpath="build/classes"
       classpathref="ivy.dep.build.test"
-      bootclasspath="${boot.classpath.j2se1.6}"
+      bootclasspath="${boot.classpath.j2se1.8}"
     />
     <copy toDir="build/test-classes">
       <fileset dir="src/test/resources"

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9df633ca/src/main/java/freemarker/core/_Java6Impl.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/_Java6Impl.java b/src/main/java/freemarker/core/_Java6Impl.java
index 05c1258..090a58d 100644
--- a/src/main/java/freemarker/core/_Java6Impl.java
+++ b/src/main/java/freemarker/core/_Java6Impl.java
@@ -26,6 +26,8 @@ import java.text.DecimalFormatSymbols;
  * Used internally only, might changes without notice!
  * Used for accessing functionality that's only present in Java 6 or later.
  */
+//Compile this against Java 6
+@SuppressWarnings("Since15") // For IntelliJ inspection   
 public final class _Java6Impl implements _Java6 {
     
     public static final _Java6 INSTANCE = new _Java6Impl();

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9df633ca/src/main/java/freemarker/core/_Java8.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/_Java8.java b/src/main/java/freemarker/core/_Java8.java
new file mode 100644
index 0000000..34979da
--- /dev/null
+++ b/src/main/java/freemarker/core/_Java8.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package freemarker.core;
+
+import java.lang.reflect.Method;
+
+/**
+ * Used internally only, might changes without notice!
+ * Used for accessing functionality that's only present in Java 8 or later.
+ */
+public interface _Java8 {
+
+    /**
+     * Returns if it's a Java 8 "default method".
+     */
+    boolean isDefaultMethod(Method method);
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9df633ca/src/main/java/freemarker/core/_Java8Impl.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/_Java8Impl.java b/src/main/java/freemarker/core/_Java8Impl.java
new file mode 100644
index 0000000..fe9bb07
--- /dev/null
+++ b/src/main/java/freemarker/core/_Java8Impl.java
@@ -0,0 +1,23 @@
+package freemarker.core;
+
+import java.lang.reflect.Method;
+
+/**
+ * Used internally only, might changes without notice!
+ * Used for accessing functionality that's only present in Java 6 or later.
+ */
+// Compile this against Java 8
+@SuppressWarnings("Since15") // For IntelliJ inspection
+public class _Java8Impl implements _Java8 {
+    
+    public static final _Java8 INSTANCE = new _Java8Impl();
+
+    private _Java8Impl() {
+        // Not meant to be instantiated
+    }    
+
+    public boolean isDefaultMethod(Method method) {
+        return method.isDefault();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9df633ca/src/main/java/freemarker/core/_JavaVersions.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/_JavaVersions.java b/src/main/java/freemarker/core/_JavaVersions.java
index 1101752..7e6f1eb 100644
--- a/src/main/java/freemarker/core/_JavaVersions.java
+++ b/src/main/java/freemarker/core/_JavaVersions.java
@@ -74,4 +74,49 @@ public final class _JavaVersions {
         JAVA_6 = java6;
     }
     
+    private static final boolean IS_AT_LEAST_8;
+    static {
+        boolean result = false;
+        String vStr = SecurityUtilities.getSystemProperty("java.version", null);
+        if (vStr != null) {
+            try {
+                Version v = new Version(vStr);
+                result = v.getMajor() == 1 && v.getMinor() >= 8 || v.getMajor() > 1;
+            } catch (Exception e) {
+                // Ignore
+            }
+        } else {
+            try {
+                Class.forName("java.time.Instant");
+                result = true;
+            } catch (Exception e) {
+                // Ignore
+            }
+        }
+        IS_AT_LEAST_8 = result;
+    }
+    
+    /**
+     * {@code null} if Java 8 is not available, otherwise the object through with the Java 8 operations are available.
+     */
+    static public final _Java8 JAVA_8;
+    static {
+        _Java8 java8;
+        if (IS_AT_LEAST_8) {
+            try {
+                java8 = (_Java8) Class.forName("freemarker.core._Java8Impl").getField("INSTANCE").get(null);
+            } catch (Exception e) {
+                try {
+                    Logger.getLogger("freemarker.runtime").error("Failed to access Java 8 functionality", e);
+                } catch (Exception e2) {
+                    // Suppressed
+                }
+                java8 = null;
+            }
+        } else {
+            java8 = null;
+        }
+        JAVA_8 = java8;
+    }
+    
 }


[13/25] incubator-freemarker git commit: Missing/incomplete copyright headers.

Posted by dd...@apache.org.
Missing/incomplete copyright headers.


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

Branch: refs/heads/2.3
Commit: cbc449518039520a07020cd03810ec92256431d0
Parents: 173abfe
Author: ddekany <dd...@apache.org>
Authored: Sat Mar 11 09:13:54 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sat Mar 11 09:13:54 2017 +0100

----------------------------------------------------------------------
 src/main/java/freemarker/core/_Java8Impl.java     | 18 ++++++++++++++++++
 src/main/misc/overloadedNumberRules/config.fmpp   |  9 +++++++++
 .../freemarker/ext/beans/unsafeMethods.properties |  9 +++++++++
 src/main/resources/freemarker/version.properties  |  9 +++++++++
 src/manual/en_US/book.xml                         |  4 ++--
 .../ext/beans/BeansWrapperJava8Test.java          | 18 ++++++++++++++++++
 .../GetPropertyNameFromReaderMethodNameTest.java  | 18 ++++++++++++++++++
 .../ext/beans/Java8DefaultMethodsBean.java        | 18 ++++++++++++++++++
 .../ext/beans/Java8DefaultMethodsBeanBase.java    | 18 ++++++++++++++++++
 .../ConfigureOutputFormatExamples1.properties     |  9 +++++++++
 .../ConfigureOutputFormatExamples2.properties     |  9 +++++++++
 .../TemplateConfigurationExamples1.properties     |  9 +++++++++
 .../TemplateConfigurationExamples2.properties     |  9 +++++++++
 .../TemplateConfigurationExamples3.properties     |  9 +++++++++
 .../models/BeansTestResources.properties          |  9 +++++++++
 15 files changed, 173 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cbc44951/src/main/java/freemarker/core/_Java8Impl.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/_Java8Impl.java b/src/main/java/freemarker/core/_Java8Impl.java
index fe9bb07..40f0910 100644
--- a/src/main/java/freemarker/core/_Java8Impl.java
+++ b/src/main/java/freemarker/core/_Java8Impl.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package freemarker.core;
 
 import java.lang.reflect.Method;

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cbc44951/src/main/misc/overloadedNumberRules/config.fmpp
----------------------------------------------------------------------
diff --git a/src/main/misc/overloadedNumberRules/config.fmpp b/src/main/misc/overloadedNumberRules/config.fmpp
index cf32e92..50aacbb 100644
--- a/src/main/misc/overloadedNumberRules/config.fmpp
+++ b/src/main/misc/overloadedNumberRules/config.fmpp
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 sources: generator.ftl
 outputFile: ../../../../build/overloadedNumberRules.java

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cbc44951/src/main/resources/freemarker/ext/beans/unsafeMethods.properties
----------------------------------------------------------------------
diff --git a/src/main/resources/freemarker/ext/beans/unsafeMethods.properties b/src/main/resources/freemarker/ext/beans/unsafeMethods.properties
index 05c1981..916d2f4 100644
--- a/src/main/resources/freemarker/ext/beans/unsafeMethods.properties
+++ b/src/main/resources/freemarker/ext/beans/unsafeMethods.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 java.lang.Object.wait()
 java.lang.Object.wait(long)

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cbc44951/src/main/resources/freemarker/version.properties
----------------------------------------------------------------------
diff --git a/src/main/resources/freemarker/version.properties b/src/main/resources/freemarker/version.properties
index c9fcce2..05a3ac1 100644
--- a/src/main/resources/freemarker/version.properties
+++ b/src/main/resources/freemarker/version.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 # Version info for the builds.
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cbc44951/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index 3e06a7b..3e0814f 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -7,9 +7,9 @@
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at
-  
+
     http://www.apache.org/licenses/LICENSE-2.0
-  
+
   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cbc44951/src/test/java/freemarker/ext/beans/BeansWrapperJava8Test.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BeansWrapperJava8Test.java b/src/test/java/freemarker/ext/beans/BeansWrapperJava8Test.java
index 4312742..abdb0f5 100644
--- a/src/test/java/freemarker/ext/beans/BeansWrapperJava8Test.java
+++ b/src/test/java/freemarker/ext/beans/BeansWrapperJava8Test.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package freemarker.ext.beans;
 
 import static org.junit.Assert.*;

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cbc44951/src/test/java/freemarker/ext/beans/GetPropertyNameFromReaderMethodNameTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/GetPropertyNameFromReaderMethodNameTest.java b/src/test/java/freemarker/ext/beans/GetPropertyNameFromReaderMethodNameTest.java
index ce95b99..d100b77 100644
--- a/src/test/java/freemarker/ext/beans/GetPropertyNameFromReaderMethodNameTest.java
+++ b/src/test/java/freemarker/ext/beans/GetPropertyNameFromReaderMethodNameTest.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package freemarker.ext.beans;
 
 import static org.junit.Assert.*;

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cbc44951/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBean.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBean.java b/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBean.java
index 0687d84..5161dae 100644
--- a/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBean.java
+++ b/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBean.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package freemarker.ext.beans;
 
 public class Java8DefaultMethodsBean implements Java8DefaultMethodsBeanBase {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cbc44951/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBeanBase.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBeanBase.java b/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBeanBase.java
index c912ace..dd867d4 100644
--- a/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBeanBase.java
+++ b/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBeanBase.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package freemarker.ext.beans;
 
 public interface Java8DefaultMethodsBeanBase {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cbc44951/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples1.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples1.properties b/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples1.properties
index 0df9e33..601ce15 100644
--- a/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples1.properties
+++ b/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples1.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 templateConfigurations = \
     ConditionalTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cbc44951/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples2.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples2.properties b/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples2.properties
index 5d2a738..0179466 100644
--- a/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples2.properties
+++ b/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples2.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 templateConfigurations = \
     FirstMatchTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cbc44951/src/test/resources/freemarker/manual/TemplateConfigurationExamples1.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/TemplateConfigurationExamples1.properties b/src/test/resources/freemarker/manual/TemplateConfigurationExamples1.properties
index cffadfb..24e9747 100644
--- a/src/test/resources/freemarker/manual/TemplateConfigurationExamples1.properties
+++ b/src/test/resources/freemarker/manual/TemplateConfigurationExamples1.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 templateConfigurations = \
     ConditionalTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cbc44951/src/test/resources/freemarker/manual/TemplateConfigurationExamples2.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/TemplateConfigurationExamples2.properties b/src/test/resources/freemarker/manual/TemplateConfigurationExamples2.properties
index f879e70..b5619f0 100644
--- a/src/test/resources/freemarker/manual/TemplateConfigurationExamples2.properties
+++ b/src/test/resources/freemarker/manual/TemplateConfigurationExamples2.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 templateConfigurations = \
     ConditionalTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cbc44951/src/test/resources/freemarker/manual/TemplateConfigurationExamples3.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/TemplateConfigurationExamples3.properties b/src/test/resources/freemarker/manual/TemplateConfigurationExamples3.properties
index cf4c5a4..1cd1b26 100644
--- a/src/test/resources/freemarker/manual/TemplateConfigurationExamples3.properties
+++ b/src/test/resources/freemarker/manual/TemplateConfigurationExamples3.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 templateConfigurations = \
     MergingTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cbc44951/src/test/resources/freemarker/test/templatesuite/models/BeansTestResources.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/test/templatesuite/models/BeansTestResources.properties b/src/test/resources/freemarker/test/templatesuite/models/BeansTestResources.properties
index 609e20b..32190a8 100644
--- a/src/test/resources/freemarker/test/templatesuite/models/BeansTestResources.properties
+++ b/src/test/resources/freemarker/test/templatesuite/models/BeansTestResources.properties
@@ -14,6 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 message=Message
 format={0,date,yyyy-MM-dd}
\ No newline at end of file


[24/25] incubator-freemarker git commit: (Fixed corrupted copyright headers in properties files)

Posted by dd...@apache.org.
(Fixed corrupted copyright headers in properties files)


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

Branch: refs/heads/2.3
Commit: edc0e411fbb04b4118de91cd6fd9a03b5a05e74d
Parents: 78793b2
Author: ddekany <dd...@apache.org>
Authored: Sun Mar 12 18:23:40 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sun Mar 12 18:23:40 2017 +0100

----------------------------------------------------------------------
 src/main/misc/overloadedNumberRules/config.fmpp   | 18 ------------------
 .../freemarker/ext/beans/unsafeMethods.properties | 18 ------------------
 src/main/resources/freemarker/version.properties  | 18 ------------------
 .../ConfigureOutputFormatExamples1.properties     | 18 ------------------
 .../ConfigureOutputFormatExamples2.properties     | 18 ------------------
 .../TemplateConfigurationExamples1.properties     | 18 ------------------
 .../TemplateConfigurationExamples2.properties     | 18 ------------------
 .../TemplateConfigurationExamples3.properties     | 18 ------------------
 .../models/BeansTestResources.properties          | 18 ------------------
 9 files changed, 162 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/edc0e411/src/main/misc/overloadedNumberRules/config.fmpp
----------------------------------------------------------------------
diff --git a/src/main/misc/overloadedNumberRules/config.fmpp b/src/main/misc/overloadedNumberRules/config.fmpp
index f1a34ce..cf32e92 100644
--- a/src/main/misc/overloadedNumberRules/config.fmpp
+++ b/src/main/misc/overloadedNumberRules/config.fmpp
@@ -14,24 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
 
 sources: generator.ftl
 outputFile: ../../../../build/overloadedNumberRules.java

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/edc0e411/src/main/resources/freemarker/ext/beans/unsafeMethods.properties
----------------------------------------------------------------------
diff --git a/src/main/resources/freemarker/ext/beans/unsafeMethods.properties b/src/main/resources/freemarker/ext/beans/unsafeMethods.properties
index ff167fd..05c1981 100644
--- a/src/main/resources/freemarker/ext/beans/unsafeMethods.properties
+++ b/src/main/resources/freemarker/ext/beans/unsafeMethods.properties
@@ -14,24 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
 
 java.lang.Object.wait()
 java.lang.Object.wait(long)

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/edc0e411/src/main/resources/freemarker/version.properties
----------------------------------------------------------------------
diff --git a/src/main/resources/freemarker/version.properties b/src/main/resources/freemarker/version.properties
index adec5f4..c9fcce2 100644
--- a/src/main/resources/freemarker/version.properties
+++ b/src/main/resources/freemarker/version.properties
@@ -14,24 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
 
 # Version info for the builds.
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/edc0e411/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples1.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples1.properties b/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples1.properties
index 5ba46d4..0df9e33 100644
--- a/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples1.properties
+++ b/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples1.properties
@@ -14,24 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
 
 templateConfigurations = \
     ConditionalTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/edc0e411/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples2.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples2.properties b/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples2.properties
index 4415630..5d2a738 100644
--- a/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples2.properties
+++ b/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples2.properties
@@ -14,24 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
 
 templateConfigurations = \
     FirstMatchTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/edc0e411/src/test/resources/freemarker/manual/TemplateConfigurationExamples1.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/TemplateConfigurationExamples1.properties b/src/test/resources/freemarker/manual/TemplateConfigurationExamples1.properties
index 36e1da6..cffadfb 100644
--- a/src/test/resources/freemarker/manual/TemplateConfigurationExamples1.properties
+++ b/src/test/resources/freemarker/manual/TemplateConfigurationExamples1.properties
@@ -14,24 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
 
 templateConfigurations = \
     ConditionalTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/edc0e411/src/test/resources/freemarker/manual/TemplateConfigurationExamples2.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/TemplateConfigurationExamples2.properties b/src/test/resources/freemarker/manual/TemplateConfigurationExamples2.properties
index d54d473..f879e70 100644
--- a/src/test/resources/freemarker/manual/TemplateConfigurationExamples2.properties
+++ b/src/test/resources/freemarker/manual/TemplateConfigurationExamples2.properties
@@ -14,24 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
 
 templateConfigurations = \
     ConditionalTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/edc0e411/src/test/resources/freemarker/manual/TemplateConfigurationExamples3.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/TemplateConfigurationExamples3.properties b/src/test/resources/freemarker/manual/TemplateConfigurationExamples3.properties
index 32aff8c..cf4c5a4 100644
--- a/src/test/resources/freemarker/manual/TemplateConfigurationExamples3.properties
+++ b/src/test/resources/freemarker/manual/TemplateConfigurationExamples3.properties
@@ -14,24 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
 
 templateConfigurations = \
     MergingTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/edc0e411/src/test/resources/freemarker/test/templatesuite/models/BeansTestResources.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/test/templatesuite/models/BeansTestResources.properties b/src/test/resources/freemarker/test/templatesuite/models/BeansTestResources.properties
index 3850ec0..609e20b 100644
--- a/src/test/resources/freemarker/test/templatesuite/models/BeansTestResources.properties
+++ b/src/test/resources/freemarker/test/templatesuite/models/BeansTestResources.properties
@@ -14,24 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
 
 message=Message
 format={0,date,yyyy-MM-dd}
\ No newline at end of file


[17/25] incubator-freemarker git commit: (Test cleanup)

Posted by dd...@apache.org.
(Test cleanup)


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

Branch: refs/heads/2.3
Commit: 593d35d32fec47baa0b7847099300feee8ba6253
Parents: f9204fe
Author: ddekany <dd...@apache.org>
Authored: Sun Mar 12 14:43:43 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sun Mar 12 14:43:43 2017 +0100

----------------------------------------------------------------------
 .../freemarker/ext/beans/BeansWrapperSingletonsTest.java     | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/593d35d3/src/test/java/freemarker/ext/beans/BeansWrapperSingletonsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BeansWrapperSingletonsTest.java b/src/test/java/freemarker/ext/beans/BeansWrapperSingletonsTest.java
index bc3d0eb..3317fe4 100644
--- a/src/test/java/freemarker/ext/beans/BeansWrapperSingletonsTest.java
+++ b/src/test/java/freemarker/ext/beans/BeansWrapperSingletonsTest.java
@@ -55,7 +55,7 @@ public class BeansWrapperSingletonsTest extends TestCase {
         BeansWrapperBuilder.clearInstanceCache();
     }
 
-    public void testBeansWrapperFactoryEquals() throws Exception {
+    public void testBeansWrapperBuilderEquals() throws Exception {
         assertEquals(Configuration.VERSION_2_3_21, new BeansWrapperBuilder(Configuration.VERSION_2_3_21).getIncompatibleImprovements());
         assertEquals(Configuration.VERSION_2_3_0, new BeansWrapperBuilder(Configuration.VERSION_2_3_20).getIncompatibleImprovements());
         try {
@@ -144,7 +144,7 @@ public class BeansWrapperSingletonsTest extends TestCase {
         assertEquals(builder1.hashCode(), builder2.hashCode());
     }
     
-    public void testBeansWrapperFactoryProducts() throws Exception {
+    public void testBeansWrapperBuilderProducts() throws Exception {
         List<BeansWrapper> hardReferences = new LinkedList<BeansWrapper>();
         
         assertEquals(0, getBeansWrapperInstanceCacheSize());
@@ -684,10 +684,6 @@ public class BeansWrapperSingletonsTest extends TestCase {
         assertEquals(expectedSize, getClassIntrospectorInstanceCacheSize());
     }
 
-    private void assertNotEquals(Object o1, Object o2) {
-        assertFalse(o1.equals(o2));
-    }
-    
     public class C {
         
         public String foo = "FOO";


[21/25] incubator-freemarker git commit: Bug fixed: If the incompatible_improvements setting is set to 2.3.26 (or higher), exp?interpret always gets the parser-related settings from the template that it's called from. Earlier, sometimes it got those from

Posted by dd...@apache.org.
Bug fixed: If the incompatible_improvements setting is set to 2.3.26 (or higher), exp?interpret always gets the parser-related settings from the template that it's called from. Earlier, sometimes it got those from the topmost (main) template instead. Similarly, the generated name of the template that ?interpret creates will always refer to the template where's it's called from.


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

Branch: refs/heads/2.3
Commit: a863373968a348d2f83872e1637b8c6499bfba50
Parents: 696ca6b
Author: ddekany <dd...@apache.org>
Authored: Sun Mar 12 17:53:48 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sun Mar 12 17:53:48 2017 +0100

----------------------------------------------------------------------
 src/main/java/freemarker/core/Interpret.java       |  4 +++-
 src/manual/en_US/book.xml                          | 13 +++++++++++++
 .../core/InterpretAndEvalTemplateNameTest.java     | 17 +++++++++++++++--
 3 files changed, 31 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a8633739/src/main/java/freemarker/core/Interpret.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Interpret.java b/src/main/java/freemarker/core/Interpret.java
index 818e7a9..a2cff1c 100644
--- a/src/main/java/freemarker/core/Interpret.java
+++ b/src/main/java/freemarker/core/Interpret.java
@@ -31,6 +31,7 @@ import freemarker.template.TemplateModelException;
 import freemarker.template.TemplateScalarModel;
 import freemarker.template.TemplateSequenceModel;
 import freemarker.template.TemplateTransformModel;
+import freemarker.template._TemplateAPI;
 
 
 /**
@@ -79,7 +80,8 @@ class Interpret extends OutputFormatBoundBuiltIn {
                     env);
         }
         String templateSource = sourceExpr.evalAndCoerceToPlainText(env);
-        Template parentTemplate = env.getTemplate();
+        Template parentTemplate = env.getConfiguration().getIncompatibleImprovements().intValue()
+                >= _TemplateAPI.VERSION_INT_2_3_26 ? env.getCurrentTemplate() : env.getTemplate();
         
         final Template interpretedTemplate;
         try {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a8633739/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index c9248de..741c1a0 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -26895,6 +26895,19 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
             </listitem>
 
             <listitem>
+              <para>Bug fixed: If <link
+              linkend="pgui_config_incompatible_improvements_how_to_set">the
+              <literal>incompatible_improvements</literal> setting</link> is
+              set to 2.3.26 (or higher),
+              <literal><replaceable>exp</replaceable>?interpret</literal>
+              always gets the parser-related settings from the template that
+              it's called from. Earlier, sometimes it got those from the
+              topmost (main) template instead. Similarly, the generated name
+              of the template that <literal>?interpret</literal> creates will
+              always refer to the template where's it's called from.</para>
+            </listitem>
+
+            <listitem>
               <para>Bug fixed: <literal>MultiTemplateLoader</literal>, when
               it's in sticky mode (the default), and the
               <literal>TemplateLoader</literal> that was successfully used for

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a8633739/src/test/java/freemarker/core/InterpretAndEvalTemplateNameTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/InterpretAndEvalTemplateNameTest.java b/src/test/java/freemarker/core/InterpretAndEvalTemplateNameTest.java
index 6f18c37..7652871 100644
--- a/src/test/java/freemarker/core/InterpretAndEvalTemplateNameTest.java
+++ b/src/test/java/freemarker/core/InterpretAndEvalTemplateNameTest.java
@@ -23,7 +23,9 @@ import java.io.IOException;
 import org.junit.Test;
 
 import freemarker.cache.StringTemplateLoader;
+import freemarker.template.Configuration;
 import freemarker.template.TemplateException;
+import freemarker.template.Version;
 import freemarker.test.TemplateTest;
 
 /**
@@ -31,9 +33,20 @@ import freemarker.test.TemplateTest;
  * {@code ?eval}-ed parts.  
  */
 public class InterpretAndEvalTemplateNameTest extends TemplateTest {
-    
+
     @Test
-    public void testInterpret() throws IOException, TemplateException {
+    public void testInterpret230() throws IOException, TemplateException {
+        testInterpret(Configuration.VERSION_2_3_0);
+    }
+
+    @Test
+    public void testInterpret2326() throws IOException, TemplateException {
+        testInterpret(Configuration.VERSION_2_3_26);
+    }
+    
+    private void testInterpret(Version version) throws IOException, TemplateException {
+        getConfiguration().setIncompatibleImprovements(version);
+        
         for (String getTemplateNames : new String[] {
                 "c=${.current_template_name}, m=${.main_template_name}",
                 "c=${\".current_template_name\"?eval}, m=${\".main_template_name\"?eval}"


[09/25] incubator-freemarker git commit: Manual: freemarker.template.DefaultNonListCollectionAdapter class is not experimental anymore, so now it has backward compatibility guarantees.

Posted by dd...@apache.org.
Manual: freemarker.template.DefaultNonListCollectionAdapter class is not experimental anymore, so now it has backward compatibility guarantees.


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

Branch: refs/heads/2.3
Commit: c56467cbd7bdc1dbe263e3b95b70c25752880b76
Parents: 655331d
Author: ddekany <dd...@apache.org>
Authored: Tue Mar 7 15:14:38 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Tue Mar 7 15:14:38 2017 +0100

----------------------------------------------------------------------
 src/manual/en_US/book.xml | 6 ++++++
 1 file changed, 6 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/c56467cb/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index 2486c6f..1b2e8de 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -26937,6 +26937,12 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
             </listitem>
 
             <listitem>
+              <para><literal>freemarker.template.DefaultNonListCollectionAdapter</literal>
+              class is not experimental anymore, so now it has backward
+              compatibility guarantees.</para>
+            </listitem>
+
+            <listitem>
               <para>Various smaller code cleanups.</para>
             </listitem>
           </itemizedlist>


[22/25] incubator-freemarker git commit: (Copyright headers)

Posted by dd...@apache.org.
(Copyright headers)


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

Branch: refs/heads/2.3
Commit: 0c518cd151149efb63e92a061a0faf61d1186ce1
Parents: a863373
Author: ddekany <dd...@apache.org>
Authored: Sun Mar 12 17:55:33 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sun Mar 12 17:55:33 2017 +0100

----------------------------------------------------------------------
 .../template/DefaultEnumerationAdapter.java       | 18 ++++++++++++++++++
 src/main/misc/overloadedNumberRules/config.fmpp   |  9 +++++++++
 .../freemarker/ext/beans/unsafeMethods.properties |  9 +++++++++
 src/main/resources/freemarker/version.properties  |  9 +++++++++
 src/manual/en_US/book.xml                         |  4 ++--
 .../ext/beans/BeansWrapperBridgeMethodsTest.java  | 18 ++++++++++++++++++
 .../freemarker/ext/beans/BridgeMethodsBean.java   | 18 ++++++++++++++++++
 .../ext/beans/BridgeMethodsBeanBase.java          | 18 ++++++++++++++++++
 .../beans/BridgeMethodsWithDefaultMethodBean.java | 18 ++++++++++++++++++
 .../BridgeMethodsWithDefaultMethodBean2.java      | 18 ++++++++++++++++++
 .../BridgeMethodsWithDefaultMethodBeanBase.java   | 18 ++++++++++++++++++
 .../BridgeMethodsWithDefaultMethodBeanBase2.java  | 18 ++++++++++++++++++
 .../ConfigureOutputFormatExamples1.properties     |  9 +++++++++
 .../ConfigureOutputFormatExamples2.properties     |  9 +++++++++
 .../TemplateConfigurationExamples1.properties     |  9 +++++++++
 .../TemplateConfigurationExamples2.properties     |  9 +++++++++
 .../TemplateConfigurationExamples3.properties     |  9 +++++++++
 .../models/BeansTestResources.properties          |  9 +++++++++
 18 files changed, 227 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/main/java/freemarker/template/DefaultEnumerationAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/DefaultEnumerationAdapter.java b/src/main/java/freemarker/template/DefaultEnumerationAdapter.java
index 74a58d4..59549b4 100644
--- a/src/main/java/freemarker/template/DefaultEnumerationAdapter.java
+++ b/src/main/java/freemarker/template/DefaultEnumerationAdapter.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package freemarker.template;
 
 import java.io.Serializable;

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/main/misc/overloadedNumberRules/config.fmpp
----------------------------------------------------------------------
diff --git a/src/main/misc/overloadedNumberRules/config.fmpp b/src/main/misc/overloadedNumberRules/config.fmpp
index 50aacbb..f1a34ce 100644
--- a/src/main/misc/overloadedNumberRules/config.fmpp
+++ b/src/main/misc/overloadedNumberRules/config.fmpp
@@ -23,6 +23,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 sources: generator.ftl
 outputFile: ../../../../build/overloadedNumberRules.java

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/main/resources/freemarker/ext/beans/unsafeMethods.properties
----------------------------------------------------------------------
diff --git a/src/main/resources/freemarker/ext/beans/unsafeMethods.properties b/src/main/resources/freemarker/ext/beans/unsafeMethods.properties
index 916d2f4..ff167fd 100644
--- a/src/main/resources/freemarker/ext/beans/unsafeMethods.properties
+++ b/src/main/resources/freemarker/ext/beans/unsafeMethods.properties
@@ -23,6 +23,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 java.lang.Object.wait()
 java.lang.Object.wait(long)

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/main/resources/freemarker/version.properties
----------------------------------------------------------------------
diff --git a/src/main/resources/freemarker/version.properties b/src/main/resources/freemarker/version.properties
index 05a3ac1..adec5f4 100644
--- a/src/main/resources/freemarker/version.properties
+++ b/src/main/resources/freemarker/version.properties
@@ -23,6 +23,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 # Version info for the builds.
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index 741c1a0..7ba4089 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -7,9 +7,9 @@
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at
-  
+
     http://www.apache.org/licenses/LICENSE-2.0
-  
+
   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/test/java/freemarker/ext/beans/BeansWrapperBridgeMethodsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BeansWrapperBridgeMethodsTest.java b/src/test/java/freemarker/ext/beans/BeansWrapperBridgeMethodsTest.java
index 5f73d0e..634fae4 100644
--- a/src/test/java/freemarker/ext/beans/BeansWrapperBridgeMethodsTest.java
+++ b/src/test/java/freemarker/ext/beans/BeansWrapperBridgeMethodsTest.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package freemarker.ext.beans;
 
 import static org.junit.Assert.*;

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/test/java/freemarker/ext/beans/BridgeMethodsBean.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BridgeMethodsBean.java b/src/test/java/freemarker/ext/beans/BridgeMethodsBean.java
index a32853c..f0cc4ee 100644
--- a/src/test/java/freemarker/ext/beans/BridgeMethodsBean.java
+++ b/src/test/java/freemarker/ext/beans/BridgeMethodsBean.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package freemarker.ext.beans;
 
 public class BridgeMethodsBean extends BridgeMethodsBeanBase<String> {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/test/java/freemarker/ext/beans/BridgeMethodsBeanBase.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BridgeMethodsBeanBase.java b/src/test/java/freemarker/ext/beans/BridgeMethodsBeanBase.java
index 4823400..0dc6d5a 100644
--- a/src/test/java/freemarker/ext/beans/BridgeMethodsBeanBase.java
+++ b/src/test/java/freemarker/ext/beans/BridgeMethodsBeanBase.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package freemarker.ext.beans;
 
 public abstract class BridgeMethodsBeanBase<T> {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean.java b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean.java
index 0c18991..25b67fe 100644
--- a/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean.java
+++ b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package freemarker.ext.beans;
 
 public class BridgeMethodsWithDefaultMethodBean implements BridgeMethodsWithDefaultMethodBeanBase<String> {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean2.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean2.java b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean2.java
index 85bc232..a2261c9 100644
--- a/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean2.java
+++ b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBean2.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package freemarker.ext.beans;
 
 public class BridgeMethodsWithDefaultMethodBean2 implements BridgeMethodsWithDefaultMethodBeanBase2 {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase.java b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase.java
index 68960de..2dbd459 100644
--- a/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase.java
+++ b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package freemarker.ext.beans;
 
 public interface BridgeMethodsWithDefaultMethodBeanBase<T> {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase2.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase2.java b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase2.java
index be46d4f..2886d8f 100644
--- a/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase2.java
+++ b/src/test/java/freemarker/ext/beans/BridgeMethodsWithDefaultMethodBeanBase2.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package freemarker.ext.beans;
 
 public interface BridgeMethodsWithDefaultMethodBeanBase2 extends BridgeMethodsWithDefaultMethodBeanBase<String> {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples1.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples1.properties b/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples1.properties
index 601ce15..5ba46d4 100644
--- a/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples1.properties
+++ b/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples1.properties
@@ -23,6 +23,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 templateConfigurations = \
     ConditionalTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples2.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples2.properties b/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples2.properties
index 0179466..4415630 100644
--- a/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples2.properties
+++ b/src/test/resources/freemarker/manual/ConfigureOutputFormatExamples2.properties
@@ -23,6 +23,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 templateConfigurations = \
     FirstMatchTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/test/resources/freemarker/manual/TemplateConfigurationExamples1.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/TemplateConfigurationExamples1.properties b/src/test/resources/freemarker/manual/TemplateConfigurationExamples1.properties
index 24e9747..36e1da6 100644
--- a/src/test/resources/freemarker/manual/TemplateConfigurationExamples1.properties
+++ b/src/test/resources/freemarker/manual/TemplateConfigurationExamples1.properties
@@ -23,6 +23,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 templateConfigurations = \
     ConditionalTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/test/resources/freemarker/manual/TemplateConfigurationExamples2.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/TemplateConfigurationExamples2.properties b/src/test/resources/freemarker/manual/TemplateConfigurationExamples2.properties
index b5619f0..d54d473 100644
--- a/src/test/resources/freemarker/manual/TemplateConfigurationExamples2.properties
+++ b/src/test/resources/freemarker/manual/TemplateConfigurationExamples2.properties
@@ -23,6 +23,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 templateConfigurations = \
     ConditionalTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/test/resources/freemarker/manual/TemplateConfigurationExamples3.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/TemplateConfigurationExamples3.properties b/src/test/resources/freemarker/manual/TemplateConfigurationExamples3.properties
index 1cd1b26..32aff8c 100644
--- a/src/test/resources/freemarker/manual/TemplateConfigurationExamples3.properties
+++ b/src/test/resources/freemarker/manual/TemplateConfigurationExamples3.properties
@@ -23,6 +23,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 templateConfigurations = \
     MergingTemplateConfigurationFactory( \

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c518cd1/src/test/resources/freemarker/test/templatesuite/models/BeansTestResources.properties
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/test/templatesuite/models/BeansTestResources.properties b/src/test/resources/freemarker/test/templatesuite/models/BeansTestResources.properties
index 32190a8..3850ec0 100644
--- a/src/test/resources/freemarker/test/templatesuite/models/BeansTestResources.properties
+++ b/src/test/resources/freemarker/test/templatesuite/models/BeansTestResources.properties
@@ -23,6 +23,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
 message=Message
 format={0,date,yyyy-MM-dd}
\ No newline at end of file


[19/25] incubator-freemarker git commit: DefaultIteratorAdapter now supports ?api. It was an oversight that it didn't. Also, added ?api support to the recently added DefaultEnumerationAdapter too.

Posted by dd...@apache.org.
DefaultIteratorAdapter now supports ?api. It was an oversight that it didn't. Also, added ?api support to the recently added DefaultEnumerationAdapter too.


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

Branch: refs/heads/2.3
Commit: da310dd91bd1d99f1553b04ac2f6934e68ab1994
Parents: 544e910
Author: ddekany <dd...@apache.org>
Authored: Sun Mar 12 16:02:37 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sun Mar 12 16:02:37 2017 +0100

----------------------------------------------------------------------
 .../template/DefaultEnumerationAdapter.java     |  7 +++-
 .../template/DefaultIteratorAdapter.java        |  7 +++-
 src/manual/en_US/book.xml                       | 41 +++++++++++---------
 .../template/DefaultObjectWrapperTest.java      | 15 +++++++
 4 files changed, 50 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/da310dd9/src/main/java/freemarker/template/DefaultEnumerationAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/DefaultEnumerationAdapter.java b/src/main/java/freemarker/template/DefaultEnumerationAdapter.java
index 570e0e8..74a58d4 100644
--- a/src/main/java/freemarker/template/DefaultEnumerationAdapter.java
+++ b/src/main/java/freemarker/template/DefaultEnumerationAdapter.java
@@ -6,6 +6,7 @@ import java.util.Iterator;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import freemarker.ext.util.WrapperTemplateModel;
+import freemarker.template.utility.ObjectWrapperWithAPISupport;
 
 /**
  * Adapts an {@link Enumeration} to the corresponding {@link TemplateModel} interface(s), most importantly to
@@ -16,7 +17,7 @@ import freemarker.ext.util.WrapperTemplateModel;
  */
 @SuppressWarnings("serial")
 public class DefaultEnumerationAdapter extends WrappingTemplateModel implements TemplateCollectionModel,
-        AdapterTemplateModel, WrapperTemplateModel, Serializable {
+        AdapterTemplateModel, WrapperTemplateModel, TemplateModelWithAPISupport, Serializable {
 
     @SuppressFBWarnings(value="SE_BAD_FIELD", justification="We hope it's Seralizable")
     private final Enumeration<?> enumeration;
@@ -52,6 +53,10 @@ public class DefaultEnumerationAdapter extends WrappingTemplateModel implements
         return new SimpleTemplateModelIterator();
     }
 
+    public TemplateModel getAPI() throws TemplateModelException {
+        return ((ObjectWrapperWithAPISupport) getObjectWrapper()).wrapAsAPI(enumeration);
+    }
+    
     /**
      * Not thread-safe.
      */

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/da310dd9/src/main/java/freemarker/template/DefaultIteratorAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/DefaultIteratorAdapter.java b/src/main/java/freemarker/template/DefaultIteratorAdapter.java
index 4ac1212..150e51f 100644
--- a/src/main/java/freemarker/template/DefaultIteratorAdapter.java
+++ b/src/main/java/freemarker/template/DefaultIteratorAdapter.java
@@ -24,6 +24,7 @@ import java.util.Iterator;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import freemarker.ext.util.WrapperTemplateModel;
+import freemarker.template.utility.ObjectWrapperWithAPISupport;
 
 /**
  * Adapts an {@link Iterator} to the corresponding {@link TemplateModel} interface(s), most importantly to
@@ -43,7 +44,7 @@ import freemarker.ext.util.WrapperTemplateModel;
  * @since 2.3.22
  */
 public class DefaultIteratorAdapter extends WrappingTemplateModel implements TemplateCollectionModel,
-        AdapterTemplateModel, WrapperTemplateModel, Serializable {
+        AdapterTemplateModel, WrapperTemplateModel, TemplateModelWithAPISupport, Serializable {
 
     @SuppressFBWarnings(value="SE_BAD_FIELD", justification="We hope it's Seralizable")
     private final Iterator iterator;
@@ -76,6 +77,10 @@ public class DefaultIteratorAdapter extends WrappingTemplateModel implements Tem
         return new SimpleTemplateModelIterator();
     }
 
+    public TemplateModel getAPI() throws TemplateModelException {
+        return ((ObjectWrapperWithAPISupport) getObjectWrapper()).wrapAsAPI(iterator);
+    }
+    
     /**
      * Not thread-safe.
      */

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/da310dd9/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index beee581..c98b35e 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -26887,24 +26887,6 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
             </listitem>
 
             <listitem>
-              <para><literal>DefaultObjectWrapper</literal>, only with its
-              <literal>incompatible_improvements</literal> set to 2.3.26
-              (<link linkend="topic.defaultObjectWrapperIcI">see how
-              here...</link>), wraps
-              <literal>java.util.Enumeration</literal>-s into
-              <literal>freemarker.template.DefaultEnumerationAdapter</literal>
-              (a new class) instead of into
-              <literal>freemarker.ext.beans.EnumerationModel</literal> (as far
-              as <literal>useAdaptersForContainers</literal> is
-              <literal>true</literal>, which is the default). This adapter is
-              cleaner than <literal>EnumerationModel</literal> as it only
-              implements the minimally required FTL type, which avoids some
-              ambiguous situations. (Note that Java API methods aren't exposed
-              anymore as subvariables; if you really need them, you can use
-              <literal>?api</literal>).</para>
-            </listitem>
-
-            <listitem>
               <para>Better error messages when someone tries to get an invalid
               <literal>@@<replaceable>...</replaceable></literal> subvariable
               of an XML DOM node. (Now it's not issued by the XPath
@@ -26959,6 +26941,29 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
             </listitem>
 
             <listitem>
+              <para><literal>DefaultObjectWrapper</literal>, only with its
+              <literal>incompatible_improvements</literal> set to 2.3.26
+              (<link linkend="topic.defaultObjectWrapperIcI">see how
+              here...</link>), wraps
+              <literal>java.util.Enumeration</literal>-s into
+              <literal>freemarker.template.DefaultEnumerationAdapter</literal>
+              (a new class) instead of into
+              <literal>freemarker.ext.beans.EnumerationModel</literal> (as far
+              as <literal>useAdaptersForContainers</literal> is
+              <literal>true</literal>, which is the default). This adapter is
+              cleaner than <literal>EnumerationModel</literal> as it only
+              implements the minimally required FTL type, which avoids some
+              ambiguous situations. (Note that Java API methods aren't exposed
+              anymore as subvariables; if you really need them, you can use
+              <literal>?api</literal>).</para>
+            </listitem>
+
+            <listitem>
+              <para><literal>DefaultIteratorAdapter</literal> now support
+              <literal>?api</literal>.</para>
+            </listitem>
+
+            <listitem>
               <para><literal>Configuration.setSetting(String,
               String)</literal> and <literal>setSettings</literal> now allows
               <literal>null</literal> value for

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/da310dd9/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/template/DefaultObjectWrapperTest.java b/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
index 4be352a..dcbc659 100644
--- a/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
+++ b/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
@@ -869,6 +869,17 @@ public class DefaultObjectWrapperTest {
         }
     }
     
+    @Test
+    public void testIteratorApiSupport() throws TemplateModelException {
+        TemplateModel wrappedIterator = OW22.wrap(Collections.emptyIterator());
+        assertThat(wrappedIterator, instanceOf(DefaultIteratorAdapter.class));
+        DefaultIteratorAdapter iteratorAdapter = (DefaultIteratorAdapter) wrappedIterator;
+        
+        TemplateHashModel api = (TemplateHashModel) iteratorAdapter.getAPI();
+        assertFalse(((TemplateBooleanModel) ((TemplateMethodModelEx)
+                api.get("hasNext")).exec(Collections.emptyList())).getAsBoolean());
+    }
+    
     @SuppressWarnings("boxing")
     @Test
     public void testCharKeyFallback() throws TemplateModelException {
@@ -982,6 +993,10 @@ public class DefaultObjectWrapperTest {
          } catch (TemplateException e) {
              assertThat(e.getMessage(), containsStringIgnoringCase("only once"));
          }
+         
+         TemplateHashModel api = (TemplateHashModel) enumAdapter.getAPI();
+         assertFalse(((TemplateBooleanModel) ((TemplateMethodModelEx)
+                 api.get("hasMoreElements")).exec(Collections.emptyList())).getAsBoolean());
     }
     
     @Test


[06/25] incubator-freemarker git commit: (Removed unused test file)

Posted by dd...@apache.org.
(Removed unused test file)


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

Branch: refs/heads/2.3
Commit: 5ca7e14ab75951ac9ffd6a47849d65ceb9758a2f
Parents: b13a876
Author: ddekany <dd...@apache.org>
Authored: Fri Mar 3 22:36:30 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Fri Mar 3 22:36:30 2017 +0100

----------------------------------------------------------------------
 .../test/templatesuite/templates/exthash.ftl    | 48 --------------------
 1 file changed, 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/5ca7e14a/src/test/resources/freemarker/test/templatesuite/templates/exthash.ftl
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/test/templatesuite/templates/exthash.ftl b/src/test/resources/freemarker/test/templatesuite/templates/exthash.ftl
deleted file mode 100644
index 24ba759..0000000
--- a/src/test/resources/freemarker/test/templatesuite/templates/exthash.ftl
+++ /dev/null
@@ -1,48 +0,0 @@
-<#--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<html>
-<head>
-<title>FreeMarker: Extended Hash Test</title>
-</head>
-<body>
-
-<p>A simple test follows:</p>
-
-<p>${message}</p>
-
-<p>A hash set of ${animals?size} animals follows:</p>
-<assign animalKeys = animals?keys>
-<p><foreach animal in animalKeys>
-  ${animal}<if animal_has_next>, <else>.</if>
-</foreach></p>
-
-<p>The first animal is an ${animalKeys?first}, and the last is a 
-${animalKeys?last}.</p>
-
-<p>A hash set of ${animals?size} digits follows:<p>
-<assign animalValues = animals._values>
-<p><foreach number in animalValues>
-  ${number}<if number_has_next>, <else>.</if>
-</foreach></p>
-
-<p>The zebra number is ${animals.zebra}.</p>
-
-<p>The end.</p>
-</body>
-</html>


[10/25] incubator-freemarker git commit: (Fixed tests broke after the TemplateCollectionModelEx.contains(TemplateModel) method was removed.

Posted by dd...@apache.org.
(Fixed tests broke after the TemplateCollectionModelEx.contains(TemplateModel) method was removed.


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

Branch: refs/heads/2.3
Commit: 7180eedb49cb8336ac85fea808d0abb7b53d598b
Parents: c56467c
Author: ddekany <dd...@apache.org>
Authored: Tue Mar 7 15:16:01 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Tue Mar 7 15:16:01 2017 +0100

----------------------------------------------------------------------
 .../template/DefaultObjectWrapperTest.java       | 19 -------------------
 1 file changed, 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7180eedb/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/template/DefaultObjectWrapperTest.java b/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
index 28dcb7c..36c12fd 100644
--- a/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
+++ b/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
@@ -732,18 +732,6 @@ public class DefaultObjectWrapperTest {
             assertFalse(coll.isEmpty());
             assertCollectionTMEquals(coll, "a", "b", "c");
 
-            assertTrue(coll.contains(OW22CA.wrap("a")));
-            assertTrue(coll.contains(OW22CA.wrap("b")));
-            assertTrue(coll.contains(OW22CA.wrap("c")));
-            assertTrue(coll.contains(OW22CA.wrap("c")));
-            assertFalse(coll.contains(OW22CA.wrap("d")));
-            try {
-                assertFalse(coll.contains(OW22CA.wrap(1)));
-                fail();
-            } catch (TemplateModelException e) {
-                assertThat(e.getMessage(), containsString("Integer"));
-            }
-
             assertRoundtrip(OW22CA, set, DefaultNonListCollectionAdapter.class, TreeSet.class, "[a, b, c]");
             
             assertSizeThroughAPIModel(3, coll);
@@ -764,13 +752,6 @@ public class DefaultObjectWrapperTest {
             assertTrue(obj1 != null && obj1.equals(list) || obj2 != null && obj2.equals(list));
             assertTrue(tm1 instanceof DefaultListAdapter || tm2 instanceof DefaultListAdapter);
 
-            List similarList = new ArrayList();
-            similarList.add("b");
-            assertTrue(coll.contains(OW22CA.wrap(similarList)));
-            assertTrue(coll.contains(OW22CA.wrap(null)));
-            assertFalse(coll.contains(OW22CA.wrap("a")));
-            assertFalse(coll.contains(OW22CA.wrap(1)));
-
             assertRoundtrip(OW22CA, set, DefaultNonListCollectionAdapter.class, HashSet.class, "[" + obj1 + ", "
                     + obj2 + "]");
         }


[08/25] incubator-freemarker git commit: The freemarker.template.TemplateCollectionModelEx interface and is not experimental anymore, so now it has backward compatibility guarantees. Note that the TemplateCollectionModelEx.contains(TemplateModel) method

Posted by dd...@apache.org.
The freemarker.template.TemplateCollectionModelEx interface and is not experimental anymore, so now it has backward compatibility guarantees. Note that the TemplateCollectionModelEx.contains(TemplateModel) method was removed from it.


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

Branch: refs/heads/2.3
Commit: 655331d9eed2b5dd18f062c84b37130fe4a70a8d
Parents: 9df633c
Author: ddekany <dd...@apache.org>
Authored: Tue Mar 7 15:13:12 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Tue Mar 7 15:13:12 2017 +0100

----------------------------------------------------------------------
 .../java/freemarker/template/TemplateCollectionModelEx.java | 8 --------
 src/manual/en_US/book.xml                                   | 9 +++++++++
 2 files changed, 9 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/655331d9/src/main/java/freemarker/template/TemplateCollectionModelEx.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/TemplateCollectionModelEx.java b/src/main/java/freemarker/template/TemplateCollectionModelEx.java
index 356644e..266c209 100644
--- a/src/main/java/freemarker/template/TemplateCollectionModelEx.java
+++ b/src/main/java/freemarker/template/TemplateCollectionModelEx.java
@@ -42,12 +42,4 @@ public interface TemplateCollectionModelEx extends TemplateCollectionModel {
      */
     boolean isEmpty() throws TemplateModelException;
 
-    /**
-     * Tells if a given value occurs in the collection, according the rules of the wrapped collection. As of 2.3.22,
-     * this interface is not yet utilized by FTL, and certainly it won't be earlier than 2.4.0. The usefulness of this
-     * method is questionable, as the equality rules of Java differs from that of FTL, hence, calling this won't be
-     * equivalent with {@code ?seq_contains(e)}.
-     */
-    boolean contains(TemplateModel item) throws TemplateModelException;
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/655331d9/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index 48b754e..2486c6f 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -26928,6 +26928,15 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
             </listitem>
 
             <listitem>
+              <para>The
+              <literal>freemarker.template.TemplateCollectionModelEx</literal>
+              interface and is not experimental anymore, so now it has
+              backward compatibility guarantees. Note that the
+              <literal>TemplateCollectionModelEx.contains(TemplateModel)</literal>
+              method was removed from it.</para>
+            </listitem>
+
+            <listitem>
               <para>Various smaller code cleanups.</para>
             </listitem>
           </itemizedlist>


[04/25] incubator-freemarker git commit: (Minor code cleanup)

Posted by dd...@apache.org.
(Minor code cleanup)


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

Branch: refs/heads/2.3
Commit: df03e037cb6780a3c6919d08203c390f3f1a1817
Parents: 9f1fea3
Author: ddekany <dd...@apache.org>
Authored: Fri Mar 3 11:35:33 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Fri Mar 3 11:35:33 2017 +0100

----------------------------------------------------------------------
 src/main/java/freemarker/ext/dom/NodeListModel.java | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/df03e037/src/main/java/freemarker/ext/dom/NodeListModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/dom/NodeListModel.java b/src/main/java/freemarker/ext/dom/NodeListModel.java
index a18b4bc..a6a7534 100644
--- a/src/main/java/freemarker/ext/dom/NodeListModel.java
+++ b/src/main/java/freemarker/ext/dom/NodeListModel.java
@@ -57,7 +57,7 @@ class NodeListModel extends SimpleSequence implements TemplateHashModel, _Unexpe
     NodeModel contextNode;
     XPathSupport xpathSupport;
     
-    private static ObjectWrapper nodeWrapper = new ObjectWrapper() {
+    private static final ObjectWrapper NODE_WRAPPER = new ObjectWrapper() {
         public TemplateModel wrap(Object obj) {
             if (obj instanceof NodeModel) {
                 return (NodeModel) obj;
@@ -71,12 +71,12 @@ class NodeListModel extends SimpleSequence implements TemplateHashModel, _Unexpe
     }
     
     NodeListModel(NodeModel contextNode) {
-        super(nodeWrapper);
+        super(NODE_WRAPPER);
         this.contextNode = contextNode;
     }
     
     NodeListModel(NodeList nodeList, NodeModel contextNode) {
-        super(nodeWrapper);
+        super(NODE_WRAPPER);
         for (int i = 0; i < nodeList.getLength(); i++) {
             list.add(nodeList.item(i));
         }
@@ -84,7 +84,7 @@ class NodeListModel extends SimpleSequence implements TemplateHashModel, _Unexpe
     }
     
     NodeListModel(NamedNodeMap nodeList, NodeModel contextNode) {
-        super(nodeWrapper);
+        super(NODE_WRAPPER);
         for (int i = 0; i < nodeList.getLength(); i++) {
             list.add(nodeList.item(i));
         }
@@ -92,7 +92,7 @@ class NodeListModel extends SimpleSequence implements TemplateHashModel, _Unexpe
     }
     
     NodeListModel(List list, NodeModel contextNode) {
-        super(list, nodeWrapper);
+        super(list, NODE_WRAPPER);
         this.contextNode = contextNode;
     }
     


[23/25] incubator-freemarker git commit: (Fixed auto-import and auto-includes merging... though in practice this bug had no effect.)

Posted by dd...@apache.org.
(Fixed auto-import and auto-includes merging... though in practice this bug had no effect.)


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

Branch: refs/heads/2.3
Commit: 78793b25a1d901004fa68d9286fd353d797ca288
Parents: 0c518cd
Author: ddekany <dd...@apache.org>
Authored: Sun Mar 12 18:18:11 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sun Mar 12 18:18:11 2017 +0100

----------------------------------------------------------------------
 src/main/java/freemarker/core/TemplateConfiguration.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/78793b25/src/main/java/freemarker/core/TemplateConfiguration.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/TemplateConfiguration.java b/src/main/java/freemarker/core/TemplateConfiguration.java
index ea9e3a3..e79bcab 100644
--- a/src/main/java/freemarker/core/TemplateConfiguration.java
+++ b/src/main/java/freemarker/core/TemplateConfiguration.java
@@ -256,10 +256,10 @@ public final class TemplateConfiguration extends Configurable implements ParserC
             setLazyAutoImports(tc.getLazyAutoImports());
         }
         if (tc.isAutoImportsSet()) {
-            setAutoImports(mergeMaps(getAutoImports(), tc.getAutoImports(), true));
+            setAutoImports(mergeMaps(getAutoImportsWithoutFallback(), tc.getAutoImportsWithoutFallback(), true));
         }
         if (tc.isAutoIncludesSet()) {
-            setAutoIncludes(mergeLists(getAutoIncludes(), tc.getAutoIncludes()));
+            setAutoIncludes(mergeLists(getAutoIncludesWithoutFallback(), tc.getAutoIncludesWithoutFallback()));
         }
         
         tc.copyDirectCustomAttributes(this, true);


[02/25] incubator-freemarker git commit: (JavaDoc typo)

Posted by dd...@apache.org.
(JavaDoc typo)


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

Branch: refs/heads/2.3
Commit: b4035cef611b60aafab0fd7a3714ad433a83feb3
Parents: 779e74a
Author: ddekany <dd...@apache.org>
Authored: Fri Mar 3 11:34:11 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Fri Mar 3 11:34:11 2017 +0100

----------------------------------------------------------------------
 .../java/freemarker/template/DefaultNonListCollectionAdapter.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/b4035cef/src/main/java/freemarker/template/DefaultNonListCollectionAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/DefaultNonListCollectionAdapter.java b/src/main/java/freemarker/template/DefaultNonListCollectionAdapter.java
index b6a157b..2ee9ca2 100644
--- a/src/main/java/freemarker/template/DefaultNonListCollectionAdapter.java
+++ b/src/main/java/freemarker/template/DefaultNonListCollectionAdapter.java
@@ -57,7 +57,7 @@ public class DefaultNonListCollectionAdapter extends WrappingTemplateModel imple
      * @param collection
      *            The collection to adapt; can't be {@code null}.
      * @param wrapper
-     *            The {@link ObjectWrapper} used to wrap the items in the array. Has to be
+     *            The {@link ObjectWrapper} used to wrap the items in the collection. Has to be
      *            {@link ObjectWrapperAndUnwrapper} because of planned future features.
      */
     public static DefaultNonListCollectionAdapter adapt(Collection collection, ObjectWrapperWithAPISupport wrapper) {


[03/25] incubator-freemarker git commit: Removed an unnecessary sync in SimpleCollection

Posted by dd...@apache.org.
Removed an unnecessary sync in SimpleCollection


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

Branch: refs/heads/2.3
Commit: 9f1fea3ed7671c3d6f71ffd8d4ac1365764a7caf
Parents: b4035ce
Author: ddekany <dd...@apache.org>
Authored: Fri Mar 3 11:34:42 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Fri Mar 3 11:34:42 2017 +0100

----------------------------------------------------------------------
 src/main/java/freemarker/template/SimpleCollection.java | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9f1fea3e/src/main/java/freemarker/template/SimpleCollection.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/SimpleCollection.java b/src/main/java/freemarker/template/SimpleCollection.java
index ebcd679..aa67ef1 100644
--- a/src/main/java/freemarker/template/SimpleCollection.java
+++ b/src/main/java/freemarker/template/SimpleCollection.java
@@ -85,13 +85,9 @@ implements TemplateCollectionModel, Serializable {
      * can't return the first element anymore.
      */
     public TemplateModelIterator iterator() {
-        if (iterator != null) {
-            return new SimpleTemplateModelIterator(iterator, false);
-        } else {
-            synchronized (collection) {
-                return new SimpleTemplateModelIterator(collection.iterator(), true);
-            }
-        }
+        return iterator != null
+                ? new SimpleTemplateModelIterator(iterator, false)
+                : new SimpleTemplateModelIterator(collection.iterator(), true);
     }
     
     /**


[15/25] incubator-freemarker git commit: Tweaked default method support a bit: Don't ignore synthetic property read methods in general, only bridge methods.

Posted by dd...@apache.org.
Tweaked default method support a bit: Don't ignore synthetic property read methods in general, only bridge methods.


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

Branch: refs/heads/2.3
Commit: b855872b0283c15a9fb74ca0d10833aebbd3dde9
Parents: d095f5a
Author: ddekany <dd...@apache.org>
Authored: Sun Mar 12 13:46:41 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sun Mar 12 13:46:41 2017 +0100

----------------------------------------------------------------------
 src/main/java/freemarker/ext/beans/ClassIntrospector.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/b855872b/src/main/java/freemarker/ext/beans/ClassIntrospector.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/ClassIntrospector.java b/src/main/java/freemarker/ext/beans/ClassIntrospector.java
index 911b14d..915fb42 100644
--- a/src/main/java/freemarker/ext/beans/ClassIntrospector.java
+++ b/src/main/java/freemarker/ext/beans/ClassIntrospector.java
@@ -421,7 +421,7 @@ class ClassIntrospector {
         // here, we don't utilize the accessibleMethods Map, which we might already have at this point.)
         for (Method method : clazz.getMethods()) {
             if (_JavaVersions.JAVA_8.isDefaultMethod(method) && method.getReturnType() != void.class
-                    && !method.isSynthetic()) {
+                    && !method.isBridge()) {
                 Class<?>[] paramTypes = method.getParameterTypes();
                 if (paramTypes.length == 0
                         || paramTypes.length == 1 && paramTypes[0] == int.class /* indexed property reader */) {


[12/25] incubator-freemarker git commit: FREEMARKER-24: Added workaround (not enabled by default) to expose Java 8 default methods (and the bean properties they define) to templates, despite that java.beans.Introspector (the official JavaBeans introspect

Posted by dd...@apache.org.
FREEMARKER-24: Added workaround (not enabled by default) to expose Java 8 default methods (and the bean properties they define) to templates, despite that java.beans.Introspector (the official JavaBeans introspector) ignores them, at least as of JRE 1.8.0_66. To enable this workaround, either increase the value of the incompatibleImprovements constructor argument of DefaultObjectWrapper or BeansWrapper the used to 2.3.26, or set its treatDefaultMethodsAsBeanMembers setting to true. Note that if you leave the object_wrapper setting of the Configuration on its default, it's enough to increase the incompatibleImprovements setting of the Configuration to 2.3.26, as that's inherited by the default object_wrapper.


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

Branch: refs/heads/2.3
Commit: 173abfe9bbcf7544e73346da471bd563809c7c85
Parents: 393d3be
Author: ddekany <dd...@apache.org>
Authored: Tue Mar 7 15:31:30 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sat Mar 11 00:34:55 2017 +0100

----------------------------------------------------------------------
 README                                          |   2 -
 .../java/freemarker/ext/beans/BeansWrapper.java |  77 +++-
 .../ext/beans/BeansWrapperConfiguration.java    |  37 +-
 .../freemarker/ext/beans/ClassIntrospector.java | 364 ++++++++++++++++---
 .../ext/beans/ClassIntrospectorBuilder.java     |  15 +
 .../java/freemarker/ext/beans/MethodSorter.java |   6 +-
 .../java/freemarker/ext/beans/_MethodUtil.java  |  26 ++
 .../java/freemarker/template/Configuration.java |   8 +
 src/manual/en_US/book.xml                       |  22 ++
 .../ext/beans/AlphabeticalMethodSorter.java     |   9 +-
 .../ext/beans/BeansWrapperJava8Test.java        | 221 +++++++++++
 ...GetPropertyNameFromReaderMethodNameTest.java |  43 +++
 .../ext/beans/Java8DefaultMethodsBean.java      |  65 ++++
 .../ext/beans/Java8DefaultMethodsBeanBase.java  |  72 ++++
 .../freemarker/template/ConfigurationTest.java  |   5 +
 .../template/DefaultObjectWrapperTest.java      |   2 +-
 16 files changed, 876 insertions(+), 98 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/README
----------------------------------------------------------------------
diff --git a/README b/README
index d5ab3b7..bcd8f20 100644
--- a/README
+++ b/README
@@ -200,8 +200,6 @@ apply it to your development environment:
    - Press "Finish"
 - Eclipse will indicate many errors at this point; it's expected, read on.
 - Project -> Properties -> Java Compiler
-  - Set "Compiler Compliance Level" to "1.5" (you will have to uncheck
-    "Use compliance from execution environment" for that)
   - In Errors/Warnings, check in "Enable project specific settings", then set
     "Forbidden reference (access rules)" from "Error" to "Warning".
 - You will still have errors on these java files (because different java

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/src/main/java/freemarker/ext/beans/BeansWrapper.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/BeansWrapper.java b/src/main/java/freemarker/ext/beans/BeansWrapper.java
index a9a3cbe..1803684 100644
--- a/src/main/java/freemarker/ext/beans/BeansWrapper.java
+++ b/src/main/java/freemarker/ext/beans/BeansWrapper.java
@@ -241,6 +241,12 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
      *       empty exactly if it has no elements left. (Note that this bug has never affected basic functionality, like
      *       {@code <#list ...>}.) 
      *     </li>  
+     *     <li>
+     *       <p>2.3.26 (or higher):
+     *       The default of {@link BeansWrapper#getTreatDefaultMethodsAsBeanMembers()} changes from {@code false} to
+     *       {@code true}. Thus, Java 8 default methods (and the bean properties they define) are exposed, despite that
+     *       {@link java.beans.Introspector} (the official JavaBeans introspector) ignores them, at least as of Java 8. 
+     *     </li>  
      *   </ul>
      *   
      *   <p>Note that the version will be normalized to the lowest version where the same incompatible
@@ -336,11 +342,11 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
             // but we need to use the same sharedInrospectionLock forever, because that's what the model factories
             // synchronize on, even during the classIntrospector is being replaced.
             sharedIntrospectionLock = new Object();
-            classIntrospector = new ClassIntrospector(bwConf.classIntrospectorFactory, sharedIntrospectionLock);
+            classIntrospector = new ClassIntrospector(bwConf.classIntrospectorBuilder, sharedIntrospectionLock);
         } else {
             // As this is a read-only BeansWrapper, the classIntrospector is never replaced, and since it's shared by
             // other BeansWrapper instances, we use the lock belonging to the shared ClassIntrospector.
-            classIntrospector = bwConf.classIntrospectorFactory.build();
+            classIntrospector = bwConf.classIntrospectorBuilder.build();
             sharedIntrospectionLock = classIntrospector.getSharedLock(); 
         }
         
@@ -539,9 +545,9 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
         checkModifiable();
      
         if (classIntrospector.getExposureLevel() != exposureLevel) {
-            ClassIntrospectorBuilder pa = classIntrospector.getPropertyAssignments();
-            pa.setExposureLevel(exposureLevel);
-            replaceClassIntrospector(pa);
+            ClassIntrospectorBuilder builder = classIntrospector.createBuilder();
+            builder.setExposureLevel(exposureLevel);
+            replaceClassIntrospector(builder);
         }
     }
     
@@ -566,9 +572,34 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
         checkModifiable();
         
         if (classIntrospector.getExposeFields() != exposeFields) {
-            ClassIntrospectorBuilder pa = classIntrospector.getPropertyAssignments();
-            pa.setExposeFields(exposeFields);
-            replaceClassIntrospector(pa);
+            ClassIntrospectorBuilder builder = classIntrospector.createBuilder();
+            builder.setExposeFields(exposeFields);
+            replaceClassIntrospector(builder);
+        }
+    }
+    
+    /**
+     * Controls whether Java 8 default methods that weren't overridden in a class will be recognized as bean property
+     * accessors and/or bean actions, and thus will be visible from templates. (We expose bean properties and bean
+     * actions, not methods in general.) Before {@link #getIncompatibleImprovements incompatibleImprovements} 2.3.26
+     * this defaults to {@code false} for backward compatibility. Starting with {@link #getIncompatibleImprovements
+     * incompatibleImprovements} 2.3.26 it defaults to {@code true}.
+     * <p>
+     * Some explanation: FreeMarker uses {@link java.beans.Introspector} to discover the bean properties and actions of
+     * classes, for maximum conformance to the JavaBeans specification. But for some reason (perhaps just a bug in the
+     * Oracle/OpenJDK Java 8 implementation) that ignores the Java 8 default methods coming from the interfaces. When
+     * this setting is {@code true}, we search for non-overridden default methods ourselves, and add them to the set of
+     * discovered bean members.
+     * 
+     * @since 2.3.26
+     */
+    public void setTreatDefaultMethodsAsBeanMembers(boolean treatDefaultMethodsAsBeanMembers) {
+        checkModifiable();
+        
+        if (classIntrospector.getTreatDefaultMethodsAsBeanMembers() != treatDefaultMethodsAsBeanMembers) {
+            ClassIntrospectorBuilder builder = classIntrospector.createBuilder();
+            builder.setTreatDefaultMethodsAsBeanMembers(treatDefaultMethodsAsBeanMembers);
+            replaceClassIntrospector(builder);
         }
     }
     
@@ -576,11 +607,20 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
      * Returns whether exposure of public instance fields of classes is 
      * enabled. See {@link #setExposeFields(boolean)} for details.
      * @return true if public instance fields are exposed, false otherwise.
+     * 
+     * @since 2.3.26
      */
     public boolean isExposeFields() {
         return classIntrospector.getExposeFields();
     }
     
+    /**
+     * See {@link #setTreatDefaultMethodsAsBeanMembers(boolean)}.
+     */
+    public boolean getTreatDefaultMethodsAsBeanMembers() {
+        return classIntrospector.getTreatDefaultMethodsAsBeanMembers();
+    }
+    
     public MethodAppearanceFineTuner getMethodAppearanceFineTuner() {
         return classIntrospector.getMethodAppearanceFineTuner();
     }
@@ -593,9 +633,9 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
         checkModifiable();
         
         if (classIntrospector.getMethodAppearanceFineTuner() != methodAppearanceFineTuner) {
-            ClassIntrospectorBuilder pa = classIntrospector.getPropertyAssignments();
-            pa.setMethodAppearanceFineTuner(methodAppearanceFineTuner);
-            replaceClassIntrospector(pa);
+            ClassIntrospectorBuilder builder = classIntrospector.createBuilder();
+            builder.setMethodAppearanceFineTuner(methodAppearanceFineTuner);
+            replaceClassIntrospector(builder);
         }
     }
 
@@ -607,9 +647,9 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
         checkModifiable();
         
         if (classIntrospector.getMethodSorter() != methodSorter) {
-            ClassIntrospectorBuilder pa = classIntrospector.getPropertyAssignments();
-            pa.setMethodSorter(methodSorter);
-            replaceClassIntrospector(pa);
+            ClassIntrospectorBuilder builder = classIntrospector.createBuilder();
+            builder.setMethodSorter(methodSorter);
+            replaceClassIntrospector(builder);
         }
     }
     
@@ -631,10 +671,10 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
      * Replaces the value of {@link #classIntrospector}, but first it unregisters
      * the model factories in the old {@link #classIntrospector}.
      */
-    private void replaceClassIntrospector(ClassIntrospectorBuilder pa) {
+    private void replaceClassIntrospector(ClassIntrospectorBuilder builder) {
         checkModifiable();
         
-        final ClassIntrospector newCI = new ClassIntrospector(pa, sharedIntrospectionLock);
+        final ClassIntrospector newCI = new ClassIntrospector(builder, sharedIntrospectionLock);
         final ClassIntrospector oldCI;
         
         // In principle this need not be synchronized, but as apps might publish the configuration improperly, or
@@ -803,7 +843,8 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
         if (incompatibleImprovements.intValue() < _TemplateAPI.VERSION_INT_2_3_0) {
             throw new IllegalArgumentException("Version must be at least 2.3.0.");
         }
-        return is2324Bugfixed(incompatibleImprovements) ? Configuration.VERSION_2_3_24
+        return incompatibleImprovements.intValue() >= _TemplateAPI.VERSION_INT_2_3_26 ? Configuration.VERSION_2_3_26
+                : is2324Bugfixed(incompatibleImprovements) ? Configuration.VERSION_2_3_24
                 : is2321Bugfixed(incompatibleImprovements) ? Configuration.VERSION_2_3_21
                 : Configuration.VERSION_2_3_0;
     }
@@ -1692,6 +1733,8 @@ public class BeansWrapper implements RichObjectWrapper, WriteProtectable {
         return "simpleMapWrapper=" + simpleMapWrapper + ", "
                + "exposureLevel=" + classIntrospector.getExposureLevel() + ", "
                + "exposeFields=" + classIntrospector.getExposeFields() + ", "
+               + "treatDefaultMethodsAsBeanMembers="
+               + classIntrospector.getTreatDefaultMethodsAsBeanMembers() + ", "
                + "sharedClassIntrospCache="
                + (classIntrospector.isShared() ? "@" + System.identityHashCode(classIntrospector) : "none");
     }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/src/main/java/freemarker/ext/beans/BeansWrapperConfiguration.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/BeansWrapperConfiguration.java b/src/main/java/freemarker/ext/beans/BeansWrapperConfiguration.java
index d80a812..26764e8 100644
--- a/src/main/java/freemarker/ext/beans/BeansWrapperConfiguration.java
+++ b/src/main/java/freemarker/ext/beans/BeansWrapperConfiguration.java
@@ -42,7 +42,7 @@ public abstract class BeansWrapperConfiguration implements Cloneable {
 
     private final Version incompatibleImprovements;
     
-    protected ClassIntrospectorBuilder classIntrospectorFactory;
+    protected ClassIntrospectorBuilder classIntrospectorBuilder;
     
     // Properties and their *defaults*:
     private boolean simpleMapWrapper = false;
@@ -81,7 +81,7 @@ public abstract class BeansWrapperConfiguration implements Cloneable {
                 : BeansWrapper.normalizeIncompatibleImprovementsVersion(incompatibleImprovements);
         this.incompatibleImprovements = incompatibleImprovements;
         
-        classIntrospectorFactory = new ClassIntrospectorBuilder(incompatibleImprovements);
+        classIntrospectorBuilder = new ClassIntrospectorBuilder(incompatibleImprovements);
     }
     
     /**
@@ -101,7 +101,7 @@ public abstract class BeansWrapperConfiguration implements Cloneable {
         result = prime * result + (outerIdentity != null ? outerIdentity.hashCode() : 0);
         result = prime * result + (strict ? 1231 : 1237);
         result = prime * result + (useModelCache ? 1231 : 1237);
-        result = prime * result + classIntrospectorFactory.hashCode();
+        result = prime * result + classIntrospectorBuilder.hashCode();
         return result;
     }
 
@@ -122,7 +122,7 @@ public abstract class BeansWrapperConfiguration implements Cloneable {
         if (outerIdentity != other.outerIdentity) return false;
         if (strict != other.strict) return false;
         if (useModelCache != other.useModelCache) return false;
-        if (!classIntrospectorFactory.equals(other.classIntrospectorFactory)) return false;
+        if (!classIntrospectorBuilder.equals(other.classIntrospectorBuilder)) return false;
         
         return true;
     }
@@ -131,8 +131,8 @@ public abstract class BeansWrapperConfiguration implements Cloneable {
         try {
             BeansWrapperConfiguration clone = (BeansWrapperConfiguration) super.clone();
             if (deepCloneKey) {
-                clone.classIntrospectorFactory
-                        = (ClassIntrospectorBuilder) classIntrospectorFactory.clone();
+                clone.classIntrospectorBuilder
+                        = (ClassIntrospectorBuilder) classIntrospectorBuilder.clone();
             }
             return clone;
         } catch (CloneNotSupportedException e) {
@@ -193,25 +193,34 @@ public abstract class BeansWrapperConfiguration implements Cloneable {
     }
     
     public int getExposureLevel() {
-        return classIntrospectorFactory.getExposureLevel();
+        return classIntrospectorBuilder.getExposureLevel();
     }
 
     /** See {@link BeansWrapper#setExposureLevel(int)}. */
     public void setExposureLevel(int exposureLevel) {
-        classIntrospectorFactory.setExposureLevel(exposureLevel);
+        classIntrospectorBuilder.setExposureLevel(exposureLevel);
     }
 
     public boolean getExposeFields() {
-        return classIntrospectorFactory.getExposeFields();
+        return classIntrospectorBuilder.getExposeFields();
     }
 
     /** See {@link BeansWrapper#setExposeFields(boolean)}. */
     public void setExposeFields(boolean exposeFields) {
-        classIntrospectorFactory.setExposeFields(exposeFields);
+        classIntrospectorBuilder.setExposeFields(exposeFields);
+    }
+
+    public boolean getTreatDefaultMethodsAsBeanMembers() {
+        return classIntrospectorBuilder.getTreatDefaultMethodsAsBeanMembers();
+    }
+    
+    /** See {@link BeansWrapper#setTreatDefaultMethodsAsBeanMembers(boolean)} */
+    public void setTreatDefaultMethodsAsBeanMembers(boolean treatDefaultMethodsAsBeanMembers) {
+        classIntrospectorBuilder.setTreatDefaultMethodsAsBeanMembers(treatDefaultMethodsAsBeanMembers);
     }
 
     public MethodAppearanceFineTuner getMethodAppearanceFineTuner() {
-        return classIntrospectorFactory.getMethodAppearanceFineTuner();
+        return classIntrospectorBuilder.getMethodAppearanceFineTuner();
     }
 
     /**
@@ -220,15 +229,15 @@ public abstract class BeansWrapperConfiguration implements Cloneable {
      * the value implements {@link SingletonCustomizer}.
      */
     public void setMethodAppearanceFineTuner(MethodAppearanceFineTuner methodAppearanceFineTuner) {
-        classIntrospectorFactory.setMethodAppearanceFineTuner(methodAppearanceFineTuner);
+        classIntrospectorBuilder.setMethodAppearanceFineTuner(methodAppearanceFineTuner);
     }
 
     MethodSorter getMethodSorter() {
-        return classIntrospectorFactory.getMethodSorter();
+        return classIntrospectorBuilder.getMethodSorter();
     }
 
     void setMethodSorter(MethodSorter methodSorter) {
-        classIntrospectorFactory.setMethodSorter(methodSorter);
+        classIntrospectorBuilder.setMethodSorter(methodSorter);
     }
  
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/src/main/java/freemarker/ext/beans/ClassIntrospector.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/ClassIntrospector.java b/src/main/java/freemarker/ext/beans/ClassIntrospector.java
index 56e510b..8fa0037 100644
--- a/src/main/java/freemarker/ext/beans/ClassIntrospector.java
+++ b/src/main/java/freemarker/ext/beans/ClassIntrospector.java
@@ -32,11 +32,14 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.IdentityHashMap;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -45,6 +48,7 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 import freemarker.core.BugException;
+import freemarker.core._JavaVersions;
 import freemarker.ext.beans.BeansWrapper.MethodAppearanceDecision;
 import freemarker.ext.beans.BeansWrapper.MethodAppearanceDecisionInput;
 import freemarker.ext.util.ModelCache;
@@ -136,6 +140,7 @@ class ClassIntrospector {
     final boolean exposeFields;
     final MethodAppearanceFineTuner methodAppearanceFineTuner;
     final MethodSorter methodSorter;
+    final boolean treatDefaultMethodsAsBeanMembers;
     final boolean bugfixed;
 
     /** See {@link #getHasSharedInstanceRestrictons()} */
@@ -185,6 +190,7 @@ class ClassIntrospector {
         this.exposeFields = builder.getExposeFields();
         this.methodAppearanceFineTuner = builder.getMethodAppearanceFineTuner();
         this.methodSorter = builder.getMethodSorter();
+        this.treatDefaultMethodsAsBeanMembers = builder.getTreatDefaultMethodsAsBeanMembers();
         this.bugfixed = builder.isBugfixed();
 
         this.sharedLock = sharedLock;
@@ -201,7 +207,7 @@ class ClassIntrospector {
      * Returns a {@link ClassIntrospectorBuilder}-s that could be used to create an identical {@link #ClassIntrospector}
      * . The returned {@link ClassIntrospectorBuilder} can be modified without interfering with anything.
      */
-    ClassIntrospectorBuilder getPropertyAssignments() {
+    ClassIntrospectorBuilder createBuilder() {
         return new ClassIntrospectorBuilder(this);
     }
 
@@ -312,72 +318,311 @@ class ClassIntrospector {
             Map<Object, Object> introspData, Class<?> clazz, Map<MethodSignature, List<Method>> accessibleMethods)
             throws IntrospectionException {
         BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
-
-        PropertyDescriptor[] pda = beanInfo.getPropertyDescriptors();
-        if (pda != null) {
-            int pdaLength = pda.length;
-            for (int i = pdaLength - 1; i >= 0; --i) {
-                addPropertyDescriptorToClassIntrospectionData(
-                        introspData, pda[i], clazz,
-                        accessibleMethods);
-            }
+        List<PropertyDescriptor> pdas = getPropertyDescriptors(beanInfo, clazz);
+        int pdasLength = pdas.size();
+        // Reverse order shouldn't mater, but we keep it to not risk backward incompatibility.
+        for (int i = pdasLength - 1; i >= 0; --i) {
+            addPropertyDescriptorToClassIntrospectionData(
+                    introspData, pdas.get(i), clazz,
+                    accessibleMethods);
         }
 
         if (exposureLevel < BeansWrapper.EXPOSE_PROPERTIES_ONLY) {
             final MethodAppearanceDecision decision = new MethodAppearanceDecision();
             MethodAppearanceDecisionInput decisionInput = null;
-            final MethodDescriptor[] mda = sortMethodDescriptors(beanInfo.getMethodDescriptors());
-            if (mda != null) {
-                int mdaLength = mda.length;
-                for (int i = mdaLength - 1; i >= 0; --i) {
-                    final MethodDescriptor md = mda[i];
-                    final Method method = getMatchingAccessibleMethod(md.getMethod(), accessibleMethods);
-                    if (method != null && isAllowedToExpose(method)) {
-                        decision.setDefaults(method);
-                        if (methodAppearanceFineTuner != null) {
-                            if (decisionInput == null) {
-                                decisionInput = new MethodAppearanceDecisionInput();
-                            }
-                            decisionInput.setContainingClass(clazz);
-                            decisionInput.setMethod(method);
-    
-                            methodAppearanceFineTuner.process(decisionInput, decision);
-                        }
-    
-                        PropertyDescriptor propDesc = decision.getExposeAsProperty();
-                        if (propDesc != null && !(introspData.get(propDesc.getName()) instanceof PropertyDescriptor)) {
-                            addPropertyDescriptorToClassIntrospectionData(
-                                    introspData, propDesc, clazz, accessibleMethods);
+            List<MethodDescriptor> mds = getMethodDescriptors(beanInfo, clazz);
+            sortMethodDescriptors(mds);
+            int mdsSize = mds.size();
+            IdentityHashMap<Method, Void> argTypesUsedByIndexerPropReaders = null;
+            for (int i = mdsSize - 1; i >= 0; --i) {
+                final MethodDescriptor md = mds.get(i);
+                final Method method = getMatchingAccessibleMethod(md.getMethod(), accessibleMethods);
+                if (method != null && isAllowedToExpose(method)) {
+                    decision.setDefaults(method);
+                    if (methodAppearanceFineTuner != null) {
+                        if (decisionInput == null) {
+                            decisionInput = new MethodAppearanceDecisionInput();
                         }
-    
-                        String methodKey = decision.getExposeMethodAs();
-                        if (methodKey != null) {
-                            Object previous = introspData.get(methodKey);
-                            if (previous instanceof Method) {
-                                // Overloaded method - replace Method with a OverloadedMethods
-                                OverloadedMethods overloadedMethods = new OverloadedMethods(bugfixed);
-                                overloadedMethods.addMethod((Method) previous);
-                                overloadedMethods.addMethod(method);
-                                introspData.put(methodKey, overloadedMethods);
-                                // Remove parameter type information
+                        decisionInput.setContainingClass(clazz);
+                        decisionInput.setMethod(method);
+
+                        methodAppearanceFineTuner.process(decisionInput, decision);
+                    }
+
+                    PropertyDescriptor propDesc = decision.getExposeAsProperty();
+                    if (propDesc != null && !(introspData.get(propDesc.getName()) instanceof PropertyDescriptor)) {
+                        addPropertyDescriptorToClassIntrospectionData(
+                                introspData, propDesc, clazz, accessibleMethods);
+                    }
+
+                    String methodKey = decision.getExposeMethodAs();
+                    if (methodKey != null) {
+                        Object previous = introspData.get(methodKey);
+                        if (previous instanceof Method) {
+                            // Overloaded method - replace Method with a OverloadedMethods
+                            OverloadedMethods overloadedMethods = new OverloadedMethods(bugfixed);
+                            overloadedMethods.addMethod((Method) previous);
+                            overloadedMethods.addMethod(method);
+                            introspData.put(methodKey, overloadedMethods);
+                            // Remove parameter type information (unless an indexed property reader needs it):
+                            if (argTypesUsedByIndexerPropReaders == null
+                                    || !argTypesUsedByIndexerPropReaders.containsKey(previous)) {
                                 getArgTypesByMethod(introspData).remove(previous);
-                            } else if (previous instanceof OverloadedMethods) {
-                                // Already overloaded method - add new overload
-                                ((OverloadedMethods) previous).addMethod(method);
-                            } else if (decision.getMethodShadowsProperty()
-                                    || !(previous instanceof PropertyDescriptor)) {
-                                // Simple method (this far)
-                                introspData.put(methodKey, method);
-                                getArgTypesByMethod(introspData).put(method,
-                                        method.getParameterTypes());
+                            }
+                        } else if (previous instanceof OverloadedMethods) {
+                            // Already overloaded method - add new overload
+                            ((OverloadedMethods) previous).addMethod(method);
+                        } else if (decision.getMethodShadowsProperty()
+                                || !(previous instanceof PropertyDescriptor)) {
+                            // Simple method (this far)
+                            introspData.put(methodKey, method);
+                            Class<?>[] replaced = getArgTypesByMethod(introspData).put(method,
+                                    method.getParameterTypes());
+                            if (replaced != null) {
+                                if (argTypesUsedByIndexerPropReaders == null) {
+                                    argTypesUsedByIndexerPropReaders = new IdentityHashMap<Method, Void>();
+                                }
+                                argTypesUsedByIndexerPropReaders.put(method, null);                                
                             }
                         }
                     }
-                } // for each in mda
-            } // if mda != null
+                }
+            } // for each in mds
         } // end if (exposureLevel < EXPOSE_PROPERTIES_ONLY)
     }
 
+    /**
+     * Very similar to {@link BeanInfo#getPropertyDescriptors()}, but can deal with Java 8 default methods too.
+     */
+    private List<PropertyDescriptor> getPropertyDescriptors(BeanInfo beanInfo, Class<?> clazz) {
+        PropertyDescriptor[] introspectorPDsArray = beanInfo.getPropertyDescriptors();
+        List<PropertyDescriptor> introspectorPDs = introspectorPDsArray != null ? Arrays.asList(introspectorPDsArray)
+                : Collections.<PropertyDescriptor>emptyList();
+        
+        if (!treatDefaultMethodsAsBeanMembers || _JavaVersions.JAVA_8 == null) {
+            // java.beans.Introspector was good enough then.
+            return introspectorPDs;
+        }
+        
+        // introspectorPDs contains each property exactly once. But as now we will search them manually too, it can
+        // happen that we find the same property for multiple times. Worse, because of indexed properties, it's possible
+        // that we have to merge entries (like one has the normal reader method, the other has the indexed reader
+        // method), instead of just replacing them in a Map. That's why we have introduced PropertyReaderMethodPair,
+        // which holds the methods belonging to the same property name. IndexedPropertyDescriptor is not good for that,
+        // as it can't store two methods whose types are incompatible, and we have to wait until all the merging was
+        // done to see if the incompatibility goes away.
+        
+        // This could be Map<String, PropertyReaderMethodPair>, but since we rarely need to do merging, we try to avoid
+        // creating those and use the source objects as much as possible. Also note that we initialize this lazily.
+        LinkedHashMap<String, Object /*PropertyReaderMethodPair|Method|PropertyDescriptor*/> mergedPRMPs = null;
+
+        // Collect Java 8 default methods that look like property readers into mergedPRMPs: 
+        // (Note that java.beans.Introspector discovers non-accessible public methods, and to emulate that behavior
+        // here, we don't utilize the accessibleMethods Map, which we might already have at this point.)
+        for (Method method : clazz.getMethods()) {
+            if (_JavaVersions.JAVA_8.isDefaultMethod(method) && method.getReturnType() != void.class
+                    && !method.isSynthetic()) {
+                Class<?>[] paramTypes = method.getParameterTypes();
+                if (paramTypes.length == 0
+                        || paramTypes.length == 1 && paramTypes[0] == int.class /* indexed property reader */) {
+                    String propName = _MethodUtil.getBeanPropertyNameFromReaderMethodName(
+                            method.getName(), method.getReturnType());
+                    if (propName != null) {
+                        if (mergedPRMPs == null) {
+                            // Lazy initialization
+                            mergedPRMPs = new LinkedHashMap<String, Object>();
+                        }
+                        if (paramTypes.length == 0) {
+                            mergeInPropertyReaderMethod(mergedPRMPs, propName, method);
+                        } else { // It's an indexed property reader method
+                            mergeInPropertyReaderMethodPair(mergedPRMPs, propName,
+                                    new PropertyReaderedMethodPair(null, method));
+                        }
+                    }
+                }
+            }
+        } // for clazz.getMethods()
+        
+        if (mergedPRMPs == null) {
+            // We had no interfering Java 8 default methods, so we can chose the fast route.
+            return introspectorPDs;
+        }
+        
+        for (PropertyDescriptor introspectorPD : introspectorPDs) {
+            mergeInPropertyDescriptor(mergedPRMPs, introspectorPD);
+        }
+        
+        // Now we convert the PRMPs to PDs, handling case where the normal and the indexed read methods contradict.
+        List<PropertyDescriptor> mergedPDs = new ArrayList<PropertyDescriptor>(mergedPRMPs.size());
+        for (Entry<String, Object> entry : mergedPRMPs.entrySet()) {
+            String propName = entry.getKey();
+            Object propDescObj = entry.getValue();
+            if (propDescObj instanceof PropertyDescriptor) {
+                mergedPDs.add((PropertyDescriptor) propDescObj);
+            } else {
+                Method readMethod;
+                Method indexedReadMethod;
+                if (propDescObj instanceof Method) {
+                    readMethod = (Method) propDescObj;
+                    indexedReadMethod = null;
+                } else if (propDescObj instanceof PropertyReaderedMethodPair) {
+                    PropertyReaderedMethodPair prmp = (PropertyReaderedMethodPair) propDescObj;
+                    readMethod = prmp.readMethod;
+                    indexedReadMethod = prmp.indexedReadMethod;
+                    if (readMethod != null && indexedReadMethod != null
+                            && indexedReadMethod.getReturnType() != readMethod.getReturnType().getComponentType()) {
+                        // Here we copy the java.beans.Introspector behavior: If the array item class is not exactly the
+                        // the same as the indexed read method return type, we say that the property is not indexed.
+                        indexedReadMethod = null;
+                    }
+                } else {
+                    throw new BugException();
+                }
+                try {
+                    mergedPDs.add(
+                            indexedReadMethod != null
+                                    ? new IndexedPropertyDescriptor(propName,
+                                            readMethod, null, indexedReadMethod, null)
+                                    : new PropertyDescriptor(propName, readMethod, null));
+                } catch (IntrospectionException e) {
+                    if (LOG.isWarnEnabled()) {
+                        LOG.warn("Failed creating property descriptor for " + clazz.getName() + " property " + propName,
+                                e);
+                    }
+                }
+            }
+        }
+        return mergedPDs;
+    }
+
+    private static class PropertyReaderedMethodPair {
+        private final Method readMethod;
+        private final Method indexedReadMethod;
+        
+        PropertyReaderedMethodPair(Method readerMethod, Method indexedReaderMethod) {
+            this.readMethod = readerMethod;
+            this.indexedReadMethod = indexedReaderMethod;
+        }
+        
+        PropertyReaderedMethodPair(PropertyDescriptor pd) {
+            this(
+                    pd.getReadMethod(),
+                    pd instanceof IndexedPropertyDescriptor
+                            ? ((IndexedPropertyDescriptor) pd).getIndexedReadMethod() : null);
+        }
+    
+        static PropertyReaderedMethodPair from(Object obj) {
+            if (obj instanceof PropertyReaderedMethodPair) {
+                return (PropertyReaderedMethodPair) obj;
+            } else if (obj instanceof PropertyDescriptor) {
+                return new PropertyReaderedMethodPair((PropertyDescriptor) obj);
+            } else if (obj instanceof Method) {
+                return new PropertyReaderedMethodPair((Method) obj, null);
+            } else {
+                throw new BugException("Unexpected obj type: " + obj.getClass().getName());
+            }
+        }
+        
+        static PropertyReaderedMethodPair merge(PropertyReaderedMethodPair oldMethods, PropertyReaderedMethodPair newMethods) {
+            return new PropertyReaderedMethodPair(
+                    newMethods.readMethod != null ? newMethods.readMethod : oldMethods.readMethod,
+                    newMethods.indexedReadMethod != null ? newMethods.indexedReadMethod
+                            : oldMethods.indexedReadMethod);
+        }
+    
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ((indexedReadMethod == null) ? 0 : indexedReadMethod.hashCode());
+            result = prime * result + ((readMethod == null) ? 0 : readMethod.hashCode());
+            return result;
+        }
+    
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) return true;
+            if (obj == null) return false;
+            if (getClass() != obj.getClass()) return false;
+            PropertyReaderedMethodPair other = (PropertyReaderedMethodPair) obj;
+            return other.readMethod == readMethod && other.indexedReadMethod == indexedReadMethod;
+        }
+        
+    }
+
+    private void mergeInPropertyDescriptor(LinkedHashMap<String, Object> mergedPRMPs, PropertyDescriptor pd) {
+        String propName = pd.getName();
+        Object replaced = mergedPRMPs.put(propName, pd);
+        if (replaced != null) {
+            PropertyReaderedMethodPair newPRMP = new PropertyReaderedMethodPair(pd);
+            putIfMergedPropertyReaderMethodPairDiffers(mergedPRMPs, propName, replaced, newPRMP);
+        }
+    }
+
+    private void mergeInPropertyReaderMethodPair(LinkedHashMap<String, Object> mergedPRMPs,
+            String propName, PropertyReaderedMethodPair newPRM) {
+        Object replaced = mergedPRMPs.put(propName, newPRM);
+        if (replaced != null) {
+            putIfMergedPropertyReaderMethodPairDiffers(mergedPRMPs, propName, replaced, newPRM);
+        }
+    }
+    
+    private void mergeInPropertyReaderMethod(LinkedHashMap<String, Object> mergedPRMPs,
+            String propName, Method readerMethod) {
+        Object replaced = mergedPRMPs.put(propName, readerMethod);
+        if (replaced != null) {
+            putIfMergedPropertyReaderMethodPairDiffers(mergedPRMPs, propName,
+                    replaced, new PropertyReaderedMethodPair(readerMethod, null));
+        }
+    }
+
+    private void putIfMergedPropertyReaderMethodPairDiffers(LinkedHashMap<String, Object> mergedPRMPs,
+            String propName, Object replaced, PropertyReaderedMethodPair newPRMP) {
+        PropertyReaderedMethodPair replacedPRMP = PropertyReaderedMethodPair.from(replaced);
+        PropertyReaderedMethodPair mergedPRMP = PropertyReaderedMethodPair.merge(replacedPRMP, newPRMP);
+        if (!mergedPRMP.equals(newPRMP)) {
+            mergedPRMPs.put(propName, mergedPRMP);
+        }
+    }
+    
+    /**
+     * Very similar to {@link BeanInfo#getMethodDescriptors()}, but can deal with Java 8 default methods too.
+     */
+    private List<MethodDescriptor> getMethodDescriptors(BeanInfo beanInfo, Class<?> clazz) {
+        MethodDescriptor[] introspectorMDArray = beanInfo.getMethodDescriptors();
+        List<MethodDescriptor> introspectionMDs = introspectorMDArray != null && introspectorMDArray.length != 0
+                ? Arrays.asList(introspectorMDArray) : Collections.<MethodDescriptor>emptyList();
+
+        if (!treatDefaultMethodsAsBeanMembers || _JavaVersions.JAVA_8 == null) {
+            // java.beans.Introspector was good enough then.
+            return introspectionMDs;
+        }
+        
+        boolean anyDefaultMethodsAdded = false;
+        findDefaultMethods: for (Method method : clazz.getMethods()) {
+            if (_JavaVersions.JAVA_8.isDefaultMethod(method)) {
+                if (!anyDefaultMethodsAdded) {
+                    for (MethodDescriptor methodDescriptor : introspectionMDs) {
+                        // Check if java.bean.Introspector now finds default methods (it did not in Java 1.8.0_66):
+                        if (_JavaVersions.JAVA_8.isDefaultMethod(methodDescriptor.getMethod())) {
+                            break findDefaultMethods;
+                        }
+                        
+                        // Recreate introspectionMDs so that its size can grow: 
+                        ArrayList<MethodDescriptor> newIntrospectionMDs
+                                = new ArrayList<MethodDescriptor>(introspectionMDs.size() + 16);
+                        newIntrospectionMDs.addAll(introspectionMDs);
+                        introspectionMDs = newIntrospectionMDs;
+                    }
+                    anyDefaultMethodsAdded = true;
+                }
+                introspectionMDs.add(new MethodDescriptor(method));
+            }
+        }
+        
+        return introspectionMDs;
+    }
+
     private void addPropertyDescriptorToClassIntrospectionData(Map<Object, Object> introspData,
             PropertyDescriptor pd, Class<?> clazz, Map<MethodSignature, List<Method>> accessibleMethods) {
         if (pd instanceof IndexedPropertyDescriptor) {
@@ -410,7 +655,6 @@ class ClassIntrospector {
                 try {
                     if (readMethod != publicReadMethod) {
                         pd = new PropertyDescriptor(pd.getName(), publicReadMethod, null);
-                        pd.setReadMethod(publicReadMethod);
                     }
                     introspData.put(pd.getName(), pd);
                 } catch (IntrospectionException e) {
@@ -539,8 +783,10 @@ class ClassIntrospector {
     /**
      * As of this writing, this is only used for testing if method order really doesn't mater.
      */
-    private MethodDescriptor[] sortMethodDescriptors(MethodDescriptor[] methodDescriptors) {
-        return methodSorter != null ? methodSorter.sortMethodDescriptors(methodDescriptors) : methodDescriptors;
+    private void sortMethodDescriptors(List<MethodDescriptor> methodDescriptors) {
+        if (methodSorter != null) {
+            methodSorter.sortMethodDescriptors(methodDescriptors);
+        }
     }
 
     boolean isAllowedToExpose(Method method) {
@@ -778,6 +1024,10 @@ class ClassIntrospector {
     boolean getExposeFields() {
         return exposeFields;
     }
+    
+    boolean getTreatDefaultMethodsAsBeanMembers() {
+        return treatDefaultMethodsAsBeanMembers;
+    }
 
     MethodAppearanceFineTuner getMethodAppearanceFineTuner() {
         return methodAppearanceFineTuner;

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java b/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java
index cbeffc3..25688e5 100644
--- a/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java
+++ b/src/main/java/freemarker/ext/beans/ClassIntrospectorBuilder.java
@@ -27,6 +27,7 @@ import java.util.Iterator;
 import java.util.Map;
 
 import freemarker.template.Version;
+import freemarker.template._TemplateAPI;
 
 final class ClassIntrospectorBuilder implements Cloneable {
     
@@ -38,6 +39,7 @@ final class ClassIntrospectorBuilder implements Cloneable {
     // Properties and their *defaults*:
     private int exposureLevel = BeansWrapper.EXPOSE_SAFE;
     private boolean exposeFields;
+    private boolean treatDefaultMethodsAsBeanMembers;
     private MethodAppearanceFineTuner methodAppearanceFineTuner;
     private MethodSorter methodSorter;
     // Attention:
@@ -50,6 +52,7 @@ final class ClassIntrospectorBuilder implements Cloneable {
         bugfixed = ci.bugfixed;
         exposureLevel = ci.exposureLevel;
         exposeFields = ci.exposeFields;
+        treatDefaultMethodsAsBeanMembers = ci.treatDefaultMethodsAsBeanMembers;
         methodAppearanceFineTuner = ci.methodAppearanceFineTuner;
         methodSorter = ci.methodSorter; 
     }
@@ -59,6 +62,8 @@ final class ClassIntrospectorBuilder implements Cloneable {
         // change in the BeansWrapper.normalizeIncompatibleImprovements results. That is, this class may don't react
         // to some version changes that affects BeansWrapper, but not the other way around. 
         bugfixed = BeansWrapper.is2321Bugfixed(incompatibleImprovements);
+        treatDefaultMethodsAsBeanMembers
+                = incompatibleImprovements.intValue() >= _TemplateAPI.VERSION_INT_2_3_26;
     }
     
     @Override
@@ -76,6 +81,7 @@ final class ClassIntrospectorBuilder implements Cloneable {
         int result = 1;
         result = prime * result + (bugfixed ? 1231 : 1237);
         result = prime * result + (exposeFields ? 1231 : 1237);
+        result = prime * result + (treatDefaultMethodsAsBeanMembers ? 1231 : 1237);
         result = prime * result + exposureLevel;
         result = prime * result + System.identityHashCode(methodAppearanceFineTuner);
         result = prime * result + System.identityHashCode(methodSorter);
@@ -91,6 +97,7 @@ final class ClassIntrospectorBuilder implements Cloneable {
         
         if (bugfixed != other.bugfixed) return false;
         if (exposeFields != other.exposeFields) return false;
+        if (treatDefaultMethodsAsBeanMembers != other.treatDefaultMethodsAsBeanMembers) return false;
         if (exposureLevel != other.exposureLevel) return false;
         if (methodAppearanceFineTuner != other.methodAppearanceFineTuner) return false;
         if (methodSorter != other.methodSorter) return false;
@@ -119,6 +126,14 @@ final class ClassIntrospectorBuilder implements Cloneable {
     public void setExposeFields(boolean exposeFields) {
         this.exposeFields = exposeFields;
     }
+    
+    public boolean getTreatDefaultMethodsAsBeanMembers() {
+        return treatDefaultMethodsAsBeanMembers;
+    }
+
+    public void setTreatDefaultMethodsAsBeanMembers(boolean treatDefaultMethodsAsBeanMembers) {
+        this.treatDefaultMethodsAsBeanMembers = treatDefaultMethodsAsBeanMembers;
+    }
 
     public MethodAppearanceFineTuner getMethodAppearanceFineTuner() {
         return methodAppearanceFineTuner;

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/src/main/java/freemarker/ext/beans/MethodSorter.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/MethodSorter.java b/src/main/java/freemarker/ext/beans/MethodSorter.java
index f7f7335..64168b4 100644
--- a/src/main/java/freemarker/ext/beans/MethodSorter.java
+++ b/src/main/java/freemarker/ext/beans/MethodSorter.java
@@ -20,6 +20,7 @@
 package freemarker.ext.beans;
 
 import java.beans.MethodDescriptor;
+import java.util.List;
 
 /**
  * Used for JUnit testing method-order dependence bugs via
@@ -27,6 +28,9 @@ import java.beans.MethodDescriptor;
  */
 interface MethodSorter {
 
-    MethodDescriptor[] sortMethodDescriptors(MethodDescriptor[] methodDescriptors);
+    /**
+     * Sorts the methods in place (that is, by modifying the parameter list).
+     */
+    void sortMethodDescriptors(List<MethodDescriptor> methodDescriptors);
     
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/src/main/java/freemarker/ext/beans/_MethodUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/_MethodUtil.java b/src/main/java/freemarker/ext/beans/_MethodUtil.java
index c313309..782b944 100644
--- a/src/main/java/freemarker/ext/beans/_MethodUtil.java
+++ b/src/main/java/freemarker/ext/beans/_MethodUtil.java
@@ -291,4 +291,30 @@ public final class _MethodUtil {
                 "; see cause exception in the Java stack trace.");
     }
 
+    /**
+     * Extracts the JavaBeans property from a reader method name, or returns {@code null} if the method name doesn't
+     * look like a reader method name. 
+     */
+    public static String getBeanPropertyNameFromReaderMethodName(String name, Class<?> returnType) {
+        int start;
+        if (name.startsWith("get")) {
+            start = 3;
+        } else if (returnType == boolean.class && name.startsWith("is")) {
+            start = 2;
+        } else {
+            return null;
+        }
+        int ln = name.length();
+        
+        if (start == ln) {
+            return null;
+        }
+        char c1 = name.charAt(start);
+        
+        return start + 1 < ln && Character.isUpperCase(name.charAt(start + 1)) && Character.isUpperCase(c1)
+                ? name.substring(start) // getFOOBar => "FOOBar" (not lower case) according the JavaBeans spec.
+                : new StringBuilder(ln - start).append(Character.toLowerCase(c1)).append(name, start + 1, ln)
+                        .toString();
+    }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/src/main/java/freemarker/template/Configuration.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/Configuration.java b/src/main/java/freemarker/template/Configuration.java
index 4405f70..a34c605 100644
--- a/src/main/java/freemarker/template/Configuration.java
+++ b/src/main/java/freemarker/template/Configuration.java
@@ -814,6 +814,14 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
      *          {@link Configurable}-s always do this filtering regardless of the incompatible improvements setting. 
      *     </ul>
      *   </li>
+     *   <li><p>
+     *     2.3.26 (or higher):
+     *     <ul>
+     *       <li><p>
+     *          {@link BeansWrapper} and {@link DefaultObjectWrapper} now exposes Java 8 default methods (and the bean
+     *          properties they define); see {@link BeansWrapper#BeansWrapper(Version)}. 
+     *     </ul>
+     *   </li>
      * </ul>
      * 
      * @throws IllegalArgumentException

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index 1b2e8de..3e06a7b 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -26845,6 +26845,28 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
 
           <itemizedlist>
             <listitem>
+              <para><link
+              xlink:href="https://issues.apache.org/jira/browse/FREEMARKER-24">FREEMARKER-24</link>:
+              Added workaround (not enabled by default) to expose Java 8
+              default methods (and the bean properties they define) to
+              templates, despite that
+              <literal>java.beans.Introspector</literal> (the official
+              JavaBeans introspector) ignores them, at least as of JRE
+              1.8.0_66. To enable this workaround, either increase the value
+              of the <literal>incompatibleImprovements</literal> constructor
+              argument of <literal>DefaultObjectWrapper</literal> or
+              <literal>BeansWrapper</literal> the used to 2.3.26, or set its
+              <literal>treatDefaultMethodsAsBeanMembers</literal> setting to
+              <literal>true</literal>. Note that if you leave the
+              <literal>object_wrapper</literal> setting of the
+              <literal>Configuration</literal> on its default, it's enough to
+              increase the <literal>incompatibleImprovements</literal> setting
+              of the <literal>Configuration</literal> to 2.3.26, as that's
+              inherited by the default <literal>object_wrapper</literal>.
+              </para>
+            </listitem>
+
+            <listitem>
               <para>Added the
               <literal>freemarker.template.TemplateNodeModelEx</literal>
               interface which extends the <literal>TemplateNodeModel</literal>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/src/test/java/freemarker/ext/beans/AlphabeticalMethodSorter.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/AlphabeticalMethodSorter.java b/src/test/java/freemarker/ext/beans/AlphabeticalMethodSorter.java
index 3adbaa8..fa2e7d7 100644
--- a/src/test/java/freemarker/ext/beans/AlphabeticalMethodSorter.java
+++ b/src/test/java/freemarker/ext/beans/AlphabeticalMethodSorter.java
@@ -20,10 +20,9 @@
 package freemarker.ext.beans;
 
 import java.beans.MethodDescriptor;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.List;
 
 class AlphabeticalMethodSorter implements MethodSorter {
 
@@ -33,15 +32,13 @@ class AlphabeticalMethodSorter implements MethodSorter {
         this.desc = desc;
     }
 
-    public MethodDescriptor[] sortMethodDescriptors(MethodDescriptor[] methodDescriptors) {
-        ArrayList<MethodDescriptor> ls = new ArrayList<MethodDescriptor>(Arrays.asList(methodDescriptors));
-        Collections.sort(ls, new Comparator<MethodDescriptor>() {
+    public void sortMethodDescriptors(List<MethodDescriptor> methodDescriptors) {
+        Collections.sort(methodDescriptors, new Comparator<MethodDescriptor>() {
             public int compare(MethodDescriptor o1, MethodDescriptor o2) {
                 int res = o1.getMethod().toString().compareTo(o2.getMethod().toString());
                 return desc ? -res : res;
             }
         });
-        return ls.toArray(new MethodDescriptor[ls.size()]);
     }
     
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/src/test/java/freemarker/ext/beans/BeansWrapperJava8Test.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/BeansWrapperJava8Test.java b/src/test/java/freemarker/ext/beans/BeansWrapperJava8Test.java
new file mode 100644
index 0000000..4312742
--- /dev/null
+++ b/src/test/java/freemarker/ext/beans/BeansWrapperJava8Test.java
@@ -0,0 +1,221 @@
+package freemarker.ext.beans;
+
+import static org.junit.Assert.*;
+
+import java.util.Collections;
+
+import org.junit.Test;
+
+import freemarker.template.Configuration;
+import freemarker.template.TemplateHashModel;
+import freemarker.template.TemplateMethodModelEx;
+import freemarker.template.TemplateModelException;
+import freemarker.template.TemplateNumberModel;
+import freemarker.template.TemplateScalarModel;
+import freemarker.template.TemplateSequenceModel;
+
+public class BeansWrapperJava8Test {
+
+    @Test
+    public void testDefaultMethodNotRecognized() throws TemplateModelException {
+        BeansWrapperBuilder owb = new BeansWrapperBuilder(Configuration.VERSION_2_3_0);
+        // owb.setTreatDefaultMethodsAsBeanMembers(false);
+        BeansWrapper ow = owb.build();
+        TemplateHashModel wrappedBean = (TemplateHashModel) ow.wrap(new Java8DefaultMethodsBean());
+        
+        {
+            TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(Java8DefaultMethodsBean.NORMAL_PROP);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.NORMAL_PROP_VALUE, prop.getAsString());
+        }
+        {
+            // This is overridden in the subclass, so it's visible even without default method support: 
+            TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(
+                    Java8DefaultMethodsBean.DEFAULT_METHOD_PROP_2);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.PROP_2_OVERRIDE_VALUE, prop.getAsString());
+        }
+        assertNull(wrappedBean.get(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_PROP));
+        assertNull(wrappedBean.get(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP));
+        {
+            // We don't see the default method indexed reader, but see the plain reader method in the subclass.
+            TemplateNumberModel prop = (TemplateNumberModel) wrappedBean.get(
+                    Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.NOT_AN_INDEXED_PROP_VALUE, prop.getAsNumber());
+        }
+        {
+            // We don't see the default method non-indexed reader that would spoil the indexed reader in the subclass.
+            TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
+                    Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.NOT_AN_INDEXED_PROP_2_VALUE,
+                    ((TemplateScalarModel) prop.get(0)).getAsString());
+        }
+        {
+            // We don't see the default method non-indexed reader that would spoil the indexed reader in the subclass.
+            TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
+                    Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.NOT_AN_INDEXED_PROP_3_VALUE,
+                    ((TemplateNumberModel) prop.get(0)).getAsNumber());
+        }
+        {
+            // We don't see the default method indexed reader, but see the plain array reader in the subclass.
+            TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
+                    Java8DefaultMethodsBean.DEFAULT_METHOD_INDEXED_PROP_2);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.ARRAY_PROP_2_VALUE_0,
+                    ((TemplateScalarModel) prop.get(0)).getAsString());
+        }
+        {
+            // Only present in the subclass.
+            TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
+                    Java8DefaultMethodsBean.INDEXED_PROP_4);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.INDEXED_PROP_4_VALUE,
+                    ((TemplateScalarModel) prop.get(0)).getAsString());
+        }        
+        {
+            // We don't see the default method non-indexed reader
+            TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
+                    Java8DefaultMethodsBean.DEFAULT_METHOD_INDEXED_PROP_3);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.INDEXED_PROP_3_VALUE,
+                    ((TemplateScalarModel) prop.get(0)).getAsString());
+        }
+        
+        {
+            TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
+                    Java8DefaultMethodsBean.NORMAL_ACTION);
+            assertNotNull(action);
+            assertEquals(
+                    Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE,
+                    ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
+        }
+        assertNull(wrappedBean.get(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_ACTION));
+        {
+            TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
+                    Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION);
+            assertNotNull(action);
+            assertEquals(
+                    Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION_RETURN_VALUE,
+                    ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
+        }
+    }
+    
+    @Test
+    public void testDefaultMethodRecognized() throws TemplateModelException {
+        BeansWrapperBuilder owb = new BeansWrapperBuilder(Configuration.VERSION_2_3_0);
+        owb.setTreatDefaultMethodsAsBeanMembers(true);
+        BeansWrapper ow = owb.build();
+        TemplateHashModel wrappedBean = (TemplateHashModel) ow.wrap(new Java8DefaultMethodsBean());
+        
+        {
+            TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(Java8DefaultMethodsBean.NORMAL_PROP);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.NORMAL_PROP_VALUE, prop.getAsString());
+        }
+        {
+            // This is overridden in the subclass, so it's visible even without default method support: 
+            TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(
+                    Java8DefaultMethodsBean.DEFAULT_METHOD_PROP_2);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.PROP_2_OVERRIDE_VALUE, prop.getAsString());
+        }
+        {
+            TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(
+                    Java8DefaultMethodsBeanBase.DEFAULT_METHOD_PROP);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_PROP_VALUE, prop.getAsString());
+        }
+        {
+            TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
+                    Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP_VALUE,
+                    ((TemplateScalarModel) prop.get(0)).getAsString());
+        }
+        {
+            // We see default method indexed read method, but it's invalidated by normal getter in the subclass
+            TemplateNumberModel prop = (TemplateNumberModel) wrappedBean.get(
+                    Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.NOT_AN_INDEXED_PROP_VALUE, prop.getAsNumber());
+        }
+        {
+            // The default method read method invalidates the indexed read method in the subclass
+            TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(
+                    Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2_VALUE, prop.getAsString());
+        }
+        {
+            // The default method read method invalidates the indexed read method in the subclass
+            TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
+                    Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3_VALUE_0,
+                    ((TemplateScalarModel) prop.get(0)).getAsString());
+        }
+        {
+            // We see the default method indexed reader, which overrides the plain array reader in the subclass.
+            TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
+                    Java8DefaultMethodsBean.DEFAULT_METHOD_INDEXED_PROP_2);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.DEFAULT_METHOD_INDEXED_PROP_2_VALUE_0,
+                    ((TemplateScalarModel) prop.get(0)).getAsString());
+        }
+        {
+            // We do see the default method non-indexed reader, but the subclass has a matching indexed reader, so that
+            // takes over.
+            TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
+                    Java8DefaultMethodsBean.DEFAULT_METHOD_INDEXED_PROP_3);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.INDEXED_PROP_3_VALUE,
+                    ((TemplateScalarModel) prop.get(0)).getAsString());
+        }        
+        {
+            // Only present in the subclass.
+            TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(
+                    Java8DefaultMethodsBean.INDEXED_PROP_4);
+            assertNotNull(prop);
+            assertEquals(Java8DefaultMethodsBean.INDEXED_PROP_4_VALUE,
+                    ((TemplateScalarModel) prop.get(0)).getAsString());
+        }        
+        {
+            TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
+                    Java8DefaultMethodsBean.NORMAL_ACTION);
+            assertNotNull(action);
+            assertEquals(
+                    Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE,
+                    ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
+        }
+        
+        {
+            TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
+                    Java8DefaultMethodsBean.NORMAL_ACTION);
+            assertNotNull(action);
+            assertEquals(
+                    Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE,
+                    ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
+        }
+        {
+            TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
+                    Java8DefaultMethodsBean.DEFAULT_METHOD_ACTION);
+            assertNotNull(action);
+            assertEquals(
+                    Java8DefaultMethodsBean.DEFAULT_METHOD_ACTION_RETURN_VALUE,
+                    ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
+        }
+        {
+            TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
+                    Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION);
+            assertNotNull(action);
+            assertEquals(
+                    Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION_RETURN_VALUE,
+                    ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/src/test/java/freemarker/ext/beans/GetPropertyNameFromReaderMethodNameTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/GetPropertyNameFromReaderMethodNameTest.java b/src/test/java/freemarker/ext/beans/GetPropertyNameFromReaderMethodNameTest.java
new file mode 100644
index 0000000..ce95b99
--- /dev/null
+++ b/src/test/java/freemarker/ext/beans/GetPropertyNameFromReaderMethodNameTest.java
@@ -0,0 +1,43 @@
+package freemarker.ext.beans;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class GetPropertyNameFromReaderMethodNameTest {
+    
+    @Test
+    public void test() {
+       assertEquals("foo", _MethodUtil.getBeanPropertyNameFromReaderMethodName("getFoo", String.class)); 
+       assertEquals("fo", _MethodUtil.getBeanPropertyNameFromReaderMethodName("getFo", String.class)); 
+       assertEquals("f", _MethodUtil.getBeanPropertyNameFromReaderMethodName("getF", String.class));
+       
+       assertEquals("FO", _MethodUtil.getBeanPropertyNameFromReaderMethodName("getFO", String.class)); 
+       assertEquals("FOo", _MethodUtil.getBeanPropertyNameFromReaderMethodName("getFOo", String.class)); 
+       assertEquals("FOO", _MethodUtil.getBeanPropertyNameFromReaderMethodName("getFOO", String.class));
+       assertEquals("fooBar", _MethodUtil.getBeanPropertyNameFromReaderMethodName("getFooBar", String.class));
+       assertEquals("FOoBar", _MethodUtil.getBeanPropertyNameFromReaderMethodName("getFOoBar", String.class));
+
+       assertEquals("foo", _MethodUtil.getBeanPropertyNameFromReaderMethodName("getFoo", boolean.class)); 
+       assertEquals("foo", _MethodUtil.getBeanPropertyNameFromReaderMethodName("isFoo", boolean.class)); 
+       assertNull(_MethodUtil.getBeanPropertyNameFromReaderMethodName("isFoo", Boolean.class));
+       assertNull(_MethodUtil.getBeanPropertyNameFromReaderMethodName("isFoo", String.class));
+       assertEquals("f", _MethodUtil.getBeanPropertyNameFromReaderMethodName("isF", boolean.class)); 
+       
+       assertEquals("foo", _MethodUtil.getBeanPropertyNameFromReaderMethodName("getfoo", String.class)); 
+       assertEquals("fo", _MethodUtil.getBeanPropertyNameFromReaderMethodName("getfo", String.class)); 
+       assertEquals("f", _MethodUtil.getBeanPropertyNameFromReaderMethodName("getf", String.class));
+       assertEquals("_f", _MethodUtil.getBeanPropertyNameFromReaderMethodName("get_f", String.class));
+       assertEquals("_F", _MethodUtil.getBeanPropertyNameFromReaderMethodName("get_F", String.class));
+       assertEquals("_", _MethodUtil.getBeanPropertyNameFromReaderMethodName("get_", String.class));
+       assertEquals("1f", _MethodUtil.getBeanPropertyNameFromReaderMethodName("get1f", String.class));
+       assertEquals("1", _MethodUtil.getBeanPropertyNameFromReaderMethodName("get1", String.class));
+       assertEquals("1F", _MethodUtil.getBeanPropertyNameFromReaderMethodName("get1F", String.class));
+       assertEquals("foo", _MethodUtil.getBeanPropertyNameFromReaderMethodName("isfoo", boolean.class)); 
+       
+       assertNull(_MethodUtil.getBeanPropertyNameFromReaderMethodName("get", String.class));
+       assertNull(_MethodUtil.getBeanPropertyNameFromReaderMethodName("is", boolean.class));
+       assertNull(_MethodUtil.getBeanPropertyNameFromReaderMethodName("f", String.class));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBean.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBean.java b/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBean.java
new file mode 100644
index 0000000..0687d84
--- /dev/null
+++ b/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBean.java
@@ -0,0 +1,65 @@
+package freemarker.ext.beans;
+
+public class Java8DefaultMethodsBean implements Java8DefaultMethodsBeanBase {
+    
+    static final String NORMAL_PROP = "normalProp";
+    static final String NORMAL_PROP_VALUE = "normalPropValue";
+    static final String PROP_2_OVERRIDE_VALUE = "prop2OverrideValue";
+    static final String INDEXED_PROP_3_VALUE = "indexedProp3Value";
+    static final int NOT_AN_INDEXED_PROP_VALUE = 1;
+    static final String ARRAY_PROP_2_VALUE_0 = "arrayProp2[0].value";
+    static final int NOT_AN_INDEXED_PROP_3_VALUE = 3;
+    static final String NOT_AN_INDEXED_PROP_2_VALUE = "notAnIndecedProp2Value";
+    static final String INDEXED_PROP_4 = "indexedProp4";
+    static final String INDEXED_PROP_4_VALUE = "indexedProp4Value[0]";
+    static final String NORMAL_ACTION = "normalAction";
+    static final String NORMAL_ACTION_RETURN_VALUE = "normalActionReturnValue";
+    static final String OVERRIDDEN_DEFAULT_METHOD_ACTION_RETURN_VALUE = "overriddenValue";
+    
+    public String getNormalProp() {
+        return NORMAL_PROP_VALUE;
+    }
+    
+    /** Override */
+    public String getDefaultMethodProp2() {
+        return PROP_2_OVERRIDE_VALUE;
+    }
+    
+    public String[] getDefaultMethodIndexedProp2() {
+        return new String[] { ARRAY_PROP_2_VALUE_0 };
+    }
+
+    /**
+     * There's a matching non-indexed reader method in the base class, but as this is indexed, it takes over. 
+     */
+    public String getDefaultMethodIndexedProp3(int index) {
+        return INDEXED_PROP_3_VALUE;
+    }
+    
+    public int getDefaultMethodNotAnIndexedProp() {
+        return NOT_AN_INDEXED_PROP_VALUE;
+    }
+
+    /** Actually, this will be indexed if the default method support is off. */
+    public String getDefaultMethodNotAnIndexedProp2(int index) {
+        return NOT_AN_INDEXED_PROP_2_VALUE;
+    }
+    
+    /** Actually, this will be indexed if the default method support is off. */
+    public int getDefaultMethodNotAnIndexedProp3(int index) {
+        return NOT_AN_INDEXED_PROP_3_VALUE;
+    }
+    
+    public String getIndexedProp4(int index) {
+        return INDEXED_PROP_4_VALUE;
+    }
+    
+    public String normalAction() {
+        return NORMAL_ACTION_RETURN_VALUE;
+    }
+    
+    public String overriddenDefaultMethodAction() {
+        return OVERRIDDEN_DEFAULT_METHOD_ACTION_RETURN_VALUE;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBeanBase.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBeanBase.java b/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBeanBase.java
new file mode 100644
index 0000000..c912ace
--- /dev/null
+++ b/src/test/java/freemarker/ext/beans/Java8DefaultMethodsBeanBase.java
@@ -0,0 +1,72 @@
+package freemarker.ext.beans;
+
+public interface Java8DefaultMethodsBeanBase {
+    
+    static final String DEFAULT_METHOD_PROP = "defaultMethodProp";
+    static final String DEFAULT_METHOD_PROP_VALUE = "defaultMethodPropValue";
+    static final String DEFAULT_METHOD_PROP_2 = "defaultMethodProp2";
+    static final String DEFAULT_METHOD_INDEXED_PROP = "defaultMethodIndexedProp";
+    static final String DEFAULT_METHOD_INDEXED_PROP_VALUE = "defaultMethodIndexedPropValue";
+    static final String DEFAULT_METHOD_INDEXED_PROP_2 = "defaultMethodIndexedProp2";
+    static final String DEFAULT_METHOD_INDEXED_PROP_2_VALUE_0 = "defaultMethodIndexedProp2(0).value";
+    static final String DEFAULT_METHOD_INDEXED_PROP_3 = "defaultMethodIndexedProp3";
+    static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP = "defaultMethodNotAnIndexedProp";
+    static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP_VALUE = "defaultMethodNotAnIndexedPropValue";
+    static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2 = "defaultMethodNotAnIndexedProp2";
+    static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2_VALUE = "defaultMethodNotAnIndexedProp2Value";
+    static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3 = "defaultMethodNotAnIndexedProp3";
+    static final String DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3_VALUE_0 = "defaultMethodNotAnIndexedProp3Value[0]";
+    static final String DEFAULT_METHOD_ACTION = "defaultMethodAction";
+    static final String DEFAULT_METHOD_ACTION_RETURN_VALUE = "defaultMethodActionReturnValue";
+    static final String OVERRIDDEN_DEFAULT_METHOD_ACTION = "overriddenDefaultMethodAction";
+
+    default String getDefaultMethodProp() {
+        return DEFAULT_METHOD_PROP_VALUE;
+    }
+
+    default String getDefaultMethodProp2() {
+        return "";
+    }
+    
+    default String getDefaultMethodIndexedProp(int i) {
+        return DEFAULT_METHOD_INDEXED_PROP_VALUE;
+    }
+
+    /**
+     * Will be kept as there will be a matching non-indexed read method in the subclass. 
+     */
+    default String getDefaultMethodIndexedProp2(int i) {
+        return DEFAULT_METHOD_INDEXED_PROP_2_VALUE_0;
+    }
+
+    /**
+     * This is not an indexed reader method, but a matching indexed reader method will be added in the subclass. 
+     */
+    default String[] getDefaultMethodIndexedProp3() {
+        return new String[] {""};
+    }
+    
+    /** Will be discarded because of a non-matching non-indexed read method in a subclass */
+    default String getDefaultMethodNotAnIndexedProp(int i) {
+        return "";
+    }
+    
+    /** The subclass will try to override this with a non-matching indexed reader, but this will be stronger. */
+    default String getDefaultMethodNotAnIndexedProp2() {
+        return DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2_VALUE;
+    }
+
+    /** The subclass will try to override this with a non-matching indexed reader, but this will be stronger. */
+    default String[] getDefaultMethodNotAnIndexedProp3() {
+        return new String[] { DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3_VALUE_0 };
+    }
+    
+    default String defaultMethodAction() {
+        return DEFAULT_METHOD_ACTION_RETURN_VALUE;
+    }
+
+    default Object overriddenDefaultMethodAction() {
+        return null;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/src/test/java/freemarker/template/ConfigurationTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/template/ConfigurationTest.java b/src/test/java/freemarker/template/ConfigurationTest.java
index e3117ad..a4dbfcc 100644
--- a/src/test/java/freemarker/template/ConfigurationTest.java
+++ b/src/test/java/freemarker/template/ConfigurationTest.java
@@ -162,6 +162,11 @@ public class ConfigurationTest extends TestCase {
         cfg = new Configuration(Configuration.VERSION_2_3_22);
         assertUses2322ObjectWrapper(cfg);
         assertUsesNewTemplateLoader(cfg);
+        
+        cfg = new Configuration(Configuration.VERSION_2_3_25);
+        assertFalse(((DefaultObjectWrapper) cfg.getObjectWrapper()).getTreatDefaultMethodsAsBeanMembers());
+        cfg.setIncompatibleImprovements(Configuration.VERSION_2_3_26);
+        assertTrue(((DefaultObjectWrapper) cfg.getObjectWrapper()).getTreatDefaultMethodsAsBeanMembers());
     }
 
     private void assertUses2322ObjectWrapper(Configuration cfg) {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/173abfe9/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/template/DefaultObjectWrapperTest.java b/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
index 36c12fd..5d3ad2b 100644
--- a/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
+++ b/src/test/java/freemarker/template/DefaultObjectWrapperTest.java
@@ -90,7 +90,7 @@ public class DefaultObjectWrapperTest {
         expected.add(Configuration.VERSION_2_3_22); // no non-BC change in 2.3.23
         expected.add(Configuration.VERSION_2_3_24);
         expected.add(Configuration.VERSION_2_3_24); // no non-BC change in 2.3.25
-        expected.add(Configuration.VERSION_2_3_24); // no non-BC change in 2.3.26
+        expected.add(Configuration.VERSION_2_3_26);
 
         List<Version> actual = new ArrayList<Version>();
         for (int i = _TemplateAPI.VERSION_INT_2_3_0; i <= Configuration.getVersion().intValue(); i++) {


[11/25] incubator-freemarker git commit: Added /.out to gitignore

Posted by dd...@apache.org.
Added /.out to gitignore


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

Branch: refs/heads/2.3
Commit: 393d3bebb0c560ff1e5857d76a9ab29e0f244395
Parents: 7180eed
Author: ddekany <dd...@apache.org>
Authored: Tue Mar 7 15:27:15 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Tue Mar 7 15:27:15 2017 +0100

----------------------------------------------------------------------
 .gitignore | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/393d3beb/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index f30cd69..28532ff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,7 @@
 *.iws
 *.ipr
 .idea_modules/
+.out/
 
 *.tmp
 *.bak