Added the `templateResolver` Configuration setting. This allows replacing the whole template lookup, loading and caching logic with a custom implementation, giving total control over this aspect of FreeMarker, in case replacing Configuration settings like `templateLoader` or `cacheStorage` wasn't enough. The `TemplateResolver` implementation declares which of the template resolution related Configuration settings it supports (for example, it may still want to rely on the `templateLoader`, but doesn't use the other settings). It's a template resolution related settings that the TemplateResolver doesn't support. The default implementation, `DefaultTemplateResolver`, supports all of them of course. Note that `TemplateCache` was removed, and was basically replaced by `DefaultTemplateResolver`.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/8915ac9b Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/8915ac9b Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/8915ac9b Branch: refs/heads/3 Commit: 8915ac9bd89ab75d187afd71b6b16619ee8b42c4 Parents: 2f1f291 Author: ddekany <[email protected]> Authored: Sun Jun 4 17:41:44 2017 +0200 Committer: ddekany <[email protected]> Committed: Wed Jun 7 00:48:23 2017 +0200 ---------------------------------------------------------------------- FM3-CHANGE-LOG.txt | 11 +- .../freemarker/core/ConfigurationTest.java | 98 +++-- .../core/CustomTemplateResolverTest.java | 390 +++++++++++++++++++ .../freemarker/core/IncludeAndImportTest.java | 79 ++-- .../freemarker/core/OutputFormatTest.java | 98 +++-- .../apache/freemarker/core/SQLTimeZoneTest.java | 26 +- .../freemarker/core/SpecialVariableTest.java | 46 ++- .../core/TemplateLookupStrategyTest.java | 12 +- .../DefaultTemplateResolverTest.java | 162 ++++---- .../impl/ExtendedDecimalFormatTest.java | 11 +- .../apache/freemarker/core/Configuration.java | 310 +++++++++++---- .../ConfigurationSettingValueException.java | 2 +- .../org/apache/freemarker/core/Environment.java | 19 +- .../freemarker/core/ParsingConfiguration.java | 5 +- .../core/SettingValueNotSetException.java | 4 - .../core/TemplateResolverDependenciesImpl.java | 120 ++++++ .../freemarker/core/TopLevelConfiguration.java | 69 +++- .../TemplateConfigurationFactory.java | 6 +- .../templateresolver/TemplateLoadingSource.java | 2 +- .../core/templateresolver/TemplateResolver.java | 154 ++++++-- .../TemplateResolverDependencies.java | 91 +++++ .../core/templateresolver/_CacheAPI.java | 43 -- .../impl/DefaultTemplateResolver.java | 206 +++++----- 23 files changed, 1411 insertions(+), 553 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8915ac9b/FM3-CHANGE-LOG.txt ---------------------------------------------------------------------- diff --git a/FM3-CHANGE-LOG.txt b/FM3-CHANGE-LOG.txt index b3676a9..7c4cfcf 100644 --- a/FM3-CHANGE-LOG.txt +++ b/FM3-CHANGE-LOG.txt @@ -80,9 +80,14 @@ the FreeMarer 3 changelog here: - Removed SimpleObjectWrapper deprecated paramerless constructor - Removed ResourceBundleLocalizedString and LocalizedString: Hardly anybody has discovered these, and they had no JUnit coverage. -- Added early draft of TemplateResolver, renamed TemplateCache to DefaultTemplateResolver. TemplateResolver is not - yet directly used in Configuration. This was only added in a hurry, so that it's visible why the - o.a.f.core.templateresolver subpackage name makes sense. +- Added the org.apache.freemarker.core.templateresolver.TemplateResolver class and the `templateResolver` Configuration + setting. This allows replacing the whole template lookup, loading and caching logic with a custom implementation, + giving total control over this aspect of FreeMarker, in case replacing Configuration settings like `templateLoader` + or `cacheStorage` wasn't enough. The `TemplateResolver` implementation declares which of the template resolution + related Configuration settings it supports (for example, it may still want to rely on the `templateLoader`, but + doesn't use the other settings). It's a template resolution related settings that the TemplateResolver doesn't + support. The default implementation, `DefaultTemplateResolver`, supports all of them of course. Note that the + `TemplateCache` was removed, and was basically replaced by `DefaultTemplateResolver`. - Marked most static utility classes as internal, and renamed them to start with "_" (for example StringUtils was renamed to _StringUtil, thus people won't accidentally use it when they wanted to autocomplete to Apache Commons StringUtil). Created published static utility class, o.a.f.core.util.FTLUtil, which contains some methods moved http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8915ac9b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurationTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurationTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurationTest.java index 8dccb2f..bbc542d 100644 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurationTest.java +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurationTest.java @@ -103,20 +103,14 @@ public class ConfigurationTest extends TestCase { // cfgB.setLogTemplateExceptions(true); { - Configuration cfg = cfgB.build(); assertTrue(cfgB.isLogTemplateExceptionsSet()); - assertTrue(cfg.isLogTemplateExceptionsSet()); assertTrue(cfgB.getLogTemplateExceptions()); - assertTrue(cfg.getLogTemplateExceptions()); } // for (int i = 0; i < 2; i++) { cfgB.unsetLogTemplateExceptions(); - Configuration cfg = cfgB.build(); assertFalse(cfgB.isLogTemplateExceptionsSet()); - assertTrue(cfg.isLogTemplateExceptionsSet()); assertFalse(cfgB.getLogTemplateExceptions()); - assertFalse(cfg.getLogTemplateExceptions()); } DefaultObjectWrapper dow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build(); @@ -408,20 +402,23 @@ public class ConfigurationTest extends TestCase { tl.putTemplate("a/b.ftl", "In a/b.ftl"); tl.putTemplate("b.ftl", "In b.ftl"); - Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0) - .templateLoader(tl); - { - cfgB.setTemplateNameFormat(DefaultTemplateNameFormatFM2.INSTANCE); - final Template template = cfgB.build().getTemplate("a/./../b.ftl"); + Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0) + .templateLoader(tl) + .templateNameFormat(DefaultTemplateNameFormatFM2.INSTANCE) + .build(); + final Template template = cfg.getTemplate("a/./../b.ftl"); assertEquals("a/b.ftl", template.getLookupName()); assertEquals("a/b.ftl", template.getSourceName()); assertEquals("In a/b.ftl", template.toString()); } { - cfgB.setTemplateNameFormat(DefaultTemplateNameFormat.INSTANCE); - final Template template = cfgB.build().getTemplate("a/./../b.ftl"); + Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0) + .templateLoader(tl) + .templateNameFormat(DefaultTemplateNameFormat.INSTANCE) + .build(); + final Template template = cfg.getTemplate("a/./../b.ftl"); assertEquals("b.ftl", template.getLookupName()); assertEquals("b.ftl", template.getSourceName()); assertEquals("In b.ftl", template.toString()); @@ -455,30 +452,28 @@ public class ConfigurationTest extends TestCase { } } - public void testTemplateLookupStrategyDefaultAndSet() throws Exception { - Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0); - assertSame(DefaultTemplateLookupStrategy.INSTANCE, cfgB.getTemplateLookupStrategy()); - assertSame(DefaultTemplateLookupStrategy.INSTANCE, cfgB.build().getTemplateLookupStrategy()); - - cfgB.setTemplateLoader(new ClassTemplateLoader(ConfigurationTest.class, "")); - assertSame(DefaultTemplateLookupStrategy.INSTANCE, cfgB.getTemplateLookupStrategy()); - Configuration cfg = cfgB.build(); + public void testTemplateLookupStrategyDefault() throws Exception { + Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0) + .templateLoader(new ClassTemplateLoader(ConfigurationTest.class, "")) + .build(); assertSame(DefaultTemplateLookupStrategy.INSTANCE, cfg.getTemplateLookupStrategy()); - cfg.getTemplate("toCache1.ftl"); + assertEquals("toCache1.ftl", cfg.getTemplate("toCache1.ftl").getSourceName()); + } + public void testTemplateLookupStrategyCustom() throws Exception { final TemplateLookupStrategy myStrategy = new TemplateLookupStrategy() { @Override public TemplateLookupResult lookup(TemplateLookupContext ctx) throws IOException { return ctx.lookupWithAcquisitionStrategy("toCache2.ftl"); } }; - cfgB.setTemplateLookupStrategy(myStrategy); - assertSame(myStrategy, cfgB.getTemplateLookupStrategy()); - cfg = cfgB.build(); - cfg.clearTemplateCache(); + + Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0) + .templateLoader(new ClassTemplateLoader(ConfigurationTest.class, "")) + .templateLookupStrategy(myStrategy) + .build(); assertSame(myStrategy, cfg.getTemplateLookupStrategy()); - Template template = cfg.getTemplate("toCache1.ftl"); - assertEquals("toCache2.ftl", template.getSourceName()); + assertEquals("toCache2.ftl", cfg.getTemplate("toCache1.ftl").getSourceName()); } public void testSetTemplateConfigurations() throws Exception { @@ -903,48 +898,50 @@ public class ConfigurationTest extends TestCase { public void testTemplateUpdateDelay() throws Exception { Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0); - assertEquals(DefaultTemplateResolver.DEFAULT_TEMPLATE_UPDATE_DELAY_MILLIS, cfgB.getTemplateUpdateDelayMilliseconds()); + assertEquals( + DefaultTemplateResolver.DEFAULT_TEMPLATE_UPDATE_DELAY_MILLIS, + (Object) cfgB.getTemplateUpdateDelayMilliseconds()); - cfgB.setTemplateUpdateDelayMilliseconds(4000); - assertEquals(4000L, cfgB.getTemplateUpdateDelayMilliseconds()); + cfgB.setTemplateUpdateDelayMilliseconds(4000L); + assertEquals(4000L, (Object) cfgB.getTemplateUpdateDelayMilliseconds()); - cfgB.setTemplateUpdateDelayMilliseconds(100); - assertEquals(100L, cfgB.getTemplateUpdateDelayMilliseconds()); + cfgB.setTemplateUpdateDelayMilliseconds(100L); + assertEquals(100L, (Object) cfgB.getTemplateUpdateDelayMilliseconds()); try { cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "5"); - assertEquals(5000L, cfgB.getTemplateUpdateDelayMilliseconds()); + assertEquals(5000L, (Object) cfgB.getTemplateUpdateDelayMilliseconds()); } catch (ConfigurationSettingValueException e) { assertThat(e.getMessage(), containsStringIgnoringCase("unit must be specified")); } cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "0"); - assertEquals(0L, cfgB.getTemplateUpdateDelayMilliseconds()); + assertEquals(0L, (Object) cfgB.getTemplateUpdateDelayMilliseconds()); try { cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "5 foo"); - assertEquals(5000L, cfgB.getTemplateUpdateDelayMilliseconds()); + assertEquals(5000L, (Object) cfgB.getTemplateUpdateDelayMilliseconds()); } catch (ConfigurationSettingValueException e) { assertThat(e.getMessage(), containsStringIgnoringCase("\"foo\"")); } cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "3 ms"); - assertEquals(3L, cfgB.getTemplateUpdateDelayMilliseconds()); + assertEquals(3L, (Object) cfgB.getTemplateUpdateDelayMilliseconds()); cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "4ms"); - assertEquals(4L, cfgB.getTemplateUpdateDelayMilliseconds()); + assertEquals(4L, (Object) cfgB.getTemplateUpdateDelayMilliseconds()); cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "3 s"); - assertEquals(3000L, cfgB.getTemplateUpdateDelayMilliseconds()); + assertEquals(3000L, (Object) cfgB.getTemplateUpdateDelayMilliseconds()); cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "4s"); - assertEquals(4000L, cfgB.getTemplateUpdateDelayMilliseconds()); + assertEquals(4000L, (Object) cfgB.getTemplateUpdateDelayMilliseconds()); cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "3 m"); - assertEquals(1000L * 60 * 3, cfgB.getTemplateUpdateDelayMilliseconds()); + assertEquals(1000L * 60 * 3, (Object) cfgB.getTemplateUpdateDelayMilliseconds()); cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "4m"); - assertEquals(1000L * 60 * 4, cfgB.getTemplateUpdateDelayMilliseconds()); + assertEquals(1000L * 60 * 4, (Object) cfgB.getTemplateUpdateDelayMilliseconds()); cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "1 h"); - assertEquals(1000L * 60 * 60, cfgB.getTemplateUpdateDelayMilliseconds()); + assertEquals(1000L * 60 * 60, (Object) cfgB.getTemplateUpdateDelayMilliseconds()); cfgB.setSetting(Configuration.ExtendableBuilder.TEMPLATE_UPDATE_DELAY_KEY, "2h"); - assertEquals(1000L * 60 * 60 * 2, cfgB.getTemplateUpdateDelayMilliseconds()); + assertEquals(1000L * 60 * 60 * 2, (Object) cfgB.getTemplateUpdateDelayMilliseconds()); } @Test @@ -1025,34 +1022,33 @@ public class ConfigurationTest extends TestCase { @Test public void testSetTabSize() throws Exception { - Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0); - String ftl = "${\t}"; try { - new Template(null, ftl, cfgB.build()); + new Template(null, ftl, + new Configuration.Builder(Configuration.VERSION_3_0_0).build()); fail(); } catch (ParseException e) { assertEquals(9, e.getColumnNumber()); } - cfgB.setTabSize(1); try { - new Template(null, ftl, cfgB.build()); + new Template(null, ftl, + new Configuration.Builder(Configuration.VERSION_3_0_0).tabSize(1).build()); fail(); } catch (ParseException e) { assertEquals(4, e.getColumnNumber()); } try { - cfgB.setTabSize(0); + new Configuration.Builder(Configuration.VERSION_3_0_0).tabSize(0); fail(); } catch (IllegalArgumentException e) { // Expected } try { - cfgB.setTabSize(257); + new Configuration.Builder(Configuration.VERSION_3_0_0).tabSize(257); fail(); } catch (IllegalArgumentException e) { // Expected http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8915ac9b/freemarker-core-test/src/test/java/org/apache/freemarker/core/CustomTemplateResolverTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/CustomTemplateResolverTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/CustomTemplateResolverTest.java new file mode 100644 index 0000000..5658ac9 --- /dev/null +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/CustomTemplateResolverTest.java @@ -0,0 +1,390 @@ +/* + * 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 org.apache.freemarker.core; + +import static junit.framework.TestCase.*; +import static org.apache.freemarker.core.Configuration.ExtendableBuilder.*; + +import java.io.IOException; +import java.io.Serializable; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Locale; + +import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory; +import org.apache.freemarker.core.templateresolver.GetTemplateResult; +import org.apache.freemarker.core.templateresolver.MalformedTemplateNameException; +import org.apache.freemarker.core.templateresolver.PathGlobMatcher; +import org.apache.freemarker.core.templateresolver.TemplateResolver; +import org.apache.freemarker.core.templateresolver.TemplateResolverDependencies; +import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateLookupStrategy; +import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormat; +import org.apache.freemarker.core.templateresolver.impl.SoftCacheStorage; +import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader; +import org.apache.freemarker.core.util.BugException; +import org.junit.Test; + +public class CustomTemplateResolverTest { + + @Test + public void testPositive() throws IOException, TemplateException { + Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0) + .templateResolver(new CustomTemplateResolver(null)) + .build(); + Template template = cfg.getTemplate(":foo::includes"); + + assertEquals("foo:includes", template.getLookupName()); + + StringWriter sw = new StringWriter(); + template.process(null, sw); + assertEquals("In foo:includes, included: In foo:inc", sw.toString()); + + try { + cfg.removeTemplateFromCache("foo", null, null); + fail(); + } catch (UnsupportedOperationException e) { + // Expected + } + + try { + cfg.clearTemplateCache(); + fail(); + } catch (UnsupportedOperationException e) { + // Expected + } + } + + @Test + public void testConfigurationDefaultForDefaultTemplateResolver() { + Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0).build(); + + assertNotNull(cfg.getTemplateLookupStrategy()); + assertNotNull(cfg.getLocalizedLookup()); + assertNotNull(cfg.getCacheStorage()); + assertNotNull(cfg.getTemplateUpdateDelayMilliseconds()); + assertNotNull(cfg.getNamingConvention()); + + assertNull(cfg.getTemplateLoader()); + assertNull(cfg.getTemplateConfigurations()); + + assertNotNull(cfg.getTemplateLanguage()); + assertNotNull(cfg.getSourceEncoding()); + } + + @Test + public void testConfigurationDefaultForCustomTemplateResolver() { + Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0) + .templateResolver(new CustomTemplateResolver(null)) + .build(); + + assertNull(cfg.getTemplateLookupStrategy()); + assertNull(cfg.getLocalizedLookup()); + assertNull(cfg.getCacheStorage()); + assertNull(cfg.getTemplateUpdateDelayMilliseconds()); + assertNull(cfg.getTemplateNameFormat()); + + assertNull(cfg.getTemplateLoader()); + assertNull(cfg.getTemplateConfigurations()); + + assertNotNull(cfg.getTemplateLanguage()); + assertNotNull(cfg.getSourceEncoding()); + } + + + @Test + public void testConfigurationDefaultForCustomTemplateResolver2() { + Configuration cfg = new Configuration.Builder(Configuration.VERSION_3_0_0) + .templateResolver(new CustomTemplateResolver(NAMING_CONVENTION_KEY)) + .build(); + + assertNull(cfg.getTemplateLookupStrategy()); + assertNull(cfg.getLocalizedLookup()); + assertNull(cfg.getCacheStorage()); + assertNull(cfg.getTemplateUpdateDelayMilliseconds()); + assertNotNull(cfg.getNamingConvention()); //! + + assertNull(cfg.getTemplateLoader()); + assertNull(cfg.getTemplateConfigurations()); + + assertNotNull(cfg.getTemplateLanguage()); + assertNotNull(cfg.getSourceEncoding()); + } + + @Test + public void testInvalidConfigurationForDefaultTemplateResolver() { + try { + new Configuration.Builder(Configuration.VERSION_3_0_0).cacheStorage(null).build(); + fail(); + } catch (ConfigurationSettingValueException e) { + // Expected + } + try { + new Configuration.Builder(Configuration.VERSION_3_0_0).templateUpdateDelayMilliseconds(null).build(); + fail(); + } catch (ConfigurationSettingValueException e) { + // Expected + } + try { + new Configuration.Builder(Configuration.VERSION_3_0_0).templateLookupStrategy(null).build(); + fail(); + } catch (ConfigurationSettingValueException e) { + // Expected + } + try { + new Configuration.Builder(Configuration.VERSION_3_0_0).localizedLookup(null).build(); + fail(); + } catch (ConfigurationSettingValueException e) { + // Expected + } + try { + new Configuration.Builder(Configuration.VERSION_3_0_0).templateNameFormat(null).build(); + fail(); + } catch (ConfigurationSettingValueException e) { + // Expected + } + + new Configuration.Builder(Configuration.VERSION_3_0_0).templateLoader(null).build(); + new Configuration.Builder(Configuration.VERSION_3_0_0).templateConfigurations(null).build(); + } + + @Test + public void testConfigurationValidityForCustomTemplateResolver() { + for (String supportedSetting : new String[]{ + TEMPLATE_LOADER_KEY, TEMPLATE_LOOKUP_STRATEGY_KEY, LOCALIZED_LOOKUP_KEY, TEMPLATE_NAME_FORMAT_KEY, + CACHE_STORAGE_KEY, TEMPLATE_UPDATE_DELAY_KEY, TEMPLATE_CONFIGURATIONS_KEY }) { + { + Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0) + .templateResolver(new CustomTemplateResolver(supportedSetting)); + setSetting(cfgB, supportedSetting); + cfgB.build(); + } + { + Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0) + .templateResolver(new CustomTemplateResolver(null)); + setSetting(cfgB, supportedSetting); + try { + cfgB.build(); + fail(); + } catch (ConfigurationSettingValueException e) { + // Expected + } + } + } + } + + private void setSetting(Configuration.Builder cfgB, String setting) { + if (TEMPLATE_LOADER_KEY.equals(setting)) { + cfgB.setTemplateLoader(new StringTemplateLoader()); + } else if (TEMPLATE_LOOKUP_STRATEGY_KEY.equals(setting)) { + cfgB.setTemplateLookupStrategy(DefaultTemplateLookupStrategy.INSTANCE); + } else if (LOCALIZED_LOOKUP_KEY.equals(setting)) { + cfgB.setLocalizedLookup(true); + } else if (TEMPLATE_NAME_FORMAT_KEY.equals(setting)) { + cfgB.setTemplateNameFormat(DefaultTemplateNameFormat.INSTANCE); + } else if (CACHE_STORAGE_KEY.equals(setting)) { + cfgB.setCacheStorage(new SoftCacheStorage()); + } else if (TEMPLATE_UPDATE_DELAY_KEY.equals(setting)) { + cfgB.setTemplateUpdateDelayMilliseconds(1234L); + } else if (TEMPLATE_CONFIGURATIONS_KEY.equals(setting)) { + cfgB.setTemplateConfigurations(new ConditionalTemplateConfigurationFactory( + new PathGlobMatcher("*.x"), + new TemplateConfiguration.Builder().build())); + } else { + throw new BugException("Unsupported setting: " + setting); + } + } + + static class CustomTemplateResolver extends TemplateResolver { + + private final String supportedSetting; + private TemplateLanguage templateLanguage; + + CustomTemplateResolver(String supportedSetting) { + this.supportedSetting = supportedSetting; + } + + @Override + protected void initialize() throws ConfigurationException { + TemplateResolverDependencies deps = getDependencies(); + + if (TEMPLATE_LOADER_KEY.equals(supportedSetting)) { + assertNotNull(deps.getTemplateLoader()); + } else { + try { + deps.getTemplateLoader(); + fail(); + } catch (IllegalStateException e) { + // Expected + } + } + + if (TEMPLATE_LOOKUP_STRATEGY_KEY.equals(supportedSetting)) { + assertNotNull(deps.getTemplateLookupStrategy()); + } else { + try { + deps.getTemplateLookupStrategy(); + fail(); + } catch (IllegalStateException e) { + // Expected + } + } + + if (LOCALIZED_LOOKUP_KEY.equals(supportedSetting)) { + assertNotNull(deps.getLocalizedLookup()); + } else { + try { + deps.getLocalizedLookup(); + fail(); + } catch (IllegalStateException e) { + // Expected + } + } + + if (TEMPLATE_NAME_FORMAT_KEY.equals(supportedSetting)) { + assertNotNull(deps.getTemplateNameFormat()); + } else { + try { + deps.getTemplateNameFormat(); + fail(); + } catch (IllegalStateException e) { + // Expected + } + } + + if (CACHE_STORAGE_KEY.equals(supportedSetting)) { + assertNotNull(deps.getCacheStorage()); + } else { + try { + deps.getCacheStorage(); + fail(); + } catch (IllegalStateException e) { + // Expected + } + } + + if (TEMPLATE_UPDATE_DELAY_KEY.equals(supportedSetting)) { + assertNotNull(deps.getTemplateUpdateDelayMilliseconds()); + } else { + try { + deps.getTemplateUpdateDelayMilliseconds(); + fail(); + } catch (IllegalStateException e) { + // Expected + } + } + + if (TEMPLATE_CONFIGURATIONS_KEY.equals(supportedSetting)) { + assertNotNull(deps.getTemplateConfigurations()); + } else { + try { + deps.getTemplateConfigurations(); + fail(); + } catch (IllegalStateException e) { + // Expected + } + } + + templateLanguage = deps.getTemplateLanguage(); + deps.getSourceEncoding(); + } + + @Override + protected void checkInitialized() { + super.checkInitialized(); + } + + @Override + public GetTemplateResult getTemplate(String name, Locale locale, Serializable customLookupCondition) + throws IOException { + name = normalizeRootBasedName(name); + return new GetTemplateResult(getDependencies() + .parse(templateLanguage, name, name, + new StringReader( + "In " + name + + (name.endsWith("includes") + ? ", included: <#include 'inc'>" + : "")), + null, null, null)); + } + + @Override + public void clearTemplateCache() throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public void removeTemplateFromCache(String name, Locale locale, Serializable customLookupCondition) + throws IOException, UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public String toRootBasedName(String baseName, String targetName) throws MalformedTemplateNameException { + if (targetName.startsWith(":")) { + return targetName.substring(1); + } else { + int lastColonIdx = baseName.lastIndexOf(':'); + return lastColonIdx == -1 ? targetName : baseName.substring(0, lastColonIdx + 1) + targetName; + } + } + + @Override + public String normalizeRootBasedName(String name) throws MalformedTemplateNameException { + name = name.replaceAll("::", ":"); + return name.startsWith(":") ? name.substring(1) : name; + } + + @Override + public boolean supportsTemplateLoaderSetting() { + return TEMPLATE_LOADER_KEY.equals(supportedSetting); + } + + @Override + public boolean supportsCacheStorageSetting() { + return CACHE_STORAGE_KEY.equals(supportedSetting); + } + + @Override + public boolean supportsTemplateLookupStrategySetting() { + return TEMPLATE_LOOKUP_STRATEGY_KEY.equals(supportedSetting); + } + + @Override + public boolean supportsTemplateNameFormatSetting() { + return TEMPLATE_NAME_FORMAT_KEY.equals(supportedSetting); + } + + @Override + public boolean supportsTemplateConfigurationsSetting() { + return TEMPLATE_CONFIGURATIONS_KEY.equals(supportedSetting); + } + + @Override + public boolean supportsTemplateUpdateDelayMillisecondsSetting() { + return TEMPLATE_UPDATE_DELAY_KEY.equals(supportedSetting); + } + + @Override + public boolean supportsLocalizedLookupSetting() { + return LOCALIZED_LOOKUP_KEY.equals(supportedSetting); + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8915ac9b/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java index 71b886b..c8a0186 100644 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/IncludeAndImportTest.java @@ -153,59 +153,80 @@ public class IncludeAndImportTest extends TemplateTest { @Test public void lazyAutoImportSettings() throws IOException, TemplateException { - TestConfigurationBuilder cfgB = new TestConfigurationBuilder() - .autoImports(ImmutableMap.of( - "l1", "lib1.ftl", - "l2", "lib2.ftl", - "l3", "lib3.ftl" - )); - + ImmutableMap<String, String> autoImports = ImmutableMap.of( + "l1", "lib1.ftl", + "l2", "lib2.ftl", + "l3", "lib3.ftl" + ); String ftl = "<@l2.m/>, <@l1.m/>; ${history}"; String expectedEagerOutput = "In lib2, In lib1; L1L2L3"; String expecedLazyOutput = "In lib2, In lib1; L2L1"; - setConfiguration(cfgB.build()); + setConfiguration(new TestConfigurationBuilder() + .autoImports(autoImports) + .build()); assertOutput(ftl, expectedEagerOutput); - cfgB.setLazyImports(true); - setConfiguration(cfgB.build()); + + setConfiguration(new TestConfigurationBuilder() + .autoImports(autoImports) + .lazyImports(true) + .build()); + assertNull(getConfiguration().getLazyAutoImports()); assertOutput(ftl, expecedLazyOutput); - cfgB.setLazyImports(false); - setConfiguration(cfgB.build()); + + setConfiguration(new TestConfigurationBuilder() + .autoImports(autoImports) + .lazyImports(false) + .build()); assertOutput(ftl, expectedEagerOutput); - cfgB.setLazyAutoImports(true); - setConfiguration(cfgB.build()); + + setConfiguration(new TestConfigurationBuilder() + .autoImports(autoImports) + .lazyImports(false) + .lazyAutoImports(true) + .build()); assertOutput(ftl, expecedLazyOutput); - cfgB.setLazyAutoImports(null); - setConfiguration(cfgB.build()); + + setConfiguration(new TestConfigurationBuilder() + .autoImports(autoImports) + .lazyImports(false) + .lazyAutoImports(null) + .build()); assertOutput(ftl, expectedEagerOutput); - cfgB.setLazyImports(true); - cfgB.setLazyAutoImports(false); - setConfiguration(cfgB.build()); + + setConfiguration(new TestConfigurationBuilder() + .autoImports(autoImports) + .lazyImports(true) + .lazyAutoImports(false) + .build()); assertOutput(ftl, expectedEagerOutput); } @Test public void lazyAutoImportMixedWithManualImport() throws IOException, TemplateException { - TestConfigurationBuilder cfgB = new TestConfigurationBuilder() - .autoImports(ImmutableMap.of( - "l1", "lib1.ftl", - "l2", "/./lib2.ftl", - "l3", "lib3.ftl")) - .lazyAutoImports(true); - + ImmutableMap<String, String> autoImports = ImmutableMap.of( + "l1", "lib1.ftl", + "l2", "/./lib2.ftl", + "l3", "lib3.ftl"); String ftl = "<@l2.m/>, <@l1.m/>; ${history}"; String expectOutputWithoutHistory = "In lib2, In lib1; "; String expecedOutput = expectOutputWithoutHistory + "L2L1"; - setConfiguration(cfgB.build()); + setConfiguration(new TestConfigurationBuilder() + .autoImports(autoImports) + .lazyAutoImports(true) + .build()); assertOutput(ftl, expecedOutput); assertOutput("<#import 'lib1.ftl' as l1>" + ftl, expectOutputWithoutHistory + "L1L2"); assertOutput("<#import './x/../lib1.ftl' as l1>" + ftl, expectOutputWithoutHistory + "L1L2"); assertOutput("<#import 'lib2.ftl' as l2>" + ftl, expecedOutput); assertOutput("<#import 'lib3.ftl' as l3>" + ftl, expectOutputWithoutHistory + "L3L2L1"); - cfgB.setLazyImports(true); - setConfiguration(cfgB.build()); + setConfiguration(new TestConfigurationBuilder() + .autoImports(autoImports) + .lazyAutoImports(true) + .lazyImports(true) + .build()); assertOutput("<#import 'lib1.ftl' as l1>" + ftl, expecedOutput); assertOutput("<#import './x/../lib1.ftl' as l1>" + ftl, expecedOutput); assertOutput("<#import 'lib2.ftl' as l2>" + ftl, expecedOutput); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8915ac9b/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java index d78c558..c656cd3 100644 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java @@ -55,9 +55,9 @@ public class OutputFormatTest extends TemplateTest { addTemplate("t.xml", "${.outputFormat}"); addTemplate("tWithHeader", "<#ftl outputFormat='HTML'>${.outputFormat}"); - TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder(); for (OutputFormat cfgOutputFormat : new OutputFormat[] { UndefinedOutputFormat.INSTANCE, RTFOutputFormat.INSTANCE } ) { + TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder(); if (!cfgOutputFormat.equals(UndefinedOutputFormat.INSTANCE)) { cfgB.setOutputFormat(cfgOutputFormat); } @@ -100,8 +100,8 @@ public class OutputFormatTest extends TemplateTest { addTemplate("t.fTlX", commonContent); addTemplate("tWithHeader.ftlx", "<#ftl outputFormat='HTML'>" + commonContent); - TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder(); for (int setupNumber = 1; setupNumber <= 3; setupNumber++) { + TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder(); final OutputFormat cfgOutputFormat; final OutputFormat ftlhOutputFormat; final OutputFormat ftlxOutputFormat; @@ -193,48 +193,38 @@ public class OutputFormatTest extends TemplateTest { .build()); { - TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder(); - - setConfiguration(cfgB.outputFormat(HTMLOutputFormat.INSTANCE).build()); + setConfiguration(createDefaultConfigurationBuilder().outputFormat(HTMLOutputFormat.INSTANCE).build()); assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it - setConfiguration(cfgB.templateConfigurations(tcfHTML).build()); + setConfiguration(createDefaultConfigurationBuilder().templateConfigurations(tcfHTML).build()); assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it - setConfiguration(cfgB.templateConfigurations(tcfNoAutoEsc).build()); + setConfiguration(createDefaultConfigurationBuilder().templateConfigurations(tcfNoAutoEsc).build()); assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it } { - TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder(); - - setConfiguration(cfgB.recognizeStandardFileExtensions(false).build()); + setConfiguration(createDefaultConfigurationBuilder().recognizeStandardFileExtensions(false).build()); assertErrorContainsForNamed("t.ftlx", UndefinedOutputFormat.INSTANCE.getName()); - setConfiguration(cfgB.outputFormat(HTMLOutputFormat.INSTANCE).build()); - assertOutputForNamed("t.ftlx", "' ' '"); - setConfiguration(cfgB.outputFormat(XMLOutputFormat.INSTANCE).build()); - assertOutputForNamed("t.ftlx", "' ' '"); - setConfiguration(cfgB.templateConfigurations(tcfHTML).build()); - assertOutputForNamed("t.ftlx", "' ' '"); - setConfiguration(cfgB.templateConfigurations(tcfNoAutoEsc).build()); - assertOutputForNamed("t.ftlx", "' ' '"); - } - { - TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder(); - cfgB.setRecognizeStandardFileExtensions(true); - - setConfiguration(cfgB.templateConfigurations(tcfHTML).build()); - assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it - setConfiguration(cfgB.templateConfigurations(tcfNoAutoEsc).build()); - assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it - } + setConfiguration(createDefaultConfigurationBuilder() + .recognizeStandardFileExtensions(false) + .outputFormat(HTMLOutputFormat.INSTANCE).build()); + assertOutputForNamed("t.ftlx", "' ' '"); - { - TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder(); + setConfiguration(createDefaultConfigurationBuilder() + .recognizeStandardFileExtensions(false) + .outputFormat(XMLOutputFormat.INSTANCE).build()); + assertOutputForNamed("t.ftlx", "' ' '"); - setConfiguration(cfgB.templateConfigurations(tcfHTML).build()); - assertOutputForNamed("t.ftlx", "' ' '"); // Can't override it - setConfiguration(cfgB.recognizeStandardFileExtensions(false).build()); + setConfiguration(createDefaultConfigurationBuilder() + .recognizeStandardFileExtensions(false) + .templateConfigurations(tcfHTML).build()); assertOutputForNamed("t.ftlx", "' ' '"); + + setConfiguration(createDefaultConfigurationBuilder() + .recognizeStandardFileExtensions(false) + .templateConfigurations(tcfNoAutoEsc) + .outputFormat(XMLOutputFormat.INSTANCE).build()); + assertOutputForNamed("t.ftlx", "' ' '"); } } @@ -288,10 +278,10 @@ public class OutputFormatTest extends TemplateTest { addTemplate("tWithHeaderFalse", "<#ftl autoEsc=false>${'a&b'}"); addTemplate("tWithHeaderTrue", "<#ftl autoEsc=true>${'a&b'}"); - TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder().outputFormat(XMLOutputFormat.INSTANCE); - assertEquals(ENABLE_IF_DEFAULT, cfgB.getAutoEscapingPolicy()); - for (boolean cfgAutoEscaping : new boolean[] { true, false }) { + TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder().outputFormat(XMLOutputFormat.INSTANCE); + assertEquals(ENABLE_IF_DEFAULT, cfgB.getAutoEscapingPolicy()); + if (!cfgAutoEscaping) { cfgB.setAutoEscapingPolicy(DISABLE); } @@ -778,41 +768,30 @@ public class OutputFormatTest extends TemplateTest { @Test public void testAutoEscPolicy() throws Exception { - TestConfigurationBuilder cfgB = createDefaultConfigurationBuilder(); - cfgB.setRegisteredCustomOutputFormats(ImmutableList.<OutputFormat>of( - SeldomEscapedOutputFormat.INSTANCE, DummyOutputFormat.INSTANCE)); - assertEquals(ENABLE_IF_DEFAULT, cfgB.getAutoEscapingPolicy()); + assertEquals(ENABLE_IF_DEFAULT, createDefaultConfigurationBuilder().getAutoEscapingPolicy()); String commonFTL = "${'.'} ${.autoEsc?c}"; String notEsced = ". false"; String esced = "\\. true"; - for (AutoEscapingPolicy autoEscPolicy : new AutoEscapingPolicy[] { ENABLE_IF_DEFAULT, ENABLE_IF_SUPPORTED, DISABLE }) { - cfgB.setAutoEscapingPolicy(autoEscPolicy); - String sExpted = autoEscPolicy == ENABLE_IF_SUPPORTED ? esced : notEsced; - cfgB.setOutputFormat(SeldomEscapedOutputFormat.INSTANCE); - setConfiguration(cfgB.build()); + setConfiguration(testAutoEscPolicy_createCfg(autoEscPolicy, SeldomEscapedOutputFormat.INSTANCE)); assertOutput(commonFTL, sExpted); - cfgB.setOutputFormat(UndefinedOutputFormat.INSTANCE); - setConfiguration(cfgB.build()); + setConfiguration(testAutoEscPolicy_createCfg(autoEscPolicy, UndefinedOutputFormat.INSTANCE)); assertOutput("<#ftl outputFormat='seldomEscaped'>" + commonFTL, sExpted); assertOutput("<#outputFormat 'seldomEscaped'>" + commonFTL + "</#outputFormat>", sExpted); String dExpted = autoEscPolicy == DISABLE ? notEsced : esced; - cfgB.setOutputFormat(DummyOutputFormat.INSTANCE); - setConfiguration(cfgB.build()); + setConfiguration(testAutoEscPolicy_createCfg(autoEscPolicy, DummyOutputFormat.INSTANCE)); assertOutput(commonFTL, dExpted); - cfgB.setOutputFormat(UndefinedOutputFormat.INSTANCE); - setConfiguration(cfgB.build()); + setConfiguration(testAutoEscPolicy_createCfg(autoEscPolicy, UndefinedOutputFormat.INSTANCE)); assertOutput("<#ftl outputFormat='dummy'>" + commonFTL, dExpted); assertOutput("<#outputFormat 'dummy'>" + commonFTL + "</#outputFormat>", dExpted); - cfgB.setOutputFormat(DummyOutputFormat.INSTANCE); - setConfiguration(cfgB.build()); + setConfiguration(testAutoEscPolicy_createCfg(autoEscPolicy, DummyOutputFormat.INSTANCE)); assertOutput( commonFTL + "<#outputFormat 'seldomEscaped'>" @@ -861,7 +840,18 @@ public class OutputFormatTest extends TemplateTest { + dExpted); } } - + + private Configuration testAutoEscPolicy_createCfg(AutoEscapingPolicy autoEscPolicy, + OutputFormat outpoutFormat) + throws TemplateModelException { + return createDefaultConfigurationBuilder() + .registeredCustomOutputFormats(ImmutableList.<OutputFormat>of( + SeldomEscapedOutputFormat.INSTANCE, DummyOutputFormat.INSTANCE)) + .autoEscapingPolicy(autoEscPolicy) + .outputFormat(outpoutFormat) + .build(); + } + @Test public void testDynamicParsingBIsInherticContextOutputFormat() throws Exception { // Dynamic parser BI-s are supposed to use the ParsingConfiguration of the calling template, and ignore anything http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8915ac9b/freemarker-core-test/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java index cf14b93..c9877ca 100644 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java @@ -51,27 +51,33 @@ public class SQLTimeZoneTest extends TemplateTest { private final Timestamp sqlTimestamp = new Timestamp(utcToLong("2014-07-12T10:30:05")); // 2014-07-12T12:30:05 private final Date javaDate = new Date(utcToLong("2014-07-12T10:30:05")); // 2014-07-12T12:30:05 private final Date javaDayErrorDate = new Date(utcToLong("2014-07-11T22:00:00")); // 2014-07-12T12:30:05 - + + @SuppressWarnings("unused") // Accessed from template public TimeZone getLastDefaultTimeZone() { return lastDefaultTimeZone; } + @SuppressWarnings("unused") // Accessed from template public void setLastDefaultTimeZone(TimeZone lastDefaultTimeZone) { this.lastDefaultTimeZone = lastDefaultTimeZone; } + @SuppressWarnings("unused") // Accessed from template public java.sql.Date getSqlDate() { return sqlDate; } + @SuppressWarnings("unused") // Accessed from template public Time getSqlTime() { return sqlTime; } + @SuppressWarnings("unused") // Accessed from template public Timestamp getSqlTimestamp() { return sqlTimestamp; } + @SuppressWarnings("unused") // Accessed from template public Date getJavaDate() { return javaDate; } @@ -202,13 +208,7 @@ public class SQLTimeZoneTest extends TemplateTest { @Test public void testCacheFlushings() throws Exception { - Configuration.ExtendableBuilder<?> cfgB = createConfigurationBuilder() - .timeZone(_DateUtil.UTC) - .dateFormat("yyyy-MM-dd E") - .timeFormat("HH:mm:ss E") - .dateTimeFormat("yyyy-MM-dd'T'HH:mm:ss E"); - - setConfiguration(cfgB.build()); + setConfiguration(testCacheFlushing_createBuilder().build()); assertOutput( "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n" + "<#setting locale='de'>\n" @@ -234,7 +234,7 @@ public class SQLTimeZoneTest extends TemplateTest { "2014-07-11 Fri, 10:30:05 Thu, 2014-07-12T10:30:05 Sat, 2014-07-12T10:30:05 Sat, 2014-07-12 Sat, 10:30:05 Sat\n" + "2014-07-11 Fri, 10:30:05 Thu, 2014-07-12T10:30:05, 2014-07-12T10:30:05, 2014-07-12 Sat, 10:30:05 Sat\n"); - setConfiguration(cfgB.sqlDateAndTimeTimeZone(GMT_P02).build()); + setConfiguration(testCacheFlushing_createBuilder().sqlDateAndTimeTimeZone(GMT_P02).build()); assertOutput( "${sqlDate}, ${sqlTime}, ${sqlTimestamp}, ${javaDate?datetime}, ${javaDate?date}, ${javaDate?time}\n" + "<#setting locale='de'>\n" @@ -261,6 +261,14 @@ public class SQLTimeZoneTest extends TemplateTest { + "2014-07-12 Sat, 12:30:05 Thu, 2014-07-12T10:30:05, 2014-07-12T10:30:05, 2014-07-12 Sat, 10:30:05 Sat\n"); } + private Configuration.ExtendableBuilder<?> testCacheFlushing_createBuilder() { + return createConfigurationBuilder() + .timeZone(_DateUtil.UTC) + .dateFormat("yyyy-MM-dd E") + .timeFormat("HH:mm:ss E") + .dateTimeFormat("yyyy-MM-dd'T'HH:mm:ss E"); + } + @Test public void testDateAndTimeBuiltInsHasNoEffect() throws Exception { setConfiguration(createConfigurationBuilder() http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8915ac9b/freemarker-core-test/src/test/java/org/apache/freemarker/core/SpecialVariableTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/SpecialVariableTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/SpecialVariableTest.java index 99aae83..c74dfd7 100644 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/SpecialVariableTest.java +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/SpecialVariableTest.java @@ -62,41 +62,51 @@ public class SpecialVariableTest extends TemplateTest { @Test public void testAutoEsc() throws Exception { - Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0); - for (AutoEscapingPolicy autoEscaping : new AutoEscapingPolicy[] { AutoEscapingPolicy.ENABLE_IF_DEFAULT, AutoEscapingPolicy.ENABLE_IF_SUPPORTED }) { - cfgB.setAutoEscapingPolicy(autoEscaping); - cfgB.setOutputFormat(HTMLOutputFormat.INSTANCE); - setConfiguration(cfgB.build()); + setConfiguration(new Configuration.Builder(Configuration.VERSION_3_0_0) + .autoEscapingPolicy(autoEscaping) + .outputFormat(HTMLOutputFormat.INSTANCE) + .build()); assertOutput("${.autoEsc?c}", "true"); assertOutput("<#ftl autoEsc=false>${.autoEsc?c}", "false"); - cfgB.setOutputFormat(PlainTextOutputFormat.INSTANCE); - setConfiguration(cfgB.build()); + setConfiguration(new Configuration.Builder(Configuration.VERSION_3_0_0) + .autoEscapingPolicy(autoEscaping) + .outputFormat(PlainTextOutputFormat.INSTANCE) + .build()); assertOutput("${.autoEsc?c}", "false"); - cfgB.setOutputFormat(UndefinedOutputFormat.INSTANCE); - setConfiguration(cfgB.build()); + setConfiguration(new Configuration.Builder(Configuration.VERSION_3_0_0) + .autoEscapingPolicy(autoEscaping) + .outputFormat(UndefinedOutputFormat.INSTANCE) + .build()); assertOutput("${.autoEsc?c}", "false"); } - cfgB.setAutoEscapingPolicy(AutoEscapingPolicy.DISABLE); - cfgB.setOutputFormat(HTMLOutputFormat.INSTANCE); - setConfiguration(cfgB.build()); + setConfiguration(new Configuration.Builder(Configuration.VERSION_3_0_0) + .autoEscapingPolicy(AutoEscapingPolicy.DISABLE) + .outputFormat(HTMLOutputFormat.INSTANCE) + .build()); assertOutput("${.autoEsc?c}", "false"); assertOutput("<#ftl autoEsc=true>${.autoEsc?c}", "true"); - cfgB.setOutputFormat(PlainTextOutputFormat.INSTANCE); - setConfiguration(cfgB.build()); + setConfiguration(new Configuration.Builder(Configuration.VERSION_3_0_0) + .autoEscapingPolicy(AutoEscapingPolicy.DISABLE) + .outputFormat(PlainTextOutputFormat.INSTANCE) + .build()); assertOutput("${.autoEsc?c}", "false"); - cfgB.setOutputFormat(UndefinedOutputFormat.INSTANCE); - setConfiguration(cfgB.build()); + setConfiguration(new Configuration.Builder(Configuration.VERSION_3_0_0) + .autoEscapingPolicy(AutoEscapingPolicy.DISABLE) + .outputFormat(UndefinedOutputFormat.INSTANCE) + .build()); assertOutput("${.autoEsc?c}", "false"); - cfgB.setAutoEscapingPolicy(AutoEscapingPolicy.ENABLE_IF_DEFAULT); - setConfiguration(cfgB.build()); + setConfiguration(new Configuration.Builder(Configuration.VERSION_3_0_0) + .autoEscapingPolicy(AutoEscapingPolicy.ENABLE_IF_DEFAULT) + .outputFormat(UndefinedOutputFormat.INSTANCE) + .build()); assertOutput( "${.autoEsc?c} " + "<#outputFormat 'HTML'>${.autoEsc?c}</#outputFormat> " http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8915ac9b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java index f0e63a8..ba6c806 100644 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java @@ -309,11 +309,15 @@ public class TemplateLookupStrategyTest { final Configuration cfg; final Configuration cfgNoLocLU; { - Configuration.Builder cfgB = new Configuration.Builder(Configuration.VERSION_3_0_0) + cfg = new Configuration.Builder(Configuration.VERSION_3_0_0) .templateLoader(tl) - .templateLookupStrategy(new DomainTemplateLookupStrategy()); - cfg = cfgB.build(); - cfgNoLocLU = cfgB.localizedLookup(false).build(); + .templateLookupStrategy(new DomainTemplateLookupStrategy()) + .build(); + cfgNoLocLU = new Configuration.Builder(Configuration.VERSION_3_0_0) + .templateLoader(tl) + .templateLookupStrategy(new DomainTemplateLookupStrategy()) + .localizedLookup(false) + .build(); } final String iAtDefaultContent = "i at default"; http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8915ac9b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/DefaultTemplateResolverTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/DefaultTemplateResolverTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/DefaultTemplateResolverTest.java index f51ba86..70254ba 100644 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/DefaultTemplateResolverTest.java +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templateresolver/DefaultTemplateResolverTest.java @@ -19,6 +19,7 @@ package org.apache.freemarker.core.templateresolver; +import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.io.IOException; @@ -28,7 +29,6 @@ import java.util.Locale; import org.apache.freemarker.core.Configuration; import org.apache.freemarker.core.Template; -import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateLookupStrategy; import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormat; import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateResolver; import org.apache.freemarker.core.templateresolver.impl.StringTemplateLoader; @@ -48,13 +48,14 @@ public class DefaultTemplateResolverTest { @Test public void testCachedException() throws Exception { MockTemplateLoader loader = new MockTemplateLoader(); - DefaultTemplateResolver tr = new DefaultTemplateResolver( - loader, - new StrongCacheStorage(), 100L, - DefaultTemplateLookupStrategy.INSTANCE, true, - DefaultTemplateNameFormat.INSTANCE, - null, - new TestConfigurationBuilder().build()); + Configuration cfg = new TestConfigurationBuilder() + .templateLoader(loader) + .cacheStorage(new StrongCacheStorage()) + .templateUpdateDelayMilliseconds(100L) + .build(); + TemplateResolver tr = cfg.getTemplateResolver(); + assertThat(tr, instanceOf(DefaultTemplateResolver.class)); + loader.setThrowException(true); try { tr.getTemplate("t", Locale.getDefault(), null).getTemplate(); @@ -88,19 +89,22 @@ public class DefaultTemplateResolverTest { @Test public void testCachedNotFound() throws Exception { MockTemplateLoader loader = new MockTemplateLoader(); - DefaultTemplateResolver cache = new DefaultTemplateResolver( - loader, - new StrongCacheStorage(), 100L, - DefaultTemplateLookupStrategy.INSTANCE, false, - DefaultTemplateNameFormat.INSTANCE, - null, new TestConfigurationBuilder().build()); - assertNull(cache.getTemplate("t", Locale.getDefault(), null).getTemplate()); + Configuration cfg = new TestConfigurationBuilder() + .templateLoader(loader) + .cacheStorage(new StrongCacheStorage()) + .templateUpdateDelayMilliseconds(100L) + .localizedLookup(false) + .build(); + TemplateResolver tr = cfg.getTemplateResolver(); + assertThat(tr, instanceOf(DefaultTemplateResolver.class)); + + assertNull(tr.getTemplate("t", Locale.getDefault(), null).getTemplate()); assertEquals(1, loader.getLoadAttemptCount()); - assertNull(cache.getTemplate("t", Locale.getDefault(), null).getTemplate()); + assertNull(tr.getTemplate("t", Locale.getDefault(), null).getTemplate()); // Still 1 - returned cached exception assertEquals(1, loader.getLoadAttemptCount()); Thread.sleep(132L); - assertNull(cache.getTemplate("t", Locale.getDefault(), null).getTemplate()); + assertNull(tr.getTemplate("t", Locale.getDefault(), null).getTemplate()); // Cache had to retest assertEquals(2, loader.getLoadAttemptCount()); } @@ -211,69 +215,77 @@ public class DefaultTemplateResolverTest { @Test public void testZeroUpdateDelay() throws Exception { MonitoredTemplateLoader loader = new MonitoredTemplateLoader(); - TestConfigurationBuilder cfgB = new TestConfigurationBuilder() - .cacheStorage(new StrongCacheStorage()) - .templateLoader(loader) - .templateUpdateDelayMilliseconds(0); - Configuration cfg = cfgB.build(); + { + Configuration cfg = new TestConfigurationBuilder() + .cacheStorage(new StrongCacheStorage()) + .templateLoader(loader) + .templateUpdateDelayMilliseconds(0L) + .build(); + for (int i = 1; i <= 3; i++) { + loader.putTextTemplate("t.ftl", "v" + i); + assertEquals("v" + i, cfg.getTemplate("t.ftl").toString()); + } + + loader.clearEvents(); + loader.putTextTemplate("t.ftl", "v8"); + assertEquals("v8", cfg.getTemplate("t.ftl").toString()); + assertEquals("v8", cfg.getTemplate("t.ftl").toString()); + loader.putTextTemplate("t.ftl", "v9"); + assertEquals("v9", cfg.getTemplate("t.ftl").toString()); + assertEquals("v9", cfg.getTemplate("t.ftl").toString()); + assertEquals( + ImmutableList.of( + new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v8 + new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND), + new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), - for (int i = 1; i <= 3; i++) { - loader.putTextTemplate("t.ftl", "v" + i); - assertEquals("v" + i, cfg.getTemplate("t.ftl").toString()); - } + new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v8 + new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND), + new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED), - loader.clearEvents(); - loader.putTextTemplate("t.ftl", "v8"); - assertEquals("v8", cfg.getTemplate("t.ftl").toString()); - assertEquals("v8", cfg.getTemplate("t.ftl").toString()); - loader.putTextTemplate("t.ftl", "v9"); - assertEquals("v9", cfg.getTemplate("t.ftl").toString()); - assertEquals("v9", cfg.getTemplate("t.ftl").toString()); - assertEquals( - ImmutableList.of( - new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v8 - new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND), - new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), + new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v9 + new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND), + new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), - new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v8 - new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND), - new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED), - - new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v9 - new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND), - new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), + new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v9 + new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND), + new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED) + ), + loader.getEvents(LoadEvent.class)); + } - new LoadEvent("t_en_US.ftl", TemplateLoadingResultStatus.NOT_FOUND), // v9 - new LoadEvent("t_en.ftl", TemplateLoadingResultStatus.NOT_FOUND), - new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED) - ), - loader.getEvents(LoadEvent.class)); - - cfg = cfgB.localizedLookup(false).build(); - loader.clearEvents(); - loader.putTextTemplate("t.ftl", "v10"); - assertEquals("v10", cfg.getTemplate("t.ftl").toString()); - loader.putTextTemplate("t.ftl", "v11"); // same time stamp, different content - assertEquals("v11", cfg.getTemplate("t.ftl").toString()); - assertEquals("v11", cfg.getTemplate("t.ftl").toString()); - assertEquals("v11", cfg.getTemplate("t.ftl").toString()); - Thread.sleep(17L); - assertEquals("v11", cfg.getTemplate("t.ftl").toString()); - loader.putTextTemplate("t.ftl", "v12"); - assertEquals("v12", cfg.getTemplate("t.ftl").toString()); - assertEquals("v12", cfg.getTemplate("t.ftl").toString()); - assertEquals( - ImmutableList.of( - new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), // v10 - new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), // v11 - new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED), - new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED), - new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED), - new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), // v12 - new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED) - ), - loader.getEvents(LoadEvent.class)); + { + Configuration cfg = new TestConfigurationBuilder() + .cacheStorage(new StrongCacheStorage()) + .templateLoader(loader) + .templateUpdateDelayMilliseconds(0L) + .localizedLookup(false) + .build(); + loader.clearEvents(); + loader.putTextTemplate("t.ftl", "v10"); + assertEquals("v10", cfg.getTemplate("t.ftl").toString()); + loader.putTextTemplate("t.ftl", "v11"); // same time stamp, different content + assertEquals("v11", cfg.getTemplate("t.ftl").toString()); + assertEquals("v11", cfg.getTemplate("t.ftl").toString()); + assertEquals("v11", cfg.getTemplate("t.ftl").toString()); + Thread.sleep(17L); + assertEquals("v11", cfg.getTemplate("t.ftl").toString()); + loader.putTextTemplate("t.ftl", "v12"); + assertEquals("v12", cfg.getTemplate("t.ftl").toString()); + assertEquals("v12", cfg.getTemplate("t.ftl").toString()); + assertEquals( + ImmutableList.of( + new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), // v10 + new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), // v11 + new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED), + new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED), + new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED), + new LoadEvent("t.ftl", TemplateLoadingResultStatus.OPENED), // v12 + new LoadEvent("t.ftl", TemplateLoadingResultStatus.NOT_MODIFIED) + ), + loader.getEvents(LoadEvent.class)); + } } @Test http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8915ac9b/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/impl/ExtendedDecimalFormatTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/impl/ExtendedDecimalFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/impl/ExtendedDecimalFormatTest.java index 76c0bfc..9637205 100644 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/impl/ExtendedDecimalFormatTest.java +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/impl/ExtendedDecimalFormatTest.java @@ -276,15 +276,14 @@ public class ExtendedDecimalFormatTest extends TemplateTest { @Test public void testTemplates() throws IOException, TemplateException { - TestConfigurationBuilder cfgB = new TestConfigurationBuilder(); - - setConfiguration(cfgB.numberFormat(",000.#").build()); + setConfiguration(new TestConfigurationBuilder().numberFormat(",000.#").build()); assertOutput("${1000.15} ${1000.25}", "1,000.2 1,000.2"); - setConfiguration(cfgB.numberFormat(",000.#;; roundingMode=halfUp groupingSeparator=_").build());; + String numberFormat = ",000.#;; roundingMode=halfUp groupingSeparator=_"; + setConfiguration(new TestConfigurationBuilder().numberFormat(numberFormat).build());; assertOutput("${1000.15} ${1000.25}", "1_000.2 1_000.3"); - setConfiguration(cfgB.locale(Locale.GERMANY).build());; + setConfiguration(new TestConfigurationBuilder().numberFormat(numberFormat).locale(Locale.GERMANY).build());; assertOutput("${1000.15} ${1000.25}", "1_000,2 1_000,3"); - setConfiguration(cfgB.locale(Locale.US).build());; + setConfiguration(new TestConfigurationBuilder().numberFormat(numberFormat).locale(Locale.US).build());; assertOutput( "${1000.15}; " + "${1000.15?string(',##.#;;groupingSeparator=\" \"')}; "
