You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2016/06/08 21:09:23 UTC
[3/3] incubator-freemarker git commit: Added duplicate filtering to
setAutoIncludes(List),
if called on non-Configuration or if IcI >= 2.3.25. Allowing duplicates was an
oversight in earlier versions.
Added duplicate filtering to setAutoIncludes(List), if called on non-Configuration or if IcI >= 2.3.25. Allowing duplicates was an oversight in earlier versions.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/6c335728
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/6c335728
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/6c335728
Branch: refs/heads/2.3-gae
Commit: 6c335728fd27857f0e1fd59d206c346fcaa922f7
Parents: 7495228
Author: ddekany <dd...@apache.org>
Authored: Wed Jun 8 23:09:08 2016 +0200
Committer: ddekany <dd...@apache.org>
Committed: Wed Jun 8 23:09:08 2016 +0200
----------------------------------------------------------------------
src/main/java/freemarker/core/Configurable.java | 24 +++++-----
.../java/freemarker/template/Configuration.java | 31 +++++++++++--
.../core/AutoImportAndIncludeTest.java | 47 ++++++++++++++++----
.../core/TemplateConfigurationTest.java | 3 +-
4 files changed, 81 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6c335728/src/main/java/freemarker/core/Configurable.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Configurable.java b/src/main/java/freemarker/core/Configurable.java
index fbee5a6..d71b64f 100644
--- a/src/main/java/freemarker/core/Configurable.java
+++ b/src/main/java/freemarker/core/Configurable.java
@@ -1763,29 +1763,29 @@ public class Configurable {
* the auto-includes, hence the namespace variables are accessible for the auto-included templates.
*
* <p>
- * You should avoid adding the same auto-include for multiple times, as you can easily end up including the same
- * template for multiple times. Calling {@link #addAutoInclude(String)} with an already added template name will
- * just move that to the end of the auto-include list, but the same won't happen when using
- * {@link #setAutoIncludes(List)}, nor when the same string occurs on a different {@link Configurable} level.
+ * Calling {@link #addAutoInclude(String)} with an already added template name will just move that to the end of the
+ * auto-include list (within the same {@link Configurable} level). This works even if the same template name appears
+ * on different {@link Configurable} levels, in which case only the inclusion on the lowest (child) level will be
+ * executed.
*
* @see #setAutoIncludes(List)
*/
public void addAutoInclude(String templateName) {
- addAutoInclude(templateName, true);
+ addAutoInclude(templateName, false);
}
/**
- * @param removeDuplicate
+ * @param keepDuplicate
* Used for emulating legacy glitch, where duplicates weren't removed if the inclusion was added via
- * {@link #setAutoIncludes(List)}, but were if it was added via {@link #addAutoInclude(String)}.
+ * {@link #setAutoIncludes(List)}.
*/
- private void addAutoInclude(String templateName, boolean removeDuplicate) {
+ private void addAutoInclude(String templateName, boolean keepDuplicate) {
// "synchronized" is removed from the API as it's not safe to set anything after publishing the Configuration
synchronized (this) {
if (autoIncludes == null) {
initAutoIncludesList();
} else {
- if (removeDuplicate) {
+ if (!keepDuplicate) {
autoIncludes.remove(templateName);
}
}
@@ -1799,6 +1799,9 @@ public class Configurable {
/**
* Removes all auto-includes, then calls {@link #addAutoInclude(String)} for each {@link List} items.
+ *
+ * <p>Before {@linkplain Configuration#Configuration(Version) incompatible improvements} 2.3.25 it doesn't filter
+ * out duplicates from the list if this method was called on a {@link Configuration} instance.
*/
public void setAutoIncludes(List templateNames) {
NullArgumentException.check("templateNames", templateNames);
@@ -1811,7 +1814,8 @@ public class Configurable {
if (!(templateName instanceof String)) {
throw new IllegalArgumentException("List items must be String-s.");
}
- addAutoInclude((String) templateName, false);
+ addAutoInclude((String) templateName, this instanceof Configuration && ((Configuration) this)
+ .getIncompatibleImprovements().intValue() < _TemplateAPI.VERSION_INT_2_3_25);
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6c335728/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 07f921a..9565258 100644
--- a/src/main/java/freemarker/template/Configuration.java
+++ b/src/main/java/freemarker/template/Configuration.java
@@ -426,6 +426,9 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
/** FreeMarker version 2.3.24 (an {@link #Configuration(Version) incompatible improvements break-point}) */
public static final Version VERSION_2_3_24 = new Version(2, 3, 24);
+ /** FreeMarker version 2.3.25 (an {@link #Configuration(Version) incompatible improvements break-point}) */
+ public static final Version VERSION_2_3_25 = new Version(2, 3, 25);
+
/** The default of {@link #getIncompatibleImprovements()}, currently {@link #VERSION_2_3_0}. */
public static final Version DEFAULT_INCOMPATIBLE_IMPROVEMENTS = Configuration.VERSION_2_3_0;
/** @deprecated Use {@link #DEFAULT_INCOMPATIBLE_IMPROVEMENTS} instead. */
@@ -820,6 +823,16 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
* (They shouldn't implement either, but this is historical heritage.)
* </ul>
* </li>
+ * <li><p>
+ * 2.3.25 (or higher):
+ * <ul>
+ * <li><p>
+ * When calling {@link Configurable#setAutoIncludes(List)} on a {@link Configuration}, it filters out
+ * duplicates from the list, similarly as repeatedly calling {@link Configurable#addAutoInclude(String)}
+ * would, hence avoiding repeated inclusions. Calling {@link Configurable#setAutoIncludes(List)} on other
+ * {@link Configurable}-s always do this filtering regardless of the incompatible improvements setting.
+ * </ul>
+ * </li>
* </ul>
*
* @throws IllegalArgumentException
@@ -3095,18 +3108,28 @@ public class Configuration extends Configurable implements Cloneable, ParserConf
private void doAutoIncludes(Environment env, Template t) throws TemplateException, IOException,
TemplateNotFoundException, MalformedTemplateNameException, ParseException {
+ // We can't store autoIncludes in LinkedHashSet-s because setAutoIncludes(List) allows duplicates,
+ // unfortunately. Yet we have to prevent duplicates among Configuration levels, with the lowest levels having
+ // priority. So we build some Set-s to do that, but we avoid the most common cases where they aren't needed.
+
+ List<String> tAutoIncludes = t.getAutoIncludesWithoutFallback();
+ List<String> envAutoIncludes = env.getAutoIncludesWithoutFallback();
+
for (String templateName : getAutoIncludesWithoutFallback()) {
- env.include(getTemplate(templateName, env.getLocale()));
+ if ((tAutoIncludes == null || !tAutoIncludes.contains(templateName))
+ && (envAutoIncludes == null || !envAutoIncludes.contains(templateName))) {
+ env.include(getTemplate(templateName, env.getLocale()));
+ }
}
- List<String> tAutoIncludes = t.getAutoIncludesWithoutFallback();
if (tAutoIncludes != null) {
for (String templateName : tAutoIncludes) {
- env.include(getTemplate(templateName, env.getLocale()));
+ if (envAutoIncludes == null || !envAutoIncludes.contains(templateName)) {
+ env.include(getTemplate(templateName, env.getLocale()));
+ }
}
}
- List<String> envAutoIncludes = env.getAutoIncludesWithoutFallback();
if (envAutoIncludes != null) {
for (String templateName : envAutoIncludes) {
env.include(getTemplate(templateName, env.getLocale()));
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6c335728/src/test/java/freemarker/core/AutoImportAndIncludeTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/AutoImportAndIncludeTest.java b/src/test/java/freemarker/core/AutoImportAndIncludeTest.java
index 91faa4b..c813e69 100644
--- a/src/test/java/freemarker/core/AutoImportAndIncludeTest.java
+++ b/src/test/java/freemarker/core/AutoImportAndIncludeTest.java
@@ -160,9 +160,9 @@ public class AutoImportAndIncludeTest extends TemplateTest {
assertEquals("T2;T3;In main: t2;t3;", sw.toString());
}
}
-
+
@Test
- public void test3LayerIncludesNoClashes2() throws Exception {
+ public void test3LayerIncludeClashes() throws Exception {
Configuration cfg = getConfiguration();
cfg.addAutoInclude("t1.ftl");
cfg.addAutoInclude("t2.ftl");
@@ -180,17 +180,44 @@ public class AutoImportAndIncludeTest extends TemplateTest {
env.addAutoInclude("t3.ftl");
env.process();
- assertEquals("T1;T2;T3;T2;T3;In main: t1;t2;t3;t2;t3;", sw.toString());
+ assertEquals("T1;T2;T3;In main: t1;t2;t3;", sw.toString());
+ }
+
+ {
+ Template t = cfg.getTemplate("main2.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+ env.addAutoInclude("t3.ftl");
+
+ env.process();
+ assertEquals("T1;T2;T3;In main2: t1;t2;t3;", sw.toString());
+ }
+
+ {
+ Template t = cfg.getTemplate("main.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+
+ env.process();
+ assertEquals("T1;T3;T2;In main: t1;t3;t2;", sw.toString());
+ }
+
+ {
+ Template t = cfg.getTemplate("main.ftl");
+ StringWriter sw = new StringWriter();
+ Environment env = t.createProcessingEnvironment(null, sw);
+ env.addAutoInclude("t1.ftl");
+
+ env.process();
+ assertEquals("T3;T2;T1;In main: t3;t2;t1;", sw.toString());
}
}
-
+
@Test
- public void test3LayerIncludesClashes() throws Exception {
+ public void test3LayerIncludesClashes2() throws Exception {
Configuration cfg = getConfiguration();
cfg.addAutoInclude("t1.ftl");
- cfg.addAutoInclude("t3.ftl");
- cfg.addAutoInclude("t2.ftl");
- cfg.addAutoInclude("t3.ftl");
+ cfg.addAutoInclude("t1.ftl");
TemplateConfiguration tc = new TemplateConfiguration();
tc.addAutoInclude("t2.ftl");
@@ -204,9 +231,11 @@ public class AutoImportAndIncludeTest extends TemplateTest {
Environment env = t.createProcessingEnvironment(null, sw);
env.addAutoInclude("t3.ftl");
env.addAutoInclude("t3.ftl");
+ env.addAutoInclude("t1.ftl");
+ env.addAutoInclude("t1.ftl");
env.process();
- assertEquals("T1;T2;T3;T2;T3;In main: t1;t2;t3;t2;t3;", sw.toString());
+ assertEquals("T2;T3;T1;In main: t2;t3;t1;", sw.toString());
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6c335728/src/test/java/freemarker/core/TemplateConfigurationTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/TemplateConfigurationTest.java b/src/test/java/freemarker/core/TemplateConfigurationTest.java
index 5b05e48..861d1f7 100644
--- a/src/test/java/freemarker/core/TemplateConfigurationTest.java
+++ b/src/test/java/freemarker/core/TemplateConfigurationTest.java
@@ -307,7 +307,8 @@ public class TemplateConfigurationTest {
propDesc2.getWriteMethod().invoke(tc2, value2);
tc1.merge(tc2);
- if (propDesc1.getName().equals(propDesc2.getName()) && value1 instanceof List) {
+ if (propDesc1.getName().equals(propDesc2.getName()) && value1 instanceof List
+ && !propDesc1.getName().equals("autoIncludes")) {
assertEquals("For " + propDesc1.getName(),
ListUtils.union((List) value1, (List) value1), propDesc1.getReadMethod().invoke(tc1));
} else { // Values of the same setting merged