- Configuration.getTemplate has no "encoding" parameter anymore. Similarly #include has no "encoding" parameter either. The charset of templates can be specified via Configuration.defaultEncoding and Configuration.templateConfigurations (for example based on the directory it is in), or wirh the #ftl directive inside the template. Thus, a given template always has the same charset, no mater how it's accessed.
- Removed Configuration.setEncoding(java.util.Locale, String) and the related other methods. Because of the new logic of template encodings, the locale to encoding mapping doesn't make much sense anymore. - #include-d/#import-ed templates don't inheirit the charset (encoding) of the #include-ing/#import-ing template. (Because, again, the charset of a template file is independent of how you access it.) - Require customLookupCondition-s to be Serializable. Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/f6a693c5 Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/f6a693c5 Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/f6a693c5 Branch: refs/heads/3 Commit: f6a693c5734130b82aa5f3c40824f27fb86355e7 Parents: e365f11 Author: ddekany <[email protected]> Authored: Mon Mar 20 10:28:02 2017 +0100 Committer: ddekany <[email protected]> Committed: Mon Mar 20 18:32:10 2017 +0100 ---------------------------------------------------------------------- .../apache/freemarker/core/ASTDirInclude.java | 49 +-- .../apache/freemarker/core/Configuration.java | 253 ++------------- .../org/apache/freemarker/core/Environment.java | 61 ++-- .../apache/freemarker/core/ParameterRole.java | 1 - .../org/apache/freemarker/core/Template.java | 25 +- .../freemarker/core/TemplateConfiguration.java | 6 +- .../core/TemplateNotFoundException.java | 3 +- .../templateresolver/GetTemplateResult.java | 3 +- .../templateresolver/TemplateLoaderSession.java | 3 +- .../templateresolver/TemplateLookupContext.java | 2 +- .../core/templateresolver/TemplateResolver.java | 10 +- .../impl/DefaultTemplateResolver.java | 102 +++--- .../freemarker/dom/JaxenXPathSupport.java | 6 +- .../freemarker/servlet/FreemarkerServlet.java | 3 +- src/main/javacc/FTL.jj | 10 +- src/manual/en_US/FM3-CHANGE-LOG.txt | 17 +- .../freemarker/core/ConfigurationTest.java | 132 ++------ .../freemarker/core/TemplatGetEncodingTest.java | 87 ----- ...igurationWithDefaltTemplateResolverTest.java | 260 +++++++++++++++ ...teConfigurationWithTemplateResolverTest.java | 321 ------------------- .../core/TemplateGetEncodingTest.java | 59 ++++ .../core/TemplateLookupStrategyTest.java | 78 +++-- .../core/TemplateNotFoundMessageTest.java | 8 +- .../DefaultTemplateResolverTest.java | 136 +------- .../test/templatesuite/TemplateTestCase.java | 4 - .../test/templatesuite/expected/include2.txt | 5 - .../templates/charset-in-header_inc2.ftl | 2 +- .../templates/include2-included-encoding.ftl | 20 -- .../test/templatesuite/templates/include2.ftl | 6 - .../freemarker/test/templatesuite/testcases.xml | 5 +- 30 files changed, 562 insertions(+), 1115 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/ASTDirInclude.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ASTDirInclude.java b/src/main/java/org/apache/freemarker/core/ASTDirInclude.java index 9a51f16..46f71f3 100644 --- a/src/main/java/org/apache/freemarker/core/ASTDirInclude.java +++ b/src/main/java/org/apache/freemarker/core/ASTDirInclude.java @@ -21,52 +21,26 @@ package org.apache.freemarker.core; import java.io.IOException; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateScalarModel; import org.apache.freemarker.core.templateresolver.MalformedTemplateNameException; import org.apache.freemarker.core.util.BugException; import org.apache.freemarker.core.util._StringUtil; - /** * AST directive node: {@code #include} */ final class ASTDirInclude extends ASTDirective { - private final ASTExpression includedTemplateNameExp, encodingExp, ignoreMissingExp; - private final String encoding; + private final ASTExpression includedTemplateNameExp, ignoreMissingExp; private final Boolean ignoreMissingExpPrecalcedValue; /** * @param template the template that this <tt>#include</tt> is a part of. * @param includedTemplateNameExp the path of the template to be included. - * @param encodingExp the encoding to be used or null, if it's the default. */ ASTDirInclude(Template template, ASTExpression includedTemplateNameExp, - ASTExpression encodingExp, ASTExpression ignoreMissingExp) throws ParseException { + ASTExpression ignoreMissingExp) throws ParseException { this.includedTemplateNameExp = includedTemplateNameExp; - - this.encodingExp = encodingExp; - if (encodingExp == null) { - encoding = null; - } else { - if (encodingExp.isLiteral()) { - try { - TemplateModel tm = encodingExp.eval(null); - if (!(tm instanceof TemplateScalarModel)) { - throw new ParseException("Expected a string as the value of the \"encoding\" argument", - encodingExp); - } - encoding = ((TemplateScalarModel) tm).getAsString(); - } catch (TemplateException e) { - // evaluation of literals must not throw a TemplateException - throw new BugException(e); - } - } else { - encoding = null; - } - } this.ignoreMissingExp = ignoreMissingExp; if (ignoreMissingExp != null && ignoreMissingExp.isLiteral()) { @@ -99,12 +73,6 @@ final class ASTDirInclude extends ASTDirective { e.getMalformednessDescription()); } - final String encoding = this.encoding != null - ? this.encoding - : (encodingExp != null - ? encodingExp.evalAndCoerceToPlainText(env) - : null); - final boolean ignoreMissing; if (ignoreMissingExpPrecalcedValue != null) { ignoreMissing = ignoreMissingExpPrecalcedValue.booleanValue(); @@ -116,7 +84,7 @@ final class ASTDirInclude extends ASTDirective { final Template includedTemplate; try { - includedTemplate = env.getTemplateForInclusion(fullIncludedTemplateName, encoding, ignoreMissing); + includedTemplate = env.getTemplateForInclusion(fullIncludedTemplateName, ignoreMissing); } catch (IOException e) { throw new _MiscTemplateException(e, env, "Template inclusion failed (for parameter value ", @@ -137,9 +105,6 @@ final class ASTDirInclude extends ASTDirective { buf.append(getNodeTypeSymbol()); buf.append(' '); buf.append(includedTemplateNameExp.getCanonicalForm()); - if (encodingExp != null) { - buf.append(" encoding=").append(encodingExp.getCanonicalForm()); - } if (ignoreMissingExp != null) { buf.append(" ignore_missing=").append(ignoreMissingExp.getCanonicalForm()); } @@ -154,15 +119,14 @@ final class ASTDirInclude extends ASTDirective { @Override int getParameterCount() { - return 3; + return 2; } @Override Object getParameterValue(int idx) { switch (idx) { case 0: return includedTemplateNameExp; - case 1: return encodingExp; - case 2: return ignoreMissingExp; + case 1: return ignoreMissingExp; default: throw new IndexOutOfBoundsException(); } } @@ -171,8 +135,7 @@ final class ASTDirInclude extends ASTDirective { ParameterRole getParameterRole(int idx) { switch (idx) { case 0: return ParameterRole.TEMPLATE_NAME; - case 1: return ParameterRole.ENCODING_PARAMETER; - case 2: return ParameterRole.IGNORE_MISSING_PARAMETER; + case 1: return ParameterRole.IGNORE_MISSING_PARAMETER; default: throw new IndexOutOfBoundsException(); } } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/Configuration.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/Configuration.java b/src/main/java/org/apache/freemarker/core/Configuration.java index e58ca5b..c5d290f 100644 --- a/src/main/java/org/apache/freemarker/core/Configuration.java +++ b/src/main/java/org/apache/freemarker/core/Configuration.java @@ -22,6 +22,7 @@ package org.apache.freemarker.core; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Collections; @@ -38,8 +39,6 @@ import java.util.Properties; import java.util.Set; import java.util.TimeZone; import java.util.TreeSet; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import org.apache.freemarker.core.model.ObjectWrapper; import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper; @@ -439,8 +438,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf private HashMap<String, Object> rewrappableSharedVariables = null; private String defaultEncoding = getDefaultDefaultEncoding(); - private ConcurrentMap localeToCharsetMap = new ConcurrentHashMap(); - + /** * @deprecated Use {@link #Configuration(Version)} instead. Note that the version can be still modified later with * {@link Configuration#setIncompatibleImprovements(Version)} (or @@ -580,7 +578,6 @@ public class Configuration extends Configurable implements Cloneable, ParserConf try { Configuration copy = (Configuration) super.clone(); copy.sharedVariables = new HashMap(sharedVariables); - copy.localeToCharsetMap = new ConcurrentHashMap(localeToCharsetMap); copy.recreateTemplateResolverWith( templateResolver.getTemplateLoader(), templateResolver.getCacheStorage(), templateResolver.getTemplateLookupStrategy(), templateResolver.getTemplateNameFormat(), @@ -598,112 +595,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf sharedVariables.put("normalize_newlines", new NormalizeNewlines()); sharedVariables.put("xml_escape", new XmlEscape()); } - - /** - * Loads a preset language-to-encoding map, similarly as if you have called - * {@link #clearEncodingMap()} and then did multiple {@link #setEncoding(Locale, String)} calls. - * It assumes the usual character encodings for most languages. - * The previous content of the encoding map will be lost. - * This default map currently contains the following mappings: - * - * <table style="width: auto; border-collapse: collapse" border="1" summary="preset language to encoding mapping"> - * <tr><td>ar</td><td>ISO-8859-6</td></tr> - * <tr><td>be</td><td>ISO-8859-5</td></tr> - * <tr><td>bg</td><td>ISO-8859-5</td></tr> - * <tr><td>ca</td><td>ISO-8859-1</td></tr> - * <tr><td>cs</td><td>ISO-8859-2</td></tr> - * <tr><td>da</td><td>ISO-8859-1</td></tr> - * <tr><td>de</td><td>ISO-8859-1</td></tr> - * <tr><td>el</td><td>ISO-8859-7</td></tr> - * <tr><td>en</td><td>ISO-8859-1</td></tr> - * <tr><td>es</td><td>ISO-8859-1</td></tr> - * <tr><td>et</td><td>ISO-8859-1</td></tr> - * <tr><td>fi</td><td>ISO-8859-1</td></tr> - * <tr><td>fr</td><td>ISO-8859-1</td></tr> - * <tr><td>hr</td><td>ISO-8859-2</td></tr> - * <tr><td>hu</td><td>ISO-8859-2</td></tr> - * <tr><td>is</td><td>ISO-8859-1</td></tr> - * <tr><td>it</td><td>ISO-8859-1</td></tr> - * <tr><td>iw</td><td>ISO-8859-8</td></tr> - * <tr><td>ja</td><td>Shift_JIS</td></tr> - * <tr><td>ko</td><td>EUC-KR</td></tr> - * <tr><td>lt</td><td>ISO-8859-2</td></tr> - * <tr><td>lv</td><td>ISO-8859-2</td></tr> - * <tr><td>mk</td><td>ISO-8859-5</td></tr> - * <tr><td>nl</td><td>ISO-8859-1</td></tr> - * <tr><td>no</td><td>ISO-8859-1</td></tr> - * <tr><td>pl</td><td>ISO-8859-2</td></tr> - * <tr><td>pt</td><td>ISO-8859-1</td></tr> - * <tr><td>ro</td><td>ISO-8859-2</td></tr> - * <tr><td>ru</td><td>ISO-8859-5</td></tr> - * <tr><td>sh</td><td>ISO-8859-5</td></tr> - * <tr><td>sk</td><td>ISO-8859-2</td></tr> - * <tr><td>sl</td><td>ISO-8859-2</td></tr> - * <tr><td>sq</td><td>ISO-8859-2</td></tr> - * <tr><td>sr</td><td>ISO-8859-5</td></tr> - * <tr><td>sv</td><td>ISO-8859-1</td></tr> - * <tr><td>tr</td><td>ISO-8859-9</td></tr> - * <tr><td>uk</td><td>ISO-8859-5</td></tr> - * <tr><td>zh</td><td>GB2312</td></tr> - * <tr><td>zh_TW</td><td>Big5</td></tr> - * </table> - * - * @see #clearEncodingMap() - * @see #setEncoding(Locale, String) - * @see #setDefaultEncoding(String) - */ - public void loadBuiltInEncodingMap() { - localeToCharsetMap.clear(); - localeToCharsetMap.put("ar", "ISO-8859-6"); - localeToCharsetMap.put("be", "ISO-8859-5"); - localeToCharsetMap.put("bg", "ISO-8859-5"); - localeToCharsetMap.put("ca", "ISO-8859-1"); - localeToCharsetMap.put("cs", "ISO-8859-2"); - localeToCharsetMap.put("da", "ISO-8859-1"); - localeToCharsetMap.put("de", "ISO-8859-1"); - localeToCharsetMap.put("el", "ISO-8859-7"); - localeToCharsetMap.put("en", "ISO-8859-1"); - localeToCharsetMap.put("es", "ISO-8859-1"); - localeToCharsetMap.put("et", "ISO-8859-1"); - localeToCharsetMap.put("fi", "ISO-8859-1"); - localeToCharsetMap.put("fr", "ISO-8859-1"); - localeToCharsetMap.put("hr", "ISO-8859-2"); - localeToCharsetMap.put("hu", "ISO-8859-2"); - localeToCharsetMap.put("is", "ISO-8859-1"); - localeToCharsetMap.put("it", "ISO-8859-1"); - localeToCharsetMap.put("iw", "ISO-8859-8"); - localeToCharsetMap.put("ja", "Shift_JIS"); - localeToCharsetMap.put("ko", "EUC-KR"); - localeToCharsetMap.put("lt", "ISO-8859-2"); - localeToCharsetMap.put("lv", "ISO-8859-2"); - localeToCharsetMap.put("mk", "ISO-8859-5"); - localeToCharsetMap.put("nl", "ISO-8859-1"); - localeToCharsetMap.put("no", "ISO-8859-1"); - localeToCharsetMap.put("pl", "ISO-8859-2"); - localeToCharsetMap.put("pt", "ISO-8859-1"); - localeToCharsetMap.put("ro", "ISO-8859-2"); - localeToCharsetMap.put("ru", "ISO-8859-5"); - localeToCharsetMap.put("sh", "ISO-8859-5"); - localeToCharsetMap.put("sk", "ISO-8859-2"); - localeToCharsetMap.put("sl", "ISO-8859-2"); - localeToCharsetMap.put("sq", "ISO-8859-2"); - localeToCharsetMap.put("sr", "ISO-8859-5"); - localeToCharsetMap.put("sv", "ISO-8859-1"); - localeToCharsetMap.put("tr", "ISO-8859-9"); - localeToCharsetMap.put("uk", "ISO-8859-5"); - localeToCharsetMap.put("zh", "GB2312"); - localeToCharsetMap.put("zh_TW", "Big5"); - } - - /** - * Clears language-to-encoding map. - * @see #loadBuiltInEncodingMap - * @see #setEncoding - */ - public void clearEncodingMap() { - localeToCharsetMap.clear(); - } - + /** * Sets a {@link TemplateLoader} that is used to look up and load templates; * as a side effect the template templateResolver will be emptied. @@ -1894,53 +1786,44 @@ public class Configuration extends Configurable implements Cloneable, ParserConf * missing/staled. * * <p> - * This is a shorthand for {@link #getTemplate(String, Locale, Object, String, boolean) - * getTemplate(name, null, null, null, false)}; see more details there. + * This is a shorthand for {@link #getTemplate(String, Locale, Serializable, boolean) + * getTemplate(name, null, null, false)}; see more details there. * * <p> * See {@link Configuration} for an example of basic usage. */ public Template getTemplate(String name) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException { - return getTemplate(name, null, null, null, false); + return getTemplate(name, null, null, false); } /** - * Shorthand for {@link #getTemplate(String, Locale, Object, String, boolean) + * Shorthand for {@link #getTemplate(String, Locale, Serializable, boolean) * getTemplate(name, locale, null, null, false)}. */ public Template getTemplate(String name, Locale locale) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException { - return getTemplate(name, locale, null, null, false); + return getTemplate(name, locale, null, false); } /** - * Shorthand for {@link #getTemplate(String, Locale, Object, String, boolean) - * getTemplate(name, null, null, encoding, false)}. + * Shorthand for {@link #getTemplate(String, Locale, Serializable, boolean) + * getTemplate(name, locale, customLookupCondition, false)}. */ - public Template getTemplate(String name, String encoding) + public Template getTemplate(String name, Locale locale, Serializable customLookupCondition) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException { - return getTemplate(name, null, null, encoding, false); + return getTemplate(name, locale, customLookupCondition, false); } /** - * Shorthand for {@link #getTemplate(String, Locale, Object, String, boolean) - * getTemplate(name, locale, null, encoding, false)}. - */ - public Template getTemplate(String name, Locale locale, String encoding) - throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException { - return getTemplate(name, locale, null, encoding, false); - } - - /** - * Shorthand for {@link #getTemplate(String, Locale, Object, String, boolean) - * getTemplate(name, locale, null, encoding, ignoreMissing)}. + * Shorthand for {@link #getTemplate(String, Locale, Serializable, boolean) + * getTemplate(name, locale, null, ignoreMissing)}. * * @since 2.3.21 */ - public Template getTemplate(String name, Locale locale, String encoding, boolean ignoreMissing) + public Template getTemplate(String name, Locale locale, boolean ignoreMissing) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException { - return getTemplate(name, locale, null, encoding, ignoreMissing); + return getTemplate(name, locale, null, ignoreMissing); } /** @@ -1996,19 +1879,6 @@ public class Configuration extends Configurable implements Cloneable, ParserConf * custom {@link TemplateLookupStrategy}. See also: * {@link TemplateLookupContext#getCustomLookupCondition()}. * - * @param encoding - * Deprecated mechanism, {@code null} is the recommended; the charset used to interpret the template - * source code bytes (if it's read from a binary source). Can be {@code null} since 2.3.22, in which case - * it will default to {@link Configuration#getEncoding(Locale)} where {@code Locale} is the - * {@code locale} parameter (when {@code locale} was {@code null} too, the its default value is used - * instead). Why is this deprecated: It doesn't make sense to get the <em>same</em> template with - * different encodings, hence, it's error prone to specify the encoding where you get the template. - * Instead, if you have template "files" with different charsets, you should use - * {@link #setTemplateConfigurations(TemplateConfigurationFactory)}, where you can associate encodings to - * individual templates based on their names (like which "directory" are they in, what's their file - * extension, etc.). The encoding associated with the templates that way overrides the encoding that you - * specify here. - * * @param ignoreMissing * If {@code true}, the method won't throw {@link TemplateNotFoundException} if the template doesn't * exist, instead it returns {@code null}. Other kind of exceptions won't be suppressed. @@ -2029,17 +1899,13 @@ public class Configuration extends Configurable implements Cloneable, ParserConf * * @since 2.3.22 */ - public Template getTemplate(String name, Locale locale, Object customLookupCondition, - String encoding, boolean ignoreMissing) + public Template getTemplate(String name, Locale locale, Serializable customLookupCondition, boolean + ignoreMissing) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException { if (locale == null) { locale = getLocale(); } - if (encoding == null) { - encoding = getEncoding(locale); - } - - final GetTemplateResult maybeTemp = templateResolver.getTemplate(name, locale, customLookupCondition, encoding); + final GetTemplateResult maybeTemp = templateResolver.getTemplate(name, locale, customLookupCondition); final Template temp = maybeTemp.getTemplate(); if (temp == null) { if (ignoreMissing) { @@ -2112,18 +1978,19 @@ public class Configuration extends Configurable implements Cloneable, ParserConf } /** - * Sets the charset used for decoding byte sequences to character sequences when - * reading template files in a locale for which no explicit encoding - * was specified via {@link #setEncoding(Locale, String)}. Note that by default there is no locale specified for - * any locale, so the default encoding is always in effect. - * + * Sets the charset used for decoding template files when there's no matching + * {@linkplain #getTemplateConfigurations() template configuration} that specifies + * the charset of the template. + * + * <p>Individual templates may specify their own charset by starting with + * <tt><#ftl encoding="..."></tt>. However, before that's detected, at least part of template must be + * decoded with some charset first, so this setting and {@linkplain #getTemplateConfigurations() template + * configuration} still has a role. + * * <p>Defaults to the default system encoding, which can change from one server to * another, so <b>you should always set this setting</b>. If you don't know what charset your should chose, * {@code "UTF-8"} is usually a good choice. - * - * <p>Note that individual templates may specify their own charset by starting with - * <tt><#ftl encoding="..."></tt> - * + * * @param encoding The name of the charset, such as {@code "UTF-8"} or {@code "ISO-8859-1"} */ public void setDefaultEncoding(String encoding) { @@ -2171,48 +2038,6 @@ public class Configuration extends Configurable implements Cloneable, ParserConf } /** - * Gets the preferred character encoding for the given locale, or the - * default encoding if no encoding is set explicitly for the specified - * locale. You can associate encodings with locales using - * {@link #setEncoding(Locale, String)} or {@link #loadBuiltInEncodingMap()}. - */ - public String getEncoding(Locale locale) { - if (localeToCharsetMap.isEmpty()) { - return defaultEncoding; - } else { - // Try for a full name match (may include country and variant) - String charset = (String) localeToCharsetMap.get(locale.toString()); - if (charset == null) { - if (locale.getVariant().length() > 0) { - Locale l = new Locale(locale.getLanguage(), locale.getCountry()); - charset = (String) localeToCharsetMap.get(l.toString()); - if (charset != null) { - localeToCharsetMap.put(locale.toString(), charset); - } - } - charset = (String) localeToCharsetMap.get(locale.getLanguage()); - if (charset != null) { - localeToCharsetMap.put(locale.toString(), charset); - } - } - return charset != null ? charset : defaultEncoding; - } - } - - /** - * Sets the character set encoding to use for templates of - * a given locale. If there is no explicit encoding set for some - * locale, then the default encoding will be used, what you can - * set with {@link #setDefaultEncoding}. - * - * @see #clearEncodingMap - * @see #loadBuiltInEncodingMap - */ - public void setEncoding(Locale locale, String encoding) { - localeToCharsetMap.put(locale.toString(), encoding); - } - - /** * Adds a shared variable to the configuration. * Shared sharedVariables are sharedVariables that are visible * as top-level sharedVariables for all templates which use this @@ -2377,8 +2202,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf * @since 2.3.19 */ public void removeTemplateFromCache(String name) throws IOException { - Locale loc = getLocale(); - removeTemplateFromCache(name, loc, getEncoding(loc)); + removeTemplateFromCache(name, getLocale()); } /** @@ -2386,15 +2210,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf * @since 2.3.19 */ public void removeTemplateFromCache(String name, Locale locale) throws IOException { - removeTemplateFromCache(name, locale, getEncoding(locale)); - } - - /** - * Equivalent to <tt>removeTemplateFromCache(name, thisCfg.getLocale(), encoding, true)</tt>. - * @since 2.3.19 - */ - public void removeTemplateFromCache(String name, String encoding) throws IOException { - removeTemplateFromCache(name, getLocale(), encoding); + removeTemplateFromCache(name, locale, null); } /** @@ -2404,14 +2220,15 @@ public class Configuration extends Configurable implements Cloneable, ParserConf * alone does. * * <p>For the meaning of the parameters, see - * {@link #getTemplate(String, Locale, String, boolean)}. + * {@link #getTemplate(String, Locale, Serializable, boolean)}. * * <p>This method is thread-safe and can be called while the engine processes templates. * * @since 2.3.19 */ - public void removeTemplateFromCache(String name, Locale locale, String encoding) throws IOException { - templateResolver.removeTemplateFromCache(name, locale, encoding); + public void removeTemplateFromCache(String name, Locale locale, Serializable customLookupCondition) + throws IOException { + templateResolver.removeTemplateFromCache(name, locale, customLookupCondition); } /** http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/Environment.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/Environment.java b/src/main/java/org/apache/freemarker/core/Environment.java index cac703d..7eac791 100644 --- a/src/main/java/org/apache/freemarker/core/Environment.java +++ b/src/main/java/org/apache/freemarker/core/Environment.java @@ -21,6 +21,7 @@ package org.apache.freemarker.core; import java.io.IOException; import java.io.PrintWriter; +import java.io.Serializable; import java.io.StringWriter; import java.io.Writer; import java.sql.Time; @@ -2368,21 +2369,19 @@ public final class Environment extends Configurable { * separately call these two methods, so you can determine the source of exceptions more precisely, and thus achieve * more intelligent error handling. * - * @see #getTemplateForInclusion(String name, String encoding, boolean parse) + * @see #getTemplateForInclusion(String, boolean) * @see #include(Template includedTemplate) */ - public void include(String name, String encoding, boolean parse) - throws IOException, TemplateException { - include(getTemplateForInclusion(name, encoding, parse)); + public void include(String name, boolean parse) throws IOException, TemplateException { + include(getTemplateForInclusion(name, parse)); } /** - * Same as {@link #getTemplateForInclusion(String, String, boolean)} with {@code false} + * Same as {@link #getTemplateForInclusion(String, boolean)} with {@code false} * {@code ignoreMissing} argument. */ - public Template getTemplateForInclusion(String name, String encoding) - throws IOException { - return getTemplateForInclusion(name, encoding, false); + public Template getTemplateForInclusion(String name) throws IOException { + return getTemplateForInclusion(name, false); } /** @@ -2396,54 +2395,34 @@ public final class Environment extends Configurable { * currently executing template file). (Note that you can use * {@link TemplateResolver#toRootBasedName(String, String)} to convert paths to template root based * paths.) For more details see the identical parameter of - * {@link Configuration#getTemplate(String, Locale, String, boolean)} - * - * @param encoding - * the charset of the obtained template. If {@code null}, the encoding of the top template that is - * currently being processed in this {@link Environment} is used, which can lead to odd situations, so - * using {@code null} is not recommended. In most applications, the value of - * {@link Configuration#getEncoding(Locale)} (or {@link Configuration#getDefaultEncoding()}) should be - * used here. + * {@link Configuration#getTemplate(String, Locale, Serializable, boolean)} * * @param ignoreMissing - * See identical parameter of {@link Configuration#getTemplate(String, Locale, String, boolean)} + * See identical parameter of {@link Configuration#getTemplate(String, Locale, Serializable, boolean)} * - * @return Same as {@link Configuration#getTemplate(String, Locale, String, boolean)} + * @return Same as {@link Configuration#getTemplate(String, Locale, Serializable, boolean)} * @throws IOException * Same as exceptions thrown by - * {@link Configuration#getTemplate(String, Locale, String, boolean)} + * {@link Configuration#getTemplate(String, Locale, Serializable, boolean)} * * @since 2.3.21 */ - public Template getTemplateForInclusion(String name, String encoding, boolean ignoreMissing) + public Template getTemplateForInclusion(String name, boolean ignoreMissing) throws IOException { - return configuration.getTemplate( - name, getLocale(), getIncludedTemplateCustomLookupCondition(), - encoding != null ? encoding : getIncludedTemplateEncoding(), - ignoreMissing); + return configuration.getTemplate(name, getLocale(), getIncludedTemplateCustomLookupCondition(), ignoreMissing); } - private Object getIncludedTemplateCustomLookupCondition() { + private Serializable getIncludedTemplateCustomLookupCondition() { return getCurrentTemplate().getCustomLookupCondition(); } - private String getIncludedTemplateEncoding() { - String encoding; - // [FM3] This branch shouldn't exist, as it doesn't make much sense to inherit encoding. But we have to keep BC. - encoding = getCurrentTemplate().getEncoding(); - if (encoding == null) { - encoding = configuration.getEncoding(getLocale()); - } - return encoding; - } - /** * Processes a Template in the context of this <code>Environment</code>, including its output in the * <code>Environment</code>'s Writer. * * @param includedTemplate * the template to process. Note that it does <em>not</em> need to be a template returned by - * {@link #getTemplateForInclusion(String name, String encoding, boolean parse)}. + * {@link #getTemplateForInclusion(String, boolean)}. */ public void include(Template includedTemplate) throws TemplateException, IOException { @@ -2522,7 +2501,7 @@ public final class Environment extends Configurable { * paths.) */ public Template getTemplateForImporting(String name) throws IOException { - return getTemplateForInclusion(name, null, true); + return getTemplateForInclusion(name, true); } /** @@ -2767,8 +2746,7 @@ public final class Environment extends Configurable { private final String templateName; private final Locale locale; - private final String encoding; - private final Object customLookupCondition; + private final Serializable customLookupCondition; private InitializationStatus status = InitializationStatus.UNINITIALIZED; @@ -2782,7 +2760,6 @@ public final class Environment extends Configurable { this.templateName = templateName; // Make snapshot of all settings that influence template resolution: locale = getLocale(); - encoding = getIncludedTemplateEncoding(); customLookupCondition = getIncludedTemplateCustomLookupCondition(); } @@ -2821,9 +2798,7 @@ public final class Environment extends Configurable { } private void initialize() throws IOException, TemplateException { - setTemplate(configuration.getTemplate( - templateName, locale, customLookupCondition, encoding, - false)); + setTemplate(configuration.getTemplate(templateName, locale, customLookupCondition, false)); Locale lastLocale = getLocale(); try { setLocale(locale); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/ParameterRole.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ParameterRole.java b/src/main/java/org/apache/freemarker/core/ParameterRole.java index 1270b1c..146f0b8 100644 --- a/src/main/java/org/apache/freemarker/core/ParameterRole.java +++ b/src/main/java/org/apache/freemarker/core/ParameterRole.java @@ -52,7 +52,6 @@ final class ParameterRole { static final ParameterRole LIST_SOURCE = new ParameterRole("list source"); static final ParameterRole TARGET_LOOP_VARIABLE = new ParameterRole("target loop variable"); static final ParameterRole TEMPLATE_NAME = new ParameterRole("template name"); - static final ParameterRole ENCODING_PARAMETER = new ParameterRole("\"encoding\" parameter"); static final ParameterRole IGNORE_MISSING_PARAMETER = new ParameterRole("\"ignore_missing\" parameter"); static final ParameterRole PARAMETER_NAME = new ParameterRole("parameter name"); static final ParameterRole PARAMETER_DEFAULT = new ParameterRole("parameter default"); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/Template.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/Template.java b/src/main/java/org/apache/freemarker/core/Template.java index 23096fe..e253197 100644 --- a/src/main/java/org/apache/freemarker/core/Template.java +++ b/src/main/java/org/apache/freemarker/core/Template.java @@ -26,6 +26,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.io.Reader; +import java.io.Serializable; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; @@ -34,6 +35,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Vector; @@ -80,7 +82,7 @@ public class Template extends Configurable { private List imports = new Vector(); private ASTElement rootElement; private String encoding, defaultNS; - private Object customLookupCondition; + private Serializable customLookupCondition; private int actualTagSyntax; private int actualNamingConvention; private boolean autoEscaping; @@ -567,17 +569,16 @@ public class Template extends Configurable { /** * @param encoding - * The encoding that was used to read this template. When this template {@code #include}-s or - * {@code #import}-s another template, by default it will use this encoding for those. For backward - * compatibility, this can be {@code null}, which will unset this setting. + * The encoding that was used to read this template, or {@code null} if the source of the template + * already gives back text (as opposed to binary data), so no decoding with a charset was needed. */ void setEncoding(String encoding) { this.encoding = encoding; } /** - * Returns the default character encoding used for reading included/imported files; if {@code null}, then - * the encoding returned by {@link Configuration#getEncoding(java.util.Locale)} should be used instead. + * The encoding that was used to read this template, or {@code null} if the source of the template + * already gives back text (as opposed to binary data), so no decoding with a charset was needed. */ public String getEncoding() { return encoding; @@ -585,12 +586,10 @@ public class Template extends Configurable { /** * Gets the custom lookup condition with which this template was found. See the {@code customLookupCondition} - * parameter of {@link Configuration#getTemplate(String, java.util.Locale, Object, String, boolean)} for - * more explanation. - * - * @since 2.3.22 + * parameter of {@link Configuration#getTemplate(String, Locale, Serializable, boolean)} for more + * explanation. */ - public Object getCustomLookupCondition() { + public Serializable getCustomLookupCondition() { return customLookupCondition; } @@ -599,10 +598,8 @@ public class Template extends Configurable { * after instantiating the template with its constructor, after a successfull lookup that used this condition. So * this should only be called from code that deals with creating new {@code Template} objects, like from * {@link DefaultTemplateResolver}. - * - * @since 2.3.22 */ - public void setCustomLookupCondition(Object customLookupCondition) { + public void setCustomLookupCondition(Serializable customLookupCondition) { this.customLookupCondition = customLookupCondition; } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/TemplateConfiguration.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/TemplateConfiguration.java b/src/main/java/org/apache/freemarker/core/TemplateConfiguration.java index 2e8c0f6..3d1b903 100644 --- a/src/main/java/org/apache/freemarker/core/TemplateConfiguration.java +++ b/src/main/java/org/apache/freemarker/core/TemplateConfiguration.java @@ -539,11 +539,7 @@ public final class TemplateConfiguration extends Configurable implements ParserC /** * When the standard template loading/caching mechanism is used, this forces the charset used for reading the - * template "file", overriding everything but the encoding coming from the {@code #ftl} header. This setting - * overrides the locale-specific encodings set via {@link Configuration#setEncoding(java.util.Locale, String)}. It - * also overrides the {@code encoding} parameter of {@link Configuration#getTemplate(String, String)} (and of its - * overloads) and the {@code encoding} parameter of the {@code #include} directive. This works like that because - * specifying the encoding where you are requesting the template is error prone and deprecated. + * template "file", overriding everything but the encoding coming from the {@code #ftl} header. * * <p> * If you are developing your own template loading/caching mechanism instead of the standard one, note that the http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/TemplateNotFoundException.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/TemplateNotFoundException.java b/src/main/java/org/apache/freemarker/core/TemplateNotFoundException.java index fced93f..37ba911 100644 --- a/src/main/java/org/apache/freemarker/core/TemplateNotFoundException.java +++ b/src/main/java/org/apache/freemarker/core/TemplateNotFoundException.java @@ -20,6 +20,7 @@ package org.apache.freemarker.core; import java.io.FileNotFoundException; +import java.io.Serializable; import org.apache.freemarker.core.templateresolver.MalformedTemplateNameException; @@ -54,7 +55,7 @@ public final class TemplateNotFoundException extends FileNotFoundException { /** * The custom lookup condition with which the template was requested, or {@code null} if there's no such condition. * See the {@code customLookupCondition} parameter of - * {@link Configuration#getTemplate(String, java.util.Locale, Object, String, boolean)}. + * {@link Configuration#getTemplate(String, java.util.Locale, Serializable, boolean)}. */ public Object getCustomLookupCondition() { return customLookupCondition; http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/templateresolver/GetTemplateResult.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/templateresolver/GetTemplateResult.java b/src/main/java/org/apache/freemarker/core/templateresolver/GetTemplateResult.java index 2260267..58c9ea9 100644 --- a/src/main/java/org/apache/freemarker/core/templateresolver/GetTemplateResult.java +++ b/src/main/java/org/apache/freemarker/core/templateresolver/GetTemplateResult.java @@ -18,12 +18,13 @@ */ package org.apache.freemarker.core.templateresolver; +import java.io.Serializable; import java.util.Locale; import org.apache.freemarker.core.Template; /** - * Used for the return value of {@link TemplateResolver#getTemplate(String, Locale, Object, String)}. + * Used for the return value of {@link TemplateResolver#getTemplate(String, Locale, Serializable)} . * * @since 3.0.0 */ http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLoaderSession.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLoaderSession.java b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLoaderSession.java index 7d6f7a6..6bf1b1f 100644 --- a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLoaderSession.java +++ b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLoaderSession.java @@ -21,6 +21,7 @@ package org.apache.freemarker.core.templateresolver; import java.io.IOException; import java.io.InputStream; import java.io.Reader; +import java.io.Serializable; import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateResolver; @@ -28,7 +29,7 @@ import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateResolver; * Stores shared state between {@link TemplateLoader} operations that are executed close to each other in the same * thread. For example, a {@link TemplateLoader} that reads from a database might wants to store the database * connection in it for reuse. The goal of sessions is mostly to increase performance. However, because a - * {@link DefaultTemplateResolver#getTemplate(String, java.util.Locale, Object, String)} call is executed inside a single + * {@link DefaultTemplateResolver#getTemplate(String, java.util.Locale, Serializable)} call is executed inside a single * session, sessions can be also be utilized to ensure that the template lookup (see {@link TemplateLookupStrategy}) * happens on a consistent view (a snapshot) of the backing storage, if the backing storage mechanism supports such * thing. http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLookupContext.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLookupContext.java b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLookupContext.java index 3db956c..0a3b33a 100644 --- a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLookupContext.java +++ b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateLookupContext.java @@ -92,7 +92,7 @@ public abstract class TemplateLookupContext<R extends TemplateLookupResult> { /** * Returns the value of the {@code customLookupCondition} parameter of - * {@link Configuration#getTemplate(String, Locale, Object, String, boolean)}; see requirements there, such + * {@link Configuration#getTemplate(String, Locale, Serializable, boolean)}; see requirements there, such * as having a proper {@link Object#equals(Object)} and {@link Object#hashCode()} method. The interpretation of this * value is up to the custom {@link TemplateLookupStrategy}. Usually, it's used similarly to as the default lookup * strategy uses {@link #getTemplateLocale()}, that is, to look for a template variation that satisfies the http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java index 1b04ba7..f257e2b 100644 --- a/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java +++ b/src/main/java/org/apache/freemarker/core/templateresolver/TemplateResolver.java @@ -19,6 +19,7 @@ package org.apache.freemarker.core.templateresolver; import java.io.IOException; +import java.io.Serializable; import java.util.Locale; import org.apache.freemarker.core.Configuration; @@ -62,7 +63,7 @@ public abstract class TemplateResolver { * * <p> * All parameters must be non-{@code null}, except {@code customLookupCondition}. For the meaning of the parameters - * see {@link Configuration#getTemplate(String, Locale, String, boolean)}. + * see {@link Configuration#getTemplate(String, Locale, Serializable, boolean)}. * * @return A {@link GetTemplateResult} object that contains the {@link Template}, or a * {@link GetTemplateResult} object that contains {@code null} as the {@link Template} and information @@ -82,8 +83,7 @@ public abstract class TemplateResolver { * value. */ // [FM3] This parameters will be removed: String encoding - public abstract GetTemplateResult getTemplate(String name, Locale locale, Object customLookupCondition, - String encoding) + public abstract GetTemplateResult getTemplate(String name, Locale locale, Serializable customLookupCondition) throws MalformedTemplateNameException, ParseException, IOException; /** @@ -108,7 +108,7 @@ public abstract class TemplateResolver { * {@link Configuration#setTemplateUpdateDelayMilliseconds(long)} alone does. * * <p> - * For the meaning of the parameters, see {@link #getTemplate(String, Locale, Object, String)} + * For the meaning of the parameters, see {@link #getTemplate(String, Locale, Serializable)} * * <p> * This method is thread-safe and can be called while the engine processes templates. @@ -116,7 +116,7 @@ public abstract class TemplateResolver { * @throws UnsupportedOperationException If the {@link TemplateResolver} implementation doesn't support this * operation. */ - public abstract void removeTemplateFromCache(String name, Locale locale, String encoding) + public abstract void removeTemplateFromCache(String name, Locale locale, Serializable customLookupCondition) throws IOException, UnsupportedOperationException; /** http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateResolver.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateResolver.java b/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateResolver.java index 14d04f7..a5a574c 100644 --- a/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateResolver.java +++ b/src/main/java/org/apache/freemarker/core/templateresolver/impl/DefaultTemplateResolver.java @@ -198,7 +198,7 @@ public class DefaultTemplateResolver extends TemplateResolver { * * <p> * All parameters must be non-{@code null}, except {@code customLookupCondition}. For the meaning of the parameters - * see {@link Configuration#getTemplate(String, Locale, String, boolean)}. + * see {@link Configuration#getTemplate(String, Locale, Serializable, boolean)}. * * @return A {@link GetTemplateResult} object that contains the {@link Template}, or a * {@link GetTemplateResult} object that contains {@code null} as the {@link Template} and information @@ -223,20 +223,18 @@ public class DefaultTemplateResolver extends TemplateResolver { * @since 2.3.22 */ @Override - public GetTemplateResult getTemplate(String name, Locale locale, Object customLookupCondition, - String encoding) + public GetTemplateResult getTemplate(String name, Locale locale, Serializable customLookupCondition) throws IOException { _NullArgumentException.check("name", name); _NullArgumentException.check("locale", locale); - _NullArgumentException.check("encoding", encoding); - + name = templateNameFormat.normalizeRootBasedName(name); if (templateLoader == null) { return new GetTemplateResult(name, "The TemplateLoader (and TemplateLoader2) was null."); } - Template template = getTemplateInternal(name, locale, customLookupCondition, encoding); + Template template = getTemplateInternal(name, locale, customLookupCondition); return template != null ? new GetTemplateResult(template) : new GetTemplateResult(name, (String) null); } @@ -251,14 +249,13 @@ public class DefaultTemplateResolver extends TemplateResolver { } private Template getTemplateInternal( - final String name, final Locale locale, final Object customLookupCondition, - final String encoding) + final String name, final Locale locale, final Serializable customLookupCondition) throws IOException { final boolean debug = LOG.isDebugEnabled(); final String debugPrefix = debug - ? getDebugPrefix("getTemplate", name, locale, customLookupCondition, encoding) + ? getDebugPrefix("getTemplate", name, locale, customLookupCondition) : null; - final CachedResultKey cacheKey = new CachedResultKey(name, locale, customLookupCondition, encoding); + final CachedResultKey cacheKey = new CachedResultKey(name, locale, customLookupCondition); CachedResult oldCachedResult = (CachedResult) cacheStorage.get(cacheKey); @@ -387,8 +384,7 @@ public class DefaultTemplateResolver extends TemplateResolver { Template template = loadTemplate( templateLoaderResult, - name, newLookupResult.getTemplateSourceName(), locale, customLookupCondition, - encoding); + name, newLookupResult.getTemplateSourceName(), locale, customLookupCondition); if (session != null) { session.close(); if (debug) { @@ -524,8 +520,8 @@ public class DefaultTemplateResolver extends TemplateResolver { @SuppressWarnings("deprecation") private Template loadTemplate( TemplateLoadingResult templateLoaderResult, - final String name, final String sourceName, Locale locale, final Object customLookupCondition, - String initialEncoding) throws IOException { + final String name, final String sourceName, Locale locale, final Serializable customLookupCondition) + throws IOException { TemplateConfiguration tc; { TemplateConfiguration cfgTC; @@ -552,23 +548,13 @@ public class DefaultTemplateResolver extends TemplateResolver { } } - TemplateLanguage templateLanguage = null; - if (tc != null) { - // TC.{encoding,locale} is stronger than the cfg.getTemplate arguments by design. - if (tc.isEncodingSet()) { - initialEncoding = tc.getEncoding(); - } - if (tc.isLocaleSet()) { - locale = tc.getLocale(); - } - if (tc.isTemplateLanguageSet()) { - templateLanguage = tc.getTemplateLanguage(); - } + if (tc != null && tc.isLocaleSet()) { + locale = tc.getLocale(); } - if (templateLanguage == null) { - templateLanguage = config.getTemplateLanguage(); - } + String initialEncoding = tc != null && tc.isEncodingSet() ? tc.getEncoding() : config.getDefaultEncoding(); + TemplateLanguage templateLanguage = tc != null && tc.isTemplateLanguageSet() ? tc.getTemplateLanguage() + : config .getTemplateLanguage(); Template template; { @@ -689,7 +675,7 @@ public class DefaultTemplateResolver extends TemplateResolver { /** * Removes all entries from the cache, forcing reloading of templates on subsequent - * {@link #getTemplate(String, Locale, Object, String)} calls. + * {@link #getTemplate(String, Locale, Serializable)} calls. * * @param resetTemplateLoader * Whether to call {@link TemplateLoader#resetState()}. on the template loader. @@ -717,25 +703,16 @@ public class DefaultTemplateResolver extends TemplateResolver { } /** - * Same as {@link #removeTemplateFromCache(String, Locale, Object, String)} with {@code null} - * {@code customLookupCondition}. - */ - @Override - public void removeTemplateFromCache( - String name, Locale locale, String encoding) throws IOException { - removeTemplateFromCache(name, locale, null, encoding); - } - - /** * Removes an entry from the cache, hence forcing the re-loading of it when it's next time requested. (It doesn't * delete the template file itself.) This is to give the application finer control over cache updating than * {@link #setTemplateUpdateDelayMilliseconds(long)} alone does. * * For the meaning of the parameters, see - * {@link Configuration#getTemplate(String, Locale, Object, String, boolean)} + * {@link Configuration#getTemplate(String, Locale, Serializable, boolean)} */ + @Override public void removeTemplateFromCache( - String name, Locale locale, Object customLookupCondition, String encoding) + String name, Locale locale, Serializable customLookupCondition) throws IOException { if (name == null) { throw new IllegalArgumentException("Argument \"name\" can't be null"); @@ -743,16 +720,13 @@ public class DefaultTemplateResolver extends TemplateResolver { if (locale == null) { throw new IllegalArgumentException("Argument \"locale\" can't be null"); } - if (encoding == null) { - throw new IllegalArgumentException("Argument \"encoding\" can't be null"); - } name = templateNameFormat.normalizeRootBasedName(name); if (name != null && templateLoader != null) { boolean debug = LOG.isDebugEnabled(); String debugPrefix = debug - ? getDebugPrefix("removeTemplate", name, locale, customLookupCondition, encoding) + ? getDebugPrefix("removeTemplate", name, locale, customLookupCondition) : null; - CachedResultKey tk = new CachedResultKey(name, locale, customLookupCondition, encoding); + CachedResultKey tk = new CachedResultKey(name, locale, customLookupCondition); cacheStorage.remove(tk); if (debug) { @@ -761,11 +735,10 @@ public class DefaultTemplateResolver extends TemplateResolver { } } - private String getDebugPrefix(String operation, String name, Locale locale, Object customLookupCondition, String encoding) { + private String getDebugPrefix(String operation, String name, Locale locale, Object customLookupCondition) { return operation + " " + _StringUtil.jQuoteNoXSS(name) + "(" + _StringUtil.jQuoteNoXSS(locale) + (customLookupCondition != null ? ", cond=" + _StringUtil.jQuoteNoXSS(customLookupCondition) : "") - + ", " + encoding + "): "; } @@ -813,41 +786,38 @@ public class DefaultTemplateResolver extends TemplateResolver { private static final class CachedResultKey implements Serializable { private final String name; private final Locale locale; - private final Object customLookupCondition; - private final String encoding; + private final Serializable customLookupCondition; - CachedResultKey(String name, Locale locale, Object customLookupCondition, String encoding) { + CachedResultKey(String name, Locale locale, Serializable customLookupCondition) { this.name = name; this.locale = locale; this.customLookupCondition = customLookupCondition; - this.encoding = encoding; } @Override public boolean equals(Object o) { - if (o instanceof CachedResultKey) { - CachedResultKey tk = (CachedResultKey) o; - return + if (!(o instanceof CachedResultKey)) { + return false; + } + CachedResultKey tk = (CachedResultKey) o; + return name.equals(tk.name) && locale.equals(tk.locale) && - nullSafeEquals(customLookupCondition, tk.customLookupCondition) && - encoding.equals(tk.encoding); - } - return false; + nullSafeEquals(customLookupCondition, tk.customLookupCondition); } @Override public int hashCode() { - return - name.hashCode() ^ - locale.hashCode() ^ - encoding.hashCode() ^ - (customLookupCondition != null ? customLookupCondition.hashCode() : 0); + int result = name.hashCode(); + result = 31 * result + locale.hashCode(); + result = 31 * result + (customLookupCondition != null ? customLookupCondition.hashCode() : 0); + return result; } + } /** - * Hold the a cached {@link #getTemplate(String, Locale, Object, String)} result and the associated + * Hold the a cached {@link #getTemplate(String, Locale, Serializable)} result and the associated * information needed to check if the cached value is up to date. * * <p> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/dom/JaxenXPathSupport.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/dom/JaxenXPathSupport.java b/src/main/java/org/apache/freemarker/dom/JaxenXPathSupport.java index cd0724a..0bb3c65 100644 --- a/src/main/java/org/apache/freemarker/dom/JaxenXPathSupport.java +++ b/src/main/java/org/apache/freemarker/dom/JaxenXPathSupport.java @@ -194,15 +194,11 @@ class JaxenXPathSupport implements XPathSupport { // [FM3] Look into this "hidden" feature static Template getTemplate(String systemId) throws IOException { Environment env = Environment.getCurrentEnvironment(); - String encoding = env.getCurrentTemplate().getEncoding(); // [FM3] Encoding shouldn't be inherited anymore - if (encoding == null) { - encoding = env.getConfiguration().getEncoding(env.getLocale()); - } String templatePath = env.getCurrentTemplate().getName(); int lastSlash = templatePath.lastIndexOf('/'); templatePath = lastSlash == -1 ? "" : templatePath.substring(0, lastSlash + 1); systemId = env.toFullTemplateName(templatePath, systemId); - return env.getConfiguration().getTemplate(systemId, env.getLocale(), encoding, false); + return env.getConfiguration().getTemplate(systemId, env.getLocale(), false); } private static InputSource createInputSource(String publicId, Template raw) throws IOException, SAXException { http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java b/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java index 0fc7cfa..0853133 100644 --- a/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java +++ b/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java @@ -205,8 +205,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; * that was the only way before Servlet 2.4), not via the more modern * {@link HttpServletResponse#setCharacterEncoding(String)} method. Note that the charset of a template usually comes * from {@link Configuration#getDefaultEncoding()} (i.e., from the {@code default_encoding} FreeMarker setting), - * occasionally from {@link Configuration#getEncoding(Locale)} (when FreeMarker was configured to use different charsets - * depending on the locale) or even more rarely from {@link Configuration#getTemplateConfigurations()} (when FreeMarker was + * or occasionally from {@link Configuration#getTemplateConfigurations()} (when FreeMarker was * configured to use a specific charset for certain templates). * <li>{@value #INIT_PARAM_VALUE_FROM_TEMPLATE}: This should be used in most applications, but it's not the default for * backward compatibility. It reads the {@link Configurable#getOutputEncoding()} setting of the template (note that the http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/main/javacc/FTL.jj ---------------------------------------------------------------------- diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj index 2566df6..ac20322 100644 --- a/src/main/javacc/FTL.jj +++ b/src/main/javacc/FTL.jj @@ -2935,7 +2935,7 @@ ASTDirInclude Include() : { ASTExpression nameExp; Token att, start, end; - ASTExpression exp, encodingExp = null, ignoreMissingExp = null; + ASTExpression exp, ignoreMissingExp = null; } { start = <_INCLUDE> @@ -2947,16 +2947,14 @@ ASTDirInclude Include() : exp = ASTExpression() { String attString = att.image; - if (attString.equalsIgnoreCase("encoding")) { - encodingExp = exp; - } else if (attString.equalsIgnoreCase("ignore_missing") || attString.equals("ignoreMissing")) { + if (attString.equalsIgnoreCase("ignore_missing") || attString.equals("ignoreMissing")) { token_source.checkNamingConvention(att); ignoreMissingExp = exp; } else { String correctedName = attString.equals("ignoreMissing") ? "ignore_missing" : null; throw new ParseException( "Unsupported named #include parameter: \"" + attString + "\". Supported parameters are: " - + "\"encoding\", \"ignore_missing\"." + + "\"ignore_missing\"." + (correctedName == null ? "" : " Supporting camelCase parameter names is planned for FreeMarker 2.4.0; " @@ -2968,7 +2966,7 @@ ASTDirInclude Include() : )* end = LooseDirectiveEnd() { - ASTDirInclude result = new ASTDirInclude(template, nameExp, encodingExp, ignoreMissingExp); + ASTDirInclude result = new ASTDirInclude(template, nameExp, ignoreMissingExp); result.setLocation(template, start, end); return result; } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/manual/en_US/FM3-CHANGE-LOG.txt ---------------------------------------------------------------------- diff --git a/src/manual/en_US/FM3-CHANGE-LOG.txt b/src/manual/en_US/FM3-CHANGE-LOG.txt index 6c7a5fb..5330a6a 100644 --- a/src/manual/en_US/FM3-CHANGE-LOG.txt +++ b/src/manual/en_US/FM3-CHANGE-LOG.txt @@ -133,7 +133,7 @@ the FreeMarer 3 changelog here: In FM2, such overloads has used the global static default DefaltObjectWrapper, but that was removed. - If the ObjectWrapper is not a DefaultObjectWrapper (or a subclass of it), `className?new(args)` will only accept 0 arguments. (Earlier we have fallen back to using the global static default DefaultObjectWrapper instance to handle argument unwrapping - and overloaded constructors.) Note that ?new is only used to instantiate TemplateModel-s, typically, tempalte language + and overloaded constructors.) Note that ?new is only used to instantiate TemplateModel-s, typically, template language functions/directives implemented in Java, and so they hardly ever has an argument. - FreemarkerServlet now requires that the ObjectWrapper it uses implements ObjectWrapperAndUnwrapper. (Thus, the return type of FreemarerServlet.createDefaultObjectWrapper() has changed to ObjectWrapperAndUnwrapper.) The unwrapping functionality is @@ -156,9 +156,18 @@ the FreeMarer 3 changelog here: - Removed DefaultObjectWrapper.methodsShadowItems setting, in effect defaulting it to true. This has decided if the generic get method (`get(String)`) had priority over methods of similar name. The generic get method is only recognized from its name and parameter type, so it's a quite consfusing feature, and might will be removed alltogether. -- DefaultObjectWrapper is not immutable (has no setter methods), and can only be constructed with DefaultObjectWrapper.Builder +- DefaultObjectWrapper is now immutable (has no setter methods), and can only be constructed with DefaultObjectWrapper.Builder - Configuration.getTemplate has no "parse" parameter anymore. Similarly #include has no "parse" parameter anymore. Whether a template is parsed can be specified via Configuration.templateConfigurations, for example based on the file extension. Thus, a certain template is either always parsed or never parsed, and whoever gets or include it need not know about that. - Also added a new setting, "templateLanguge", which decides this; the two available values are - TemplateLanguage.FTL and TemplateLanguage.STATIC_TEXT. \ No newline at end of file + Also added a new setting, "templateLanguage", which decides this; the two available values are + TemplateLanguage.FTL and TemplateLanguage.STATIC_TEXT. +- Configuration.getTemplate has no "encoding" parameter anymore. Similarly #include has no "encoding" parameter either. The charset + of templates can be specified via Configuration.defaultEncoding and Configuration.templateConfigurations (for example based on the + directory it is in), or wirh the #ftl directive inside the template. Thus, a given template always has the same charset, no mater how + it's accessed. +- #include-d/#import-ed templates don't inheirit the charset (encoding) of the #include-ing/#import-ing template. (Because, + again, the charset of a template file is independent of how you access it.) +- Removed Configuration.setEncoding(java.util.Locale, String) and the related other methods. Because of the new logic of template + encodings, the locale to encoding mapping doesn't make much sense anymore. +- Require customLookupCondition-s to be Serializable. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/test/java/org/apache/freemarker/core/ConfigurationTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/ConfigurationTest.java b/src/test/java/org/apache/freemarker/core/ConfigurationTest.java index 51cdcc3..6539753 100644 --- a/src/test/java/org/apache/freemarker/core/ConfigurationTest.java +++ b/src/test/java/org/apache/freemarker/core/ConfigurationTest.java @@ -24,6 +24,7 @@ import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.io.IOException; +import java.io.Serializable; import java.io.StringWriter; import java.lang.reflect.Field; import java.nio.charset.StandardCharsets; @@ -51,6 +52,8 @@ import org.apache.freemarker.core.outputformat.impl.RTFOutputFormat; import org.apache.freemarker.core.outputformat.impl.UndefinedOutputFormat; import org.apache.freemarker.core.outputformat.impl.XMLOutputFormat; import org.apache.freemarker.core.templateresolver.CacheStorageWithGetSize; +import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory; +import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher; import org.apache.freemarker.core.templateresolver.TemplateLookupContext; import org.apache.freemarker.core.templateresolver.TemplateLookupResult; import org.apache.freemarker.core.templateresolver.TemplateLookupStrategy; @@ -249,18 +252,25 @@ public class ConfigurationTest extends TestCase { final String latin2 = "ISO-8859-2"; final String utf8 = "utf-8"; final String tFtl = "t.ftl"; + final String tHuFtl = "t_hu.ftl"; final String tEnFtl = "t_en.ftl"; final String tUtf8Ftl = "t-utf8.ftl"; - final Integer custLookupCond = 123; + final Serializable custLookupCond = new Serializable() { }; Configuration cfg = new Configuration(Configuration.VERSION_3_0_0); cfg.setLocale(Locale.GERMAN); cfg.setDefaultEncoding(latin1); - cfg.setEncoding(hu, latin2); - + + TemplateConfiguration huTC = new TemplateConfiguration(); + huTC.setEncoding(latin2); + cfg.setTemplateConfigurations( + new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*_hu.*"), + huTC)); + ByteArrayTemplateLoader tl = new ByteArrayTemplateLoader(); tl.putTemplate(tFtl, "${1}".getBytes(StandardCharsets.UTF_8)); tl.putTemplate(tEnFtl, "${1}".getBytes(StandardCharsets.UTF_8)); + tl.putTemplate(tHuFtl, "${1}".getBytes(StandardCharsets.UTF_8)); tl.putTemplate(tUtf8Ftl, "<#ftl encoding='utf-8'>".getBytes(StandardCharsets.UTF_8)); cfg.setTemplateLoader(tl); @@ -282,7 +292,7 @@ public class ConfigurationTest extends TestCase { assertEquals(utf8, t.getEncoding()); } - // 2 args overload 1: + // 2 args: { Template t = cfg.getTemplate(tFtl, Locale.GERMAN); assertEquals(tFtl, t.getName()); @@ -318,7 +328,7 @@ public class ConfigurationTest extends TestCase { { Template t = cfg.getTemplate(tFtl, hu); assertEquals(tFtl, t.getName()); - assertEquals(tFtl, t.getSourceName()); + assertEquals(tHuFtl, t.getSourceName()); assertEquals(hu, t.getLocale()); assertNull(t.getCustomLookupCondition()); assertEquals(latin2, t.getEncoding()); @@ -331,55 +341,17 @@ public class ConfigurationTest extends TestCase { assertNull(t.getCustomLookupCondition()); assertEquals(utf8, t.getEncoding()); } - - // 2 args overload 2: - { - Template t = cfg.getTemplate(tFtl, utf8); - assertEquals(tFtl, t.getName()); - assertEquals(tFtl, t.getSourceName()); - assertEquals(Locale.GERMAN, t.getLocale()); - assertNull(t.getCustomLookupCondition()); - assertEquals(utf8, t.getEncoding()); - } - { - Template t = cfg.getTemplate(tFtl, (String) null); - assertEquals(tFtl, t.getName()); - assertEquals(tFtl, t.getSourceName()); - assertEquals(Locale.GERMAN, t.getLocale()); - assertNull(t.getCustomLookupCondition()); - assertEquals(latin1, t.getEncoding()); - } - + // 3 args: - { - Template t = cfg.getTemplate(tFtl, hu, utf8); - assertEquals(tFtl, t.getName()); - assertEquals(tFtl, t.getSourceName()); - assertEquals(hu, t.getLocale()); - assertNull(t.getCustomLookupCondition()); - assertEquals(utf8, t.getEncoding()); - assertOutputEquals("1", t); - } - { - Template t = cfg.getTemplate(tFtl, hu, null); - assertEquals(tFtl, t.getName()); - assertEquals(tFtl, t.getSourceName()); - assertEquals(hu, t.getLocale()); - assertNull(t.getCustomLookupCondition()); - assertEquals(latin2, t.getEncoding()); - assertOutputEquals("1", t); - } - { - Template t = cfg.getTemplate(tFtl, null, utf8); - assertEquals(tFtl, t.getName()); - assertEquals(tFtl, t.getSourceName()); - assertEquals(Locale.GERMAN, t.getLocale()); - assertNull(t.getCustomLookupCondition()); - assertEquals(utf8, t.getEncoding()); - assertOutputEquals("1", t); + try { + cfg.getTemplate("missing.ftl", hu, false); + fail(); + } catch (TemplateNotFoundException e) { + // Expected } + assertNull(cfg.getTemplate("missing.ftl", hu, true)); { - Template t = cfg.getTemplate(tFtl, null, null); + Template t = cfg.getTemplate(tFtl, null, true); assertEquals(tFtl, t.getName()); assertEquals(tFtl, t.getSourceName()); assertEquals(Locale.GERMAN, t.getLocale()); @@ -387,80 +359,42 @@ public class ConfigurationTest extends TestCase { assertEquals(latin1, t.getEncoding()); assertOutputEquals("1", t); } - - // 4 args: { - Template t = cfg.getTemplate(tFtl, hu, utf8, true); + Template t = cfg.getTemplate(tFtl, hu, true); assertEquals(tFtl, t.getName()); - assertEquals(tFtl, t.getSourceName()); - assertEquals(hu, t.getLocale()); - assertNull(t.getCustomLookupCondition()); - assertEquals(utf8, t.getEncoding()); - assertOutputEquals("1", t); - } - { - Template t = cfg.getTemplate(tFtl, null, utf8, true); - assertEquals(tFtl, t.getName()); - assertEquals(tFtl, t.getSourceName()); - assertEquals(Locale.GERMAN, t.getLocale()); - assertNull(t.getCustomLookupCondition()); - assertEquals(utf8, t.getEncoding()); - assertOutputEquals("1", t); - } - { - Template t = cfg.getTemplate(tFtl, hu, null, true); - assertEquals(tFtl, t.getName()); - assertEquals(tFtl, t.getSourceName()); + assertEquals(tHuFtl, t.getSourceName()); assertEquals(hu, t.getLocale()); assertNull(t.getCustomLookupCondition()); assertEquals(latin2, t.getEncoding()); assertOutputEquals("1", t); } - // Ignore missing + // 4 args: try { - cfg.getTemplate("missing.ftl", hu, utf8, false); + cfg.getTemplate("missing.ftl", hu, custLookupCond, false); fail(); } catch (TemplateNotFoundException e) { // Expected } - assertNull(cfg.getTemplate("missing.ftl", hu, utf8, true)); - - // 5 args: + assertNull(cfg.getTemplate("missing.ftl", hu, custLookupCond, true)); { - Template t = cfg.getTemplate(tFtl, hu, custLookupCond, utf8, false); + Template t = cfg.getTemplate(tFtl, hu, custLookupCond, false); assertEquals(tFtl, t.getName()); - assertEquals(tFtl, t.getSourceName()); + assertEquals(tHuFtl, t.getSourceName()); assertEquals(hu, t.getLocale()); assertEquals(custLookupCond, t.getCustomLookupCondition()); - assertEquals(utf8, t.getEncoding()); + assertEquals(latin2, t.getEncoding()); assertOutputEquals("1", t); } { - Template t = cfg.getTemplate(tFtl, null, custLookupCond, utf8, false); + Template t = cfg.getTemplate(tFtl, null, custLookupCond, false); assertEquals(tFtl, t.getName()); assertEquals(tFtl, t.getSourceName()); assertEquals(Locale.GERMAN, t.getLocale()); assertEquals(custLookupCond, t.getCustomLookupCondition()); - assertEquals(utf8, t.getEncoding()); - assertOutputEquals("1", t); - } - { - Template t = cfg.getTemplate(tFtl, hu, custLookupCond, null, false); - assertEquals(tFtl, t.getName()); - assertEquals(tFtl, t.getSourceName()); - assertEquals(hu, t.getLocale()); - assertEquals(custLookupCond, t.getCustomLookupCondition()); - assertEquals(latin2, t.getEncoding()); + assertEquals(latin1, t.getEncoding()); assertOutputEquals("1", t); } - try { - cfg.getTemplate("missing.ftl", hu, custLookupCond, utf8, false); - fail(); - } catch (TemplateNotFoundException e) { - // Expected - } - assertNull(cfg.getTemplate("missing.ftl", hu, custLookupCond, utf8, true)); } private void assertOutputEquals(final String expectedContent, final Template t) throws ConfigurationException, http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f6a693c5/src/test/java/org/apache/freemarker/core/TemplatGetEncodingTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/TemplatGetEncodingTest.java b/src/test/java/org/apache/freemarker/core/TemplatGetEncodingTest.java deleted file mode 100644 index 60ba865..0000000 --- a/src/test/java/org/apache/freemarker/core/TemplatGetEncodingTest.java +++ /dev/null @@ -1,87 +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. - */ -package org.apache.freemarker.core; - -import static org.junit.Assert.*; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -import org.apache.freemarker.core.templateresolver.ConditionalTemplateConfigurationFactory; -import org.apache.freemarker.core.templateresolver.FileNameGlobMatcher; -import org.apache.freemarker.core.templateresolver.impl.ByteArrayTemplateLoader; -import org.apache.freemarker.core.templateresolver.impl.StrongCacheStorage; -import org.junit.Test; - -public class TemplatGetEncodingTest { - - @Test - public void test() throws IOException { - Configuration cfg = new Configuration(Configuration.VERSION_3_0_0); - { - cfg.setDefaultEncoding("ISO-8859-2"); - ByteArrayTemplateLoader tl = new ByteArrayTemplateLoader(); - tl.putTemplate("t", "test".getBytes(StandardCharsets.UTF_8)); - tl.putTemplate("static", "<#test>".getBytes(StandardCharsets.UTF_8)); - TemplateConfiguration staticTextTC = new TemplateConfiguration(); - staticTextTC.setTemplateLanguage(TemplateLanguage.STATIC_TEXT); - cfg.setTemplateConfigurations( - new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("static"), staticTextTC)); - cfg.setTemplateLoader(tl); - cfg.setCacheStorage(new StrongCacheStorage()); - } - - { - Template tDefEnc = cfg.getTemplate("t"); - assertEquals("ISO-8859-2", tDefEnc.getEncoding()); - assertSame(tDefEnc, cfg.getTemplate("t")); - - Template tDefEnc2 = cfg.getTemplate("t", (String) null); - assertEquals("ISO-8859-2", tDefEnc2.getEncoding()); - assertSame(tDefEnc, tDefEnc2); - - Template tUTF8 = cfg.getTemplate("t", "UTF-8"); - assertEquals("UTF-8", tUTF8.getEncoding()); - assertSame(tUTF8, cfg.getTemplate("t", "UTF-8")); - assertNotSame(tDefEnc, tUTF8); - } - - { - Template tDefEnc = cfg.getTemplate("static", null, null, false); - assertEquals("ISO-8859-2", tDefEnc.getEncoding()); - assertSame(tDefEnc, cfg.getTemplate("static", null, null, false)); - - Template tUTF8 = cfg.getTemplate("static", null, "UTF-8", false); - assertEquals("UTF-8", tUTF8.getEncoding()); - assertSame(tUTF8, cfg.getTemplate("static", null, "UTF-8", false)); - assertNotSame(tDefEnc, tUTF8); - } - - { - Template nonStoredT = new Template(null, "test", cfg); - assertNull(nonStoredT.getEncoding()); - } - - { - Template nonStoredT = Template.createPlainTextTemplate(null, "<#test>", cfg); - assertNull(nonStoredT.getEncoding()); - } - } - -}
